From 0f9a9129da0d0ef60956dcfa36b02b62d731b1b1 Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Fri, 29 Jan 2021 17:45:33 +1100 Subject: [PATCH] stm32/rfcore: Fix flow control for IPCC RX IRQ. Don't clear the IPCC channel flag until we've actually handled the incoming data, or else the wireless firmware may clobber the IPCC buffer if more data arrives. This requires masking the IRQ until the data is handled. Signed-off-by: Jim Mussared --- ports/stm32/rfcore.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/ports/stm32/rfcore.c b/ports/stm32/rfcore.c index 7d0a8520a6..b11c4f2022 100644 --- a/ports/stm32/rfcore.c +++ b/ports/stm32/rfcore.c @@ -434,10 +434,16 @@ 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)) { + // Process new data. tl_process_msg(head, ch, parse); - // Clear receive channel. + // Clear receive channel (allows RF core to send more data to us). LL_C1_IPCC_ClearFlag_CHx(IPCC, ch); + + if (ch == IPCC_CH_BLE) { + // Renable IRQs for BLE now that we've cleared the flag. + LL_C1_IPCC_EnableReceiveChannel(IPCC, IPCC_CH_BLE); + } } } @@ -495,17 +501,17 @@ STATIC int tl_ble_wait_resp(void) { } } - // C2 set IPCC flag. + // C2 set IPCC flag -- process the data, clear the flag, and re-enable IRQs. 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) { + // Poll for completion rather than wait for IRQ->scheduler. 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); } /******************************************************************************/ @@ -632,7 +638,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_process_msg(&ipcc_mem_ble_evt_queue, IPCC_CH_BLE, &parse); + 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) { @@ -679,7 +685,8 @@ void IPCC_C1_RX_IRQHandler(void) { 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); + // Disable this IRQ until the incoming data is processed (in tl_check_msg). + LL_C1_IPCC_DisableReceiveChannel(IPCC, IPCC_CH_BLE); #if MICROPY_PY_BLUETOOTH // Queue up the scheduler to process UART data and run events.