Compare commits

..

No commits in common. "b893a0283fb03422571956c325af31fd40eaea8d" and "daf59208147bf574cffdaa03c1b3025b792a45da" have entirely different histories.

4 changed files with 43 additions and 38 deletions

View File

@ -161,27 +161,26 @@ static void apply_speed_preset(void)
//restore sane values //restore sane values
apply_default_preset(); apply_default_preset();
//enable HSE //try enabling HSE, fallback to HSI if HSE fails
regs->CR.HSEON = 1; regs->CR.HSEON = 1;
for (uint32_t i=0; i<10000; ++i) { for (uint32_t i=0; i<1000; ++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 {
apply_default_preset(); regs->CR.HSEON = 0;
while (true);
} }
//configure PLL //configure PLL, fallback to HSI if PLL fails
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<10000; ++i) { for (uint32_t i=0; i<1000; ++i) {
__asm("nop"); __asm__("nop");
} }
if (regs->CR.PLLRDY != 0x1) { if (regs->CR.PLLRDY != 0x1) {
apply_default_preset(); regs->CR.PLLON = 0;
while (true); return; //clock low enough, no need for prescalers
} }
//configure prescalers //configure prescalers

View File

@ -18,7 +18,6 @@
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
@ -35,7 +34,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, DEBUG_BAUDRATE); usart_configure(usart, USART_CONFIG_8N1, 1000000);
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);

View File

@ -47,6 +47,8 @@ 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------------------------------------------------------------
@ -56,15 +58,9 @@ void task_start_scheduler(void)
rcc_configure_lsi(true); rcc_configure_lsi(true);
pwr_configure_bkp_write(true); pwr_configure_bkp_write(true);
//may need to be looked into later: basically, the RTC only wakes up the bkp_configure_rtc(1000, BKP_RTC_CLOCK_SRC_LSI, BKP_RTC_IRQ_NONE, nullptr);
//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;
@ -80,12 +76,20 @@ 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_stop(PWR_WAKEUP_SPEED_SLOW); pwr_sleep();
} }
} }
} }
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) {
@ -108,7 +112,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); task_list[i].function(&task_list[i].state, timestamp);
task_list[i].function = nullptr; task_list[i].function = nullptr;
return; return;
@ -135,14 +139,18 @@ 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); task->function(&task->state, timestamp);
} else { } else {
if ((task->state.trigger & triggers) != 0) { if ((task->state.trigger & triggers) != 0) {
--task->state.timestamp; if (task->state.timestamp <= 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);
} }
} }
} }
@ -156,13 +164,11 @@ 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;
pwr_configure_bkp_write(true); timestamp = bkp_read_rtc() * 1000;
bkp_set_rtc_alam(1);
pwr_configure_bkp_write(false);
} }

View File

@ -47,16 +47,16 @@ enum TaskTrigger {
* struct * struct
*/ */
struct TaskState { struct TaskState {
uint32_t timestamp:24; //timestamp at wich to wakeup the task, if any uint32_t timestamp; //timestamp at wich to wakeup the task, if any
uint32_t count:5; //task counter: active step of task uint8_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
uint32_t timeout_mode:1; //whether the timestamp is a timeout or a delay uint8_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*); typedef void(*TaskFunction)(struct TaskState*, uint32_t);
/** /**
* 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,7 +74,8 @@ 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
@ -83,6 +84,7 @@ 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) {
/** /**
@ -215,7 +217,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 += delay_ms; \ __task_state->timestamp = __task_time + delay_ms; \
__task_state->trigger = TASK_TRIGGER_STK; \ __task_state->trigger = TASK_TRIGGER_STK; \
return; \ return; \
case (count_val): \ case (count_val): \
@ -224,7 +226,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 += delay_s; \ __task_state->timestamp = __task_time + delay_s * 1000; \
__task_state->trigger = TASK_TRIGGER_RTC; \ __task_state->trigger = TASK_TRIGGER_RTC; \
return; \ return; \
case (count_val): \ case (count_val): \
@ -243,7 +245,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 += delay_ms; \ __task_state->timestamp = __task_time + 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): \
@ -251,14 +253,13 @@ 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 += delay_s; \ __task_state->timestamp = __taks_time + delay_s * 1000; \
__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): \