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.

I am trying to implement FIFO for the uart, issue about the interrupt

I am trying to implement FIFO for the uart, and I found a tutor online to show me how to realize the FIFO, but the code say it has some prerequisite, 

like this:

  • To use this software buffer, the microcontroller must support "UART TX buffer empty" and "UART RX data received" interrupts.

I looked the interrupt table,  I only find the  UART Rx and Tx interrupt handler, and for each UART pin, is only has one in the interrupt table, so can anyone tell me how could I found the interrupt for specific use? do I need to define one for the specific use? I knew the system reserve some interrupt for DIY use.

question 2: how the Uart interrupt trigged? is that a timer interrupt? I knew these is hardware trig and software trig, please provide some material for me to read and learn.

Thanks

Shan

  • Hello Shan

    Answer#1: There is a UARTMIS register which can be used to find out whether TX or RX path generated the interrupt and action can be taken accordingly

    Answer#2: Ummm, when UART sends a byte or receives a byte or if the byte remains in the RXFIFO for time more than Receive Timeout.

    General: Datasheet for the device and ARM have a lot of reading material.

    Regards
    Amit
  • And - Joseph Yiu's book (past described) and, "Robert's bookshelf" (ditto) provide great detail & add clarity...
  • Amit, almost mentions it but as well as the RX interrupt you MUST implement the Receive Timeout interrupt as well (luckily the RTI response is identical to the RX response)

    Robert

  • Hi, I got Joseph Yiu's book, and I read the interrupt chapter, I did not find what I want for how to trig a uart interupt, can you give me more specific info over this?

    Thanks

    Shan

  • Which Tiva chip are you using? Have you looked at the TivaWare examples?

    You can check out 'void UARTStdioIntHandler(void)' in the <YourTivawareFolder>/utils/uartstdio.c for the interrupt handler, it's called as long as you set up your vector table properly.

    It's the very last function in the file. Here's the function so you can more easily see if it'll help:

    //*****************************************************************************
    //
    //! Handles UART interrupts.
    //!
    //! This function handles interrupts from the UART.  It will copy data from the
    //! transmit buffer to the UART transmit FIFO if space is available, and it
    //! will copy data from the UART receive FIFO to the receive buffer if data is
    //! available.
    //!
    //! \return None.
    //
    //*****************************************************************************
    #if defined(UART_BUFFERED) || defined(DOXYGEN)
    void
    UARTStdioIntHandler(void)
    {
        uint32_t ui32Ints;
        int8_t cChar;
        int32_t i32Char;
        static bool bLastWasCR = false;
    
        //
        // Get and clear the current interrupt source(s)
        //
        ui32Ints = MAP_UARTIntStatus(g_ui32Base, true);
        MAP_UARTIntClear(g_ui32Base, ui32Ints);
    
        //
        // Are we being interrupted because the TX FIFO has space available?
        //
        if(ui32Ints & UART_INT_TX)
        {
            //
            // Move as many bytes as we can into the transmit FIFO.
            //
            UARTPrimeTransmit(g_ui32Base);
    
            //
            // If the output buffer is empty, turn off the transmit interrupt.
            //
            if(TX_BUFFER_EMPTY)
            {
                MAP_UARTIntDisable(g_ui32Base, UART_INT_TX);
            }
        }
    
        //
        // Are we being interrupted due to a received character?
        //
        if(ui32Ints & (UART_INT_RX | UART_INT_RT))
        {
            //
            // Get all the available characters from the UART.
            //
            while(MAP_UARTCharsAvail(g_ui32Base))
            {
                //
                // Read a character
                //
                i32Char = MAP_UARTCharGetNonBlocking(g_ui32Base);
                cChar = (unsigned char)(i32Char & 0xFF);
    
                //
                // If echo is disabled, we skip the various text filtering
                // operations that would typically be required when supporting a
                // command line.
                //
                if(!g_bDisableEcho)
                {
                    //
                    // Handle backspace by erasing the last character in the
                    // buffer.
                    //
                    if(cChar == '\b')
                    {
                        //
                        // If there are any characters already in the buffer, then
                        // delete the last.
                        //
                        if(!RX_BUFFER_EMPTY)
                        {
                            //
                            // Rub out the previous character on the users
                            // terminal.
                            //
                            UARTwrite("\b \b", 3);
    
                            //
                            // Decrement the number of characters in the buffer.
                            //
                            if(g_ui32UARTRxWriteIndex == 0)
                            {
                                g_ui32UARTRxWriteIndex = UART_RX_BUFFER_SIZE - 1;
                            }
                            else
                            {
                                g_ui32UARTRxWriteIndex--;
                            }
                        }
    
                        //
                        // Skip ahead to read the next character.
                        //
                        continue;
                    }
    
                    //
                    // If this character is LF and last was CR, then just gobble up
                    // the character since we already echoed the previous CR and we
                    // don't want to store 2 characters in the buffer if we don't
                    // need to.
                    //
                    if((cChar == '\n') && bLastWasCR)
                    {
                        bLastWasCR = false;
                        continue;
                    }
    
                    //
                    // See if a newline or escape character was received.
                    //
                    if((cChar == '\r') || (cChar == '\n') || (cChar == 0x1b))
                    {
                        //
                        // If the character is a CR, then it may be followed by an
                        // LF which should be paired with the CR.  So remember that
                        // a CR was received.
                        //
                        if(cChar == '\r')
                        {
                            bLastWasCR = 1;
                        }
    
                        //
                        // Regardless of the line termination character received,
                        // put a CR in the receive buffer as a marker telling
                        // UARTgets() where the line ends.  We also send an
                        // additional LF to ensure that the local terminal echo
                        // receives both CR and LF.
                        //
                        cChar = '\r';
                        UARTwrite("\n", 1);
                    }
                }
    
                //
                // If there is space in the receive buffer, put the character
                // there, otherwise throw it away.
                //
                if(!RX_BUFFER_FULL)
                {
                    //
                    // Store the new character in the receive buffer
                    //
                    g_pcUARTRxBuffer[g_ui32UARTRxWriteIndex] =
                        (unsigned char)(i32Char & 0xFF);
                    ADVANCE_RX_BUFFER_INDEX(g_ui32UARTRxWriteIndex);
    
                    //
                    // If echo is enabled, write the character to the transmit
                    // buffer so that the user gets some immediate feedback.
                    //
                    if(!g_bDisableEcho)
                    {
                        UARTwrite((const char *)&cChar, 1);
                    }
                }
            }
    
            //
            // If we wrote anything to the transmit buffer, make sure it actually
            // gets transmitted.
            //
            UARTPrimeTransmit(g_ui32Base);
            MAP_UARTIntEnable(g_ui32Base, UART_INT_TX);
        }
    }

    Another good file to look at is <YourTivawareFolder>/driverlib/uart.c There are many functions there that can get you on your way to understanding UART FIFO.

  • Hi, Amit, for the UARTMIS, I check the datasheet

    this is all I see:

    Register 12: UART Masked Interrupt Status (UARTMIS), offset 0x040

    The UARTMIS register is the masked interrupt status register. On a read, this register gives the

    current masked status value of the corresponding interrupt. A write has no effect.

    is there any more specific introduction?

    "TX or RX path generated the interrupt and action can be taken accordingly", is this mean the processor could use the UARTMIS to tell which pin actually generated the interrupt,  but how the ISR processed, according to the table, there is only one interrupt handler for each UART module, but what I need is two different handler. I am trying to describe my mis-understanding, I am trying to learn, can you give me a brief intro, and tell me where I can found the material to help me to understand.

    Thanks

    Shan

  • thanks, I read the code above, so no matter what kind of interrupt it is,(RX or TX), the ISR went to the same handler which define in the NVIC table, and in the handler use the flag to determine which reaction should be taken?

    Shan
  • Make sure to also include the receive timeout.

    Robert
  • Take a look at this book recommendation. It is not TI or even microcontroller specific but it does, I think, give you a good background.

    e2e.ti.com/.../1799723

    The tags below that post lead to other resources that may be of use but are not serial protocol specific.

    Robert
  • Hello Shan

    In my first writing I mentioned UARTMIS can be used to find out whether TX or RX caused the interrupt. To use the UARTMIS, you would need to set the corresponding bits in UARTIM register. Once done, and an interrupt source is asserted, the UARTMIS bit is set while an interrupt is generated for the CPU. The handling of the UARTMIS would be performed in the interrupt handler by doing a read of the UARTMIS register and clearing it using the UARTISC register

    Regards
    Amit