/** @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; static uint32_t prescaler; //--public functions------------------------------------------------------------ uint32_t stk_configure(uint32_t period_us, StkCallback cb) { stk_reset(); struct RccClocks clocks; rcc_get_clocks(&clocks); uint32_t prescaler = (clocks.ahb_freq / 1000000 / 8); uint32_t reload = period_us * prescaler; if (reload < 1) { //period is too small, try using the non-prescaled clock prescaler *= 8; reload = period_us * prescaler; if (reload < 1) { //period is still too small return 1; } regs->CTRL.CLKSOURCE = 1; } regs->LOAD.RELOAD = reload; regs->CTRL.TICKINT = 1; callback = cb; return 0; } void stk_reset(void) { regs->CTRL.ENABLE = 0; regs->CTRL.TICKINT = 0; regs->CTRL.CLKSOURCE = 0; regs->CTRL.COUNTFLAG = 0; regs->LOAD.RELOAD = 0; regs->VAL.CURRENT = 0; } void stk_start(void) { regs->CTRL.ENABLE = 1; } void stk_stop(void) { regs->CTRL.ENABLE = 0; } uint32_t stk_read_us(void) { return (regs->VAL.word & 0x00FFFFFF) / prescaler; } //--local functions------------------------------------------------------------- void hdr_sys_tick(void) { //clearing the pending bit in SCB_ICSR isn't needed, though I don't know why callback(); }