cancel
Showing results for 
Search instead for 
Did you mean: 

I2C action from timer callback

sireevenkat1
Senior

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

 

1 ACCEPTED SOLUTION

Accepted Solutions

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...
}
...
If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

15 REPLIES 15
KnarfB
Principal III

"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

 

 

AScha.3
Chief II

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.

If you feel a post has answered your question, please click "Accept as Solution".

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

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

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 .

If you feel a post has answered your question, please click "Accept as Solution".
sireevenkat1
Senior

@AScha.3,

I will try the first suggestion and also 
If I want to use the  50us timer any suggestions.

Thanks

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...
}
...
If you feel a post has answered your question, please click "Accept as Solution".
sireevenkat1
Senior

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;
    }
    
}

 

 

Check and clear the flag that is triggering the TIM1 handler, otherwise it will continuously trigger. Look at how HAL_TIM_IRQHandler does it.

 

If you feel a post has answered your question, please click "Accept as Solution".