2015-06-25 03:17 PM
Greetings all,
I'm using the 1.6.0 release of the STM32F4xx_HAL_Driver, and I believe there's a problem with doing 1-byte I2C reads using the HAL_I2C_Master_Receive_IT function.Doing reads of more than one byte works fine:The user calls HAL_I2C_Master_Receive_IT
The I2C_EV_IRQn interrupt fires, which calls HAL_I2C_EV_IRQHandler
The HAL_I2C_EV_IRQHandler finds I2C_FLAG_MSL set (implying ''Master'' mode)
The event is processed by the ''Master'' portion of the HAL_I2C_EV_IRQHandler function
Once all bytes are read, the HAL_I2C_MasterRxCpltCallback function is invoked
The user calls HAL_I2C_Master_Receive_IT
The HAL_I2C_Master_Receive_IT function
sets I2C_CR1_STOP
(to stop after the first byte)The I2C_EV_IRQn interrupt fires, which calls HAL_I2C_EV_IRQHandler
The HAL_I2C_EV_IRQHandler
finds I2C_FLAG_MSL clear
(implying ''Slave'' mode)The event is processed by the ''Slave'' portion of the HAL_I2C_EV_IRQHandler function
The ''Slave'' portion of HAL_I2C_EV_IRQHandler cannot invoke HAL_I2C_MasterRxCpltCallback
I can't switch to the DMA version, as I'm out of DMA channels
I can't switch to the polling version, as this is a medical device with hard real-time requirements.
I can't just round up all 1-byte reads to 2 bytes as the part I'm talking to is intolerant to that kind of behavior.
2015-06-26 03:36 AM
Hello Malcolm,
Which external events may clear the MSL bit?In your case, please pay attention that there is no other interrupt with greater priority than I2C. It may cause a delay for ACK clear and STOP bit setting.-Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2015-07-10 05:14 AM
Hi Mayla,
The MSL can be cleared by a stop condition on the bus, or a loss of arbitration (ARLO=1), or by hardware when PE=0. This is described in the description of the MSL bit of I2C_SR2 in the reference manual (section 2.6.7).When the user calls HAL_I2C_Master_Receive_IT, it makes sense that the HAL will call back to the users HAL_I2C_MasterRxCpltCallback; however the HAL doesn't remember exactly what operation it's doing; instead it ''infers'' the type of operation that was in progress based on the I2C register states.The HAL only infers it's doing a ''Master'' operation if the ''MSL'' bit is set; but the MSL bit can be cleared for different reasons (Stop condition on the bus, loss of arbitration, or by hardware). As such if any of these events occur, the HAL forgets what type of operation it was doing.With regards to interrupt priorities; unfortunately I can't make the I2C the highest priority. I'm actually running 4x I2C ports, 4x SPI ports, 2x UARTs, Ethernet, USB, and an RTOS. The devices on the I2C bus are (from the systems perspective) the least important tasks in the system. The RTOS disables interrupts at certain points, and even then as I have four I2C devices I can't make every one of them the the highest priority interrupt.Many thanks,- Malcolm2015-07-13 04:26 AM
Hi nixon.malcolm,
A possible workaround is to set the STOP bit in the interrupt routine, not in HAL_I2C_Master_Receive_IT.This particular case (master receiver of a single byte) is under review and an official fix for the reported issue will be provided.-Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.