/** @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) { callback(); }