Showing results for 
Search instead for 
Did you mean: 

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

Associate II

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?



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.

If you feel a post has answered your question, please click "Accept as Solution".

@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.



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.

If you feel a post has answered your question, please click "Accept as Solution".

Yeah, thanks, currently going through time consuming process of low level driver creation is not really an option right now. I would very much assume that HAL driver provided by ST will be properly working, at least to some extend. Or at most with clearly stated limitations.

It would be great if someone from ST team could specify if this is a known issue that could be fixed at some point, or I can not count on that. Is there any way of submitting an issue/bug report? For now, for me, it is very hard to specify where the bug is located, the HAL driver, peripheral itself, or the shear amount of data transfer in the system causing timing problems...