Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: MicroBlaze I2C - XIic, отправка-прием
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
AVR
Не понимаю что я делаю не так. Не могу найти фукнцию, которая бы записала один байт (адрес регистра внутри slave) и затем стала бы читать N байт.

Вот код:
Код
    XUartLite_RecvByte(XPAR_UARTLITE_1_BASEADDR);

    u8 msg[16];

    msg[0] = 0x00;
    int sent = 0;
    sent = XIic_Send(XPAR_IIC_0_BASEADDR, 0x38, msg, 1, XIIC_REPEATED_START);
    for(int i = 0; i < 16; i++) msg[i] = 0;

    int received;
    received = XIic_Recv(XPAR_IIC_0_BASEADDR, 0x38, msg, 10, XIIC_STOP);

    xil_printf("sent=%d\n\r", sent);
    xil_printf("received=%d\n\r", received);

    xil_printf("received data: ");
    for(int i = 0; i < 10; i++) xil_printf("%02X ", msg[i]);
    xil_printf(" OK\n\r");

Код
sent=1
received=0
received data: 00 00 00 00 00 00 00 00 00 00  OK

Вот с точки зрения даташита я должен отправить адрес регистра который хочу читать, а затем уже принять байт начиная с него:
Нажмите для просмотра прикрепленного файла
На деле же получается вот что, запись заканчивается новым стартом (XIIC_REPEATED_START)
Нажмите для просмотра прикрепленного файла
Тут линии такие:
Project.unit<0>.dataChannel<0>=mb/fpga_0_Generic_IIC_Bus_Sda_pin_T
Project.unit<0>.dataChannel<1>=mb/fpga_0_Generic_IIC_Bus_Sda_pin_O
Project.unit<0>.dataChannel<2>=mb/fpga_0_Generic_IIC_Bus_Scl_pin_T
Project.unit<0>.dataChannel<3>=mb/fpga_0_Generic_IIC_Bus_Scl_pin_O

Ну а как без XIIC_REPEATED_START? Тогда если XIIC_STOP то стоп и возникнет. ACK я видеть к сожалению не могу, _Sda_pin_O у меня увы выдает все время ноль, но зато на _Scl_pin_T должны быть правильные клоки достоверно быть видны.

Неужели возможно самый распространенный сценарий они не поддерживают? Когда пишется один байт с адресом а затем адрес регистра 8 бит и сразу чтение?

Вопрос: как осуществить нормальную запись одного байта и затем сразу чтение??? Я бьюсь уже очень много дней. Но работу с теми же датчиками по I2C на ARM процессоре с Linux я осилил ща 30 минут и всё сразу работало, а тут какой-то затык.
misyachniy
Цитата(AVR @ Oct 22 2012, 04:04) *
for(int i = 0; i < 16; i++) msg[i] = 0;
int received;
received = XIic_Recv(XPAR_IIC_0_BASEADDR, 0x38, msg, 10, XIIC_STOP);


Не знаю как работает функция XIic_Recv(), но по моему msg нужно заполнить 0xFF.
AVR
Получилось так:
Код
int test_i2c::i2c_read(int i2c_address, unsigned char reg_address, unsigned char *data, int read_count)
{
    int received;
    unsigned short status_reg;
    xil_printf("reg_address=%d\n\r", reg_address);

    do
    {
        status_reg = XIic_ReadReg(XPAR_IIC_0_BASEADDR, XIIC_SR_REG_OFFSET);
        if(!(status_reg & XIIC_SR_BUS_BUSY_MASK))
        {
            received = XIic_Send(XPAR_IIC_0_BASEADDR, i2c_address, (u8*)&reg_address, 1, XIIC_STOP);

            if(received != 1)
            {
                XIic_WriteReg(XPAR_IIC_0_BASEADDR, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK);
                XIic_WriteReg(XPAR_IIC_0_BASEADDR, XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK);
            }
        }

    } while(received != 1);

    received = XIic_Recv(XPAR_IIC_0_BASEADDR, i2c_address, data, read_count, XIIC_STOP);
    return received;
}

Черт ногу сломит, но хотя бы работает (это типа low level), потом перепишу на "высшем" уровне, с прерываниями и т.п.

Тестировал с акселерометром:
Код
        int xyz[3];
        received = i2c_read(0x38, 2, msg, 6);

        xil_printf("received data: ");
        for(int k = 0; k < 6; k++) xil_printf("%02X ", msg[k]);
        xil_printf(" END\n\r");

        for(int i = 0; i < 3; i++)
        {
            xyz[i] = ((msg[i*2] >> 6) & 0x03) + (msg[i*2 + 1] << 2);
            if(xyz[i] & (1<<9))
            {
                xyz[i] &= ~(1<<9);
                xyz[i] = -(512 - xyz[i]);
            }
        }

        xil_printf("x=%d y=%d z=%d\n\r", xyz[0], xyz[1], xyz[2]);

Код
reg_address=2
received data: 81 20 01 FF 01 03  END
x=130 y=-4 z=12
xor.kruger
А проблемы с записью были ?
У меня та же фигня когда пытаюсь записать байты данных с помощью XIic_Send.
Ни у кого нету функции записи для микроблейза ?
xor.kruger
Разобрался.
Привожу пример работающих функций, может кому-то пригодится.
Запись:
Код
int WriteI2CBuffer(XIic *InstancePtr, unsigned char device, void * source, int len)
{
    unsigned int count;
    unsigned char * ptr;

    ptr = source;
    count = XIic_Send(InstancePtr->BaseAddress, device, ptr, len, XIIC_STOP);
    if(count != len)
        count = -1;
    else
       count = 0;
    return count;
}

Чтение:
Код
int ReadI2CBuffer(XIic *InstancePtr, unsigned char device, void * destination, int len)
{
    unsigned int count;
    unsigned char * ptr;

    ptr = destination;
    count = XIic_Recv(InstancePtr->BaseAddress, device, ptr, len, XIIC_STOP);
    if(count != len)
        count = -1;
    else
        count = 0;
    return count;
}

Запись 6-ти байт начиная с 7-го регистра:
Код
WriteBuffer[0] = 0x07;
    WriteBuffer[1] = 0xA0;
    WriteBuffer[2] = 0xC2;
    WriteBuffer[3] = 0xc9;
    WriteBuffer[4] = 0xd8;
    WriteBuffer[5] = 0xe7;
    WriteBuffer[6] = 0x80;
    // Start the IIC device.
    Status = XIic_Start(&Iic);
    if (Status != XST_SUCCESS) {
        xil_printf("Failed to start the IIC device\r\n");
        return XST_FAILURE;
    }
    Status = WriteI2CBuffer(InstancePtr, IIC_SLAVE_DEVICE_ADDRESS, WriteBuffer, 7);
    // Stop the IIC device.
    Status = XIic_Stop(&Iic);
    if (Status != XST_SUCCESS) {
        xil_printf("Failed to stop the IIC device\r\n");
        return XST_FAILURE;
    }
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.