NRF52: fix us_ticker IRQ handler

Applying PR to NRF52 SDK 14.2:
https://github.com/ARMmbed/mbed-os/pull/5046
pull/6547/head
Marcus Chang 2018-03-06 11:20:25 -08:00
parent 97426d63e9
commit cfb480447a
3 changed files with 25 additions and 10 deletions

View File

@ -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);

View File

@ -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)

View File

@ -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);
}