stm32/rfcore: Make RX IRQ schedule the NimBLE handler.
This commit switches the STM32WB HCI interface (between the two CPUs) to require the use of MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS, and as a consequence to require NimBLE. IPCC RX IRQs now schedule the NimBLE handler to run via mp_sched_schedule. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
parent
efc0800132
commit
a64121b0d4
|
@ -31,6 +31,7 @@
|
||||||
#include "py/mperrno.h"
|
#include "py/mperrno.h"
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
|
#include "extmod/modbluetooth.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
#include "rfcore.h"
|
#include "rfcore.h"
|
||||||
|
|
||||||
|
@ -40,6 +41,10 @@
|
||||||
|
|
||||||
#define DEBUG_printf(...) // printf("rfcore: " __VA_ARGS__)
|
#define DEBUG_printf(...) // printf("rfcore: " __VA_ARGS__)
|
||||||
|
|
||||||
|
#if !MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS
|
||||||
|
#error "STM32WB must use synchronous events in the BLE implementation."
|
||||||
|
#endif
|
||||||
|
|
||||||
// Define to 1 to print traces of HCI packets
|
// Define to 1 to print traces of HCI packets
|
||||||
#define HCI_TRACE (0)
|
#define HCI_TRACE (0)
|
||||||
|
|
||||||
|
@ -191,9 +196,6 @@ STATIC uint8_t ipcc_membuf_ble_cs_buf[272]; // mem2
|
||||||
STATIC tl_list_node_t ipcc_mem_ble_evt_queue; // mem1
|
STATIC tl_list_node_t ipcc_mem_ble_evt_queue; // mem1
|
||||||
STATIC uint8_t ipcc_membuf_ble_hci_acl_data_buf[272]; // mem2
|
STATIC uint8_t ipcc_membuf_ble_hci_acl_data_buf[272]; // mem2
|
||||||
|
|
||||||
// Set by the RX IRQ handler on incoming HCI payload.
|
|
||||||
STATIC volatile bool had_ble_irq = false;
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
// Transport layer linked list
|
// Transport layer linked list
|
||||||
|
|
||||||
|
@ -408,6 +410,7 @@ STATIC void tl_process_msg(volatile tl_list_node_t *head, unsigned int ch, parse
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 void tl_check_msg(volatile tl_list_node_t *head, unsigned int ch, parse_hci_info_t *parse) {
|
||||||
if (LL_C2_IPCC_IsActiveFlag_CHx(IPCC, ch)) {
|
if (LL_C2_IPCC_IsActiveFlag_CHx(IPCC, ch)) {
|
||||||
tl_process_msg(head, ch, parse);
|
tl_process_msg(head, ch, parse);
|
||||||
|
@ -417,14 +420,6 @@ STATIC void tl_check_msg(volatile tl_list_node_t *head, unsigned int ch, parse_h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void tl_check_msg_ble(volatile tl_list_node_t *head, parse_hci_info_t *parse) {
|
|
||||||
if (had_ble_irq) {
|
|
||||||
tl_process_msg(head, IPCC_CH_BLE, parse);
|
|
||||||
|
|
||||||
had_ble_irq = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void tl_hci_cmd(uint8_t *cmd, unsigned int ch, uint8_t hdr, uint16_t opcode, const uint8_t *buf, size_t 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) {
|
||||||
tl_list_node_t *n = (tl_list_node_t *)cmd;
|
tl_list_node_t *n = (tl_list_node_t *)cmd;
|
||||||
n->next = n;
|
n->next = n;
|
||||||
|
@ -472,7 +467,7 @@ STATIC ssize_t tl_sys_hci_cmd_resp(uint16_t opcode, const uint8_t *buf, size_t l
|
||||||
|
|
||||||
STATIC int tl_ble_wait_resp(void) {
|
STATIC int tl_ble_wait_resp(void) {
|
||||||
uint32_t t0 = mp_hal_ticks_ms();
|
uint32_t t0 = mp_hal_ticks_ms();
|
||||||
while (!had_ble_irq) {
|
while (!LL_C2_IPCC_IsActiveFlag_CHx(IPCC, IPCC_CH_BLE)) {
|
||||||
if (mp_hal_ticks_ms() - t0 > BLE_ACK_TIMEOUT_MS) {
|
if (mp_hal_ticks_ms() - t0 > BLE_ACK_TIMEOUT_MS) {
|
||||||
printf("tl_ble_wait_resp: timeout\n");
|
printf("tl_ble_wait_resp: timeout\n");
|
||||||
return -MP_ETIMEDOUT;
|
return -MP_ETIMEDOUT;
|
||||||
|
@ -480,14 +475,16 @@ STATIC int tl_ble_wait_resp(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// C2 set IPCC flag.
|
// C2 set IPCC flag.
|
||||||
tl_check_msg_ble(&ipcc_mem_ble_evt_queue, NULL);
|
tl_check_msg(&ipcc_mem_ble_evt_queue, IPCC_CH_BLE, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synchronously send a BLE command.
|
// Synchronously send a BLE command.
|
||||||
STATIC void tl_ble_hci_cmd_resp(uint16_t opcode, const uint8_t *buf, size_t len) {
|
STATIC void tl_ble_hci_cmd_resp(uint16_t opcode, const uint8_t *buf, size_t len) {
|
||||||
|
LL_C1_IPCC_DisableReceiveChannel(IPCC, IPCC_CH_BLE);
|
||||||
tl_hci_cmd(ipcc_membuf_ble_cmd_buf, IPCC_CH_BLE, HCI_KIND_BT_CMD, opcode, buf, len);
|
tl_hci_cmd(ipcc_membuf_ble_cmd_buf, IPCC_CH_BLE, HCI_KIND_BT_CMD, opcode, buf, len);
|
||||||
tl_ble_wait_resp();
|
tl_ble_wait_resp();
|
||||||
|
LL_C1_IPCC_EnableReceiveChannel(IPCC, IPCC_CH_BLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -554,11 +551,10 @@ static const struct {
|
||||||
void rfcore_ble_init(void) {
|
void rfcore_ble_init(void) {
|
||||||
DEBUG_printf("rfcore_ble_init\n");
|
DEBUG_printf("rfcore_ble_init\n");
|
||||||
|
|
||||||
// Clear any outstanding messages from ipcc_init
|
// Clear any outstanding messages from ipcc_init.
|
||||||
tl_check_msg(&ipcc_mem_sys_queue, IPCC_CH_SYS, NULL);
|
tl_check_msg(&ipcc_mem_sys_queue, IPCC_CH_SYS, NULL);
|
||||||
tl_check_msg_ble(&ipcc_mem_ble_evt_queue, NULL);
|
|
||||||
|
|
||||||
// Configure and reset the BLE controller
|
// Configure and reset the BLE controller.
|
||||||
tl_sys_hci_cmd_resp(HCI_OPCODE(OGF_VENDOR, OCF_BLE_INIT), (const uint8_t *)&ble_init_params, sizeof(ble_init_params), 0);
|
tl_sys_hci_cmd_resp(HCI_OPCODE(OGF_VENDOR, OCF_BLE_INIT), (const uint8_t *)&ble_init_params, sizeof(ble_init_params), 0);
|
||||||
tl_ble_hci_cmd_resp(HCI_OPCODE(0x03, 0x0003), NULL, 0);
|
tl_ble_hci_cmd_resp(HCI_OPCODE(0x03, 0x0003), NULL, 0);
|
||||||
}
|
}
|
||||||
|
@ -597,7 +593,7 @@ 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) {
|
void rfcore_ble_check_msg(int (*cb)(void *, const uint8_t *, size_t), void *env) {
|
||||||
parse_hci_info_t parse = { cb, env, false };
|
parse_hci_info_t parse = { cb, env, false };
|
||||||
tl_check_msg_ble(&ipcc_mem_ble_evt_queue, &parse);
|
tl_process_msg(&ipcc_mem_ble_evt_queue, IPCC_CH_BLE, &parse);
|
||||||
|
|
||||||
// Intercept HCI_Reset events and reconfigure the controller following the reset
|
// Intercept HCI_Reset events and reconfigure the controller following the reset
|
||||||
if (parse.was_hci_reset_evt) {
|
if (parse.was_hci_reset_evt) {
|
||||||
|
@ -629,9 +625,9 @@ void IPCC_C1_TX_IRQHandler(void) {
|
||||||
void IPCC_C1_RX_IRQHandler(void) {
|
void IPCC_C1_RX_IRQHandler(void) {
|
||||||
IRQ_ENTER(IPCC_C1_RX_IRQn);
|
IRQ_ENTER(IPCC_C1_RX_IRQn);
|
||||||
|
|
||||||
if (LL_C2_IPCC_IsActiveFlag_CHx(IPCC, IPCC_CH_BLE)) {
|
DEBUG_printf("IPCC_C1_RX_IRQHandler\n");
|
||||||
had_ble_irq = true;
|
|
||||||
|
|
||||||
|
if (LL_C2_IPCC_IsActiveFlag_CHx(IPCC, IPCC_CH_BLE)) {
|
||||||
LL_C1_IPCC_ClearFlag_CHx(IPCC, IPCC_CH_BLE);
|
LL_C1_IPCC_ClearFlag_CHx(IPCC, IPCC_CH_BLE);
|
||||||
|
|
||||||
// Queue up the scheduler to process UART data and run events.
|
// Queue up the scheduler to process UART data and run events.
|
||||||
|
|
Loading…
Reference in New Issue