parent
17f768a478
commit
39d47509ec
@ -0,0 +1,59 @@ |
||||
#include "init.h" |
||||
|
||||
#include "utils/gpio.h" |
||||
#include "utils/usart.h" |
||||
|
||||
|
||||
void init_gpios(void) |
||||
{ |
||||
gpio_enable(GPIOA); |
||||
gpio_enable(GPIOB); |
||||
gpio_enable(GPIOC); |
||||
|
||||
gpio_set_mode(GPIOC, BIT8 | BIT9 | BIT7, MODER_OUTPUT); |
||||
} |
||||
|
||||
|
||||
|
||||
void init_clock(void) |
||||
{ |
||||
// Flash timing - 64-bit access, pre-fetch, latency = 1
|
||||
FLASH_ACR |= FLASH_ACR_ACC64; // Cannot write both at once
|
||||
FLASH_ACR |= FLASH_ACR_PRFTEN | FLASH_ACR_LATENCY; |
||||
|
||||
// Power on HSI (runs from MSI on start)
|
||||
RCC_CR |= RCC_CR_HSION; |
||||
|
||||
// Wait for HSIRDY
|
||||
while (!(RCC_CR & RCC_CR_HSIRDY)); |
||||
|
||||
// Select HSI as the core clock source
|
||||
RCC_CFGR &= ~RCC_CFGR_SW; |
||||
RCC_CFGR |= RCC_CFGR_SW_HSI; |
||||
} |
||||
|
||||
|
||||
|
||||
void init_usart(void) |
||||
{ |
||||
gpio_set_af(GPIOC, BIT10 | BIT11, AF7); |
||||
|
||||
// USART at C10 (tx), C11 (rx)
|
||||
RCC_APB1ENR |= RCC_APB1ENR_USART3EN; |
||||
|
||||
// RATE 9600Bd 104.1875 (see datasheet for reference)
|
||||
//USART3_BRR = 0x00683; // 9600 @ 16MHz
|
||||
USART3_BRR = 0x0008A; // 115200 @ 16MHz
|
||||
|
||||
// USART enable
|
||||
USART3_CR1 = USART_CR1_UE | USART_CR1_RE | USART_CR1_TE; |
||||
} |
||||
|
||||
|
||||
|
||||
void init_systick(void) |
||||
{ |
||||
SysTick_CSR = (SysTick_CSR & ~SysTick_CSR_CLKSOURCE) | SysTick_CSR_CLKSOURCE_CORE; |
||||
SysTick_RELOAD = 16000; // 1ms interrupt @ 16MHz core clock
|
||||
SysTick_CSR |= SysTick_CSR_TICKINT | SysTick_CSR_ENABLE; |
||||
} |
@ -0,0 +1,7 @@ |
||||
#pragma once |
||||
#include <common.h> |
||||
|
||||
void init_clock(void); |
||||
void init_gpios(void); |
||||
void init_usart(void); |
||||
void init_systick(void); |
@ -1,20 +0,0 @@ |
||||
#include "systick.h" |
||||
|
||||
void systick_setup(uint32_t prescaller) |
||||
{ |
||||
SysTick_CSR = (SysTick_CSR & ~SysTick_CSR_CLKSOURCE) | SysTick_CSR_CLKSOURCE_CORE; |
||||
SysTick_RELOAD = prescaller; |
||||
SysTick_CSR |= SysTick_CSR_TICKINT | SysTick_CSR_ENABLE; |
||||
} |
||||
|
||||
|
||||
void systick_enable(void) |
||||
{ |
||||
SysTick_CSR |= SysTick_CSR_ENABLE; |
||||
} |
||||
|
||||
|
||||
void systick_disable(void) |
||||
{ |
||||
SysTick_CSR &= ~SysTick_CSR_ENABLE; |
||||
} |
@ -1,20 +0,0 @@ |
||||
#pragma once |
||||
#include "common.h" |
||||
|
||||
// don't forget to implement the handler:
|
||||
// void SysTick_Handler(void)
|
||||
|
||||
|
||||
/**
|
||||
* Set up and start systick |
||||
* @param prescaller divider (eg. for 1ms @ 16MHz: 16000) |
||||
*/ |
||||
void systick_setup(uint32_t prescaller); |
||||
|
||||
|
||||
/** Enable (start) systick */ |
||||
void systick_enable(void); |
||||
|
||||
|
||||
/** Disable (stop) systick */ |
||||
void systick_disable(void); |
@ -0,0 +1,68 @@ |
||||
#include "timebase.h" |
||||
|
||||
volatile uint32_t TIME_MS; |
||||
|
||||
#define TASK_COUNT 10 |
||||
|
||||
// --- time scheduler system ---
|
||||
typedef struct { |
||||
/** User callback */ |
||||
void (*callback) (void); |
||||
/** Callback interval */ |
||||
uint32_t interval_ms; |
||||
/** Counter, when reaches interval_ms, is cleared and callback is called. */ |
||||
uint32_t countup; |
||||
} timebase_cb_t; |
||||
|
||||
static uint8_t scheduled_task_n = 0; |
||||
static timebase_cb_t scheduled_tasks[TASK_COUNT]; |
||||
|
||||
|
||||
bool schedule_timed_task(void (*callback) (void), uint32_t interval_ms) |
||||
{ |
||||
if (scheduled_task_n >= TASK_COUNT) return false; |
||||
|
||||
// add the task
|
||||
timebase_cb_t *task = &scheduled_tasks[scheduled_task_n++]; |
||||
task->callback = callback; |
||||
task->countup = 0; |
||||
task->interval_ms = interval_ms; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
|
||||
/** IRQ */ |
||||
void SysTick_Handler(void) |
||||
{ |
||||
TIME_MS++; |
||||
|
||||
// run scheduled tasks
|
||||
for (int i = 0; i < scheduled_task_n; i++) { |
||||
timebase_cb_t *task = &scheduled_tasks[i]; |
||||
if (task->countup++ >= task->interval_ms) { |
||||
task->callback(); |
||||
task->countup = 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
void delay_ms(uint32_t ms) |
||||
{ |
||||
uint32_t last_ms = TIME_MS; |
||||
|
||||
while (ms-- != 0) { |
||||
while (TIME_MS == last_ms); |
||||
last_ms = TIME_MS; |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
void delay_s(uint32_t s) |
||||
{ |
||||
while (s-- != 0) { |
||||
delay_ms(1000); |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
#pragma once |
||||
#include <common.h> |
||||
|
||||
extern volatile uint32_t TIME_MS; |
||||
|
||||
void delay_ms(uint32_t ms); |
||||
void delay_s(uint32_t s); |
||||
|
||||
/** Schedule a timed task (like a cron job) */ |
||||
bool schedule_timed_task(void (*callback) (void), uint32_t interval_ms); |
Loading…
Reference in new issue