aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple
diff options
context:
space:
mode:
Diffstat (limited to 'libmaple')
-rw-r--r--libmaple/systick.c54
-rw-r--r--libmaple/systick.h46
-rw-r--r--libmaple/util.h37
3 files changed, 81 insertions, 56 deletions
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
-