This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1230H6PM UART issue

Other Parts Discussed in Thread: TM4C1230H6PM, EK-TM4C123GXL

Hi,

I am using TM4C1230H6PM. I convert one of the UART port to interrupt base for receive data package which able to speed up the port process and reduce significantly for the package lost (I am using TI-RTOS method).

Now I intended to change all port to interrupt base for receive data package to ensure robust communication to all the slave devices. But the 2nd and 3rd UART port will always fail to get the 2nd byte.

 1st UART port with 9600bps at UART 1 (working good and very stable). This port connect to our Host system.

2nd UART port with 57600bps at UART 6 (only able to get the first byte for every data package received). This port connect to our slave 1 system.

3rd UART port with 57600bps at UART 2 (only able to get the first byte for every data package received) this port connect to our slave 2 system.

I already try FIFO But my data need to be 31 bytes… fifo only with 16 bytes and too fast…

 

Please provide how to activate the FIFO correctly and DMA correcty?  Sample code needed because the document not really clear enough.

FIFO is working for data up to 16 bytes. Unable to receive data longer than 16 bytes. Either I set with FIFO enable or not it still the same (only 16 bytes) .

 

In ISR, I clear the UARTIntClear after get the UARTInStatus valid get up to 16 bytes by using UARTCharGetNonBlocking. After clear interrupt, system should be able to have next interrupt for the next 16 bytes coming in.

 

On Freescale, as long as you do UARTIntClear, the UART will immediately activate and receive the UART data and never miss any information for 100 over incoming bytes at the speed of 115200bps.

Need advise urgently on this issue. Please help, Thank you very much.

Thanks and best regards,

