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.

Uart0 problem, interrupt driven, tm4c123gxl launch pad

Genius 3300 points

1. i have written a code for uart0 on tm4c123gxl lauchpad. When I use polled method it works fine & when i have changed it to interript methof for receive it dont work.

2. I am using driverlib v2.1.1.71 with keil 5.13.0.0.

3. I have put a red led flag in case of receive error. I have sent bytes from PC to launchpad. On sending multiple bytes from keyboard only twice code goes ISR & invert led indicating receive error.

4. code is below:

volatile uint8_t rx_data , rx_flag;

void uart0_isr(void)
{
    uint32_t status;
    
/* get int status */    
    status = UARTIntStatus(UART0_BASE , UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE);
    
/* clear int flags */
    UARTIntClear(UART0_BASE , UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE);
    
/* if any error then flush tha data */
    if(status & (UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE))
    {
    /* flush the data */
        (void)( HWREG(UART0_BASE + UART_O_DR) );
        RED_LED_INVERT();
    }   
/* read the correct data */    
    else
    {
        rx_data = HWREG(UART0_BASE + UART_O_DR);
        rx_flag = 1;
    }    
    
}    



void uart_0_init(void) 
{     
    uint32_t ready_count;

/* enable uart0 */    
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_UART0)))  &&  (--ready_count));
    if(0U == ready_count)   /* if periph not ready take action */
    {
    }    
    
/* enable gpioa */      
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA)))  &&  (--ready_count));
    if(0U == ready_count)   /* if periph not ready take action */
    {
    }    
    
/* mix muxing */
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0);
    
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE,  GPIO_PIN_1);
    
/* diable uart */    
    UARTDisable(UART0_BASE);
    
/* configure uart */
    UARTClockSourceSet(UART0_BASE , UART_CLOCK_SYSTEM);
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));
    UARTFlowControlSet(UART0_BASE , UART_FLOWCONTROL_NONE);
    
/* disable all int, whatever enabled earlier */
    UARTIntDisable(UART0_BASE , UART_INT_9BIT | UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RT
                  | UART_INT_TX | UART_INT_RX | UART_INT_DSR | UART_INT_DCD | UART_INT_CTS | UART_INT_RI);
    
/* clear all int flags whatever set earlier */    
    UARTIntClear(UART0_BASE , UART_INT_9BIT | UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RT
                  | UART_INT_TX | UART_INT_RX | UART_INT_DSR | UART_INT_DCD | UART_INT_CTS | UART_INT_RI);
                  
/* register interrupts */                 
    UARTIntRegister(UART0_BASE , uart0_isr);
    
/* enable required ints i.e overrun, break, parity & framing */    
    UARTIntEnable(UART0_BASE , UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE);

/* enable uart */
    UARTEnable(UART0_BASE);
    
/* echo back */
    while(1)
    {
        while(0U == rx_flag);
        rx_flag = 0U;
        UARTCharPut(UART0_BASE , rx_data);
    
    }    

   
    
} /* function ends here */    

  • Hello Vindhyachal,

    Where has the Receive interrupt or the Receive Time Out interrupt been enabled?

    Regards
    Amit
  • 1. Ahhhh!!!! Stupid mistake.

    2. I modified code like this as below. One strange thing is when from console/PC I try to type like "tm4c miController",

    I receive nothing back on console unless capital C in string is reached. Now as I keep typing forward I start receive last digit.

    For example:

    Type: tm4c miContoller

    Rx:                   tm4c miController

    Earlier i thought it could be due to FIFO. So disabled that also, but still same problem.

    On console side I have same setting like 8bits, 1stop, 115200, no hardware control.

    3. What is receive timeout error? If I enable this MCU keep on going in this error.

    volatile uint8_t rx_data , rx_flag;
    
    void uart0_isr(void)
    {
        uint32_t status;
    /* get int status */    
        status = UARTIntStatus(UART0_BASE , UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RX);
        
    /* clear int flags */
        UARTIntClear(UART0_BASE , UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RX);
    
    /* if any error then flush tha data */
        if(status & (UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE))
        {
            
        /* flush the data */
            (void)( HWREG(UART0_BASE + UART_O_DR) );
             RED_LED_INVERT();
        }   
    /* read the correct data */    
        else
        {
            rx_data = HWREG(UART0_BASE + UART_O_DR);
            UARTCharPut(UART0_BASE , (uint8_t)rx_data );
            rx_flag = 1;
        }    
        
    }    
    
    
    
    
    void uart_init(void) 
    {     
        uint32_t ready_count;
    
    /* enable uart0 */    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_UART0)))  &&  (--ready_count));
        if(0U == ready_count)   /* if periph not ready take action */
        {
        }    
        
    /* enable gpioa */      
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA)))  &&  (--ready_count));
        if(0U == ready_count)   /* if periph not ready take action */
        {
        }    
        
    /* mix muxing */
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0);
        
        GPIOPinConfigure(GPIO_PA1_U0TX);
        GPIOPinTypeUART(GPIO_PORTA_BASE,  GPIO_PIN_1);
        
    /* diable uart */    
        UARTDisable(UART0_BASE);
        
    /* configure uart */
        UARTClockSourceSet(UART0_BASE , UART_CLOCK_SYSTEM);
        UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));
        UARTFlowControlSet(UART0_BASE , UART_FLOWCONTROL_NONE);
        
    /* disable all int, whatever enabled earlier */
        UARTIntDisable(UART0_BASE , UART_INT_9BIT | UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RT
                      | UART_INT_TX | UART_INT_RX | UART_INT_DSR | UART_INT_DCD | UART_INT_CTS | UART_INT_RI);
        
    /* clear all int flags whatever set earlier */    
        UARTIntClear(UART0_BASE , UART_INT_9BIT | UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RT
                      | UART_INT_TX | UART_INT_RX | UART_INT_DSR | UART_INT_DCD | UART_INT_CTS | UART_INT_RI);
                      
    /* register interrupts */                 
        UARTIntRegister(UART0_BASE , uart0_isr);
        
    /* enable required ints i.e overrun, break, parity & framing */    
        UARTIntEnable(UART0_BASE , UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RX);
    
    /* */
        UARTFIFODisable(UART0_BASE);
        
    /* enable uart */
        UARTEnable(UART0_BASE);
        
    /* echo back */
        while(1)
        {
        
        }    
    
       
        
    } /* function ends here */    

  • Hello VT

    Receive TO Interrupt is received when there is data in the RXFIFO that has not been read for a duration of time as specified in the data sheet. The corrective action is to read the data.

    Make sure that the UART peripheral is reset before doing any configuration. This will ensure that there is no data in the FIFO. Also note that UARTEnable sets the FIFO back ON. Hence you would need to replace the call with the direct enable to the UARTCTL register.

    Regards
    Amit
  • Hi Amit,

    It is working now. I have also reset the peripheral like in code below.

    void uart0_isr(void)
    {
        uint32_t status;
    /* get int status */    
        status = UARTIntStatus(UART0_BASE , UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RX);
        
    /* clear int flags */
        UARTIntClear(UART0_BASE , UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RX);
    
    /* if any error then flush tha data */
        if(status & (UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE))
        {
            
        /* flush the data */
            (void)( HWREG(UART0_BASE + UART_O_DR) );
             RED_LED_INVERT();
        }   
    /* read the correct data */    
        else
        {
            rx_data = HWREG(UART0_BASE + UART_O_DR);
            UARTCharPut(UART0_BASE , rx_data );
        }    
        
    }    
    
    
    void uart_init(void)
    {
        uint32_t ready_count;
    
    /* enable uart0 */    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_UART0)))  &&  (--ready_count));
        if(0U == ready_count)   /* if periph not ready take action */
        {
        }    
        
    /* enable gpioa */      
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA)))  &&  (--ready_count));
        if(0U == ready_count)   /* if periph not ready take action */
        {
        }    
        
    /* mix muxing */
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0);
        
        GPIOPinConfigure(GPIO_PA1_U0TX);
        GPIOPinTypeUART(GPIO_PORTA_BASE,  GPIO_PIN_1);
        
    /* diable uart */    
        UARTDisable(UART0_BASE);
        
    /* reset the peripheral */
        SysCtlPeripheralReset(SYSCTL_PERIPH_UART0);
        while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_UART0)))  &&  (--ready_count));
        if(0U == ready_count)   /* if periph not ready take action */
        {    
        }
        
    /* configure uart */
        UARTClockSourceSet(UART0_BASE , UART_CLOCK_SYSTEM);
        UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200U, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));
        UARTFlowControlSet(UART0_BASE , UART_FLOWCONTROL_NONE);
        
    /* disable all int, whatever enabled earlier */
        UARTIntDisable(UART0_BASE , UART_INT_9BIT | UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RT
                      | UART_INT_TX | UART_INT_RX | UART_INT_DSR | UART_INT_DCD | UART_INT_CTS | UART_INT_RI);
        
    /* clear all int flags whatever set earlier */    
        UARTIntClear(UART0_BASE , UART_INT_9BIT | UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RT
                      | UART_INT_TX | UART_INT_RX | UART_INT_DSR | UART_INT_DCD | UART_INT_CTS | UART_INT_RI);
                      
    /* register interrupts */                 
        UARTIntRegister(UART0_BASE , uart0_isr);
        
    /* enable required ints i.e overrun, break, parity & framing */    
        UARTIntEnable(UART0_BASE , UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RX);
    
    /* */
        UARTFIFODisable(UART0_BASE);
        
    /* enable uart */
        HWREG(UART0_BASE + UART_O_CTL) |= (UART_CTL_UARTEN | UART_CTL_TXE | UART_CTL_RXE);
    }

  • Hello VT

    That is a good idea to reset the peripheral before use. However the sequence can be simplified as follows

    SysCtlPeripheralDisable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralReset(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    while( (!(SysCtlPeripheralReady(SYSCTL_PERIPH_UART0))) && (--ready_count));
    if(0U == ready_count) /* if periph not ready take action */
    {
    }

    In fact this change is going to be made to the driverlib user guide examples

    Regards
    Amit