diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/common_rtc.h b/targets/TARGET_NORDIC/TARGET_NRF5x/common_rtc.h index f15ff83a58..2ebe70ecf7 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/common_rtc.h +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/common_rtc.h @@ -33,6 +33,9 @@ #define OS_TICK_CC_CHANNEL 1 #define LP_TICKER_CC_CHANNEL 2 +#define US_TICKER_SW_IRQ_MASK 0x1 +#define LP_TICKER_SW_IRQ_MASK 0x2 + #define COMMON_RTC_EVENT_COMPARE(channel) \ CONCAT_2(NRF_RTC_EVENT_COMPARE_, channel) #define COMMON_RTC_INT_COMPARE_MASK(channel) \ @@ -47,6 +50,7 @@ extern bool m_common_rtc_enabled; extern uint32_t volatile m_common_rtc_overflows; +extern uint8_t volatile m_common_sw_irq_flag; void common_rtc_init(void); uint32_t common_rtc_32bit_ticks_get(void); diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/lp_ticker.c b/targets/TARGET_NORDIC/TARGET_NRF5x/lp_ticker.c index 41f4b8ea2b..def44835e2 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/lp_ticker.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/lp_ticker.c @@ -18,6 +18,7 @@ #if DEVICE_LOWPOWERTIMER #include "common_rtc.h" +#include "mbed_critical.h" void lp_ticker_init(void) { @@ -37,10 +38,10 @@ void lp_ticker_set_interrupt(timestamp_t timestamp) void lp_ticker_fire_interrupt(void) { - uint32_t closest_safe_compare = common_rtc_32bit_ticks_get() + 2; - - nrf_rtc_cc_set(COMMON_RTC_INSTANCE, LP_TICKER_CC_CHANNEL, RTC_WRAP(closest_safe_compare)); - nrf_rtc_event_enable(COMMON_RTC_INSTANCE, LP_TICKER_INT_MASK); + core_util_critical_section_enter(); + m_common_sw_irq_flag |= LP_TICKER_SW_IRQ_MASK; + NVIC_SetPendingIRQ(RTC1_IRQn); + core_util_critical_section_exit(); } void lp_ticker_disable_interrupt(void) diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/us_ticker.c b/targets/TARGET_NORDIC/TARGET_NRF5x/us_ticker.c index c1ff2b9231..a939606297 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/us_ticker.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/us_ticker.c @@ -43,12 +43,14 @@ #include "lp_ticker_api.h" #include "mbed_critical.h" +#if defined(NRF52_ERRATA_20) #if defined(SOFTDEVICE_PRESENT) #include "nrf_sdh.h" #define NRF_HAL_US_TICKER_SD_IS_ENABLED() nrf_sdh_is_enabled() #else #define NRF_HAL_US_TICKER_SD_IS_ENABLED() 0 #endif +#endif //------------------------------------------------------------------------------ // Common stuff used also by lp_ticker and rtc_api (see "common_rtc.h"). @@ -58,6 +60,9 @@ bool m_common_rtc_enabled = false; uint32_t volatile m_common_rtc_overflows = 0; +// lp/us ticker fire interrupt flag for IRQ handler +volatile uint8_t m_common_sw_irq_flag = 0; + __STATIC_INLINE void rtc_ovf_event_check(void) { if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) { @@ -77,11 +82,15 @@ void COMMON_RTC_IRQ_HANDLER(void) rtc_ovf_event_check(); - if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, US_TICKER_EVENT)) { + if ((m_common_sw_irq_flag & US_TICKER_SW_IRQ_MASK) || nrf_rtc_event_pending(COMMON_RTC_INSTANCE, US_TICKER_EVENT)) { us_ticker_irq_handler(); } #if DEVICE_LOWPOWERTIMER + if (m_common_sw_irq_flag & LP_TICKER_SW_IRQ_MASK) { + m_common_sw_irq_flag &= ~LP_TICKER_SW_IRQ_MASK; + lp_ticker_irq_handler(); + } if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, LP_TICKER_EVENT)) { lp_ticker_irq_handler(); @@ -117,7 +126,7 @@ void common_rtc_init(void) errata_20(); NVIC_SetVector(RTC1_IRQn, (uint32_t)RTC1_IRQHandler); - + // RTC is driven by the low frequency (32.768 kHz) clock, a proper request // must be made to have it running. // Currently this clock is started in 'SystemInit' (see "system_nrf51.c" @@ -276,10 +285,10 @@ void us_ticker_set_interrupt(timestamp_t timestamp) void us_ticker_fire_interrupt(void) { - uint32_t closest_safe_compare = common_rtc_32bit_ticks_get() + 2; - - nrf_rtc_cc_set(COMMON_RTC_INSTANCE, US_TICKER_CC_CHANNEL, RTC_WRAP(closest_safe_compare)); - nrf_rtc_event_enable(COMMON_RTC_INSTANCE, US_TICKER_INT_MASK); + core_util_critical_section_enter(); + m_common_sw_irq_flag |= US_TICKER_SW_IRQ_MASK; + NVIC_SetPendingIRQ(RTC1_IRQn); + core_util_critical_section_exit(); } void us_ticker_disable_interrupt(void) @@ -289,6 +298,7 @@ void us_ticker_disable_interrupt(void) void us_ticker_clear_interrupt(void) { + m_common_sw_irq_flag &= ~US_TICKER_SW_IRQ_MASK; nrf_rtc_event_clear(COMMON_RTC_INSTANCE, US_TICKER_EVENT); }