Fix rare NRF52 serial TX lockup

When using UARTSerial sending data over the uart follows the sequence
below:
<-TX done ISR runs and sets a software interrupt to pending
<-Software interrupt fires:
    -disables TX done interrupt
    -calls UARTSerial TX handler which sends bytes until the uart
     buffer filled (writeable returns false). Sending a byte
     re-enables the TX done interrupt continuing the cycle

Due to this sequence, if the UARTSerial TX handler does not send a byte
then the transmit state machine mentioned above will get stuck with
the TX done interrupt disabled. The events causing this failure:
<-TX done ISR runs and sets a software interrupt to pending
<-Software interrupt fires:
    -disables TX done interrupt
    -calls UARTSerial TX handler:
        -checks writeable which is true and sends a byte
            <- interrupted by a higher priority interrrupt
            <- TX done ISR runs, setting software interrupt to
               pending again
        -checks writeable which is true and sends a second byte
    -Software interrupt finishes
<-Software interrupt fires:
    -disables TX done interrupt
    -calls UARTSerial TX handler:
        -checks writeable which is false and DOES NOT SEND A BYTE
    -Software interrupt finishes, the TX interrupt is still disabled
*-Byte gets sent but TX done ISR does not fire

This patch prevents the TX lockup by removing the code in the
software interrupt which disables the TX done interrupt. Disabling the
TX done interrupt at this point is not necessary so this code is safe
to remove.
pull/8910/head
Russ Butler 2018-11-29 16:03:44 -06:00
parent e2ae84ec59
commit 131eed9b4f
1 changed files with 0 additions and 6 deletions

View File

@ -251,9 +251,6 @@ static void nordic_nrf5_uart_callback_handler(uint32_t instance)
*/
static void nordic_nrf5_uart_event_handler_endtx(int instance)
{
/* Disable ENDTX event again. */
nrf_uarte_int_disable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDTX_MASK);
/* Release mutex. As the owner this call is safe. */
nordic_nrf5_uart_state[instance].tx_in_progress = 0;
@ -277,9 +274,6 @@ static void nordic_nrf5_uart_event_handler_endtx(int instance)
#if DEVICE_SERIAL_ASYNCH
static void nordic_nrf5_uart_event_handler_endtx_asynch(int instance)
{
/* Disable ENDTX interrupt. */
nrf_uarte_int_disable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDTX_MASK);
/* Set Tx done and reset Tx mode to be not asynchronous. */
nordic_nrf5_uart_state[instance].tx_in_progress = 0;
nordic_nrf5_uart_state[instance].tx_asynch = false;