2021-08-17 03:57 PM
I need to write a code that acts as an I2C slave to another processor, but I haven't figured out how to tell if the master does a repeated start. That is: what does the slave get if there is a "addressed" read? And how does that differ from one byte "addressed" write?
I understand the protocol.
One byte write: start-condition write-command, address-bytes, data, stop condition.
Read: start-condition write-command, address-bytes, repeated start-condition, read-command, ...
But how does that look from the slave processor's POV?
Like, does the I2C-device know that there's an address after every (repeated) start condition? If, after the write command, I clear the address match flag, does it set again, when the read command is encountered after the repeated start condition?
For clarification, I'm talking about memory read, I I should handle non-addressed reads and writes too (without the memory address field).
2021-08-18 03:02 PM
A-ha. From an example (STM32Cube_FW_L4_V1.8.0) ,I found this:
"Then through HAL_I2C_Master_Sequential_Receive_IT() routine, Master device generate a RESTART condition
with Slave address and a read bit condition.
In Slave side, when address Slave match code is received on I2C3, an event interrupt (ADDR) occurs."
Now the question remains, does the address match trigger with any byte that match, or just (the next) byte after (repeated) start condition?
That is: does (repeated) start condition "arm" the address matching?
2021-09-08 10:25 AM
Looks like address match is only checked after start condition. (If the previous match has been cleared.) And the address match interrupt replaces the RXNE. The address doesn't show up in the RXDR.
2021-09-16 08:14 AM
Does anyone have an idea of the callback logic of the Cube I2C sequential fuctions? And what do the XferOptions really mean?
The thing is, the slave expects writes (always addressed), addressed reads and non-addressed reads from the master. Addressed write has 2 bytes of address and 0 - 32 bytes of data after that.
Addressed read has 2 byte write (the address) then repeated start and read (0 - 32 bytes).
The master can try to read or write more than 32 bytes, but only maximum of 32 bytes in a pre-defined address range are handled. The rest of the written bytes are just dropped, and in case of read, dummy data is returned.
I found out that the application layer doesn't see the stop condition. If, in the middle of read or write, master issues a stop condition, the library resets the stop flag and returns ACK-error instead (error callback), and instead of rx-complete callback, a listen-complete callback takes place.
If you start slave transmission with "LAST_FRAME", there doesn't seem to be any callbacks.