From 91fb9e7888d5babb6e52427eeb67fcd052a30a10 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Wed, 25 May 2022 12:41:51 +1000 Subject: [PATCH] extmod/nimble: Add support for reading whole HCI UART packets. This can improve efficiency for Bluetooth systems that already process whole packets at the lower layers. --- extmod/mpbthci.h | 11 ++++++++++- extmod/nimble/hal/hal_uart.c | 27 ++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/extmod/mpbthci.h b/extmod/mpbthci.h index 6997238033..c10f99c3df 100644 --- a/extmod/mpbthci.h +++ b/extmod/mpbthci.h @@ -27,6 +27,9 @@ #ifndef MICROPY_INCLUDED_EXTMOD_MPBTHCI_H #define MICROPY_INCLUDED_EXTMOD_MPBTHCI_H +#define MICROPY_PY_BLUETOOTH_HCI_READ_MODE_BYTE (0) +#define MICROPY_PY_BLUETOOTH_HCI_READ_MODE_PACKET (1) + // --- Optionally can be implemented by the driver. --------------------------- // Start/stop the HCI controller. @@ -46,7 +49,13 @@ int mp_bluetooth_hci_uart_init(uint32_t port, uint32_t baudrate); int mp_bluetooth_hci_uart_deinit(void); int mp_bluetooth_hci_uart_set_baudrate(uint32_t baudrate); int mp_bluetooth_hci_uart_any(void); -int mp_bluetooth_hci_uart_readchar(void); int mp_bluetooth_hci_uart_write(const uint8_t *buf, size_t len); +// Used for mode: MICROPY_PY_BLUETOOTH_HCI_READ_MODE_BYTE +int mp_bluetooth_hci_uart_readchar(void); + +// Used for mode: MICROPY_PY_BLUETOOTH_HCI_READ_MODE_PACKET +typedef void (*mp_bluetooth_hci_uart_readchar_t)(uint8_t chr); +int mp_bluetooth_hci_uart_readpacket(mp_bluetooth_hci_uart_readchar_t handler); + #endif // MICROPY_INCLUDED_EXTMOD_MPBTHCI_H diff --git a/extmod/nimble/hal/hal_uart.c b/extmod/nimble/hal/hal_uart.c index 84a964fde9..6c17da0860 100644 --- a/extmod/nimble/hal/hal_uart.c +++ b/extmod/nimble/hal/hal_uart.c @@ -34,6 +34,10 @@ #if MICROPY_PY_BLUETOOTH && MICROPY_BLUETOOTH_NIMBLE +#ifndef MICROPY_PY_BLUETOOTH_HCI_READ_MODE +#define MICROPY_PY_BLUETOOTH_HCI_READ_MODE MICROPY_PY_BLUETOOTH_HCI_READ_MODE_BYTE +#endif + #define HCI_TRACE (0) static hal_uart_tx_cb_t hal_uart_tx_cb; @@ -86,15 +90,28 @@ int hal_uart_close(uint32_t port) { return 0; // success } +STATIC void mp_bluetooth_hci_uart_char_cb(uint8_t chr) { + #if HCI_TRACE + printf("> %02x\n", chr); + #endif + hal_uart_rx_cb(hal_uart_rx_arg, chr); +} + void mp_bluetooth_nimble_hci_uart_process(bool run_events) { bool host_wake = mp_bluetooth_hci_controller_woken(); - int chr; - while ((chr = mp_bluetooth_hci_uart_readchar()) >= 0) { - #if HCI_TRACE - printf("> %02x\n", chr); + for (;;) { + #if MICROPY_PY_BLUETOOTH_HCI_READ_MODE == MICROPY_PY_BLUETOOTH_HCI_READ_MODE_BYTE + int chr = mp_bluetooth_hci_uart_readchar(); + if (chr < 0) { + break; + } + mp_bluetooth_hci_uart_char_cb(chr); + #elif MICROPY_PY_BLUETOOTH_HCI_READ_MODE == MICROPY_PY_BLUETOOTH_HCI_READ_MODE_PACKET + if (mp_bluetooth_hci_uart_readpacket(mp_bluetooth_hci_uart_char_cb) < 0) { + break; + } #endif - hal_uart_rx_cb(hal_uart_rx_arg, chr); // Incoming data may result in events being enqueued. If we're in // scheduler context then we can run those events immediately.