This is an automated email from the ASF dual-hosted git repository. andk pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 462c3910c07a67c33707bf47a4a6020a89ce61db Author: Andrzej Kaczmarek <andrzej.kaczma...@codecoup.pl> AuthorDate: Mon Jun 19 23:15:12 2023 +0200 hw/mcu/cmac: Fix os_tick handling The os_tick is handled by 36_10_EQ_Y and 9_0_EQ_Y comparators which requires extra handling to match full value on 2 separate comparators. This could also trigger an assert on wakeup in cmac_timer_slp_disable which expects that no interrupt is fired during that process. This is to guarantee that we complete wake up before timer expires. However, since we initially match on 36_10_EQ_Y only which has resolution of 1024us it's possible that it will trigger an interrupt even though we woke up before complete EQ_Y value matches. To fix this and simplify the process we can use single EQ_Y comparator to match on complete value, just as we do for EQ_X. --- hw/mcu/dialog/cmac/include/mcu/cmac_timer.h | 30 ++++++----------------------- hw/mcu/dialog/cmac/src/cmac_sleep.c | 5 +++-- hw/mcu/dialog/cmac/src/cmac_timer.c | 29 +++++++++------------------- 3 files changed, 18 insertions(+), 46 deletions(-) diff --git a/hw/mcu/dialog/cmac/include/mcu/cmac_timer.h b/hw/mcu/dialog/cmac/include/mcu/cmac_timer.h index 4d5f5d0b0..0c1264733 100644 --- a/hw/mcu/dialog/cmac/include/mcu/cmac_timer.h +++ b/hw/mcu/dialog/cmac/include/mcu/cmac_timer.h @@ -149,38 +149,20 @@ cmac_timer_disable_eq_hal_timer(void) static inline uint32_t cmac_timer_read_eq_hal_os_tick(void) { - return (CMAC->CM_LL_TIMER1_36_10_EQ_Y_REG << 5) | - (CMAC->CM_LL_TIMER1_9_0_EQ_Y_REG >> 5); + return (CMAC->CM_LL_TIMER1_EQ_Y_HI_REG << 5) | + (CMAC->CM_LL_TIMER1_EQ_Y_LO_REG >> 5); } /* Write comparator value for hal_os_tick callback */ static inline void cmac_timer_write_eq_hal_os_tick(uint32_t val) { - uint32_t val_36_10; - - val_36_10 = val >> 5; - CMAC->CM_LL_TIMER1_36_10_EQ_Y_REG = val_36_10; - CMAC->CM_LL_TIMER1_9_0_EQ_Y_REG = val << 5; - - /* If msb comparator is set at least 2 "ticks" ahead, we can enable it here - * and then enable lsb comparator on match. Otherwise, we need to enable lsb - * comparator here to make sure we do not miss a match in case lsb matches - * just after msb (we would not be able to switch from msb to lsb comparator - * on time). - */ - if ((int32_t)(val_36_10 - CMAC->CM_LL_TIMER1_36_10_REG) >= 2) { - CMAC->CM_LL_INT_MSK_SET_REG = CMAC_CM_LL_INT_MSK_SET_REG_LL_TIMER1_36_10_EQ_Y_SEL_Msk; - CMAC->CM_LL_INT_MSK_CLR_REG = CMAC_CM_LL_INT_MSK_CLR_REG_LL_TIMER1_9_0_EQ_Y_SEL_Msk; - } else { - CMAC->CM_LL_INT_MSK_CLR_REG = CMAC_CM_LL_INT_MSK_CLR_REG_LL_TIMER1_36_10_EQ_Y_SEL_Msk; - CMAC->CM_LL_INT_MSK_SET_REG = CMAC_CM_LL_INT_MSK_SET_REG_LL_TIMER1_9_0_EQ_Y_SEL_Msk; - } + CMAC->CM_LL_TIMER1_EQ_Y_HI_REG = val >> 5; + CMAC->CM_LL_TIMER1_EQ_Y_LO_REG = val << 5; + CMAC->CM_LL_INT_MSK_SET_REG = CMAC_CM_LL_INT_MSK_SET_REG_LL_TIMER1_EQ_Y_SEL_Msk; if ((int32_t)(val - cmac_timer_read32_msb()) <= 0) { - CMAC->CM_LL_INT_MSK_CLR_REG = CMAC_CM_LL_INT_MSK_CLR_REG_LL_TIMER1_36_10_EQ_Y_SEL_Msk; - CMAC->CM_LL_INT_MSK_CLR_REG = CMAC_CM_LL_INT_MSK_CLR_REG_LL_TIMER1_9_0_EQ_Y_SEL_Msk; - cm_ll_int_stat_reg = CMAC_CM_LL_INT_STAT_REG_LL_TIMER1_9_0_EQ_Y_SEL_Msk; + cm_ll_int_stat_reg = CMAC_CM_LL_INT_STAT_REG_LL_TIMER1_EQ_Y_SEL_Msk; NVIC_SetPendingIRQ(LL_TIMER2LLC_IRQn); } } diff --git a/hw/mcu/dialog/cmac/src/cmac_sleep.c b/hw/mcu/dialog/cmac/src/cmac_sleep.c index bcf6c12d4..cc78f7047 100644 --- a/hw/mcu/dialog/cmac/src/cmac_sleep.c +++ b/hw/mcu/dialog/cmac/src/cmac_sleep.c @@ -42,8 +42,9 @@ static __IOM uint32_t * const retained_regs[] = { &CMAC->CM_LL_INT_SEL_REG, &CMAC->CM_LL_TIMER1_EQ_X_HI_REG, &CMAC->CM_LL_TIMER1_EQ_X_LO_REG, - &CMAC->CM_LL_TIMER1_36_10_EQ_Y_REG, - &CMAC->CM_LL_TIMER1_9_0_EQ_Y_REG, + &CMAC->CM_LL_TIMER1_EQ_Y_HI_REG, + &CMAC->CM_LL_TIMER1_EQ_Y_LO_REG, + &CMAC->CM_LL_TIMER1_EQ_Y_CTRL_REG, &CMAC->CM_ERROR_DIS_REG, #if MYNEWT_VAL(CMAC_DEBUG_DIAG_ENABLE) &CMAC->CM_DIAG_PORT0_REG, diff --git a/hw/mcu/dialog/cmac/src/cmac_timer.c b/hw/mcu/dialog/cmac/src/cmac_timer.c index 569c3f6d4..1820362ee 100644 --- a/hw/mcu/dialog/cmac/src/cmac_timer.c +++ b/hw/mcu/dialog/cmac/src/cmac_timer.c @@ -50,7 +50,6 @@ void LL_TIMER2LLC_IRQHandler(void) { uint32_t int_stat; - uint32_t val; /* Clear interrupt now since callback may set comparators again */ int_stat = CMAC->CM_LL_INT_STAT_REG | cm_ll_int_stat_reg; @@ -62,16 +61,8 @@ LL_TIMER2LLC_IRQHandler(void) cmac_timer_int_hal_timer(); } - if (int_stat & CMAC_CM_LL_INT_STAT_REG_LL_TIMER1_36_10_EQ_Y_SEL_Msk) { - CMAC->CM_LL_INT_MSK_CLR_REG = CMAC_CM_LL_INT_MSK_CLR_REG_LL_TIMER1_36_10_EQ_Y_SEL_Msk; - CMAC->CM_LL_INT_MSK_SET_REG = CMAC_CM_LL_INT_MSK_SET_REG_LL_TIMER1_9_0_EQ_Y_SEL_Msk; - } - - if (int_stat & CMAC_CM_LL_INT_STAT_REG_LL_TIMER1_9_0_EQ_Y_SEL_Msk) { - val = cmac_timer_read_eq_hal_os_tick(); - if ((int32_t)(val - cmac_timer_read32_msb()) <= 0) { - cmac_timer_int_hal_os_tick(); - } + if (int_stat & CMAC_CM_LL_INT_STAT_REG_LL_TIMER1_EQ_Y_SEL_Msk) { + cmac_timer_int_hal_os_tick(); } } @@ -285,15 +276,14 @@ cmac_timer_init(void) /* Make sure LL Timer does not use limited range */ assert(CMAC->CM_CTRL2_REG & CMAC_CM_CTRL2_REG_LL_TIMER1_9_0_LIMITED_N_Msk); - CMAC->CM_LL_TIMER1_EQ_Y_CTRL_REG = 7; - /* * Set EQ_X and EQ_Y comparators to trigger LL_TIMER2LLC interrupt. * They are used for hal_timer and os_tick respectively. + * Set EQ_Y to match on all 37 bits. */ CMAC->CM_LL_INT_SEL_REG |= CMAC_CM_LL_INT_SEL_REG_LL_TIMER1_EQ_X_SEL_Msk | - CMAC_CM_LL_INT_SEL_REG_LL_TIMER1_36_10_EQ_Y_SEL_Msk | - CMAC_CM_LL_INT_SEL_REG_LL_TIMER1_9_0_EQ_Y_SEL_Msk; + CMAC_CM_LL_INT_SEL_REG_LL_TIMER1_EQ_Y_SEL_Msk; + CMAC->CM_LL_TIMER1_EQ_Y_CTRL_REG = 0x7f; switch_to_llt(); @@ -403,7 +393,7 @@ cmac_timer_int_os_tick_register(cmac_timer_int_func_t func) void cmac_timer_int_os_tick_clear(void) { - CMAC->CM_LL_INT_STAT_REG = CMAC_CM_LL_INT_STAT_REG_LL_TIMER1_9_0_EQ_Y_SEL_Msk; + CMAC->CM_LL_INT_STAT_REG = CMAC_CM_LL_INT_STAT_REG_LL_TIMER1_EQ_Y_SEL_Msk; } uint32_t @@ -431,10 +421,9 @@ cmac_timer_next_at(void) to_next = min(to_next, reg32 - val32); } - if (mask & (CMAC_CM_LL_INT_MSK_SET_REG_LL_TIMER1_36_10_EQ_Y_SEL_Msk | - CMAC_CM_LL_INT_MSK_SET_REG_LL_TIMER1_9_0_EQ_Y_SEL_Msk)) { - reg32 = (CMAC->CM_LL_TIMER1_36_10_EQ_Y_REG << 10) | - CMAC->CM_LL_TIMER1_9_0_EQ_Y_REG; + if (mask & CMAC_CM_LL_INT_MSK_SET_REG_LL_TIMER1_EQ_Y_SEL_Msk) { + reg32 = (CMAC->CM_LL_TIMER1_EQ_Y_HI_REG << 10) | + CMAC->CM_LL_TIMER1_EQ_Y_LO_REG; to_next = min(to_next, reg32 - val32); }