KH Lee

  • Hello Kum Hoo,

    The FIFO size if fixed on TM4C devices. When communicating with the Slave devices which would be sending the 31 bytes of data you need to ensure that the uDMA Burst Mode is set. There is an example code called udma_demo which shows the initialization of the UDMA. What you need to do is

    1. Use Basic Mode of transfer with Burst feature enabled so that all data is transferred by the UDMA before switching channels
    2. Set the DMA RX threshold to a level where the DMA can read between the channels w/o loss of banddwith. I would suggest using 1/2 level
    3. Set the System Clock to 80MHz allowing enough time for the uDMA to service the slave UARTs.

    There is not a ready code for your case (unless forum members can share it), so you can make a start and we can help build it. But please note that we do not have your setup, so we can only correct the code if something is grossly incorrect.

    Regards
    Amit
  • Hi Amit,

    I am lionel as friend of Kum Hoo. The information from slave devices is not fix at 31 bytes. The slave devices will send either 9 bytes, 31 bytes, 45 bytes or 65 bytes to the TM4C device.

    Before your previous answer, i managed to make FIFO working well but only up to 16 bytes of data with UART6 HWI interrupt service routine. for information more than 16 bytes like 31 bytes or more, i can only get the first 16 bytes. This mean the FIFO overflow is not working. as in the HWI interrupt service routine i do UARTIntClear. the UART interrupt never continue receive the sub sequence 16 bytes after the first 16 bytes.

    Clock as 80Mhz 

    i already try using uDMA Basic Mode with Burst as in the attached c file. Do not seem to be working and very slow to get the data (more worst than like using old polling port method)

    #include "Configuration.h"
    
    #if ANTENNA_TYPE == ANTENNA_GEMPROX_C2
    
    #include <string.h>
    #include "GemproxAntenna.h"
    #include "GEMPROXProtocol.h"
    #include "driverlib/uart.h"
    
    uint8_t antBuff[64];
    uint8_t antennaStatus;
    uint16_t swStatus;
    //volatile uint32_t uartBase = ENTRY_ANT_UART_BASE;
    APDUCommand apduAntCmd;
    
    uint8_t deselectCard[] = {0xE4, 0x15, 0x01};	// 0x01 is the card CID
    uint8_t rfReset[] = {0xE1};
    uint8_t getFirstCardA[] = {0xE2, 0x01};
    uint8_t getNextCardA[] = {0xE2, 0x00};
    uint8_t getFirstTCL[] = {0xE2, 0x03, 0x04};	// Get first T=CL and set card baud rate to 848 kbps
    uint8_t getNextTCL[] = {0xE2, 0x02, 0x04};	// Get first T=CL and set card baud rate to 848 kbps
    uint8_t apduVerifyCHV[] = {0x00, 0x20, 0x00, 0x01};
    uint8_t apduEncWithSYM[] = {0x00, 0x88, 0x00, 0x0E};	// 0x0E is the EF.SYM file code
    uint8_t apduSelectAID[] = {0x00, 0xA4, 0x04, 0x0C, 0x08, 0xA0, 0x00, 0x00, 0x03, 0x41, 0x00, 0x00, 0x01};
    uint8_t apduSelectEF[] = {0x00, 0xA4, 0x02, 0x0C, 0x02, 0x01, 0xFF};	// Replace 0xFF with EF ID
    uint8_t apduReadBinary[] = {0x00, 0xB0, 0xFF, 0xFE, 0xAA};	// Replace 0xFF with OffsetHi, 0xFE with OffsetLo, 0xAA with len
    uint8_t mifareSectorRead[] = {0x29, 0, 0, 0, 0, 0, 0, 0, 0};
    uint8_t mifareBlockRead[] = {0xE5, 0x84, 0xB8, 0x00, 0x04, 0x01, 0x20, 0x10};
    uint8_t mifareLoadKey[] = {0xE5, 0x80, 0x24, 0x00, 0x04, 0x0D, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    uint8_t TransportCodeS00[] = {0xBD, 0xDE, 0x6F, 0x37, 0x83, 0x83};
    uint8_t TransportCodeS01[] = {0x14, 0x8A, 0xC5, 0xE2, 0x28, 0x28};
    uint8_t TransportCodeS02[] = {0x7D, 0x3E, 0x9F, 0x4F, 0x95, 0x95};
    uint8_t TransportCodeS03[] = {0xAD, 0xD6, 0x6B, 0x35, 0xC8, 0xC8};
    uint8_t TransportCodeS04[] = {0xDF, 0xEF, 0x77, 0xBB, 0xE4, 0xE4};
    uint8_t TransportCodeS05[] = {0x09, 0x84, 0x42, 0x21, 0xBC, 0xBC};
    uint8_t TransportCodeS06[] = {0x5F, 0xAF, 0xD7, 0xEB, 0xA5, 0xA5};
    uint8_t TransportCodeS07[] = {0x29, 0x14, 0x8A, 0xC5, 0x9F, 0x9F};
    uint8_t TransportCodeS08[] = {0xFA, 0xFD, 0xFE, 0x7F, 0xFF, 0xFF};
    uint8_t TransportCodeS09[] = {0x73, 0x39, 0x9C, 0xCE, 0xBE, 0xBE};
    uint8_t TransportCodeS10[] = {0xFC, 0x7E, 0xBF, 0xDF, 0xBF, 0xBF};
    uint8_t TransportCodeS11[] = {0xCF, 0xE7, 0x73, 0x39, 0x51, 0x51};
    uint8_t TransportCodeS12[] = {0xF7, 0xFB, 0x7D, 0x3E, 0x5A, 0x5A};
    uint8_t TransportCodeS13[] = {0xF2, 0x79, 0x3C, 0x1E, 0x8D, 0x8D};
    uint8_t TransportCodeS14[] = {0xCF, 0xE7, 0x73, 0x39, 0x45, 0x45};
    uint8_t TransportCodeS15[] = {0xB7, 0xDB, 0x6D, 0xB6, 0x7D, 0x7D};
    
    #define UART_RXBUF_SIZE         16
    static  uint8_t g_pui8RxPingA[UART_RXBUF_SIZE];
    //static  uint8_t g_pui8RxPingB[UART_RXBUF_SIZE];
    
    //UInt gateKey;
    //GateTask_Handle gateTask;
    //GateTask_Params prms;
    //Error_Block eb;
    //BOOL gateInitialized = FALSE;
    
    ////////////////////////
    // this section must be
    // refactored and placed
    // in a HAL section of
    // this project
    
    static volatile uint8_t EntryUartRxIntBuf[ANT_RX_FIFO_SZ+5]; // Lionel 5 as allowance
    static volatile uint8_t EntryRxFifoHead=0,EntryRxFifoTail=0;
    static volatile uint8_t ExitUartRxIntBuf[ANT_RX_FIFO_SZ+5]; // Lionel 5 as allowance
    static volatile uint8_t ExitRxFifoHead=0,ExitRxFifoTail=0;
    
    #pragma DATA_ALIGN(ucControlTable, 1024)
    uint8_t ucControlTable[1024];
    
    //*****************************************************************************
    //
    // The count of uDMA errors.  This value is incremented by the uDMA error
    // handler.
    //
    //*****************************************************************************
    static volatile uint32_t g_ui32uDMAErrCount = 0;
    static volatile short DMA_EndWaitA = 0;
    static volatile short DMA_EndWaitB = 0;
    static volatile uint8_t EntryRxDataLength = 0;
    static volatile uint8_t ExitRxDataLength = 0;
    
    //*****************************************************************************
    //
    // The interrupt handler for uDMA errors.  This interrupt will occur if the
    // uDMA encounters a bus error while trying to perform a transfer.  This
    // handler just increments a counter if an error occurs.
    //
    //*****************************************************************************
    void uDMAErrorHandler(void)
    {
        uint32_t ui32Status;
    
        //
        // Check for uDMA error bit
        //
        ui32Status = uDMAErrorStatusGet();
    
        //
        // If there is a uDMA error, then clear the error and increment
        // the error counter.
        //
    	DumpString("In uDMAErrorHandler\r\n");
        if(ui32Status)
        {
            uDMAErrorStatusClear();
            g_ui32uDMAErrCount++;
        }
    }
    
    #if 1
    // This interrupt handler uses ring buffer software FIFO implementation. - Lionel
    void Entry_Uart_rxIntHandler(void)
    {
    	static uint32_t status;
    	static uint32_t DMAMode;
    	static uint8_t data;
    	uint8_t localcount = 0;
    
    	status=UARTIntStatus(ENTRY_ANT_UART_BASE,UART_INT_RX);
    	UARTIntClear(ENTRY_ANT_UART_BASE, UART_INT_RX | UART_INT_RT);
    	//UARTRxErrorClear(ENTRY_ANT_UART_BASE); // should this be here?
    
    	DumpString("In Entry_Uart_rxIntHandler\r\n");
    	if(status&UART_INT_RX)
    	{
    //		if (DMA_EndWaitA == 1 && DMA_EndWaitB == 0)
    		{
    			DMAMode = uDMAChannelModeGet(UDMA_CH10_UART6RX | UDMA_PRI_SELECT);
    			//if(DMAMode == UDMA_MODE_STOP)
    			DumpString("Entry Status = ");
    				DumpHex(status>>8);
    				DumpHex(status);
    				DumpString(" Entry Data A = ");
    				do{
    					data=g_pui8RxPingA[localcount];//UARTCharGetNonBlocking(ENTRY_ANT_UART_BASE);
    					if (data != 0xFF){
    						DumpHex(data);
    						localcount++;
    						EntryUartRxIntBuf[EntryRxFifoHead]=data;
    						EntryRxFifoHead++;
    						if(EntryRxFifoHead>ANT_RX_FIFO_SZ){
    							EntryRxFifoHead=0;
    							DumpString("EntryRxFifoHead reset\r\n");
    						}
    					}
    				} while (data != 0xFF && localcount < UART_RXBUF_SIZE);
    				DumpString(" EntryRxFifoHead = ");
    				DumpHex(EntryRxFifoHead);
    				DumpString(" EntryRxFifoTail = ");
    				DumpHex(EntryRxFifoTail);
    				DumpString(" localcount = ");
    				DumpHex(localcount);
    				DumpNewLine();
    				DMA_EndWaitA = 0;
    
    		    	//UARTDMADisable(ENTRY_ANT_UART_BASE, UART_DMA_RX); // uDMA only work GOOD with first uDMADisable!
    			    //uDMAChannelAttributeEnable(UDMA_CH10_UART6RX, UDMA_ATTR_ALTSELECT);
    				uDMAChannelTransferSet(UDMA_CH10_UART6RX | UDMA_PRI_SELECT,
    						UDMA_MODE_BASIC,
    				                                   (void *)(ENTRY_ANT_UART_BASE + UART_O_DR),
    				                                   g_pui8RxPingA, UART_RXBUF_SIZE);
    				//uDMAChannelEnable(UDMA_CH10_UART6RX);
    				//UARTDMAEnable(ENTRY_ANT_UART_BASE,UART_DMA_RX);
    				DMA_EndWaitB = 1;
    			/*} else if (DMA_EndWaitB == 1 && DMA_EndWaitA == 0){
    				DMAMode = uDMAChannelModeGet(UDMA_CH10_UART6RX | UDMA_ALT_SELECT);
    				//if(DMAMode == UDMA_MODE_STOP)
    				DumpString("Entry Status = ");
    				DumpHex(status>>8);
    				DumpHex(status);
    				DumpString(" Entry Data B = ");
    				do{
    					data=g_pui8RxPingB[localcount];//UARTCharGetNonBlocking(ENTRY_ANT_UART_BASE);
    					if (data != 0xFF){
    						DumpHex(data);
    						localcount++;
    						EntryUartRxIntBuf[EntryRxFifoHead]=data;
    						EntryRxFifoHead++;
    						if(EntryRxFifoHead>ANT_RX_FIFO_SZ){
    							EntryRxFifoHead=0;
    							DumpString("EntryRxFifoHead reset\r\n");
    						}
    					}
    				} while (data != 0xFF && localcount < UART_RXBUF_SIZE);
    				DumpString(" EntryRxFifoHead = ");
    				DumpHex(EntryRxFifoHead);
    				DumpString(" EntryRxFifoTail = ");
    				DumpHex(EntryRxFifoTail);
    				DumpString(" localcount = ");
    				DumpHex(localcount);
    				DumpNewLine();
    				DMA_EndWaitB = 0;
    
    		    	UARTDMADisable(ENTRY_ANT_UART_BASE, UART_DMA_RX); // uDMA only work GOOD with first uDMADisable!
    			    uDMAChannelAttributeDisable(UDMA_CH10_UART6RX, UDMA_ATTR_ALTSELECT);
    				uDMAChannelTransferSet(UDMA_CH10_UART6RX | UDMA_PRI_SELECT,
    						UDMA_MODE_BASIC,
    				                                   (void *)(ENTRY_ANT_UART_BASE + UART_O_DR),
    				                                   g_pui8RxPingA, UART_RXBUF_SIZE);
    				uDMAChannelEnable(UDMA_CH10_UART6RX);
    				UARTDMAEnable(ENTRY_ANT_UART_BASE,UART_DMA_RX);
    				DMA_EndWaitA = 1;*/
    			}
    
    /*		} else {
    	    	UARTDMADisable(ENTRY_ANT_UART_BASE, UART_DMA_RX); // uDMA only work GOOD with first uDMADisable!
    			uDMAChannelTransferSet(UDMA_CH10_UART6RX | UDMA_PRI_SELECT,
    			                                   UDMA_MODE_BASIC,
    			                                   (void *)(ENTRY_ANT_UART_BASE + UART_O_DR),
    			                                   g_pui8RxPingA, UART_RXBUF_SIZE);
    			uDMAChannelEnable(UDMA_CH10_UART6RX);
    			UARTDMAEnable(ENTRY_ANT_UART_BASE,UART_DMA_RX);
    			DMA_EndWaitA = 1;*/
    	}
    #if 0//ENABLE_DBG_STR_IN_UART_RX_INT
    	else
    	{
    		DumpString("Entry Interrupt Error Status = ");
    		DumpHex(status>>8);
    		DumpHex(status);
    		//DumpHex(data);
    		DumpNewLine();
    	}
    #endif
    }
    
    // This interrupt handler uses ring buffer software FIFO implementation. - Lionel
    #else
    void Entry_Uart_rxIntHandler(void)
    {
    	static unsigned long status;
    	static uint8_t data;
    	uint8_t localcount = 0;
    
    	status=UARTIntStatus(ENTRY_ANT_UART_BASE,UART_INT_RX);
    	UARTIntClear(ENTRY_ANT_UART_BASE, UART_INT_RX | UART_INT_RT);
    	UARTRxErrorClear(ENTRY_ANT_UART_BASE); // should this be here?
    
    	DumpString("In Entry_Uart_rxIntHandler\r\n");
    	if(status&UART_INT_RX)
    	{
    		DumpString("Entry Status = ");
    		DumpHex(status>>8);
    		DumpHex(status);
    		DumpString(" Entry Data = ");
    		do{
    			data=UARTCharGetNonBlocking(ENTRY_ANT_UART_BASE);
    			if (data != 0xFF){
    				DumpHex(data);
    				localcount++;
    				EntryUartRxIntBuf[EntryRxFifoHead]=data;
    				EntryRxFifoHead++;
    				if(EntryRxFifoHead>ANT_RX_FIFO_SZ){
    					EntryRxFifoHead=0;
    					DumpString("EntryRxFifoHead reset\r\n");
    				}
    			}
    		} while (data != 0xFF && localcount < 32);
    		DumpString(" EntryRxFifoHead = ");
    		DumpHex(EntryRxFifoHead);
    		DumpString(" EntryRxFifoTail = ");
    		DumpHex(EntryRxFifoTail);
    		DumpString(" localcount = ");
    		DumpHex(localcount);
    		DumpNewLine();
    	}
    #if ENABLE_DBG_STR_IN_UART_RX_INT
    	else
    	{
    		DumpString("Entry Interrupt Error Status = ");
    		DumpHex(status>>8);
    		DumpHex(status);
    		//DumpHex(data);
    		DumpNewLine();
    	}
    #endif
    }
    #endif
    // This interrupt handler uses ring buffer software FIFO implementation. - Lionel
    void Exit_Uart_rxIntHandler(void)
    {
    	static unsigned long status;
    	static uint8_t data;
    	uint8_t localcount = 0;
    
    	status=UARTIntStatus(EXIT_ANT_UART_BASE,UART_INT_RX);
    	UARTIntClear(EXIT_ANT_UART_BASE, UART_INT_RX | UART_INT_RT);
    	UARTRxErrorClear(EXIT_ANT_UART_BASE); // should this be here?
    
    	//DumpString("In Exit_Uart_rxIntHandler\r\n");
    	if(status&UART_INT_RX)
    	{
    		//DumpString("Exit Status = ");
    		//DumpHex(status>>8);
    		//DumpHex(status);
    		//DumpString(" Exit Data = ");
    		do{
    			data=UARTCharGetNonBlocking(EXIT_ANT_UART_BASE);
    			if (data != 0xFF){
    				//DumpHex(data);
    				localcount++;
    				ExitUartRxIntBuf[ExitRxFifoHead]=data;
    				ExitRxFifoHead++;
    				if(ExitRxFifoHead>ANT_RX_FIFO_SZ) {
    					ExitRxFifoHead=0;
    					//DumpString("ExitRxFifoHead reset\r\n");
    				}
    			}
    		} while (data != 0xFF && localcount < 32);
    		//DumpString(" ExitRxFifoHead = ");
    		//DumpHex(ExitRxFifoHead);
    		//DumpString(" ExitRxFifoTail = ");
    		//DumpHex(ExitRxFifoTail);
    		//DumpString(" localcount = ");
    		//DumpHex(localcount);
    		//DumpNewLine();
    	}
    #if ENABLE_DBG_STR_IN_UART_RX_INT
    	else
    	{
    		DumpString("Exit Interrupt Error Status = ");
    		DumpHex(status>>8);
    		DumpHex(status);
    		//DumpHex(data);
    		DumpNewLine();
    	}
    #endif
    }
    
    int32_t Process_UARTTimedReceiveByte(uint8_t antenna)
    {
    	uint8_t data;
    	if (antenna == ENTRY_ANTENNA){
    		// If RX FIFO is not empty
    		if (EntryRxFifoHead!=EntryRxFifoTail)
    		{
    			data=EntryUartRxIntBuf[EntryRxFifoTail];
    			EntryRxFifoTail++;
    			if(EntryRxFifoTail>ANT_RX_FIFO_SZ)
    				EntryRxFifoTail=0;
    			//DumpString(" ");
    			return data;
    		}
    		return -1;
    	} else {
    		// If RX FIFO is not empty
    		if (ExitRxFifoHead!=ExitRxFifoTail)
    		{
    			data=ExitUartRxIntBuf[ExitRxFifoTail];
    			ExitRxFifoTail++;
    			if(ExitRxFifoTail>ANT_RX_FIFO_SZ)
    				ExitRxFifoTail=0;
    			//DumpString(" ");
    			return data;
    		}
    		return -1;
    	}
    }
    
    void Antenna_Uart_FlushRxBuffer(uint8_t antenna)
    {
    	if (antenna == ENTRY_ANTENNA){
    		Entry_Uart_FlushRxBuffer();
    	} else {
    		Exit_Uart_FlushRxBuffer();
    	}
    }
    
    void Entry_Uart_FlushRxBuffer(void)
    {
    	EntryRxFifoHead=0;
    	EntryRxFifoTail=0;
    	DumpString("EntryRxFifoHead & EntryRxFifoTail reset \r\n");
    }
    
    void Exit_Uart_FlushRxBuffer(void)
    {
    	ExitRxFifoHead=0;
    	ExitRxFifoTail=0;
    	DumpString("ExitRxFifoHead & ExitRxFifoTail reset \r\n");
    }
    
    void Antenna_Baudrate(uint8_t antenna, uint32_t baudrate){
    	if (antenna == ENTRY_ANTENNA)
    	{
    	    UARTConfigSetExpClk(ENTRY_ANT_UART_BASE, SysCtlClockGet(), baudrate, ENTRY_ANT_UART_CONFIG);
    	}
    	else if (antenna == EXIT_ANTENNA)
    	{
    	    UARTConfigSetExpClk(EXIT_ANT_UART_BASE, SysCtlClockGet(), baudrate, EXIT_ANT_UART_CONFIG);
    	}
    }
    
    void Antenna_Init( uint8_t antenna, uint32_t baudrate )
    {
    	if (antenna == ENTRY_ANTENNA)
    	{
    	    // Enable the uDMA controller at the system level.  Enable it to continue
    	    // to run while the processor is in sleep.
    		SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA);
    		SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    	    SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
    	    // Enable the uDMA controller.
    	    uDMAEnable();
    	    // Point at the control table to use for channel control structures.
    		uDMAControlBaseSet(ucControlTable);
    
    	    // Enable the peripherals used by this example.
    		SysCtlPeripheralEnable(ENTRY_ANT_UART_PERIPH);
    	    SysCtlPeripheralEnable(ENTRY_ANT_PORT_PERIPH);
    
    		// Set GPIO A0 and A1 as UART6 pins.
    		GPIOPinConfigure(ENTRY_ANT_PORT_PIN_RX);
    		GPIOPinConfigure(ENTRY_ANT_PORT_PIN_TX);
    		// Configure and enable the UART with DMA
    		GPIOPinTypeUART(ENTRY_ANT_PORT_BASE, ENTRY_ANT_PORT_PIN);
    
    	    // Configure the UART6 for 57,600, 8-N-1 operation.
    	    UARTConfigSetExpClk(ENTRY_ANT_UART_BASE, SysCtlClockGet(), baudrate, ENTRY_ANT_UART_CONFIG);
    
    		UARTFIFOLevelSet(ENTRY_ANT_UART_BASE, UART_FIFO_TX1_8, UART_FIFO_RX4_8);
    
    		// Enable FIFO
    		UARTFIFOEnable(ENTRY_ANT_UART_BASE);
    
    	    UARTFlowControlSet(ENTRY_ANT_UART_BASE, UART_FLOWCONTROL_NONE);
    
    		// Configure the UART
    		UARTEnable(ENTRY_ANT_UART_BASE);
    
    		IntEnable(ENTRY_ANT_UART_INT);
    
    
    
    	    // Enable the uDMA controller error interrupt.  This interrupt will occur
    	    // if there is a bus error during a transfer.
    	    IntEnable(INT_UDMAERR);
    
    		uDMAChannelAssign(UDMA_CH10_UART6RX);
    
    	    // Receive channel setup
    	    uDMAChannelAttributeDisable(UDMA_CH10_UART6RX,
    	    		UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    	                                UDMA_ATTR_HIGH_PRIORITY |
    	                                UDMA_ATTR_REQMASK);
    //	    uDMAChannelAttributeEnable(UDMA_CH10_UART6RX, UDMA_ATTR_USEBURST);
    	    uDMAChannelControlSet(UDMA_CH10_UART6RX | UDMA_PRI_SELECT,
    	                          UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
    	                          UDMA_ARB_4);
    	    //uDMAChannelControlSet(UDMA_CH10_UART6RX | UDMA_ALT_SELECT,
    	    //                          UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
    	    //                          UDMA_ARB_4);
    
     		uDMAChannelTransferSet(UDMA_CH10_UART6RX | UDMA_PRI_SELECT,
     				UDMA_MODE_BASIC,
    		                                   (void *)(ENTRY_ANT_UART_BASE + UART_O_DR),
    		                                   g_pui8RxPingA, UART_RXBUF_SIZE);
    		//uDMAChannelTransferSet(UDMA_CH10_UART6RX | UDMA_ALT_SELECT,
    		//		UDMA_MODE_BASIC,
    		//                                   (void *)(ENTRY_ANT_UART_BASE + UART_O_DR),
    		//                                   g_pui8RxPingB, UART_RXBUF_SIZE);
    		uDMAChannelEnable(UDMA_CH10_UART6RX);
    		UARTDMAEnable(ENTRY_ANT_UART_BASE,UART_DMA_RX);
    	    DMA_EndWaitA = 1;
    	    //DMA_EndWaitB = 0;
    		//uDMAChannelEnable(UDMA_CH10_UART6RX);
    		UARTIntEnable(ENTRY_ANT_UART_BASE, UART_INT_RX);
    	    // Disable the UART interrupt.
    	    //IntDisable(ENTRY_ANT_UART_INT);
    	    //UARTIntEnable(ENTRY_ANT_UART_BASE, UART_INT_RX | UART_INT_RT);
    //		IntMasterEnable();
    
    		//DumpPrintf("----- ENTRY -----\r\n");
    	}
    	else if (antenna == EXIT_ANTENNA)
    	{
    		//uartBase = EXIT_ANT_UART_BASE;
    		// Set unused UART port direction into input with weak pull-up resistor
    	   // SysCtlPeripheralEnable(ENTRY_ANT_UART_PERIPH);
    	   // SysCtlPeripheralEnable(ENTRY_ANT_PORT_PERIPH);
    	   // GPIODirModeSet(ENTRY_ANT_PORT_BASE, ENTRY_ANT_PORT_PIN, GPIO_DIR_MODE_IN);
        	//GPIOPadConfigSet(ENTRY_ANT_PORT_BASE, ENTRY_ANT_PORT_PIN, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
    		//GPIOPinConfigure(ENTRY_ANT_PORT_PIN_RX & 0xFFFFFFF0);
    		//GPIOPinConfigure(ENTRY_ANT_PORT_PIN_TX & 0xFFFFFFF0);
    
    		// Enable the peripherals used by this example.
    	    SysCtlPeripheralEnable(EXIT_ANT_UART_PERIPH);
    	    SysCtlPeripheralEnable(EXIT_ANT_PORT_PERIPH);
    
    		// Set GPIO A0 and A1 as UART0 pins.
    		GPIOPinConfigure(EXIT_ANT_PORT_PIN_RX);
    		GPIOPinConfigure(EXIT_ANT_PORT_PIN_TX);
    		GPIOPinTypeUART(EXIT_ANT_PORT_BASE, EXIT_ANT_PORT_PIN);
    	
    	    // Configure the UART
    		UARTEnable(EXIT_ANT_PORT_BASE);
    	    // Configure the UART0 for 115,200, 8-N-1 operation.
    	    UARTConfigSetExpClk(EXIT_ANT_UART_BASE, SysCtlClockGet(), baudrate, EXIT_ANT_UART_CONFIG);
    
    		UARTFlowControlSet(EXIT_ANT_UART_BASE,UART_FLOWCONTROL_NONE);
    	    //UARTFIFODisable(EXIT_ANT_UART_BASE);
    		// Enable FIFO
     		UARTFIFOLevelSet(EXIT_ANT_UART_BASE, UART_FIFO_TX1_8, UART_FIFO_RX1_8);
     		UARTFIFOEnable(EXIT_ANT_UART_BASE);
    
    	    // Disable the UART interrupt.
    	    //IntDisable(EXIT_ANT_UART_INT);
    	    //UARTIntDisable(EXIT_ANT_UART_BASE, UART_INT_RX | UART_INT_RT);
    		UARTIntEnable(EXIT_ANT_UART_BASE,UART_INT_RX);
    		IntEnable(EXIT_ANT_UART_INT);
    		//IntMasterEnable();
    
    		//DumpPrintf("----- EXIT -----\r\n");
    	}
    }
    
    BOOL Antenna_SetBaudrate(uint8_t antenna, uint8_t baudrate, uint32_t timeout)
    {
    	uint8_t buff[] = {0x0A, 0x00};
    	int32_t tmp;
    	uint8_t _buff[16];
    	volatile uint32_t uartBase = ENTRY_ANT_UART_BASE;
    	buff[1] = baudrate;
    
    	if (antenna == ENTRY_ANTENNA)
    		uartBase = ENTRY_ANT_UART_BASE;
    	else
    		uartBase = EXIT_ANT_UART_BASE;
    
    	//portENTER_CRITICAL();
    	GEMPROX_Send(uartBase, buff, sizeof(buff));
    	//portEXIT_CRITICAL();
    	
    	//if (Antenna_WaitByte(200))
    	//{
    		tmp = GEMPROX_Receive(antenna, uartBase, &antennaStatus, _buff, timeout);
    	
    		//DelayMS(100);	// Delay after changing antenna's baud rate
    	
    		// Check return code
    		if ((tmp & 0xFF) > 0 && antennaStatus == 0)
    			return TRUE;
    	//}
    	
    	return FALSE;
    }
    
    /*BOOL Antenna_RFReset( void )
    {
    	int32_t tmp;
    
    	GEMPROX_Send(uartBase, rfReset, sizeof(rfReset));
    	tmp = GEMPROX_Receive(antenna, uartBase, &antennaStatus, antBuff, 100);
    
    	// Check return code
    	if ((tmp & 0xFF) > 0 && antennaStatus == 0)	
    		return TRUE;
    	
    	return FALSE;
    }
    */
    BOOL Antenna_DeselectCard(uint8_t antenna)
    {
    	int32_t tmp;
    	volatile uint32_t uartBase = ENTRY_ANT_UART_BASE;
    	
    	if (antenna == ENTRY_ANTENNA)
    		uartBase = ENTRY_ANT_UART_BASE;
    	else
    		uartBase = EXIT_ANT_UART_BASE;
    
    	deselectCard[2] = 0x01;	// Set CID
    
    	GEMPROX_Send(uartBase, deselectCard, sizeof(deselectCard));
    	tmp = GEMPROX_Receive(antenna, uartBase, &antennaStatus, antBuff, 100);
    
    	// Check return code
    	if ((tmp & 0xFF) > 0 && antennaStatus == 0)	
    		return TRUE;
    	
    	return FALSE;
    }
    
    // Return 1  : Card is ISO14443-A
    // Return -1 : status error
    // Return -2 : No card
    // Return -3 : SAK not match
    // Return -4 : Reader error
    // Return -5 : No response from reader
    int8_t Antenna_GetFirstTCL(uint8_t antenna, uint32_t *CSN )
    {
    	int32_t tmp;
    	volatile uint32_t uartBase = ENTRY_ANT_UART_BASE;
    	
    	if (antenna == ENTRY_ANTENNA)
    		uartBase = ENTRY_ANT_UART_BASE;
    	else
    		uartBase = EXIT_ANT_UART_BASE;
    
    	//portENTER_CRITICAL();
    	GEMPROX_Send(uartBase, getFirstTCL, sizeof(getFirstTCL));
    	//portEXIT_CRITICAL();
    	
    	//if (UARTWaitByte(uartBase, 100))
    	//if (Antenna_WaitByte(200))
    	//{
    		tmp = GEMPROX_Receive(antenna, uartBase, &antennaStatus, antBuff, 500);
    		//taskEXIT_CRITICAL();
    		
    		if (tmp < 0)
    			return -6;
    			
    		if (antennaStatus == 0xFB)
    			return -2;
    			
    		if (antennaStatus == 0xE0)
    			return -4;
    			
    		// Check status
    		if (antennaStatus != 0)
    			return -1;
    	
    		// Check SAK
    		if (antBuff[9] == SAK_SSID_CARD)
    		{
    			// Get CSN
    			*CSN = antBuff[8] << 24;
    			*CSN |= antBuff[7] << 16;
    			*CSN |= antBuff[6] << 8;
    			*CSN |= antBuff[5];
    
    			return 1;
    		}
    		else
    			return -3;
    	//}
    	//else
    	//	return -5;
    }
    
    BOOL Antenna_GetInfo(uint8_t antenna, uint32_t timeout )
    {
    	int8_t c;
    	c = Antenna_GetNextCardA(antenna, NULL, NULL, timeout);
    
    	if (c == 1 || c == 2)
    		return TRUE;
    
    	return FALSE;
    }
    
    // Get T=CL.
    // This method will only recognise a card once when it first tap in.
    // Return 2 : No card
    // Return 1  : Card is ISO14443-A
    // Return -1 : status error
    // Return -4 : Reader error
    // Return -5 : No response from reader
    // Return -6 : Other error
    int8_t Antenna_GetNextCardA( uint8_t antenna, uint32_t *CSN, uint8_t *sak, uint32_t timeout )
    {
    	int32_t tmp;
    	//uint8_t localUARTINT;
    	
    	volatile uint32_t uartBase = ENTRY_ANT_UART_BASE;
    
    	if (antenna == ENTRY_ANTENNA){
    		uartBase = ENTRY_ANT_UART_BASE;
    		//localUARTINT = ENTRY_ANT_UART_INT;
    	} else {
    		uartBase = EXIT_ANT_UART_BASE;
    		//localUARTINT = EXIT_ANT_UART_INT;
    	}
    //	gateKey = GateTask_enter(gateTask);
    //	gateKey = Task_disable();
    
    	//portENTER_CRITICAL();
    
        //IntDisable(localUARTINT);
        //UARTIntDisable(uartBase, UART_INT_RX | UART_INT_RT);
    	GEMPROX_Send(uartBase, getNextCardA, sizeof(getNextCardA));
    	//UARTIntEnable(uartBase,UART_INT_RX);
    	//IntEnable(localUARTINT);
    	//portEXIT_CRITICAL();
    	
    	//if (UARTWaitByte(uartBase, 100))
    	//if (Antenna_WaitByte(200))
    	//{
    
    	tmp = GEMPROX_Receive(antenna, uartBase, &antennaStatus, antBuff, timeout);
    
    //	Task_restore(gateKey);
    //	GateTask_leave(gateTask, gateKey);
    //	Task_Mode_RUNNING
    
    	//taskEXIT_CRITICAL();
    		//Task_enable();
    		if (tmp < 0)
    		{
    			//DumpString("Antenna Rx Error = ");
    			//DumpHex(tmp);
    			//DumpNewLine();
    			return -6; //Lionel: invalid length
    		}
    			
    		if (antennaStatus == 0xFB)
    			return 2; //Lionel: Timeout (no card)
    			
    		if (antennaStatus == 0xE0)
    			return -4; //Lionel: CID is not free or incorrect
    			
    		// Check status
    		if (antennaStatus != 0)
    			return -1; //Lionel: Invalid Status
    	
    		// Get CSN
    		*CSN = antBuff[8] << 24;
    		*CSN |= antBuff[7] << 16;
    		*CSN |= antBuff[6] << 8;
    		*CSN |= antBuff[5];
    
    		// Check SAK
    		*sak = antBuff[9];
    
    		return 1; //Valid CSN
    	//}
    	//else
    	//	return -5;
    }
    
    
    // Output : [ data 1 ] [ data 2 ] [ data 3 ] [ data... ]
    // Return actual received bytes
    // If return > 0, is the number of data read
    // If parity error, return -3
    // If no EOT received, return -4
    // Return -5 : Other error
    int32_t Antenna_GCRCmd( uint8_t antenna, uint8_t *data, uint8_t len, uint8_t *rcvBuff )
    {
    	int32_t tmp;
    	volatile uint32_t uartBase = ENTRY_ANT_UART_BASE;
    
    	if (antenna == ENTRY_ANTENNA)
    		uartBase = ENTRY_ANT_UART_BASE;
    	else
    		uartBase = EXIT_ANT_UART_BASE;
    
    	GEMPROX_Send(uartBase, data, len);
    	tmp = GEMPROX_Receive(antenna, uartBase, &antennaStatus, rcvBuff+1, 500);
    	*rcvBuff = antennaStatus;
    	return tmp+1;
    	//}
    	//else
    	//	return -5;
    }
    
    // Get T=CL.
    // This method will only recognise a card once when it first tap in.
    // Return 1  : Card is ISO14443-A
    // Return -1 : status error
    // Return -2 : No card
    // Return -3 : SAK not match
    // Return -4 : Reader error
    // Return -5 : No response from reader
    // Return -6 : Other error
    int8_t Antenna_GetNextTCL( uint8_t antenna, uint32_t *CSN )
    {
    	int32_t tmp;
    	
    	volatile uint32_t uartBase = ENTRY_ANT_UART_BASE;
    
    	if (antenna == ENTRY_ANTENNA)
    		uartBase = ENTRY_ANT_UART_BASE;
    	else
    		uartBase = EXIT_ANT_UART_BASE;
    
    	//portENTER_CRITICAL();
    	GEMPROX_Send(uartBase, getNextTCL, sizeof(getNextTCL));
    	//portEXIT_CRITICAL();
    	
    	//if (UARTWaitByte(uartBase, 100))
    	//if (Antenna_WaitByte(200))
    	//{
    		tmp = GEMPROX_Receive(antenna, uartBase, &antennaStatus, antBuff, 500);
    		//taskEXIT_CRITICAL();
    	
    		if (tmp < 0)
    			return -6;
    			
    		if (antennaStatus == 0xFB)
    			return -2;
    			
    		if (antennaStatus == 0xE0)
    			return -4;
    			
    		// Check status
    		if (antennaStatus != 0)
    			return -1;
    	
    		// Check SAK
    		if (antBuff[9] == SAK_SSID_CARD)
    		{
    			// Get CSN
    			*CSN = antBuff[8] << 24;
    			*CSN |= antBuff[7] << 16;
    			*CSN |= antBuff[6] << 8;
    			*CSN |= antBuff[5];
    
    			return 1;
    		}
    		else
    			return -3;
    	//}
    	//else
    	//	return -5;
    }
    //
    //// Encrypt 16-byte number with AES256 with EF.SYM as the encryption key.
    //// inData must be 16 bytes array
    //// outData must be 16 bytes array
    //// Return 1  : Success
    //// Return -1 : status error
    //// Return -2 : APDU status error (not 0x9000)
    //// Return -3 : No response from reader
    //int8_t Antenna_EncWithSYM( uint8_t *inData, uint8_t *outData, uint32_t *status)
    //{
    //	int32_t tmp;
    //
    //	apduAntCmd.cmd = apduEncWithSYM;
    //	apduAntCmd.Lc = 16;
    //	apduAntCmd.Le = 0;
    //	apduAntCmd.data = inData;
    //
    //	//portENTER_CRITICAL();
    //	GEMPROX_SendAPDU(uartBase, apduAntCmd);
    //	//portEXIT_CRITICAL();
    //
    //	//GEMPROX_SendAPDUWithData(uartBase, apduEncWithSYM, sizeof(apduEncWithSYM), inData, 16);
    //
    //	//if (UARTWaitByte(uartBase, 400))
    //	//if (Antenna_WaitByte(500))
    //	//{
    //		tmp = GEMPROX_ReceiveAPDU(uartBase, &antennaStatus, outData, 500, &swStatus);
    //
    //		*status = 0;
    //		*status = antennaStatus<<16;
    //		*status |= swStatus;
    //
    //		// Check status
    //		if (antennaStatus != 0)
    //			return -1;
    //
    //		if (swStatus != 0x9000)
    //			return -2;
    //
    //		return 1;
    //	//}
    //	//return -3;
    //}
    //
    //// pin is 8-byte long variable
    //// Return 1  : Success
    //// Return -1 : status error
    //// Return -2 : APDU status error (not 0x9000)
    //// Return -3 : Other error
    //int8_t Antenna_VerifyCHV( uint8_t *pin )
    //{
    //	int32_t tmp;
    //
    //	apduAntCmd.cmd = apduVerifyCHV;
    //	apduAntCmd.Lc = 8;
    //	apduAntCmd.Le = 0;
    //	apduAntCmd.data = pin;
    //
    //	//portENTER_CRITICAL();
    //	GEMPROX_SendAPDU(uartBase, apduAntCmd);
    //	//portEXIT_CRITICAL();
    //	//GEMPROX_SendAPDUWithData(uartBase, apduVerifyCHV, sizeof(apduVerifyCHV), pin, 8);
    //
    //	//if (Antenna_WaitByte(200))
    //	//{
    //		tmp = GEMPROX_ReceiveAPDU(uartBase, &antennaStatus, antBuff, 200, &swStatus);
    //		if (antennaStatus != 0)
    //			return -1;
    //
    //		// Minimun length is [status] [SW1] [SW3] = 3 bytes
    //
    //		if (swStatus != 0x9000)
    //			return -2;
    //	//}
    //	//else
    //	//	return -3;
    //
    //	return 1;
    //}
    //
    //// Return 1  : Success
    //// Return -1 : status error
    //// Return -2 : APDU status error (not 0x9000)
    //// Return -3 : Other error
    //int8_t Antenna_SelectAID( void )
    //{
    //	int32_t tmp;
    //
    //	//portENTER_CRITICAL();
    //	GEMPROX_SendRawAPDU(uartBase, apduSelectAID, sizeof(apduSelectAID));
    //	//portEXIT_CRITICAL();
    //
    //	//if (Antenna_WaitByte(200))
    //	//{
    //		tmp = GEMPROX_ReceiveAPDU(uartBase, &antennaStatus, antBuff, 200, &swStatus);
    //
    //		if (antennaStatus != 0)
    //			return -1;
    //
    //		// Minimun length is [status] [SW1] [SW3] = 3 bytes
    //
    //		if (swStatus != 0x9000)
    //			return -2;
    //	//}
    //	//else
    //	//	return -3;
    //
    //	return 1;
    //}
    //
    //// First byte of efid must be 0x01 (ignored)
    //// Return 1  : Success
    //// Return -1 : status error
    //// Return -2 : APDU status error (not 0x9000)
    //// Return -3 : Other error
    //int8_t Antenna_SelectEF( uint16_t efid )
    //{
    //	int32_t tmp;
    //
    //	// Change file ID
    //	apduSelectEF[6] = efid & 0xFF;
    //	GEMPROX_SendRawAPDU(uartBase, apduSelectEF, sizeof(apduSelectEF));
    //
    //	//if (Antenna_WaitByte(100))
    //	//{
    //		tmp = GEMPROX_ReceiveAPDU(uartBase, &antennaStatus, antBuff, 100, &swStatus);
    //
    ////		DumpPrintf("antennaStatus = %x \r\n", antennaStatus);
    //		if (antennaStatus != 0)
    //			return -1;
    //
    //		// Minimun length is [status] [SW1] [SW3] = 3 bytes
    //
    ////		DumpPrintf("swStatus = %x \r\n", swStatus);
    //		if (swStatus != 0x9000)
    //			return -2;
    //	//}
    //	//else
    //	//	return -3;
    //
    //	return 1;
    //}
    ///*
    //uint16_t DecodeASN1Length(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint16_t *offset)
    //{
    //	if (byte1 < 128)
    //	{
    //		*offset = 2;
    //		return byte1+2;
    //	}
    //	else if (byte1 == 0x81)
    //	{
    //		*offset = 3;
    //		return byte2+3;
    //	}
    //	else if (byte1 == 0x82)
    //	{
    //		*offset = 4;
    //		return ((byte2 << 8) | byte3)+4;
    //	}
    //	else
    //	{
    //		*offset = 0;
    //		return 0;
    //	}
    //}*/
    //
    //uint32_t DecodeASN1Length(uint8_t *data, uint16_t *offset)
    //{
    //	uint8_t tmp, i;
    //	uint32_t length = 0;
    //
    //	if (*data < 128)
    //	{
    //		*offset = 2;
    //		return *data+2;
    //	}
    //	else
    //	{
    //		tmp = *data - 0x80;
    //		data++;
    //		for (i=0; i<tmp; i++)
    //		{
    //			length <<= 8;
    //			length |= *data;
    //			data++;
    //		}
    //
    //		*offset = 2 + tmp;
    //		return length + *offset;
    //	}
    //}
    //
    //// Read binary. Maximum data len is 255 bytes
    //// Offset is the memory address to start reading
    //// len is the number of byte to read from card
    //// Return > 0  : Success (number of bytes read)
    //// Return -1 : status error
    //// Return -2 : APDU status error (not 0x9000)
    //// Return -3 : Parity error
    //// Return -4 : No EOT received
    //// Return -5 : Other error
    //int32_t Antenna_ReadBinary(uint16_t offset, uint16_t len, uint8_t *buffer)
    //{
    //	int32_t tmp;
    //
    //	if (len>245)
    //		return Antenna_ReadBinary2(offset, len, buffer);
    //
    //	// Change offset hi
    //	apduReadBinary[2] = offset >> 8;
    //	apduReadBinary[3] = offset & 0xFF;
    //
    //	apduAntCmd.cmd = apduReadBinary;
    //	apduAntCmd.Lc = 0;
    //	apduAntCmd.Le = len;
    //	apduAntCmd.data = 0;
    //
    //	//portENTER_CRITICAL();
    //	GEMPROX_SendAPDU(uartBase, apduAntCmd);
    //	//portEXIT_CRITICAL();
    //	/*
    //	// Change offset hi
    //	apduReadBinary[2] = offset >> 8;
    //	apduReadBinary[3] = offset & 0xFF;
    //	apduReadBinary[4] = len;
    //	GEMPROX_SendAPDU(uartBase, apduReadBinary, sizeof(apduReadBinary));
    //	*/
    //	//if (Antenna_WaitByte(200))
    //	{
    //		tmp = GEMPROX_ReceiveAPDU(uartBase, &antennaStatus, buffer, 100, &swStatus);
    //
    //		// Check status
    //		if (antennaStatus != 0)
    //			return -1;
    //
    //		// Minimun length is [status] [data...] [SW1] [SW2] = (len + 3) bytes
    //
    //		if (swStatus != 0x9000)
    //			return -2;
    //	}
    //	//else
    //	//	return -5;
    //
    //	return tmp;
    //}
    //
    //// Read binary. Support data len longer than 255 bytes
    //// Offset is the memory address to start reading
    //// len is the number of byte to read from card
    //// Return > 0  : Success (number of bytes read)
    //// Return -1 : status error
    //// Return -2 : APDU status error (not 0x9000)
    //int32_t Antenna_ReadBinary2(uint16_t offset, int32_t len, uint8_t *buffer)
    //{
    //	int32_t tmp;
    //	int32_t counter = 0;
    //	int32_t arrOffset = 0;
    //	int32_t readLen = 0;
    //
    //	if (len<=245)
    //	{
    //		tmp = Antenna_ReadBinary(offset, len, buffer);
    //		return tmp;
    //	}
    //	else
    //	{
    //		while (len>0)
    //		{
    //			readLen = (len > 245 ? 245 : len);
    //			//DumpPrintf("readLen = %d\r\n", readLen);
    //			readLen = Antenna_ReadBinary(offset, readLen, buffer+arrOffset);
    ////DumpPrintf("---------------------- %d, %d, %d\r\n", len, readLen, arrOffset);
    //			if (readLen <= 0)
    //				return readLen;
    //
    //			offset += readLen;
    //			arrOffset += readLen;
    //			len -= readLen;
    //		}
    //		return arrOffset;
    //	}
    //}
    //
    //// Reaf data group which contain TLV in the beginning of the data, for example DG11, DG3, etc.
    //// First byte of efid must be 0x01 (ignored)
    //// Return > 0  : Success (number of bytes read)
    //// Return -1 : status error
    //// Return -2 : APDU status error (not 0x9000)
    //// Return -3 : Other error
    //int32_t Antenna_ReadDG(uint16_t efid, uint8_t *buffer)
    //{
    //	int32_t tmp;
    //	uint16_t offset, len;
    ////DumpPrintf("Select EF\r\n");
    //	tmp = Antenna_SelectEF(efid);
    //	if (tmp != 1)
    //		return -3;
    //
    ////DumpPrintf("Read binary\r\n");
    //	// Read first 4 bytes: [EF Tag] [ASN1] [(ASN1)] [(ASN1)]
    //	tmp = Antenna_ReadBinary(0, 4, antBuff);
    //	if (tmp < 0)
    //		return -3;
    //
    //	len = DecodeASN1Length(antBuff+1, &offset);
    ////DumpPrintf("Decode len %d\r\n", len);
    //	if (len>0)
    //		return Antenna_ReadBinary2(0, len, buffer);
    //	else
    //		return -3;
    //}
    //
    //// Reaf data group which contain TLV in the beginning of the data, for example DG11, DG3, etc.
    //// First byte of efid must be 0x01 (ignored)
    //// Return > 0  : Success (number of bytes read)
    //// Return -1 : status error
    //// Return -2 : APDU status error (not 0x9000)
    //// Return -3 : Other error
    //int32_t Antenna_ReadDGLen(uint16_t efid, uint8_t *buffer, uint16_t offset, uint16_t len)
    //{
    //	int32_t tmp;
    //	//uint16_t offset, len;
    ////DumpPrintf("Select EF\r\n");
    //	tmp = Antenna_SelectEF(efid);
    //	if (tmp != 1)
    //		return -3;
    //
    ////DumpPrintf("Read binary\r\n");
    //	// Read first 4 bytes: [EF Tag] [ASN1] [(ASN1)] [(ASN1)]
    ////	tmp = Antenna_ReadBinary(0, 4, antBuff);
    ////	if (tmp < 0)
    ////		return -3;
    //
    ////	len = DecodeASN1Length(antBuff[1], antBuff[2], antBuff[3], &offset);
    ////DumpPrintf("Decode len %d\r\n", len);
    //	if (len>0)
    //		return Antenna_ReadBinary2(offset, len, buffer);
    //	else
    //		return -3;
    //}
    //
    //void Antenna_Test( void )
    //{
    //	int32_t tmp;
    //	uint32_t csn;
    //	uint8_t tmpBuff[50];
    //	uint8_t tmpBuff2[16];
    //	uint8_t pin[] = {'P', 'A', 'S', 'S', 'W', 'O', 'R', 'D'};
    //	uint32_t status;
    //
    //
    //	DumpPrintf("Entry Antenna testing...\r\n");
    //
    //	/*
    //	DumpPrintf("Reset RF...\r\n");
    //	tmp = Antenna_RFReset();
    //	DumpPrintf("Return : ");
    //	DumpHex(tmp & 0xFF);
    //	DumpNewLine();*/
    //
    //	DumpPrintf("Get First T=CL\r\n");
    //	tmp = Antenna_GetFirstTCL(&csn);
    //	DumpPrintf("Return : ");
    //	DumpHex(tmp & 0xFF);
    //	DumpNewLine();
    //
    //	DumpPrintf("CSN    : ");
    //	DumpHex(csn >> 24);
    //	DumpHex(csn >> 16);
    //	DumpHex(csn >> 8);
    //	DumpHex(csn);
    //	DumpNewLine();
    //
    //
    //	DumpPrintf("Encryption using EF.SYM\r\n");
    //
    //	for (tmp=0; tmp<16; tmp++)
    //		tmpBuff2[tmp] = tmp;
    //	tmp = Antenna_EncWithSYM(tmpBuff2, tmpBuff, &status);
    //
    //	DumpPrintf("Return        : ");
    //	DumpHex(tmp & 0xFF);
    //	DumpNewLine();
    //	DumpPrintf("Output Data   : ");
    //	if (tmp == 1)
    //		DumpHexArray(tmpBuff, 16);
    //	DumpNewLine();
    //
    //	DumpPrintf("Verify CHV\r\n");
    //	tmp = Antenna_VerifyCHV(pin);
    //	DumpPrintf("Return        : ");
    //	DumpHex(tmp & 0xFF);
    //	DumpNewLine();
    //
    //	DumpPrintf("Select AID\r\n");
    //	tmp = Antenna_SelectAID();
    //	DumpPrintf("Return        : ");
    //	DumpHex(tmp & 0xFF);
    //	DumpNewLine();
    //
    //	DumpPrintf("Select DG11\r\n");
    //	tmp = Antenna_SelectEF(0x0B);
    //	DumpPrintf("Return        : ");
    //	DumpHex(tmp & 0xFF);
    //	DumpNewLine();
    //
    //	DumpPrintf("Read Binary 32 bytes\r\n");
    //	tmp = Antenna_ReadBinary(0, 32, tmpBuff);
    //	DumpPrintf("Return        : ");
    //	DumpHex(tmp & 0xFF);
    //	DumpNewLine();
    //	if (tmp > 0)
    //		DumpHexArray(tmpBuff, tmp);
    //	DumpNewLine();
    //
    //	DumpPrintf("Read DG EF.DG11\r\n");
    //	tmp = Antenna_ReadDG(0x0B, tmpBuff);
    //	DumpPrintf("Return        : ");
    //	DumpHex(tmp & 0xFF);
    //	DumpNewLine();
    //	if (tmp > 0)
    //		DumpHexArray(tmpBuff, tmp);
    //	DumpNewLine();
    //
    //}
    
    /*BOOL Antenna_WaitByte( uint32_t ms )
    {
    	if( xSemaphoreTake( antUARTINTSemaphore, (portTickType)ms/portTICK_RATE_MS ) == pdPASS )
    		return TRUE;
    	return FALSE;
    }*/
    
    void Antenna_FlushRXBuffer( uint8_t antenna )
    {
    	volatile uint32_t uartBase = ENTRY_ANT_UART_BASE;
    
    	if (antenna == ENTRY_ANTENNA)
    		uartBase = ENTRY_ANT_UART_BASE;
    	else
    		uartBase = EXIT_ANT_UART_BASE;
    
    	while(UARTCharsAvail(uartBase))
    		UARTCharGetNonBlocking(uartBase);
    }
    /*
    void UART1IntHandler ( void )
    {
     	unsigned long ulStatus;
    	static signed portBASE_TYPE xHigherPriorityTaskWoken;
    
    	xHigherPriorityTaskWoken = pdFALSE;
    	
        // Get the interrrupt status.
        ulStatus = UARTIntStatus(ENTRY_ANT_UART_BASE, true);
    
        // Clear the asserted interrupts.
        UARTIntClear(ENTRY_ANT_UART_BASE, ulStatus);
    	UARTIntClear(ENTRY_ANT_UART_BASE, UART_INT_PE);
    
        if(UARTCharsAvail(ENTRY_ANT_UART_BASE))
        {
    		xSemaphoreGiveFromISR( antUARTINTSemaphore, &xHigherPriorityTaskWoken );
        }
    	portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
    }*/
    
    // key is 6 bytes
    int8_t Antenna_BlockRead(uint8_t antenna,  uint8_t block, uint8_t *key, uint8_t *dataRead )
    {
    	int32_t tmp;
    
    	volatile uint32_t uartBase = ENTRY_ANT_UART_BASE;
    
    	if (antenna == ENTRY_ANTENNA)
    		uartBase = ENTRY_ANT_UART_BASE;
    	else
    		uartBase = EXIT_ANT_UART_BASE;
    
    	Assign_TransportCode(block);
    
    	mifareLoadKey[13] = *key;
    	key++;
    	mifareLoadKey[14] = *key;
    	key++;
    	mifareLoadKey[15] = *key;
    	key++;
    	mifareLoadKey[16] = *key;
    	key++;
    	mifareLoadKey[17] = *key;
    	key++;
    	mifareLoadKey[18] = *key;
    
    	DumpString("mifareLoadKey: ");
    	DumpHexArray(mifareLoadKey, sizeof(mifareLoadKey));
    	DumpNewLine();
    
    	GEMPROX_Send(uartBase, mifareLoadKey, sizeof(mifareLoadKey));
    
    	tmp = GEMPROX_Receive(antenna, uartBase, &antennaStatus, antBuff, 100 | 0x80000000); //Lionel default as 100
    
    	if (tmp < 0)
    	{
    		return -6; //Lionel: invalid length
    	}
    
    	if (antennaStatus == 0xFB)
    		return -2; //Lionel: Timeout (no card)
    
    	if (antennaStatus == 0xE7)
    		return -4; //Lionel: Command execution error
    
    	// Check status
    	if (antennaStatus != 0)
    		return -1; //Lionel: Invalid Status
    
    	mifareBlockRead[4] = block;
    	mifareBlockRead[7] = 0x10;	// Read 16 bytes
    
    	DumpString("mifareBlockRead: ");
    	DumpHexArray(mifareBlockRead, sizeof(mifareBlockRead));
    	DumpNewLine();
    
    	GEMPROX_Send(uartBase, mifareBlockRead, sizeof(mifareBlockRead));
    
    	tmp = GEMPROX_Receive(antenna, uartBase, &antennaStatus, antBuff, 100 | 0x80000000);  //Lionel default as 100
    //DumpString("tmp: ");
    //DumpHex(tmp);
    //DumpNewLine();
    //DumpHexArray(antBuff, tmp);
    //DumpNewLine();
    	if (tmp >= 16)
    	{
    		// Get data
    		memcpy(dataRead, antBuff, 16);
    		return 1;
    	}
    
    	return -3; //Lionel: Invalid Block Read
    
    //	int32_t tmp;
    //	static uint8_t antBuff[80];
    //	uint8_t status;
    //
    ////	Antenna_MulticardDisable();
    //
    //	mifareBlockRead[1] = 0;		// Key ID
    //	mifareBlockRead[2] = block;		// Sector
    //	mifareBlockRead[3] = *key;		// Key
    //	key++;
    //	mifareBlockRead[4] = *key;		// Key
    //	key++;
    //	mifareBlockRead[5] = *key;		// Key
    //	key++;
    //	mifareBlockRead[6] = *key;		// Key
    //	key++;
    //	mifareBlockRead[7] = *key;		// Key
    //	key++;
    //	mifareBlockRead[8] = *key;		// Key
    //
    //	//portENTER_CRITICAL();
    //	JMY680C_Send(uartBase, mifareBlockRead, sizeof(mifareBlockRead));
    //	//portEXIT_CRITICAL();
    //
    //	//if (UARTWaitByte(uartBase, 100))
    //	//if (Antenna_WaitByte(200))
    //	//{
    //	tmp = JMY680C_Receive(uartBase, &antennaStatus, antBuff, DEFAULT_UART_TIMEOUT_MS);
    //	status = antennaStatus;
    //	tmp = tmp;
    //	//taskEXIT_CRITICAL();
    //
    ////	Antenna_MulticardEnable();
    //
    ////	if (tmp < 0)
    ////		return -6;
    //
    //	// Check status
    //	if (status != mifareBlockRead[0])
    //	{
    //		DumpString("Status: ");
    //		DumpHex(status);
    //		DumpHex(antBuff[0]);
    //		DumpHex(antBuff[1]);
    //		DumpHex(antBuff[2]);
    //		DumpNewLine();
    //		return -2;
    //
    //	}
    //
    //
    //	// Get data
    //	memcpy(dataRead, antBuff, 16);
    //
    //	return 1;
    //	//}
    //	//else
    //	//	return -5;
    }
    
    // key is 6 bytes
    int8_t Antenna_MultiBlockRead(uint8_t antenna,  uint8_t startBlock, uint8_t numOfBlock, uint8_t *key, uint8_t *dataRead )
    {
    	int32_t tmp;
    	int32_t length = (numOfBlock << 4);	// (16 * numOfBlock) bytes
    
    	volatile uint32_t uartBase = ENTRY_ANT_UART_BASE;
    
    	if (antenna == ENTRY_ANTENNA)
    		uartBase = ENTRY_ANT_UART_BASE;
    	else
    		uartBase = EXIT_ANT_UART_BASE;
    
    //	DumpString("Antenna_MultiBlockRead: ");
    //	DumpHex(startBlock);
    //	DumpHex(numOfBlock);
    //	DumpNewLine();
    
    	Assign_TransportCode(startBlock);
    
    	mifareLoadKey[13] = *key;
    	key++;
    	mifareLoadKey[14] = *key;
    	key++;
    	mifareLoadKey[15] = *key;
    	key++;
    	mifareLoadKey[16] = *key;
    	key++;
    	mifareLoadKey[17] = *key;
    	key++;
    	mifareLoadKey[18] = *key;
    
    //	DumpString("mifareLoadKey: ");
    //	DumpHexArray(mifareLoadKey, sizeof(mifareLoadKey));
    //	DumpNewLine();
    
    	GEMPROX_Send(uartBase, mifareLoadKey, sizeof(mifareLoadKey));
    
    	tmp = GEMPROX_Receive(antenna, uartBase, &antennaStatus, antBuff, 300);
    
    //	DumpString("MIFARE load key tmp: ");
    //	DumpHex(tmp);
    //	DumpNewLine();
    
    	if (tmp < 0)
    	{
    		return -6; //Lionel: invalid length
    	}
    
    	if (antennaStatus == 0xFB)
    		return -2; //Lionel: Timeout (no card)
    
    	if (antennaStatus == 0xE7)
    		return -4; //Lionel: Command execution error
    
    	// Check status
    	if (antennaStatus != 0)
    		return -1; //Lionel: Invalid Status
    
    //	DumpHexArray(antBuff, tmp);
    //	DumpNewLine();
    
    	mifareBlockRead[4] = startBlock;
    	mifareBlockRead[7] = length;	// Read (16 * numOfBlock) bytes
    
    //	DumpString("mifareBlockRead: ");
    //	DumpHexArray(mifareBlockRead, sizeof(mifareBlockRead));
    //	DumpNewLine();
    
    	GEMPROX_Send(uartBase, mifareBlockRead, sizeof(mifareBlockRead));
    
    	tmp = GEMPROX_Receive(antenna, uartBase, &antennaStatus, antBuff, 300);
    
    //	DumpString("MIFARE block read tmp: ");
    //	DumpHex(tmp);
    //	DumpNewLine();
    
    //	if (tmp > 0)
    //	{
    //		DumpHexArray(antBuff, tmp);
    //		DumpNewLine();
    //	}
    
    	if (tmp >= length)
    	{
    		// Get data
    		memcpy(dataRead, antBuff, length);
    		return 1;
    	}
    
    	return -3; //Lionel: Invalid Block Read
    //	int32_t tmp;
    //	static uint8_t antBuff[80];
    //	uint8_t status;
    //
    ////	Antenna_MulticardDisable();
    //
    //	mifareMultiBlockRead[1] = 0;		// Key ID
    //	mifareMultiBlockRead[2] = startBlock;		// Start block
    //	mifareMultiBlockRead[3] = numOfBlock;		// Number of block
    //	mifareMultiBlockRead[4] = *key;		// Key
    //	key++;
    //	mifareMultiBlockRead[5] = *key;		// Key
    //	key++;
    //	mifareMultiBlockRead[6] = *key;		// Key
    //	key++;
    //	mifareMultiBlockRead[7] = *key;		// Key
    //	key++;
    //	mifareMultiBlockRead[8] = *key;		// Key
    //	key++;
    //	mifareMultiBlockRead[9] = *key;		// Key
    //
    //	//portENTER_CRITICAL();
    //	JMY680C_Send(uartBase, mifareMultiBlockRead, sizeof(mifareMultiBlockRead));
    //	//portEXIT_CRITICAL();
    //
    //	//if (UARTWaitByte(uartBase, 100))
    //	//if (Antenna_WaitByte(200))
    //	//{
    //	tmp = JMY680C_Receive(uartBase, &antennaStatus, antBuff, DEFAULT_UART_TIMEOUT_MS);
    //	status = antennaStatus;
    //	tmp = tmp;
    //	//taskEXIT_CRITICAL();
    //
    ////	Antenna_MulticardEnable();
    //
    ////	if (tmp < 0)
    ////		return -6;
    //
    //	// Check status
    //	if (status != mifareMultiBlockRead[0])
    //	{
    //		DumpString("Status: ");
    //		DumpHex(status);
    //		DumpHex(antBuff[0]);
    //		DumpHex(antBuff[1]);
    //		DumpHex(antBuff[2]);
    //		DumpNewLine();
    //		return -2;
    //
    //	}
    //
    //
    //	// Get data
    //	memcpy(dataRead, antBuff, numOfBlock << 4);
    //
    //	return 1;
    //	//}
    //	//else
    //	//	return -5;
    //	return -1;
    }
    
    void Assign_TransportCode(uint8_t block)
    {
    	switch (block/4){
    	case 0:
    		memcpy(mifareLoadKey+7, TransportCodeS00, 6);
    		break;
    	case 1:
    		memcpy(mifareLoadKey+7, TransportCodeS01, 6);
    		break;
    	case 2:
    		memcpy(mifareLoadKey+7, TransportCodeS02, 6);
    		break;
    	case 3:
    		memcpy(mifareLoadKey+7, TransportCodeS03, 6);
    		break;
    	case 4:
    		memcpy(mifareLoadKey+7, TransportCodeS04, 6);
    		break;
    	case 5:
    		memcpy(mifareLoadKey+7, TransportCodeS05, 6);
    		break;
    	case 6:
    		memcpy(mifareLoadKey+7, TransportCodeS06, 6);
    		break;
    	case 7:
    		memcpy(mifareLoadKey+7, TransportCodeS07, 6);
    		break;
    	case 8:
    		memcpy(mifareLoadKey+7, TransportCodeS08, 6);
    		break;
    	case 9:
    		memcpy(mifareLoadKey+7, TransportCodeS09, 6);
    		break;
    	case 10:
    		memcpy(mifareLoadKey+7, TransportCodeS10, 6);
    		break;
    	case 11:
    		memcpy(mifareLoadKey+7, TransportCodeS11, 6);
    		break;
    	case 12:
    		memcpy(mifareLoadKey+7, TransportCodeS12, 6);
    		break;
    	case 13:
    		memcpy(mifareLoadKey+7, TransportCodeS13, 6);
    		break;
    	case 14:
    		memcpy(mifareLoadKey+7, TransportCodeS14, 6);
    		break;
    	default:
    		memcpy(mifareLoadKey+7, TransportCodeS15, 6);
    		break;
    	}
    }
    #endif
    

  • HI Amit,

    I able to make the DMA ping pong mode work, where system keep listening to port UART6 for polling package for 9 bytes... and DMA able to continuous looking for 9 bytes of data ...

    #define UART_RXBUF_SIZE 64
    static uint8_t g_pui8RxPingA[UART_RXBUF_SIZE];
    static uint8_t g_pui8RxPingB[UART_RXBUF_SIZE];
    static uint8_t checklengthA = 9;
    static uint8_t checklengthB = 9;

    in initialization:
    uDMAChannelTransferSet(UDMA_CH10_UART6RX | UDMA_PRI_SELECT,
    UDMA_MODE_PINGPONG,
    (void *)(ENTRY_ANT_UART_BASE + UART_O_DR),
    g_pui8RxPingA, checklengthA);
    uDMAChannelTransferSet(UDMA_CH10_UART6RX | UDMA_ALT_SELECT,
    UDMA_MODE_PINGPONG,
    (void *)(ENTRY_ANT_UART_BASE + UART_O_DR),
    g_pui8RxPingB, checklengthB);

    g_pui8RxPingA as buffer for A and length as checklengthA as 9 in default
    g_pui8RxPingB as buffer for B and length as checklengthB as 9 in default

    in interrupt:
    when i know data length from the buffer as longer then 9 i will change the length.
    For example if i get package length in g_pui8RxPingA as 31 i will set new checklengthA as 31 - current checklengthA - checklengthB. Reason as in ping pong mode when set checklengthA the g_pui8RxPingB running.

    But DMA can only get the first g_pui8RxPingA and g_pui8RxPingB for length of 9 and can not continue.

    Is it mean the DMA tranfers the length can not be change? or can not be not the same?
  • Hi Lionel,
    to get all received UART data you can combine the RX complete (RX FIFO interrupt level configured) and Receive Timeout interrupt.

    I'm not sure if I understood your question related to DMA: Is ping-pong mode working but only once? Or is it also working multiple times but you'd like to change the size?
    When using the call ROM_uDMAChannelTransferSet() the last parameter is the number of data items to transfer.

    See also document SPMU367 and the uDMA example:
    C:\ti\TivaWare_C_Series-2.1.0.12573\examples\boards\ek-tm4c123gxl\udma_demo\udma_demo.c

    Regards,
    Marc
  • Hi Marc,

    I copy the DMA from the example and working now.
    I mean if i set both uDMAChannelTransferSet() last parameter to 9 (in UDMA_MODE_PINGPONG mode) it is working continuously as long as the incoming data length as 9. since i am keep checking the receive data length from the messages so when the message come in is longer then 9 bytes i need to change the last parameter right?

    See if i set 9 bytes at last parameter... so it one message of 31 bytes come in and happen at UDMA_PRI_SELECT so the first 9 will be get at first UDMA_PRI_SELECT and 2nd 9 byte will be at UDMA_ALT_SELECT, 3rd will be at UDMA_PRI_SELECT again. The last one left 4 bytes only BUT the next ping pong mode will be 9 byte at UDMA_ALT_SELECT which will never be achieve. so i must change the last one to 4 byte to ensure the interrupt able to trigger. But this fail.
  • Hi Marc,

    BTW i do try another way... First i just disable uDMA, run normal FIFO to get the first 16 bytes.... after i see the length coming in as more then 9 bytes. i start a uDMA with uDMAChannelTransferSet() with UDMA_PRI_SELECT and UDMA_MODE_BASIC for next 15 bytes (get first 16 bytes in FIFO [15+16 => 31]). Theoretically working good BUT it miss 5 bytes in between (mean first 16 bytes OK ... 5 byte gone ... and sub sequence 10 bytes is OK). I think is due to when start up DMA the UART miss the UART DATA.

    So I really hope able to change the last parameter of uDMAChannelTransferSet() which is the number of data items to transfer and both UDMA_PRI_SELECT and UDMA_ALT_SELECT can be different.

    Thank & Best Regards,
    Lionel
  • Hi Marc,

    Can explain more on your message on "to get all received UART data you can combine the RX complete (RX FIFO interrupt level configured) and Receive Timeout interrupt."

    the API to use as?

    Thank & Best Regards,
    Lionel
  • Hi Lionel,
    instead of changing the uDMA, you could also use the timeout interrupt of the UART to collect the last couple of bytes (ROM_UARTIntEnable with UART_INT_RT flag).

    EDIT: Size and address increment of data items cannot be changed. However with the TransferSet function you define the number of data items to transfer which should be no problem to change. But how do you know when to change this? The RX timeout interrupt should be the safe way of detecting the end of the message.

  • Hi Marc,

    I could i know how long is the UART Receive Timeout? Or how can i change?

    Thank & Best Regards,
    Lionel
  • The receive timeout interrupt is asserted when the receive FIFO is not empty, and no further data
    is received over a 32-bit period when the HSE bit is clear or over a 64-bit period when the HSE bit
    is set.
    Note: HSE refers to the High-Speed Enable bit (see also Tiva datasheet).
    The receive timeout interrupt is cleared either when the FIFO becomes empty through reading
    all the data (or by reading the holding register), or when a 1 is written to the corresponding bit in the
    UARTICR register.

    So basically you receive the timeout when you do not read the data which should only happen if the buffer is not completely full which again only happens at the message's end. The timeout is fixed to the 32-bit period.
  • HI Marc,

    I try what you mean by receive time out. i just use in normal UART ISR interrupt FIFO to receive 16 bytes by reading 16 times when i receive UART_INT_RX from API UARTIntStatus(). the next will wait for UART_INT_RT (timeout) from API UARTIntStatus() and i only get the last 8 bytes.
    This also mean that I miss the 7 bytes after the first 16 bytes.

    Thank & Best Regards
    Lionel...

    PS... is 1134 pm now....
  • What works fine for me is to use the UART without the FIFO, and use a circular buffer to store the data, which is updated within the RX receive data interrupt(although, I read directly from the registers, not using the (ROM)API). I never missed any data using 2 UART's at 56K baud rate.

    But, maybe one thing, you're using an RTOS, so maybe you have a problem with the UART interrupt priority level. When the program misses data bytes, check, when debugging, if you have an interrupt pending on one of the UART's.

  • Lionel,
    what if you move on from your previous implementation with the pingpong DMA configuration?
    There you are fast enough to catch all bytes and when there are only the last 4 bytes in FIFO you can collect those with the timeout interrupt.
  • Hi Marc,

    From the first day when i start to use TI i am using RTOS. I try to disable all other Interrupt only the UART 6 with priority as 0 for this 56Kbaud without FIFO i only get the first 16 bytes (by API UARTCharGetNonBlocking() )

    in Interrupt when receive UART_INT_RX i instead of using API UARTCharGetNonBlocking() i change to check on ((HWREG(ENTRY_ANT_UART_BASE + UART_O_FR) & UART_FR_RXFE) == 0)
    store (HWREG(ENTRY_ANT_UART_BASE + UART_O_DR)) & 0xFF; into my own FIFO buffer seem to be working for one port... will try for 3 ports after our lunch time (SGP time)..

    Hope this way can clear all my issue. Will update you after confirm later today.

    Thank & Best Regards
    Lionel
  • Hi Marc,
    I check with using non API direct registers ((HWREG(ENTRY_ANT_UART_BASE + UART_O_FR) & UART_FR_RXFE) == 0) and (HWREG(ENTRY_ANT_UART_BASE + UART_O_DR)) . the issue still there as the first 16 bytes correct... 7 bytes missing ... next 8 bytes are correct.

    ANd very important i only activate 1 interrupt that is this UART6 other 2 disabled.

    Please advice.

    Lionel
  • Lionel,

    When you enable the UART(UARTEnable()), the FIFO is also enabled by default, so you must disable the FIFO(UARTFIFODisable()) after enabling the UART(when using the API), or else the FIFO will still be used.

    In the UART interrupt, no need to check if there's a byte in the buffer as the receive interrupt has triggered.

    I use this with the Modbus protocol, as timing is important, the FIFO can not be used. I also update the firmware via the RS485 serial line, works really robust.

    If you still miss some bytes, then try using the FIFO, but within the interrupt, always read the byte(s) until the FIFO is empty in a loop(thus blocking).
  • HI Marc,


    Now with registers way, I manage to get most of the bytes but i try 31 bytes information in between lot of 9 bytes information. 1 out 10 lost some bytes (5 to 7 bytes after first 16 bytes)... although is far better then before.

    Understand for your first statement. Will do so and hope will further improve the error rate.

    Thank & Best Regards,
    Lionel
  • Hi Marc,

    Do you mean by ...
    Initialization: (ENTRY_ANT_UART_BASE = UART_6)
    // Configure the UART
    UARTEnable(ENTRY_ANT_UART_BASE);
    // Configure the UART0 for 115,200, 8-N-1 operation.
    UARTConfigSetExpClk(ENTRY_ANT_UART_BASE, SysCtlClockGet(), baudrate, ENTRY_ANT_UART_CONFIG);

    UARTFlowControlSet(ENTRY_ANT_UART_BASE, UART_FLOWCONTROL_NONE);
    UARTIntEnable(ENTRY_ANT_UART_BASE, UART_INT_RX);
    UARTFIFODisable(ENTRY_ANT_UART_BASE);
    IntEnable(ENTRY_ANT_UART_INT);

    Interrupt Service Routine:
    void Entry_Uart_rxIntHandler(void)
    {
    static unsigned long status;
    static u8 data;
    status=UARTIntStatus(ENTRY_ANT_UART_BASE,UART_INT_RX);
    UARTIntClear(ENTRY_ANT_UART_BASE,UART_INT_RX);
    UARTRxErrorClear(ENTRY_ANT_UART_BASE); // should this be here?

    if(status&UART_INT_RX)
    {
    do{
    data=(HWREG(ENTRY_ANT_UART_BASE + UART_O_DR)) & 0xFF;
    if (data != 0xFF){
    EntryUartRxIntBuf[EntryRxFifoHead]=data;
    EntryRxFifoHead++;
    if(EntryRxFifoHead>ANT_RX_FIFO_SZ){
    EntryRxFifoHead=0;
    }
    }
    } while (data != 0xFF);
    }
    }

    is this correct?
  • Hi Lionel,

    This really shouldn't be a problem, I read constantly different payloads from many slaves, without loosing(to my knowledge) any data at 57K baud(I'm pushing the limits just to test it, but will bring it later down to 9200). This while updating a display(with a FT800 chip) via SPI at 4MHz, another serial line with a different protocol, logging data, etc.

    In time critical sections, I mostly use the direct register manipulation approach, it's always a little faster, but also easier to make a mistake :)
  • Sorry missed your reply, although I enable the UART at the end of the configuration, and then disable the FIFO.

    Then in the loop(after checking if for the RX receive), I simply check the FIFO empty bit like this;

    if(ui32Status & UART_INT_RX)
    {
    //
    // Place characters in the buffer until no more char are available.
    //
    while(!(HWREG(UART1_BASE + UART_O_FR) & UART_FR_RXFE))
    {
    //
    // Put the char in the buffer.
    //
    EBUSUART_BufferWrite((uint16_t)HWREG(UART1_BASE + UART_O_DR));
    }
    }
  • But this is when using the FIFO, when disabling the UART FIFO, there can only be one byte anyway in the UART data buffer.
  • FOr intterrupt.. if my UART6 and UART2 having same priority. if i am in UART6 ISR. RTOS will wait till ISR done and serve UART2 ISR right?
    The UART1 who serve Host only at priority of 7.
  • Yes, if no other higher priority interrupts(or tasks) are pending...
  • HI Marc & Marc,

    My data still have lost.

    For message having data length of 9 bytes. None lost at all.

    For message having data length of 31 bytes. i found quite consistently of 1 in 20 times have lost bytes (5 to 7 bytes lost after first 16 bytes).

    For message having data length of 45 bytes. I found quite consistently of 1 in 5 times have lost bytes (5 to 10 bytes lost after first 16 bytes).

    The issue happen in both case with our without FIFO. FIFO at level of 4/8.

    I have 4 questions:

    1. If I am using Just interrupt UART_INT_RX without checking UART_FR_RXFE,and FIFO Diabled. I can only get the first 2 bytes.

    2. If I am using Just interrupt UART_INT_RX with checking UART_FR_RXFE,and FIFO Diabled. I can get all the bytes of data.

    3. What is the different between API with ROM and without ROM, for example ROM_UARTEnable() and UARTEnable.

    4. How can i convert from TI_RTOS to same as your method (not by RTOS). My data MUST be robust as the slave will only send once.

    Thank & Best Regards

    Lionel

  • Hi Lionel,

    The API calls starting with ROM ensures that driverlib/TivaWare is used that resides within the ROM memory of the device. Otherwise the driverlib would be taken out of the Flash.

    If you did not apply your own changes to the driverlib/TivaWare, the executed actions should be the same.

    The RXFE field helps you to see if there is rx data available.

    When not using FIFO, there should be no difference between the bytes..

    • Are you still using DMA to read out your data?
    • Did you check all priorities you have in your system?


    If you send me your code (you also have my email contact) I can get a better understanding of it.

    Regards,
    Marc

  • Hi Marc,

    After your email guide and some time adjustment on the task timing. the problem already solved.

    Thank for your help .

    Thank & Best Regards,

    Lionel

  • BTW how to close this issue?
  • Hi Lionel,
    glad to hear that you could solve it!

    By flagging the answer that was most helpful to you as "Verified Answer" you can mark the whole thread as 'answered'. This is done by the green button which is available under each posting.

    Regards,
    Marc