2025-09-23 14:07:59 +02:00

8.5 KiB

sub_title auther
Real Time Systems 10
name email name_short
Finley van Reenen mail@lailatheelf.nl E.L.F. van Reenen

Week 1.3

assignment 3.1

base project opdr_2_1.

#include <stdint.h>

#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

#include <stdint.h>
#include <stm32f4xx.h>

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

#include <stdint.h>
#include <stdbool.h>

#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

#include <stdint.h>
#include <stm32f4xx.h>
#include <stdbool.h>

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

#include <stdint.h>
#include <stm32f4xx.h>
#include <stdbool.h>

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

#include <stdint.h>
#include <stm32f4xx.h>
#include <stdbool.h>

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<Tasks_len; i++)
        {
            if (Tasks[i].counter > ticks)
            {
                Tasks[i].counter -= ticks;
            }
            else
            {
                Tasks[i].counter = 0;
            }
        }

        for (uint8_t int=0; i<Tasks_len; i++)
        {
            if (Tasks[i].counter == 0)
            {
                (&(Tasks[i].fn))();
            }
        }
    }
}