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
|
||||
apply_default_preset();
|
||||
|
||||
//try enabling HSE, fallback to HSI if HSE fails
|
||||
//enable HSE
|
||||
regs->CR.HSEON = 1;
|
||||
for (uint32_t i=0; i<1000; ++i) {
|
||||
__asm__("nop");
|
||||
for (uint32_t i=0; i<10000; ++i) {
|
||||
__asm("nop");
|
||||
}
|
||||
if (regs->CR.HSERDY == 0x1) {
|
||||
regs->CFGR.PLLSCR = 1;
|
||||
} 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->CR.PLLON = 1;
|
||||
for (uint32_t i=0; i<1000; ++i) {
|
||||
__asm__("nop");
|
||||
for (uint32_t i=0; i<10000; ++i) {
|
||||
__asm("nop");
|
||||
}
|
||||
if (regs->CR.PLLRDY != 0x1) {
|
||||
regs->CR.PLLON = 0;
|
||||
return; //clock low enough, no need for prescalers
|
||||
apply_default_preset();
|
||||
while (true);
|
||||
}
|
||||
|
||||
//configure prescalers
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
static uint32_t write_debug(uint8_t c, void* arg);
|
||||
|
||||
#define DEBUG_BAUDRATE 115200
|
||||
#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_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_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 volatile bool stk_irq;
|
||||
static volatile bool rtc_irq;
|
||||
static volatile uint32_t timestamp;
|
||||
|
||||
|
||||
//--public functions------------------------------------------------------------
|
||||
|
||||
@ -58,9 +56,15 @@ void task_start_scheduler(void)
|
||||
|
||||
rcc_configure_lsi(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);
|
||||
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;
|
||||
@ -76,20 +80,12 @@ 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_sleep();
|
||||
pwr_stop(PWR_WAKEUP_SPEED_SLOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t task_current_time(void)
|
||||
{
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
void task_start(TaskFunction function)
|
||||
{
|
||||
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) {
|
||||
if (task_list[i].function == function) {
|
||||
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;
|
||||
|
||||
return;
|
||||
@ -139,18 +135,14 @@ 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, timestamp);
|
||||
task->function(&task->state);
|
||||
} else {
|
||||
if ((task->state.trigger & triggers) != 0) {
|
||||
|
||||
if (task->state.timestamp <= timestamp) {
|
||||
task->state.timestamp = 0;
|
||||
}
|
||||
|
||||
--task->state.timestamp;
|
||||
if ((task->state.timestamp == 0) ||
|
||||
task->state.timeout_mode) {
|
||||
task->function(&task->state,
|
||||
timestamp);
|
||||
task->function(&task->state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -164,11 +156,13 @@ 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;
|
||||
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 TaskState {
|
||||
uint32_t timestamp; //timestamp at wich to wakeup the task, if any
|
||||
uint8_t count:5; //task counter: active step of task
|
||||
uint32_t timestamp:24; //timestamp at wich to wakeup the task, if any
|
||||
uint32_t count:5; //task counter: active step of 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
|
||||
*/
|
||||
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
|
||||
@ -74,8 +74,7 @@ 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, \
|
||||
uint32_t __task_time)
|
||||
#define TASK(fct_name) void fct_name(struct TaskState* restrict __task_state)
|
||||
|
||||
/**
|
||||
* Task entry macro, must be present at the begin of every task. Setup code to
|
||||
@ -84,7 +83,6 @@ struct Task {
|
||||
*/
|
||||
#define TASK_ENTRY \
|
||||
_TASK_COUNT_INIT; \
|
||||
(void) __task_time; \
|
||||
switch (__task_state->count) {
|
||||
|
||||
/**
|
||||
@ -217,7 +215,7 @@ bool task_is_running(TaskFunction task);
|
||||
|
||||
#define _TASK_PAUSE(delay_ms, count_val) do { \
|
||||
__task_state->count = count_val; \
|
||||
__task_state->timestamp = __task_time + delay_ms; \
|
||||
__task_state->timestamp += delay_ms; \
|
||||
__task_state->trigger = TASK_TRIGGER_STK; \
|
||||
return; \
|
||||
case (count_val): \
|
||||
@ -226,7 +224,7 @@ bool task_is_running(TaskFunction task);
|
||||
|
||||
#define _TASK_SLEEP(delay_s, count_val) do { \
|
||||
__task_state->count = count_val; \
|
||||
__task_state->timestamp = __task_time + delay_s * 1000; \
|
||||
__task_state->timestamp += delay_s; \
|
||||
__task_state->trigger = TASK_TRIGGER_RTC; \
|
||||
return; \
|
||||
case (count_val): \
|
||||
@ -245,7 +243,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 = __task_time + delay_ms; \
|
||||
__task_state->timestamp += delay_ms; \
|
||||
__task_state->trigger = TASK_TRIGGER_STK; \
|
||||
__task_state->timeout_mode = true; \
|
||||
case (count_val): \
|
||||
@ -253,13 +251,14 @@ 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 = __taks_time + delay_s * 1000; \
|
||||
__task_state->timestamp += delay_s; \
|
||||
__task_state->trigger = TASK_TRIGGER_RTC; \
|
||||
__task_state->timeout_mode = true; \
|
||||
case (count_val): \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user