summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/rfcore.c34
1 files changed, 15 insertions, 19 deletions
diff --git a/ports/stm32/rfcore.c b/ports/stm32/rfcore.c
index 08338fcdc2..550e5323e8 100644
--- a/ports/stm32/rfcore.c
+++ b/ports/stm32/rfcore.c
@@ -31,6 +31,7 @@
#include "py/mperrno.h"
#include "py/mphal.h"
#include "py/runtime.h"
+#include "extmod/modbluetooth.h"
#include "rtc.h"
#include "rfcore.h"
@@ -40,6 +41,10 @@
#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 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 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
@@ -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) {
if (LL_C2_IPCC_IsActiveFlag_CHx(IPCC, ch)) {
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) {
tl_list_node_t *n = (tl_list_node_t *)cmd;
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) {
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) {
printf("tl_ble_wait_resp: timeout\n");
return -MP_ETIMEDOUT;
@@ -480,14 +475,16 @@ STATIC int tl_ble_wait_resp(void) {
}
// 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;
}
// Synchronously send a BLE command.
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_ble_wait_resp();
+ LL_C1_IPCC_EnableReceiveChannel(IPCC, IPCC_CH_BLE);
}
/******************************************************************************/
@@ -554,11 +551,10 @@ static const struct {
void rfcore_ble_init(void) {
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_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_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) {
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
if (parse.was_hci_reset_evt) {
@@ -629,9 +625,9 @@ void IPCC_C1_TX_IRQHandler(void) {
void IPCC_C1_RX_IRQHandler(void) {
IRQ_ENTER(IPCC_C1_RX_IRQn);
- if (LL_C2_IPCC_IsActiveFlag_CHx(IPCC, IPCC_CH_BLE)) {
- had_ble_irq = true;
+ DEBUG_printf("IPCC_C1_RX_IRQHandler\n");
+ if (LL_C2_IPCC_IsActiveFlag_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.