AnsweredAssumed Answered

Kinetis UART TX DMA Transmit Complete Interrupt fails occasionally

Question asked by julian morrison on Feb 11, 2016
Latest reply on Feb 18, 2016 by julian morrison

Hi,

We have a UART driver on a Kinetis K10DX using DMA to TX and single character interrupt for the RX.

It all works just fine but occasionally, very occasionally (like 10 days), it appears the Transmit Complete interrupt fails to fire causing us some problems.

I've poured over the code and put debug code in to try to re-create the problem without success.

 

I could put in a work around to check the state of TCFIFO after a timeout but this sound like a bit of a hack.

I think the question are:

1) Has anyone else had issues with the Transmit Complete interrupt (UART_S1_TC)?

2) Does anyone have any suggestions for a fix or a robust work around?

 

Cheers,

Here are the relevant bits of the driver:

 

// ===================================================================
// UART TX send buffer
// ===================================================================
void Uart0_TxBuff(UCHAR* buffer, USHORT length)
{     
   DMA_TCD2_BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(length);   // set beginning loop count
   DMA_TCD2_CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(length);   // set loop current count
   DMA_TCD2_SADDR = (ULONG)buffer;                             // set source address
   DMA_SERQ = UART0_CHANNEL;                                   // set enable request
   UART0_C2 |= UART_C2_TCIE_MASK;                              // enable TX complete interrupts
}

// ===================================================================
// UART TX/RX Interrupt
// ===================================================================
void UART0_RX_TX_IRQHandler()
{
   UCHAR data;
   UCHAR statReg1 = UART0_S1;                      // save status register

   if (statReg1 & (UART_S1_OR_MASK                 // is any error flag set?
                 | UART_S1_NF_MASK
                 | UART_S1_FE_MASK
                 | UART_S1_PF_MASK))
   {
      data = UART0_D;                              // consume any data and ignore it
   }
   else if (statReg1 & UART_S1_RDRF_MASK)          // is RX data available?
   {
      data = UART0_D;                              // get data
      rxFunction(data);                            // send client the received character
   }
  
   if ((UART0_C2 & UART_C2_TCIE_MASK) &&           // is TX complete enabled and
       (statReg1 & UART_S1_TC_MASK))               // is TX complete?
   {
      UART0_C2 &= ~UART_C2_TCIE_MASK;              // disable TX complete interrupts
      responseCompleteFunction();                  // notify client transmission complete
   }
}

Outcomes