diff --git a/hal/targets.json b/hal/targets.json index dfaf269e8a9..374370dcb28 100644 --- a/hal/targets.json +++ b/hal/targets.json @@ -1375,7 +1375,7 @@ "supported_form_factors": ["ARDUINO"], "inherits": ["MCU_NRF51_32K"], "progen": {"target": "nrf51-dk"}, - "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"] + "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"] }, "NRF51_DK_BOOT": { "supported_form_factors": ["ARDUINO"], @@ -1773,6 +1773,6 @@ "NRF52_PAN_62", "NRF52_PAN_63" ], - "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"] + "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"] } } diff --git a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/common_rtc.h b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/common_rtc.h index 390faf53d39..fc1d99c2a51 100644 --- a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/common_rtc.h +++ b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/common_rtc.h @@ -50,5 +50,8 @@ extern uint32_t volatile m_common_rtc_overflows; void common_rtc_init(void); uint32_t common_rtc_32bit_ticks_get(void); +uint64_t common_rtc_64bit_us_get(void); +void common_rtc_set_interrupt(uint32_t us_timestamp, uint32_t cc_channel, + uint32_t int_mask); #endif // COMMON_RTC_H diff --git a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/lp_ticker.c b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/lp_ticker.c index 404c18c2598..ae63c2a1e1a 100644 --- a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/lp_ticker.c +++ b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/lp_ticker.c @@ -18,43 +18,31 @@ #if DEVICE_LOWPOWERTIMER #include "common_rtc.h" -#include "sleep_api.h" void lp_ticker_init(void) { common_rtc_init(); } -uint32_t lp_ticker_read(void) +uint32_t lp_ticker_read() { - return common_rtc_32bit_ticks_get(); + return (uint32_t)common_rtc_64bit_us_get(); } -void lp_ticker_set_interrupt(uint32_t now, uint32_t time) +void lp_ticker_set_interrupt(timestamp_t timestamp) { - (void)now; - nrf_rtc_cc_set(COMMON_RTC_INSTANCE, LP_TICKER_CC_CHANNEL, RTC_WRAP(time)); - nrf_rtc_event_enable(COMMON_RTC_INSTANCE, LP_TICKER_INT_MASK); + common_rtc_set_interrupt(timestamp, + LP_TICKER_CC_CHANNEL, LP_TICKER_INT_MASK); } -uint32_t lp_ticker_get_overflows_counter(void) +void lp_ticker_disable_interrupt(void) { - // Cut out the part of 'm_common_rtc_overflows' used by - // 'common_rtc_32bit_ticks_get()'. - return (m_common_rtc_overflows >> (32u - RTC_COUNTER_BITS)); + nrf_rtc_event_disable(COMMON_RTC_INSTANCE, LP_TICKER_INT_MASK); } -uint32_t lp_ticker_get_compare_match(void) +void lp_ticker_clear_interrupt(void) { - return nrf_rtc_cc_get(COMMON_RTC_INSTANCE, LP_TICKER_CC_CHANNEL); -} - -void lp_ticker_sleep_until(uint32_t now, uint32_t time) -{ - lp_ticker_set_interrupt(now, time); - sleep_t sleep_obj; - mbed_enter_sleep(&sleep_obj); - mbed_exit_sleep(&sleep_obj); + nrf_rtc_event_clear(COMMON_RTC_INSTANCE, LP_TICKER_EVENT); } #endif // DEVICE_LOWPOWERTIMER diff --git a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/us_ticker.c b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/us_ticker.c index d95580538a2..8eb018a69ad 100644 --- a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/us_ticker.c +++ b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/us_ticker.c @@ -39,6 +39,7 @@ #include "us_ticker_api.h" #include "common_rtc.h" #include "app_util.h" +#include "lp_ticker_api.h" //------------------------------------------------------------------------------ @@ -56,30 +57,19 @@ void common_rtc_irq_handler(void) void COMMON_RTC_IRQ_HANDLER(void) #endif { - nrf_rtc_event_t event; - uint32_t int_mask; - - event = US_TICKER_EVENT; - int_mask = US_TICKER_INT_MASK; - if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, event)) { - nrf_rtc_event_clear(COMMON_RTC_INSTANCE, event); - nrf_rtc_event_disable(COMMON_RTC_INSTANCE, int_mask); - + if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, US_TICKER_EVENT)) { us_ticker_irq_handler(); } #if DEVICE_LOWPOWERTIMER - event = LP_TICKER_EVENT; - int_mask = LP_TICKER_INT_MASK; - if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, event)) { - nrf_rtc_event_clear(COMMON_RTC_INSTANCE, event); - nrf_rtc_event_disable(COMMON_RTC_INSTANCE, int_mask); + if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, LP_TICKER_EVENT)) { + + lp_ticker_irq_handler(); } #endif - event = NRF_RTC_EVENT_OVERFLOW; - if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, event)) { - nrf_rtc_event_clear(COMMON_RTC_INSTANCE, event); + if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) { + nrf_rtc_event_clear(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW); // Don't disable this event. It shall occur periodically. ++m_common_rtc_overflows; @@ -151,27 +141,16 @@ uint32_t common_rtc_32bit_ticks_get(void) ticks += (m_common_rtc_overflows << RTC_COUNTER_BITS); return ticks; } -//------------------------------------------------------------------------------ - - -void us_ticker_init(void) -{ - common_rtc_init(); -} -static uint64_t us_ticker_64bit_get(void) +uint64_t common_rtc_64bit_us_get(void) { uint32_t ticks = common_rtc_32bit_ticks_get(); // [ticks -> microseconds] return ROUNDED_DIV(((uint64_t)ticks) * 1000000, RTC_INPUT_FREQ); } -uint32_t us_ticker_read() -{ - return (uint32_t)us_ticker_64bit_get(); -} - -void us_ticker_set_interrupt(timestamp_t timestamp) +void common_rtc_set_interrupt(uint32_t us_timestamp, uint32_t cc_channel, + uint32_t int_mask) { // The internal counter is clocked with a frequency that cannot be easily // multiplied to 1 MHz, therefore besides the translation of values @@ -182,12 +161,13 @@ void us_ticker_set_interrupt(timestamp_t timestamp) // is then translated to counter ticks. Finally, the lower 24 bits of thus // calculated value is written to the counter compare register to prepare // the interrupt generation. - uint64_t current_time64 = us_ticker_64bit_get(); + uint64_t current_time64 = common_rtc_64bit_us_get(); // [add upper 32 bits from the current time to the timestamp value] - uint64_t timestamp64 = timestamp + (current_time64 & ~(uint64_t)0xFFFFFFFF); + uint64_t timestamp64 = us_timestamp + + (current_time64 & ~(uint64_t)0xFFFFFFFF); // [if the original timestamp value happens to be after the 32 bit counter // of microsends overflows, correct the upper 32 bits accordingly] - if (timestamp < (uint32_t)(current_time64 & 0xFFFFFFFF)) { + if (us_timestamp < (uint32_t)(current_time64 & 0xFFFFFFFF)) { timestamp64 += ((uint64_t)1 << 32); } // [microseconds -> ticks, always round the result up to avoid too early @@ -205,9 +185,26 @@ void us_ticker_set_interrupt(timestamp_t timestamp) compare_value = closest_safe_compare; } - nrf_rtc_cc_set(COMMON_RTC_INSTANCE, US_TICKER_CC_CHANNEL, - RTC_WRAP(compare_value)); - nrf_rtc_event_enable(COMMON_RTC_INSTANCE, US_TICKER_INT_MASK); + nrf_rtc_cc_set(COMMON_RTC_INSTANCE, cc_channel, RTC_WRAP(compare_value)); + nrf_rtc_event_enable(COMMON_RTC_INSTANCE, int_mask); +} +//------------------------------------------------------------------------------ + + +void us_ticker_init(void) +{ + common_rtc_init(); +} + +uint32_t us_ticker_read() +{ + return (uint32_t)common_rtc_64bit_us_get(); +} + +void us_ticker_set_interrupt(timestamp_t timestamp) +{ + common_rtc_set_interrupt(timestamp, + US_TICKER_CC_CHANNEL, US_TICKER_INT_MASK); } void us_ticker_disable_interrupt(void) @@ -217,6 +214,5 @@ void us_ticker_disable_interrupt(void) void us_ticker_clear_interrupt(void) { - // No implementation needed. The event that triggers the interrupt is - // cleared in 'common_rtc_irq_handler'. + nrf_rtc_event_clear(COMMON_RTC_INSTANCE, US_TICKER_EVENT); }