Skip to content

Commit

Permalink
nrf/bluetooth: Add support for nimble based bluetooth.
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Leech <[email protected]>
  • Loading branch information
pi-anl committed Jan 25, 2024
1 parent 50d5d2d commit 6eb6155
Show file tree
Hide file tree
Showing 20 changed files with 767 additions and 36 deletions.
4 changes: 3 additions & 1 deletion extmod/nimble/logcfg/logcfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
#include "modlog/modlog.h"
#include "log_common/log_common.h"

#define MICROPY_PY_BLUETOOTH_DIAGNOSTIC_LOGGING (1)
#ifndef MICROPY_PY_BLUETOOTH_DIAGNOSTIC_LOGGING
#define MICROPY_PY_BLUETOOTH_DIAGNOSTIC_LOGGING (0)
#endif

#if MICROPY_PY_BLUETOOTH_DIAGNOSTIC_LOGGING
#define DFLT_LOG_DEBUG(...) MODLOG_DEBUG(4, __VA_ARGS__)
Expand Down
16 changes: 11 additions & 5 deletions extmod/nimble/modbluetooth_nimble.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,24 +519,30 @@ STATIC int central_gap_event_cb(struct ble_gap_event *event, void *arg) {

// On ports such as ESP32 where we only implement the bindings, then
// the port must provide these functions.
// But for STM32 / Unix-H4, we provide a default implementation of the
// For STM32 / Unix-H4, we provide a default implementation of the
// port-specific functionality.
// TODO: In the future if a port ever needs to customise these functions
// then investigate using MP_WEAK or splitting them out to another .c file.

#if !MICROPY_BLUETOOTH_NIMBLE_CONTROLLER
#include "transport/uart/ble_hci_uart.h"
#endif

void mp_bluetooth_nimble_port_hci_init(void) {
DEBUG_printf("mp_bluetooth_nimble_port_hci_init (nimble default)\n");
#if MYNEWT_VAL(BLE_HCI_TRANSPORT_UART)
// This calls mp_bluetooth_hci_uart_init (via ble_hci_uart_init --> hal_uart_config --> mp_bluetooth_hci_uart_init).
ble_hci_uart_init();
#endif
mp_bluetooth_hci_controller_init();
}

void mp_bluetooth_nimble_port_hci_deinit(void) {
DEBUG_printf("mp_bluetooth_nimble_port_hci_deinit (nimble default)\n");
mp_bluetooth_hci_controller_deinit();
#if MYNEWT_VAL(BLE_HCI_TRANSPORT_UART)
mp_bluetooth_hci_uart_deinit();
#endif
}

void mp_bluetooth_nimble_port_start(void) {
Expand Down Expand Up @@ -611,17 +617,17 @@ int mp_bluetooth_init(void) {
MP_STATE_PORT(bluetooth_nimble_memory) = NULL;
#endif

// Allow port (ESP32) to override NimBLE's HCI init.
// Otherwise default implementation above calls ble_hci_uart_init().
mp_bluetooth_nimble_port_hci_init();

// Static initialization is complete, can start processing events.
mp_bluetooth_nimble_ble_state = MP_BLUETOOTH_NIMBLE_BLE_STATE_WAITING_FOR_SYNC;

// Initialise NimBLE memory and data structures.
DEBUG_printf("mp_bluetooth_init: nimble_port_init\n");
nimble_port_init();

// Allow port (ESP32) to override NimBLE's HCI init.
// Otherwise default implementation above calls ble_hci_uart_init().
mp_bluetooth_nimble_port_hci_init();

// Make sure that the HCI UART and event handling task is running.
mp_bluetooth_nimble_port_start();

Expand Down
51 changes: 48 additions & 3 deletions extmod/nimble/nimble.mk
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_LIB_DIR)/, \
ble_uuid.c \
) \
nimble/host/util/src/addr.c \
nimble/transport/uart/src/ble_hci_uart.c \
$(addprefix porting/nimble/src/, \
endian.c \
mem.c \
Expand All @@ -100,7 +99,6 @@ SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_LIB_DIR)/, \
SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_EXTMOD_DIR)/, \
nimble/nimble_npl_os.c \
hal/hal_uart.c \
)

INC += -I$(TOP)/$(NIMBLE_EXTMOD_DIR)
Expand All @@ -112,11 +110,58 @@ 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 -Wno-sign-compare -Wno-old-style-declaration

endif

ifeq ($(MICROPY_BLUETOOTH_NIMBLE_CONTROLLER),1)

# Include controller layer to run entire stack on-chip
CFLAGS_EXTMOD += -DMICROPY_BLUETOOTH_NIMBLE_CONTROLLER=1

INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/controller/include

SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_LIB_DIR)/, \
$(addprefix nimble/controller/src/, \
ble_ll.c \
ble_ll_adv.c \
ble_ll_conn.c \
ble_ll_conn_hci.c \
ble_ll_ctrl.c \
ble_ll_dtm.c \
ble_ll_hci.c \
ble_ll_hci_ev.c \
ble_ll_iso.c \
ble_ll_rand.c \
ble_ll_resolv.c \
ble_ll_rfmgmt.c \
ble_ll_scan.c \
ble_ll_sched.c \
ble_ll_supp_cmd.c \
ble_ll_sync.c \
ble_ll_trace.c \
ble_ll_utils.c \
ble_ll_whitelist.c \
) \
)

SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_LIB_DIR)/, \
$(addprefix porting/nimble/src/, \
hal_timer.c \
os_cputime.c \
os_cputime_pwr2.c \
) \
)

SRC_THIRDPARTY_C += $(NIMBLE_LIB_DIR)/nimble/transport/ram/src/ble_hci_ram.c
INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/transport/ram/include

else # !MICROPY_BLUETOOTH_NIMBLE_CONTROLLER
# External controller being used
SRC_THIRDPARTY_C += $(NIMBLE_LIB_DIR)/nimble/transport/uart/src/ble_hci_uart.c
INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/transport/uart/include

endif
endif
79 changes: 77 additions & 2 deletions extmod/nimble/nimble/nimble_npl_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include "nimble/ble.h"
#include "nimble/nimble_npl.h"
#include "extmod/nimble/hal/hal_uart.h"
#include "os/os_cputime.h"
#include "hal/hal_timer.h"

#include "extmod/modbluetooth.h"
#include "extmod/nimble/modbluetooth_nimble.h"
Expand All @@ -44,7 +46,7 @@
#define DEBUG_TIME_printf(...) // printf(__VA_ARGS__)
#define DEBUG_CRIT_printf(...) // printf(__VA_ARGS__)

bool ble_npl_os_started(void) {
MP_WEAK bool ble_npl_os_started(void) {
DEBUG_OS_printf("ble_npl_os_started\n");
return true;
}
Expand Down Expand Up @@ -175,6 +177,24 @@ int nimble_sprintf(char *str, const char *fmt, ...) {
return 0;
}

// Function to implement `strncat()` function in C
char* strncat(char* destination, const char* source, size_t num)
{
// make `ptr` point to the end of the destination string
char* ptr = destination + strlen(destination);

// Appends characters of the source to the destination string
while (*source != '\0' && num--) {
*ptr++ = *source++;
}

// null terminate destination string
*ptr = '\0';

// destination string is returned by standard `strncat()`
return destination;
}

/******************************************************************************/
// EVENTQ

Expand Down Expand Up @@ -278,6 +298,61 @@ void ble_npl_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev) {
mp_bluetooth_hci_poll_now();
}

struct ble_npl_event *ble_npl_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo) {
if (tmo != BLE_NPL_TIME_FOREVER && tmo != 0) {
tmo += mp_hal_ticks_ms();
}

struct ble_npl_event *ev = NULL;
os_sr_t sr;
do {
ev = evq->head;
if (ev) {
OS_ENTER_CRITICAL(sr);
// Remove this event from the queue.
evq->head = ev->next;
if (ev->next) {
ev->next->prev = NULL;
ev->next = NULL;
}
ev->prev = NULL;

ev->pending = false;

// Stop searching and execute this event.
OS_EXIT_CRITICAL(sr);
break;
}
} while (tmo != 0 && (tmo == BLE_NPL_TIME_FOREVER || tmo < mp_hal_ticks_ms()));

return ev;
}

void ble_npl_event_run(struct ble_npl_event *ev) {
// Run the event handler.
DEBUG_EVENT_printf("ble_npl_event_run(%p)\n", ev);
ev->fn(ev);
}

inline bool ble_npl_event_is_queued(struct ble_npl_event *ev) {
return ev->pending;
}

void ble_npl_eventq_run(struct ble_npl_eventq *evq) {
printf("ble_npl_eventq_run\n");
assert(0);
}

void ble_npl_eventq_remove(struct ble_npl_eventq *evq, struct ble_npl_event *ev) {
DEBUG_EVENT_printf("ble_npl_eventq_remove(%p, %p (%p, %p))\n", evq, ev, ev->prev, ev->next);
os_sr_t sr;
OS_ENTER_CRITICAL(sr);
// Set the previous events next to this events next, so removing it from the chain
ev->prev->next = ev->next;
OS_EXIT_CRITICAL(sr);
}


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;
Expand Down Expand Up @@ -473,7 +548,7 @@ void ble_npl_callout_set_arg(struct ble_npl_callout *c, void *arg) {
}

/******************************************************************************/
// TIME
// TIME (ticks in ms)

uint32_t ble_npl_time_get(void) {
DEBUG_TIME_printf("ble_npl_time_get -> %u\n", (uint)mp_hal_ticks_ms());
Expand Down
2 changes: 2 additions & 0 deletions extmod/nimble/nimble/nimble_npl_os.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ struct ble_npl_sem {
// --- Called by the MicroPython port -----------------------------------------

void mp_bluetooth_nimble_os_eventq_run_all(void);
void mp_bluetooth_nimble_eventq_run_all(struct ble_npl_eventq *eventq);
void mp_bluetooth_nimble_os_callout_process(void);
void mp_bluetooth_nimble_os_cputime_timer_poll(void);

// --- Must be provided by the MicroPython port -------------------------------

Expand Down
Loading

0 comments on commit 6eb6155

Please sign in to comment.