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.

Problem while reading the UART in Tiva C series MCU

Hello Every One,


I am trying to send AT commands to CDMA modem(Telit) and receive the response from it through UART interface.

MCU: Tiva C series (TM4C123GH6PMI)

Interface for communication: UART

Problem: I am able to send the AT command and also receive the response in buffer, but I can receive only 16 bytes of data not more than that.I also try to disable and enable the FIFO after read first 16 bytes of data then also I cant read the rest of bytes and it will get stuck in UARTCharsAvail() API functio of UART.

Command : "AT+CGMM\r\n"

Actual Response: "AT+CGMM\r\r\nCE910-DUAL\r\n"

Received Response: "AT+CGMM\r\r\nCE910-" (only 16 bytes)

Could you please help me to resolve this issue.

thanks in advance

Sreenivasa S

  • Hello Sreeni

    The FIFO is 8 locations deep. Since you are able to receive 16-bytes it would mean that there is nothing wrong in the FIFO. For checking why the remaining bytes are not being received, can you put a blocking read condition such that till all expected number of bytes are not received the CPU remains in a while loop.

    Also a code post would be useful to see how the data is being read.

    Regards

    Amit

  • Hi Amit,

    Thanks for earliest reply..

    I am using Keil as my IDE and the I got the libraries from TI web sight. 

    My UART initialization is as below:

    void UART_INIT (void)
    {
    static int i;
    //Data1[30];

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);// To enable the CDMA modem

    GPIOPinConfigure(GPIO_PC4_U1RX);
    GPIOPinConfigure(GPIO_PC5_U1TX);

    GPIOPinTypeUART(GPIO_PORTC_BASE, 0x30);
    GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, 0x40);

    //UARTClockSourceSet(UART1_BASE, UART_CLOCK_PIOSC);

    UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 115200,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));

    // Enable the UART.
    UARTEnable(UART1_BASE);

    /*Turn ON the PA6*/
    GPIOPinWrite(GPIO_PORTA_BASE, 0x40,0x40);
    for(i = 0; i <= 100000; i++);
    /*Turn OFF the PA6*/
    GPIOPinWrite(GPIO_PORTA_BASE, 0x40,0);
    for(i = 0; i <= 500000; i++);

    and below is my code to receive the response.

    while(UARTCharsAvail(UART1_BASE) != FALSE){

    DataBuffer[i] = UARTCharGetNonBlocking(UART1_BASE);

    i++;

    }

     

    Thanks 

    Sreenivasa S

  • Hello Sreenivas,

    Change the loop as below to see if all bytes are being recieved

    while(i != CHAR_COUNT){

    DataBuffer[i] = UARTCharGet(UART1_BASE);

    i++;

    }

    Regards

    Amit

  • Hi Amit,

    I tried like this earlier and also now I put CHAR_COUNT =50 and tried,

    but after I read 16 bytes of data it is get stuck in the below while loop to check the availability of char.

    // Wait until a char is available.
    //
    while(HWREG(ui32Base + UART_O_FR) & UART_FR_RXFE)
    {
    }

    and it will never come out of this loop.

     

    Thanks

    sreenivasa

  • Hi Amith,

    Apart from our own board, I tried in stellaris launch pad. There I am losing some data...

    my code is as follows

    char get_char[38]; // global declaration

    int main(void) {

    int i,j;

    static char send[38] = "Dexcel Electronics Designs Pvt Ltd...";

    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_OSC | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16_3MHZ);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART5);

    GPIOPinConfigure(GPIO_PC4_U4RX);

    GPIOPinConfigure(GPIO_PE4_U5RX);
    GPIOPinConfigure(GPIO_PC5_U4TX);

    GPIOPinConfigure(GPIO_PE5_U5TX);

    GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    GPIOPinTypeUART(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5);

    UARTConfigSetExpClk(UART4_BASE, SysCtlClockGet(), 115200,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));

    UARTConfigSetExpClk(UART5_BASE, SysCtlClockGet(), 115200,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));

    UARTEnable(UART4_BASE); UARTEnable(UART5_BASE);

    i = 0;

    while(send[i] != '\0')
    {
    UARTCharPut(UART4_BASE, send[i]);
    i++;
    }

    i = 0;

    while(send[i] != '\0')

    {
    get_char[i] = UARTCharGet(UART5_BASE);
    i++;
    }

    while(1);

    }

    Please help me..

    OUTPUT:

    1) For 115200 baud rate - get_char contains "Dexcel Electroniesigns Pvt Ltd..." // missing chars - "cs D"

    1) For 9600 baud rate - get_char contains "Dexcel ElectroniDesigns Pvt Ltd..." // missing chars - "cs "

  • Hello Sreeni,

    Try the following change

    while(send[i] != '\0')
    {
    UARTCharPut(UART4_BASE, send[i]);
    get_char[i] = UARTCharGet(UART5_BASE);
    i++;
    }

    Regards

    Amit

  • Hi Amith,

    Thanks for solution. It works fine now....

    So should not put any delay in between send and receive I guess...

    But in our board I cant able to get it....Anyway I have some other work to be done at priority after that I will look into this..

    Thanks

    Sreenivasa S 

  • Hello Sreeni,

    My point is that there is a Overrun Interrupt happening. You can always check the UARTFR register to see if Overrun Flag is set or not. The same is available along with other flags in the UARTDR register from bits 8 to 11.

    Regards

    Amit

  • Hi Amit, 

    I`m sorry if i`m posting this in the wrong place. 

    But i`m getting the same problem as Sreeni first described. I´m not being able to read more than 16 bits. As you said, i paid attention to the registers and indeed:

     

    UART_RIS_OERIS 1 UART Overrun Error Raw Interrupt Status

    So how can I solve this issue?

    Here is the code:

    #include <stdint.h>
    #include <stdbool.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/uart.h"
    
    int main(void){
    	SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    
    	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    
    	GPIOPinConfigure(GPIO_PA0_U0RX);
    	GPIOPinConfigure(GPIO_PA1_U0TX);
    
    	GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0|GPIO_PIN_1);
    	UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
    	UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, UART_CONFIG_WLEN_8|UART_CONFIG_PAR_NONE|UART_CONFIG_STOP_ONE);
    	int i = 0;
    	char str[32];
    	while(1){
    		while(UARTCharsAvail(UART0_BASE)){
    			str[i] = UARTCharGet(UART0_BASE);
    			i++;
    			SysCtlDelay(900000);
    			GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 2);
    			SysCtlDelay(900000);
    			GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);
    			}
    		i = 0;
    	}
    }
    

    Best regards

    Adriano

     

  • Hello Adriano

    OK. Let me check this on my LaunchPad, but I am fairly certain that it would get more than 16 bytes. Also can you confirm that this is the only code in your project?

    Regards
    Amit
  • Hello Amit,

    That's not all of the code. After that i'll just analyse the string and execute some functions that aren't written yet.  Here is the code:

    #include <stdint.h>
    #include <stdbool.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/uart.h"
    
    int main(void){
    	SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    
    	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    
    	GPIOPinConfigure(GPIO_PA0_U0RX);
    	GPIOPinConfigure(GPIO_PA1_U0TX);
    
    	GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0|GPIO_PIN_1);
    	UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
    	UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, UART_CONFIG_WLEN_8|UART_CONFIG_PAR_NONE|UART_CONFIG_STOP_ONE);
    	int i = 0, k, xrml, yrml, irml;
    	float x, y, z, f, s;
    	char str[32];
    	while(1){
    		while(UARTCharsAvail(UART0_BASE)){
    			str[i] = UARTCharGet(UART0_BASE);
    			i++;
    			SysCtlDelay(900000);
    			GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 2);
    			SysCtlDelay(900000);
    			GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);
    			}
    		if((str[0] == 'G')){
    			for(k=2;k<i;++k){			//retrieve values from the string
    				if(str[k]=='X'){
    					x = atof(&str[k+1]);
    				}
    				else if(str[k]=='Y'){
    					y = atof(&str[k+1]);
    				}
    				else if(str[k]=='Z'){
    					z = atof(&str[k+1]);
    				}
    				else if(str[k]=='F'){
    					f = atof(&str[k+1]);
    				}
    				else if(str[k]=='S'){
    					s = atof(&str[k+1]);
    				}
    				// execute moviment functions
    			}
    			else if(str[0] == 'P'){
    				xrml = atoi(&str[2]);
    				irml = 0;
    				while(str[irml] != ','){
    					++irml;
    				}
    				yrml = atoi(&str[irml+1]);
    				if(str[1] == 'U'){
    					// execute moviment functions					
    				}
    				else if(str[1] == 'D'){
    					// execute moviment functions
    				}
    
    			}
    		i = 0;
    	}
    
    Regards
    Adriano

  • Hello Adriano.

    I checked your program and the Lint tool showed missing closing braces"}" and misplaced else-if statement. I ended up correcting to get compilation errors sorted. Now as many times I place a character the Red LED goes ON and definitely did it 40 times to get the LED running 40 times. Also something potentially hazardous about the code was

    while(UARTCharsAvail(UART0_BASE))
    {
    str[i] = UARTCharGet(UART0_BASE);
    i++;
    SysCtlDelay(900000);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 2);
    SysCtlDelay(900000);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);
    }

    If the input stream is faster than the loop then the code execution will remain in the while loop and i++ will go above the string length of 32 to cause corruption of the memory beyond the size of the variable str.
    You may want to take this into account as well.

    Regards
    Amit
  • Forum should "well" note the "above/beyond" skills & effort of vendor's Amit.     Bravo!

    Not too many would, "dig so deep as to detect - then "fix" - an issue, "not yet recognized nor reported" by poster!     Outstanding!

  • Hello Amit, 

    Thank you very much for your reply.

    I took in consideration what you said, and performed the changes needed. But i´m still not being able to get more than 16 characters in the string. 

    I´ll describe briefly what i´m doing: 

    I´m connecting to the device using Putty. When I type a letter and press enter, one at a time, the string is successfully completed. But when i type, let´s say, 20 characters and press enter afterwards, only 16 of the 20 are stored.

    Best regards

    Adriano

  • Hello Adriano,

    When the user writes to the serial port, each character gets transmitted. I am not sure if PuTTY does that or not (I use TeraTerm). So if I press 20 characters then inspect the string, then only the last one exist on account of the larger while loop.

    What you would need to be doing is to use the cmdline utility from TivaWare to be able to parse commands. That is there in some of the examples and will give you better results.

    Regards
    Amit
  • Hi Amit,

    Do you mean if the input stream is longer than the loop ? I see that if it is faster, the code still can catch the data even if the while loop is slow.

    Regards,

    Ahmed

  • Hello Ahmed,

    No, I meant the delay in the while loop.

    Regards
    Amit
  • Hello Amit,

    I think in all cases if the stream is longer than 32 the loop will continue ! There is nothing to stop the loop as long as data is coming in UART.

    Regards,

    Ahmed

  • Hello Ahmed

    Not necessarily. The while loop has delay long enough that the buffer fill in rate would be larger than buffer read out rate. This would eventually cause FIFO overflow.

    Regards
    Amit