cancel
Showing results for 
Search instead for 
Did you mean: 

I2C documentation error (Master Read N Bytes)

flyer31
Senior
Posted on December 04, 2012 at 19:14

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

1 REPLY 1
Nickname12657_O
Associate III
Posted on December 05, 2012 at 16:59

Hi bil.til,

Thanks for your feedbacks, you help to enhance our documentation!

Your suggestions will be sent to relevant person

0690X0000060MlvQAE.gif

Cheers,

STOne-32