From a5904291f1d0c5f4f95493355e8447bab5c132ab Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 9 Aug 2023 01:53:17 +0200 Subject: [PATCH 1/4] hw/mcu/dialog: Fix XTAL32M settle time calculation We should calculate XTALRDY value assuming worst case which is the max possible RC32M frequency (32.6 MHz). If the actual frequency of RC32M is lower than 32.6 MHz, it will take longer time than set to mark xtal as settled which is still ok since we don't want xtal to be "settled" to early. --- hw/mcu/dialog/da1469x/src/da1469x_clock.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/hw/mcu/dialog/da1469x/src/da1469x_clock.c b/hw/mcu/dialog/da1469x/src/da1469x_clock.c index 114023f24f..22ea67bb39 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_clock.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_clock.c @@ -51,11 +51,14 @@ da1469x_clock_sys_xtal32m_init(void) uint32_t reg; int xtalrdy_cnt; - /* - * Number of 256kHz clock cycles (~4.085us) assuming worst case when actual frequency is 244800. - * RC32M is in range <30.6, 32.6> so 256Khz can ba as low as 30.6MHz / 125 = 244.8kHz. + /* Number of 256kHz clock cycles for XTAL32M to settle. + * To make sure we wait no less than configured settle time, we need to + * calculate using the shortest possible clock cycle, i.e. the max possible + * frequency of RC32M (32.6 MHz). + * + * Max frequency of 256kHz clock: 32.6 MHz / 125 = 260.8 kHz -> 3.834 us */ - xtalrdy_cnt = MYNEWT_VAL(MCU_CLOCK_XTAL32M_SETTLE_TIME_US) * 1000 / 4085; + xtalrdy_cnt = MYNEWT_VAL(MCU_CLOCK_XTAL32M_SETTLE_TIME_US) * 1000 / 3834; reg = CRG_XTAL->XTALRDY_CTRL_REG; reg &= ~(CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Msk); From 3866201d185257365ad9de638c53350fb0d7f063 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 5 Aug 2023 23:50:39 +0200 Subject: [PATCH 2/4] hw/mcu/dialog: Add helper to calculate wakeup ticks This adds helper to calculate number of lpclk ticks required for wakeup, i.e. wakeup fsm + xtal32m settle time. This can be then used to adjust sleep time. --- .../da1469x/include/mcu/da1469x_sleep.h | 1 + hw/mcu/dialog/da1469x/src/da1469x_sleep.c | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/hw/mcu/dialog/da1469x/include/mcu/da1469x_sleep.h b/hw/mcu/dialog/da1469x/include/mcu/da1469x_sleep.h index 9083d715dd..79730890f8 100644 --- a/hw/mcu/dialog/da1469x/include/mcu/da1469x_sleep.h +++ b/hw/mcu/dialog/da1469x/include/mcu/da1469x_sleep.h @@ -33,6 +33,7 @@ struct da1469x_sleep_cb { }; void da1469x_sleep_cb_register(struct da1469x_sleep_cb *cb); +uint32_t da1469x_sleep_wakeup_ticks_get(void); #ifdef __cplusplus } diff --git a/hw/mcu/dialog/da1469x/src/da1469x_sleep.c b/hw/mcu/dialog/da1469x/src/da1469x_sleep.c index fa0f9d2e9a..6a5656b406 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_sleep.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_sleep.c @@ -19,6 +19,7 @@ #include #include "mcu/da1469x_clock.h" +#include "mcu/da1469x_lpclk.h" #include "mcu/da1469x_pd.h" #include "mcu/da1469x_pdc.h" #include "mcu/da1469x_prail.h" @@ -167,3 +168,40 @@ da1469x_sleep_cb_register(struct da1469x_sleep_cb *cb) { } #endif + +#define FAST_WAKEUP_TICKS 12 + +uint32_t +da1469x_sleep_wakeup_ticks_get(void) +{ + uint16_t rc32k_freq; + uint16_t lpclk_freq; + uint32_t wakeup_lpclk_ticks; + uint32_t xtal32m_settle_us; + + rc32k_freq = da1469x_clock_lp_rc32k_freq_get(); + lpclk_freq = da1469x_lpclk_freq_get(); + + if (lpclk_freq == 0) { + wakeup_lpclk_ticks = 0; + } else if (CRG_TOP->PMU_SLEEP_REG & CRG_TOP_PMU_SLEEP_REG_FAST_WAKEUP_Msk) { + /* Calculate worst case XTAL32M settling time, i.e. at the lowest + * frequency of RC32M (30.6 MHz) + * + * Min frequency of 256kHz clock: 30.6 MHz / 125 = 244.8 kHz -> 4.085 us + */ + xtal32m_settle_us = + (CRG_XTAL->XTALRDY_CTRL_REG & CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Msk) * 4085 / 1000; + + wakeup_lpclk_ticks = + /* Wakeup ticks converted from RC32K ticks to lpclk ticks */ + (FAST_WAKEUP_TICKS * lpclk_freq + rc32k_freq - 1) / rc32k_freq + + /* XTAL32M settling time converted to lpclk ticks */ + (xtal32m_settle_us * lpclk_freq + 999999) / 1000000; + } else { + /* TODO add calculations for other wakeup modes */ + wakeup_lpclk_ticks = 0; + } + + return wakeup_lpclk_ticks; +} From c8596c32ea184bd0aeac5cba8ed91acd8a4b18f8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 5 Aug 2023 23:53:03 +0200 Subject: [PATCH 3/4] hw/mcu/dialog: Move lpclk enable to lpclk sysinit In case RCX is enabled, we call lpclk enable from sysinit instead of system init. --- hw/mcu/dialog/da1469x/src/da1469x_lpclk.c | 4 ++++ hw/mcu/dialog/da1469x/src/hal_system.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c b/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c index 3b603cbf5a..4248a90229 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c @@ -79,6 +79,10 @@ da1469x_lpclk_updated(void) void da1469x_lpclk_init(void) { +#if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RCX) + da1469x_lpclk_enabled(); +#endif + #if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, XTAL32K) static struct hal_timer lpclk_settle_tmr; da1469x_clock_lp_xtal32k_enable(); diff --git a/hw/mcu/dialog/da1469x/src/hal_system.c b/hw/mcu/dialog/da1469x/src/hal_system.c index 0a503915d4..d6c3a5f704 100644 --- a/hw/mcu/dialog/da1469x/src/hal_system.c +++ b/hw/mcu/dialog/da1469x/src/hal_system.c @@ -130,7 +130,6 @@ hal_system_clock_start(void) da1469x_clock_lp_rcx_enable(); da1469x_clock_lp_rcx_switch(); da1469x_clock_lp_rcx_calibrate(); - da1469x_lpclk_enabled(); #else /* * We cannot switch lp_clk to XTAL32K here since it needs some time to From 742b87bb9a59b15e7c3b4c4eba898e5f412e0b7f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 6 Aug 2023 21:57:26 +0200 Subject: [PATCH 4/4] hw/mcu/dialog: Rework CMAC sleep calculations Sleep time calculation on CMAC assumed incorrectly that wakeup fsm uses lpclk but in fact RC32K is used so we need to take it into account. To make things easier to handle on CMAC side we will calculate wakeup time on M33 side and pass it to CMAC instead of XTAL32M settle time. This way we don't really need to care about how wakeup fsm is configured. It's now expected that M33 will take care of RC32K calibration and will calculate proper wakeup time based on wakeup fsm settings and XTAL32M settle time, and then notify CMAC on any change so we can recalculate our min sleep time. --- hw/drivers/ipc_cmac/include/ipc_cmac/shm.h | 4 +- hw/drivers/ipc_cmac/include/ipc_cmac/shm_hs.h | 2 + hw/drivers/ipc_cmac/src/shm_hs.c | 56 ++++++++++----- hw/mcu/dialog/cmac/include/mcu/cmac_timer.h | 2 +- hw/mcu/dialog/cmac/src/cmac_isr.c | 7 +- hw/mcu/dialog/cmac/src/cmac_priv.h | 2 +- hw/mcu/dialog/cmac/src/cmac_sleep.c | 68 ++++++++----------- hw/mcu/dialog/cmac/src/cmac_timer.c | 14 ++-- .../da1469x/include/mcu/da1469x_lpclk.h | 3 +- hw/mcu/dialog/da1469x/src/da1469x_lpclk.c | 30 +++++--- 10 files changed, 101 insertions(+), 87 deletions(-) diff --git a/hw/drivers/ipc_cmac/include/ipc_cmac/shm.h b/hw/drivers/ipc_cmac/include/ipc_cmac/shm.h index 376095366f..e8ec5aa96d 100644 --- a/hw/drivers/ipc_cmac/include/ipc_cmac/shm.h +++ b/hw/drivers/ipc_cmac/include/ipc_cmac/shm.h @@ -38,7 +38,7 @@ extern "C" { #define CMAC_SHM_CB_MAGIC 0xc3ac -#define CMAC_SHM_CB_PENDING_OP_LP_CLK 0x0001 +#define CMAC_SHM_CB_PENDING_OP_SLEEP_UPDATE 0x0001 #define CMAC_SHM_CB_PENDING_OP_RF_CAL 0x0002 #define CMAC_SHM_VECT_MAGIC 0xc3ac0001 @@ -59,7 +59,7 @@ struct cmac_shm_ctrl { uint16_t magic; uint16_t pending_ops; uint16_t lp_clock_freq; - uint16_t xtal32m_settle_us; + uint16_t wakeup_lpclk_ticks; }; struct cmac_shm_mbox { diff --git a/hw/drivers/ipc_cmac/include/ipc_cmac/shm_hs.h b/hw/drivers/ipc_cmac/include/ipc_cmac/shm_hs.h index 1de158a94d..4aefa9d243 100644 --- a/hw/drivers/ipc_cmac/include/ipc_cmac/shm_hs.h +++ b/hw/drivers/ipc_cmac/include/ipc_cmac/shm_hs.h @@ -38,6 +38,8 @@ extern volatile struct cmac_shm_debugdata *g_cmac_shm_debugdata; void cmac_host_init(void); void cmac_host_signal2cmac(void); + +void cmac_host_req_sleep_update(void); void cmac_host_rf_calibrate(void); #ifdef __cplusplus diff --git a/hw/drivers/ipc_cmac/src/shm_hs.c b/hw/drivers/ipc_cmac/src/shm_hs.c index 444de258a5..ea40393a08 100644 --- a/hw/drivers/ipc_cmac/src/shm_hs.c +++ b/hw/drivers/ipc_cmac/src/shm_hs.c @@ -36,6 +36,7 @@ #include #include "trng/trng.h" #include "console/console.h" +#include "mcu/da1469x_sleep.h" extern char _binary_cmac_img_bin_start[]; extern char _binary_cmac_img_bin_end; @@ -196,20 +197,10 @@ cmac_host_rand_chk_fill(void) } } -static void -cmac_host_lpclk_cb(uint32_t freq) +static bool +shm_synced(void) { - /* No need to wakeup CMAC if LP clock frequency did not change */ - if (g_cmac_shm_ctrl->lp_clock_freq == freq) { - return; - } - - cmac_shm_lock(); - g_cmac_shm_ctrl->lp_clock_freq = freq; - g_cmac_shm_ctrl->pending_ops |= CMAC_SHM_CB_PENDING_OP_LP_CLK; - cmac_shm_unlock(); - - cmac_host_signal2cmac(); + return g_cmac_shm_ctrl && (g_cmac_shm_ctrl->magic == CMAC_SHM_CB_MAGIC); } static void @@ -234,8 +225,8 @@ shm_configure(void) struct cmac_shm_trim *trim; uint32_t *trim_data; - g_cmac_shm_ctrl->xtal32m_settle_us = - MYNEWT_VAL(MCU_CLOCK_XTAL32M_SETTLE_TIME_US); + g_cmac_shm_ctrl->lp_clock_freq = 0; + g_cmac_shm_ctrl->wakeup_lpclk_ticks = 0; trim = (struct cmac_shm_trim *)g_cmac_shm_trim; trim_data = trim->data; @@ -415,7 +406,7 @@ cmac_start(void) /* Release CMAC from reset and sync */ CRG_TOP->CLK_RADIO_REG &= ~CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Msk; - while (g_cmac_shm_ctrl->magic != CMAC_SHM_CB_MAGIC) { + while (!shm_synced()) { /* Wait for CMAC to initialize */ } NVIC_EnableIRQ(CMAC2SYS_IRQn); @@ -443,7 +434,7 @@ cmac_host_init(void) cmac_start(); - da1469x_lpclk_register_cmac_cb(cmac_host_lpclk_cb); + cmac_host_req_sleep_update(); #if MYNEWT_VAL(CMAC_DEBUG_HOST_PRINT_ENABLE) && MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) /* Trim values are calculated on RF init, so are valid after synced with CMAC */ @@ -462,9 +453,40 @@ cmac_host_signal2cmac(void) da1469x_pdc_set(g_cmac_host_pdc_sys2cmac); } +void +cmac_host_req_sleep_update(void) +{ + uint16_t lpclk_freq; + uint32_t wakeup_lpclk_ticks; + + if (!shm_synced()) { + return; + } + + lpclk_freq = da1469x_lpclk_freq_get(); + wakeup_lpclk_ticks = da1469x_sleep_wakeup_ticks_get(); + + if ((g_cmac_shm_ctrl->lp_clock_freq == lpclk_freq) && + (g_cmac_shm_ctrl->wakeup_lpclk_ticks == wakeup_lpclk_ticks)) { + return; + } + + cmac_shm_lock(); + g_cmac_shm_ctrl->lp_clock_freq = lpclk_freq; + g_cmac_shm_ctrl->wakeup_lpclk_ticks = wakeup_lpclk_ticks; + g_cmac_shm_ctrl->pending_ops |= CMAC_SHM_CB_PENDING_OP_SLEEP_UPDATE; + cmac_shm_unlock(); + + cmac_host_signal2cmac(); +} + void cmac_host_rf_calibrate(void) { + if (!shm_synced()) { + return; + } + cmac_shm_lock(); g_cmac_shm_ctrl->pending_ops |= CMAC_SHM_CB_PENDING_OP_RF_CAL; cmac_shm_unlock(); diff --git a/hw/mcu/dialog/cmac/include/mcu/cmac_timer.h b/hw/mcu/dialog/cmac/include/mcu/cmac_timer.h index 0c12647336..b8e56dd730 100644 --- a/hw/mcu/dialog/cmac/include/mcu/cmac_timer.h +++ b/hw/mcu/dialog/cmac/include/mcu/cmac_timer.h @@ -35,7 +35,7 @@ extern struct cmac_timer_ctrl g_cmac_timer_ctrl; void cmac_timer_init(void); void cmac_timer_slp_enable(uint32_t ticks); void cmac_timer_slp_disable(uint32_t exp_ticks); -bool cmac_timer_slp_update(void); +void cmac_timer_slp_update(uint16_t lp_clock_freq); bool cmac_timer_slp_is_ready(void); #if MYNEWT_VAL(MCU_SLP_TIMER_32K_ONLY) static inline uint32_t diff --git a/hw/mcu/dialog/cmac/src/cmac_isr.c b/hw/mcu/dialog/cmac/src/cmac_isr.c index a460687d3c..3147133076 100644 --- a/hw/mcu/dialog/cmac/src/cmac_isr.c +++ b/hw/mcu/dialog/cmac/src/cmac_isr.c @@ -17,8 +17,10 @@ * under the License. */ +#include #include #include +#include #include #include #include @@ -40,8 +42,9 @@ SYS2CMAC_IRQHandler(void) cmac_mbox_read(); cmac_rand_read(); - if (pending_ops & CMAC_SHM_CB_PENDING_OP_LP_CLK) { - cmac_sleep_recalculate(); + if (pending_ops & CMAC_SHM_CB_PENDING_OP_SLEEP_UPDATE) { + cmac_timer_slp_update(g_cmac_shm_ctrl.lp_clock_freq); + cmac_sleep_wakeup_time_update(g_cmac_shm_ctrl.wakeup_lpclk_ticks); } if (pending_ops & CMAC_SHM_CB_PENDING_OP_RF_CAL) { diff --git a/hw/mcu/dialog/cmac/src/cmac_priv.h b/hw/mcu/dialog/cmac/src/cmac_priv.h index 45edf43daf..eab0309d0c 100644 --- a/hw/mcu/dialog/cmac/src/cmac_priv.h +++ b/hw/mcu/dialog/cmac/src/cmac_priv.h @@ -30,7 +30,7 @@ extern "C" { extern int8_t g_cmac_pdc_cmac2sys; void cmac_sleep(void); -void cmac_sleep_recalculate(void); +void cmac_sleep_wakeup_time_update(uint16_t wakeup_lpclk_ticks); #ifdef __cplusplus } diff --git a/hw/mcu/dialog/cmac/src/cmac_sleep.c b/hw/mcu/dialog/cmac/src/cmac_sleep.c index cc78f70471..c7214382cc 100644 --- a/hw/mcu/dialog/cmac/src/cmac_sleep.c +++ b/hw/mcu/dialog/cmac/src/cmac_sleep.c @@ -72,9 +72,9 @@ static uint32_t g_retained_regs_val[ ARRAY_SIZE(retained_regs) ]; static uint32_t g_mcu_wait_for_swd_start; /* Minimum time required to go to sleep (until switch to SLP) and then wake up */ -static uint32_t g_mcu_wakeup_usecs_min; +static uint32_t g_mcu_sleep_lp_ticks_min; -static bool +static inline bool cmac_sleep_is_switch_allowed(void) { return (ble_phy_xcvr_state_get() == 0) && @@ -168,44 +168,34 @@ cmac_sleep_wait4xtal(void) *(volatile uint32_t *)0x5000001c = 1; } -#define T_USEC(_t) (_t) -#define T_LPTICK(_t) ((_t) * cmac_timer_slp_tick_us()) -#define T_LPTICK_U(_t) (T_LPTICK(_t) * 15 / 10) +#define T_USEC(_t) (((_t) + cmac_timer_slp_tick_us() - 1) / \ + cmac_timer_slp_tick_us()) +#define T_LPTICK(_t) (_t) -static void -cmac_sleep_calculate_wakeup_time(void) +void +cmac_sleep_wakeup_time_update(uint16_t wakeup_lpclk_ticks) { - assert(g_cmac_shm_ctrl.xtal32m_settle_us); + if (wakeup_lpclk_ticks == 0) { + g_mcu_sleep_lp_ticks_min = 0; + return; + } - g_mcu_wakeup_usecs_min = + g_mcu_sleep_lp_ticks_min = /* - * We need ~12us to prepare for sleep before starting switch to SLP. + * We need ~15us to prepare for sleep before starting switch to SLP. * Switch to SLP is done by switching SLP clock to LPCLK first and then * enabling SLP. The former has to be synchronized with negative edge of * LPCLK and the latter happens on positive edge of LPCLK so we just * assume 2 LPCLK ticks in worst case. */ - T_USEC(12) + T_LPTICK(2) + + T_USEC(15) + T_LPTICK(2) + /* - * On wake up we assume fast wake up mode which has 3 phases that take - * up to 2, 2 and 3 LPCLK ticks respectively (need to add some margin - * here for worst-worst case). XTAL32M is started at 3rd phase and we - * need to wait for it to settle before switch back to LLT. This is done - * by disabling SLP and then switching SLP clock to PCLK. Both actions - * are synchronized with LPCLK negative edge so take 2 LPCLK ticks in - * worst case. Finally, LLP compensation takes around 50us. + * After wakeup (this includes XTAL32M settling) we need to switch back + * to LLT. This is done by disabling SLP and then switching SLP clock to + * PCLK. Both actions are synchronized with LPCLK negative edge so take + * 2 LPCLK ticks in worst case. Finally, LLT compensation takes ~50us. */ - T_LPTICK_U(2) + T_LPTICK_U(2) + - max(T_LPTICK_U(3), T_USEC(g_cmac_shm_ctrl.xtal32m_settle_us)) + - T_LPTICK(2) + T_USEC(50); -} - -void -cmac_sleep_recalculate(void) -{ - if (cmac_timer_slp_update()) { - cmac_sleep_calculate_wakeup_time(); - } + T_LPTICK(wakeup_lpclk_ticks) + T_LPTICK(2) + T_USEC(50); } extern bool ble_rf_try_recalibrate(uint32_t idle_time_us); @@ -228,25 +218,21 @@ cmac_sleep(void) cmac_pdc_ack_all(); wakeup_at = cmac_timer_next_at(); + sleep_usecs = wakeup_at - cmac_timer_read32(); - /* - * At this point in time we know exactly when next LLT interrupt should - * happen so need to make sure we can be up and running on time. - */ + if (ble_rf_try_recalibrate(sleep_usecs)) { + goto skip_sleep; + } - sleep_usecs = wakeup_at - cmac_timer_read32() - g_mcu_wakeup_usecs_min; - if ((int32_t)sleep_usecs <= 0) { + if (g_mcu_sleep_lp_ticks_min == 0) { switch_to_slp = false; deep_sleep = false; goto do_sleep; } - if (ble_rf_try_recalibrate(sleep_usecs)) { - goto skip_sleep; - } - - sleep_lp_ticks = cmac_timer_usecs_to_lp_ticks(sleep_usecs); - if (sleep_lp_ticks <= 1) { + sleep_lp_ticks = cmac_timer_usecs_to_lp_ticks(sleep_usecs) - + g_mcu_sleep_lp_ticks_min; + if ((int32_t)sleep_lp_ticks <= 1) { switch_to_slp = false; deep_sleep = false; goto do_sleep; diff --git a/hw/mcu/dialog/cmac/src/cmac_timer.c b/hw/mcu/dialog/cmac/src/cmac_timer.c index 1820362eee..a230c9efdb 100644 --- a/hw/mcu/dialog/cmac/src/cmac_timer.c +++ b/hw/mcu/dialog/cmac/src/cmac_timer.c @@ -334,15 +334,11 @@ cmac_timer_slp_disable(uint32_t exp_ticks) assert(CMAC->CM_LL_INT_STAT_REG == 0); } -bool -cmac_timer_slp_update(void) +void +cmac_timer_slp_update(uint16_t lp_clock_freq) { - uint32_t lp_clock_freq; - - lp_clock_freq = g_cmac_shm_ctrl.lp_clock_freq; - if (lp_clock_freq == g_cmac_timer_slp.freq) { - return false; + return; } g_cmac_timer_slp.freq = lp_clock_freq; @@ -353,8 +349,6 @@ cmac_timer_slp_update(void) g_cmac_timer_slp.tick_ns = 1000000000 / g_cmac_timer_slp.freq; } #endif - - return true; } bool @@ -363,7 +357,7 @@ cmac_timer_slp_is_ready(void) #if MYNEWT_VAL(MCU_SLP_TIMER_32K_ONLY) return g_cmac_timer_slp.freq == 32768; #else - return g_cmac_timer_slp.freq; + return g_cmac_timer_slp.freq != 0; #endif } diff --git a/hw/mcu/dialog/da1469x/include/mcu/da1469x_lpclk.h b/hw/mcu/dialog/da1469x/include/mcu/da1469x_lpclk.h index 5f0ace4fc5..9cdfe95eb9 100644 --- a/hw/mcu/dialog/da1469x/include/mcu/da1469x_lpclk.h +++ b/hw/mcu/dialog/da1469x/include/mcu/da1469x_lpclk.h @@ -26,9 +26,8 @@ extern "C" { #endif -typedef void (da1469x_lpclk_cb)(uint32_t freq); +uint16_t da1469x_lpclk_freq_get(void); -void da1469x_lpclk_register_cmac_cb(da1469x_lpclk_cb *cb); /* Stable lp clock enabled (e.g. switched to XTAL after settling) */ void da1469x_lpclk_enabled(void); /* Frequency of lp clock changed (e.g. after RCX recalibration) */ diff --git a/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c b/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c index 4248a90229..b562977d02 100644 --- a/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c +++ b/hw/mcu/dialog/da1469x/src/da1469x_lpclk.c @@ -28,11 +28,12 @@ #include "hal/hal_timer.h" #include "os/os_cputime.h" #include "da1469x_priv.h" +#if MYNEWT_PKG_apache_mynewt_core__hw_drivers_ipc_cmac +#include "ipc_cmac/shm.h" +#endif bool g_mcu_lpclk_available; -static da1469x_lpclk_cb *g_da1469x_lpclk_cmac_cb; - #if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, XTAL32K) static void da1469x_lpclk_settle_tmr_cb(void *arg) @@ -45,22 +46,29 @@ da1469x_lpclk_settle_tmr_cb(void *arg) static void da1469x_lpclk_notify(void) { - if (!g_da1469x_lpclk_cmac_cb || !g_mcu_lpclk_available) { + if (!g_mcu_lpclk_available) { return; } -#if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, XTAL32K) - g_da1469x_lpclk_cmac_cb(32768); -#elif MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RCX) - g_da1469x_lpclk_cmac_cb(da1469x_clock_lp_rcx_freq_get()); +#if MYNEWT_PKG_apache_mynewt_core__hw_drivers_ipc_cmac + cmac_host_req_sleep_update(); #endif } -void -da1469x_lpclk_register_cmac_cb(da1469x_lpclk_cb *cb) +uint16_t +da1469x_lpclk_freq_get(void) { - g_da1469x_lpclk_cmac_cb = cb; - da1469x_lpclk_notify(); + if (!g_mcu_lpclk_available) { + return 0; + } + +#if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, XTAL32K) + return 32768; +#elif MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RCX) + return da1469x_clock_lp_rcx_freq_get(); +#else + return 0; +#endif } void