summaryrefslogtreecommitdiff
path: root/chip/nrf51/hwtimer.c
diff options
context:
space:
mode:
authorMyles Watson <mylesgw@chromium.org>2015-02-26 11:40:44 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-07-22 18:40:13 -0700
commitc44ee5f93d354f38dfacec6bd63b5d40392a7e55 (patch)
tree4653392390b5a527b1509fa640986c8bbc0bb2ff /chip/nrf51/hwtimer.c
parenta11c8b0b1465630540f87971b981545232da2f4c (diff)
downloadchrome-ec-c44ee5f93d354f38dfacec6bd63b5d40392a7e55.tar.gz
nrf51: Make timer handling names more obvious
There are three timers, each with four capture/compare (CC) registers. The timer code uses 3 CC registers from one timer. Use macros for the defines, so that it is more obvious which timer and which register are being used. TEST=make BOARD=hadoken BRANCH=NONE BUG=None Change-Id: Icb058d9717800a87b394270eef38a3a744a13b7d Signed-off-by: Myles Watson <mylesgw@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/361793 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Levi Oliver <levio@google.com>
Diffstat (limited to 'chip/nrf51/hwtimer.c')
-rw-r--r--chip/nrf51/hwtimer.c76
1 files changed, 46 insertions, 30 deletions
diff --git a/chip/nrf51/hwtimer.c b/chip/nrf51/hwtimer.c
index 281b21211b..75079789dc 100644
--- a/chip/nrf51/hwtimer.c
+++ b/chip/nrf51/hwtimer.c
@@ -6,12 +6,8 @@
/*
* Hardware timers driver.
*
- * nRF51x has one hardware counter, but 4 stand-alone capture/compare (CC)
- * registers.
- *
- * CC(0) -- used to interrupt next clock event.
- * CC(1) -- used to capture the current value.
- * CC(2) -- used to detect overflow on virtual timer (not hardware).
+ * nRF51x has one fully functional hardware counter, but 4 stand-alone
+ * capture/compare (CC) registers.
*/
#include "common.h"
@@ -20,11 +16,25 @@
#include "hwtimer.h"
#include "registers.h"
#include "task.h"
+#include "util.h"
#define CPUTS(outstr) cputs(CC_CLOCK, outstr)
#define CPRINTF(format, args...) cprintf(CC_CLOCK, format, ## args)
#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args)
+/*
+ * capture/compare (CC) registers:
+ * CC_INTERRUPT -- used to interrupt next clock event.
+ * CC_CURRENT -- used to capture the current value.
+ * CC_OVERFLOW -- used to detect overflow on virtual timer (not hardware).
+ */
+
+#define CC_INTERRUPT 0
+#define CC_CURRENT 1
+#define CC_OVERFLOW 2
+
+/* The nRF51 has 3 timers, use HWTIMER to specify which one is used here. */
+#define HWTIMER 0
static uint32_t last_deadline; /* cache of event set */
@@ -60,10 +70,11 @@ static uint32_t shift;
void __hw_clock_event_set(uint32_t deadline)
{
last_deadline = deadline;
- NRF51_TIMER0_CC0 = deadline - shift;
+ NRF51_TIMER_CC(HWTIMER, CC_INTERRUPT) = deadline - shift;
/* enable interrupt */
- NRF51_TIMER0_INTENSET = 1 << NRF51_TIMER_COMPARE0_BIT;
+ NRF51_TIMER_INTENSET(HWTIMER) =
+ 1 << NRF51_TIMER_COMPARE_BIT(CC_INTERRUPT);
}
uint32_t __hw_clock_event_get(void)
@@ -74,14 +85,15 @@ uint32_t __hw_clock_event_get(void)
void __hw_clock_event_clear(void)
{
/* disable interrupt */
- NRF51_TIMER0_INTENCLR = 1 << NRF51_TIMER_COMPARE0_BIT;
+ NRF51_TIMER_INTENCLR(HWTIMER) =
+ 1 << NRF51_TIMER_COMPARE_BIT(CC_INTERRUPT);
}
uint32_t __hw_clock_source_read(void)
{
/* to capture the current value */
- NRF51_TIMER0_CAPTURE1 = 1;
- return NRF51_TIMER0_CC1 + shift;
+ NRF51_TIMER_CAPTURE(HWTIMER, CC_CURRENT) = 1;
+ return NRF51_TIMER_CC(HWTIMER, CC_CURRENT) + shift;
}
void __hw_clock_source_set(uint32_t ts)
@@ -89,17 +101,17 @@ void __hw_clock_source_set(uint32_t ts)
shift = ts;
/* reset counter to zero */
- NRF51_TIMER0_STOP = 1;
- NRF51_TIMER0_CLEAR = 1;
+ NRF51_TIMER_STOP(HWTIMER) = 1;
+ NRF51_TIMER_CLEAR(HWTIMER) = 1;
/* So that no interrupt until next __hw_clock_event_set() */
- NRF51_TIMER0_CC0 = ts - 1;
+ NRF51_TIMER_CC(HWTIMER, CC_INTERRUPT) = ts - 1;
/* Update the overflow point */
- NRF51_TIMER0_CC2 = 0 - shift;
+ NRF51_TIMER_CC(HWTIMER, CC_OVERFLOW) = 0 - shift;
/* Start the timer again */
- NRF51_TIMER0_START = 1;
+ NRF51_TIMER_START(HWTIMER) = 1;
}
@@ -109,55 +121,59 @@ void timer_irq(void)
int overflow = 0;
/* clear status */
- NRF51_TIMER0_COMPARE0 = 0;
+ NRF51_TIMER_COMPARE(HWTIMER, CC_INTERRUPT) = 0;
- if (NRF51_TIMER0_COMPARE2) {
- NRF51_TIMER0_COMPARE2 = 0;
+ if (NRF51_TIMER_COMPARE(HWTIMER, CC_OVERFLOW)) {
+ NRF51_TIMER_COMPARE(HWTIMER, CC_OVERFLOW) = 0;
overflow = 1;
}
process_timers(overflow);
}
-DECLARE_IRQ(NRF51_PERID_TIMER0, timer_irq, 1);
+/* DECLARE_IRQ doesn't like the NRF51_PERID_TIMER(n) macro */
+BUILD_ASSERT(NRF51_PERID_TIMER(HWTIMER) == NRF51_PERID_TIMER0);
+DECLARE_IRQ(NRF51_PERID_TIMER0, timer_irq, 1);
int __hw_clock_source_init(uint32_t start_t)
{
+
/* Start the high freq crystal oscillator */
NRF51_CLOCK_HFCLKSTART = 1;
/* TODO: check if the crystal oscillator is running (HFCLKSTAT) */
/* 32-bit timer mode */
- NRF51_TIMER0_MODE = NRF51_TIMER0_MODE_TIMER;
- NRF51_TIMER0_BITMODE = NRF51_TIMER0_BITMODE_32;
+ NRF51_TIMER_MODE(HWTIMER) = NRF51_TIMER_MODE_TIMER;
+ NRF51_TIMER_BITMODE(HWTIMER) = NRF51_TIMER_BITMODE_32;
/*
* The external crystal oscillator is 16MHz (HFCLK).
* Set the prescaler to 16 so that the timer counter is increasing
* every micro-second (us).
*/
- NRF51_TIMER0_PRESCALER = 4; /* actual value is 2**4 = 16 */
+ NRF51_TIMER_PRESCALER(HWTIMER) = 4; /* actual value is 2**4 = 16 */
/* Not to trigger interrupt until __hw_clock_event_set() is called. */
- NRF51_TIMER0_CC0 = 0xffffffff;
+ NRF51_TIMER_CC(HWTIMER, CC_INTERRUPT) = 0xffffffff;
/* Set to 0 so that the next overflow can trigger timer_irq(). */
- NRF51_TIMER0_CC2 = 0;
- NRF51_TIMER0_INTENSET = 1 << NRF51_TIMER_COMPARE2_BIT;
+ NRF51_TIMER_CC(HWTIMER, CC_OVERFLOW) = 0;
+ NRF51_TIMER_INTENSET(HWTIMER) =
+ 1 << NRF51_TIMER_COMPARE_BIT(CC_OVERFLOW);
/* Clear the timer counter */
- NRF51_TIMER0_CLEAR = 1;
+ NRF51_TIMER_CLEAR(HWTIMER) = 1;
/* Override the count with the start value now that counting has
* started. */
__hw_clock_source_set(start_t);
/* Enable interrupt */
- task_enable_irq(NRF51_PERID_TIMER0);
+ task_enable_irq(NRF51_PERID_TIMER(HWTIMER));
/* Start the timer */
- NRF51_TIMER0_START = 1;
+ NRF51_TIMER_START(HWTIMER) = 1;
- return NRF51_PERID_TIMER0;
+ return NRF51_PERID_TIMER(HWTIMER);
}