summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extmod/nimble/bsp/bsp.h1
-rw-r--r--extmod/nimble/hal/hal_gpio.h1
-rw-r--r--extmod/nimble/hal/hal_uart.h18
-rw-r--r--extmod/nimble/nimble.mk96
-rw-r--r--extmod/nimble/nimble/hci_uart.c122
-rw-r--r--extmod/nimble/nimble/hci_uart.h42
-rw-r--r--extmod/nimble/nimble/misc.c44
-rw-r--r--extmod/nimble/nimble/nimble_npl_os.h66
-rw-r--r--extmod/nimble/nimble/npl_os.c307
-rw-r--r--extmod/nimble/syscfg/syscfg.h160
10 files changed, 857 insertions, 0 deletions
diff --git a/extmod/nimble/bsp/bsp.h b/extmod/nimble/bsp/bsp.h
new file mode 100644
index 000000000..8b1a39374
--- /dev/null
+++ b/extmod/nimble/bsp/bsp.h
@@ -0,0 +1 @@
+// empty
diff --git a/extmod/nimble/hal/hal_gpio.h b/extmod/nimble/hal/hal_gpio.h
new file mode 100644
index 000000000..8b1a39374
--- /dev/null
+++ b/extmod/nimble/hal/hal_gpio.h
@@ -0,0 +1 @@
+// empty
diff --git a/extmod/nimble/hal/hal_uart.h b/extmod/nimble/hal/hal_uart.h
new file mode 100644
index 000000000..294dfb50d
--- /dev/null
+++ b/extmod/nimble/hal/hal_uart.h
@@ -0,0 +1,18 @@
+#ifndef MICROPY_INCLUDED_EXTMOD_NIMBLE_HAL_HAL_UART_H
+#define MICROPY_INCLUDED_EXTMOD_NIMBLE_HAL_HAL_UART_H
+
+#include <stdint.h>
+
+#define SYSINIT_PANIC_ASSERT_MSG(cond, msg)
+
+#define HAL_UART_PARITY_NONE (0)
+
+typedef int (*hal_uart_tx_cb_t)(void *arg);
+typedef int (*hal_uart_rx_cb_t)(void *arg, uint8_t data);
+
+int hal_uart_init_cbs(uint32_t port, hal_uart_tx_cb_t tx_cb, void *tx_arg, hal_uart_rx_cb_t rx_cb, void *rx_arg);
+int hal_uart_config(uint32_t port, uint32_t baud, uint32_t bits, uint32_t stop, uint32_t parity, uint32_t flow);
+void hal_uart_start_tx(uint32_t port);
+int hal_uart_close(uint32_t port);
+
+#endif // MICROPY_INCLUDED_EXTMOD_NIMBLE_HAL_HAL_UART_H
diff --git a/extmod/nimble/nimble.mk b/extmod/nimble/nimble.mk
new file mode 100644
index 000000000..274fcdb9f
--- /dev/null
+++ b/extmod/nimble/nimble.mk
@@ -0,0 +1,96 @@
+# Makefile directives for Apache mynewt nimble BLE component
+
+ifeq ($(MICROPY_BLUETOOTH_NIMBLE),1)
+
+NIMBLE_LIB_DIR = lib/mynewt-nimble
+NIMBLE_EXTMOD_DIR = extmod/nimble
+
+SRC_LIB += $(addprefix $(NIMBLE_LIB_DIR)/, \
+ $(addprefix ext/tinycrypt/src/, \
+ aes_encrypt.c \
+ cmac_mode.c \
+ ecc.c \
+ ecc_dh.c \
+ utils.c \
+ ) \
+ nimble/host/services/gap/src/ble_svc_gap.c \
+ nimble/host/services/gatt/src/ble_svc_gatt.c \
+ $(addprefix nimble/host/src/, \
+ ble_att.c \
+ ble_att_clt.c \
+ ble_att_cmd.c \
+ ble_att_svr.c \
+ ble_eddystone.c \
+ ble_gap.c \
+ ble_gattc.c \
+ ble_gatts.c \
+ ble_hs_adv.c \
+ ble_hs_atomic.c \
+ ble_hs.c \
+ ble_hs_cfg.c \
+ ble_hs_conn.c \
+ ble_hs_dbg.c \
+ ble_hs_flow.c \
+ ble_hs_hci.c \
+ ble_hs_hci_cmd.c \
+ ble_hs_hci_evt.c \
+ ble_hs_hci_util.c \
+ ble_hs_id.c \
+ ble_hs_log.c \
+ ble_hs_mbuf.c \
+ ble_hs_misc.c \
+ ble_hs_mqueue.c \
+ ble_hs_pvcy.c \
+ ble_hs_startup.c \
+ ble_hs_stop.c \
+ ble_ibeacon.c \
+ ble_l2cap.c \
+ ble_l2cap_coc.c \
+ ble_l2cap_sig.c \
+ ble_l2cap_sig_cmd.c \
+ ble_monitor.c \
+ ble_sm_alg.c \
+ ble_sm.c \
+ ble_sm_cmd.c \
+ ble_sm_lgcy.c \
+ ble_sm_sc.c \
+ ble_store.c \
+ ble_store_util.c \
+ ble_uuid.c \
+ ) \
+ nimble/host/store/ram/src/ble_store_ram.c \
+ nimble/host/util/src/addr.c \
+ nimble/transport/uart/src/ble_hci_uart.c \
+ $(addprefix porting/nimble/src/, \
+ endian.c \
+ mem.c \
+ nimble_port.c \
+ os_mbuf.c \
+ os_mempool.c \
+ os_msys_init.c \
+ ) \
+ )
+
+EXTMOD_SRC_C += $(addprefix $(NIMBLE_EXTMOD_DIR)/, \
+ nimble/misc.c \
+ nimble/npl_os.c \
+ nimble/hci_uart.c \
+ )
+
+CFLAGS_MOD += -DMICROPY_BLUETOOTH_NIMBLE=1
+
+INC += -I$(TOP)/$(NIMBLE_EXTMOD_DIR)
+INC += -I$(TOP)/$(NIMBLE_LIB_DIR)
+INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/ext/tinycrypt/include
+INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/host/include
+INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/host/services/gap/include
+INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/host/services/gatt/include
+INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/host/store/ram/include
+INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/host/util/include
+INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/include
+INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/transport/uart/include
+INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/porting/nimble/include
+
+$(BUILD)/$(NIMBLE_LIB_DIR)/%.o: CFLAGS += -Wno-maybe-uninitialized -Wno-pointer-arith -Wno-unused-but-set-variable -Wno-format
+
+endif
diff --git a/extmod/nimble/nimble/hci_uart.c b/extmod/nimble/nimble/hci_uart.c
new file mode 100644
index 000000000..801291def
--- /dev/null
+++ b/extmod/nimble/nimble/hci_uart.c
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018-2019 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/runtime.h"
+#include "py/mphal.h"
+#include "pin_static_af.h"
+#include "nimble/ble.h"
+#include "hal/hal_uart.h"
+#include "hci_uart.h"
+
+#if MICROPY_BLUETOOTH_NIMBLE
+
+/******************************************************************************/
+// Bindings Uart to Nimble
+uint8_t bt_hci_cmd_buf[4 + 256];
+
+static hal_uart_tx_cb_t hal_uart_tx_cb;
+static void *hal_uart_tx_arg;
+static hal_uart_rx_cb_t hal_uart_rx_cb;
+static void *hal_uart_rx_arg;
+
+static uint32_t bt_sleep_ticks;
+
+int hal_uart_init_cbs(uint32_t port, hal_uart_tx_cb_t tx_cb, void *tx_arg, hal_uart_rx_cb_t rx_cb, void *rx_arg) {
+ hal_uart_tx_cb = tx_cb;
+ hal_uart_tx_arg = tx_arg;
+ hal_uart_rx_cb = rx_cb;
+ hal_uart_rx_arg = rx_arg;
+ return 0; // success
+}
+
+int hal_uart_config(uint32_t port, uint32_t baudrate, uint32_t bits, uint32_t stop, uint32_t parity, uint32_t flow) {
+ nimble_hci_uart_configure(port);
+ nimble_hci_uart_set_baudrate(baudrate);
+ return nimble_hci_uart_activate();
+}
+
+void hal_uart_start_tx(uint32_t port) {
+ size_t len = 0;
+ for (;;) {
+ int data = hal_uart_tx_cb(hal_uart_tx_arg);
+ if (data == -1) {
+ break;
+ }
+ bt_hci_cmd_buf[len++] = data;
+ }
+
+ #if 0
+ printf("[% 8d] BTUTX: %02x", mp_hal_ticks_ms(), hci_cmd_buf[0]);
+ for (int i = 1; i < len; ++i) {
+ printf(":%02x", hci_cmd_buf[i]);
+ }
+ printf("\n");
+ #endif
+
+ bt_sleep_ticks = mp_hal_ticks_ms();
+
+ #ifdef pyb_pin_BT_DEV_WAKE
+ if (mp_hal_pin_read(pyb_pin_BT_DEV_WAKE) == 1) {
+ //printf("BT WAKE for TX\n");
+ mp_hal_pin_low(pyb_pin_BT_DEV_WAKE); // wake up
+ mp_hal_delay_ms(5); // can't go lower than this
+ }
+ #endif
+
+ nimble_hci_uart_tx_strn((void*)bt_hci_cmd_buf, len);
+}
+
+int hal_uart_close(uint32_t port) {
+ return 0; // success
+}
+
+void nimble_uart_process(void) {
+ int host_wake = 0;
+ #ifdef pyb_pin_BT_HOST_WAKE
+ host_wake = mp_hal_pin_read(pyb_pin_BT_HOST_WAKE);
+ #endif
+ /*
+ // this is just for info/tracing purposes
+ static int last_host_wake = 0;
+ if (host_wake != last_host_wake) {
+ printf("HOST_WAKE change %d -> %d\n", last_host_wake, host_wake);
+ last_host_wake = host_wake;
+ }
+ */
+ while (nimble_hci_uart_rx_any()) {
+ uint8_t data = nimble_hci_uart_rx_char();
+ //printf("UART RX: %02x\n", data);
+ hal_uart_rx_cb(hal_uart_rx_arg, data);
+ }
+ if (host_wake == 1 && mp_hal_pin_read(pyb_pin_BT_DEV_WAKE) == 0) {
+ if (mp_hal_ticks_ms() - bt_sleep_ticks > 500) {
+ //printf("BT SLEEP\n");
+ mp_hal_pin_high(pyb_pin_BT_DEV_WAKE); // let sleep
+ }
+ }
+}
+
+#endif // MICROPY_BLUETOOTH_NIMBLE
diff --git a/extmod/nimble/nimble/hci_uart.h b/extmod/nimble/nimble/hci_uart.h
new file mode 100644
index 000000000..e18421083
--- /dev/null
+++ b/extmod/nimble/nimble/hci_uart.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef MICROPY_INCLUDED_EXTMOD_NIMBLE_NIMBLE_HCI_UART_H
+#define MICROPY_INCLUDED_EXTMOD_NIMBLE_NIMBLE_HCI_UART_H
+
+// To be implemented by the port.
+
+int nimble_hci_uart_configure(uint32_t port);
+
+// This will default to MICROPY_HW_BLE_UART_BAUDRATE, but can be updated later.
+int nimble_hci_uart_set_baudrate(uint32_t baudrate);
+
+int nimble_hci_uart_activate(void);
+
+mp_uint_t nimble_hci_uart_rx_any();
+int nimble_hci_uart_rx_char();
+void nimble_hci_uart_tx_strn(const char *str, uint len);
+
+#endif // MICROPY_INCLUDED_EXTMOD_NIMBLE_NIMBLE_HCI_UART_H
diff --git a/extmod/nimble/nimble/misc.c b/extmod/nimble/nimble/misc.c
new file mode 100644
index 000000000..0e7d8a42a
--- /dev/null
+++ b/extmod/nimble/nimble/misc.c
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018-2019 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/runtime.h"
+
+#if MICROPY_BLUETOOTH_NIMBLE
+
+/******************************************************************************/
+// Misc functions needed by Nimble
+
+#include <stdarg.h>
+
+int nimble_sprintf(char *str, const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ int ret = vsnprintf(str, 65535, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
+#endif
diff --git a/extmod/nimble/nimble/nimble_npl_os.h b/extmod/nimble/nimble/nimble_npl_os.h
new file mode 100644
index 000000000..3d886fedb
--- /dev/null
+++ b/extmod/nimble/nimble/nimble_npl_os.h
@@ -0,0 +1,66 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018-2019 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32_NIMBLE_NIMBLE_NPL_OS_H
+#define MICROPY_INCLUDED_STM32_NIMBLE_NIMBLE_NPL_OS_H
+
+#include <stdint.h>
+
+#define BLE_NPL_OS_ALIGNMENT (4)
+#define BLE_NPL_TIME_FOREVER (0xffffffff)
+
+typedef uint32_t ble_npl_time_t;
+typedef int32_t ble_npl_stime_t;
+
+struct ble_npl_event {
+ ble_npl_event_fn *fn;
+ void *arg;
+ struct ble_npl_event *prev;
+ struct ble_npl_event *next;
+};
+
+struct ble_npl_eventq {
+ struct ble_npl_event *head;
+ struct ble_npl_eventq *nextq;
+};
+
+struct ble_npl_callout {
+ bool active;
+ uint32_t ticks;
+ struct ble_npl_eventq *evq;
+ struct ble_npl_event ev;
+ struct ble_npl_callout *nextc;
+};
+
+struct ble_npl_mutex {
+ volatile uint8_t locked;
+};
+
+struct ble_npl_sem {
+ volatile uint16_t count;
+};
+
+#endif // MICROPY_INCLUDED_STM32_NIMBLE_NIMBLE_NPL_OS_H
diff --git a/extmod/nimble/nimble/npl_os.c b/extmod/nimble/nimble/npl_os.c
new file mode 100644
index 000000000..0f852c878
--- /dev/null
+++ b/extmod/nimble/nimble/npl_os.c
@@ -0,0 +1,307 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018-2019 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include "py/mphal.h"
+#include "nimble/nimble_npl.h"
+
+#define DEBUG_OS_printf(...) //printf(__VA_ARGS__)
+#define DEBUG_EVENT_printf(...) //printf(__VA_ARGS__)
+#define DEBUG_MUTEX_printf(...) //printf(__VA_ARGS__)
+#define DEBUG_SEM_printf(...) //printf(__VA_ARGS__)
+#define DEBUG_CALLOUT_printf(...) //printf(__VA_ARGS__)
+#define DEBUG_TIME_printf(...) //printf(__VA_ARGS__)
+#define DEBUG_CRIT_printf(...) //printf(__VA_ARGS__)
+
+bool ble_npl_os_started(void) {
+ DEBUG_OS_printf("ble_npl_os_started\n");
+ return true;
+}
+
+void *ble_npl_get_current_task_id(void) {
+ DEBUG_OS_printf("ble_npl_get_current_task_id\n");
+ return NULL;
+}
+
+/******************************************************************************/
+// EVENTQ
+
+struct ble_npl_eventq *global_eventq = NULL;
+
+void os_eventq_run_all(void) {
+ for (struct ble_npl_eventq *evq = global_eventq; evq != NULL; evq = evq->nextq) {
+ while (evq->head != NULL) {
+ struct ble_npl_event *ev = evq->head;
+ evq->head = ev->next;
+ if (ev->next) {
+ ev->next->prev = NULL;
+ ev->next = NULL;
+ }
+ ev->prev = NULL;
+ DEBUG_EVENT_printf("event_run(%p)\n", ev);
+ ev->fn(ev);
+ DEBUG_EVENT_printf("event_run(%p) done\n", ev);
+ }
+ }
+}
+
+void ble_npl_eventq_init(struct ble_npl_eventq *evq) {
+ DEBUG_EVENT_printf("ble_npl_eventq_init(%p)\n", evq);
+ evq->head = NULL;
+ struct ble_npl_eventq **evq2;
+ for (evq2 = &global_eventq; *evq2 != NULL; evq2 = &(*evq2)->nextq) {
+ }
+ *evq2 = evq;
+ evq->nextq = NULL;
+}
+
+void ble_npl_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev) {
+ DEBUG_EVENT_printf("ble_npl_eventq_put(%p, %p (%p, %p))\n", evq, ev, ev->fn, ev->arg);
+ ev->next = NULL;
+ if (evq->head == NULL) {
+ evq->head = ev;
+ ev->prev = NULL;
+ } else {
+ struct ble_npl_event *ev2 = evq->head;
+ while (true) {
+ if (ev2 == ev) {
+ DEBUG_EVENT_printf(" --> already in queue\n");
+ return;
+ }
+ if (ev2->next == NULL) {
+ break;
+ }
+ DEBUG_EVENT_printf(" --> %p\n", ev2->next);
+ ev2 = ev2->next;
+ }
+ ev2->next = ev;
+ ev->prev = ev2;
+ }
+}
+
+void ble_npl_event_init(struct ble_npl_event *ev, ble_npl_event_fn *fn, void *arg) {
+ DEBUG_EVENT_printf("ble_npl_event_init(%p, %p, %p)\n", ev, fn, arg);
+ ev->fn = fn;
+ ev->arg = arg;
+ ev->next = NULL;
+}
+
+void *ble_npl_event_get_arg(struct ble_npl_event *ev) {
+ DEBUG_EVENT_printf("ble_npl_event_get_arg(%p) -> %p\n", ev, ev->arg);
+ return ev->arg;
+}
+
+void ble_npl_event_set_arg(struct ble_npl_event *ev, void *arg) {
+ DEBUG_EVENT_printf("ble_npl_event_set_arg(%p, %p)\n", ev, arg);
+ ev->arg = arg;
+}
+
+/******************************************************************************/
+// MUTEX
+
+ble_npl_error_t ble_npl_mutex_init(struct ble_npl_mutex *mu) {
+ DEBUG_MUTEX_printf("ble_npl_mutex_init(%p)\n", mu);
+ mu->locked = 0;
+ return BLE_NPL_OK;
+}
+
+ble_npl_error_t ble_npl_mutex_pend(struct ble_npl_mutex *mu, ble_npl_time_t timeout) {
+ DEBUG_MUTEX_printf("ble_npl_mutex_pend(%p, %u) locked=%u\n", mu, (uint)timeout, (uint)mu->locked);
+ mu->locked = 1;
+ return BLE_NPL_OK;
+}
+
+ble_npl_error_t ble_npl_mutex_release(struct ble_npl_mutex *mu) {
+ DEBUG_MUTEX_printf("ble_npl_mutex_release(%p) locked=%u\n", mu, (uint)mu->locked);
+ mu->locked = 0;
+ return BLE_NPL_OK;
+}
+
+/******************************************************************************/
+// SEM
+
+ble_npl_error_t ble_npl_sem_init(struct ble_npl_sem *sem, uint16_t tokens) {
+ DEBUG_SEM_printf("ble_npl_sem_init(%p, %u)\n", sem, (uint)tokens);
+ sem->count = tokens;
+ return BLE_NPL_OK;
+}
+
+ble_npl_error_t ble_npl_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout) {
+ DEBUG_SEM_printf("ble_npl_sem_pend(%p, %u) count=%u\n", sem, (uint)timeout, (uint)sem->count);
+ if (sem->count == 0) {
+ uint32_t t0 = mp_hal_ticks_ms();
+ while (sem->count == 0 && mp_hal_ticks_ms() - t0 < timeout) {
+ extern void nimble_uart_process(void);
+ nimble_uart_process();
+ if (sem->count != 0) {
+ break;
+ }
+ __WFI();
+ }
+ if (sem->count == 0) {
+ printf("timeout\n");
+ return BLE_NPL_TIMEOUT;
+ }
+ DEBUG_SEM_printf("got response in %u ms\n", (int)(mp_hal_ticks_ms() - t0));
+ }
+ sem->count -= 1;
+ return BLE_NPL_OK;
+}
+
+ble_npl_error_t ble_npl_sem_release(struct ble_npl_sem *sem) {
+ DEBUG_SEM_printf("ble_npl_sem_release(%p)\n", sem);
+ sem->count += 1;
+ return BLE_NPL_OK;
+}
+
+uint16_t ble_npl_sem_get_count(struct ble_npl_sem *sem) {
+ DEBUG_SEM_printf("ble_npl_sem_get_count(%p)\n", sem);
+ return sem->count;
+}
+
+/******************************************************************************/
+// CALLOUT
+
+static struct ble_npl_callout *global_callout = NULL;
+
+void os_callout_process(void) {
+ uint32_t tnow = mp_hal_ticks_ms();
+ for (struct ble_npl_callout *c = global_callout; c != NULL; c = c->nextc) {
+ if (!c->active) {
+ continue;
+ }
+ if ((int32_t)(tnow - c->ticks) >= 0) {
+ DEBUG_CALLOUT_printf("callout_run(%p) tnow=%u ticks=%u evq=%p\n", c, (uint)tnow, (uint)c->ticks, c->evq);
+ c->active = false;
+ if (c->evq) {
+ ble_npl_eventq_put(c->evq, &c->ev);
+ } else {
+ c->ev.fn(&c->ev);
+ }
+ DEBUG_CALLOUT_printf("callout_run(%p) done\n", c);
+ }
+ }
+}
+
+void ble_npl_callout_init(struct ble_npl_callout *c, struct ble_npl_eventq *evq, ble_npl_event_fn *ev_cb, void *ev_arg) {
+ DEBUG_CALLOUT_printf("ble_npl_callout_init(%p, %p, %p, %p)\n", c, evq, ev_cb, ev_arg);
+ c->active = false;
+ c->ticks = 0;
+ c->evq = evq;
+ ble_npl_event_init(&c->ev, ev_cb, ev_arg);
+
+ struct ble_npl_callout **c2;
+ for (c2 = &global_callout; *c2 != NULL; c2 = &(*c2)->nextc) {
+ if (c == *c2) {
+ // callout already in linked list so don't link it in again
+ return;
+ }
+ }
+ *c2 = c;
+ c->nextc = NULL;
+}
+
+ble_npl_error_t ble_npl_callout_reset(struct ble_npl_callout *c, ble_npl_time_t ticks) {
+ DEBUG_CALLOUT_printf("ble_npl_callout_reset(%p, %u) tnow=%u\n", c, (uint)ticks, (uint)mp_hal_ticks_ms());
+ c->active = true;
+ c->ticks = ble_npl_time_get() + ticks;
+ return BLE_NPL_OK;
+}
+
+void ble_npl_callout_stop(struct ble_npl_callout *c) {
+ DEBUG_CALLOUT_printf("ble_npl_callout_stop(%p)\n", c);
+ c->active = false;
+}
+
+bool ble_npl_callout_is_active(struct ble_npl_callout *c) {
+ DEBUG_CALLOUT_printf("ble_npl_callout_is_active(%p)\n", c);
+ return c->active;
+}
+
+ble_npl_time_t ble_npl_callout_get_ticks(struct ble_npl_callout *c) {
+ DEBUG_CALLOUT_printf("ble_npl_callout_get_ticks(%p)\n", c);
+ return c->ticks;
+}
+
+ble_npl_time_t ble_npl_callout_remaining_ticks(struct ble_npl_callout *c, ble_npl_time_t now) {
+ DEBUG_CALLOUT_printf("ble_npl_callout_remaining_ticks(%p, %u)\n", c, (uint)now);
+ if (c->ticks > now) {
+ return c->ticks - now;
+ } else {
+ return 0;
+ }
+}
+
+void *ble_npl_callout_get_arg(struct ble_npl_callout *c) {
+ DEBUG_CALLOUT_printf("ble_npl_callout_get_arg(%p)\n", c);
+ return ble_npl_event_get_arg(&c->ev);
+}
+
+void ble_npl_callout_set_arg(struct ble_npl_callout *c, void *arg) {
+ DEBUG_CALLOUT_printf("ble_npl_callout_set_arg(%p, %p)\n", c, arg);
+ ble_npl_event_set_arg(&c->ev, arg);
+}
+
+/******************************************************************************/
+// TIME
+
+uint32_t ble_npl_time_get(void) {
+ DEBUG_TIME_printf("ble_npl_time_get -> %u\n", (uint)mp_hal_ticks_ms());
+ return mp_hal_ticks_ms();
+}
+
+ble_npl_error_t ble_npl_time_ms_to_ticks(uint32_t ms, ble_npl_time_t *out_ticks) {
+ DEBUG_TIME_printf("ble_npl_time_ms_to_ticks(%u)\n", (uint)ms);
+ *out_ticks = ms;
+ return BLE_NPL_OK;
+}
+
+ble_npl_time_t ble_npl_time_ms_to_ticks32(uint32_t ms) {
+ DEBUG_TIME_printf("ble_npl_time_ms_to_ticks32(%u)\n", (uint)ms);
+ return ms;
+}
+
+uint32_t ble_npl_time_ticks_to_ms32(ble_npl_time_t ticks) {
+ DEBUG_TIME_printf("ble_npl_time_ticks_to_ms32(%u)\n", (uint)ticks);
+ return ticks;
+}
+
+void ble_npl_time_delay(ble_npl_time_t ticks) {
+ mp_hal_delay_ms(ticks + 1);
+}
+
+/******************************************************************************/
+// CRITICAL
+
+uint32_t ble_npl_hw_enter_critical(void) {
+ DEBUG_CRIT_printf("ble_npl_hw_enter_critical()\n");
+ return raise_irq_pri(15);
+}
+
+void ble_npl_hw_exit_critical(uint32_t ctx) {
+ DEBUG_CRIT_printf("ble_npl_hw_exit_critical(%u)\n", (uint)ctx);
+ restore_irq_pri(ctx);
+}
diff --git a/extmod/nimble/syscfg/syscfg.h b/extmod/nimble/syscfg/syscfg.h
new file mode 100644
index 000000000..0d3acf9a7
--- /dev/null
+++ b/extmod/nimble/syscfg/syscfg.h
@@ -0,0 +1,160 @@
+#ifndef MICROPY_INCLUDED_EXTMOD_NIMBLE_SYSCFG_H
+#define MICROPY_INCLUDED_EXTMOD_NIMBLE_SYSCFG_H
+
+#include "py/mphal.h"
+#include "uart.h"
+
+void *nimble_malloc(size_t size);
+void nimble_free(void *ptr);
+void *nimble_realloc(void *ptr, size_t size);
+
+#define malloc(size) nimble_malloc(size)
+#define free(ptr) nimble_free(ptr)
+#define realloc(ptr, size) nimble_realloc(ptr, size)
+
+int nimble_sprintf(char *str, const char *fmt, ...);
+#define sprintf(str, fmt, ...) nimble_sprintf(str, fmt, __VA_ARGS__)
+
+#define MYNEWT_VAL(x) MYNEWT_VAL_ ## x
+
+#define MYNEWT_VAL_LOG_LEVEL (255)
+
+/*** compiler/arm-none-eabi-m4 */
+#define MYNEWT_VAL_HARDFLOAT (1)
+
+/*** kernel/os */
+#define MYNEWT_VAL_FLOAT_USER (0)
+#define MYNEWT_VAL_MSYS_1_BLOCK_COUNT (12)
+#define MYNEWT_VAL_MSYS_1_BLOCK_SIZE (292)
+#define MYNEWT_VAL_MSYS_2_BLOCK_COUNT (0)
+#define MYNEWT_VAL_MSYS_2_BLOCK_SIZE (0)
+#define MYNEWT_VAL_OS_CPUTIME_FREQ (1000000)
+#define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0)
+#define MYNEWT_VAL_OS_CTX_SW_STACK_CHECK (0)
+#define MYNEWT_VAL_OS_CTX_SW_STACK_GUARD (4)
+#define MYNEWT_VAL_OS_MAIN_STACK_SIZE (1024)
+#define MYNEWT_VAL_OS_MAIN_TASK_PRIO (127)
+#define MYNEWT_VAL_OS_MEMPOOL_CHECK (0)
+#define MYNEWT_VAL_OS_MEMPOOL_POISON (0)
+
+/*** nimble */
+#define MYNEWT_VAL_BLE_EXT_ADV (0)
+#define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31)
+#define MYNEWT_VAL_BLE_MAX_CONNECTIONS (1)
+#define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0)
+#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1)
+#define MYNEWT_VAL_BLE_ROLE_CENTRAL (1)
+#define MYNEWT_VAL_BLE_ROLE_OBSERVER (1)
+#define MYNEWT_VAL_BLE_ROLE_PERIPHERAL (1)
+#define MYNEWT_VAL_BLE_WHITELIST (1)
+
+/*** nimble/host */
+#define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256)
+#define MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO (1)
+#define MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE (1)
+#define MYNEWT_VAL_BLE_ATT_SVR_INDICATE (1)
+#define MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES (64)
+#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1)
+#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1)
+#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO (30000)
+#define MYNEWT_VAL_BLE_ATT_SVR_READ (1)
+#define MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB (1)
+#define MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE (1)
+#define MYNEWT_VAL_BLE_ATT_SVR_READ_MULT (1)
+#define MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE (1)
+#define MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE (1)
+#define MYNEWT_VAL_BLE_ATT_SVR_WRITE (1)
+#define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1)
+#define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1)
+#define MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_INDICATE (1)
+#define MYNEWT_VAL_BLE_GATT_MAX_PROCS (4)
+#define MYNEWT_VAL_BLE_GATT_NOTIFY (1)
+#define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_READ_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS (8)
+#define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_RESUME_RATE (1000)
+#define MYNEWT_VAL_BLE_GATT_SIGNED_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_WRITE_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS (4)
+#define MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#define MYNEWT_VAL_BLE_HOST (1)
+#define MYNEWT_VAL_BLE_HS_DEBUG (0)
+#define MYNEWT_VAL_BLE_HS_FLOW_CTRL (0)
+#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_ITVL (1000)
+#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_THRESH (2)
+#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT (0)
+#define MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS (0)
+#define MYNEWT_VAL_BLE_HS_REQUIRE_OS (1)
+#define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (0)
+#define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1)
+#define MYNEWT_VAL_BLE_L2CAP_MAX_CHANS (3*MYNEWT_VAL_BLE_MAX_CONNECTIONS)
+#define MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT (30000)
+#define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1)
+#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128)
+#define MYNEWT_VAL_BLE_MONITOR_RTT (0)
+#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1)
+#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME ("monitor")
+#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256)
+#define MYNEWT_VAL_BLE_MONITOR_UART (0)
+#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000)
+#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64)
+#define MYNEWT_VAL_BLE_MONITOR_UART_DEV ("uart0")
+#define MYNEWT_VAL_BLE_RPA_TIMEOUT (300)
+#define MYNEWT_VAL_BLE_SM_BONDING (0)
+#define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT)
+#define MYNEWT_VAL_BLE_SM_KEYPRESS (0)
+#define MYNEWT_VAL_BLE_SM_LEGACY (1)
+#define MYNEWT_VAL_BLE_SM_MAX_PROCS (1)
+#define MYNEWT_VAL_BLE_SM_MITM (0)
+#define MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG (0)
+#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0)
+#define MYNEWT_VAL_BLE_SM_SC (1)
+#define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0)
+#define MYNEWT_VAL_BLE_STORE_MAX_BONDS (3)
+#define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8)
+
+/*** nimble/host/services/gap */
+#define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE (0)
+#define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM (-1)
+#define MYNEWT_VAL_BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION (-1)
+#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME ("pybd")
+#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH (31)
+#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM (-1)
+#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL (0)
+#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL (0)
+#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SLAVE_LATENCY (0)
+#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO (0)
+
+/* Overridden by targets/porting-nimble (defined by nimble/transport) */
+#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0)
+#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0)
+#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0)
+#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (1)
+
+/*** nimble/transport/uart */
+#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (12)
+#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255)
+#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12)
+#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70)
+#define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (8)
+#define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8)
+
+/* Overridden by targets/porting-nimble (defined by nimble/transport/uart) */
+#define MYNEWT_VAL_BLE_HCI_UART_BAUD (MICROPY_HW_BLE_UART_BAUDRATE)
+#define MYNEWT_VAL_BLE_HCI_UART_DATA_BITS (8)
+#define MYNEWT_VAL_BLE_HCI_UART_FLOW_CTRL (1)
+#define MYNEWT_VAL_BLE_HCI_UART_PARITY (HAL_UART_PARITY_NONE)
+#define MYNEWT_VAL_BLE_HCI_UART_PORT (MICROPY_HW_BLE_UART_ID)
+#define MYNEWT_VAL_BLE_HCI_UART_STOP_BITS (1)
+
+#endif // MICROPY_INCLUDED_EXTMOD_NIMBLE_SYSCFG_H