You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2022/02/12 11:13:00 UTC

[mynewt-nimble] 01/02: nimble/phy/cmac: Use 31250 tps timer

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-nimble.git

commit 5d67e47985a6f0a46e082ad84a0f0dbbec277eff
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Fri Jan 28 15:33:51 2022 +0100

    nimble/phy/cmac: Use 31250 tps timer
    
    This adjusts phy to 31250 tps timer used in LL on CMAC.
---
 nimble/drivers/dialog_cmac/src/ble_phy.c | 108 +++++++++++--------------------
 1 file changed, 36 insertions(+), 72 deletions(-)

diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c
index 1b1d821..e36a31c 100644
--- a/nimble/drivers/dialog_cmac/src/ble_phy.c
+++ b/nimble/drivers/dialog_cmac/src/ble_phy.c
@@ -258,9 +258,7 @@ struct ble_phy_data {
 #endif
     uint32_t access_addr;       /* Current access address */
     uint32_t crc_init;
-    uint32_t llt_at_cputime;
-    uint32_t cputime_at_llt;
-    uint64_t start_llt;
+    uint64_t llt_rx_start;
     struct ble_mbuf_hdr rxhdr;
     ble_phy_tx_end_func txend_cb;
     void *txend_arg;
@@ -454,24 +452,6 @@ SW_MAC_IRQHandler(void)
     MCU_DIAG_SER('s');
 }
 
