cancel
Showing results for 
Search instead for 
Did you mean: 

The STM32 LL library's LL_I2C_MODE_AUTOEND did not generate a STOP condition after the data transmis

Tokit
Associate II

  As mentioned above, I encountered a similar issue before when using the L0 series, and at that time, I chose to abandon hardware I2C in favor of software emulation. Now, with the STM32G431, when I use LL_I2C_HandleTransfer to configure continuous reading of multiple data along with LL_I2C_MODE_AUTOEND, after the first read operation completes the specified number of bytes, it automatically triggers a STOP condition, which is as expected. However, upon the second invocation of this code segment, I noticed that after reading the last byte, the SCL remains pulled low. This behavior seems equivalent to the I2C peripheral being stuck. The STM32, as the master, should not keep the SCL pulled low without performing any operation at any point.

Tokit_0-1710673718996.png

On the first read operation, a STOP condition was automatically triggered after reading 6 bytes of data, which is normal.

Tokit_1-1710673771525.png

When I call the same function for the second time to read data, after the last byte is read, the SCL remains pulled low, which is abnormal.

void qmc_read_databuf(uint8_t *buf)
{
  LL_I2C_HandleTransfer(QMC_I2C, QMC5883_ADD,LL_I2C_ADDRSLAVE_7BIT, 1,LL_I2C_MODE_SOFTEND,LL_I2C_GENERATE_START_WRITE );
  LL_I2C_TransmitData8(QMC_I2C, 0);
  while(LL_I2C_IsActiveFlag_TXE(QMC_I2C)==RESET);
  LL_I2C_AcknowledgeNextData(QMC_I2C, LL_I2C_ACK);
  LL_I2C_HandleTransfer(QMC_I2C, (QMC5883_ADD|1), LL_I2C_ADDRSLAVE_7BIT, 6, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
  for(uint8_t i=0; i<5; i++)
  {
    if(i<4)
      LL_I2C_AcknowledgeNextData(QMC_I2C, LL_I2C_ACK);
    else
      LL_I2C_AcknowledgeNextData(QMC_I2C, LL_I2C_NACK);
    while(LL_I2C_IsActiveFlag_RXNE(QMC_I2C)==0);
    buf[i]=LL_I2C_ReceiveData8(QMC_I2C);
  }
  //LL_I2C_GenerateStopCondition(QMC_I2C);
}

 Now, I need to add the last line LL_I2C_GenerateStopCondition(QMC_I2C); to manually control the microcontroller to generate STOP. The issue is resolved.

However, I believe LL_I2C_MODE_AUTOEND should imply that it will automatically generate STOP, or does this setting have another meaning?

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

The reference manual will be the best resource for understanding the effect of the various register fields.

TDK_0-1710686453872.png

 

In your code, it looks like you're setting up a transfer for 6 bytes, but only reading 5 of them. Perhaps since you haven't finished reading all 6 of them, the stop condition is not sent.

TDK_1-1710686510883.png

 

Probably debugging the code and hitting "pause" when this happens and examining the state of the registers would tell the full story. Likely RXNE is set and code is off somewhere else not acting on it.

 

 

> The STM32, as the master, should not keep the SCL pulled low without performing any operation at any point.

Just as an aside, the master is certainly allowed to stretch the clock. The peripheral may be "stuck" but likely due to code, not any hardware issue.

 

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

2 REPLIES 2
TDK
Guru

The reference manual will be the best resource for understanding the effect of the various register fields.

TDK_0-1710686453872.png

 

In your code, it looks like you're setting up a transfer for 6 bytes, but only reading 5 of them. Perhaps since you haven't finished reading all 6 of them, the stop condition is not sent.

TDK_1-1710686510883.png

 

Probably debugging the code and hitting "pause" when this happens and examining the state of the registers would tell the full story. Likely RXNE is set and code is off somewhere else not acting on it.

 

 

> The STM32, as the master, should not keep the SCL pulled low without performing any operation at any point.

Just as an aside, the master is certainly allowed to stretch the clock. The peripheral may be "stuck" but likely due to code, not any hardware issue.

 

If you feel a post has answered your question, please click "Accept as Solution".
Tokit
Associate II

Thank you very much:smiling_face_with_smiling_eyes:. Because I've encountered similar situations before, and at that time, debugging with colleagues didn't identify the problem. We eventually concluded it was an issue with the STM32, so we compromised by using software I2C. Consequently, this time, without carefully checking the code, I mistakenly assumed it was an issue with the STM32 again. I apologize for the waste of resources due to my rookie mistake:slightly_frowning_face: