Compare commits
7 Commits
daf5920814
...
b893a0283f
| Author | SHA1 | Date | |
|---|---|---|---|
| b893a0283f | |||
| 8540e2e21f | |||
| 021180a22f | |||
| b032890a2c | |||
| c4358a7c28 | |||
| 99f3bb79c3 | |||
| 4df0ba5c6a |
19
drv/rcc.c
19
drv/rcc.c
@ -161,26 +161,27 @@ static void apply_speed_preset(void)
|
|||||||
//restore sane values
|
//restore sane values
|
||||||
apply_default_preset();
|
apply_default_preset();
|
||||||
|
|
||||||
//try enabling HSE, fallback to HSI if HSE fails
|
//enable HSE
|
||||||
regs->CR.HSEON = 1;
|
regs->CR.HSEON = 1;
|
||||||
for (uint32_t i=0; i<1000; ++i) {
|
for (uint32_t i=0; i<10000; ++i) {
|
||||||
__asm__("nop");
|
__asm("nop");
|
||||||
}
|
}
|
||||||
if (regs->CR.HSERDY == 0x1) {
|
if (regs->CR.HSERDY == 0x1) {
|
||||||
regs->CFGR.PLLSCR = 1;
|
regs->CFGR.PLLSCR = 1;
|
||||||
} else {
|
} else {
|
||||||
regs->CR.HSEON = 0;
|
apply_default_preset();
|
||||||
|
while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//configure PLL, fallback to HSI if PLL fails
|
//configure PLL
|
||||||
regs->CFGR.PLLMUL = 0x7; //PLL x9
|
regs->CFGR.PLLMUL = 0x7; //PLL x9
|
||||||
regs->CR.PLLON = 1;
|
regs->CR.PLLON = 1;
|
||||||
for (uint32_t i=0; i<1000; ++i) {
|
for (uint32_t i=0; i<10000; ++i) {
|
||||||
__asm__("nop");
|
__asm("nop");
|
||||||
}
|
}
|
||||||
if (regs->CR.PLLRDY != 0x1) {
|
if (regs->CR.PLLRDY != 0x1) {
|
||||||
regs->CR.PLLON = 0;
|
apply_default_preset();
|
||||||
return; //clock low enough, no need for prescalers
|
while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//configure prescalers
|
//configure prescalers
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
static uint32_t write_debug(uint8_t c, void* arg);
|
static uint32_t write_debug(uint8_t c, void* arg);
|
||||||
|
|
||||||
|
#define DEBUG_BAUDRATE 115200
|
||||||
#define BUFFER_SIZE 162 //(80 char line + \n) * 2
|
#define BUFFER_SIZE 162 //(80 char line + \n) * 2
|
||||||
|
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ void _debug_init(enum UsartPeriph usart, enum GpioPort tx_port,
|
|||||||
{
|
{
|
||||||
gpio_configure(tx_port, tx_pin, GPIO_MODE_OUTPUT_FAST,
|
gpio_configure(tx_port, tx_pin, GPIO_MODE_OUTPUT_FAST,
|
||||||
GPIO_CONFIG_OUT_ALT_PUSH_PULL);
|
GPIO_CONFIG_OUT_ALT_PUSH_PULL);
|
||||||
usart_configure(usart, USART_CONFIG_8N1, 1000000);
|
usart_configure(usart, USART_CONFIG_8N1, DEBUG_BAUDRATE);
|
||||||
dma_mbuf_configure(&mbuf,usart_configure_tx_dma(usart),
|
dma_mbuf_configure(&mbuf,usart_configure_tx_dma(usart),
|
||||||
DMA_CONFIG_PRIO_LOW, tx_buffer, BUFFER_SIZE);
|
DMA_CONFIG_PRIO_LOW, tx_buffer, BUFFER_SIZE);
|
||||||
|
|
||||||
|
|||||||
38
srv/task.c
38
srv/task.c
@ -47,8 +47,6 @@ static struct Task task_list[MAX_TASK_NB];
|
|||||||
static uint8_t task_nb;
|
static uint8_t task_nb;
|
||||||
static volatile bool stk_irq;
|
static volatile bool stk_irq;
|
||||||
static volatile bool rtc_irq;
|
static volatile bool rtc_irq;
|
||||||
static volatile uint32_t timestamp;
|
|
||||||
|
|
||||||
|
|
||||||
//--public functions------------------------------------------------------------
|
//--public functions------------------------------------------------------------
|
||||||
|
|
||||||
@ -58,9 +56,15 @@ void task_start_scheduler(void)
|
|||||||
|
|
||||||
rcc_configure_lsi(true);
|
rcc_configure_lsi(true);
|
||||||
pwr_configure_bkp_write(true);
|
pwr_configure_bkp_write(true);
|
||||||
bkp_configure_rtc(1000, BKP_RTC_CLOCK_SRC_LSI, BKP_RTC_IRQ_NONE, nullptr);
|
//may need to be looked into later: basically, the RTC only wakes up the
|
||||||
|
//system 1 tick too late when using pwr_stop(). To fix that, we can use a
|
||||||
|
//tick divided by 2, but I have no idea what the underlying problem is
|
||||||
|
bkp_configure_rtc(500, BKP_RTC_CLOCK_SRC_LSI, BKP_RTC_IRQ_NONE, nullptr);
|
||||||
pwr_configure_bkp_write(false);
|
pwr_configure_bkp_write(false);
|
||||||
exti_configure(EXTI_LINE_RTC, EXTI_CONFIG_RISING_EDGE, callback_rtc);
|
exti_configure(EXTI_LINE_RTC, EXTI_CONFIG_RISING_EDGE, callback_rtc);
|
||||||
|
pwr_configure_bkp_write(true);
|
||||||
|
bkp_set_rtc_alam(1);
|
||||||
|
pwr_configure_bkp_write(false);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
uint8_t triggers = stk_irq << 0 | rtc_irq << 1;
|
uint8_t triggers = stk_irq << 0 | rtc_irq << 1;
|
||||||
@ -76,20 +80,12 @@ void task_start_scheduler(void)
|
|||||||
stk_start();
|
stk_start();
|
||||||
pwr_sleep();
|
pwr_sleep();
|
||||||
} else {
|
} else {
|
||||||
pwr_configure_bkp_write(true);
|
|
||||||
bkp_set_rtc_alam(1);
|
|
||||||
pwr_configure_bkp_write(false);
|
|
||||||
stk_stop();
|
stk_stop();
|
||||||
pwr_sleep();
|
pwr_stop(PWR_WAKEUP_SPEED_SLOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t task_current_time(void)
|
|
||||||
{
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void task_start(TaskFunction function)
|
void task_start(TaskFunction function)
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < MAX_TASK_NB; ++i) {
|
for (uint8_t i = 0; i < MAX_TASK_NB; ++i) {
|
||||||
@ -112,7 +108,7 @@ void task_stop(TaskFunction function)
|
|||||||
for (uint8_t i = 0; i < task_nb; ++i) {
|
for (uint8_t i = 0; i < task_nb; ++i) {
|
||||||
if (task_list[i].function == function) {
|
if (task_list[i].function == function) {
|
||||||
task_list[i].state.count = _TASK_COUNT_CLEANUP & 0x1F;
|
task_list[i].state.count = _TASK_COUNT_CLEANUP & 0x1F;
|
||||||
task_list[i].function(&task_list[i].state, timestamp);
|
task_list[i].function(&task_list[i].state);
|
||||||
task_list[i].function = nullptr;
|
task_list[i].function = nullptr;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -139,18 +135,14 @@ static bool execute_task(struct Task* restrict task, uint8_t triggers)
|
|||||||
{
|
{
|
||||||
if (task->function != nullptr) {
|
if (task->function != nullptr) {
|
||||||
if (task->state.trigger == TASK_TRIGGER_ANY) {
|
if (task->state.trigger == TASK_TRIGGER_ANY) {
|
||||||
task->function(&task->state, timestamp);
|
task->function(&task->state);
|
||||||
} else {
|
} else {
|
||||||
if ((task->state.trigger & triggers) != 0) {
|
if ((task->state.trigger & triggers) != 0) {
|
||||||
|
|
||||||
if (task->state.timestamp <= timestamp) {
|
--task->state.timestamp;
|
||||||
task->state.timestamp = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((task->state.timestamp == 0) ||
|
if ((task->state.timestamp == 0) ||
|
||||||
task->state.timeout_mode) {
|
task->state.timeout_mode) {
|
||||||
task->function(&task->state,
|
task->function(&task->state);
|
||||||
timestamp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,11 +156,13 @@ static bool execute_task(struct Task* restrict task, uint8_t triggers)
|
|||||||
static void callback_stk(void)
|
static void callback_stk(void)
|
||||||
{
|
{
|
||||||
stk_irq = true;
|
stk_irq = true;
|
||||||
++timestamp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void callback_rtc(void)
|
static void callback_rtc(void)
|
||||||
{
|
{
|
||||||
rtc_irq = true;
|
rtc_irq = true;
|
||||||
timestamp = bkp_read_rtc() * 1000;
|
pwr_configure_bkp_write(true);
|
||||||
|
bkp_set_rtc_alam(1);
|
||||||
|
pwr_configure_bkp_write(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
srv/task.h
21
srv/task.h
@ -47,16 +47,16 @@ enum TaskTrigger {
|
|||||||
* struct
|
* struct
|
||||||
*/
|
*/
|
||||||
struct TaskState {
|
struct TaskState {
|
||||||
uint32_t timestamp; //timestamp at wich to wakeup the task, if any
|
uint32_t timestamp:24; //timestamp at wich to wakeup the task, if any
|
||||||
uint8_t count:5; //task counter: active step of task
|
uint32_t count:5; //task counter: active step of task
|
||||||
enum TaskTrigger trigger:2; //triggers on wich to execute the task
|
enum TaskTrigger trigger:2; //triggers on wich to execute the task
|
||||||
uint8_t timeout_mode:1; //whether the timestamp is a timeout or a delay
|
uint32_t timeout_mode:1; //whether the timestamp is a timeout or a delay
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function prototype of tasks
|
* Function prototype of tasks
|
||||||
*/
|
*/
|
||||||
typedef void(*TaskFunction)(struct TaskState*, uint32_t);
|
typedef void(*TaskFunction)(struct TaskState*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Full definition of a task. Contains the function supporting the task as well
|
* Full definition of a task. Contains the function supporting the task as well
|
||||||
@ -74,8 +74,7 @@ struct Task {
|
|||||||
* Task declaration macro, to be used to declare and define a task instead of a
|
* Task declaration macro, to be used to declare and define a task instead of a
|
||||||
* regular function declaration/defintion
|
* regular function declaration/defintion
|
||||||
*/
|
*/
|
||||||
#define TASK(fct_name) void fct_name(struct TaskState* restrict __task_state, \
|
#define TASK(fct_name) void fct_name(struct TaskState* restrict __task_state)
|
||||||
uint32_t __task_time)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task entry macro, must be present at the begin of every task. Setup code to
|
* Task entry macro, must be present at the begin of every task. Setup code to
|
||||||
@ -84,7 +83,6 @@ struct Task {
|
|||||||
*/
|
*/
|
||||||
#define TASK_ENTRY \
|
#define TASK_ENTRY \
|
||||||
_TASK_COUNT_INIT; \
|
_TASK_COUNT_INIT; \
|
||||||
(void) __task_time; \
|
|
||||||
switch (__task_state->count) {
|
switch (__task_state->count) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -217,7 +215,7 @@ bool task_is_running(TaskFunction task);
|
|||||||
|
|
||||||
#define _TASK_PAUSE(delay_ms, count_val) do { \
|
#define _TASK_PAUSE(delay_ms, count_val) do { \
|
||||||
__task_state->count = count_val; \
|
__task_state->count = count_val; \
|
||||||
__task_state->timestamp = __task_time + delay_ms; \
|
__task_state->timestamp += delay_ms; \
|
||||||
__task_state->trigger = TASK_TRIGGER_STK; \
|
__task_state->trigger = TASK_TRIGGER_STK; \
|
||||||
return; \
|
return; \
|
||||||
case (count_val): \
|
case (count_val): \
|
||||||
@ -226,7 +224,7 @@ bool task_is_running(TaskFunction task);
|
|||||||
|
|
||||||
#define _TASK_SLEEP(delay_s, count_val) do { \
|
#define _TASK_SLEEP(delay_s, count_val) do { \
|
||||||
__task_state->count = count_val; \
|
__task_state->count = count_val; \
|
||||||
__task_state->timestamp = __task_time + delay_s * 1000; \
|
__task_state->timestamp += delay_s; \
|
||||||
__task_state->trigger = TASK_TRIGGER_RTC; \
|
__task_state->trigger = TASK_TRIGGER_RTC; \
|
||||||
return; \
|
return; \
|
||||||
case (count_val): \
|
case (count_val): \
|
||||||
@ -245,7 +243,7 @@ bool task_is_running(TaskFunction task);
|
|||||||
|
|
||||||
#define _TASK_PAUSE_UNTIL(cond, delay_ms, count_val) do { \
|
#define _TASK_PAUSE_UNTIL(cond, delay_ms, count_val) do { \
|
||||||
__task_state->count = count_val; \
|
__task_state->count = count_val; \
|
||||||
__task_state->timestamp = __task_time + delay_ms; \
|
__task_state->timestamp += delay_ms; \
|
||||||
__task_state->trigger = TASK_TRIGGER_STK; \
|
__task_state->trigger = TASK_TRIGGER_STK; \
|
||||||
__task_state->timeout_mode = true; \
|
__task_state->timeout_mode = true; \
|
||||||
case (count_val): \
|
case (count_val): \
|
||||||
@ -253,13 +251,14 @@ bool task_is_running(TaskFunction task);
|
|||||||
return; \
|
return; \
|
||||||
} else { \
|
} else { \
|
||||||
__task_state->timeout_mode = false; \
|
__task_state->timeout_mode = false; \
|
||||||
|
__task_state->timestamp = 0; \
|
||||||
} \
|
} \
|
||||||
/* fall through */ \
|
/* fall through */ \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define _TASK_SLEEP_UNTIL(cond, delay_s, count_val) do { \
|
#define _TASK_SLEEP_UNTIL(cond, delay_s, count_val) do { \
|
||||||
__task_state->count = count_val; \
|
__task_state->count = count_val; \
|
||||||
__task_state->timestamp = __taks_time + delay_s * 1000; \
|
__task_state->timestamp += delay_s; \
|
||||||
__task_state->trigger = TASK_TRIGGER_RTC; \
|
__task_state->trigger = TASK_TRIGGER_RTC; \
|
||||||
__task_state->timeout_mode = true; \
|
__task_state->timeout_mode = true; \
|
||||||
case (count_val): \
|
case (count_val): \
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user