mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #14 from anangl/hal_improvements
Enabled lp_ticker after adjusting its implementation to the new API.pull/2234/head
commit
6a31d1abc1
|
@ -1375,7 +1375,7 @@
|
||||||
"supported_form_factors": ["ARDUINO"],
|
"supported_form_factors": ["ARDUINO"],
|
||||||
"inherits": ["MCU_NRF51_32K"],
|
"inherits": ["MCU_NRF51_32K"],
|
||||||
"progen": {"target": "nrf51-dk"},
|
"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": {
|
"NRF51_DK_BOOT": {
|
||||||
"supported_form_factors": ["ARDUINO"],
|
"supported_form_factors": ["ARDUINO"],
|
||||||
|
@ -1773,6 +1773,6 @@
|
||||||
"NRF52_PAN_62",
|
"NRF52_PAN_62",
|
||||||
"NRF52_PAN_63"
|
"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"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,5 +50,8 @@ extern uint32_t volatile m_common_rtc_overflows;
|
||||||
|
|
||||||
void common_rtc_init(void);
|
void common_rtc_init(void);
|
||||||
uint32_t common_rtc_32bit_ticks_get(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
|
#endif // COMMON_RTC_H
|
||||||
|
|
|
@ -18,43 +18,31 @@
|
||||||
#if DEVICE_LOWPOWERTIMER
|
#if DEVICE_LOWPOWERTIMER
|
||||||
|
|
||||||
#include "common_rtc.h"
|
#include "common_rtc.h"
|
||||||
#include "sleep_api.h"
|
|
||||||
|
|
||||||
void lp_ticker_init(void)
|
void lp_ticker_init(void)
|
||||||
{
|
{
|
||||||
common_rtc_init();
|
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;
|
common_rtc_set_interrupt(timestamp,
|
||||||
nrf_rtc_cc_set(COMMON_RTC_INSTANCE, LP_TICKER_CC_CHANNEL, RTC_WRAP(time));
|
LP_TICKER_CC_CHANNEL, LP_TICKER_INT_MASK);
|
||||||
nrf_rtc_event_enable(COMMON_RTC_INSTANCE, 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
|
nrf_rtc_event_disable(COMMON_RTC_INSTANCE, LP_TICKER_INT_MASK);
|
||||||
// 'common_rtc_32bit_ticks_get()'.
|
|
||||||
return (m_common_rtc_overflows >> (32u - RTC_COUNTER_BITS));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, LP_TICKER_EVENT);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // DEVICE_LOWPOWERTIMER
|
#endif // DEVICE_LOWPOWERTIMER
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "us_ticker_api.h"
|
#include "us_ticker_api.h"
|
||||||
#include "common_rtc.h"
|
#include "common_rtc.h"
|
||||||
#include "app_util.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)
|
void COMMON_RTC_IRQ_HANDLER(void)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
nrf_rtc_event_t event;
|
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, US_TICKER_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);
|
|
||||||
|
|
||||||
us_ticker_irq_handler();
|
us_ticker_irq_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEVICE_LOWPOWERTIMER
|
#if DEVICE_LOWPOWERTIMER
|
||||||
event = LP_TICKER_EVENT;
|
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, LP_TICKER_EVENT)) {
|
||||||
int_mask = LP_TICKER_INT_MASK;
|
|
||||||
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, event)) {
|
lp_ticker_irq_handler();
|
||||||
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, event);
|
|
||||||
nrf_rtc_event_disable(COMMON_RTC_INSTANCE, int_mask);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
event = NRF_RTC_EVENT_OVERFLOW;
|
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) {
|
||||||
if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, event)) {
|
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW);
|
||||||
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, event);
|
|
||||||
// Don't disable this event. It shall occur periodically.
|
// Don't disable this event. It shall occur periodically.
|
||||||
|
|
||||||
++m_common_rtc_overflows;
|
++m_common_rtc_overflows;
|
||||||
|
@ -151,27 +141,16 @@ uint32_t common_rtc_32bit_ticks_get(void)
|
||||||
ticks += (m_common_rtc_overflows << RTC_COUNTER_BITS);
|
ticks += (m_common_rtc_overflows << RTC_COUNTER_BITS);
|
||||||
return ticks;
|
return ticks;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
uint64_t common_rtc_64bit_us_get(void)
|
||||||
void us_ticker_init(void)
|
|
||||||
{
|
|
||||||
common_rtc_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint64_t us_ticker_64bit_get(void)
|
|
||||||
{
|
{
|
||||||
uint32_t ticks = common_rtc_32bit_ticks_get();
|
uint32_t ticks = common_rtc_32bit_ticks_get();
|
||||||
// [ticks -> microseconds]
|
// [ticks -> microseconds]
|
||||||
return ROUNDED_DIV(((uint64_t)ticks) * 1000000, RTC_INPUT_FREQ);
|
return ROUNDED_DIV(((uint64_t)ticks) * 1000000, RTC_INPUT_FREQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t us_ticker_read()
|
void common_rtc_set_interrupt(uint32_t us_timestamp, uint32_t cc_channel,
|
||||||
{
|
uint32_t int_mask)
|
||||||
return (uint32_t)us_ticker_64bit_get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void us_ticker_set_interrupt(timestamp_t timestamp)
|
|
||||||
{
|
{
|
||||||
// The internal counter is clocked with a frequency that cannot be easily
|
// The internal counter is clocked with a frequency that cannot be easily
|
||||||
// multiplied to 1 MHz, therefore besides the translation of values
|
// 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
|
// is then translated to counter ticks. Finally, the lower 24 bits of thus
|
||||||
// calculated value is written to the counter compare register to prepare
|
// calculated value is written to the counter compare register to prepare
|
||||||
// the interrupt generation.
|
// 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]
|
// [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
|
// [if the original timestamp value happens to be after the 32 bit counter
|
||||||
// of microsends overflows, correct the upper 32 bits accordingly]
|
// 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);
|
timestamp64 += ((uint64_t)1 << 32);
|
||||||
}
|
}
|
||||||
// [microseconds -> ticks, always round the result up to avoid too early
|
// [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;
|
compare_value = closest_safe_compare;
|
||||||
}
|
}
|
||||||
|
|
||||||
nrf_rtc_cc_set(COMMON_RTC_INSTANCE, US_TICKER_CC_CHANNEL,
|
nrf_rtc_cc_set(COMMON_RTC_INSTANCE, cc_channel, RTC_WRAP(compare_value));
|
||||||
RTC_WRAP(compare_value));
|
nrf_rtc_event_enable(COMMON_RTC_INSTANCE, int_mask);
|
||||||
nrf_rtc_event_enable(COMMON_RTC_INSTANCE, US_TICKER_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)
|
void us_ticker_disable_interrupt(void)
|
||||||
|
@ -217,6 +214,5 @@ void us_ticker_disable_interrupt(void)
|
||||||
|
|
||||||
void us_ticker_clear_interrupt(void)
|
void us_ticker_clear_interrupt(void)
|
||||||
{
|
{
|
||||||
// No implementation needed. The event that triggers the interrupt is
|
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, US_TICKER_EVENT);
|
||||||
// cleared in 'common_rtc_irq_handler'.
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue