2020-06-16 08:28 AM
Program code all generated with STM32CubeIDE 1.3.1 Build 6291_20200406_0752 (with STMCube F0 v 1.11)
Program uses I2C1 on STM32030CC using AF1 GPIOB pin 6 and 7 and reads data from an HTU2X via interrupt based transfer.
First it select the register :
HAL_I2C_Master_Transmit_IT(&hi2c1, 0x40 << 1, aTxBuffer, 1);
after that a wait loop seems needed to wait for
HAL_I2C_MasterTxCpltCallback
to be called. The wait loop is
HAL_Delay(40);
After that
HAL_I2C_Master_Receive_IT(&hi2c1, 0x40 << 1, aRxBuffer, 3);
which waits for
HAL_I2C_MasterRxCpltCallback()
to be called. After that no additional delay seems to be needed.
The issue is, going below 40msec the HAL_I2C_Master_Receive_IT( fails (no IRQ) and going even lower to about 20msec, HAL_I2C_MasterTxCpltCallback does not get called, This is all very consistent and reproducable. Above about 40msec there are no such issues.
Running this with 40msec result in about 22 successful transactions per second which is quite slow
Why is such a long delay time needed and why is the TX CB not called when shorter time is used and is there a way to speed this up ?
One a side note: It seems that the HAL library functions for the same MCU changes over time, (example I2C1_IRQHandler) so it's hard to reference other code on the web using the exact same function calls especially when using the newer HAL libraries.
Solved! Go to Solution.
2020-06-17 07:55 AM
Hi Thanks a lot. Just completed to figured this out. The HTU21D has two modes, One is E3 and the other F3. I was using F3 which is non-block mode and that results in NACKS when the device is not ready (and would need retries to read). Now added the error callback so that I can detect NACKS and moved to E3 mode which hold SCL low during conversion (not ready) until the conversion is complete, only after that reading the data. Removed all HAL_Delays. The device's conversion time is about 16msec and at best i could get 1300 conversion/min (not the theoretical 3750 @ ~16msec/conversion) which may be due to the speed of the code exection and other overhead code. Bottom line, It seems this was device specific.
2020-06-16 09:24 AM
Observe the I2C bus using oscilloscope/logic analyzer.
JW
2020-06-16 08:29 PM
Thanks, will do, but what to look for ? HAL_I2C_Master_Transmit_IT(&hi2c1, 0x40 << 1, aTxBuffer, 1); returns with OK almost immediately. if the HAL_Delay is made shorter, the callback appears not to be occurring After HALDelay the code waits indefinitely for a flag set by the callback. While (!txflag) ... (which flag was reset before the Transmit call) What could this indicate ? I assumed the callback should happen sooner or later no matter the HAL_delay (even if no delay at all was used). I am trying to understand how the transaction on the bus relates to the HAL delay ?
Edit: Bumped onto this but not sure if it's the cause. since I am not caling HAL_Delay from the ISR.
Care must be taken when using HAL_Delay(), this function provides accurate delay (in milliseconds) based on variable incremented in SysTick ISR. This implies that if HAL_Delay() is called from a peripheral ISR process, then the SysTick interrupt must have higher priority (numerically lower) than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
Side note for this code: Noticed the ISR
void I2Cx_IRQHandler(void) { HAL_I2C_EV_IRQHandler(&I2cHandle);
HAL_I2C_ER_IRQHandler(&I2cHandle); }
Which is different from the CubeIDE generated code which uses HAL_I2C_IRQHandler(&I2cHandle); Whiuch would indicate Cube libraries and sample code may not be backward compatible with IDE generated code
2020-06-17 12:22 AM
I am not going to comment on Cube/HAL/CubeMX, I don't use them. You debug them as you do with your own code.
What I was trying to say was, that transmitting one byte on any reasonable I2C speed should take below 1ms, so if delays of tens of ms make significant difference, then something is maybe fundamentally broken and you perhaps see secondary effects of some timeouts.
JW
2020-06-17 07:55 AM
Hi Thanks a lot. Just completed to figured this out. The HTU21D has two modes, One is E3 and the other F3. I was using F3 which is non-block mode and that results in NACKS when the device is not ready (and would need retries to read). Now added the error callback so that I can detect NACKS and moved to E3 mode which hold SCL low during conversion (not ready) until the conversion is complete, only after that reading the data. Removed all HAL_Delays. The device's conversion time is about 16msec and at best i could get 1300 conversion/min (not the theoretical 3750 @ ~16msec/conversion) which may be due to the speed of the code exection and other overhead code. Bottom line, It seems this was device specific.