AnsweredAssumed Answered

I2C documentation error (Master Read N Bytes)

Question asked by bil.til on Dec 4, 2012
Latest reply on Dec 5, 2012 by STOne-32
In the STM32F4 ref manual (RM0090, current version Nov. 2012), the read of N (>2) Bytes is described like this (end of 25.3.3):

For N >2 -byte reception, from N-2 data reception
● Wait until BTF = 1 (data N-2 in DR, data N-1 in shift register, SCL stretched low until
data N-2 is read)
● Set ACK low
● Read data N-2
● Wait until BTF = 1 (data N-1 in DR, data N in shift register, SCL stretched low until a
data N-1 is read)
● Set STOP high
● Read data N-1 and N


The last 2 lines here are NOT correct. If I do so, then the RXNE keeps set for a short time. Instead it should say:
● Set STOP high
● Read data N-1
● Wait until STOP low
● Read data N

The same applies to the last 2 lines of the preceding instructions "Read 2 Bytes". There it now says:
● Set STOP high
● Read data 1 and 2


Instead it should say:
● Set STOP high
● Read data 1
● Wait until STOP low
● Read data 2

Further the instruction, how to receive 1 Byte is missing here - this is described only in the AN2824 - nicely correct (but the description how to receive N>2 Bytes is NOT correct there - this will need to nerving flow errors every 100th-300th receiption to my experience (100kHz IIC, a simple ADC IIC device polled with 3 bytes):
● Set ACK low
● Clear ADDR
● Set STOP high
● Wait until STOP low
● Read data 1

Further it would be helpful to add the following warning:
In case of a busy bus, which might be forced by a peripheral slave device which stopped the transfer in some illegal state (keeping SDA low), the only possibility to resolve this bus blocking is the following:
Re-configure the SCL output to standard out (switch off alternate function in the GPIO->MODER register) and send out 9 clock pulses "manually" (toggle GPIO->ODR, take care that they are not too shorter than the  IIC baud rate). Then switch the GPIO->MODER register back to alternate function, and re-initialize the I2C configuration registers (at the beginning please set the bit I2C_CR1_SWRST for 1 processor cycle).

[When such a blocking peripheral slave device needs further clock cycles, it will have somehow stopped in a middle of a byte transfer. STM32F4 I2C module cannot resolve such a situation in an active way, as in case of a "busy bus" situation it will refuse to send a START condition, so STM32 I2C module will also refuse to become bus master. But if the peripheral device clocks out its byte after receiving the 9 manual SCL cycles, it will automatically stop transfer, as it will recognize that the ACK is missing.]

One last warning: If you intermix read transfers with 2 and N bytes: Do not forget to reset the POS flag before start of each I2C transfer. The  I2C_CR1_POS flag must be set ONLY in case of reading exactly 2 bytes. Also I would recommend to set SR1=0 and SR2=0 before start of each transfer.(It is a bit weird, that if you do not reset the POS flag, in 98% of the transfers it somehow will be reset automatically - only about every 100th-200th transfer it will disturb that the POS flag is set... but maybe this is due to my special sort of polling algorithm, I did not analyze this further - after I resetted it at the start, it now works 100% fine).

Outcomes