Hi,
i have problem with use multiple hardware timer, i get timer event for timer which is already retrigered.
Version is uTasker 1.4 for M5223X
Here is simplified example:
//this task is automaticaly called every 100ms
extern void fnMyLedControlTask(TTASKTABLE *ptrTaskTable)
{static int FirstInit=0;
if (FirstInit==0)//Only be proceed on first run
{
FirstInit=1;
uTaskerGlobalMonoTimer((UTASK_TASK)(TASK_MY_TIMEOUT_CHECK | HARDWARE_TIMER),(550*MILISEC),E_TIMEOUT_TEST);
}
uTaskerGlobalMonoTimer((UTASK_TASK)(TASK_MY_TIMEOUT_CHECK | HARDWARE_TIMER),(550*MILISEC),TIMEOUT_CHECK_WD_LED_CONTROL);
return ;
}
What i expect is that E_TIMEOUT_TEST will be called once and TIMEOUT_CHECK_WD_LED_CONTROL will never be called(because is retrigered every 100msec).
What i see is that both events is called:TIMEOUT_CHECK_WD_LED_CONTROL first and then E_TIMEOUT_TEST.
Note:The same code works well with SW timer
After some examination, i think that problem is in fnSetNewHWTimer function "GlobalTImer.c"
When another timer is running(with less or the same DelayTime) the actualy added timer variable is set to
ptrNewTimer->TimerDelay=(requestedDelay-CurrentHwTimerRemainingTime);
I think the right formula my be:
ptrNewTimer->TimerDelay=ActualHWTime->TimerDelay+(requestedDelay-CurrentHwTimerRemainingTime);
because when firing HW timer all timers has been decreased by FiredTimerActualHWTime->TimerDelay so for new(or retrigered value) there is need to add this value.
the dirty patch{i actualy used) is add Actualy running HW timer->TimerDelay to New->TimerDelay
like this:
+static TIMER_BLOCK *fnGetHWFired(void);
+
// Start hardware timer or queue the new timer
//
static void fnSetNewHWTimer(TIMER_BLOCK *ptrNewTimer) // {5} stop and adjust if retriggering HW monostable timer which is next to fire on its own
{
CLOCK_LIMIT adjusted;
uDisable_Interrupt();
if (fnCheckHWFirst(ptrNewTimer) != 0) { // if we are adjusting the active HW timer that would fire as next, and alone
........
}
else {
- uEnable_Interrupt();
+ TIMER_BLOCK *ptrFirstFired=0;
+ uEnable_Interrupt();
+ ptrFirstFired=fnGetHWFired();
+ ptrNewTimer->TimerDelay+=ptrFirstFired->TimerDelay;
}
adjusted = fnSetHardwareTimer(&ptrNewTimer->TimerDelay);
....
}
But i am not sure if this is correct.
Maybe also value which is compared in fnCheckHWFirst should be adjusted in some way.
P.S. I am sorry for my bad english