From d006eaacbfafc29c6b14905ff8cc4afb266b5fe2 Mon Sep 17 00:00:00 2001 From: Martin Kojtal <0xc0170@gmail.com> Date: Fri, 6 Oct 2017 12:50:48 +0100 Subject: [PATCH] us ticker: fix fire interrupt handling Few targets need more than just pending IRQ set. They include some flags to be set that are checked in IRQ handler. This is the case for targets in this commit. --- .../TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c | 2 +- .../TARGET_Freescale/TARGET_KLXX/us_ticker.c | 3 +++ .../TARGET_Maxim/TARGET_MAX32600/us_ticker.c | 4 +++- .../TARGET_Maxim/TARGET_MAX32610/us_ticker.c | 4 +++- .../TARGET_Maxim/TARGET_MAX32620/us_ticker.c | 4 +++- .../TARGET_Maxim/TARGET_MAX32625/us_ticker.c | 2 +- .../TARGET_Maxim/TARGET_MAX32630/us_ticker.c | 2 +- .../TARGET_MCU_NRF51822/us_ticker.c | 14 ++++++++++++++ .../TARGET_NORDIC/TARGET_NRF5/common_rtc.h | 4 ++++ targets/TARGET_NORDIC/TARGET_NRF5/lp_ticker.c | 9 +++++---- targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c | 19 +++++++++++++++---- 11 files changed, 53 insertions(+), 14 deletions(-) diff --git a/targets/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c b/targets/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c index 68c51dbc242..b09ecb8ab10 100644 --- a/targets/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c +++ b/targets/TARGET_ARM_SSG/TARGET_BEETLE/us_ticker.c @@ -100,7 +100,7 @@ void us_ticker_set_interrupt(timestamp_t timestamp) { void us_ticker_fire_interrupt(void) { - uint32_t us_ticker_irqn1 = Timer_GetIRQn(TIMER1); + uint32_t us_ticker_irqn1 = Timer_GetIRQn(TIMER0); NVIC_SetPendingIRQ((IRQn_Type)us_ticker_irqn1); } diff --git a/targets/TARGET_Freescale/TARGET_KLXX/us_ticker.c b/targets/TARGET_Freescale/TARGET_KLXX/us_ticker.c index 96cb66f2fdd..6fcaa1d94bf 100644 --- a/targets/TARGET_Freescale/TARGET_KLXX/us_ticker.c +++ b/targets/TARGET_Freescale/TARGET_KLXX/us_ticker.c @@ -199,6 +199,9 @@ void us_ticker_set_interrupt(timestamp_t timestamp) { void us_ticker_fire_interrupt(void) { + us_ticker_int_counter = 0; + us_ticker_int_remainder = 0; + #if defined(TARGET_KL43Z) NVIC_SetPendingIRQ(LPTMR0_IRQn); #else diff --git a/targets/TARGET_Maxim/TARGET_MAX32600/us_ticker.c b/targets/TARGET_Maxim/TARGET_MAX32600/us_ticker.c index f0ff494b2f3..46acd821381 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32600/us_ticker.c +++ b/targets/TARGET_Maxim/TARGET_MAX32600/us_ticker.c @@ -236,7 +236,9 @@ void us_ticker_set_interrupt(timestamp_t timestamp) void us_ticker_fire_interrupt(void) { - NVIC_SetPendingIRQ(US_TIMER_IRQn); + US_TIMER->ctrl &= ~MXC_F_TMR_CTRL_ENABLE0; // disable timer + US_TIMER->term_cnt32 = 1; + US_TIMER->ctrl |= MXC_F_TMR_CTRL_ENABLE0; // enable timer } //****************************************************************************** diff --git a/targets/TARGET_Maxim/TARGET_MAX32610/us_ticker.c b/targets/TARGET_Maxim/TARGET_MAX32610/us_ticker.c index f0ff494b2f3..97257af3fbd 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32610/us_ticker.c +++ b/targets/TARGET_Maxim/TARGET_MAX32610/us_ticker.c @@ -236,7 +236,9 @@ void us_ticker_set_interrupt(timestamp_t timestamp) void us_ticker_fire_interrupt(void) { - NVIC_SetPendingIRQ(US_TIMER_IRQn); + US_TIMER->ctrl &= ~MXC_F_TMR_CTRL_ENABLE0; // disable timer + US_TIMER->term_cnt32 = 1; + US_TIMER->ctrl |= MXC_F_TMR_CTRL_ENABLE0; // enable timer } //****************************************************************************** diff --git a/targets/TARGET_Maxim/TARGET_MAX32620/us_ticker.c b/targets/TARGET_Maxim/TARGET_MAX32620/us_ticker.c index e219e30d900..2762e2e14af 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620/us_ticker.c +++ b/targets/TARGET_Maxim/TARGET_MAX32620/us_ticker.c @@ -267,7 +267,9 @@ void us_ticker_set_interrupt(timestamp_t timestamp) void us_ticker_fire_interrupt(void) { - NVIC_SetPendingIRQ(US_TIMER_IRQn); + US_TIMER->ctrl &= ~MXC_F_TMR_CTRL_ENABLE0; // disable timer + US_TIMER->term_cnt32 = 1; + US_TIMER->ctrl |= MXC_F_TMR_CTRL_ENABLE0; // enable timer } //****************************************************************************** diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/us_ticker.c b/targets/TARGET_Maxim/TARGET_MAX32625/us_ticker.c index 8bd5f111c30..d577f653928 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/us_ticker.c +++ b/targets/TARGET_Maxim/TARGET_MAX32625/us_ticker.c @@ -230,7 +230,7 @@ void us_ticker_set_interrupt(timestamp_t timestamp) void us_ticker_fire_interrupt(void) { - NVIC_SetPendingIRQ(US_TIMER_IRQn); + TMR32_SetCompare(US_TIMER, 1); } //****************************************************************************** diff --git a/targets/TARGET_Maxim/TARGET_MAX32630/us_ticker.c b/targets/TARGET_Maxim/TARGET_MAX32630/us_ticker.c index 8bd5f111c30..d577f653928 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32630/us_ticker.c +++ b/targets/TARGET_Maxim/TARGET_MAX32630/us_ticker.c @@ -230,7 +230,7 @@ void us_ticker_set_interrupt(timestamp_t timestamp) void us_ticker_fire_interrupt(void) { - NVIC_SetPendingIRQ(US_TIMER_IRQn); + TMR32_SetCompare(US_TIMER, 1); } //****************************************************************************** diff --git a/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c b/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c index 251ec50aa07..45dab1a706f 100644 --- a/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c +++ b/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c @@ -20,6 +20,7 @@ #include "PeripheralNames.h" #include "nrf_delay.h" #include "mbed_toolchain.h" +#include "mbed_critical.h" /* * Note: The micro-second timer API on the nRF51 platform is implemented using @@ -52,6 +53,8 @@ #define RTC_UNITS_TO_MICROSECONDS(RTC_UNITS) (((RTC_UNITS) * (uint64_t)1000000) / RTC_CLOCK_FREQ) #define MICROSECONDS_TO_RTC_UNITS(MICROS) ((((uint64_t)(MICROS) * RTC_CLOCK_FREQ) + 999999) / 1000000) +#define US_TICKER_SW_IRQ_MASK 0x1 + static bool us_ticker_inited = false; static volatile uint32_t overflowCount; /**< The number of times the 24-bit RTC counter has overflowed. */ static volatile bool us_ticker_callbackPending = false; @@ -62,6 +65,9 @@ static bool os_tick_started = false; /**< flag indicating i */ static uint32_t previous_tick_cc_value = 0; +// us ticker fire interrupt flag for IRQ handler +volatile uint8_t m_common_sw_irq_flag = 0; + /* RTX provide the following definitions which are used by the tick code: * os_trv: The number (minus 1) of clock cycle between two tick. @@ -181,6 +187,11 @@ static inline uint32_t rtc1_getCounter(void) */ void us_ticker_handler(void) { + if (m_common_sw_irq_flag & US_TICKER_SW_IRQ_MASK) { + m_common_sw_irq_flag &= ~US_TICKER_SW_IRQ_MASK; + us_ticker_irq_handler(); + } + if (NRF_RTC1->EVENTS_OVRFLW) { overflowCount++; NRF_RTC1->EVENTS_OVRFLW = 0; @@ -287,7 +298,10 @@ void us_ticker_set_interrupt(timestamp_t timestamp) void us_ticker_fire_interrupt(void) { + 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) diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/common_rtc.h b/targets/TARGET_NORDIC/TARGET_NRF5/common_rtc.h index f15ff83a589..2ebe70ecf72 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/common_rtc.h +++ b/targets/TARGET_NORDIC/TARGET_NRF5/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_NRF5/lp_ticker.c b/targets/TARGET_NORDIC/TARGET_NRF5/lp_ticker.c index 41f4b8ea2bb..def44835e29 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/lp_ticker.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/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_NRF5/us_ticker.c b/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c index 8ca24697abd..472c4d8f0de 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c @@ -55,6 +55,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)) { @@ -74,11 +77,19 @@ void COMMON_RTC_IRQ_HANDLER(void) rtc_ovf_event_check(); + if (m_common_sw_irq_flag & US_TICKER_SW_IRQ_MASK) { + m_common_sw_irq_flag &= ~US_TICKER_SW_IRQ_MASK; + us_ticker_irq_handler(); + } if (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(); @@ -273,10 +284,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)