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
apply_default_preset();
//enable HSE
//try enabling HSE, fallback to HSI if HSE fails
regs->CR.HSEON = 1;
for (uint32_t i=0; i<10000; ++i) {
__asm("nop");
for (uint32_t i=0; i<1000; ++i) {
__asm__("nop");
}
if (regs->CR.HSERDY == 0x1) {
regs->CFGR.PLLSCR = 1;
} else {
apply_default_preset();
while (true);
regs->CR.HSEON = 0;
}
//configure PLL
//configure PLL, fallback to HSI if PLL fails
regs->CFGR.PLLMUL = 0x7; //PLL x9
regs->CR.PLLON = 1;
for (uint32_t i=0; i<10000; ++i) {
__asm("nop");
for (uint32_t i=0; i<1000; ++i) {
__asm__("nop");
}
if (regs->CR.PLLRDY != 0x1) {
apply_default_preset();
while (true);
regs->CR.PLLON = 0;
return; //clock low enough, no need for prescalers
}
//configure prescalers

View File

@ -18,7 +18,6 @@
static uint32_t write_debug(uint8_t c, void* arg);
#define DEBUG_BAUDRATE 115200
#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_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_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 volatile bool stk_irq;
static volatile bool rtc_irq;
static volatile uint32_t timestamp;
//--public functions------------------------------------------------------------
@ -56,15 +58,9 @@ void task_start_scheduler(void)
rcc_configure_lsi(true);
pwr_configure_bkp_write(true);
//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);
bkp_configure_rtc(1000, BKP_RTC_CLOCK_SRC_LSI, BKP_RTC_IRQ_NONE, nullptr);
pwr_configure_bkp_write(false);
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) {
uint8_t triggers = stk_irq << 0 | rtc_irq << 1;
@ -80,12 +76,20 @@ void task_start_scheduler(void)
stk_start();
pwr_sleep();
} else {
pwr_configure_bkp_write(true);
bkp_set_rtc_alam(1);
pwr_configure_bkp_write(false);
stk_stop();
pwr_stop(PWR_WAKEUP_SPEED_SLOW);
pwr_sleep();
}
}
}
uint32_t task_current_time(void)
{
return timestamp;
}
void task_start(TaskFunction function)
{
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) {
if (task_list[i].function == function) {
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;
return;
@ -135,14 +139,18 @@ static bool execute_task(struct Task* restrict task, uint8_t triggers)
{
if (task->function != nullptr) {
if (task->state.trigger == TASK_TRIGGER_ANY) {
task->function(&task->state);
task->function(&task->state, timestamp);
} else {
if ((task->state.trigger & triggers) != 0) {
--task->state.timestamp;
if (task->state.timestamp <= timestamp) {
task->state.timestamp = 0;
}
if ((task->state.timestamp == 0) ||
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)
{
stk_irq = true;
++timestamp;
}
static void callback_rtc(void)
{
rtc_irq = true;
pwr_configure_bkp_write(true);
bkp_set_rtc_alam(1);
pwr_configure_bkp_write(false);
timestamp = bkp_read_rtc() * 1000;
}

View File

@ -47,16 +47,16 @@ enum TaskTrigger {
* struct
*/
struct TaskState {
uint32_t timestamp:24; //timestamp at wich to wakeup the task, if any
uint32_t count:5; //task counter: active step of task
uint32_t timestamp; //timestamp at wich to wakeup the task, if any
uint8_t count:5; //task counter: active step of 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
*/
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
@ -74,7 +74,8 @@ struct Task {
* Task declaration macro, to be used to declare and define a task instead of a
* 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
@ -83,6 +84,7 @@ struct Task {
*/
#define TASK_ENTRY \
_TASK_COUNT_INIT; \
(void) __task_time; \
switch (__task_state->count) {
/**
@ -215,7 +217,7 @@ bool task_is_running(TaskFunction task);
#define _TASK_PAUSE(delay_ms, count_val) do { \
__task_state->count = count_val; \
__task_state->timestamp += delay_ms; \
__task_state->timestamp = __task_time + delay_ms; \
__task_state->trigger = TASK_TRIGGER_STK; \
return; \
case (count_val): \
@ -224,7 +226,7 @@ bool task_is_running(TaskFunction task);
#define _TASK_SLEEP(delay_s, count_val) do { \
__task_state->count = count_val; \
__task_state->timestamp += delay_s; \
__task_state->timestamp = __task_time + delay_s * 1000; \
__task_state->trigger = TASK_TRIGGER_RTC; \
return; \
case (count_val): \
@ -243,7 +245,7 @@ bool task_is_running(TaskFunction task);
#define _TASK_PAUSE_UNTIL(cond, delay_ms, count_val) do { \
__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->timeout_mode = true; \
case (count_val): \
@ -251,14 +253,13 @@ bool task_is_running(TaskFunction task);
return; \
} else { \
__task_state->timeout_mode = false; \
__task_state->timestamp = 0; \
} \
/* fall through */ \
} while (0)
#define _TASK_SLEEP_UNTIL(cond, delay_s, count_val) do { \
__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->timeout_mode = true; \
case (count_val): \