cancel
Showing results for 
Search instead for 
Did you mean: 

Erratum in errata of STM32F101xC/D/E ?

hendrik2
Associate II
Posted on November 29, 2013 at 11:53

ES0104: STM32F101xC/D/E and STM32F103xC/D/E high-density device limitations

In CD00197763 �2.13.1 it is stated

Clear ADDR by reading SR1 register followed by reading SR3

SR3? Not SR2? I assume this is an erratum in the errata document?

#stm32-i2c-errata-crappy_i2c_core
2 REPLIES 2
hendrik2
Associate II
Posted on November 29, 2013 at 11:58

The reason I ask is because I get 2 bytes NACK'ed instead of just the last one.


SR1Register = I2C2->SR1;


// If ADDR is set, we cannot read SR2 without clearing ADDR and triggering the

// continuation of the bus access. Instead, we will assume a sensible SR2 value

// (master bit) and defer the reading of SR2 to when we actually want to proceed

SR2Register = (SR1Register & I2C_SR1_ADDR) ? I2C_SR2_MSL : I2C2->SR2;


// If I2C2 is Master (MSL flag = 1)

if
(SR2Register & I2C_SR2_MSL)

{

// If SB = 1, I2C master sent a START on the bus: EV5)

if
(SR1Register & I2C_SR1_SB)

{...

}

else
if
(SR1Register & I2C_SR1_ADDR) 
// EV6

{

if
(I2CBus[I2C2BUS].I2CDirection == I2C_Direction_Transmitter)

{...

}

else
// Master Receiver

{

if
(totalSize >2)

{...

}

else
if
(totalSize == 2)

{

// Errata 2.1 EV6_2:

// a) ADDR=1

// b) Override SCL, driving it low

I2C_StretchSCL(I2C2BUS,
true
);

// c) Clear ADDR by reading SR2 after reading SR1

I2C2->SR2;

// d) Program ACK=0

I2C_AcknowledgeConfig(I2C2, DISABLE);

// e) Return SCL control to the I2C core

I2C_StretchSCL(I2C2BUS,
false
);

// We will still get one RxNE interrupt (EV7) after this

When I breakpoint on line 30, the ACK bit is still on. So according to my interpretation of the errata sheet, this should be the way to go. But on the I2C bus I see the 2 bytes both being NACK'ed?
hendrik2
Associate II
Posted on November 29, 2013 at 12:06

Update: the POS bit needed to be set, then it only nacks the 2nd byte as intended.

I2C_NACKPositionConfig(I2C2, I2C_NACKPosition_Next);