AnsweredAssumed Answered

STM32F4 DSP and standard peripherals library - bug in I2C_CheckEvent() ?

Question asked by Andrew Neil on May 7, 2016
Latest reply on May 23, 2016 by Clive One
Reference manual RM0383, "STM32F411xC/E advanced ARM®-based 32-bit MCUs", says:

18.6.7 I2C Status register 2 (I2C_SR2)

Note: Reading I2C_SR2 after reading I2C_SR1 clears the ADDR flag, even if the ADDR flag was
set after reading I2C_SR1. Consequently, I2C_SR2 must be read only when ADDR is found
set in I2C_SR1 or when the STOPF bit is cleared.


But the STM32F4 DSP and standard peripherals library, STSW-STM32065, does not do this in I2C_CheckEvent():

ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{
  uint32_t lastevent = 0;
  uint32_t flag1 = 0, flag2 = 0;
  ErrorStatus status = ERROR;
 
  /* Check the parameters */
  assert_param(IS_I2C_ALL_PERIPH(I2Cx));
  assert_param(IS_I2C_EVENT(I2C_EVENT));
 
  /* Read the I2Cx status register */
  flag1 = I2Cx->SR1;
  flag2 = I2Cx->SR2;
  flag2 = flag2 << 16;


It will always read SR2 immediately after SR1 - without any attempt to check ADDR or STOPF.

I guess it should look something like this:

/* Read the I2Cx status registers */
flag1 = I2Cx->SR1;
 
/*
 * RM0383 states, "I2C_SR2 must be read only when ADDR is found
 * set in I2C_SR1 or when the STOPF bit is cleared"
 * See section 18.6.7 I2C Status register 2 (I2C_SR2) on page 492 (Rev 1).
 */
if( (flag1 &  I2C_SR1_ADDR) ||
    (flag1 & ~I2C_SR1_STOPF)  )
{
  flag2 = I2Cx->SR2;
}
else
{
    return ERROR;
}



(can't raise a ticket on this as the system is down for "upgrades").


This is in the current 1.7.0 library release, and previous releases.



Outcomes