debuggingstm32i2cnucleo

Extracting I2C SDA signal content using STM32CUBEIDE Debug


I want to extract the content/sequence of an I2C communication on the SDA line, without using an oscilloscope to decrypt the signal, so i was wondering if it was possible to do it via STM32CUBEIDE debug?

Thanks


Solution

  • Not directly, and not the entire communication. You can output the data you send/receive to the UART connected to ST-Link. Don't forget that you'll have to convert a data byte (such as) 0x34 into a string of "0x34" for UART to make it readable from the terminal (otherwise the terminal will display an ASCII character with the code 0x34, which may even be invisible), so there will have to be some data conversion, which is a whole function you need to implement, there are multiple solutions on this very site about how to do that, or you can come up with your own solution to that.

    You will not be able to fully trace the communication, as in see the waveforms. You won't be able to see start and stop bits and address communication physically, but you can watch I2C status register, which will have various flags. You can use breakpoints and see the flags in I2C, but remember, that tracing communication with breakpoints is very hard and limited. You can break packets of data in the middle, ruin timings when the program pauses and so on. Be mindful of where you place your breakpoints. You will also not be able to verify that the data you send from master to slave actually gets physically sent out to I2C line (since you can successfully send it out to UART but you have no idea if I2C sent it out, flags in I2C status register are all you have). But you can totally verify incoming data from the slave by redirecting it to UART.

    In order to access I2C flags, run debug in STM32CubeIDE, when you're in debug mode and sitting at a breakpoint, go to Special Function Registers (SFR) tab on the top-right (default panels), find your I2C interface, unfold it and find SR (status register) or ISR (interrupt and status register), whichever exists. There you should have various 0 and 1, which indicate certain state of the peripheral (e.g. line idle, busy, transfer complete, overrun error etc.)