Compare commits
4 Commits
cbe6409f69
...
7e69bfd89c
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e69bfd89c | |||
| ddd05da6eb | |||
| 7ba9063d02 | |||
| fb1c11132f |
87
drv/stk.c
Normal file
87
drv/stk.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/** @file stk.c
|
||||||
|
* Module handling the system timer (systick or STK for short)
|
||||||
|
*
|
||||||
|
* The module provides functions to configure and use the system timer embedded
|
||||||
|
* in the cortex m core
|
||||||
|
*/
|
||||||
|
|
||||||
|
//--includes--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "stk.h"
|
||||||
|
#include "stk_regs.h"
|
||||||
|
|
||||||
|
#include "rcc.h"
|
||||||
|
|
||||||
|
|
||||||
|
//--local definitions-----------------------------------------------------------
|
||||||
|
|
||||||
|
static volatile struct STK* regs = (struct STK*)STK_BASE_ADDRESS;
|
||||||
|
|
||||||
|
|
||||||
|
//--local variables-------------------------------------------------------------
|
||||||
|
|
||||||
|
static StkCallback callback;
|
||||||
|
|
||||||
|
|
||||||
|
//--public functions------------------------------------------------------------
|
||||||
|
|
||||||
|
uint32_t stk_configure(uint32_t period_us, StkCallback cb)
|
||||||
|
{
|
||||||
|
stk_reset();
|
||||||
|
|
||||||
|
struct RccClocks clocks;
|
||||||
|
rcc_get_clocks(&clocks);
|
||||||
|
|
||||||
|
uint32_t reload = period_us * (clocks.ahb_freq / 1000000 / 8);
|
||||||
|
if (reload < 1) {
|
||||||
|
//period is too small, try using the non-prescaled clock
|
||||||
|
reload = period_us * (clocks.ahb_freq / 1000000);
|
||||||
|
if (reload < 1) {
|
||||||
|
//period is still too small
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
reg_set(regs->CTRL, STK_CTRL_CLKSOURCE);
|
||||||
|
}
|
||||||
|
reg_write(regs->LOAD, STK_LOAD_RELOAD, reload);
|
||||||
|
reg_set(regs->CTRL, STK_CTRL_TICKINT);
|
||||||
|
|
||||||
|
callback = cb;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stk_reset(void)
|
||||||
|
{
|
||||||
|
reg_reset(regs->CTRL, STK_CTRL_ENABLE);
|
||||||
|
reg_reset(regs->CTRL, STK_CTRL_TICKINT);
|
||||||
|
reg_reset(regs->CTRL, STK_CTRL_CLKSOURCE);
|
||||||
|
reg_reset(regs->CTRL, STK_CTRL_COUNTFLAG);
|
||||||
|
|
||||||
|
reg_write(regs->LOAD, STK_LOAD_RELOAD, 0);
|
||||||
|
reg_write(regs->VAL, STK_VAL_CURRENT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stk_start(void)
|
||||||
|
{
|
||||||
|
reg_set(regs->CTRL, STK_CTRL_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stk_stop(void)
|
||||||
|
{
|
||||||
|
reg_reset(regs->CTRL, STK_CTRL_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t stk_read(void)
|
||||||
|
{
|
||||||
|
return regs->VAL.word & 0x00FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--local functions-------------------------------------------------------------
|
||||||
|
|
||||||
|
void hdr_sys_tick(void)
|
||||||
|
{
|
||||||
|
//clearing the pending bit in SCB_ICSR isn't needed, though I don't know why
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
55
drv/stk.h
Normal file
55
drv/stk.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/** @file stk.h
|
||||||
|
* Module handling the system timer (systick or STK for short)
|
||||||
|
*
|
||||||
|
* The module provides functions to configure and use the system timer embedded
|
||||||
|
* in the cortex m core
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _STK_H_
|
||||||
|
#define _STK_H_
|
||||||
|
|
||||||
|
//--includes--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
//--type definitions------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef void (*StkCallback)(void);
|
||||||
|
|
||||||
|
|
||||||
|
//--functions-------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the system timer to run at the specified period in µs and call the
|
||||||
|
* given callback when said period is reached. Due to the limited configuration
|
||||||
|
* options, 1.8s is the maximum period when running in speed preset (see rcc
|
||||||
|
* module). The maximum period can be substantially increased by reducing the
|
||||||
|
* core clock
|
||||||
|
*/
|
||||||
|
uint32_t stk_configure(uint32_t period_us, StkCallback cb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the system timer configuration, restoring the default configuration
|
||||||
|
* and stopping it
|
||||||
|
*/
|
||||||
|
void stk_reset(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the system timer. The timer will run until stopped
|
||||||
|
*/
|
||||||
|
void stk_start(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the system timer
|
||||||
|
*/
|
||||||
|
void stk_stop(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the current value of the timer's counter
|
||||||
|
*/
|
||||||
|
uint32_t stk_read(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif //_STK_H_
|
||||||
|
|
||||||
90
drv/stk_regs.h
Normal file
90
drv/stk_regs.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/** @file stk_regs.h
|
||||||
|
* Module defining systick (STK) registers.
|
||||||
|
*
|
||||||
|
* Mainly made to be used by the stk module. It is recommanded to go through
|
||||||
|
* the functions provided by that module instead of directly using the registers
|
||||||
|
* defined here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _STK_REGS_H_
|
||||||
|
#define _STK_REGS_H_
|
||||||
|
|
||||||
|
//--includes--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "reg.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
//--type definitions------------------------------------------------------------
|
||||||
|
|
||||||
|
#define STK_BASE_ADDRESS 0xE000E010
|
||||||
|
|
||||||
|
union STK_CTRL {
|
||||||
|
struct __attribute__((packed)) {
|
||||||
|
uint32_t ENABLE:1;
|
||||||
|
uint32_t TICKINT:1;
|
||||||
|
uint32_t CLKSOURCE:1;
|
||||||
|
uint32_t reserved1:13;
|
||||||
|
uint32_t COUNTFLAG:1;
|
||||||
|
uint32_t reserved2:15;
|
||||||
|
};
|
||||||
|
uint32_t word;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define STK_CTRL_ENABLE reg_def( 0, 1)
|
||||||
|
#define STK_CTRL_TICKINT reg_def( 1, 1)
|
||||||
|
#define STK_CTRL_CLKSOURCE reg_def( 2, 1)
|
||||||
|
#define STK_CTRL_reserved reg_def( 3, 13)
|
||||||
|
#define STK_CTRL_COUNTFLAG reg_def(16, 1)
|
||||||
|
#define STK_CTRL_reserved2 reg_def(17, 15)
|
||||||
|
|
||||||
|
union STK_LOAD {
|
||||||
|
struct __attribute__((packed)) {
|
||||||
|
uint32_t RELOAD:24;
|
||||||
|
uint32_t reserved1:8;
|
||||||
|
};
|
||||||
|
uint32_t word;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define STK_LOAD_RELOAD reg_def( 0, 24)
|
||||||
|
#define STK_LOAD_reserved1 reg_def(24, 8)
|
||||||
|
|
||||||
|
union STK_VAL {
|
||||||
|
struct __attribute__((packed)) {
|
||||||
|
uint32_t CURRENT:24;
|
||||||
|
uint32_t reserved1:8;
|
||||||
|
};
|
||||||
|
uint32_t word;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define STK_VAL_CURRENT reg_def( 0, 24)
|
||||||
|
#define STK_VAL_reserved1 reg_def(24, 8)
|
||||||
|
|
||||||
|
union STK_CALIB {
|
||||||
|
struct __attribute__((packed)) {
|
||||||
|
uint32_t TENMS:24;
|
||||||
|
uint32_t reserved1:6;
|
||||||
|
uint32_t SKEW:1;
|
||||||
|
uint32_t NOREF:1;
|
||||||
|
};
|
||||||
|
uint32_t word;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define STK_CALIB_RELOAD reg_def( 0, 24)
|
||||||
|
#define STK_CALIB_reserved1 reg_def(24, 6)
|
||||||
|
#define STK_CALIB_SKEW reg_def(30, 1)
|
||||||
|
#define STK_CALIB_NOREF reg_def(31, 1)
|
||||||
|
|
||||||
|
struct __attribute__((packed)) STK {
|
||||||
|
union STK_CTRL CTRL;
|
||||||
|
union STK_LOAD LOAD;
|
||||||
|
union STK_VAL VAL;
|
||||||
|
union STK_CALIB CALIB;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//--functions-------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif //_STK_REGS_H_
|
||||||
|
|
||||||
8
srv/task.c
Normal file
8
srv/task.c
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/** @file task.c
|
||||||
|
* Module handling the task creation and management
|
||||||
|
*
|
||||||
|
* The module provides an API to create, run and manage lightweight, stack-less
|
||||||
|
* threads (tasks). This system is based on protothreads,
|
||||||
|
* see https://dunkels.com/adam/pt/index.html
|
||||||
|
*/
|
||||||
|
|
||||||
52
srv/task.h
Normal file
52
srv/task.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/** @file task.h
|
||||||
|
* Module handling the task creation and management
|
||||||
|
*
|
||||||
|
* The module provides an API to create, run and manage lightweight, stack-less
|
||||||
|
* threads (tasks). This system is based on protothreads,
|
||||||
|
* see https://dunkels.com/adam/pt/index.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _task_h_
|
||||||
|
#define _task_h_
|
||||||
|
|
||||||
|
//--includes--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
//--functions-------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define TASK(fct_name) uint8_t fct_name(uint8_t __task_context)
|
||||||
|
|
||||||
|
#define task_begin() do { \
|
||||||
|
_TASK_COUNT_INIT; \
|
||||||
|
switch (__task_context) { \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define task_end() do { \
|
||||||
|
} \
|
||||||
|
return _TASK_COUNT_STOP; \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
#define task_wait_until(cond) _task_wait_until(cond, _TASK_COUNT_INCR)
|
||||||
|
|
||||||
|
|
||||||
|
//--internal_functions----------------------------------------------------------
|
||||||
|
|
||||||
|
#define _TASK_COUNT_INIT enum { TASK_COUNTER_BASE = __COUNTER__ }
|
||||||
|
#define _TASK_COUNT_INCR (uint8_t)(__COUNTER__ - TASK_COUNTER_BASE - 1)
|
||||||
|
#define _TASK_COUNT_STOP UINT8_MAX
|
||||||
|
|
||||||
|
#define _task(fct_name)
|
||||||
|
|
||||||
|
#define _task_wait_until(cond, count) do { \
|
||||||
|
case (count): \
|
||||||
|
if (!(cond)) { \
|
||||||
|
return count; \
|
||||||
|
} \
|
||||||
|
/* fall through */ \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#endif //_task_h_
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user