aboutsummaryrefslogtreecommitdiff
path: root/extmod
diff options
context:
space:
mode:
Diffstat (limited to 'extmod')
-rw-r--r--extmod/nimble/modbluetooth_nimble.c28
-rw-r--r--extmod/nimble/nimble/nimble_npl_os.c15
2 files changed, 33 insertions, 10 deletions
diff --git a/extmod/nimble/modbluetooth_nimble.c b/extmod/nimble/modbluetooth_nimble.c
index 4222f58fa..9ca90b602 100644
--- a/extmod/nimble/modbluetooth_nimble.c
+++ b/extmod/nimble/modbluetooth_nimble.c
@@ -52,6 +52,9 @@
STATIC uint8_t nimble_address_mode = BLE_OWN_ADDR_RANDOM;
+#define NIMBLE_STARTUP_TIMEOUT 2000
+STATIC struct ble_npl_sem startup_sem;
+
// Any BLE_HS_xxx code not in this table will default to MP_EIO.
STATIC int8_t ble_hs_err_to_errno_table[] = {
[BLE_HS_EAGAIN] = MP_EAGAIN,
@@ -206,6 +209,8 @@ STATIC void sync_cb(void) {
ble_svc_gap_device_name_set(MICROPY_PY_BLUETOOTH_DEFAULT_GAP_NAME);
mp_bluetooth_nimble_ble_state = MP_BLUETOOTH_NIMBLE_BLE_STATE_ACTIVE;
+
+ ble_npl_sem_release(&startup_sem);
}
STATIC void gatts_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) {
@@ -355,6 +360,8 @@ int mp_bluetooth_init(void) {
ble_hs_cfg.gatts_register_cb = gatts_register_cb;
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
+ ble_npl_sem_init(&startup_sem, 0);
+
MP_STATE_PORT(bluetooth_nimble_root_pointers) = m_new0(mp_bluetooth_nimble_root_pointers_t, 1);
mp_bluetooth_gatts_db_create(&MP_STATE_PORT(bluetooth_nimble_root_pointers)->gatts_db);
@@ -370,21 +377,28 @@ int mp_bluetooth_init(void) {
// Initialise NimBLE memory and data structures.
nimble_port_init();
- // By default, just register the default gap/gatt service.
- ble_svc_gap_init();
- ble_svc_gatt_init();
-
// Make sure that the HCI UART and event handling task is running.
mp_bluetooth_nimble_port_start();
// Static initialization is complete, can start processing events.
mp_bluetooth_nimble_ble_state = MP_BLUETOOTH_NIMBLE_BLE_STATE_WAITING_FOR_SYNC;
- // Wait for sync callback
- while (mp_bluetooth_nimble_ble_state != MP_BLUETOOTH_NIMBLE_BLE_STATE_ACTIVE) {
- MICROPY_EVENT_POLL_HOOK
+ ble_npl_sem_pend(&startup_sem, NIMBLE_STARTUP_TIMEOUT);
+
+ if (mp_bluetooth_nimble_ble_state != MP_BLUETOOTH_NIMBLE_BLE_STATE_ACTIVE) {
+ mp_bluetooth_deinit();
+ return MP_ETIMEDOUT;
}
+ // By default, just register the default gap/gatt service.
+ ble_svc_gap_init();
+ ble_svc_gatt_init();
+ // The preceeding two calls allocate service definitions on the heap,
+ // then we must now call gatts_start to register those services
+ // and free the heap memory.
+ // Otherwise it will be realloc'ed on the next stack startup.
+ ble_gatts_start();
+
DEBUG_printf("mp_bluetooth_init: ready\n");
return 0;
diff --git a/extmod/nimble/nimble/nimble_npl_os.c b/extmod/nimble/nimble/nimble_npl_os.c
index 46f7a0b29..2ec012940 100644
--- a/extmod/nimble/nimble/nimble_npl_os.c
+++ b/extmod/nimble/nimble/nimble_npl_os.c
@@ -32,6 +32,7 @@
#include "extmod/nimble/hal/hal_uart.h"
#include "extmod/modbluetooth.h"
+#include "extmod/nimble/modbluetooth_nimble.h"
#define DEBUG_OS_printf(...) // printf(__VA_ARGS__)
#define DEBUG_MALLOC_printf(...) // printf(__VA_ARGS__)
@@ -180,7 +181,8 @@ struct ble_npl_eventq *global_eventq = NULL;
void mp_bluetooth_nimble_os_eventq_run_all(void) {
for (struct ble_npl_eventq *evq = global_eventq; evq != NULL; evq = evq->nextq) {
- while (evq->head != NULL) {
+ int n = 0;
+ while (evq->head != NULL && mp_bluetooth_nimble_ble_state > MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF) {
struct ble_npl_event *ev = evq->head;
evq->head = ev->next;
if (ev->next) {
@@ -191,6 +193,13 @@ void mp_bluetooth_nimble_os_eventq_run_all(void) {
DEBUG_EVENT_printf("event_run(%p)\n", ev);
ev->fn(ev);
DEBUG_EVENT_printf("event_run(%p) done\n", ev);
+
+ if (++n > 3) {
+ // Limit to running 3 tasks per queue.
+ // Some tasks (such as reset) can enqueue themselves
+ // making this an infinite loop (while in PENDSV).
+ break;
+ }
}
}
}
@@ -348,11 +357,11 @@ ble_npl_error_t ble_npl_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout
}
if (sem->count == 0) {
- printf("NimBLE: HCI ACK timeout\n");
+ DEBUG_SEM_printf("ble_npl_sem_pend: semaphore timeout\n");
return BLE_NPL_TIMEOUT;
}
- DEBUG_SEM_printf("got response in %u ms\n", (int)(mp_hal_ticks_ms() - t0));
+ DEBUG_SEM_printf("ble_npl_sem_pend: acquired in %u ms\n", (int)(mp_hal_ticks_ms() - t0));
}
sem->count -= 1;
return BLE_NPL_OK;