mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-11-06 04:22:49 +00:00
nimble/transport/cmac: Flush UART on CMAC error
When CMAC is used with HCI bridge over UART we should wait for all data to be flushed from UART before asserting on error, otherwise we will lose debug events.
This commit is contained in:
@@ -142,6 +142,7 @@ typedef int (cmac_mbox_read_cb)(const void *data, uint16_t len);
|
||||
typedef void (cmac_mbox_write_notif_cb)(void);
|
||||
void cmac_mbox_set_read_cb(cmac_mbox_read_cb *cb);
|
||||
void cmac_mbox_set_write_notif_cb(cmac_mbox_write_notif_cb *cb);
|
||||
int cmac_mbox_has_data(void);
|
||||
int cmac_mbox_read(void);
|
||||
int cmac_mbox_write(const void *data, uint16_t len);
|
||||
|
||||
|
||||
@@ -65,6 +65,13 @@ static struct os_event g_cmac_host_rand_ev = {
|
||||
|
||||
static void cmac_host_rand_chk_fill(void);
|
||||
|
||||
#if MYNEWT_VAL(BLE_HCI_BRIDGE) && MYNEWT_VAL_CHOICE(BLE_HCI_TRANSPORT, uart)
|
||||
static void cmac_host_error_w4flush(struct os_event *ev);
|
||||
static struct os_event g_cmac_host_error_ev = {
|
||||
.ev_cb = cmac_host_error_w4flush
|
||||
};
|
||||
#endif
|
||||
|
||||
static void
|
||||
cmac2sys_isr(void)
|
||||
{
|
||||
@@ -105,6 +112,14 @@ cmac2sys_isr(void)
|
||||
for (;;);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_HCI_BRIDGE) && MYNEWT_VAL_CHOICE(BLE_HCI_TRANSPORT, uart)
|
||||
NVIC_DisableIRQ(CMAC2SYS_IRQn);
|
||||
/* Wait until UART is flushed and then assert */
|
||||
cmac_host_error_w4flush(NULL);
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* XXX CMAC is in error state, need to recover */
|
||||
assert(0);
|
||||
return;
|
||||
@@ -147,6 +162,40 @@ cmac_host_rand_chk_fill(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_HCI_BRIDGE) && MYNEWT_VAL_CHOICE(BLE_HCI_TRANSPORT, uart)
|
||||
#if MYNEWT_VAL(BLE_HCI_UART_PORT) < 0 || MYNEWT_VAL(BLE_HCI_UART_PORT) > 2
|
||||
#error Invalid BLE_HCI_UART_PORT
|
||||
#endif
|
||||
static void
|
||||
cmac_host_error_w4flush(struct os_event *ev)
|
||||
{
|
||||
static UART_Type * const regs[] = {
|
||||
(void *)UART,
|
||||
(void *)UART2,
|
||||
(void *)UART3
|
||||
};
|
||||
|
||||
if (!ev) {
|
||||
/* Move to task context, we do not want to spin in interrupt */
|
||||
os_eventq_put(os_eventq_dflt_get(), &g_cmac_host_error_ev);
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
cmac_mbox_read();
|
||||
while ((regs[MYNEWT_VAL(BLE_HCI_UART_PORT)]->UART_LSR_REG &
|
||||
UART_UART_LSR_REG_UART_TEMT_Msk) == 0) {
|
||||
/* Wait until both FIFO and shift registers are empty */
|
||||
}
|
||||
} while (cmac_mbox_has_data());
|
||||
|
||||
/* Reset CMAC */
|
||||
CRG_TOP->CLK_RADIO_REG |= CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Msk;
|
||||
|
||||
assert(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
cmac_host_signal2cmac(void)
|
||||
{
|
||||
|
||||
@@ -46,6 +46,18 @@ cmac_mbox_set_write_notif_cb(cmac_mbox_write_notif_cb *cb)
|
||||
g_cmac_mbox_write_notif_cb = cb;
|
||||
}
|
||||
|
||||
int
|
||||
cmac_mbox_has_data(void)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE)
|
||||
volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s;
|
||||
#else
|
||||
volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_s2c;
|
||||
#endif
|
||||
|
||||
return mbox->rd_off != mbox->wr_off;
|
||||
}
|
||||
|
||||
int
|
||||
cmac_mbox_read(void)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user