From ef48541d0988956d8746a7c6f510a1ef2b53b989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Tue, 6 Mar 2018 14:43:14 +0100 Subject: [PATCH] nimble/ll: Improve extended scanner for both PHYs This patch simplify a bit scanner core and make sure to reuse all available bandwith when scanning for two PHYs is requested X-Original-Commit: 1efe9e5a084373104eda914caba8252b054ddb27 --- nimble/controller/src/ble_ll_scan.c | 129 ++++++++++++++-------------- 1 file changed, 66 insertions(+), 63 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index de3178f07..d62620cd1 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1244,9 +1244,9 @@ ble_ll_scan_switch_phy(struct ble_ll_scan_sm *scansm) * * @param arg */ -static uint32_t +static bool ble_ll_scan_start_next_phy(struct ble_ll_scan_sm *scansm, - uint32_t next_event_time) + uint32_t *next_event_time) { struct ble_ll_scan_params *cur_phy; struct ble_ll_scan_params *next_phy; @@ -1256,35 +1256,33 @@ ble_ll_scan_start_next_phy(struct ble_ll_scan_sm *scansm, /* Lets check if we want to switch to other PHY */ if (scansm->cur_phy == scansm->next_phy || scansm->next_phy == PHY_NOT_CONFIGURED) { - return next_event_time; + return false; } cur_phy = &scansm->phy_data[scansm->cur_phy]; next_phy = &scansm->phy_data[scansm->next_phy]; - cur_phy->next_event_start = next_event_time; + /* Store next event for current phy */ + cur_phy->next_event_start = *next_event_time; - if ((int32_t)(next_phy->next_event_start - next_event_time)< 0) { - /* Other PHY already wanted to scan. Allow it */ - ble_ll_scan_switch_phy(scansm); - now = os_cputime_get32(); - if ((int32_t)(next_phy->next_event_start - now) <= 0) { - /* Start with new channel only if PHY was scanning already */ - if (next_phy->next_event_start != 0) { - next_phy->scan_chan = - ble_ll_scan_get_next_adv_prim_chan(next_phy->scan_chan); - } - next_phy->scan_win_start_time = now; - win = os_cputime_usecs_to_ticks(next_phy->scan_window * - BLE_HCI_SCAN_ITVL); + /* Other PHY already wanted to scan. Allow it */ + ble_ll_scan_switch_phy(scansm); - next_phy->next_event_start = now + win; - ble_ll_scan_start(scansm, NULL); - } - next_event_time = next_phy->next_event_start; + now = os_cputime_get32(); + + /* Start with new channel only if PHY was scanning already */ + if (next_phy->next_event_start != 0) { + next_phy->scan_chan = + ble_ll_scan_get_next_adv_prim_chan(next_phy->scan_chan); } + next_phy->scan_win_start_time = now; + win = os_cputime_usecs_to_ticks(next_phy->scan_window * + BLE_HCI_SCAN_ITVL); - return next_event_time; + next_phy->next_event_start = now + win; + + *next_event_time = next_phy->next_event_start; + return true; } static void @@ -1369,6 +1367,16 @@ ble_ll_scan_event_proc(struct os_event *ev) next_event_time = win_start + scan_itvl; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if (inside_window == 0 && + ble_ll_scan_start_next_phy(scansm, &next_event_time)) { + /* Check if we should start next phy. If so let's say we are inside + * the window + */ + inside_window = 1; + } +#endif + /* * If we are not in the standby state it means that the scheduled * scanning event was overlapped in the schedule. In this case all we do @@ -1403,6 +1411,41 @@ ble_ll_scan_event_proc(struct os_event *ev) break; } + if (start_scan && inside_window) { +#ifdef BLE_XCVR_RFCLK + xtal_state = ble_ll_xcvr_rfclk_state(); + if (xtal_state != BLE_RFCLK_STATE_SETTLED) { + if (xtal_state == BLE_RFCLK_STATE_OFF) { + xtal_ticks = g_ble_ll_data.ll_xtal_ticks; + } else { + xtal_ticks = ble_ll_xcvr_rfclk_time_till_settled(); + } + + /* + * Only bother if we have enough time to receive anything + * here. The next event time will turn off the clock. + */ + if (win != 0) { + if ((win - dt) <= xtal_ticks) { + goto done; + } + } + + /* + * If clock off, start clock. Set next event time to now plus + * the clock setting time. + */ + if (xtal_state == BLE_RFCLK_STATE_OFF) { + ble_ll_xcvr_rfclk_start_now(now); + } + next_event_time = now + xtal_ticks; + goto done; + } +#endif + ble_ll_scan_start(scansm, NULL); + goto done; + } + #ifdef BLE_XCVR_RFCLK if (inside_window == 0) { /* @@ -1427,47 +1470,7 @@ ble_ll_scan_event_proc(struct os_event *ev) } #endif - if (start_scan && inside_window) { -#ifdef BLE_XCVR_RFCLK - xtal_state = ble_ll_xcvr_rfclk_state(); - if (xtal_state != BLE_RFCLK_STATE_SETTLED) { - if (xtal_state == BLE_RFCLK_STATE_OFF) { - xtal_ticks = g_ble_ll_data.ll_xtal_ticks; - } else { - xtal_ticks = ble_ll_xcvr_rfclk_time_till_settled(); - } - - /* - * Only bother if we have enough time to receive anything - * here. The next event time will turn off the clock. - */ - if (win != 0) { - if ((win - dt) <= xtal_ticks) { - goto rfclk_not_settled; - } - } - - /* - * If clock off, start clock. Set next event time to now plus - * the clock setting time. - */ - if (xtal_state == BLE_RFCLK_STATE_OFF) { - ble_ll_xcvr_rfclk_start_now(now); - } - next_event_time = now + xtal_ticks; - goto rfclk_not_settled; - } -#endif - ble_ll_scan_start(scansm, NULL); - } else { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - next_event_time = ble_ll_scan_start_next_phy(scansm, next_event_time); -#endif - } - -#ifdef BLE_XCVR_RFCLK -rfclk_not_settled: -#endif +done: OS_EXIT_CRITICAL(sr); os_cputime_timer_start(&scansm->scan_timer, next_event_time); }