You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by we...@apache.org on 2017/03/16 16:59:43 UTC
[3/3] incubator-mynewt-core git commit: Checking in almost working
code. Not quite there yet.
Checking in almost working code. Not quite there yet.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/6db66772
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/6db66772
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/6db66772
Branch: refs/heads/nrf_cputime
Commit: 6db66772cf077f1ac3cf84148bec47453e9b208c
Parents: 94a59a3
Author: William San Filippo <wi...@runtime.io>
Authored: Thu Mar 16 09:48:28 2017 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Thu Mar 16 09:48:28 2017 -0700
----------------------------------------------------------------------
apps/bletest/src/main.c | 2 +-
hw/drivers/nimble/nrf52/include/ble/xcvr.h | 22 +++
hw/drivers/nimble/nrf52/src/ble_phy.c | 17 ++
.../controller/include/controller/ble_ll.h | 25 ++-
.../include/controller/ble_ll_sched.h | 5 +
.../controller/include/controller/ble_ll_xcvr.h | 48 +++++
.../controller/include/controller/ble_phy.h | 10 +
net/nimble/controller/src/ble_ll.c | 30 +++
net/nimble/controller/src/ble_ll_adv.c | 24 +++
net/nimble/controller/src/ble_ll_conn.c | 4 +
net/nimble/controller/src/ble_ll_scan.c | 129 ++++++++++++-
net/nimble/controller/src/ble_ll_sched.c | 106 +++++++++++
net/nimble/controller/src/ble_ll_xcvr.c | 183 +++++++++++++++++++
net/nimble/controller/syscfg.yml | 8 +
net/nimble/host/src/ble_hs_hci_evt.c | 9 +-
net/nimble/syscfg.yml | 2 +-
16 files changed, 612 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/apps/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletest/src/main.c b/apps/bletest/src/main.c
index e2519eb..efb3fd4 100755
--- a/apps/bletest/src/main.c
+++ b/apps/bletest/src/main.c
@@ -172,7 +172,7 @@ bletest_multi_adv_instances[BLETEST_CFG_ADV_TEST_INSTANCES] = {
#define BLETEST_CFG_MAX_CE_LEN (BLETEST_CFG_CONN_ITVL)
#define BLETEST_CFG_CONN_PEER_ADDR_TYPE (BLE_HCI_CONN_PEER_ADDR_PUBLIC)
#define BLETEST_CFG_CONN_OWN_ADDR_TYPE (BLE_HCI_ADV_OWN_ADDR_PUBLIC)
-#define BLETEST_CFG_CONCURRENT_CONNS (1)
+#define BLETEST_CFG_CONCURRENT_CONNS (8)
/* Test packet config */
#define BLETEST_CFG_RAND_PKT_SIZE (1)
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/hw/drivers/nimble/nrf52/include/ble/xcvr.h
----------------------------------------------------------------------
diff --git a/hw/drivers/nimble/nrf52/include/ble/xcvr.h b/hw/drivers/nimble/nrf52/include/ble/xcvr.h
index effe81d..45d2739 100644
--- a/hw/drivers/nimble/nrf52/include/ble/xcvr.h
+++ b/hw/drivers/nimble/nrf52/include/ble/xcvr.h
@@ -24,8 +24,30 @@
extern "C" {
#endif
+/*
+ * WWW: Need to think about this. Does this definition need to be in xcvr.h?
+ * I guess this should not depend on the 32768 crystal to be honest. This
+ * should be done for TIMER0 as well since the rf clock chews up more current.
+ * Deal with this later.
+ *
+ * Another note: BLE_XTAL_SETTLE_TIME should be bsp related (I guess). There
+ * should be a note in there that the converted usecs to ticks value of this
+ * should not be 0. Thus: if you are using a 32.768 os cputime freq, the min
+ * value of settle time should be 31 usecs. I would suspect all settling times
+ * would exceed 31 usecs.
+ */
+
+/* Determines if we need to turn on/off rf clock */
+#undef BLE_XCVR_RFCLK
+
/* Transceiver specific definitions */
#if MYNEWT_VAL(OS_CPUTIME_FREQ) == 32768
+
+/* We will turn on/off rf clock */
+#if MYNEWT_VAL(BLE_XTAL_SETTLE_TIME) != 0
+#define BLE_XCVR_RFCLK
+#endif
+
/*
* NOTE: we have to account for the RTC output compare issue, which is why
* this number is much larger when using the 32.768 crystal for cputime. We
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/hw/drivers/nimble/nrf52/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/hw/drivers/nimble/nrf52/src/ble_phy.c b/hw/drivers/nimble/nrf52/src/ble_phy.c
index 410e0dc..a3254ca 100644
--- a/hw/drivers/nimble/nrf52/src/ble_phy.c
+++ b/hw/drivers/nimble/nrf52/src/ble_phy.c
@@ -794,6 +794,8 @@ int
ble_phy_init(void)
{
int rc;
+
+#if !defined(BLE_XCVR_RFCLK)
uint32_t os_tmo;
/* Make sure HFXO is started */
@@ -808,6 +810,7 @@ ble_phy_init(void)
return BLE_PHY_ERR_INIT;
}
}
+#endif
/* Set phy channel to an invalid channel so first set channel works */
g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS;
@@ -1498,3 +1501,17 @@ ble_phy_resolv_list_disable(void)
g_ble_phy_data.phy_privacy = 0;
}
#endif
+
+#ifdef BLE_XCVR_RFCLK
+void
+ble_phy_rfclk_enable(void)
+{
+ NRF_CLOCK->TASKS_HFCLKSTART = 1;
+}
+
+void
+ble_phy_rfclk_disable(void)
+{
+ NRF_CLOCK->TASKS_HFCLKSTOP = 1;
+}
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/controller/include/controller/ble_ll.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll.h b/net/nimble/controller/include/controller/ble_ll.h
index d46f722..cdb170f 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -22,8 +22,10 @@
#include "stats/stats.h"
#include "os/os_eventq.h"
+#include "os/os_callout.h"
#include "os/os_cputime.h"
#include "nimble/nimble_opt.h"
+#include "controller/ble_phy.h"
#ifdef __cplusplus
extern "C" {
@@ -61,11 +63,22 @@ struct ble_ll_obj
/* Number of ACL data packets supported */
uint8_t ll_num_acl_pkts;
+
+#ifdef BLE_XCVR_RFCLK
+ uint8_t ll_rfclk_state;
+ uint16_t ll_xtal_ticks;
+#else
uint8_t _pad;
+ uint16_t _pad16;
+#endif
/* ACL data packet size */
uint16_t ll_acl_pkt_size;
- uint16_t _pad16;
+
+#ifdef BLE_XCVR_RFCLK
+ uint32_t ll_rfclk_start_time;
+ struct hal_timer ll_rfclk_timer;
+#endif
/* Task event queue */
struct os_eventq ll_evq;
@@ -382,6 +395,11 @@ int ble_ll_rand_data_get(uint8_t *buf, uint8_t len);
void ble_ll_rand_prand_get(uint8_t *prand);
int ble_ll_rand_start(void);
+/* Clock management */
+#ifdef BLE_XCVR_RFCLK
+void ble_ll_rfclk_start(uint32_t cputime);
+#endif
+
/*
* XXX: temporary LL debug log. Will get removed once we transition to real
* log
@@ -408,6 +426,11 @@ int ble_ll_rand_start(void);
#define BLE_LL_LOG_ID_ADV_TXBEG (50)
#define BLE_LL_LOG_ID_ADV_TXDONE (60)
#define BLE_LL_LOG_ID_SCHED (80)
+#define BLE_LL_LOG_ID_RFCLK_START (90)
+#define BLE_LL_LOG_ID_RFCLK_ENABLE (91)
+#define BLE_LL_LOG_ID_RFCLK_STOP (95)
+#define BLE_LL_LOG_ID_RFCLK_SCHED_DIS (96)
+#define BLE_LL_LOG_ID_RFCLK_SCAN_DIS (97)
#ifdef BLE_LL_LOG
void ble_ll_log(uint8_t id, uint8_t arg8, uint16_t arg16, uint32_t arg32);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/controller/include/controller/ble_ll_sched.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_sched.h b/net/nimble/controller/include/controller/ble_ll_sched.h
index bf3bc6d..d2321b7 100644
--- a/net/nimble/controller/include/controller/ble_ll_sched.h
+++ b/net/nimble/controller/include/controller/ble_ll_sched.h
@@ -149,6 +149,11 @@ int ble_ll_sched_next_time(uint32_t *next_event_time);
/* Stop the scheduler */
void ble_ll_sched_stop(void);
+#ifdef BLE_XCVR_RFCLK
+/* Check if RF clock needs to be restarted */
+void ble_ll_sched_rfclk_chk_restart(void);
+#endif
+
#ifdef __cplusplus
}
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/controller/include/controller/ble_ll_xcvr.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_xcvr.h b/net/nimble/controller/include/controller/ble_ll_xcvr.h
new file mode 100644
index 0000000..0ede701
--- /dev/null
+++ b/net/nimble/controller/include/controller/ble_ll_xcvr.h
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_BLE_LL_XCVR_
+#define H_BLE_LL_XCVR_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef BLE_XCVR_RFCLK
+
+/* RF clock states */
+#define BLE_RFCLK_STATE_OFF (0)
+#define BLE_RFCLK_STATE_ON (1)
+#define BLE_RFCLK_STATE_SETTLED (2)
+
+int ble_ll_xcvr_rfclk_state(void);
+void ble_ll_xcvr_rfclk_start(uint32_t cputime);
+void ble_ll_xcvr_rfclk_start_now(uint32_t now);
+void ble_ll_xcvr_rfclk_stop(void);
+void ble_ll_xcvr_rfclk_enable(void);
+void ble_ll_xcvr_rfclk_disable(void);
+uint32_t ble_ll_xcvr_rfclk_time_till_settled(void);
+void ble_ll_xcvr_rfclk_timer_exp(void *arg);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_LL_ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/controller/include/controller/ble_phy.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_phy.h b/net/nimble/controller/include/controller/ble_phy.h
index f300a13..e2b83e3 100644
--- a/net/nimble/controller/include/controller/ble_phy.h
+++ b/net/nimble/controller/include/controller/ble_phy.h
@@ -20,6 +20,8 @@
#ifndef H_BLE_PHY_
#define H_BLE_PHY_
+#include "ble/xcvr.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -129,6 +131,14 @@ void ble_phy_wfr_enable(uint32_t wfr_usecs);
#define ble_phy_stop_usec_timer()
#endif
+#ifdef BLE_XCVR_RFCLK
+/* Starts rf clock */
+void ble_phy_rfclk_enable(void);
+
+/* Stops rf clock */
+void ble_phy_rfclk_disable(void);
+#endif
+
/*
* Used to restart reception on same channel after wfr timer expiration or
* frame received.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/controller/src/ble_ll.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll.c b/net/nimble/controller/src/ble_ll.c
index 0d1fa07..1a06d4e 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -39,6 +39,7 @@
#include "controller/ble_ll_hci.h"
#include "controller/ble_ll_whitelist.h"
#include "controller/ble_ll_resolv.h"
+#include "controller/ble_ll_xcvr.h"
#include "ble_ll_conn_priv.h"
/* XXX:
@@ -224,6 +225,15 @@ ble_ll_log(uint8_t id, uint8_t arg8, uint16_t arg16, uint32_t arg32)
os_sr_t sr;
struct ble_ll_log *le;
+ /* WWW */
+ if ((id >= 90) || (id == 10) || (id == 20)) {
+ goto good;
+ } else {
+ return;
+ }
+good:
+ /* WWW */
+
OS_ENTER_CRITICAL(sr);
le = &g_ble_ll_log[g_ble_ll_log_index];
le->cputime = os_cputime_get32();
@@ -1181,6 +1191,11 @@ ble_ll_reset(void)
/* Set state to standby */
ble_ll_state_set(BLE_LL_STATE_STANDBY);
+#ifdef BLE_XCVR_RFCLK
+ /* Stops rf clock and rfclock timer */
+ ble_ll_xcvr_rfclk_stop();
+#endif
+
/* Reset our random address */
memset(g_random_addr, 0, BLE_DEV_ADDR_LEN);
@@ -1225,11 +1240,26 @@ ble_ll_init(void)
{
int rc;
uint8_t features;
+#ifdef BLE_XCVR_RFCLK
+ uint32_t xtal_ticks;
+#endif
struct ble_ll_obj *lldata;
/* Ensure this function only gets called by sysinit. */
SYSINIT_ASSERT_ACTIVE();
+#ifdef BLE_XCVR_RFCLK
+ /* Settling time of crystal, in ticks */
+ xtal_ticks = MYNEWT_VAL(BLE_XTAL_SETTLE_TIME);
+ assert(xtal_ticks != 0);
+ g_ble_ll_data.ll_xtal_ticks = os_cputime_usecs_to_ticks(xtal_ticks);
+
+ /* Initialize rf clock timer */
+ os_cputime_timer_init(&g_ble_ll_data.ll_rfclk_timer,
+ ble_ll_xcvr_rfclk_timer_exp, NULL);
+
+#endif
+
/* Get pointer to global data object */
lldata = &g_ble_ll_data;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/controller/src/ble_ll_adv.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_adv.c b/net/nimble/controller/src/ble_ll_adv.c
index dd27336..b478922 100644
--- a/net/nimble/controller/src/ble_ll_adv.c
+++ b/net/nimble/controller/src/ble_ll_adv.c
@@ -746,6 +746,10 @@ ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm)
ble_ll_wfr_disable();
ble_ll_state_set(BLE_LL_STATE_STANDBY);
g_ble_ll_cur_adv_sm = NULL;
+ ble_ll_scan_chk_resume();
+#ifdef BLE_XCVR_RFCLK
+ ble_ll_sched_rfclk_chk_restart();
+#endif
}
#else
if (ble_ll_state_get() == BLE_LL_STATE_ADV) {
@@ -753,6 +757,12 @@ ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm)
ble_ll_wfr_disable();
ble_ll_state_set(BLE_LL_STATE_STANDBY);
g_ble_ll_cur_adv_sm = NULL;
+ ble_ll_scan_chk_resume();
+#ifdef BLE_XCVR_RFCLK
+ /* WWW */
+ ble_ll_log(201,0,0,0);
+ ble_ll_sched_rfclk_chk_restart();
+#endif
}
#endif
OS_EXIT_CRITICAL(sr);
@@ -1508,6 +1518,11 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm)
/* Check if we need to resume scanning */
ble_ll_scan_chk_resume();
+ /* Turn off the clock if not doing anything else */
+#ifdef BLE_XCVR_RFCLK
+ ble_ll_sched_rfclk_chk_restart();
+#endif
+
/* This event is over. Set adv channel to first one */
advsm->adv_chan = ble_ll_adv_first_chan(advsm);
@@ -1600,6 +1615,14 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm)
/* Schedule advertising transmit */
ble_ll_adv_set_sched(advsm);
+ /* WWW: Need to look at direct advertising (HD) to see if I messed up
+ * the resched pdu call.
+ *
+ * For xcvr clock, we only need to worry when we schedule new adv
+ * event. We want to make sure we dont turn off the clock if we are
+ * not done with the advertising event. Think about this.
+ */
+
/*
* In the unlikely event we cant reschedule this, just post a done
* event and we will reschedule the next advertising event
@@ -1607,6 +1630,7 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm)
if (resched_pdu) {
rc = ble_ll_sched_adv_resched_pdu(&advsm->adv_sch);
} else {
+ /* Reschedule advertising event */
rc = ble_ll_sched_adv_reschedule(&advsm->adv_sch, &start_time,
max_delay_ticks);
if (!rc) {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/controller/src/ble_ll_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_conn.c b/net/nimble/controller/src/ble_ll_conn.c
index 1f4ab8b..253e96e 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -2049,6 +2049,10 @@ ble_ll_conn_event_end(struct os_event *ev)
/* Check if we need to resume scanning */
ble_ll_scan_chk_resume();
+#ifdef BLE_XCVR_RFCLK
+ ble_ll_sched_rfclk_chk_restart();
+#endif
+
/* If we have transmitted the terminate IND successfully, we are done */
if ((connsm->csmflags.cfbit.terminate_ind_txd) ||
(connsm->csmflags.cfbit.terminate_ind_rxd)) {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/controller/src/ble_ll_scan.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_scan.c b/net/nimble/controller/src/ble_ll_scan.c
index 306b8cc..5b81219 100644
--- a/net/nimble/controller/src/ble_ll_scan.c
+++ b/net/nimble/controller/src/ble_ll_scan.c
@@ -37,6 +37,7 @@
#include "controller/ble_ll_hci.h"
#include "controller/ble_ll_whitelist.h"
#include "controller/ble_ll_resolv.h"
+#include "controller/ble_ll_xcvr.h"
#include "hal/hal_gpio.h"
/*
@@ -618,6 +619,37 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm, uint8_t chan)
}
}
+#ifdef BLE_XCVR_RFCLK
+static void
+ble_ll_scan_rfclk_chk_stop(void)
+{
+ int stop;
+ int32_t time_till_next;
+ os_sr_t sr;
+ uint32_t next_time;
+
+ stop = 0;
+ OS_ENTER_CRITICAL(sr);
+ if (ble_ll_sched_next_time(&next_time)) {
+ /*
+ * If the time until the next event is too close, dont bother to turn
+ * off the clock
+ */
+ time_till_next = (int32_t)(next_time - os_cputime_get32());
+ if (time_till_next > g_ble_ll_data.ll_xtal_ticks) {
+ stop = 1;
+ }
+ } else {
+ stop = 1;
+ }
+ if (stop) {
+ ble_ll_log(BLE_LL_LOG_ID_RFCLK_SCAN_DIS, g_ble_ll_data.ll_rfclk_state,0,0);
+ ble_ll_xcvr_rfclk_disable();
+ }
+ OS_EXIT_CRITICAL(sr);
+}
+#endif
+
/**
* Called to determine if we are inside or outside the scan window. If we
* are inside the scan window it means that the device should be receiving
@@ -635,6 +667,7 @@ ble_ll_scan_window_chk(struct ble_ll_scan_sm *scansm, uint32_t cputime)
int rc;
uint8_t chan;
uint32_t itvl;
+ uint32_t dt;
uint32_t win_start;
itvl = os_cputime_usecs_to_ticks(scansm->scan_itvl * BLE_HCI_SCAN_ITVL);
@@ -651,7 +684,13 @@ ble_ll_scan_window_chk(struct ble_ll_scan_sm *scansm, uint32_t cputime)
rc = 0;
if (scansm->scan_window != scansm->scan_itvl) {
itvl = os_cputime_usecs_to_ticks(scansm->scan_window * BLE_HCI_SCAN_ITVL);
- if ((cputime - win_start) >= itvl) {
+ dt = cputime - win_start;
+ if (dt >= itvl) {
+#ifdef BLE_XCVR_RFCLK
+ if (dt < (scansm->scan_itvl - g_ble_ll_data.ll_xtal_ticks)) {
+ ble_ll_scan_rfclk_chk_stop();
+ }
+#endif
rc = 1;
}
}
@@ -694,6 +733,11 @@ ble_ll_scan_sm_stop(int chk_disable)
/* Set LL state to standby */
ble_ll_state_set(BLE_LL_STATE_STANDBY);
+
+ /* May need to stop the rfclk */
+#ifdef BLE_XCVR_RFCLK
+ ble_ll_scan_rfclk_chk_stop();
+#endif
}
OS_EXIT_CRITICAL(sr);
}
@@ -763,6 +807,9 @@ ble_ll_scan_event_proc(struct os_event *ev)
uint32_t win_start;
uint32_t scan_itvl;
uint32_t next_event_time;
+#ifdef BLE_XCVR_RFCLK
+ uint32_t xtal_ticks;
+#endif
struct ble_ll_scan_sm *scansm;
/*
@@ -792,12 +839,19 @@ ble_ll_scan_event_proc(struct os_event *ev)
dt = now - win_start;
scansm->scan_chan = chan;
scansm->scan_win_start_time = win_start;
+ if (scansm->scan_window != scansm->scan_itvl) {
+ win = os_cputime_usecs_to_ticks(scansm->scan_window * BLE_HCI_SCAN_ITVL);
+ } else {
+ win = 0;
+ }
/* Determine on/off state based on scan window */
rxstate = 1;
next_event_time = win_start + scan_itvl;
- if (scansm->scan_window != scansm->scan_itvl) {
- win = os_cputime_usecs_to_ticks(scansm->scan_window * BLE_HCI_SCAN_ITVL);
+
+ OS_ENTER_CRITICAL(sr);
+
+ if (win != 0) {
if (dt >= win) {
rxstate = 0;
} else {
@@ -805,7 +859,6 @@ ble_ll_scan_event_proc(struct os_event *ev)
}
}
- OS_ENTER_CRITICAL(sr);
/*
* 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
@@ -821,6 +874,9 @@ ble_ll_scan_event_proc(struct os_event *ev)
case BLE_LL_STATE_SCANNING:
/* Must disable PHY since we will move to a new channel */
ble_phy_disable();
+ if (!rxstate) {
+ ble_ll_state_set(BLE_LL_STATE_STANDBY);
+ }
break;
case BLE_LL_STATE_STANDBY:
break;
@@ -828,11 +884,72 @@ ble_ll_scan_event_proc(struct os_event *ev)
assert(0);
break;
}
+
+#ifdef BLE_XCVR_RFCLK
+ if (rxstate == 0) {
+ /*
+ * We need to wake up before we need to start scanning in order
+ * to make sure the rfclock is on. If we are close to being on,
+ * enable the rfclock. If not, set wakeup time.
+ */
+ if (dt >= (scan_itvl - g_ble_ll_data.ll_xtal_ticks)) {
+ /* Start the clock if necessary */
+ if (start_scan) {
+ if (ble_ll_xcvr_rfclk_state() == BLE_RFCLK_STATE_OFF) {
+ ble_ll_xcvr_rfclk_start_now(now);
+ next_event_time = now + g_ble_ll_data.ll_xtal_ticks;
+ }
+ }
+ } else {
+ next_event_time -= g_ble_ll_data.ll_xtal_ticks;
+ if (start_scan) {
+ ble_ll_scan_rfclk_chk_stop();
+ }
+ }
+ }
+#endif
+
if (start_scan && rxstate) {
+#ifdef BLE_XCVR_RFCLK
+ /* NOTE: reuse rxstate */
+ rxstate = ble_ll_xcvr_rfclk_state();
+ if (rxstate != BLE_RFCLK_STATE_SETTLED) {
+ if (rxstate == 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;
+ }
+ }
+
+ /* WWW: This should just be an enable. No need to start
+ cputimer here! */
+ /*
+ * If clock off, start clock. Set next event time to now plus
+ * the clock setting time.
+ */
+ if (rxstate == BLE_RFCLK_STATE_OFF) {
+ ble_ll_xcvr_rfclk_start(now);
+ }
+ next_event_time = now + xtal_ticks;
+ goto rfclk_not_settled;
+ }
+#endif
ble_ll_scan_start(scansm, scansm->scan_chan);
}
- OS_EXIT_CRITICAL(sr);
+#ifdef BLE_XCVR_RFCLK
+rfclk_not_settled:
+#endif
+ OS_EXIT_CRITICAL(sr);
os_cputime_timer_start(&scansm->scan_timer, next_event_time);
}
@@ -1484,7 +1601,7 @@ ble_ll_scan_init(void)
scansm->scan_itvl = BLE_HCI_SCAN_ITVL_DEF;
scansm->scan_window = BLE_HCI_SCAN_WINDOW_DEF;
- /* Initialize connection supervision timer */
+ /* Initialize scanning timer */
os_cputime_timer_init(&scansm->scan_timer, ble_ll_scan_timer_cb, scansm);
/* Get a scan request mbuf (packet header) and attach to state machine */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/controller/src/ble_ll_sched.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_sched.c b/net/nimble/controller/src/ble_ll_sched.c
index 2c18e0c..b5109dd 100644
--- a/net/nimble/controller/src/ble_ll_sched.c
+++ b/net/nimble/controller/src/ble_ll_sched.c
@@ -28,11 +28,17 @@
#include "controller/ble_ll_sched.h"
#include "controller/ble_ll_adv.h"
#include "controller/ble_ll_scan.h"
+#include "controller/ble_ll_xcvr.h"
#include "ble_ll_conn_priv.h"
/* XXX: this is temporary. Not sure what I want to do here */
struct hal_timer g_ble_ll_sched_timer;
+#ifdef BLE_XCVR_RFCLK
+/* Settling time of crystal, in ticks */
+uint8_t g_ble_ll_sched_xtal_ticks;
+#endif
+
#if MYNEWT_VAL(OS_CPUTIME_FREQ) == 32768
uint8_t g_ble_ll_sched_offset_ticks;
#endif
@@ -253,8 +259,17 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm)
entry = start_overlap;
}
+#ifdef BLE_XCVR_RFCLK
+ entry = TAILQ_FIRST(&g_ble_ll_sched_q);
+ if (entry == sch) {
+ ble_ll_rfclk_start(sch->start_time);
+ } else {
+ sch = entry;
+ }
+#else
/* Get first on list */
sch = TAILQ_FIRST(&g_ble_ll_sched_q);
+#endif
OS_EXIT_CRITICAL(sr);
@@ -450,6 +465,15 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm,
return rc;
}
+/**
+ * Schedules a slave connection for the first time.
+ *
+ * Context: Link Layer
+ *
+ * @param connsm
+ *
+ * @return int
+ */
int
ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm)
{
@@ -459,6 +483,11 @@ ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm)
struct ble_ll_sched_item *next_sch;
struct ble_ll_sched_item *sch;
+#ifdef BLE_XCVR_RFCLK
+ int first;
+ first = 0;
+#endif
+
/* Get schedule element from connection */
rc = -1;
sch = &connsm->conn_sch;
@@ -494,6 +523,9 @@ ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm)
if (!entry) {
/* Nothing in schedule. Schedule as soon as possible */
rc = 0;
+#ifdef BLE_XCVR_RFCLK
+ first = 1;
+#endif
} else {
os_cputime_timer_stop(&g_ble_ll_sched_timer);
while (1) {
@@ -526,9 +558,24 @@ ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm)
if (!rc) {
sch->enqueued = 1;
}
+#ifdef BLE_XCVR_RFCLK
+ next_sch = TAILQ_FIRST(&g_ble_ll_sched_q);
+ if (next_sch == sch) {
+ first = 1;
+ } else {
+ sch = next_sch;
+ }
+#else
sch = TAILQ_FIRST(&g_ble_ll_sched_q);
+#endif
}
+#ifdef BLE_XCVR_RFCLK
+ if (first) {
+ ble_ll_rfclk_start(sch->start_time);
+ }
+#endif
+
OS_EXIT_CRITICAL(sr);
os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time);
@@ -590,6 +637,12 @@ ble_ll_sched_adv_new(struct ble_ll_sched_item *sch)
ble_ll_adv_scheduled((struct ble_ll_adv_sm *)orig->cb_arg, adv_start);
+#ifdef BLE_XCVR_RFCLK
+ if (orig == sch) {
+ ble_ll_rfclk_start(sch->start_time);
+ }
+#endif
+
OS_EXIT_CRITICAL(sr);
os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time);
@@ -708,6 +761,12 @@ ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch, uint32_t *start,
}
sch->end_time = sch->start_time + duration;
*start = sch->start_time;
+
+#ifdef BLE_XCVR_RFCLK
+ if (sch == TAILQ_FIRST(&g_ble_ll_sched_q)) {
+ ble_ll_rfclk_start(sch->start_time);
+ }
+#endif
}
OS_EXIT_CRITICAL(sr);
@@ -899,6 +958,53 @@ ble_ll_sched_next_time(uint32_t *next_event_time)
return rc;
}
+#ifdef BLE_XCVR_RFCLK
+void
+ble_ll_sched_rfclk_chk_restart(void)
+{
+ int stop;
+ os_sr_t sr;
+ uint8_t ll_state;
+ int32_t time_till_next;
+ uint32_t next_time;
+
+ stop = 0;
+ OS_ENTER_CRITICAL(sr);
+ ll_state = ble_ll_state_get();
+ if (ble_ll_sched_next_time(&next_time)) {
+ /*
+ * If the time until the next event is too close, no need to start
+ * the timer and leave the clock on
+ */
+ time_till_next = (int32_t)(next_time - os_cputime_get32());
+ if (time_till_next > g_ble_ll_data.ll_xtal_ticks) {
+ /* Stop the clock */
+ stop = 1;
+
+ /*
+ * Restart the timer as long as not advertising or in connection
+ * event
+ */
+ if (!((ll_state == BLE_LL_STATE_ADV) ||
+ (ll_state == BLE_LL_STATE_CONNECTION))) {
+ ble_ll_xcvr_rfclk_start(next_time - g_ble_ll_data.ll_xtal_ticks);
+ }
+ }
+ } else {
+ stop = 1;
+ }
+
+ if (stop && (ll_state == BLE_LL_STATE_STANDBY)) {
+ ble_ll_log(BLE_LL_LOG_ID_RFCLK_SCHED_DIS, g_ble_ll_data.ll_rfclk_state,
+ 0, 0);
+ ble_ll_xcvr_rfclk_disable();
+ }
+ OS_EXIT_CRITICAL(sr);
+}
+
+#endif
+
+
/**
* Stop the scheduler
*
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/controller/src/ble_ll_xcvr.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_xcvr.c b/net/nimble/controller/src/ble_ll_xcvr.c
new file mode 100644
index 0000000..43a2e49
--- /dev/null
+++ b/net/nimble/controller/src/ble_ll_xcvr.c
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <stdint.h>
+#include <assert.h>
+#include "syscfg/syscfg.h"
+#include "os/os_cputime.h"
+#include "controller/ble_phy.h"
+#include "controller/ble_ll.h"
+#include "controller/ble_ll_xcvr.h"
+
+#if 0
+#include <string.h>
+#include "sysinit/sysinit.h"
+#include "os/os.h"
+#include "stats/stats.h"
+#include "bsp/bsp.h"
+#include "nimble/ble.h"
+#include "nimble/nimble_opt.h"
+#include "nimble/hci_common.h"
+#include "nimble/ble_hci_trans.h"
+#include "controller/ble_hw.h"
+#include "controller/ble_ll_adv.h"
+#include "controller/ble_ll_sched.h"
+#include "controller/ble_ll_scan.h"
+#include "controller/ble_ll_hci.h"
+#include "controller/ble_ll_whitelist.h"
+#include "controller/ble_ll_resolv.h"
+#include "ble_ll_conn_priv.h"
+#endif
+
+#ifdef BLE_XCVR_RFCLK
+int
+ble_ll_xcvr_rfclk_state(void)
+{
+ uint32_t expiry;
+
+ if (g_ble_ll_data.ll_rfclk_state == BLE_RFCLK_STATE_ON) {
+ expiry = g_ble_ll_data.ll_rfclk_start_time;
+ if ((int32_t)(os_cputime_get32() - expiry) >
+ g_ble_ll_data.ll_xtal_ticks) {
+ g_ble_ll_data.ll_rfclk_state = BLE_RFCLK_STATE_SETTLED;
+ }
+ }
+ return g_ble_ll_data.ll_rfclk_state;
+}
+
+/**
+ * Start the rf clock timer running at the specified cputime. The cputime
+ * is when the clock should start; it will be settled after xtal ticks have
+ * expired.
+ *
+ * If the clock is ON or SETTLED there is no need to start the timer. If the
+ * clock is OFF the timer might be set for some time in the future. If it is,
+ * we will reset the time if 'cputime' is earlier than the expiry time.
+ *
+ * @param cputime
+ */
+void
+ble_ll_xcvr_rfclk_start(uint32_t cputime)
+{
+ if (g_ble_ll_data.ll_rfclk_state == BLE_RFCLK_STATE_OFF) {
+
+ /*
+ * If the timer is on the list, we need to see if its expiry is before
+ * 'cputime'. If the expiry is before, no need to do anything. If it
+ * is after, we need to stop the timer and start at new time.
+ */
+ if (g_ble_ll_data.ll_rfclk_timer.link.tqe_prev != NULL) {
+ if ((int32_t)(cputime - g_ble_ll_data.ll_rfclk_timer.expiry) >= 0) {
+ return;
+ }
+ os_cputime_timer_stop(&g_ble_ll_data.ll_rfclk_timer);
+ }
+ os_cputime_timer_start(&g_ble_ll_data.ll_rfclk_timer, cputime);
+ ble_ll_log(BLE_LL_LOG_ID_RFCLK_START, g_ble_ll_data.ll_rfclk_state, 0,
+ g_ble_ll_data.ll_rfclk_timer.expiry);
+ }
+}
+
+void
+ble_ll_xcvr_rfclk_enable(void)
+{
+ g_ble_ll_data.ll_rfclk_state = BLE_RFCLK_STATE_ON;
+ ble_phy_rfclk_enable();
+}
+
+void
+ble_ll_xcvr_rfclk_disable(void)
+{
+ ble_phy_rfclk_disable();
+ g_ble_ll_data.ll_rfclk_state = BLE_RFCLK_STATE_OFF;
+}
+
+void
+ble_ll_xcvr_rfclk_stop(void)
+{
+ ble_ll_log(BLE_LL_LOG_ID_RFCLK_STOP, g_ble_ll_data.ll_rfclk_state, 0,0);
+ os_cputime_timer_stop(&g_ble_ll_data.ll_rfclk_timer);
+ ble_ll_xcvr_rfclk_disable();
+}
+
+uint32_t
+ble_ll_xcvr_rfclk_time_till_settled(void)
+{
+ int32_t dt;
+ uint32_t rc;
+
+ rc = 0;
+ if (g_ble_ll_data.ll_rfclk_state == BLE_RFCLK_STATE_ON) {
+ dt = (int32_t)(os_cputime_get32() - g_ble_ll_data.ll_rfclk_start_time);
+ assert(dt >= 0);
+ if (dt < g_ble_ll_data.ll_xtal_ticks) {
+ rc = g_ble_ll_data.ll_xtal_ticks - (uint32_t)dt;
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * Called when the timer to turn on the RF CLOCK expires
+ *
+ * Context: Interrupt
+ *
+ * @param arg
+ */
+void
+ble_ll_xcvr_rfclk_timer_exp(void *arg)
+{
+ if (g_ble_ll_data.ll_rfclk_state == BLE_RFCLK_STATE_OFF) {
+ ble_ll_xcvr_rfclk_enable();
+ g_ble_ll_data.ll_rfclk_start_time = g_ble_ll_data.ll_rfclk_timer.expiry;
+ ble_ll_log(BLE_LL_LOG_ID_RFCLK_ENABLE, g_ble_ll_data.ll_rfclk_state, 0,
+ g_ble_ll_data.ll_rfclk_start_time);
+ }
+}
+
+/**
+ * This API is used to turn on the rfclock without setting the cputimer timer
+ * to start the clock at some later point.
+ *
+ * @param now
+ */
+void
+ble_ll_xcvr_rfclk_start_now(uint32_t now)
+{
+ ble_ll_xcvr_rfclk_enable();
+ g_ble_ll_data.ll_rfclk_start_time = now;
+ ble_ll_log(BLE_LL_LOG_ID_RFCLK_ENABLE, g_ble_ll_data.ll_rfclk_state, 0,
+ g_ble_ll_data.ll_rfclk_start_time);
+}
+
+/* WWW: This is really confusing. This is called when we add something
+ * to schedule at the start. We want to stop the current cputime timer
+ * for the clock and restart it at the new time.
+ *
+ */
+void
+ble_ll_rfclk_start(uint32_t cputime)
+{
+ /* If we are currently doing something, no need to start the clock */
+ if (g_ble_ll_data.ll_state == BLE_LL_STATE_STANDBY) {
+ ble_ll_xcvr_rfclk_start(cputime - g_ble_ll_data.ll_xtal_ticks);
+ }
+}
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/controller/syscfg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/controller/syscfg.yml b/net/nimble/controller/syscfg.yml
index 357decc..569010f 100644
--- a/net/nimble/controller/syscfg.yml
+++ b/net/nimble/controller/syscfg.yml
@@ -137,6 +137,14 @@ syscfg.defs:
material often.
value: '32'
+ # Crystal setting time
+ BLE_XTAL_SETTLE_TIME:
+ description: >
+ The settling time of the high-frequency oscillator. This is
+ used to turn on/off the clock used for the radio (assuming
+ the HW supports this). This value is in microseconds.
+ value: '0'
+
# Configuration for LL supported features.
#
# There are a total 8 features that the LL can support. These can be found
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/host/src/ble_hs_hci_evt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_hci_evt.c b/net/nimble/host/src/ble_hs_hci_evt.c
index a2d7a52..664df7b 100644
--- a/net/nimble/host/src/ble_hs_hci_evt.c
+++ b/net/nimble/host/src/ble_hs_hci_evt.c
@@ -6,7 +6,7 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
@@ -622,15 +622,18 @@ ble_hs_hci_evt_acl_process(struct os_mbuf *om)
goto err;
}
+ /* WWW*/
+#if 0
#if (BLETEST_THROUGHPUT_TEST == 0)
BLE_HS_LOG(DEBUG, "ble_hs_hci_evt_acl_process(): conn_handle=%u pb=%x "
"len=%u data=",
- BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc),
- BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc),
+ BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc),
+ BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc),
hci_hdr.hdh_len);
ble_hs_log_mbuf(om);
BLE_HS_LOG(DEBUG, "\n");
#endif
+#endif /* WWW */
if (hci_hdr.hdh_len != OS_MBUF_PKTHDR(om)->omp_len) {
rc = BLE_HS_EBADDATA;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6db66772/net/nimble/syscfg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/syscfg.yml b/net/nimble/syscfg.yml
index f44da01..1f0aaf4 100644
--- a/net/nimble/syscfg.yml
+++ b/net/nimble/syscfg.yml
@@ -35,7 +35,7 @@ syscfg.defs:
BLE_MAX_CONNECTIONS:
description: 'The maximum number of concurrent connections.'
- value: 1
+ value: 8
BLE_WHITELIST:
description: 'TBD'
value: 1