2023-12-27 09:30 PM - last edited on 2023-12-28 03:26 AM by SofLit
Hi,
I am working with STM32G4 and I have problem reading/writing the I2C data with in the timer callback.
I have Timer1 calling my interrupt callback every 50 microseconds which is working well.
I have I2C read/write functions which are working well.I2C is not Interrupt based.
The problem occur while reading/writing the I2C data within the timer callback
I am unable to read/write the I2C data in the timer interrupt callback
Below is the timer callback
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim == &htim1)
{
if(dcheck.flagon_2sec1){
dcount.s_2_sec1++;
if(dcount.s_2_sec1==40000){
delay.flag_2sec1 = 1;
expander_read(&hmcp,REGISTER_INPUT,data);
dcount.s_2_sec1=0;
dcheck.flagon_2sec1=0;
}
}
}
}
Normal I2C read/write working but with in the timer callback its not working.
Can anyone suggest.
Thanks
Solved! Go to Solution.
2023-12-28 02:00 AM
When only using 50us timer, i would make a simple counter in the INT and set a global (volatile) variable, to start the i2c command.
volatile int aa, start_i2c = 0 ;
in INT:
aa++;
if (aa>2000) {aa=0; start_i2c = 1; }
in main loop then:
...
if(start_i2c==1)
{
start_i2c=0;
... >> do i2c things...
}
...
2023-12-27 11:50 PM
"not working" is a very vague description, be more precise what happens.
Same with expander_read which probably nobody except you has ever heard of.
Note that the callbacks run in handler mode, which may prevert other interrupts from running depending on priority... settings. Such as another timer that may not tick while in the callback.
hth
KnarfB
2023-12-28 12:32 AM
Hi,
50us - really ?? In this time you can send on standard I2C about 5 bit , on hi-speed I2C (400kHz) two bytes ...
No useful setting, simply said.
First calculate, how many byte you want to transfer on I2C , at 100 or 400kHz, then add some "free" time for the cpu (to do anything else than I2C), so you get the useful/possible timer setting.
2023-12-28 01:12 AM - edited 2023-12-28 01:14 AM
Hi @KnarfB,
1.I am interfacing IO expander with STM32G4
Same with expander_read which probably nobody except you has ever heard of.
expander_read(&hmcp,REGISTER_INPUT,data);
This will read the input register of expander and data present in the input register will be saved to data variable.
2.
"not working" is a very vague description, be more precise what happens.
While debugging I found that its entering into the timer callback 2sec delay check but its not reading the io expander input register. I changed the read operation with io expander output register write .I can't able to read/write in the timer callback.
If I do the same operation other than timer callback its working.
3.For I2C I am not using interrupt to give the priority.
4.IO expander driver reference .I took this as reference for my IO expander driver development. Its working well other than timer callback
Please suggest.
Thanks
2023-12-28 01:23 AM
Hi @AScha.3 ,
I thought of using same timer callback for all delay requirements.
In my application 50us delay required for high priority operation that's why I took 50 usec delay.
I checked for 50us ,800 usec delays in other functions(related to PWM/ADC ) they are working fine.
But for I2C communication(read/write) not working with in the timer callback.
I need to do i2c read& write after 2sec and 100 msec delays. Its not working.
1.Can I take other timer interrupt with less time?
2.For read I need to read 8 bit register and for write I need to write 8 bits data.
Please suggest
Thanks
2023-12-28 01:33 AM
1: If your i2c tx/rx needs not to be "sync" to the 50us timer (anyway almost impossible) use other timer with making 100ms delay or whatever, or set it with trigger from your 50us timer, counting 2000 triggers -> 100ms (almost sync to the 50us event )
2: ok . At 100ms or 2s interval i see no problem with using the i2c .
2023-12-28 01:42 AM
@AScha.3,
I will try the first suggestion and also
If I want to use the 50us timer any suggestions.
Thanks
2023-12-28 02:00 AM
When only using 50us timer, i would make a simple counter in the INT and set a global (volatile) variable, to start the i2c command.
volatile int aa, start_i2c = 0 ;
in INT:
aa++;
if (aa>2000) {aa=0; start_i2c = 1; }
in main loop then:
...
if(start_i2c==1)
{
start_i2c=0;
... >> do i2c things...
}
...
2023-12-28 04:35 AM
Hi @AScha.3 ,
I tried above way but after expander_write execution not going inside if loop.
aa++;
if (aa > 40000) {
aa = 0;
start_i2c = 1;
}
previously same logic I checked inside HAL_TIM_PeriodElapsedCallback()
that time execution not going inside the if loop.
volatile int aa, start_i2c = 0 ;
function_on(){
expander_write_GPIO(&hmcp ,HIGH);
if(start_i2c){
start_i2c=0;
tca9537_write_gpio(&hmcp ,TCA9537_OUTPUT_IO12_HIGH);
}
}
void TIM1_IRQHandler(void) {
aa++;
if (aa > 40000) {
aa = 0;
start_i2c = 1;
}
}
2023-12-28 06:16 AM
Check and clear the flag that is triggering the TIM1 handler, otherwise it will continuously trigger. Look at how HAL_TIM_IRQHandler does it.