Search code examples
cmicrocontrollerpicuartmicrochip

UART interrupt infinite loop microchip


Hi I'm using PIC32MX370F512L and encountered a "problem", in reality, it's not a real problem because I already fixed it, but I can't understand why does my fix work. I Will show you a piece of code then explain:

void __ISR(_UART_4_VECTOR, ipl1) Uart4Handler(void) {
    putU4_string("Entered Interrupt\n\r"); //This command send to my terminal the Text entered
    int c = U4RXREG; // PAY ATTENTION TO THIS LINE <-------
    IFS2bits.U4RXIF = 0; //Clear the Uart4 interrupt flag.
    putU4_string("Exit Interrupt\n\r");
}

If I DO NOT put the line int c = U4RXREG; then the interrupt is continuously called and I can't no more clear the IFS2bits.U4RXIF

These are my UART settings:

void UART_Config_Interrupt() {
    INTEnableSystemMultiVectoredInt(); //from plib.h
    IPC9bits.U4IP = 1; //Priority
    IPC9bits.U4IS = 3; //Sub-priority

    IFS2bits.U4RXIF = 0; //Interrupt flag putted at zero
    IFS2bits.U4TXIF = 0;

    IEC2bits.U4RXIE = 1; //Enable RX interrupt
}

void UART_Config_Uart(int baud) {

    U4MODEbits.ON = 0;
    U4MODEbits.SIDL = 0;
    U4MODEbits.IREN = 0;
    U4MODEbits.RTSMD = 0;
    U4MODEbits.UEN0 = 0;
    U4MODEbits.UEN1 = 0;
    U4MODEbits.WAKE = 0;
    U4MODEbits.LPBACK = 0;
    U4MODEbits.ABAUD = 0;
    U4MODEbits.RXINV = 0;
    U4MODEbits.PDSEL1 = 0;
    U4MODEbits.PDSEL0 = 0; //8 bit data NO parity
    U4MODEbits.STSEL = 0; //1 stop bit
    U4MODEbits.BRGH = 0;

    /*Configure baudRate
     *Source: http://ww1.microchip.com/downloads/en/DeviceDoc/61107F.pdf
     */
    UartBrg = (int) (((float) PbusClock / (16 * baud) - 1) + 0.5);
    U4BRG = UartBrg;

    U4STAbits.UTXEN = 1;
    U4STAbits.URXEN = 1;
    U4MODEbits.ON = 1;
}

void UART_Config_Pins() {
    TRISFbits.TRISF12 = 0; //TX as digital output
    RPF12R = 2; // 0010 U4TX ? Mapping U4TX t o RPF12 ;

    TRISFbits.TRISF13 = 1; // RX as digital input
    U4RXR = 9; // 1001 RF13 ? Mapping U4RX t o RPF13
}

My real question is WHERE can I retrieve this information? HOW can I know that I MUST int c = U4RXREG before clearing the flag.

This is the data-sheet http://ww1.microchip.com/downloads/en/DeviceDoc/61107F.pdf

The only information near to this topic I can find is in section 21.13, 26.1.1 and 21.6.3 but I really can't figure it out by my self. Can someone tell me how should I read this data-sheet for retrieving this information? For example:

The information you search is at page X at line Y and they MEAN this by saying this...

I personally think it can be on page 21 because they say:

a piece of text from pg21 section 21.6.3:

====

This means, to clear an interrupt for these modules before clearing the corresponding UxRXIF flag bit, the user application must ensure that the interrupt condition specified by the URXISEL control bits is no longer true.

====

If yes, can someone explain why? Or how do you interpret this?

Thx :)


Solution

  • I think you need to look at this part of the data sheet:

    For UART modules having 8-level-deep FIFO, an interrupt is generated when the interrupt condition specified by the URXISEL control bits is true. This means, to clear an interrupt for these modules before clearing the corresponding UxRXIF flag bit, the user application must ensure that the interrupt condition specified by the URXISEL control bits is no longer true.

    together with this part:

    For 8-level deep FIFO UART modules:

    11 = Reserved; do not use

    10 = Interrupt flag bit is asserted while receive buffer is 3/4 or more full (i.e., has 6 or more data characters)

    01 = Interrupt flag bit is asserted while receive buffer is 1/2 or more full (i.e., has 4 or more data characters)

    00 = Interrupt flag bit is asserted while receive buffer is not empty (i.e., has at least 1 data character)

    This means that you have to read some data out of the receive buffer in order to clear the interrupt condition. Consequently you need:

    int c = U4RXREG;