Repository: incubator-mynewt-core Updated Branches: refs/heads/develop 6c9762b1e -> 21387d2b7
MYNEWT-538: Add RTC to hal timers for nordic platforms Added RTC0 only to the hal timers for the nordic platforms. Note that the only frequency we currently allow for this timer is 32768. Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/21387d2b Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/21387d2b Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/21387d2b Branch: refs/heads/develop Commit: 21387d2b7b17089459cef4c4264b9dead5c98d3f Parents: 6c9762b Author: William San Filippo <[email protected]> Authored: Fri Jan 6 13:07:05 2017 -0800 Committer: William San Filippo <[email protected]> Committed: Fri Jan 6 13:10:19 2017 -0800 ---------------------------------------------------------------------- apps/bletest/src/main.c | 4 +- hw/bsp/arduino_primo_nrf52/src/hal_bsp.c | 4 + hw/bsp/arduino_primo_nrf52/syscfg.yml | 3 + hw/bsp/bmd300eval/src/hal_bsp.c | 4 + hw/bsp/bmd300eval/syscfg.yml | 3 + hw/bsp/nrf51-arduino_101/src/hal_bsp.c | 4 + hw/bsp/nrf51-arduino_101/syscfg.yml | 3 + hw/bsp/nrf51-blenano/src/hal_bsp.c | 4 + hw/bsp/nrf51-blenano/syscfg.yml | 3 + hw/bsp/nrf51dk-16kbram/src/hal_bsp.c | 4 + hw/bsp/nrf51dk-16kbram/syscfg.yml | 3 + hw/bsp/nrf51dk/src/hal_bsp.c | 5 + hw/bsp/nrf51dk/syscfg.yml | 3 + hw/bsp/nrf52840pdk/src/hal_bsp.c | 4 + hw/bsp/nrf52840pdk/syscfg.yml | 3 + hw/bsp/nrf52dk/src/hal_bsp.c | 4 + hw/bsp/nrf52dk/syscfg.yml | 3 + hw/bsp/rb-nano2/src/hal_bsp.c | 5 +- hw/bsp/rb-nano2/syscfg.yml | 3 + hw/mcu/nordic/nrf51xxx/src/hal_timer.c | 232 +++++++++++++++++++--- hw/mcu/nordic/nrf52xxx/src/hal_timer.c | 272 ++++++++++++++++++++++---- 21 files changed, 502 insertions(+), 71 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/apps/bletest/src/main.c ---------------------------------------------------------------------- diff --git a/apps/bletest/src/main.c b/apps/bletest/src/main.c index 5a3627e..11ecb4e 100755 --- a/apps/bletest/src/main.c +++ b/apps/bletest/src/main.c @@ -67,8 +67,8 @@ uint8_t g_host_adv_len; #define BLETEST_ROLE_SCANNER (1) #define BLETEST_ROLE_INITIATOR (2) -//#define BLETEST_CFG_ROLE (BLETEST_ROLE_INITIATOR) -#define BLETEST_CFG_ROLE (BLETEST_ROLE_ADVERTISER) +#define BLETEST_CFG_ROLE (BLETEST_ROLE_INITIATOR) +//#define BLETEST_CFG_ROLE (BLETEST_ROLE_ADVERTISER) //#define BLETEST_CFG_ROLE (BLETEST_ROLE_SCANNER) /* Advertiser config */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/arduino_primo_nrf52/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/arduino_primo_nrf52/src/hal_bsp.c b/hw/bsp/arduino_primo_nrf52/src/hal_bsp.c index 1a61b07..ea2d74f 100644 --- a/hw/bsp/arduino_primo_nrf52/src/hal_bsp.c +++ b/hw/bsp/arduino_primo_nrf52/src/hal_bsp.c @@ -163,6 +163,10 @@ hal_bsp_init(void) rc = hal_timer_init(4, NULL); assert(rc == 0); #endif +#if MYNEWT_VAL(TIMER_5) + rc = hal_timer_init(5, NULL); + assert(rc == 0); +#endif /* Set cputime to count at 1 usec increments */ rc = os_cputime_init(MYNEWT_VAL(CLOCK_FREQ)); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/arduino_primo_nrf52/syscfg.yml ---------------------------------------------------------------------- diff --git a/hw/bsp/arduino_primo_nrf52/syscfg.yml b/hw/bsp/arduino_primo_nrf52/syscfg.yml index c353c54..3052b94 100644 --- a/hw/bsp/arduino_primo_nrf52/syscfg.yml +++ b/hw/bsp/arduino_primo_nrf52/syscfg.yml @@ -110,6 +110,9 @@ syscfg.defs: TIMER_4: description: 'NRF52 Timer 4' value: 0 + TIMER_5: + description: 'NRF52 RTC 0' + value: 1 syscfg.vals: CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/bmd300eval/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/bmd300eval/src/hal_bsp.c b/hw/bsp/bmd300eval/src/hal_bsp.c index 7bd7e2d..6d70e4a 100644 --- a/hw/bsp/bmd300eval/src/hal_bsp.c +++ b/hw/bsp/bmd300eval/src/hal_bsp.c @@ -158,6 +158,10 @@ hal_bsp_init(void) rc = hal_timer_init(4, NULL); assert(rc == 0); #endif +#if MYNEWT_VAL(TIMER_5) + rc = hal_timer_init(5, NULL); + assert(rc == 0); +#endif /* Set cputime to count at 1 usec increments */ rc = os_cputime_init(MYNEWT_VAL(CLOCK_FREQ)); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/bmd300eval/syscfg.yml ---------------------------------------------------------------------- diff --git a/hw/bsp/bmd300eval/syscfg.yml b/hw/bsp/bmd300eval/syscfg.yml index ccfdadb..2113c25 100644 --- a/hw/bsp/bmd300eval/syscfg.yml +++ b/hw/bsp/bmd300eval/syscfg.yml @@ -86,6 +86,9 @@ syscfg.defs: TIMER_4: description: 'NRF52 Timer 4' value: 0 + TIMER_5: + description: 'NRF52 RTC 0' + value: 1 syscfg.vals: CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/nrf51-arduino_101/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51-arduino_101/src/hal_bsp.c b/hw/bsp/nrf51-arduino_101/src/hal_bsp.c index df33be2..7975d54 100644 --- a/hw/bsp/nrf51-arduino_101/src/hal_bsp.c +++ b/hw/bsp/nrf51-arduino_101/src/hal_bsp.c @@ -153,6 +153,10 @@ hal_bsp_init(void) rc = hal_timer_init(2, NULL); assert(rc == 0); #endif +#if MYNEWT_VAL(TIMER_3) + rc = hal_timer_init(3, NULL); + assert(rc == 0); +#endif /* Set cputime to count at 1 usec increments */ rc = os_cputime_init(MYNEWT_VAL(CLOCK_FREQ)); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/nrf51-arduino_101/syscfg.yml ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51-arduino_101/syscfg.yml b/hw/bsp/nrf51-arduino_101/syscfg.yml index 8c47db4..75c3aca 100644 --- a/hw/bsp/nrf51-arduino_101/syscfg.yml +++ b/hw/bsp/nrf51-arduino_101/syscfg.yml @@ -80,6 +80,9 @@ syscfg.defs: TIMER_2: description: 'NRF51 Timer 2' value: 0 + TIMER_3: + description: 'NRF51 RTC0' + value: 0 syscfg.vals: CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/nrf51-blenano/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51-blenano/src/hal_bsp.c b/hw/bsp/nrf51-blenano/src/hal_bsp.c index c85ece2..85c1c99 100644 --- a/hw/bsp/nrf51-blenano/src/hal_bsp.c +++ b/hw/bsp/nrf51-blenano/src/hal_bsp.c @@ -154,6 +154,10 @@ hal_bsp_init(void) rc = hal_timer_init(2, NULL); assert(rc == 0); #endif +#if MYNEWT_VAL(TIMER_3) + rc = hal_timer_init(3, NULL); + assert(rc == 0); +#endif /* * XXXX, depending on what timer OS_CPUTIME_TIMER_NUM is set to use. http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/nrf51-blenano/syscfg.yml ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51-blenano/syscfg.yml b/hw/bsp/nrf51-blenano/syscfg.yml index 569382d..2376352 100644 --- a/hw/bsp/nrf51-blenano/syscfg.yml +++ b/hw/bsp/nrf51-blenano/syscfg.yml @@ -77,6 +77,9 @@ syscfg.defs: TIMER_2: description: 'NRF51 Timer 2' value: 0 + TIMER_3: + description: 'NRF51 RTC0' + value: 0 syscfg.vals: CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c b/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c index 63b6d94..68e262f 100644 --- a/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c +++ b/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c @@ -164,6 +164,10 @@ hal_bsp_init(void) rc = hal_timer_init(2, NULL); assert(rc == 0); #endif +#if MYNEWT_VAL(TIMER_3) + rc = hal_timer_init(3, NULL); + assert(rc == 0); +#endif /* Set cputime to count at 1 usec increments */ rc = os_cputime_init(MYNEWT_VAL(CLOCK_FREQ)); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/nrf51dk-16kbram/syscfg.yml ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51dk-16kbram/syscfg.yml b/hw/bsp/nrf51dk-16kbram/syscfg.yml index 8e14b43..0bcd8d9 100644 --- a/hw/bsp/nrf51dk-16kbram/syscfg.yml +++ b/hw/bsp/nrf51dk-16kbram/syscfg.yml @@ -77,6 +77,9 @@ syscfg.defs: TIMER_2: description: 'NRF51 Timer 2' value: 0 + TIMER_3: + description: 'NRF51 RTC0' + value: 0 I2C_0: description: 'NRF51 I2C (TWI) interface 0' http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/nrf51dk/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51dk/src/hal_bsp.c b/hw/bsp/nrf51dk/src/hal_bsp.c index 4e65c68..8f5b832 100644 --- a/hw/bsp/nrf51dk/src/hal_bsp.c +++ b/hw/bsp/nrf51dk/src/hal_bsp.c @@ -162,6 +162,11 @@ hal_bsp_init(void) assert(rc == 0); #endif +#if MYNEWT_VAL(TIMER_3) + rc = hal_timer_init(3, NULL); + assert(rc == 0); +#endif + /* Set cputime to count at 1 usec increments */ rc = os_cputime_init(MYNEWT_VAL(CLOCK_FREQ)); assert(rc == 0); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/nrf51dk/syscfg.yml ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51dk/syscfg.yml b/hw/bsp/nrf51dk/syscfg.yml index bade890..89e118f 100644 --- a/hw/bsp/nrf51dk/syscfg.yml +++ b/hw/bsp/nrf51dk/syscfg.yml @@ -77,6 +77,9 @@ syscfg.defs: TIMER_2: description: 'NRF51 Timer 2' value: 0 + TIMER_3: + description: 'NRF51 RTC0' + value: 1 I2C_0: description: 'NRF51 I2C (TWI) interface 0' http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/nrf52840pdk/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf52840pdk/src/hal_bsp.c b/hw/bsp/nrf52840pdk/src/hal_bsp.c index e53d53b..cbe15ea 100644 --- a/hw/bsp/nrf52840pdk/src/hal_bsp.c +++ b/hw/bsp/nrf52840pdk/src/hal_bsp.c @@ -169,6 +169,10 @@ hal_bsp_init(void) rc = hal_timer_init(4, NULL); assert(rc == 0); #endif +#if MYNEWT_VAL(TIMER_5) + rc = hal_timer_init(5, NULL); + assert(rc == 0); +#endif /* Set cputime to count at 1 usec increments */ rc = os_cputime_init(MYNEWT_VAL(CLOCK_FREQ)); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/nrf52840pdk/syscfg.yml ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf52840pdk/syscfg.yml b/hw/bsp/nrf52840pdk/syscfg.yml index d6701eb..452541c 100644 --- a/hw/bsp/nrf52840pdk/syscfg.yml +++ b/hw/bsp/nrf52840pdk/syscfg.yml @@ -91,6 +91,9 @@ syscfg.defs: TIMER_4: description: 'NRF52840 Timer 4' value: 0 + TIMER_5: + description: 'NRF52 RTC 0' + value: 0 I2C_0: description: 'NRF52840 I2C (TWI) interface 0' http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/nrf52dk/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf52dk/src/hal_bsp.c b/hw/bsp/nrf52dk/src/hal_bsp.c index 57b0f4a..188b488 100644 --- a/hw/bsp/nrf52dk/src/hal_bsp.c +++ b/hw/bsp/nrf52dk/src/hal_bsp.c @@ -177,6 +177,10 @@ hal_bsp_init(void) rc = hal_timer_init(4, NULL); assert(rc == 0); #endif +#if MYNEWT_VAL(TIMER_5) + rc = hal_timer_init(5, NULL); + assert(rc == 0); +#endif /* * What this depends on is what the OS_CPUTIME_TIMER_NUM is set to. http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/nrf52dk/syscfg.yml ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf52dk/syscfg.yml b/hw/bsp/nrf52dk/syscfg.yml index 18024af..94653dc 100644 --- a/hw/bsp/nrf52dk/syscfg.yml +++ b/hw/bsp/nrf52dk/syscfg.yml @@ -91,6 +91,9 @@ syscfg.defs: TIMER_4: description: 'NRF52 Timer 4' value: 0 + TIMER_5: + description: 'NRF52 RTC 0' + value: 1 I2C_0: description: 'NRF52 I2C (TWI) interface 0' http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/rb-nano2/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/rb-nano2/src/hal_bsp.c b/hw/bsp/rb-nano2/src/hal_bsp.c index ef4add8..3602354 100644 --- a/hw/bsp/rb-nano2/src/hal_bsp.c +++ b/hw/bsp/rb-nano2/src/hal_bsp.c @@ -150,7 +150,10 @@ hal_bsp_init(void) rc = hal_timer_init(4, NULL); assert(rc == 0); #endif - +#if MYNEWT_VAL(TIMER_5) + rc = hal_timer_init(5, NULL); + assert(rc == 0); +#endif /* Set cputime to count at 1 usec increments */ rc = os_cputime_init(MYNEWT_VAL(CLOCK_FREQ)); assert(rc == 0); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/bsp/rb-nano2/syscfg.yml ---------------------------------------------------------------------- diff --git a/hw/bsp/rb-nano2/syscfg.yml b/hw/bsp/rb-nano2/syscfg.yml index ad48bd6..e97a790 100644 --- a/hw/bsp/rb-nano2/syscfg.yml +++ b/hw/bsp/rb-nano2/syscfg.yml @@ -81,6 +81,9 @@ syscfg.defs: TIMER_4: description: 'NRF52 Timer 4' value: 0 + TIMER_5: + description: 'NRF52 RTC 0' + value: 1 syscfg.vals: CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/mcu/nordic/nrf51xxx/src/hal_timer.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_timer.c b/hw/mcu/nordic/nrf51xxx/src/hal_timer.c index 45e4ac5..ab6a437 100644 --- a/hw/mcu/nordic/nrf51xxx/src/hal_timer.c +++ b/hw/mcu/nordic/nrf51xxx/src/hal_timer.c @@ -40,9 +40,11 @@ typedef void (*hal_timer_irq_handler_t)(void); #define NRF_TIMER_CC_READ (2) #define NRF_TIMER_CC_INT (3) -/* XXX: what about RTC timers? How are they instantiated? How do we - relate timer numbers to them? */ -#define NRF51_HAL_TIMER_MAX (3) +/* Output compare 2 used for RTC timers */ +#define NRF_RTC_TIMER_CC_INT (2) + +/* Maximum number of hal timers used */ +#define NRF51_HAL_TIMER_MAX (4) /* Maximum timer frequency */ #define NRF51_MAX_TIMER_FREQ (16000000) @@ -63,11 +65,11 @@ struct nrf51_hal_timer { uint8_t tmr_enabled; uint8_t tmr_irq_num; uint8_t tmr_16bit; - uint8_t tmr_pad; + uint8_t tmr_rtc; uint32_t tmr_cntr; uint32_t timer_isrs; uint32_t tmr_freq; - NRF_TIMER_Type *tmr_reg; + void *tmr_reg; TAILQ_HEAD(hal_timer_qhead, hal_timer) hal_timer_q; }; @@ -80,6 +82,9 @@ struct nrf51_hal_timer nrf51_hal_timer1; #if MYNEWT_VAL(TIMER_2) struct nrf51_hal_timer nrf51_hal_timer2; #endif +#if MYNEWT_VAL(TIMER_3) +struct nrf51_hal_timer nrf51_hal_timer3; +#endif struct nrf51_hal_timer *nrf51_hal_timers[NRF51_HAL_TIMER_MAX] = { #if MYNEWT_VAL(TIMER_0) @@ -97,8 +102,17 @@ struct nrf51_hal_timer *nrf51_hal_timers[NRF51_HAL_TIMER_MAX] = { #else NULL, #endif +#if MYNEWT_VAL(TIMER_3) + &nrf51_hal_timer3, +#else + NULL, +#endif }; +#define NRF51_TIMER_DEFINED \ + (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2) || \ + MYNEWT_VAL(TIMER_3)) + /* Resolve timer number into timer structure */ #define NRF51_HAL_TIMER_RESOLVE(__n, __v) \ if ((__n) >= NRF51_HAL_TIMER_MAX) { \ @@ -140,15 +154,16 @@ nrf_timer_set_ocmp(struct nrf51_hal_timer *bsptimer, uint32_t expiry) { int32_t delta_t; uint16_t expiry16; + uint32_t expiry24; uint32_t temp; NRF_TIMER_Type *hwtimer; - - hwtimer = bsptimer->tmr_reg; - - /* Disable ocmp interrupt and set new value */ - hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + NRF_RTC_Type *rtctimer; if (bsptimer->tmr_16bit) { + /* Disable ocmp interrupt */ + hwtimer = (NRF_TIMER_Type *)bsptimer->tmr_reg; + hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + temp = expiry & 0xffff0000; delta_t = (int32_t)(temp - bsptimer->tmr_cntr); if (delta_t < 0) { @@ -165,13 +180,46 @@ nrf_timer_set_ocmp(struct nrf51_hal_timer *bsptimer, uint32_t expiry) hwtimer->INTENSET = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); /* Force interrupt to occur as we may have missed it */ - if (nrf_read_timer_cntr(hwtimer) >= expiry16) { + if ((nrf_read_timer_cntr(hwtimer) >= expiry16) || + (hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_OVERFLOW])) { goto set_ocmp_late; } } else { /* Nothing to do; wait for overflow interrupt to set ocmp */ } + } else if (bsptimer->tmr_rtc) { + /* The RTC is a 24-bit counter so we need to check them first */ + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + temp = expiry & 0xff000000; + delta_t = (int32_t)(temp - bsptimer->tmr_cntr); + if (delta_t < 0) { + goto set_ocmp_late; + } else if (delta_t == 0) { + /* Check if we might miss the timer */ + expiry24 = expiry & 0x00ffffff; + + /* + * The nrf documentation states that you must set the output + * compare to 2 greater than the counter to guarntee an interrupt. + * Since the counter can tick once while we check, we make sure + * it is greater than 2. + */ + if ((expiry <= (rtctimer->COUNTER+2)) || rtctimer->EVENTS_OVRFLW) { + goto set_ocmp_late; + } + + /* Set the output compare and enable interrupt */ + rtctimer->CC[NRF_RTC_TIMER_CC_INT] = expiry24; + rtctimer->INTENSET = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + } else { + /* Nothing to do; wait for overflow interrupt to set ocmp */ + } } else { + /* Disable ocmp interrupt */ + hwtimer = (NRF_TIMER_Type *)bsptimer->tmr_reg; + hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + /* Set output compare register to timer expiration */ hwtimer->CC[NRF_TIMER_CC_INT] = expiry; @@ -192,7 +240,6 @@ set_ocmp_late: NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); } - /* Disable output compare used for timer */ static void nrf_timer_disable_ocmp(NRF_TIMER_Type *hwtimer) @@ -200,16 +247,24 @@ nrf_timer_disable_ocmp(NRF_TIMER_Type *hwtimer) hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); } +static void +nrf_rtc_disable_ocmp(NRF_RTC_Type *rtctimer) +{ + rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); +} + static uint32_t hal_timer_read_bsptimer(struct nrf51_hal_timer *bsptimer) { uint16_t low; + uint32_t low32; uint32_t ctx; uint32_t tcntr; NRF_TIMER_Type *hwtimer; + NRF_RTC_Type *rtctimer; if (bsptimer->tmr_16bit) { - hwtimer = bsptimer->tmr_reg; + hwtimer = (NRF_TIMER_Type *)bsptimer->tmr_reg; __HAL_DISABLE_INTERRUPTS(ctx); tcntr = bsptimer->tmr_cntr; low = nrf_read_timer_cntr(hwtimer); @@ -222,6 +277,20 @@ hal_timer_read_bsptimer(struct nrf51_hal_timer *bsptimer) } tcntr |= low; __HAL_ENABLE_INTERRUPTS(ctx); + } else if (bsptimer->tmr_rtc) { + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + __HAL_DISABLE_INTERRUPTS(ctx); + tcntr = bsptimer->tmr_cntr; + low32 = rtctimer->COUNTER; + if (rtctimer->EVENTS_OVRFLW) { + tcntr += (1UL << 24); + bsptimer->tmr_cntr = tcntr; + low32 = rtctimer->COUNTER; + rtctimer->EVENTS_OVRFLW = 0; + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } + tcntr |= low32; + __HAL_ENABLE_INTERRUPTS(ctx); } else { /* Force a capture of the timer into 'cntr' capture channel; read it */ tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg); @@ -230,7 +299,7 @@ hal_timer_read_bsptimer(struct nrf51_hal_timer *bsptimer) return tcntr; } -#if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2)) +#if NRF51_TIMER_DEFINED /** * hal timer chk queue * @@ -247,7 +316,7 @@ hal_timer_chk_queue(struct nrf51_hal_timer *bsptimer) /* disable interrupts */ __HAL_DISABLE_INTERRUPTS(ctx); while ((timer = TAILQ_FIRST(&bsptimer->hal_timer_q)) != NULL) { - if (bsptimer->tmr_16bit) { + if (bsptimer->tmr_16bit || bsptimer->tmr_rtc) { tcntr = hal_timer_read_bsptimer(bsptimer); } else { tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg); @@ -266,11 +335,14 @@ hal_timer_chk_queue(struct nrf51_hal_timer *bsptimer) if (timer) { nrf_timer_set_ocmp(bsptimer, timer->expiry); } else { - nrf_timer_disable_ocmp(bsptimer->tmr_reg); + if (bsptimer->tmr_rtc) { + nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg); + } else { + nrf_timer_disable_ocmp(bsptimer->tmr_reg); + } } __HAL_ENABLE_INTERRUPTS(ctx); } - #endif /** @@ -286,8 +358,7 @@ hal_timer_chk_queue(struct nrf51_hal_timer *bsptimer) * This is the global timer interrupt routine. * */ -#if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2)) - +#if NRF51_TIMER_DEFINED static void hal_timer_irq_handler(struct nrf51_hal_timer *bsptimer) { @@ -330,6 +401,46 @@ hal_timer_irq_handler(struct nrf51_hal_timer *bsptimer) } #endif +#if MYNEWT_VAL(TIMER_3) +static void +hal_rtc_timer_irq_handler(struct nrf51_hal_timer *bsptimer) +{ + uint32_t overflow; + uint32_t compare; + NRF_RTC_Type *rtctimer; + + /* Check interrupt source. If set, clear them */ + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT]; + if (compare) { + rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT] = 0; + } + + overflow = rtctimer->EVENTS_OVRFLW; + if (overflow) { + rtctimer->EVENTS_OVRFLW = 0; + bsptimer->tmr_cntr += (1UL << 24); + } + + /* Count # of timer isrs */ + ++bsptimer->timer_isrs; + + /* + * NOTE: we dont check the 'compare' variable here due to how the timer + * is implemented on this chip. There is no way to force an output + * compare, so if we are late setting the output compare (i.e. the timer + * counter is already passed the output compare value), we use the NVIC + * to set a pending interrupt. This means that there will be no compare + * flag set, so all we do is check to see if the compare interrupt is + * enabled. + */ + hal_timer_chk_queue(bsptimer); + + /* Recommended by nordic to make sure interrupts are cleared */ + compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT]; +} +#endif + #if MYNEWT_VAL(TIMER_0) void nrf51_timer0_irq_handler(void) @@ -354,6 +465,14 @@ nrf51_timer2_irq_handler(void) } #endif +#if MYNEWT_VAL(TIMER_3) +void +nrf51_timer3_irq_handler(void) +{ + hal_rtc_timer_irq_handler(&nrf51_hal_timer3); +} +#endif + /** * hal timer init * @@ -370,7 +489,7 @@ hal_timer_init(int timer_num, void *cfg) int rc; uint8_t irq_num; struct nrf51_hal_timer *bsptimer; - NRF_TIMER_Type *hwtimer; + void *hwtimer; hal_timer_irq_handler_t irq_isr; NRF51_HAL_TIMER_RESOLVE(timer_num, bsptimer); @@ -405,6 +524,14 @@ hal_timer_init(int timer_num, void *cfg) bsptimer->tmr_16bit = 1; break; #endif +#if MYNEWT_VAL(TIMER_3) + case 3: + irq_num = RTC0_IRQn; + hwtimer = NRF_RTC0; + irq_isr = nrf51_timer3_irq_handler; + bsptimer->tmr_rtc = 1; + break; +#endif default: hwtimer = NULL; break; @@ -450,9 +577,49 @@ hal_timer_config(int timer_num, uint32_t freq_hz) uint32_t max_delta; struct nrf51_hal_timer *bsptimer; NRF_TIMER_Type *hwtimer; +#if MYNEWT_VAL(TIMER_3) + NRF_RTC_Type *rtctimer; +#endif NRF51_HAL_TIMER_RESOLVE(timer_num, bsptimer); +#if MYNEWT_VAL(TIMER_3) + if (timer_num == 3) { + /* NOTE: we only allow the RTC frequency to be set at 32768 */ + if (bsptimer->tmr_enabled || (freq_hz != 32768) || + (bsptimer->tmr_reg == NULL)) { + rc = EINVAL; + goto err; + } + + bsptimer->tmr_freq = freq_hz; + bsptimer->tmr_enabled = 1; + + __HAL_DISABLE_INTERRUPTS(ctx); + + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + + /* Stop the timer first */ + rtctimer->TASKS_STOP = 1; + + /* Always no prescaler */ + rtctimer->PRESCALER = 0; + + /* Clear overflow events and set overflow interrupt */ + rtctimer->EVENTS_OVRFLW = 0; + rtctimer->INTENSET = RTC_INTENSET_OVRFLW_Msk; + + /* Start the timer */ + rtctimer->TASKS_START = 1; + + /* Set isr in vector table and enable interrupt */ + NVIC_EnableIRQ(bsptimer->tmr_irq_num); + + __HAL_ENABLE_INTERRUPTS(ctx); + return 0; + } +#endif + /* Set timer to desired frequency */ div = NRF51_MAX_TIMER_FREQ / freq_hz; @@ -497,7 +664,7 @@ hal_timer_config(int timer_num, uint32_t freq_hz) } } } - hwtimer = bsptimer->tmr_reg; + hwtimer = (NRF_TIMER_Type *)bsptimer->tmr_reg; /* Stop the timer first */ hwtimer->TASKS_STOP = 1; @@ -547,16 +714,23 @@ hal_timer_deinit(int timer_num) uint32_t ctx; struct nrf51_hal_timer *bsptimer; NRF_TIMER_Type *hwtimer; + NRF_RTC_Type *rtctimer; NRF51_HAL_TIMER_RESOLVE(timer_num, bsptimer); __HAL_DISABLE_INTERRUPTS(ctx); - hwtimer = bsptimer->tmr_reg; - hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); - hwtimer->TASKS_STOP = 1; - __HAL_ENABLE_INTERRUPTS(ctx); - + if (bsptimer->tmr_rtc) { + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + rtctimer->TASKS_STOP = 1; + } else { + hwtimer = (NRF_TIMER_Type *)bsptimer->tmr_reg; + hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + hwtimer->TASKS_STOP = 1; + } bsptimer->tmr_enabled = 0; + bsptimer->tmr_reg = NULL; + __HAL_ENABLE_INTERRUPTS(ctx); err: return rc; @@ -760,7 +934,11 @@ hal_timer_stop(struct hal_timer *timer) nrf_timer_set_ocmp((struct nrf51_hal_timer *)entry->bsp_timer, entry->expiry); } else { - nrf_timer_disable_ocmp(bsptimer->tmr_reg); + if (bsptimer->tmr_rtc) { + nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg); + } else { + nrf_timer_disable_ocmp(bsptimer->tmr_reg); + } } } } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/21387d2b/hw/mcu/nordic/nrf52xxx/src/hal_timer.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_timer.c b/hw/mcu/nordic/nrf52xxx/src/hal_timer.c index c721903..d556f2c 100644 --- a/hw/mcu/nordic/nrf52xxx/src/hal_timer.c +++ b/hw/mcu/nordic/nrf52xxx/src/hal_timer.c @@ -34,9 +34,11 @@ typedef void (*hal_timer_irq_handler_t)(void); #define NRF_TIMER_CC_READ (2) #define NRF_TIMER_CC_INT (3) -/* XXX: what about RTC timers? How are they instantiated? How do we - relate timer numbers to them? */ -#define NRF52_HAL_TIMER_MAX (5) +/* Output compare 2 used for RTC timers */ +#define NRF_RTC_TIMER_CC_INT (2) + +/* Maximum number of hal timers used */ +#define NRF52_HAL_TIMER_MAX (6) /* Maximum timer frequency */ #define NRF52_MAX_TIMER_FREQ (16000000) @@ -44,10 +46,12 @@ typedef void (*hal_timer_irq_handler_t)(void); struct nrf52_hal_timer { uint8_t tmr_enabled; uint8_t tmr_irq_num; - uint8_t tmr_pad[2]; + uint8_t tmr_rtc; + uint8_t tmr_pad; + uint32_t tmr_cntr; uint32_t timer_isrs; uint32_t tmr_freq; - NRF_TIMER_Type *tmr_reg; + void *tmr_reg; TAILQ_HEAD(hal_timer_qhead, hal_timer) hal_timer_q; }; @@ -66,6 +70,9 @@ struct nrf52_hal_timer nrf52_hal_timer3; #if MYNEWT_VAL(TIMER_4) struct nrf52_hal_timer nrf52_hal_timer4; #endif +#if MYNEWT_VAL(TIMER_5) +struct nrf52_hal_timer nrf52_hal_timer5; +#endif static const struct nrf52_hal_timer *nrf52_hal_timers[NRF52_HAL_TIMER_MAX] = { #if MYNEWT_VAL(TIMER_0) @@ -89,7 +96,12 @@ static const struct nrf52_hal_timer *nrf52_hal_timers[NRF52_HAL_TIMER_MAX] = { NULL, #endif #if MYNEWT_VAL(TIMER_4) - &nrf52_hal_timer4 + &nrf52_hal_timer4, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_5) + &nrf52_hal_timer5 #else NULL #endif @@ -134,25 +146,59 @@ nrf_read_timer_cntr(NRF_TIMER_Type *hwtimer) static void nrf_timer_set_ocmp(struct nrf52_hal_timer *bsptimer, uint32_t expiry) { + int32_t delta_t; + uint32_t expiry24; + uint32_t temp; NRF_TIMER_Type *hwtimer; + NRF_RTC_Type *rtctimer; + + if (bsptimer->tmr_rtc) { + /* The RTC is a 24-bit counter so we need to check them first */ + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + temp = expiry & 0xff000000; + delta_t = (int32_t)(temp - bsptimer->tmr_cntr); + if (delta_t < 0) { + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } else if (delta_t == 0) { + /* Check if we might miss the timer */ + expiry24 = expiry & 0x00ffffff; + + /* + * The nrf documentation states that you must set the output + * compare to 2 greater than the counter to guarntee an interrupt. + * Since the counter can tick once while we check, we make sure + * it is greater than 2. + */ + if ((expiry <= (rtctimer->COUNTER+2)) || rtctimer->EVENTS_OVRFLW) { + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } - hwtimer = bsptimer->tmr_reg; + /* Set the output compare and enable interrupt */ + rtctimer->CC[NRF_RTC_TIMER_CC_INT] = expiry24; + rtctimer->INTENSET = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + } else { + /* Nothing to do; wait for overflow interrupt to set ocmp */ + } + } else { + hwtimer = bsptimer->tmr_reg; - /* Disable ocmp interrupt and set new value */ - hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + /* Disable ocmp interrupt and set new value */ + hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); - /* Set output compare register to timer expiration */ - hwtimer->CC[NRF_TIMER_CC_INT] = expiry; + /* Set output compare register to timer expiration */ + hwtimer->CC[NRF_TIMER_CC_INT] = expiry; - /* Clear interrupt flag */ - hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT] = 0; + /* Clear interrupt flag */ + hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT] = 0; - /* Enable the output compare interrupt */ - hwtimer->INTENSET = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + /* Enable the output compare interrupt */ + hwtimer->INTENSET = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); - /* Force interrupt to occur as we may have missed it */ - if ((int32_t)(nrf_read_timer_cntr(hwtimer) - expiry) >= 0) { - NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + /* Force interrupt to occur as we may have missed it */ + if ((int32_t)(nrf_read_timer_cntr(hwtimer) - expiry) >= 0) { + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } } } @@ -163,8 +209,39 @@ nrf_timer_disable_ocmp(NRF_TIMER_Type *hwtimer) hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); } +static void +nrf_rtc_disable_ocmp(NRF_RTC_Type *rtctimer) +{ + rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); +} + +static uint32_t +hal_timer_read_bsptimer(struct nrf52_hal_timer *bsptimer) +{ + uint32_t low32; + uint32_t ctx; + uint32_t tcntr; + NRF_RTC_Type *rtctimer; + + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + __HAL_DISABLE_INTERRUPTS(ctx); + tcntr = bsptimer->tmr_cntr; + low32 = rtctimer->COUNTER; + if (rtctimer->EVENTS_OVRFLW) { + tcntr += (1UL << 24); + bsptimer->tmr_cntr = tcntr; + low32 = rtctimer->COUNTER; + rtctimer->EVENTS_OVRFLW = 0; + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } + tcntr |= low32; + __HAL_ENABLE_INTERRUPTS(ctx); + + return tcntr; +} + #if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2) || \ - MYNEWT_VAL(TIMER_3) || MYNEWT_VAL(TIMER_4)) + MYNEWT_VAL(TIMER_3) || MYNEWT_VAL(TIMER_4) || MYNEWT_VAL(TIMER_5)) /** * hal timer chk queue * @@ -181,7 +258,11 @@ hal_timer_chk_queue(struct nrf52_hal_timer *bsptimer) /* disable interrupts */ __HAL_DISABLE_INTERRUPTS(ctx); while ((timer = TAILQ_FIRST(&bsptimer->hal_timer_q)) != NULL) { - tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg); + if (bsptimer->tmr_rtc) { + tcntr = hal_timer_read_bsptimer(bsptimer); + } else { + tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg); + } if ((int32_t)(tcntr - timer->expiry) >= 0) { TAILQ_REMOVE(&bsptimer->hal_timer_q, timer, link); timer->link.tqe_prev = NULL; @@ -196,7 +277,11 @@ hal_timer_chk_queue(struct nrf52_hal_timer *bsptimer) if (timer) { nrf_timer_set_ocmp(bsptimer, timer->expiry); } else { - nrf_timer_disable_ocmp(bsptimer->tmr_reg); + if (bsptimer->tmr_rtc) { + nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg); + } else { + nrf_timer_disable_ocmp(bsptimer->tmr_reg); + } } __HAL_ENABLE_INTERRUPTS(ctx); } @@ -252,6 +337,46 @@ hal_timer_irq_handler(struct nrf52_hal_timer *bsptimer) } #endif +#if MYNEWT_VAL(TIMER_5) +static void +hal_rtc_timer_irq_handler(struct nrf52_hal_timer *bsptimer) +{ + uint32_t overflow; + uint32_t compare; + NRF_RTC_Type *rtctimer; + + /* Check interrupt source. If set, clear them */ + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT]; + if (compare) { + rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT] = 0; + } + + overflow = rtctimer->EVENTS_OVRFLW; + if (overflow) { + rtctimer->EVENTS_OVRFLW = 0; + bsptimer->tmr_cntr += (1UL << 24); + } + + /* Count # of timer isrs */ + ++bsptimer->timer_isrs; + + /* + * NOTE: we dont check the 'compare' variable here due to how the timer + * is implemented on this chip. There is no way to force an output + * compare, so if we are late setting the output compare (i.e. the timer + * counter is already passed the output compare value), we use the NVIC + * to set a pending interrupt. This means that there will be no compare + * flag set, so all we do is check to see if the compare interrupt is + * enabled. + */ + hal_timer_chk_queue(bsptimer); + + /* Recommended by nordic to make sure interrupts are cleared */ + compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT]; +} +#endif + #if MYNEWT_VAL(TIMER_0) void nrf52_timer0_irq_handler(void) @@ -292,6 +417,14 @@ nrf52_timer4_irq_handler(void) } #endif +#if MYNEWT_VAL(TIMER_5) +void +nrf52_timer5_irq_handler(void) +{ + hal_rtc_timer_irq_handler(&nrf52_hal_timer5); +} +#endif + /** * hal timer init * @@ -308,7 +441,7 @@ hal_timer_init(int timer_num, void *cfg) int rc; uint8_t irq_num; struct nrf52_hal_timer *bsptimer; - NRF_TIMER_Type *hwtimer; + void *hwtimer; hal_timer_irq_handler_t irq_isr; NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer); @@ -355,6 +488,14 @@ hal_timer_init(int timer_num, void *cfg) irq_isr = nrf52_timer4_irq_handler; break; #endif +#if MYNEWT_VAL(TIMER_5) + case 5: + irq_num = RTC0_IRQn; + hwtimer = NRF_RTC0; + irq_isr = nrf52_timer5_irq_handler; + bsptimer->tmr_rtc = 1; + break; +#endif default: hwtimer = NULL; break; @@ -400,9 +541,49 @@ hal_timer_config(int timer_num, uint32_t freq_hz) uint32_t max_delta; struct nrf52_hal_timer *bsptimer; NRF_TIMER_Type *hwtimer; +#if MYNEWT_VAL(TIMER_5) + NRF_RTC_Type *rtctimer; +#endif NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer); +#if MYNEWT_VAL(TIMER_5) + if (timer_num == 5) { + /* NOTE: we only allow the RTC frequency to be set at 32768 */ + if (bsptimer->tmr_enabled || (freq_hz != 32768) || + (bsptimer->tmr_reg == NULL)) { + rc = EINVAL; + goto err; + } + + bsptimer->tmr_freq = freq_hz; + bsptimer->tmr_enabled = 1; + + __HAL_DISABLE_INTERRUPTS(ctx); + + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + + /* Stop the timer first */ + rtctimer->TASKS_STOP = 1; + + /* Always no prescaler */ + rtctimer->PRESCALER = 0; + + /* Clear overflow events and set overflow interrupt */ + rtctimer->EVENTS_OVRFLW = 0; + rtctimer->INTENSET = RTC_INTENSET_OVRFLW_Msk; + + /* Start the timer */ + rtctimer->TASKS_START = 1; + + /* Set isr in vector table and enable interrupt */ + NVIC_EnableIRQ(bsptimer->tmr_irq_num); + + __HAL_ENABLE_INTERRUPTS(ctx); + return 0; + } +#endif + /* Set timer to desired frequency */ div = NRF52_MAX_TIMER_FREQ / freq_hz; @@ -491,13 +672,20 @@ hal_timer_deinit(int timer_num) uint32_t ctx; struct nrf52_hal_timer *bsptimer; NRF_TIMER_Type *hwtimer; + NRF_RTC_Type *rtctimer; NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer); __HAL_DISABLE_INTERRUPTS(ctx); - hwtimer = bsptimer->tmr_reg; - hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); - hwtimer->TASKS_STOP = 1; + if (bsptimer->tmr_rtc) { + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT); + rtctimer->TASKS_STOP = 1; + } else { + hwtimer = (NRF_TIMER_Type *)bsptimer->tmr_reg; + hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT); + hwtimer->TASKS_STOP = 1; + } bsptimer->tmr_enabled = 0; bsptimer->tmr_reg = NULL; __HAL_ENABLE_INTERRUPTS(ctx); @@ -549,9 +737,11 @@ hal_timer_read(int timer_num) struct nrf52_hal_timer *bsptimer; NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer); - - /* Force a capture of the timer into 'cntr' capture channel; read it */ - tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg); + if (bsptimer->tmr_rtc) { + tcntr = hal_timer_read_bsptimer(bsptimer); + } else { + tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg); + } return tcntr; @@ -575,22 +765,14 @@ err: int hal_timer_delay(int timer_num, uint32_t ticks) { - int rc; uint32_t until; - NRF_TIMER_Type *hwtimer; - struct nrf52_hal_timer *bsptimer; - NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer); - - hwtimer = bsptimer->tmr_reg; - until = nrf_read_timer_cntr(hwtimer) + ticks; - while ((int32_t)(nrf_read_timer_cntr(hwtimer) - until) <= 0) { + until = hal_timer_read(timer_num) + ticks; + while ((int32_t)(hal_timer_read(timer_num) - until) <= 0) { /* Loop here till finished */ } - rc = 0; -err: - return rc; + return 0; } /** @@ -631,7 +813,11 @@ hal_timer_start(struct hal_timer *timer, uint32_t ticks) /* Set the tick value at which the timer should expire */ bsptimer = (struct nrf52_hal_timer *)timer->bsp_timer; - tick = nrf_read_timer_cntr(bsptimer->tmr_reg) + ticks; + if (bsptimer->tmr_rtc) { + tick = hal_timer_read_bsptimer(bsptimer) + ticks; + } else { + tick = nrf_read_timer_cntr(bsptimer->tmr_reg) + ticks; + } rc = hal_timer_start_at(timer, tick); return rc; } @@ -715,7 +901,11 @@ hal_timer_stop(struct hal_timer *timer) nrf_timer_set_ocmp((struct nrf52_hal_timer *)entry->bsp_timer, entry->expiry); } else { - nrf_timer_disable_ocmp(bsptimer->tmr_reg); + if (bsptimer->tmr_rtc) { + nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg); + } else { + nrf_timer_disable_ocmp(bsptimer->tmr_reg); + } } } }
