AnsweredAssumed Answered

i.MX28 Windows CE BSP Serial Port Bug Missing Received Data

Question asked by markwilliams on Feb 26, 2014
Latest reply on Jan 22, 2017 by Scott Stone

Hi,


We are using the i.MX28 with the current BSP and have noticed that the UART serial interface is losing data. On closer inspection of the driver I think I have found a bug in the code and could do with some support to resolve this.

 

The serial receive interrupt handler function is defined as ULONG SL_RxIntrHandler(PVOID pContext,PUCHAR pTargetBuffer,ULONG *pByteNumber) at the following path:

 

C:\WINCE600\PLATFORM\COMMON\src\soc\COMMON_FSL_V2_PDK1_9\SERIALAPP\COM_PDD\serialhw.c

 

The parameters are defined as:

 

//      pContext

//          [in] Pointer to device head.

//      pTargetBuffer

//          [in] Pointer to the target buffer in which to put the data.

//      pByteNumber

//          [in] Pointer to, on entry, the maximum number of bytes to read. On exit, the number of

//                bytes read.

 

This follows the Microsoft function prototype for HWRxIntrHandler.

 

I have found that the pByteNumber value is not the number of bytes to read but a decrementing value each time a block of data is received. On the first receive the value is 2047, and then for each block of received data this value decrements by the size of the last received block each time the RX interrupt handler runs.

 

Eventually the pByteNumber passed gets lower than the size of the next block of data received. In this case the remaining data is thrown away and the value reset to 2047. I have some debug output to show this:

 

Below I am sending chunks of 409 bytes into the serial port. The 'len' value in the SL_RxIntrHandler+ debug output is actually the *pByteNumber value - clearly not the number of bytes received and also decrementing on each receive.

The ByteRead value is what the RX interrupt got out of the receive - not always 409 bytes.

 

4491457 PID:400002 TID:1a50006 Rx Event

4491457 PID:400002 TID:1a50006 SL_RxIntrHandler+ : len 2047. EvtChar 0x1a

4491457 PID:400002 TID:1a50006 After HWGetBytes, Fifo(R=0,W=0,BA=0,L=2048) ByteRead=409

 

4491907 PID:400002 TID:1a50006 Rx Event

4491907 PID:400002 TID:1a50006 SL_RxIntrHandler+ : len 1639. EvtChar 0x1a

4491907 PID:400002 TID:1a50006 After HWGetBytes, Fifo(R=409,W=409,BA=0,L=2048) ByteRead=409

 

4494129 PID:400002 TID:1a50006 Rx Event

4494129 PID:400002 TID:1a50006 SL_RxIntrHandler+ : len 1230. EvtChar 0x1a

4494129 PID:400002 TID:1a50006 After HWGetBytes, Fifo(R=818,W=818,BA=0,L=2048) ByteRead=409

 

4494753 PID:400002 TID:1a50006 Rx Event

4494753 PID:400002 TID:1a50006 SL_RxIntrHandler+ : len 821. EvtChar 0x1a

4494753 PID:400002 TID:1a50006 After HWGetBytes, Fifo(R=1227,W=1227,BA=0,L=2048) ByteRead=409

 

4497799 PID:400002 TID:1a50006 Rx Event

4497799 PID:400002 TID:1a50006 SL_RxIntrHandler+ : len 412. EvtChar 0x1a

4497799 PID:400002 TID:1a50006 After HWGetBytes, Fifo(R=1636,W=1636,BA=0,L=2048) ByteRead=409

 

4498068 PID:400002 TID:1a50006 Rx Event                                                                      **********  409 chars are sent in here but after the function it only reads 3 and throws the rest away *************

4498068 PID:400002 TID:1a50006 SL_RxIntrHandler+ : len 3. EvtChar 0x1a

4498068 PID:400002 TID:1a50006 After HWGetBytes, Fifo(R=2045,W=2045,BA=0,L=2048) ByteRead=3

 

4500466 PID:400002 TID:1a50006 Rx Event                                      

4500466 PID:400002 TID:1a50006 SL_RxIntrHandler+ : len 2047. EvtChar 0x1a                  **********  len 'counter' value back to 2047 *************

4500466 PID:400002 TID:1a50006 After HWGetBytes, Fifo(R=0,W=0,BA=0,L=2048) ByteRead=409

 

4500906 PID:400002 TID:1a50006 Rx Event

4500906 PID:400002 TID:1a50006 SL_RxIntrHandler+ : len 1639. EvtChar 0x1a

4500906 PID:400002 TID:1a50006 After HWGetBytes, Fifo(R=409,W=409,BA=0,L=2048) ByteRead=409

 

 

The calling function SerialEventHandler() is in the freescale file mdd.c at the following path and calls the above using a function pointer as pFuncTbl->HWRxIntrHandler:

 

C:\WINCE600\PLATFORM\COMMON\src\soc\COMMON_FSL_V2_PDK1_9\SERIALAPP\COM_MDD2\mdd.c

 

As part of this function it calculates a 'RoomLeft' variable and passes a pointer to this in to the HWRxIntrHandler as the 'pByteNumber' parameter. Clearly this is not the correct thing to be passing.

 

if ( RxRIndex == 0 ) {

                // have to leave one byte free.

                RoomLeft = RxLength(pSerialHead) - RxWIndex - 1;

            } else {

                RoomLeft = RxLength(pSerialHead) - RxWIndex;

            }

            if ( RxRIndex > RxWIndex ) {

                RoomLeft = RxRIndex - RxWIndex - 1;

            }

            if ( RoomLeft ) {

                pSerialHead->DroppedBytesPDD +=

                    pFuncTbl->HWRxIntrHandler(pHWHead,

                                              RxBuffWrite(pSerialHead),

                                              &RoomLeft);

            } else {

                BYTE TempBuf[16];

                RoomLeft = 16;

                pFuncTbl->HWRxIntrHandler(pHWHead,

                                          TempBuf,

                                          &RoomLeft);

 

I would have thought that the RX handler would be passed the number of bytes to extract from the DMA memory and return how many it managed to read on that interrupt. Therefore I do not understand why it is a decrementing number.

 

Anyway it is clear that the Freescale i.MX28 Windows CE 6.0 BSP throws serial data away due to the above issue.

 

Can anyone help me with this?

Outcomes