2024-03-17 04:13 AM
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.
On the first read operation, a STOP condition was automatically triggered after reading 6 bytes of data, which is normal.
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?
Solved! Go to Solution.
2024-03-17 08:04 AM
The reference manual will be the best resource for understanding the effect of the various register fields.
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.
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.
2024-03-17 08:04 AM
The reference manual will be the best resource for understanding the effect of the various register fields.
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.
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.
2024-03-17 08:39 AM
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: