From 5ef170def22f5327f3c8252799e9f499eb50e5a6 Mon Sep 17 00:00:00 2001 From: Stephane D'Alu Date: Sun, 14 Feb 2016 17:53:22 +0100 Subject: Now ST can also use RTC1. Added NRF51_ST_PRIORITY for interrupts. Default values are changed if SOFTDEVICE_PRESENT is defined --- os/hal/ports/NRF51/NRF51822/st_lld.c | 120 ++++++++++++++++++++++++++++++----- os/hal/ports/NRF51/NRF51822/st_lld.h | 118 +++++++++++++++++++++++++++------- 2 files changed, 200 insertions(+), 38 deletions(-) (limited to 'os/hal') diff --git a/os/hal/ports/NRF51/NRF51822/st_lld.c b/os/hal/ports/NRF51/NRF51822/st_lld.c index e144a11..f65117b 100644 --- a/os/hal/ports/NRF51/NRF51822/st_lld.c +++ b/os/hal/ports/NRF51/NRF51822/st_lld.c @@ -52,11 +52,11 @@ /*===========================================================================*/ #if (OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC) || defined(__DOXYGEN__) -#if (NRF51_SYSTEM_TICKS == NRF51_SYSTEM_TICKS_AS_RTC) +#if NRF51_ST_USE_RTC0 == TRUE /** * @brief System Timer vector (RTC0) * @details This interrupt is used for system tick in periodic mode - * if selected with NRF51_SYSTEM_TICKS == NRF51_SYSTEM_TICKS_AS_RTC + * if selected with NRF51_ST_USE_RTC0 * * @isr */ @@ -74,11 +74,33 @@ OSAL_IRQ_HANDLER(Vector6C) { } #endif -#if (NRF51_SYSTEM_TICKS == NRF51_SYSTEM_TICKS_AS_TIMER) +#if NRF51_ST_USE_RTC1 == TRUE +/** + * @brief System Timer vector (RTC1) + * @details This interrupt is used for system tick in periodic mode + * if selected with NRF51_ST_USE_RTC1 + * + * @isr + */ +OSAL_IRQ_HANDLER(Vector84) { + + OSAL_IRQ_PROLOGUE(); + + NRF_RTC1->EVENTS_TICK = 0; + + osalSysLockFromISR(); + osalOsTimerHandlerI(); + osalSysUnlockFromISR(); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if NRF51_ST_USE_TIMER0 == TRUE /** * @brief System Timer vector. (TIMER0) * @details This interrupt is used for system tick in periodic mode - * if selected with NRF51_SYSTEM_TICKS == NRF51_SYSTEM_TICKS_AS_TIMER + * if selected with NRF51_ST_USE_TIMER0 * * @isr */ @@ -100,11 +122,11 @@ OSAL_IRQ_HANDLER(Vector60) { #endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */ #if (OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING) || defined(__DOXYGEN__) -#if (NRF51_SYSTEM_TICKS == NRF51_SYSTEM_TICKS_AS_RTC) +#if NRF51_ST_USE_RTC0 == TRUE /** * @brief System Timer vector (RTC0) * @details This interrupt is used for freerunning mode (tick-less) - * if selected with NRF51_SYSTEM_TICKS == NRF51_SYSTEM_TICKS_AS_RTC + * if selected with NRF51_ST_USE_RTC0 * * @isr */ @@ -130,7 +152,38 @@ OSAL_IRQ_HANDLER(Vector6C) { OSAL_IRQ_EPILOGUE(); } #endif + +#if NRF51_ST_USE_RTC1 == TRUE +/** + * @brief System Timer vector (RTC1) + * @details This interrupt is used for freerunning mode (tick-less) + * if selected with NRF51_ST_USE_RTC1 + * + * @isr + */ +OSAL_IRQ_HANDLER(Vector84) { + + OSAL_IRQ_PROLOGUE(); + + if (NRF_RTC1->EVENTS_COMPARE[0]) { + NRF_RTC1->EVENTS_COMPARE[0] = 0; + + osalSysLockFromISR(); + osalOsTimerHandlerI(); + osalSysUnlockFromISR(); + } + +#if OSAL_ST_RESOLUTION == 16 + if (NRF_RTC1->EVENTS_COMPARE[1]) { + NRF_RTC1->EVENTS_COMPARE[1] = 0; + NRF_RTC1->TASKS_CLEAR = 1; + } +#endif + + OSAL_IRQ_EPILOGUE(); +} #endif +#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */ /*===========================================================================*/ /* Driver exported functions. */ @@ -142,8 +195,9 @@ OSAL_IRQ_HANDLER(Vector6C) { * @notapi */ void st_lld_init(void) { -#if (OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING) -#if (NRF51_SYSTEM_TICKS == NRF51_SYSTEM_TICKS_AS_RTC) +#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING + +#if NRF51_ST_USE_RTC0 == TRUE /* Using RTC with prescaler */ NRF_RTC0->TASKS_STOP = 1; NRF_RTC0->PRESCALER = (NRF51_LFCLK_FREQUENCY / OSAL_ST_FREQUENCY) - 1; @@ -159,24 +213,57 @@ void st_lld_init(void) { NRF_RTC0->TASKS_CLEAR = 1; /* Start timer */ - nvicEnableVector(RTC0_IRQn, 8); + nvicEnableVector(RTC0_IRQn, NRF51_ST_PRIORITY); NRF_RTC0->TASKS_START = 1; +#endif /* NRF51_ST_USE_RTC0 == TRUE */ + +#if NRF51_ST_USE_RTC1 == TRUE + /* Using RTC with prescaler */ + NRF_RTC1->TASKS_STOP = 1; + NRF_RTC1->PRESCALER = (NRF51_LFCLK_FREQUENCY / OSAL_ST_FREQUENCY) - 1; + NRF_RTC1->EVTENCLR = RTC_EVTENSET_COMPARE0_Msk; + NRF_RTC1->EVENTS_COMPARE[0] = 0; + NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk; +#if OSAL_ST_RESOLUTION == 16 + NRF_RTC1->CC[1] = 0x10000; /* 2^16 */ + NRF_RTC1->EVENTS_COMPARE[1] = 0; + NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; + NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE1_Msk; #endif + NRF_RTC1->TASKS_CLEAR = 1; + + /* Start timer */ + nvicEnableVector(RTC1_IRQn, NRF51_ST_PRIORITY); + NRF_RTC1->TASKS_START = 1; +#endif /* NRF51_ST_USE_RTC1 == TRUE */ + #endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */ #if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC -#if (NRF51_SYSTEM_TICKS == NRF51_SYSTEM_TICKS_AS_RTC) + +#if NRF51_ST_USE_RTC0 == TRUE /* Using RTC with prescaler */ NRF_RTC0->TASKS_STOP = 1; NRF_RTC0->PRESCALER = (NRF51_LFCLK_FREQUENCY / OSAL_ST_FREQUENCY) - 1; NRF_RTC0->INTENSET = RTC_INTENSET_TICK_Msk; /* Start timer */ - nvicEnableVector(RTC0_IRQn, 8); + nvicEnableVector(RTC0_IRQn, NRF51_ST_PRIORITY); NRF_RTC0->TASKS_START = 1; -#endif +#endif /* NRF51_ST_USE_RTC0 == TRUE */ + +#if NRF51_ST_USE_RTC1 == TRUE + /* Using RTC with prescaler */ + NRF_RTC1->TASKS_STOP = 1; + NRF_RTC1->PRESCALER = (NRF51_LFCLK_FREQUENCY / OSAL_ST_FREQUENCY) - 1; + NRF_RTC1->INTENSET = RTC_INTENSET_TICK_Msk; + + /* Start timer */ + nvicEnableVector(RTC1_IRQn, NRF51_ST_PRIORITY); + NRF_RTC1->TASKS_START = 1; +#endif /* NRF51_ST_USE_RTC1 == TRUE */ -#if (NRF51_SYSTEM_TICKS == NRF51_SYSTEM_TICKS_AS_TIMER) +#if NRF51_ST_USE_TIMER0 == TRUE NRF_TIMER0->TASKS_CLEAR = 1; /* @@ -195,10 +282,11 @@ void st_lld_init(void) { NRF_TIMER0->INTENSET = 0x10000; /* Start timer */ - nvicEnableVector(TIMER0_IRQn, 8); + nvicEnableVector(TIMER0_IRQn, NRF51_ST_PRIORITY); NRF_TIMER0->TASKS_START = 1; -#endif -#endif +#endif /* NRF51_ST_USE_TIMER0 == TRUE */ + +#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */ } #endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */ diff --git a/os/hal/ports/NRF51/NRF51822/st_lld.h b/os/hal/ports/NRF51/NRF51822/st_lld.h index 54dabda..ab25dbb 100644 --- a/os/hal/ports/NRF51/NRF51822/st_lld.h +++ b/os/hal/ports/NRF51/NRF51822/st_lld.h @@ -33,54 +33,95 @@ /* Driver constants. */ /*===========================================================================*/ +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + /** - * @brief System ticks implementer as a timer. + * @brief Use RTC0 to generates system ticks */ -#define NRF51_SYSTEM_TICKS_AS_TIMER 1 +#if !defined(NRF51_ST_USE_RTC0) || defined(__DOXYGEN__) +#if !defined(SOFTDEVICE_PRESENT) +#define NRF51_ST_USE_RTC0 TRUE +#else +#define NRF51_ST_USE_RTC0 FALSE +#endif +#endif /** - * @brief System ticks implementer as an rtc. + * @brief Use RTC1 to generates system ticks */ -#define NRF51_SYSTEM_TICKS_AS_RTC 2 +#if !defined(NRF51_ST_USE_RTC1) || defined(__DOXYGEN__) +#if !defined(SOFTDEVICE_PRESENT) +#define NRF51_ST_USE_RTC1 FALSE +#else +#define NRF51_ST_USE_RTC1 TRUE +#endif +#endif -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ +/** + * @brief Use TIMER0 to generates system ticks + */ +#if !defined(NRF51_ST_USE_TIMER0) || defined(__DOXYGEN__) +#define NRF51_ST_USE_TIMER0 FALSE +#endif /** - * @brief Select the method to generates system ticks - * @details Possibles values are: - * NRF51_SYSTEM_TICKS_AS_TIMER for TIMER0 - * NRF51_SYSTEM_TICKS_AS_RTC for RTC0 + * @brief ST interrupt priority level setting. */ -#if !defined(NRF51_SYSTEM_TICKS) || defined(__DOXYGEN__) -#define NRF51_SYSTEM_TICKS NRF51_SYSTEM_TICKS_AS_RTC +#if !defined(NRF51_ST_PRIORITY) || defined(__DOXYGEN__) +#if !defined(SOFTDEVICE_PRESENT) +#define NRF51_ST_PRIORITY 8 +#else +#define NRF51_ST_PRIORITY 1 +#endif #endif /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ -#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) -#if (NRF51_GPT_USE_TIMER0 == TRUE) && \ - (NRF51_SYSTEM_TICKS == NRF51_SYSTEM_TICKS_AS_TIMER) +#if OSAL_ST_MODE != OSAL_ST_MODE_NONE +#if (NRF51_ST_USE_TIMER0 == TRUE) && (NRF51_GPT_USE_TIMER0 == TRUE) #error "TIMER0 already used by GPT driver" #endif + +#if (NRF51_ST_USE_RTC0 == FALSE) && \ + (NRF51_ST_USE_RTC1 == FALSE) && \ + (NRF51_ST_USE_TIMER0 == FALSE) +#error "One clock source is needed, enable one (RTC0, RTC1, or TIMER0)" +#endif + +#if ((NRF51_ST_USE_RTC0 == TRUE ? 1 : 0) + \ + (NRF51_ST_USE_RTC1 == TRUE ? 1 : 0) + \ + (NRF51_ST_USE_TIMER0 == TRUE ? 1 : 0)) > 1 +#error "Only one clock source can be used (RTC0, RTC1, or TIMER0)" +#endif + +#if defined(SOFTDEVICE_PRESENT) +#if NRF51_ST_USE_RTC0 == TRUE +#error "RTC0 cannot be used for system ticks when SOFTDEVICE present" #endif -#if ((NRF51_SYSTEM_TICKS != NRF51_SYSTEM_TICKS_AS_RTC) && \ - (NRF51_SYSTEM_TICKS != NRF51_SYSTEM_TICKS_AS_TIMER)) -#error "NRF51_SYSTEM_TICKS illegal value" +#if NRF51_ST_USE_TIMER0 == TRUE +#error "TIMER0 cannot be used for system ticks when SOFTDEVICE present" #endif +#if NRF51_ST_PRIORITY != 1 +#error "ST priority must be 1 when SOFTDEVICE present" +#endif + +#endif /* defined(SOFTDEVICE_PRESENT) */ +#endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */ + #if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING #if defined(CH_CFG_ST_TIMEDELTA) && (CH_CFG_ST_TIMEDELTA < 5) #error "CH_CFG_ST_TIMEDELTA is too low" #endif -#if NRF51_SYSTEM_TICKS == NRF51_SYSTEM_TICKS_AS_TIMER +#if NRF51_ST_USE_TIMER0 == TRUE #error "Freeruning (tick-less) mode not supported with TIMER, use RTC" #endif -#endif +#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */ /*===========================================================================*/ /* Driver data structures and types. */ @@ -114,7 +155,12 @@ extern "C" { * @notapi */ static inline systime_t st_lld_get_counter(void) { - return (systime_t)NRF_RTC0->COUNTER; +#if NRF51_ST_USE_RTC0 == TRUE + return (systime_t)NRF_RTC0->COUNTER; +#endif +#if NRF51_ST_USE_RTC1 == TRUE + return (systime_t)NRF_RTC1->COUNTER; +#endif } /** @@ -127,9 +173,16 @@ static inline systime_t st_lld_get_counter(void) { * @notapi */ static inline void st_lld_start_alarm(systime_t abstime) { +#if NRF51_ST_USE_RTC0 == TRUE NRF_RTC0->CC[0] = abstime; NRF_RTC0->EVENTS_COMPARE[0] = 0; NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; +#endif +#if NRF51_ST_USE_RTC1 == TRUE + NRF_RTC1->CC[0] = abstime; + NRF_RTC1->EVENTS_COMPARE[0] = 0; + NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; +#endif } /** @@ -138,8 +191,14 @@ static inline void st_lld_start_alarm(systime_t abstime) { * @notapi */ static inline void st_lld_stop_alarm(void) { +#if NRF51_ST_USE_RTC0 == TRUE NRF_RTC0->EVTENCLR = RTC_EVTENCLR_COMPARE0_Msk; NRF_RTC0->EVENTS_COMPARE[0] = 0; +#endif +#if NRF51_ST_USE_RTC1 == TRUE + NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE0_Msk; + NRF_RTC1->EVENTS_COMPARE[0] = 0; +#endif } /** @@ -150,7 +209,12 @@ static inline void st_lld_stop_alarm(void) { * @notapi */ static inline void st_lld_set_alarm(systime_t abstime) { +#if NRF51_ST_USE_RTC0 == TRUE NRF_RTC0->CC[0] = abstime; +#endif +#if NRF51_ST_USE_RTC1 == TRUE + NRF_RTC1->CC[0] = abstime; +#endif } /** @@ -161,7 +225,12 @@ static inline void st_lld_set_alarm(systime_t abstime) { * @notapi */ static inline systime_t st_lld_get_alarm(void) { +#if NRF51_ST_USE_RTC0 == TRUE return (systime_t)NRF_RTC0->CC[0]; +#endif +#if NRF51_ST_USE_RTC1 == TRUE + return (systime_t)NRF_RTC1->CC[0]; +#endif } /** @@ -174,7 +243,12 @@ static inline systime_t st_lld_get_alarm(void) { * @notapi */ static inline bool st_lld_is_alarm_active(void) { +#if NRF51_ST_USE_RTC0 == TRUE return NRF_RTC0->EVTEN & RTC_EVTEN_COMPARE0_Msk; +#endif +#if NRF51_ST_USE_RTC1 == TRUE + return NRF_RTC1->EVTEN & RTC_EVTEN_COMPARE0_Msk; +#endif } #endif /* _ST_LLD_H_ */ -- cgit v1.2.3