stm32/rfcore: Remove extra layer of buffering on BLE IPCC.

Whole packets are now pushed up to the higher layer of the BLE stack,
instead of buffering the packets so individual bytes can be requested.
This commit is contained in:
Andrew Leech 2022-05-25 12:41:51 +10:00 committed by Damien George
parent 91fb9e7888
commit 8fb01be6cf
4 changed files with 30 additions and 34 deletions

View File

@ -24,6 +24,7 @@
* THE SOFTWARE.
*/
#include <stdio.h>
#include "py/runtime.h"
#include "py/mphal.h"
#include "extmod/mpbthci.h"
@ -99,10 +100,6 @@ void mp_bluetooth_hci_poll_now_default(void) {
#include <string.h>
#include "rfcore.h"
STATIC uint16_t hci_uart_rx_buf_cur;
STATIC uint16_t hci_uart_rx_buf_len;
STATIC uint8_t hci_uart_rx_buf_data[256];
int mp_bluetooth_hci_uart_init(uint32_t port, uint32_t baudrate) {
(void)port;
(void)baudrate;
@ -110,8 +107,6 @@ int mp_bluetooth_hci_uart_init(uint32_t port, uint32_t baudrate) {
DEBUG_printf("mp_bluetooth_hci_uart_init (stm32 rfcore)\n");
rfcore_ble_init();
hci_uart_rx_buf_cur = 0;
hci_uart_rx_buf_len = 0;
// Start the HCI polling to process any initial events/packets.
mp_bluetooth_hci_start_polling();
@ -137,29 +132,17 @@ int mp_bluetooth_hci_uart_write(const uint8_t *buf, size_t len) {
return 0;
}
// Callback to copy data into local hci_uart_rx_buf_data buffer for subsequent use.
STATIC int mp_bluetooth_hci_uart_msg_cb(void *env, const uint8_t *buf, size_t len) {
(void)env;
if (hci_uart_rx_buf_len + len > MP_ARRAY_SIZE(hci_uart_rx_buf_data)) {
len = MP_ARRAY_SIZE(hci_uart_rx_buf_data) - hci_uart_rx_buf_len;
// Callback to forward data from rfcore to the bluetooth hci handler.
STATIC void mp_bluetooth_hci_uart_msg_cb(void *env, const uint8_t *buf, size_t len) {
mp_bluetooth_hci_uart_readchar_t handler = (mp_bluetooth_hci_uart_readchar_t)env;
for (size_t i = 0; i < len; ++i) {
handler(buf[i]);
}
memcpy(hci_uart_rx_buf_data + hci_uart_rx_buf_len, buf, len);
hci_uart_rx_buf_len += len;
return 0;
}
int mp_bluetooth_hci_uart_readchar(void) {
if (hci_uart_rx_buf_cur >= hci_uart_rx_buf_len) {
hci_uart_rx_buf_cur = 0;
hci_uart_rx_buf_len = 0;
rfcore_ble_check_msg(mp_bluetooth_hci_uart_msg_cb, NULL);
}
if (hci_uart_rx_buf_cur < hci_uart_rx_buf_len) {
return hci_uart_rx_buf_data[hci_uart_rx_buf_cur++];
} else {
return -1;
}
int mp_bluetooth_hci_uart_readpacket(mp_bluetooth_hci_uart_readchar_t handler) {
size_t len = rfcore_ble_check_msg(mp_bluetooth_hci_uart_msg_cb, (void *)handler);
return (len > 0) ? len : -1;
}
#else

View File

@ -384,6 +384,12 @@ static inline mp_uint_t disable_irq(void) {
#define MICROPY_PY_BLUETOOTH_EXIT MICROPY_PY_PENDSV_EXIT
#endif
#if defined(STM32WB)
#define MICROPY_PY_BLUETOOTH_HCI_READ_MODE MICROPY_PY_BLUETOOTH_HCI_READ_MODE_PACKET
#else
#define MICROPY_PY_BLUETOOTH_HCI_READ_MODE MICROPY_PY_BLUETOOTH_HCI_READ_MODE_BYTE
#endif
// We need an implementation of the log2 function which is not a macro
#define MP_NEED_LOG2 (1)

View File

@ -105,7 +105,7 @@ typedef struct _tl_list_node_t {
} tl_list_node_t;
typedef struct _parse_hci_info_t {
int (*cb_fun)(void *, const uint8_t *, size_t);
rfcore_ble_msg_callback_t cb_fun;
void *cb_env;
bool was_hci_reset_evt;
} parse_hci_info_t;
@ -408,11 +408,12 @@ STATIC size_t tl_parse_hci_msg(const uint8_t *buf, parse_hci_info_t *parse) {
return len;
}
STATIC void tl_process_msg(volatile tl_list_node_t *head, unsigned int ch, parse_hci_info_t *parse) {
STATIC size_t tl_process_msg(volatile tl_list_node_t *head, unsigned int ch, parse_hci_info_t *parse) {
volatile tl_list_node_t *cur = head->next;
bool added_to_free_queue = false;
size_t len = 0;
while (cur != head) {
tl_parse_hci_msg((uint8_t *)cur->body, parse);
len += tl_parse_hci_msg((uint8_t *)cur->body, parse);
volatile tl_list_node_t *next = tl_list_unlink(cur);
@ -436,13 +437,15 @@ STATIC void tl_process_msg(volatile tl_list_node_t *head, unsigned int ch, parse
// Notify change in free pool.
LL_C1_IPCC_SetFlag_CHx(IPCC, IPCC_CH_MM);
}
return len;
}
// Only call this when IRQs are disabled on this channel.
STATIC void tl_check_msg(volatile tl_list_node_t *head, unsigned int ch, parse_hci_info_t *parse) {
STATIC size_t tl_check_msg(volatile tl_list_node_t *head, unsigned int ch, parse_hci_info_t *parse) {
size_t len = 0;
if (LL_C2_IPCC_IsActiveFlag_CHx(IPCC, ch)) {
// Process new data.
tl_process_msg(head, ch, parse);
len = tl_process_msg(head, ch, parse);
// Clear receive channel (allows RF core to send more data to us).
LL_C1_IPCC_ClearFlag_CHx(IPCC, ch);
@ -452,6 +455,7 @@ STATIC void tl_check_msg(volatile tl_list_node_t *head, unsigned int ch, parse_h
LL_C1_IPCC_EnableReceiveChannel(IPCC, IPCC_CH_BLE);
}
}
return len;
}
STATIC void tl_hci_cmd(uint8_t *cmd, unsigned int ch, uint8_t hdr, uint16_t opcode, const uint8_t *buf, size_t len) {
@ -643,9 +647,9 @@ void rfcore_ble_hci_cmd(size_t len, const uint8_t *src) {
LL_C1_IPCC_SetFlag_CHx(IPCC, ch);
}
void rfcore_ble_check_msg(int (*cb)(void *, const uint8_t *, size_t), void *env) {
size_t rfcore_ble_check_msg(rfcore_ble_msg_callback_t cb, void *env) {
parse_hci_info_t parse = { cb, env, false };
tl_check_msg(&ipcc_mem_ble_evt_queue, IPCC_CH_BLE, &parse);
size_t len = tl_check_msg(&ipcc_mem_ble_evt_queue, IPCC_CH_BLE, &parse);
// Intercept HCI_Reset events and reconfigure the controller following the reset
if (parse.was_hci_reset_evt) {
@ -660,6 +664,7 @@ void rfcore_ble_check_msg(int (*cb)(void *, const uint8_t *, size_t), void *env)
SWAP_UINT8(buf[4], buf[5]);
tl_ble_hci_cmd_resp(HCI_OPCODE(OGF_VENDOR, OCF_WRITE_CONFIG), buf, 8); // set BDADDR
}
return len;
}
// "level" is 0x00-0x1f, ranging from -40 dBm to +6 dBm (not linear).

View File

@ -28,11 +28,13 @@
#include <stdint.h>
typedef void (*rfcore_ble_msg_callback_t)(void *, const uint8_t *, size_t);
void rfcore_init(void);
void rfcore_ble_init(void);
void rfcore_ble_hci_cmd(size_t len, const uint8_t *src);
void rfcore_ble_check_msg(int (*cb)(void *, const uint8_t *, size_t), void *env);
size_t rfcore_ble_check_msg(rfcore_ble_msg_callback_t cb, void *env);
void rfcore_ble_set_txpower(uint8_t level);
void rfcore_start_flash_erase(void);