You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2017/11/02 14:26:09 UTC

[GitHub] andrzej-kaczmarek closed pull request #622: nimble: Some fixes for scheduling aux tx/rx

andrzej-kaczmarek closed pull request #622: nimble: Some fixes for scheduling aux tx/rx
URL: https://github.com/apache/mynewt-core/pull/622
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/hw/drivers/nimble/nrf52/src/ble_phy.c b/hw/drivers/nimble/nrf52/src/ble_phy.c
index b39bb07cd..690bbd79f 100644
--- a/hw/drivers/nimble/nrf52/src/ble_phy.c
+++ b/hw/drivers/nimble/nrf52/src/ble_phy.c
@@ -398,8 +398,8 @@ nrf_wait_disabled(void)
  *
  *
  */
-int
-ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs)
+static int
+ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx)
 {
     uint32_t next_cc;
     uint32_t cur_cc;
@@ -407,23 +407,33 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs)
     uint32_t delta;
 
     /*
-     * With the 32.768 kHz crystal, we may need to adjust the RTC compare
-     * value by 1 tick due to the time it takes for radio ramp-up. The code uses
-     * a 2 RTC tick offset, which is 61.0 usecs. The radio ramp-up time is 40 usecs.
-     * This means that with a remainder of 0, TIMER0 should be set to 21 (as
-     * TIMER0 counts at 1MHz). A remainder of 10 or more we will need to add
-     * 1 tick. We dont need to add 1 tick per se, but it does give us slightly
-     * more time and thus less of a chance to miss a tick. Another note: we
-     * cant set TIMER0 CC to 0 as the compare wont occur; it must be 1 or more.
-     * This is why we subtract 9 (as opposed to 10) as rem_uses will be >= 1.
+     * We need to adjust start time to include radio ramp-up and TX pipeline
+     * delay (the latter only if applicable, so only for TX).
+     *
+     * Radio ramp-up time is 40 usecs and TX delay is 3 or 5 usecs depending on
+     * phy, thus we'll offset RTC by 2 full ticks (61 usecs) and then compensate
+     * using TIMER0 with 1 usec precision.
      */
 
-    if (rem_usecs <= 9) {
-        cputime -= 2;
-        rem_usecs += 21;
+    cputime -= 2;
+    rem_usecs += 61;
+    if (tx) {
+        rem_usecs -= BLE_PHY_T_TXENFAST;
+        rem_usecs -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode];
     } else {
-        cputime -= 1;
-        rem_usecs -= 9;
+        rem_usecs -= BLE_PHY_T_RXENFAST;
+    }
+
+    /*
+     * rem_usecs will be no more than 2 ticks, but if it is more than single
+     * tick then we should better count one more low-power tick rather than
+     * 30 high-power usecs. Also make sure we don't set TIMER0 CC to 0 as the
+     * compare won't occur.
+     */
+
+    if (rem_usecs > 30) {
+        cputime++;
+        rem_usecs -= 30;
     }
 
     /*
@@ -884,6 +894,7 @@ ble_phy_rx_start_isr(void)
     int rc;
     uint32_t state;
     uint32_t usecs;
+    uint32_t pdu_usecs;
     uint32_t ticks;
     struct ble_mbuf_hdr *ble_hdr;
     uint8_t *dptr;
@@ -909,18 +920,30 @@ ble_phy_rx_start_isr(void)
 #endif
 
     /*
-     * Calculate receive start time.
+     * Calculate accurate packets start time (with remainder)
      *
-     * XXX: possibly use other routine with remainder!
+     * We may start receiving packet somewhere during preamble in which case
+     * it is possible that actual transmission started before TIMER0 was
+     * running - need to take this into account.
      */
-    usecs = NRF_TIMER0->CC[1] - ble_phy_mode_pdu_start_off(g_ble_phy_data.phy_cur_phy_mode);
+    usecs = NRF_TIMER0->CC[1];
+    pdu_usecs = ble_phy_mode_pdu_start_off(ble_hdr->rxinfo.phy_mode) +
+                g_ble_phy_t_rxaddrdelay[ble_hdr->rxinfo.phy_mode];
+    if (usecs < pdu_usecs) {
+        ticks--;
+        usecs += 30;
+    }
+    usecs -= pdu_usecs;
+
     ticks = os_cputime_usecs_to_ticks(usecs);
