diff options
-rw-r--r-- | examples/test-systick.cpp | 2 | ||||
-rw-r--r-- | libmaple/systick.c | 54 | ||||
-rw-r--r-- | libmaple/systick.h | 46 | ||||
-rw-r--r-- | libmaple/util.h | 37 |
4 files changed, 82 insertions, 57 deletions
diff --git a/examples/test-systick.cpp b/examples/test-systick.cpp index c7b5529..bbf0adf 100644 --- a/examples/test-systick.cpp +++ b/examples/test-systick.cpp @@ -30,7 +30,7 @@ void loop() { SerialUSB.println("Disabling SysTick"); } else { SerialUSB.println("Re-enabling SysTick"); - systick_resume(); + systick_enable(); } disable = !disable; } diff --git a/libmaple/systick.c b/libmaple/systick.c index b9a52c1..c04f4f3 100644 --- a/libmaple/systick.c +++ b/libmaple/systick.c @@ -26,44 +26,46 @@ * @brief System timer interrupt handler and initialization routines */ -#include "libmaple.h" #include "systick.h" -#define SYSTICK_RELOAD 0xE000E014 // Reload value register -#define SYSTICK_CNT 0xE000E018 // Current value register -#define SYSTICK_CALIB 0xE000E01C // Calibration value register - -#define SYSTICK_SRC_HCLK BIT(2) // Use core clock -#define SYSTICK_TICKINT BIT(1) // Interrupt on systick countdown -#define SYSTICK_ENABLE BIT(0) // Turn on the counter - volatile uint32 systick_timer_millis; +/** + * @brief Initialize and enable SysTick. + * + * Clocks the system timer with the core clock, turns it on, and + * enables interrupts. + * + * @param reload_val Appropriate reload counter to tick every 1 ms. + */ void systick_init(uint32 reload_val) { - /* Set the reload counter to tick every 1ms */ - __write(SYSTICK_RELOAD, reload_val); - - /* Clock the system timer with the core clock and turn it on, - * interrrupt every 1ms to keep track of millis() */ - __write(SYSTICK_CSR, SYSTICK_SRC_HCLK | - SYSTICK_ENABLE | - SYSTICK_TICKINT); + SYSTICK_BASE->RVR = reload_val; + systick_enable(); } +/** + * Clock the system timer with the core clock, but don't turn it + * on or enable interrupt. + */ void systick_disable() { - /* clock the system timer with the core clock, but don't turn it - on or enable interrupt. */ - __write(SYSTICK_CSR, SYSTICK_SRC_HCLK); + SYSTICK_BASE->CSR = SYSTICK_CSR_CLKSOURCE_CORE; } -void systick_resume() { - /* re-enable init registers without changing reload val */ - __write(SYSTICK_CSR, SYSTICK_SRC_HCLK | - SYSTICK_ENABLE | - SYSTICK_TICKINT); +/** + * Clock the system timer with the core clock and turn it on; + * interrupt every 1 ms, for systick_timer_millis. + */ +void systick_enable() { + /* re-enables init registers without changing reload val */ + SYSTICK_BASE->CSR = (SYSTICK_CSR_CLKSOURCE_CORE | + SYSTICK_CSR_ENABLE | + SYSTICK_CSR_TICKINT_PEND); } -/** SysTick interrupt handler. Bumps up the tick counter. */ +/* + * SysTick ISR + */ + void __exc_systick(void) { systick_timer_millis++; } diff --git a/libmaple/systick.h b/libmaple/systick.h index 33a3cf8..35b4cb9 100644 --- a/libmaple/systick.h +++ b/libmaple/systick.h @@ -31,30 +31,60 @@ #ifndef _SYSTICK_H_ #define _SYSTICK_H_ -#include "libmaple.h" +#include "libmaple_types.h" +#include "util.h" #ifdef __cplusplus extern "C"{ #endif -#define SYSTICK_CSR 0xE000E010 // Control and status register -#define SYSTICK_CNT 0xE000E018 // Current value register +/** SysTick register map type */ +typedef struct systick_reg_map { + __io uint32 CSR; /**< Control and status register */ + __io uint32 RVR; /**< Reload value register */ + __io uint32 CNT; /**< Current value register ("count") */ + __io uint32 CVR; /**< Calibration value register */ +} systick_reg_map; -#define SYSTICK_CSR_COUNTFLAG BIT(16) +/** SysTick register map base pointer */ +#define SYSTICK_BASE ((struct systick_reg_map*)0xE000E010) -/** System elapsed time in milliseconds */ +/* + * Register bit definitions. + */ + +/* Control and status register */ + +#define SYSTICK_CSR_COUNTFLAG BIT(16) +#define SYSTICK_CSR_CLKSOURCE BIT(2) +#define SYSTICK_CSR_CLKSOURCE_EXTERNAL 0 +#define SYSTICK_CSR_CLKSOURCE_CORE BIT(2) +#define SYSTICK_CSR_TICKINT BIT(1) +#define SYSTICK_CSR_TICKINT_PEND BIT(1) +#define SYSTICK_CSR_TICKINT_NO_PEND 0 +#define SYSTICK_CSR_ENABLE BIT(0) +#define SYSTICK_CSR_ENABLE_MULTISHOT BIT(0) +#define SYSTICK_CSR_ENABLE_DISABLED 0 + +/* Calibration value register */ + +#define SYSTICK_CVR_NOREF BIT(31) +#define SYSTICK_CVR_SKEW BIT(30) +#define SYSTICK_CVR_TENMS 0xFFFFFF + +/** System elapsed time, in milliseconds */ extern volatile uint32 systick_timer_millis; void systick_init(uint32 reload_val); void systick_disable(); -void systick_resume(); +void systick_enable(); static inline uint32 systick_get_count(void) { - return __read(SYSTICK_CNT); + return SYSTICK_BASE->CNT; } static inline uint32 systick_check_underflow(void) { - return (__read(SYSTICK_CSR) & SYSTICK_CSR_COUNTFLAG); + return SYSTICK_BASE->CSR & SYSTICK_CSR_COUNTFLAG; } #ifdef __cplusplus diff --git a/libmaple/util.h b/libmaple/util.h index 25dd56e..aff70e1 100644 --- a/libmaple/util.h +++ b/libmaple/util.h @@ -23,14 +23,12 @@ *****************************************************************************/ /** - * @file util.h - * - * @brief Various macros and utility procedures. + * @file util.h + * @brief Miscellaneous utility macros and procedures. */ #include "libmaple_types.h" -/* Generally "useful" utility procedures */ #ifndef _UTIL_H_ #define _UTIL_H_ @@ -38,33 +36,23 @@ extern "C"{ #endif -/* Debug configuration */ -#define DEBUG_NONE 0 -#define DEBUG_FAULT 1 -#define DEBUG_ALL 2 - -#ifndef DEBUG_LEVEL -#define DEBUG_LEVEL DEBUG_ALL -#endif +/* + * Bit manipulation + */ #define BIT(shift) (1UL << (shift)) #define BIT_MASK_SHIFT(mask, shift) ((mask) << (shift)) - -/* Return bits m to n of x */ +/* Bits m to n of x */ #define GET_BITS(x, m, n) ((((uint32)x) << (31 - (n))) >> ((31 - (n)) + (m))) +#define IS_POWER_OF_TWO(v) (v && !(v & (v - 1))) /* * Register reads and writes */ -#define __set_bits(addr, mask) (*(volatile uint32*)(addr) |= (uint32)(mask)) -#define __clear_bits(addr, mask) (*(volatile uint32*)(addr) &= (uint32)~(mask)) -#define __get_bits(addr, mask) (*(volatile uint32*)(addr) & (uint32)(mask)) #define __read(reg) (*(volatile uint32*)(reg)) #define __write(reg, value) (*(volatile uint32*)(reg) = (value)) -#define IS_POWER_OF_TWO(v) (v && !(v & (v - 1))) - /* * Failure routines */ @@ -77,13 +65,20 @@ void throb(void); * Asserts and debug levels */ +#define DEBUG_NONE 0 +#define DEBUG_FAULT 1 +#define DEBUG_ALL 2 + +#ifndef DEBUG_LEVEL +#define DEBUG_LEVEL DEBUG_ALL +#endif + #if DEBUG_LEVEL >= DEBUG_ALL #define ASSERT(exp) \ if (exp) { \ } else { \ _fail(__FILE__, __LINE__, #exp); \ } - #else #define ASSERT(exp) (void)((0)) #endif @@ -94,7 +89,6 @@ void throb(void); } else { \ _fail(__FILE__, __LINE__, #exp); \ } - #else #define ASSERT_FAULT(exp) (void)((0)) #endif @@ -104,4 +98,3 @@ void throb(void); #endif #endif - |