-static inline uint32_t
-ble_phy_convert_and_record_start_time(uint32_t cputime, uint8_t rem_usecs)
-{
-    uint64_t ll_val;
-
-    ll_val = cmac_timer_convert_hal2llt(cputime);
-
-    /*
-     * Since we just converted cputime to the LL timer, record both these
-     * values as they will be used to calculate packet reception start time.
-     */
-    g_ble_phy_data.cputime_at_llt = cputime;
-    g_ble_phy_data.llt_at_cputime = ll_val;
-    g_ble_phy_data.start_llt = ll_val + rem_usecs;
-
-    return ll_val;
-}
-
 static inline void
 ble_phy_sw_mac_handover(uint8_t exc)
 {
@@ -525,12 +505,8 @@ ble_phy_rx_end_isr(void)
 static bool
 ble_phy_rx_start_isr(void)
 {
-    uint32_t llt32;
-    uint32_t llt_10_0;
-    uint32_t llt_10_0_mask;
+    uint64_t llt;
     uint32_t timestamp;
-    uint32_t ticks;
-    uint32_t usecs;
     struct ble_mbuf_hdr *ble_hdr;
 
     /* Initialize the ble mbuf header */
@@ -565,44 +541,31 @@ ble_phy_rx_start_isr(void)
     timestamp = CMAC->CM_TS1_REG;
     assert((timestamp & CMAC_CM_TS1_REG_TS1_DIRTY_Msk) != 0);
 
-    /* Get the LL timer (only need 32 bits) */
-    llt32 = cmac_timer_read32();
+    llt = cmac_timer_read37();
 
-    /*
-     * We assume that the timestamp was set within 11 bits, or 2047 usecs, of
-     * when we read the ll timer. We assume this because we need to calculate
-     * the LL timer value at the timestamp. If the low 11 bits of the LL timer
-     * are greater than the timestamp, it means that the upper bits of the
-     * timestamp are correct. If the timestamp value is greater, it means the
-     * timer wrapped the 11 bits and we need to adjust the LL timer value.
+    /* Captured timestamp has only 11lsb, we use current LL timer value to
+     * calculate 37-bit timestamp. To do this we will replace 11 lsb of current
+     * LL timer value with captured value, but we need to check if msb of
+     * captured timestamp (i.e. 11) is the same as in current LL timer value.
+     * If not, it means 10 lsb of LL timer value wrapped around since timestamp
+     * was captured and we need to adjust LL timer value. This assumes that
+     * LL timer value was read no later than 1024 usecs from timestamp capture,
+     * but that's fine since isr should be triggered immediately after capture.
      */
-    llt_10_0_mask = (CMAC_CM_TS1_REG_TS1_TIMER1_9_0_Msk |
-                     CMAC_CM_TS1_REG_TS1_TIMER1_10_Msk);
-    timestamp &= llt_10_0_mask;
-    llt_10_0 = llt32 & llt_10_0_mask;
-    llt32 &= ~llt_10_0_mask;
-    if (timestamp > llt_10_0) {
-        llt32 -= 2048;
+    if (((uint32_t)llt ^ timestamp) & (1 << 10)) {
+        llt -= 1024;
     }
-    llt32 |= timestamp;
+    llt &= ~((uint64_t)0x3ff);
+    llt |= timestamp & 0x3ff;
 
-    /* Actual RX start time needs to account for preamble and access address */
-    llt32 -= g_ble_phy_mode_pkt_start_off[g_ble_phy_data.phy_mode_rx] +
-             g_ble_phy_data.path_delay_rx;
-
-    if (llt32 < g_ble_phy_data.llt_at_cputime) {
-        g_ble_phy_data.llt_at_cputime -= 31;
-        g_ble_phy_data.cputime_at_llt--;
-    }
-
-    /*
-     * We now have the LL timer when the packet was received. Get the cputime
-     * and the leftover usecs.
+    /* Timestamp is captured after access address so we need to adjust rx start
+     * time accordingly.
      */
-    usecs = llt32 - g_ble_phy_data.llt_at_cputime;
-    ticks = os_cputime_usecs_to_ticks(usecs);
-    ble_hdr->beg_cputime = g_ble_phy_data.cputime_at_llt + ticks;
-    ble_hdr->rem_usecs = usecs - os_cputime_ticks_to_usecs(ticks);
+    llt -= g_ble_phy_mode_pkt_start_off[g_ble_phy_data.phy_mode_rx] +
+           g_ble_phy_data.path_delay_rx;
+
+    ble_hdr->beg_cputime = llt >> 5;
+    ble_hdr->rem_usecs = llt & 0x1f;
 
     return true;
 }
@@ -1180,7 +1143,7 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs)
         CMAC->CM_EV_LINKUP_REG = CMAC_CM_EV_LINKUP_REG_LU_CORR_TMR_LD_2_CORR_START_Msk;
     } else {
         wfr_usecs += aa_time;
-        llt = g_ble_phy_data.start_llt;
+        llt = g_ble_phy_data.llt_rx_start;
 
         /*
          * wfr is outside range of CORR_WINDOW so we need to use LLT to start
@@ -1380,7 +1343,8 @@ ble_phy_rx(void)
 int
 ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
 {
-    uint32_t ll_val32;
+    uint64_t llt_rx_start;
+    uint32_t llt32;
     int32_t time_till_start;
     int rc = 0;
 
@@ -1394,21 +1358,22 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
 
     ble_phy_rx();
 
-    /* Get LL timer at cputime */
-    ll_val32 = ble_phy_convert_and_record_start_time(cputime, rem_usecs);
-
-    /* Add remaining usecs to get exact receive start time */
-    ll_val32 += rem_usecs;
+    /* Store LLT value at RX start, we'll need this to set wfr */
+    llt_rx_start = (uint64_t)cputime * 32 + rem_usecs;
+    g_ble_phy_data.llt_rx_start = llt_rx_start;
 
-    /* Adjust start time for rx delays */
-    ll_val32 -= PHY_DELAY_POWER_UP_RX - g_ble_phy_data.path_delay_rx;
+    /* Adjust start time for rx delays.
+     * Note: we can use 32lsb for remaining calculations.
+     */
+    llt32 = llt_rx_start;
+    llt32 -= PHY_DELAY_POWER_UP_RX - g_ble_phy_data.path_delay_rx;
 
     __disable_irq();
-    CMAC->CM_LL_TIMER1_9_0_EQ_X_REG = ll_val32;
+    CMAC->CM_LL_TIMER1_9_0_EQ_X_REG = llt32;
     CMAC->CM_EV_LINKUP_REG =
         CMAC_CM_EV_LINKUP_REG_LU_FRAME_START_2_TMR1_9_0_EQ_X_Msk;
 
-    time_till_start = (int32_t)(ll_val32 - cmac_timer_read32());
+    time_till_start = (int32_t)(llt32 - cmac_timer_read32());
     if (time_till_start <= 0) {
         /*
          * Possible we missed the frame start! If we have, we need to start
@@ -1520,8 +1485,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
     ble_rf_configure();
     ble_rf_setup_tx(rf_chan, g_ble_phy_data.phy_mode_tx);
 
-    ll_val32 = ble_phy_convert_and_record_start_time(cputime, rem_usecs);
-    ll_val32 += rem_usecs;
+    ll_val32 = cputime * 32 + rem_usecs;
     ll_val32 -= PHY_DELAY_POWER_UP_TX + g_ble_phy_data.path_delay_tx;
     /* we can schedule TX only up to 1023us in advance */
     assert((int32_t)(ll_val32 - cmac_timer_read32()) < 1024);