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

Не принимается >1 байта с I2C

Всем привет!

 

Работаю с железкой по i2c, в основном "обращения" все по 1 байту - пишу адресс, читаю 1 байт. всё это работает. Но вот если хотя бы 2 байта, а то и более зависает приём на последнем байте.

void MPU6050_I2C_BufferRead(u8 slaveAddr, u8* pBuffer, u8 readAddr, u16 NumByteToRead)
{
    // ENTR_CRT_SECTION();

    /* While the bus is busy */
    //while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));

    /* Send START condition */
    I2C_GenerateSTART(ENABLE);

    /* Test on EV5 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

    /* Send MPU6050 address for write */
    I2C_Send7bitAddress(slaveAddr, I2C_DIRECTION_TX);

    /* Test on EV6 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    /* Clear EV6 by setting again the PE bit */
    I2C_Cmd(ENABLE);

    /* Send the MPU6050's internal address to write to */
    I2C_SendData(readAddr);

    /* Test on EV8 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    /* Send STRAT condition a second time */
    I2C_GenerateSTART(ENABLE);

    /* Test on EV5 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

    /* Send MPU6050 address for read */
    I2C_Send7bitAddress(slaveAddr, I2C_DIRECTION_RX);

    /* Test on EV6 and clear it */
    while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    volatile u8 t;
    
    /* While there is data to be read */
    while (NumByteToRead)
    {      
        if (NumByteToRead == 1)
        {
            /* Disable Acknowledgement */
            I2C_AcknowledgeConfig(I2C_ACK_NONE);

            /* Send STOP Condition */
            I2C_GenerateSTOP(ENABLE);
            
        t=0;
        } 

        /* Test on EV7 and clear it */
        if (I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
        {
            /* Read a byte from the MPU6050 */
            *pBuffer = I2C_ReceiveData();

            /* Point to the next location where the byte read will be saved */
            pBuffer++;

            /* Decrement the read bytes counter */
            NumByteToRead--;
        }
    }

    /* Enable Acknowledgement to be ready for another reception */
    I2C_AcknowledgeConfig(I2C_ACK_CURR);
    // EXT_CRT_SECTION();
}

 

t=0; чтобы отладчиком туда попасть после STOP :)

Анализатором на щине i2c всё правильно - все байты приняты, последний NACK и STOP.

По коду же после STOP событие I2C_EVENT_MASTER_BYTE_RECEIVED не выставляется, но при 1 байте всё работает. Что я делаю не так? Да и код-то из примера STMовского...

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


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

А чем пугают прерывания? :) Я бы сначала принял байт, а уж потом, в зависимости от обстоятельств, выставлял STOP.

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


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

Вот хотите бейте меня палками, но беспроблемной реализации именно аппаратного I2C я нигде не видел. Где это Ерратами подтверждено, где просто битьем об стену лбом. Пока что мне "не везло" c PIC от 16 до 32, Atmel AT91RM9200, ST STM32F407. То зависает после захвата клока слейвом, то теряет или не выдает или вообще игнорирует аки/наки/стопы, то блокируется после нескольких суток работы.... везде свои хитрости и куча аппноутов и еррат с костылями.

Очень может быть, что я его так и научился готовить, но я пытался.

Так что таскаю давным-давно однажды отлаженную программную реализацию I2C из продукта в продукт, из процессора в процессор.

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


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

Вот хотите бейте меня палками, но беспроблемной реализации именно аппаратного I2C я нигде не видел.

Смотрите в сторону TWI на AVR; модуля I2C в MB91F362GB; SERCOM в режиме I2C на AT91SAMD21.

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


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

В сторону NXP надо смотреть. Как-никак авторы сего интерфейса. :)

Ближе к теме. Для STM32F1 пришлось писать три процедуры чтения - для 1 байта, 2 и более 2. В STM8 I2C устроен сходным кривым образом. На сайте ST есть пример, в котором это всё разруливается (в периферийную библиотеку он не входит). AN3281.

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


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

В сторону NXP надо смотреть. Как-никак авторы сего интерфейса. :)

Ближе к теме. Для STM32F1 пришлось писать три процедуры чтения - для 1 байта, 2 и более 2. В STM8 I2C устроен сходным кривым образом. На сайте ST есть пример, в котором это всё разруливается (в периферийную библиотеку он не входит). AN3281.

Именно так и сдала - работает. Очередной костыль.

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


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

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

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

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

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

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

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

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

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

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