Skip to main content
Visitor II
February 12, 2024
Question

Double NAK - additional byte transmitted in I2C read sequence - STM32F401

  • February 12, 2024
  • 1 reply
  • 1686 views

Hi Everyone!

My STM32F401 MCU is a master for communication with an I2C device which requires to write 3 bytes and than read 2 bytes. This cycle repeats each 50 ms. Each cycle includes:

  1. Check presence of the slave device using HAL_I2C_IsDeviceReady
  2. Write 3 bytes with HAL_I2C_Master_Transmit_DMA
  3. Short delay for some other operations
  4. Check presence of the slave device using HAL_I2C_IsDeviceReady
  5. Read 2 bytes using HAL_I2C_Master_Receive_DMA

Most of the time every thing works as expected, here is a single cycle:

image (2).png

However, randomly (at least I have not seen any pattern) STM generated additional byte transfer in the read sequence, after a NAK has been already generated. The abnormality is the double NAK and than a STOP condition.

image (3).png

I am assuming the STM is generating additional clocks, based on the unchanged analog signal characteristics. Would very much appreciate any help, did any one encountered such behavior before?

Regards

    This topic has been closed for replies.

    1 reply

    Super User
    February 12, 2024

    The I2C peripheral in the F4 is complicated. Flags need to be handled in a specific timeframe in order for it to work correctly. Do you have other things going on in the program that would delay relevant I2C/DMA callbacks?

    Perhaps consider using HAL_I2C_Master_Transmit_IT instead, though I think it also has issues.

    TomaszMAuthor
    Visitor II
    February 12, 2024

    @TDK Saying I have a lot going on in the program is an understatement. I have at least 2x I2C, 1x SPI, UART and ADC all using DMA transfers only, it is a rather complex project. Using IT version in not an option and it would preemption other tasks and compromise the system.

    I am currently using HAL for all the operation, is it at least possible if I write my own driver or use LL to handle transmission to achieve a working solution? Or the timings/architecture of the peripheral it self could cause problems?

    Would appreciate very much if smbd could point me in the direction of the solution, exploring HAL to find the issue will be very time consuming. The most weird thing is that additional byte transfer is generated by, probably, DMA despite of NAK being already generated.

     

    Regards

    Super User
    February 12, 2024

    It is possible to write your own driver. But if you want to use DMA, I believe you need to handle flags within a certain amount of time. Writing a robust interrupt-based driver that does not have this behavior and does not require immediate priority (i.e. allows for clock stretching) is possible, but quite complicated. I have done so. The reference manual and using direct register access are your best resources if you want to go this route.