116 lines
2.3 KiB
C
116 lines
2.3 KiB
C
#include <stdint.h>
|
|
#include <stm32f4xx.h>
|
|
#include <stdbool.h>
|
|
|
|
volatile uint32_t ISR_Ticks = 0;
|
|
|
|
struct TASK {
|
|
void (*fn)(void);
|
|
uint32_t counter;
|
|
uint32_t counter_rst;
|
|
};
|
|
|
|
uint8_t Tasks_len = 0;
|
|
struct TASK Tasks[8];
|
|
|
|
void SysTick_Handler()
|
|
{
|
|
ISR_Ticks++;
|
|
}
|
|
|
|
bool addTask(void (*fn)(void), uint32_t counter, uint32_t counter_init)
|
|
{
|
|
if (Tasks_len >= 8) {
|
|
return false;
|
|
}
|
|
Tasks[Tasks_len].fn = fn;
|
|
Tasks[Tasks_len].counter = counter_init;
|
|
Tasks[Tasks_len].counter_rst = counter;
|
|
Tasks_len++;
|
|
return true;
|
|
}
|
|
|
|
void taskGreen()
|
|
{
|
|
GPIOD->ODR ^= GPIO_ODR_OD12;
|
|
}
|
|
|
|
void taskOrange()
|
|
{
|
|
GPIOD->ODR ^= GPIO_ODR_OD13;
|
|
}
|
|
|
|
void taskRed()
|
|
{
|
|
GPIOD->ODR ^= GPIO_ODR_OD14;
|
|
}
|
|
|
|
void taskBlue()
|
|
{
|
|
GPIOD->ODR ^= GPIO_ODR_OD15;
|
|
}
|
|
|
|
enum STATE {
|
|
STATE_GREEN,
|
|
STATE_ORANGE,
|
|
STATE_RED
|
|
};
|
|
|
|
int main(void)
|
|
{
|
|
// GPIO Port D Clock Enable
|
|
RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN;
|
|
// GPIO Port D Pin 15 down to 12 Push/Pull Output
|
|
GPIOD->MODER = GPIO_MODER_MODER12_0
|
|
| GPIO_MODER_MODER13_0
|
|
| GPIO_MODER_MODER14_0
|
|
| GPIO_MODER_MODER15_0;
|
|
// Set all leds off
|
|
GPIOD->ODR = 0;
|
|
|
|
|
|
// SysTick enable with interupt and clk source to AHB/8
|
|
SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
|
|
SysTick->LOAD = 2000; // 1 ms / (16 MHz / 8)
|
|
|
|
addTask(*taskGreen, 200, 100);
|
|
addTask(*taskOrange, 500, 200);
|
|
addTask(*taskRed, 750, 300);
|
|
addTask(*taskBlue, 300, 400);
|
|
|
|
// Do forever:
|
|
while (1)
|
|
{
|
|
// Wait a moment
|
|
while (ISR_Ticks == 0)
|
|
{
|
|
__asm__(" WFI"); // sleep until SysTick
|
|
}
|
|
uint32_t ticks = ISR_Ticks;
|
|
ISR_Ticks = 0;
|
|
|
|
// decrement all counters
|
|
for (uint8_t i=0; i<Tasks_len; i++)
|
|
{
|
|
if (Tasks[i].counter > ticks)
|
|
{
|
|
Tasks[i].counter -= ticks;
|
|
}
|
|
else
|
|
{
|
|
Tasks[i].counter = 0;
|
|
}
|
|
}
|
|
|
|
// rust all tasks where the counter has run out
|
|
for (uint8_t i=0; i<Tasks_len; i++)
|
|
{
|
|
if (Tasks[i].counter == 0)
|
|
{
|
|
Tasks[i].fn();
|
|
Tasks[i].counter = Tasks[i].counter_rst;
|
|
}
|
|
}
|
|
}
|
|
}
|