Перейти к содержанию
    

MicroBlaze I2C - XIic, отправка-прием

Не понимаю что я делаю не так. Не могу найти фукнцию, которая бы записала один байт (адрес регистра внутри 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

Вот с точки зрения даташита я должен отправить адрес регистра который хочу читать, а затем уже принять байт начиная с него:

post-10008-1350867176_thumb.png

На деле же получается вот что, запись заканчивается новым стартом (XIIC_REPEATED_START)

post-10008-1350867194_thumb.png

Тут линии такие:

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 минут и всё сразу работало, а тут какой-то затык.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

for(int i = 0; i < 16; i++) msg = 0;

int received;

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

 

Не знаю как работает функция XIic_Recv(), но по моему msg нужно заполнить 0xFF.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Получилось так:

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А проблемы с записью были ?

У меня та же фигня когда пытаюсь записать байты данных с помощью XIic_Send.

Ни у кого нету функции записи для микроблейза ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разобрался.

Привожу пример работающих функций, может кому-то пригодится.

Запись:

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;
    }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...