-    ble_hdr->rem_usecs = usecs - os_cputime_ticks_to_usecs(ticks);
-    if (ble_hdr->rem_usecs == 31) {
-        ble_hdr->rem_usecs = 0;
+    usecs -= os_cputime_ticks_to_usecs(ticks);
+    if (usecs == 31) {
+        usecs = 0;
         ++ticks;
     }
+
     ble_hdr->beg_cputime = g_ble_phy_data.phy_start_cputime + ticks;
+    ble_hdr->rem_usecs = usecs;
 
     /* XXX: I wonder if we always have the 1st byte. If we need to wait for
      * rx chain delay, it could be 18 usecs from address interrupt. The
@@ -1365,7 +1388,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
     /* Clear timer0 compare to RXEN since we are transmitting */
     NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
 
-    if (ble_phy_set_start_time(cputime, rem_usecs) != 0) {
+    if (ble_phy_set_start_time(cputime, rem_usecs, true) != 0) {
         STATS_INC(ble_phy_stats, tx_late);
         ble_phy_disable();
         rc = BLE_PHY_ERR_TX_LATE;
@@ -1399,7 +1422,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
     /* Clear timer0 compare to TXEN since we are transmitting */
     NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
 
-    if (ble_phy_set_start_time(cputime, rem_usecs) != 0) {
+    if (ble_phy_set_start_time(cputime, rem_usecs, false) != 0) {
         STATS_INC(ble_phy_stats, rx_late);
         NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
         NRF_RADIO->TASKS_RXEN = 1;
diff --git a/net/nimble/controller/include/controller/ble_ll.h b/net/nimble/controller/include/controller/ble_ll.h
index 7be6e4dd7..53e14e91e 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -156,6 +156,7 @@ STATS_SECT_START(ble_ll_stats)
     STATS_SECT_ENTRY(adv_txg)
     STATS_SECT_ENTRY(adv_late_starts)
     STATS_SECT_ENTRY(adv_resched_pdu_fail)
+    STATS_SECT_ENTRY(adv_drop_event)
     STATS_SECT_ENTRY(sched_state_conn_errs)
     STATS_SECT_ENTRY(sched_state_adv_errs)
     STATS_SECT_ENTRY(scan_starts)
diff --git a/net/nimble/controller/src/ble_ll.c b/net/nimble/controller/src/ble_ll.c
index ed36a8212..81fccc778 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -176,6 +176,7 @@ STATS_NAME_START(ble_ll_stats)
     STATS_NAME(ble_ll_stats, adv_txg)
     STATS_NAME(ble_ll_stats, adv_late_starts)
     STATS_NAME(ble_ll_stats, adv_resched_pdu_fail)
+    STATS_NAME(ble_ll_stats, adv_drop_event)
     STATS_NAME(ble_ll_stats, sched_state_conn_errs)
     STATS_NAME(ble_ll_stats, sched_state_adv_errs)
     STATS_NAME(ble_ll_stats, scan_starts)
diff --git a/net/nimble/controller/src/ble_ll_adv.c b/net/nimble/controller/src/ble_ll_adv.c
index 4f55f7f45..99bb24704 100644
--- a/net/nimble/controller/src/ble_ll_adv.c
+++ b/net/nimble/controller/src/ble_ll_adv.c
@@ -844,6 +844,19 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
     rc = ble_phy_setchan(advsm->adv_chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV);
     assert(rc == 0);
 
+#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
+    /* Set phy mode */
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
+        ble_phy_mode_set(BLE_PHY_MODE_1M, BLE_PHY_MODE_1M);
+    } else {
+        ble_phy_mode_set(advsm->pri_phy, advsm->pri_phy);
+    }
+#else
+    ble_phy_mode_set(BLE_PHY_MODE_1M, BLE_PHY_MODE_1M);
+#endif
+#endif
+
     /* Set transmit start time. */
     txstart = sch->start_time + g_ble_ll_sched_offset_ticks;
     rc = ble_phy_tx_set_start_time(txstart, sch->remainder);
@@ -887,19 +900,8 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
 
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
     ble_ll_adv_pdu_make(advsm, adv_pdu);
-
-#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
-    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
-        ble_phy_mode_set(BLE_PHY_MODE_1M, BLE_PHY_MODE_1M);
-    } else {
-        ble_phy_mode_set(advsm->pri_phy, advsm->pri_phy);
-    }
-#endif
 #else
     ble_ll_adv_legacy_pdu_make(advsm, adv_pdu);
-#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
-    ble_phy_mode_set(BLE_PHY_MODE_1M, BLE_PHY_MODE_1M);
-#endif
 #endif
 
     /* Transmit advertisement */
@@ -999,6 +1001,11 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch)
                          BLE_LL_CRCINIT_ADV);
     assert(rc == 0);
 
+#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
+    /* Set phy mode */
+     ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy);
+#endif
+
     /* Set transmit start time. */
     txstart = sch->start_time + g_ble_ll_sched_offset_ticks;
     rc = ble_phy_tx_set_start_time(txstart, sch->remainder);
@@ -1040,10 +1047,6 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch)
 
     ble_ll_adv_pdu_make(advsm, adv_pdu);
 
-#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
-     ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy);
-#endif
-
     /* Transmit advertisement */
     rc = ble_phy_tx(adv_pdu, end_trans);
     os_mbuf_free_chain(adv_pdu);
@@ -2613,6 +2616,8 @@ ble_ll_adv_rx_isr_start(uint8_t pdu_type)
 static void
 ble_ll_adv_drop_event(struct ble_ll_adv_sm *advsm)
 {
+    STATS_INC(ble_ll_stats, adv_drop_event);
+
     ble_ll_sched_rmv_elem(&advsm->adv_sch);
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
     ble_ll_sched_rmv_elem(&advsm->adv_secondary_sch);
@@ -2777,6 +2782,16 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm)
          */
         advsm->adv_pdu_start_time = os_cputime_get32() +
                                     g_ble_ll_sched_offset_ticks;
+
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+        /* If we're past aux (unlikely, but can happen), just drop an event */
+        if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) &&
+                (advsm->adv_pdu_start_time > advsm->adv_secondary_start_time)) {
+            ble_ll_adv_drop_event(advsm);
+            return;
+        }
+#endif
+
         resched_pdu = 1;
     }
 


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services