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