Kinetis UART TX DMA Transmit Complete Interrupt fails occasionally

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Kinetis UART TX DMA Transmit Complete Interrupt fails occasionally

Jump to solution
2,496 Views
julian_morrison
Contributor III

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
   }
}

Labels (1)
1 Solution
1,605 Views
EarlOrlando
Senior Contributor II

Hello Julian,

Is it possible to confirm that the responseCompleteFunction is not being called? It could be achieved through some LEDs or some flags (i.e. setting it before to call this function and clearing it inside the function).

Honestly, starting from this information, this behavior is very odd. I don't think this is happening but supposing that the interrupt handler is being executed, then it would mean that the TX flag is being cleared outside this function. Please double check that there is not another instruction in the code that is doing this.

At this moment, the only workaround that comes to mi mind is to do the same as the responseCompleteFunction does in the IRQ before to clear the TX interrupts.

Best regards,

Earl.

View solution in original post

0 Kudos
Reply
5 Replies
1,605 Views
EarlOrlando
Senior Contributor II

Hello Julian,

Your configurations seems to be ok, however, it is very difficult to find a solution without recreate the problem.

My advice is to wait for the MCU to fails, and once it fails attach the debugger to the running MCU. This will let you debug your system and look for the problem once the problem has been generated.

Attaching to a Running Target with Segger J-Link, GDB and Eclipse | MCU on Eclipse

Please let me know if this solution is helpful for you.

Best regards,

Earl.

1,605 Views
julian_morrison
Contributor III

Hi Earl,

I managed to capture some register details after the event.

It appears that there is no DMA error, no UART error, DMA has completed and the FIFO is empty. The TC complete flag is set and TCIE is reset suggesting that the interrupt had occurred but the responseCompleteFunction had not been called??

Here are the contents of the registers I managed to log:

C1   0x00   

:C2   0xAC  TIE,RIE,TE,RE (TCIE disabled) 

:C3   0x0F  errors enabled 

:C4   0x03  BRFA 

C5   0x80  TDMAS 

:C6   0x00   

BDL   0x41  19.2k,20MHz 

:BDH   0x00  RXEDGIE disabled 

S1   0xD0  TDRE,TC,IDLE 

:S2   0x40  RXEDGIF (not enabled) 

SFIFO   0xC0  TXEMPT,RXEMPT 

:CFIFO   0x00   

:PFIFO   0xAA  fifo's enabled 

RCFIFO   0x00  RX fifo empty 

:RWFIFO   0x01  wmark = 1 

:TCFIFO   0x00  TX fifo empty 

:TWFIFO   0x01  wmark = 1 

TCD2_SADDR  0x1FFFE738   

CITER_ELINKNO  0x0019  TX length 

:BITER_ELINKNO  0x0019  TX length 

TCD2_CSR  0x0088  DONE,DREQ 

:DMA_ERR  0x0000   

DMA_ES   0x0000   

DMA_CR   0x0084  EMLM(???),ERCA 

NBYTES_MLOFFYES  0x80000401 SMLOE,MLOFF=1,NBYTES=1

We need to fix this urgently as it is becoming an serious issue for our customers.

In desperation I am thinking of trying the following:

a) Turning off the RX/TX FIFO's

b) Using DMA complete interrupt instead of UART TC interrupt

c) Not using DMA at all and ship the data out one character at a time!!

Can you see anything that may be causing the problem or think of anything else?

Cheers, Julian

0 Kudos
Reply
1,606 Views
EarlOrlando
Senior Contributor II

Hello Julian,

Is it possible to confirm that the responseCompleteFunction is not being called? It could be achieved through some LEDs or some flags (i.e. setting it before to call this function and clearing it inside the function).

Honestly, starting from this information, this behavior is very odd. I don't think this is happening but supposing that the interrupt handler is being executed, then it would mean that the TX flag is being cleared outside this function. Please double check that there is not another instruction in the code that is doing this.

At this moment, the only workaround that comes to mi mind is to do the same as the responseCompleteFunction does in the IRQ before to clear the TX interrupts.

Best regards,

Earl.

0 Kudos
Reply
1,605 Views
julian_morrison
Contributor III

Hi Earl,

I believe I have found the problem. After putting counters in the entry and exit of the ISR and callback I see that that the callback is being called!! I believe I have an issue with the state machine being pre-empted by the ISR which I can fix. I shall mark your last response as Correct Answer.

Thanks you so much for your assistance and patience :-)

Cheers, Julian

0 Kudos
Reply
1,605 Views
julian_morrison
Contributor III

Thanks Earl,

Its good to know that at least there is nothing fundamentally wrong with the code.

It's going to be tricky getting access to the debug port as the modules are embedded in our system.

However, lets see what this shows up.

Cheers, Julian

0 Kudos
Reply