AnsweredAssumed Answered

K60F120M 3 Mbps Uart RX / DMA user watchout if using KSDK LDD

Question asked by Henry Nguyen on Feb 8, 2017
Latest reply on Feb 12, 2017 by xiangjun.rong

Hi,

I am doing an evaluation of the data path: CPU => uart_0_tx => external loopback through RS485 => uart_0_rx => DMA => memory where the Uart is transferring at 3 mbps as required by application.

 

I used LDD from Kinetis and instantiated DMA channel_ldd, uart_ldd.  They worked fine at lower baud rate but start failing at higher baud rate.

 

Looking carefully, i came to noticed that the uart0 Tx RX is combined in an ISR (KSDK implementation).

When there is a slight changes in ISR service latency timing such that RX is ready and TX is ready at the same time when ISR is executed, the codes accidentally read the RX FIFO and thus causing the DMA request to be out of sync.  the received data is missed.

 

This happens regardless if C2[RIE] and C5[RDMAS] are both set.  The interrupt is triggered only by TX fifo condition.

 

i have to comment out that section of codes and the program works ok.

 

i would like to give this feedback to NXP so that this can be improved on next revision and may potentially save debugging times for other user.

 

uart.c file:

========

 

PE_ISR(HSB_Interrupt)
{
/* {Default RTOS Adapter} ISR parameter is passed through the global variable */
HSB_TDeviceDataPtr DeviceDataPrv = INT_UART0_RX_TX__DEFAULT_RTOS_ISRPARAM;
register uint32_t StatReg = UART_PDD_ReadInterruptStatusReg(UART0_BASE_PTR); /* Read status register */

if (StatReg & (UART_S1_NF_MASK | UART_S1_OR_MASK | UART_S1_FE_MASK | UART_S1_PF_MASK)) { /* Is any error flag set? */
(void)UART_PDD_GetChar8(UART0_BASE_PTR); /* Dummy read 8-bit character from receiver */
StatReg &= (uint32_t)(~(uint32_t)UART_S1_RDRF_MASK); /* Clear the receive data flag to discard the errorneous data */

 

// Buggy part:
// comment out the RDRF check. This is done by KSDK because it shares the same TX and RX ISR.
// in this ISR, if the timing of the ISR service latency in such that the RX flag and TX flag active at the same time when

// ISR is branched to, then, this ISR wrongly read the RX Data and cause DMA request to be dropped and out of sync.

// this happens regardless if C2[RIE] and C5[RDMAS] are both set.  The interrupt is triggered only by TX fifo condition,

// but accidentally read the RX FIFO.

 

//   if (StatReg & UART_S1_RDRF_MASK) { /* Is the receiver's interrupt flag set? */
//      InterruptRx(DeviceDataPrv); /* If yes, then invoke the internal service routine. This routine is inlined. */
//  }


if (DeviceDataPrv->SerFlag & ENABLED_TX_INT) { /* Is the transmitter interrupt enabled? */
if (StatReg & UART_S1_TDRE_MASK) { /* Is the transmitter empty? */
InterruptTx(DeviceDataPrv); /* If yes, then invoke the internal service routine. This routine is inlined. */
}
}
}

 

vector.c file:

=========

 

(tIsrFunc)&Cpu_Interrupt, /* 0x3C 0x000000F0 - ivINT_UART0_LON unused by PE */
(tIsrFunc)&HSB_Interrupt, /* 0x3D 0x000000F4 8 ivINT_UART0_RX_TX used by PE */
(tIsrFunc)&HSB_Interrupt, /* 0x3E 0x000000F8 12 ivINT_UART0_ERR used by PE */
(tIsrFunc)&Cpu_Interrupt, /* 0x3F 0x000000FC - ivINT_UART1_RX_TX unused by PE */

 

 

Cheers,

Henry

Outcomes