--- sub_title: "Real Time Systems 10" auther: - name: "Finley van Reenen" email: "mail@lailatheelf.nl" name_short: "E.L.F. van Reenen" --- # Week 1.3 ## assignment 3.1 base project [opdr_2_1](/assets/opdr_2_1.zip). ```c #include #define RCC_AHB1ENR_BIT_GPIODEN *(volatile uint32_t*)(0x42000000 + 0x00023830 * 32 + 3 * 4) #define GPIOD_BASE 0x40020C00 #define GPIOD_MODER *(volatile uint32_t*)(GPIOD_BASE + 0x00) #define GPIOD_ODR *(volatile uint32_t*)(GPIOD_BASE + 0x14) #define STK_CTRL *(volatile uint32_t*)(0xE000E010) #define STK_LOAD *(volatile uint32_t*)(0xE000E014) int main(void) { // GPIO Port D Clock Enable RCC_AHB1ENR_BIT_GPIODEN = 1; // GPIO Port D Pin 15 down to 12 Push/Pull Output GPIOD_MODER = 0x55000000; // Set green and red LEDs GPIOD_ODR = 0x5000; // SysTick enable with clk source to AHB/8 STK_CTRL = (1<<2) | 1; STK_LOAD = 500000; // 0.5 sec / (8 MHz / 8) // Do forever: while (1) { // Wait a moment while ((STK_CTRL & (1 << 16)) == 0); // Flip all LEDs GPIOD_ODR ^= 0xF000; } } ``` ## assignment 3.2 ```c #include #include 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 green and red LEDs GPIOD->ODR = GPIO_ODR_OD12 | GPIO_ODR_OD14; // SysTick enable with clk source to AHB/8 SysTick->CTRL = SysTick_CTRL_ENABLE_Msk; SysTick->LOAD = 500000; // 0.5 sec / (8 MHz / 8) // Do forever: while (1) { // Wait a moment while ((SysTick->CTRL & (1 << 16)) == 0); // Flip all LEDs GPIOD->ODR ^= GPIO_ODR_OD12 | GPIO_ODR_OD13 | GPIO_ODR_OD14 | GPIO_ODR_OD15; } } ``` ## assignment 3.3 ```c #include #include #define RCC_AHB1ENR_BIT_GPIODEN *(volatile uint32_t*)(0x42000000 + 0x00023830 * 32 + 3 * 4) #define GPIOD_BASE 0x40020C00 #define GPIOD_MODER *(volatile uint32_t*)(GPIOD_BASE + 0x00) #define GPIOD_ODR *(volatile uint32_t*)(GPIOD_BASE + 0x14) #define STK_CTRL *(volatile uint32_t*)(0xE000E010) #define STK_LOAD *(volatile uint32_t*)(0xE000E014) volatile bool flag = false; void SysTick_Handler() { flag = true; } int main(void) { // GPIO Port D Clock Enable RCC_AHB1ENR_BIT_GPIODEN = 1; // GPIO Port D Pin 15 down to 12 Push/Pull Output GPIOD_MODER = 0x55000000; // Set green and red LEDs GPIOD_ODR = 0x5000; // SysTick enable with interupt and clk source to AHB/8 STK_CTRL = (1<<1) | 1; STK_LOAD = 500000; // 0.5 sec / (8 MHz / 8) // Do forever: while (1) { // Wait a moment while (!flag) { __asm__(" WFI"); // sleep until SysTick } flag = false; // Flip all LEDs GPIOD_ODR ^= 0xF000; } } ``` > C) Why must the flag variable be defined as volatile? becouse the compiler doesn't know when `flag` changes. Without `volatile` optimisations can think it does not change at all. ## assignment 3.4 ```c #include #include #include volatile bool flag = false; void SysTick_Handler() { flag = true; } 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 green and red LEDs GPIOD->ODR = GPIO_ODR_OD12 | GPIO_ODR_OD14; // SysTick enable with interupt and clk source to AHB/8 SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; SysTick->LOAD = 500000; // 0.5 sec / (8 MHz / 8) // Do forever: while (1) { // Wait a moment while (!flag) { __asm__(" WFI"); // sleep until SysTick } flag = false; // Flip all LEDs GPIOD->ODR ^= GPIO_ODR_OD12 | GPIO_ODR_OD13 | GPIO_ODR_OD14 | GPIO_ODR_OD15; } } ``` ## assignment 3.5 ```c #include #include #include volatile bool flag = false; void SysTick_Handler() { flag = true; } 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 green and red LEDs GPIOD->ODR = GPIO_ODR_OD12 | GPIO_ODR_OD14; // SysTick enable with interupt and clk source to AHB/8 SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; SysTick->LOAD = 500000; // 0.5 sec / (8 MHz / 8) // time of each color in half seconds const uint32_t time_green = 10; // 5 seconds const uint32_t time_orange = 2; // 1 seconds const uint32_t time_red = 8; // 4 seconds uint32_t timer = time_green; enum STATE State = STATE_GREEN; // Do forever: while (1) { // Wait a moment while (!flag) { __asm__(" WFI"); // sleep until SysTick } flag = false; timer--; if (timer == 0) { // turn off all leds GPIOD->ODR &= ~(GPIO_ODR_OD12 | GPIO_ODR_OD13 | GPIO_ODR_OD14 | GPIO_ODR_OD15); switch (State) { case STATE_GREEN: State = STATE_ORANGE; GPIOD->ODR |= GPIO_ODR_OD13; timer = time_orange; break; case STATE_ORANGE: State = STATE_RED; GPIOD->ODR |= GPIO_ODR_OD14; timer = time_red; break; case STATE_RED: State = STATE_GREEN; GPIOD->ODR |= GPIO_ODR_OD12; timer = time_green; break; } } } } ``` ## assignment 3.6 ```c #include #include #include volatile uint32_t ISR_Ticks = 0; struct TASK { void* fn, 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, uint32_t counter) { if (Tasks_len >= 8) { return false; } Tasks[Task_len].fn = fn; Tasks[Task_len].counter = counter; Tasks[Task_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 = 1000; // 1 ms / (8 MHz / 8) addTask(*taskGreen, 200); addTask(*taskOrange, 500); addTask(*taskRed, 750); addTask(*taskBlue, 300); // Do forever: while (1) { // Wait a moment while (ISR_Ticks != 0) { __asm__(" WFI"); // sleep until SysTick } uint32_t ticks = ISR_Ticks; ISR_Ticks = 0; for (uint8_t int=0; i ticks) { Tasks[i].counter -= ticks; } else { Tasks[i].counter = 0; } } for (uint8_t int=0; i