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);
     }
 

Reply via email to