cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F030CC I2C master needs a long delay for interrupt based transmit

debugging
Senior III

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.

1 ACCEPTED SOLUTION

Accepted Solutions
debugging
Senior III

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.

View solution in original post

4 REPLIES 4

Observe the I2C bus using oscilloscope/logic analyzer.

JW

debugging
Senior III

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.

https://github.com/STMicroelectronics/STM32CubeF0/blob/master/Projects/STM32F030R8-Nucleo/Examples/I2C/I2C_TwoBoards_AdvComIT/Src/stm32f0xx_it.c

 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

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

debugging
Senior III

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.