2024-02-03 12:14 PM
I have an STM32WB design using I2C to get 6 bytes from a BMI0888 every 50ms (triggered by an external interrupt). The interrupt sets a flag in my main loop to go get the data. The devices first requires you to write the desired register, then read the 6 bytes. If I use back to back calls to HAL_I2C_Master_Transmit followed by HAL_I2C_Master_Receive, it works great. See figure 1 below. That will happen every 50ms.
I am now trying to do this using the interrupt versions of the functions. If I try and use HAL_I2C_Master_Transmit_IT and HAL_I2C_Master_Transmit_IT. I again use flags to inform my main loop what to do. The external interrupt flags the loop to perform the transmit, then the HAL_I2C_MasterTxCpltCallback informs the main loop to perform the receive, and then HAL_I2C_MasterRxCpltCallback tells the main loop the data is ready. I get all of these interrupts, however the data isn't actually read. See figure 2 below where SCL stops high.
Blocking:
Interrupt:
2024-02-06 04:17 PM - edited 2024-02-06 04:21 PM
I traced the execution of this and found where it's failing, but I don't know why.
status = HAL_I2C_Master_Transmit_IT (
&hi2c1, ACC_ADDR,
®Addr, 1);
status = HAL_I2C_Master_Receive_IT(
&hi2c1,
ACC_ADDR,
buffer,
6);
while(1)
{ }
I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
/* Remove RXNE flag on temporary variable as read done */
tmpITFlags &= ~I2C_FLAG_RXNE;
/* Read data from RXDR */
*hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
/* Increment Buffer pointer */
hi2c->pBuffPtr++;
hi2c->XferSize--;
hi2c->XferCount--;
2024-02-08 02:59 PM
Another example. Every blocking read here works fine, but the IT version hangs SCL low.
uint8_t regAddr = BMI_ACC_DATA;
uint8_t status = 1;
status = HAL_I2C_Master_Transmit (
&hi2c1, ACC_ADDR,
®Addr, 1, 1000);
status = HAL_I2C_Master_Receive(
&hi2c1,
ACC_ADDR,
buffer,
6, 1000);
status = HAL_I2C_Master_Receive(
&hi2c1,
ACC_ADDR,
buffer,
6, 1000);
status = HAL_I2C_Master_Receive(
&hi2c1,
ACC_ADDR,
buffer,
6, 1000);
status = HAL_I2C_Master_Receive_IT(
&hi2c1,
ACC_ADDR,
buffer,
6);
while(1)
{
}
2024-02-08 03:17 PM
The manual describes this exact behavior is RXDR isn't read. Specifically that SCL will stretch between and 8th and 9th bit. However I am seeing the callback in the hal read from RXDR yet nothing happens on the line: