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.

Launchpad misses UART Recieve Timeout interrupt

Hi !

I'am working with EM-LM4F120XL Rev A. My current aim is interrupt driven communiation via UART0 (Modbus© protocol) with FIFO. I`am using 3 UART interrupt RX, TX complete (RX/TX FIFO interrupt level select configured to default = 1/2 -> 8 bytes) and Recieve Timeout interrut. I use Recieve Timeout interrut to detect Modbus end of message event. I've used this method with LPC's Cortex -M0, so I just ported source code and rewrote some MCU-specific features. When I started to debug, I've noticed that:

if  ( UART message length ) == N*(FIFO interrupt level select register value) then Recieve Timeout interrut is not triggered.

N - integer

#define    RX_TOUT_INT                (1<<6)
#define    RX_INT                    (1<<4)
#define    TX_INT                    (1<<5)

#define RX_FIFO_EMPTY            (1<<4)
#define TX_FIFO_FULL            (1<<5)

//============================================================================================

static uint32_t FUARTStatus;

//============================================================================================


void Init_UART (){
    
    SYSCTL_RCGCUART_R |= (1<<0);                    //Enable and provide a clock to UART module 0 in Run mode
    SYSCTL_RCGCGPIO_R |= (1<<0);                    //Enable and provide a clock to GPIO Port A in Run mode

    __NOP();
    __NOP();

    GPIO_PORTA_DEN_R |= (1<<0) | (1<<1);
    GPIO_PORTA_AFSEL_R |= (1<<0) | (1<<1);            //pin A.0 and A.1 function as a peripheral signal UART0 RX/TX
    GPIO_PORTA_DR4R_R |= (1<<0) | (1<<1);            //pin A.0 and A.1 function with 4 mA drive load

    GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R & 0xFFFFFF00)+0x00000011;            //pin A.0 and A.1 function as a peripheral signal UART0 RX/TX

    UART0_IBRD_R = 43;                                //UART_BAUD_RATE = 80000000/(16*115200)= 43.402777(7); Integer = 43
    UART0_FBRD_R = 26;                                //Fractional  0,4027777(7) -> UART0_FBRD_R = 0.4027777*64+0.5=26
    UART0_LCRH_R = (1<<4) | (1<<5) | (1<<6);        //none parity, 1 stop bit, 8-bit length, FIFO enabled
    UART0_CC_R = 0;                                    //UART clock from SystemClock
    UART0_CTL_R |= (1<<0) | (1<<8) | (1<<9);        //Enable UART block, enable reciever, enable transmitter
//    UART0_IFLS_R = (UART0_IFLS_R & 0xFFFFFFC0);        //Interrupt level select RXFIFO > 1/2 Full, TXFIFO < 1/2 Full
    UART0_IM_R = (1<<4) | (1<<6);                    //UART Receive Interrupt and Timeout Interrupt
    
    NVIC_EnableIRQ(UART0_IRQn);

    FUARTStatus = UART_EMPTY_STATUS;
}

//============================================================================================

void UART0_IRQHandler (){
    uint32_t _interrupt_source = UART0_MIS_R;

    if(_interrupt_source & (RX_INT | RX_TOUT_INT)){          
        UART0_ICR_R |= (1<<4);
        while(!(UART0_FR_R & RX_FIFO_EMPTY)){      
            BuffMBSlave[MBBuffIndex++] = (uint8_t)UART0_DR_R;
            if(MBBuffIndex >= SLAVE_BUF_LEN) MBBuffIndex = SLAVE_BUF_LEN;
        }
        if((_interrupt_source & RX_TOUT_INT)){
            UART0_ICR_R |= (1<<6);
            RX_INT_DISABLE;
            EndRecieve = TRUE;
            MBMessLength = MBBuffIndex;
        }
    }
    UART0_ICR_R = _interrupt_source;
}

  • Hi,

    Not using StellarisWare makes the helping task more difficult - not speaking about your efforts to develop such thing. However, i cannot see if you enabled global interrupt flag - call the function IntMasterEnable() or the function CPUcpsie() - this is an intrinsic function in cpu.c file in StellarisWare.

    Note there is an application note about Modbus on TI site, not sure if there is some code already developed for that.

    Petrei

  • Actually I was trying to make focus on UART configuration and UART interrupt handling. All necessary interrupts are enabled, global interrupts are enabled (_enable_irq() from CMSIS). Code that I've posted normally generate RX/TX interrupt (always) and RX Timeout interrupt, except condition above.

    LM4F120 is first Cortex-M4 MCU I am working with. Using StellasrisWare is too complex for me now.

  • I believe that the explanation is that since you have both RX and RX TIMEOUT interrupts enabled, when the packet size matches the FIFO size, the RX interrupt occurs and the data is read from the FIFO in your RX interrupt handler.  The reading of the data from the FIFO will clear any TIMEOUT interrupt that may have been pending.

    Also, the TIMEOUT interrupt will not occur unless there is data in the FIFO and the elapsed time (32 bit clocks) has occurred with no additional RX activity.

    So, since the interrupt handler has drained the FIFO, and there is no additional data on the RX line, the TIMEOUT interrupt will not occur.

    --Bobby

  • Thanks a lot !

    So, since the interrupt handler has drained the FIFO, and there is no additional data on the RX line, the TIMEOUT interrupt will not occur.


    It is all my inattentiveness.