11 #if !defined(__AVR__) && !defined(__SAM3X8E__)
12 #error board not supported, error
22 #define TASKS_MEASURE_PIN 0
23 #if (TASKS_MEASURE_PIN)
24 #define SET_PIN (PORTB |= B00000010)
25 #define CLEAR_PIN (PORTB &= ~B00000010)
26 #define TOGGLE_PIN (PORTB ^= B00000010)
33 #define PAUSE_INTERRUPTS { oldISR = SREG; noInterrupts(); }
34 #define RESUME_INTERRUPTS { SREG = oldISR; interrupts(); }
35 #elif defined(__SAM3X8E__)
36 #define PAUSE_INTERRUPTS { oldISR = ((__get_PRIMASK() & 0x1) == 0 && (__get_FAULTMASK() & 0x1) == 0); noInterrupts(); }
37 #define RESUME_INTERRUPTS { if (oldISR != 0) { interrupts(); } }
42 struct SchedulingStruct
53 struct SchedulingStruct SchedulingTable[
MAX_TASK_CNT] = { {(
Task)NULL,
false,
false, 0, 0} };
54 bool SchedulingActive;
60 #if defined(__SAM3X8E__)
74 void startTasksTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency)
76 pmc_set_writeprotect(
false);
77 pmc_enable_periph_clk((uint32_t)irq);
78 TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
79 uint32_t rc = (SystemCoreClock >> 1)/frequency;
81 TC_SetRC(tc, channel, rc);
82 TC_Start(tc, channel);
83 tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
84 tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
85 NVIC_SetPriority(SysTick_IRQn, 8);
86 NVIC_SetPriority(irq, 15);
92 void Scheduler_update_nexttime(
void)
98 _nexttime = _timebase + INT16_MAX;
99 for (uint8_t i = 0; i < _lasttask; i++)
101 if ((SchedulingTable[i].active ==
true) && (SchedulingTable[i].func != NULL))
105 if ((int16_t)(SchedulingTable[i].time - _nexttime) < 0)
107 _nexttime = SchedulingTable[i].time;
152 SchedulingActive =
false;
159 SchedulingTable[i].func = NULL;
160 SchedulingTable[i].active =
false;
161 SchedulingTable[i].running =
false;
162 SchedulingTable[i].period = 0;
163 SchedulingTable[i].time = 0;
176 if ((period < 0) || (delay < 0))
181 delay = (uint16_t)(((((int32_t)delay) * 250) + 128) >> 8);
182 period = (uint16_t)(((((int32_t)period) * 250) + 128) >> 8);
186 for(uint8_t i = 0; i < _lasttask; i++)
192 if (SchedulingTable[i].func == func)
194 SchedulingTable[i].active =
true;
195 SchedulingTable[i].running =
false;
196 SchedulingTable[i].period = period;
197 SchedulingTable[i].time = _timebase + delay;
203 Scheduler_update_nexttime();
221 if (SchedulingTable[i].func == NULL)
224 SchedulingTable[i].func = func;
225 SchedulingTable[i].active =
true;
226 SchedulingTable[i].running =
false;
227 SchedulingTable[i].period = period;
228 SchedulingTable[i].time = _timebase + delay;
238 Scheduler_update_nexttime();
261 for (uint8_t i = 0; i < _lasttask; i++)
267 if (SchedulingTable[i].func == func)
270 SchedulingTable[i].func = NULL;
271 SchedulingTable[i].active =
false;
272 SchedulingTable[i].running =
false;
273 SchedulingTable[i].period = 0;
274 SchedulingTable[i].time = 0;
277 if (i == (_lasttask - 1))
280 while(_lasttask != 0)
282 if(SchedulingTable[_lasttask - 1].func != NULL)
294 Scheduler_update_nexttime();
322 delay = (uint16_t)(((((int32_t)delay) * 250) + 128) >> 8);
326 for (uint8_t i = 0; i < _lasttask; i++)
332 if (SchedulingTable[i].func == func)
335 if (SchedulingTable[i].running ==
true)
336 SchedulingTable[i].time = SchedulingTable[i].time - SchedulingTable[i].period;
339 SchedulingTable[i].time = _timebase + delay;
345 Scheduler_update_nexttime();
368 for (uint8_t i = 0; i < _lasttask; i++)
374 if(SchedulingTable[i].func == func)
377 SchedulingTable[i].active = state;
378 SchedulingTable[i].time = _timebase + SchedulingTable[i].period;
384 Scheduler_update_nexttime();
406 #if (TASKS_MEASURE_PIN)
411 SchedulingActive =
true;
414 _nexttime = _timebase;
418 TIMSK0 |= (1<<OCIE0A);
419 #elif defined(__SAM3X8E__)
420 startTasksTimer(TC1, 0, TC3_IRQn, 1000);
424 Scheduler_update_nexttime();
433 SchedulingActive =
false;
438 TIMSK0 &= ~(1<<OCIE0A);
439 #elif defined(__SAM3X8E__)
440 NVIC_DisableIRQ(TC3_IRQn);
453 ISR(TIMER0_COMPA_vect)
454 #elif defined(__SAM3X8E__)
455 void TC3_Handler(
void)
457 void Scheduler_dummy_handler(
void)
463 #if (TASKS_MEASURE_PIN)
467 #if defined(__SAM3X8E__)
468 TC1->TC_CHANNEL[0].TC_SR;
472 if (SchedulingActive ==
false) {
473 #if (TASKS_MEASURE_PIN) // measure speed via GPIO
483 if ((int16_t)(_nexttime - _timebase) > 0) {
484 #if (TASKS_MEASURE_PIN) // measure speed via GPIO
491 for(i = 0; i < _lasttask; i++)
497 if ((SchedulingTable[i].active ==
true) && (SchedulingTable[i].running ==
false) && (SchedulingTable[i].func != NULL))
500 if((int16_t)(SchedulingTable[i].time - _timebase) <= 0)
503 SchedulingTable[i].running =
true;
504 SchedulingTable[i].time = _timebase + SchedulingTable[i].period;
510 SchedulingTable[i].func();
516 SchedulingTable[i].running =
false;
519 if(SchedulingTable[i].period == 0)
521 SchedulingTable[i].func = NULL;
535 Scheduler_update_nexttime();
538 #if (TASKS_MEASURE_PIN)
void(* Task)(void)
Example prototype for a function than can be executed as a task.
void Tasks_Pause(void)
Pause the task scheduler.
void Tasks_Start(void)
Start the task scheduler.
bool Tasks_SetState(Task func, bool state)
Enable or disable the execution of a task.
bool Tasks_Add(Task func, int16_t period, int16_t delay)
Add a task to the task scheduler.
#define MAX_TASK_CNT
Maximum number of parallel tasks.
void Tasks_Init(void)
Initialize timer and reset the tasks scheduler at first call.
bool Tasks_Delay(Task func, int16_t delay)
Delay execution of a task.
Library providing a simple task scheduler for multitasking.
void Tasks_Clear(void)
Reset the tasks schedulder.
bool Tasks_Remove(Task func)
Remove a task from the task scheduler.