Hi !
Context/Plug : I program Smoothie ( http://smoothieware.org/ ), a CNC controller for LPC17xx ( incl. mbed ) boards that can control CNC mills, lasercutters, and 3D printers.
The project is based on gcc4mbed ( https://github.com/adamgreen/gcc4mbed ), and makes heavy use of the mBed libraries.
I've spent 4 days trying to debug a problem I'm having with Ticker and I think it's time to call for help :)
Basically the problem is that from time to time, Ticker will stop calling the handlers.
A bit info about the setup : I have 3 Tickers configured, two at 400hz and one at 5hz.
Also, I use Timer1 and Timer0. ( Timer1 is disabled when the bug occurs ). Priorities are set like this :
NVIC_SetPriority(TIMER3_IRQn, 4);
NVIC_SetPriority(TIMER0_IRQn, 2);
NVIC_SetPriority(TIMER1_IRQn, 3);
So Timer0 moves the motors ( sends step signals ), and Timer3 updates the speed at which it does that ( acceleration/deceleration ). ( Timer1 steps the extruder motor, but the bug occurs even when it's disabled ).
When the bug occurs, the speed stops being updated ( the Ticker handler stops being called ), and Timer0 continues stepping at a constant speed. After a while ( may be quite long depending on the speed ), it goes back to normal.
So I've started debugging the values of LPC_TIM3->MR0 and TC from the Timer0 handler. The way I understand how it works ( what I observe when the bug does not occur ) is :
TC increments continuously ( no reset ), when it matches MR0 the interrupt is called, MR0 is incremented by 2500, handlers are called if needed, then we wait for the next match.
Now I think the bug is occuring when the Timer3 handler is interrupted by Timer0, thus taking too much time, and thus having TC > MR0 + 2500 after the end of the handler. But that does not cause the bug every time.
I've put a bit of code, executed inside Timer0, to see what Timer3 does :
printf("tc(%u) mr0(%u) diff(%d) pending:%u \r\n", LPC_TIM3->TC, LPC_TIM3->MR0, int(LPC_TIM3->MR0) - int(LPC_TIM3->TC), ( NVIC->ISPR[0] & ( 1<<4 ) ) );
This outputs ( bug not occuring ):
tc(396225035) mr0(396225000) -35 pending:16
tc(396282688) mr0(396285000) 2312 pending:0
tc(396296647) mr0(396296459) -189 pending:0
tc(396446673) mr0(396445000) -1674 pending:16
tc(396468532) mr0(396445000) -23533 pending:16
tc(396474138) mr0(396450000) -24139 pending:0
tc(396479083) mr0(396455000) -24084 pending:0
tc(396484028) mr0(396460000) -24029 pending:0
tc(396488959) mr0(396482500) -6460 pending:0
tc(396493804) mr0(396495000) 1195 pending:0
tc(396498563) mr0(396497500) -1064 pending:0
Now what happens ( mostly, I'm not sure why it's not always that way, maybe the printfs are messing with it ), is that when TC > MR0, the interrupt is made pending, and called. MR0 is incremented, and everybody is happy.
Now from time to time, Timer0 takes longer than usual ( longer than 2500 ), and interrupts Timer3 when doing so, and so Timer3 takes longer than 2500 ( here 25000 ). But in this example, it does not disrupt the process, MR0 keeps on being incremented.
When the bug occurs, on the other hand, M0 stops being incremented, and I think that's what's causing the problem :
tc(401787404) mr0(401787500) 96 pending:0
tc(402016942) mr0(402017500) 557 pending:0
tc(402296701) mr0(402284451) -12251 pending:0
tc(402446942) mr0(402284451) -162492 pending:0
tc(402469066) mr0(402284451) -184616 pending:0
tc(402504306) mr0(402284451) -219856 pending:0
tc(402561230) mr0(402284451) -276780 pending:0
tc(402618154) mr0(402284451) -333704 pending:0
tc(402675063) mr0(402284451) -390613 pending:0
tc(402731987) mr0(402284451) -447537 pending:0
tc(402788911) mr0(402284451) -504460 pending:0
So the same thing happens ( I'm guessing that Timer3 takes too long to execute, possibly because it's interrupted by a long Timer0 interrupt ), but now MR0 steps being incremented !
So Timer3 stops calling the handler, and the program stops working correctly.
Anyone has some idea of how to fix this ?
( I can't have Timer0 not last more than 2500, it has to do so from time to time, that's from design ).
Thank you very much in advance for your help.
And a happy new year :)
Hi !
Context/Plug : I program Smoothie ( http://smoothieware.org/ ), a CNC controller for LPC17xx ( incl. mbed ) boards that can control CNC mills, lasercutters, and 3D printers. The project is based on gcc4mbed ( https://github.com/adamgreen/gcc4mbed ), and makes heavy use of the mBed libraries.
I've spent 4 days trying to debug a problem I'm having with Ticker and I think it's time to call for help :)
Basically the problem is that from time to time, Ticker will stop calling the handlers.
A bit info about the setup : I have 3 Tickers configured, two at 400hz and one at 5hz. Also, I use Timer1 and Timer0. ( Timer1 is disabled when the bug occurs ). Priorities are set like this :
So Timer0 moves the motors ( sends step signals ), and Timer3 updates the speed at which it does that ( acceleration/deceleration ). ( Timer1 steps the extruder motor, but the bug occurs even when it's disabled ). When the bug occurs, the speed stops being updated ( the Ticker handler stops being called ), and Timer0 continues stepping at a constant speed. After a while ( may be quite long depending on the speed ), it goes back to normal.
So I've started debugging the values of LPC_TIM3->MR0 and TC from the Timer0 handler. The way I understand how it works ( what I observe when the bug does not occur ) is : TC increments continuously ( no reset ), when it matches MR0 the interrupt is called, MR0 is incremented by 2500, handlers are called if needed, then we wait for the next match.
Now I think the bug is occuring when the Timer3 handler is interrupted by Timer0, thus taking too much time, and thus having TC > MR0 + 2500 after the end of the handler. But that does not cause the bug every time.
I've put a bit of code, executed inside Timer0, to see what Timer3 does :
This outputs ( bug not occuring ):
Now what happens ( mostly, I'm not sure why it's not always that way, maybe the printfs are messing with it ), is that when TC > MR0, the interrupt is made pending, and called. MR0 is incremented, and everybody is happy. Now from time to time, Timer0 takes longer than usual ( longer than 2500 ), and interrupts Timer3 when doing so, and so Timer3 takes longer than 2500 ( here 25000 ). But in this example, it does not disrupt the process, MR0 keeps on being incremented.
When the bug occurs, on the other hand, M0 stops being incremented, and I think that's what's causing the problem :
So the same thing happens ( I'm guessing that Timer3 takes too long to execute, possibly because it's interrupted by a long Timer0 interrupt ), but now MR0 steps being incremented ! So Timer3 stops calling the handler, and the program stops working correctly.
Anyone has some idea of how to fix this ? ( I can't have Timer0 not last more than 2500, it has to do so from time to time, that's from design ).
Thank you very much in advance for your help. And a happy new year :)