Lpuart on the 5340 using interrupt mode fails to recover from a TX timeout

I am using the lpuart between an nRF5340DK and an nRF9160DK.The lpuart is configured to operate in interrupt mode. Everything seems to work fine as long both DK boards come up at the same time. However, if the nRF9160DK takes a while to come up and the nRF5340Dk tries to send data over the lpuart it will timeout, as expected. But once the nRF9160DK is operational, the lpuart tx on the nRF5340 will no loner try to send. I tracked the issue down to a CAS (compare and set) call in the  uart_fiffo_fill function. Because the previous TX timed out, data->int_driven.txlen still holds the previous send attempt data length and this causes the CAS to fail and no send attempt is made. There appears to be no way to recover form this aside from rebooting the device. Stepping through the lpuart driver I found the int_driven_evt_handler() function is called with an event type of UART_TX_ABORTED which is not handled. For debugging purposes, I added  a UART_TX_ABORTED handler and just set the txlen to zero as it would do in the async mode. This seemed to solve the problem i.e. all lpuart sends would timeout until the nRF9160DK became operational at which point all data transfers between the two devices resumed normally. So my question is, are there other ways to recover from an lpuart TX timeout while operating in interrupt mode?

Parents
  • Hello,

    Not sure if I can think of a better workaround, do you have any logic analyzer trace of the tx, rx, rdy and req pin when failing and working for comparison? does adding an external pull up on rdy or req make any difference? what is the timeout used here, does increasing it help?

    Kenneth

  • I have not considered an external pull up on the control lines as it doesn't seem to be the root of the issue. If you have additional data that would support using pull ups I would like to see it. Also, increasing the timeout will only kick the can down the road in my opinion and would not be a viable solution for this device. I have attached some traces for you to look at. One with the uart_nrf_sw_lpuart.c unmodified and the other with the modification of adding support for the UART_TX_ABORTED event in the int_driven_evt_handler(). The only thing the UART_TX_ABORED  code does is to set the txLen to zero.

    	case UART_TX_ABORTED:
    		LOG_DBG("tx aborted");
    		data->int_driven.txlen = 0;
    		call_handler = true;
    		break;
    

    Failure-with-lpuart-mod.sal

    Lpuart-tx-timeout-no-recover.sal

    --Kyle

Reply
  • I have not considered an external pull up on the control lines as it doesn't seem to be the root of the issue. If you have additional data that would support using pull ups I would like to see it. Also, increasing the timeout will only kick the can down the road in my opinion and would not be a viable solution for this device. I have attached some traces for you to look at. One with the uart_nrf_sw_lpuart.c unmodified and the other with the modification of adding support for the UART_TX_ABORTED event in the int_driven_evt_handler(). The only thing the UART_TX_ABORED  code does is to set the txLen to zero.

    	case UART_TX_ABORTED:
    		LOG_DBG("tx aborted");
    		data->int_driven.txlen = 0;
    		call_handler = true;
    		break;
    

    Failure-with-lpuart-mod.sal

    Lpuart-tx-timeout-no-recover.sal

    --Kyle

Children
Related