10 #if !defined(__AVR_ATmega2560__) && !defined(__AVR_ATmega328P__) && !defined(__SAM3X8E__)
11 #error board not supported, error
22 #define SET_PIN (PORTB |= B00000010)
23 #define CLEAR_PIN (PORTB &= ~B00000010)
24 #define TOGGLE_PIN (PORTB ^= B00000010)
29 typedef struct SchedulingStruct
41 bool SchedulingActive;
46 #if defined(__SAM3X8E__)
60 void startTasksTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency)
62 pmc_set_writeprotect(
false);
63 pmc_enable_periph_clk((uint32_t)irq);
64 TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
65 uint32_t rc = (SystemCoreClock >> 1)/frequency;
67 TC_SetRC(tc, channel, rc);
68 TC_Start(tc, channel);
69 tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
70 tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
71 NVIC_SetPriority(SysTick_IRQn, 8);
72 NVIC_SetPriority(irq, 15);
78 void Scheduler_update_nexttime(
void)
81 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
82 uint8_t oldSREG = SREG;
83 #elif defined(__SAM3X8E__)
84 uint8_t enableInterrupts = ((__get_PRIMASK() & 0x1) == 0 && (__get_FAULTMASK() & 0x1) == 0);
89 int16_t _min = INT16_MAX;
91 if ((SchedulingTable[i].func != NULL) && (SchedulingTable[i].active ==
true)) {
92 int16_t tmp = (int16_t)(SchedulingTable[i].time - _timebase);
93 if ((tmp >= 0) && (tmp < _min)) {
95 _nexttime = SchedulingTable[i].time;
101 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
103 #elif defined(__SAM3X8E__)
104 if (enableInterrupts)
122 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
123 uint8_t oldSREG = SREG;
124 #elif defined(__SAM3X8E__)
125 uint8_t enableInterrupts = ((__get_PRIMASK() & 0x1) == 0 && (__get_FAULTMASK() & 0x1) == 0);
130 SchedulingActive =
false;
132 _nexttime = INT16_MAX;
136 SchedulingTable[i].func = NULL;
137 SchedulingTable[i].active =
false;
138 SchedulingTable[i].running =
false;
139 SchedulingTable[i].period = 0;
140 SchedulingTable[i].time = 0;
144 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
146 #elif defined(__SAM3X8E__)
147 if (enableInterrupts)
157 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
159 #elif defined(__SAM3X8E__)
160 uint8_t enableInterrupts = 0;
164 if ((period < 0) || (delay < 0))
168 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
169 delay = (uint16_t)(((((int32_t)delay) * 250) + 128) >> 8);
170 period = (uint16_t)(((((int32_t)period) * 250) + 128) >> 8);
177 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
179 #elif defined(__SAM3X8E__)
180 enableInterrupts = ((__get_PRIMASK() & 0x1) == 0 && (__get_FAULTMASK() & 0x1) == 0);
185 if (SchedulingTable[i].func == func)
187 SchedulingTable[i].active =
true;
188 SchedulingTable[i].running =
false;
189 SchedulingTable[i].period = period;
190 SchedulingTable[i].time = _timebase + delay;
193 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
195 #elif defined(__SAM3X8E__)
196 if (enableInterrupts)
201 Scheduler_update_nexttime();
208 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
210 #elif defined(__SAM3X8E__)
211 if (enableInterrupts)
221 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
223 #elif defined(__SAM3X8E__)
224 enableInterrupts = ((__get_PRIMASK() & 0x1) == 0 && (__get_FAULTMASK() & 0x1) == 0);
229 if (SchedulingTable[i].func == NULL)
232 SchedulingTable[i].func = func;
233 SchedulingTable[i].active =
true;
234 SchedulingTable[i].running =
false;
235 SchedulingTable[i].period = period;
236 SchedulingTable[i].time = _timebase + delay;
239 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
241 #elif defined(__SAM3X8E__)
242 if (enableInterrupts)
247 Scheduler_update_nexttime();
255 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
257 #elif defined(__SAM3X8E__)
258 if (enableInterrupts)
265 Scheduler_update_nexttime();
276 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
278 #elif defined(__SAM3X8E__)
279 uint8_t enableInterrupts = 0;
286 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
288 #elif defined(__SAM3X8E__)
289 enableInterrupts = ((__get_PRIMASK() & 0x1) == 0 && (__get_FAULTMASK() & 0x1) == 0);
294 if (SchedulingTable[i].func == func)
297 SchedulingTable[i].func = NULL;
298 SchedulingTable[i].active =
false;
299 SchedulingTable[i].running =
false;
300 SchedulingTable[i].period = 0;
301 SchedulingTable[i].time = 0;
304 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
306 #elif defined(__SAM3X8E__)
307 if (enableInterrupts)
312 Scheduler_update_nexttime();
320 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
322 #elif defined(__SAM3X8E__)
323 if (enableInterrupts)
330 Scheduler_update_nexttime();
341 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
343 #elif defined(__SAM3X8E__)
344 uint8_t enableInterrupts = 0;
352 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
353 delay = (uint16_t)(((((int32_t)delay) * 250) + 128) >> 8);
360 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
362 #elif defined(__SAM3X8E__)
363 enableInterrupts = ((__get_PRIMASK() & 0x1) == 0 && (__get_FAULTMASK() & 0x1) == 0);
368 if (SchedulingTable[i].func == func)
371 if (SchedulingTable[i].running ==
true)
372 SchedulingTable[i].time = SchedulingTable[i].time - SchedulingTable[i].period;
375 SchedulingTable[i].time = _timebase + delay;
378 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
380 #elif defined(__SAM3X8E__)
381 if (enableInterrupts)
386 Scheduler_update_nexttime();
394 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
396 #elif defined(__SAM3X8E__)
397 if (enableInterrupts)
404 Scheduler_update_nexttime();
415 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
417 #elif defined(__SAM3X8E__)
418 uint8_t enableInterrupts = 0;
425 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
427 #elif defined(__SAM3X8E__)
428 enableInterrupts = ((__get_PRIMASK() & 0x1) == 0 && (__get_FAULTMASK() & 0x1) == 0);
433 if (SchedulingTable[i].func == func)
436 if (SchedulingTable[i].active ==
false)
438 SchedulingTable[i].active =
true;
439 SchedulingTable[i].time = _timebase + SchedulingTable[i].period;
443 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
445 #elif defined(__SAM3X8E__)
446 if (enableInterrupts)
451 Scheduler_update_nexttime();
459 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
461 #elif defined(__SAM3X8E__)
462 if (enableInterrupts)
468 Scheduler_update_nexttime();
479 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
481 #elif defined(__SAM3X8E__)
482 uint8_t enableInterrupts = 0;
489 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
491 #elif defined(__SAM3X8E__)
492 enableInterrupts = ((__get_PRIMASK() & 0x1) == 0 && (__get_FAULTMASK() & 0x1) == 0);
497 if (SchedulingTable[i].func == func)
500 SchedulingTable[i].active =
false;
501 SchedulingTable[i].time = _timebase + SchedulingTable[i].period;
504 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
506 #elif defined(__SAM3X8E__)
507 if (enableInterrupts)
512 Scheduler_update_nexttime();
520 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
522 #elif defined(__SAM3X8E__)
523 if (enableInterrupts)
529 Scheduler_update_nexttime();
545 SchedulingActive =
true;
548 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
549 TIMSK0 |= (1<<OCIE0A);
550 #elif defined(__SAM3X8E__)
551 startTasksTimer(TC1, 0, TC3_IRQn, 1000);
555 Scheduler_update_nexttime();
564 SchedulingActive =
false;
567 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
568 TIMSK0 &= ~(1<<OCIE0A);
569 #elif defined(__SAM3X8E__)
570 NVIC_DisableIRQ(TC3_IRQn);
582 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
583 ISR(TIMER0_COMPA_vect)
584 #elif defined(__SAM3X8E__)
585 void TC3_Handler(
void)
587 void Scheduler_dummy_handler(
void)
597 #if defined(__SAM3X8E__)
598 TC_GetStatus(TC1, 0);
602 if (SchedulingActive ==
false) {
603 #if (MEASURE_PIN) // measure speed via GPIO
613 if ((int16_t)(_nexttime - _timebase) > 0) {
614 #if (MEASURE_PIN) // measure speed via GPIO
624 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
626 #elif defined(__SAM3X8E__)
627 NVIC_DisableIRQ(TC3_IRQn);
631 if ((SchedulingTable[i].func != NULL) && (SchedulingTable[i].active ==
true))
634 if (SchedulingTable[i].running ==
false)
637 if ((int16_t)(SchedulingTable[i].time - _timebase) <= 0)
640 SchedulingTable[i].running =
true;
641 SchedulingTable[i].time = _timebase + SchedulingTable[i].period;
644 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
646 #elif defined(__SAM3X8E__)
647 NVIC_EnableIRQ(TC3_IRQn);
651 SchedulingTable[i].func();
654 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
656 #elif defined(__SAM3X8E__)
657 NVIC_DisableIRQ(TC3_IRQn);
661 SchedulingTable[i].running =
false;
664 if (SchedulingTable[i].period == 0)
665 SchedulingTable[i].func = NULL;
668 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
670 #elif defined(__SAM3X8E__)
671 NVIC_EnableIRQ(TC3_IRQn);
681 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
683 #elif defined(__SAM3X8E__)
684 NVIC_EnableIRQ(TC3_IRQn);
690 Scheduler_update_nexttime();
void Scheduler_Start(void)
Start the task scheduler.
Library providing a simple task scheduler for multitasking.
#define MAX_TASK_CNT
Maximum number of parallel tasks.
bool Scheduler_Task_Add(Task func, int16_t period, int16_t delay)
Add a task to the task scheduler.
bool Scheduler_Task_Remove(Task func)
Remove a task from the task scheduler.
bool Scheduler_Task_Pause(Task func)
Deactivate a task in the scheduler.
void(* Task)(void)
Example prototype for a function than can be executed as a task.
bool Scheduler_Task_Start(Task func)
Activate a task in the scheduler.
bool Scheduler_Task_Delay(Task func, int16_t delay)
Delay execution of a task.
void Scheduler_Init(void)
Initialize and reset the tasks library.
void Scheduler_Pause(void)
Pause the task scheduler.