Skip to content

Resolve hangs and reduce SERCOM drops

Neil Armstrong requested to merge bjorn-stall-fix into clo/main

When the host doesn't read out CDC buffers fast enough the udi_cdc_tx_buf buffers fills up, followed by the uart_fifo and all communication with the debug board stalls, indefinitely.

The reason for this is that as the uart_fifo fills up, the uart_fifo_put() macro will no longer evaluate the "b" expression, which is where the FIFO register is drained. This results in a live lock, where the SERCOM interrupt starves the system.

The initial attempts to resolve this by disabling the SERCOM interrupts when the uart fifo is full, or by reading the SERCOM FIFO and discarding the data both resulted in significant loss of UART data (1 in 20-40 bytes typically lost). This main culprit here seems to be the time spent with irqs disabled in the CDC implementation, but no conclusive remedy was found - all attempts resulted various degree of SERCOM underflow.

Instead, bring up the DMAC and use this to drain the SERCOM FIFO into a pair of buffers. The USB and CDC driver ticks off the USB SOF, so this is used to flip the buffers. When saturated, the UART should produce for about 15 characters per SOF, so as long as we get a CDC buffer out every 4 SOFs we should no longer underflow.

The DMAC interrupt is not wired up, as the CDC buffers are drained by the SOF events, and thereby flipping the DMAC buffers only following this should in general guarantee that the full 64 bytes of buffer space is available.

Signed-off-by: Bjorn Andersson bjorn.andersson@oss.qualcomm.com

Merge request reports

Loading