This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

UART interrupt routine

hi guys,

can i have some help regarding the given code below.

in the code i am capable of using the interrupt based receiving.

but i have to tell how much byte i m sending.

Now i wish whenever the data come it should go to IRQ handler

void UART0_IRQHandler(void)
{
  if(UART_GetITStatus(UART0, UART_IT_Receive) != RESET)
  {
        RxBuffer[RxCounter++] = UART0->DR;
        RxBuffer[RxCounter++] = UART0->DR;
        RxCounter==rxNum +2;
        if(rxNum == 0)
        {
         rxNum = (RxBuffer[0] * 256) + RxBuffer[1];
         while((RxCounter - 2) != rxNum)
         {
          test_num++;
          if((UART_GetFlagStatus(UART0, UART_FLAG_RxFIFOEmpty) != SET)&&(RxCounter < RxBufferSize))
            {
              RxBuffer[RxCounter++] = UART0->DR;
            }
          }
          rxNum = 0;
          test_num = 0;
        }
    }
}


  • 1) You forgot to mention what processor you have.

    2) Why do you think you can pick up more than one byte from the FIFO without first checking if there are more than one character in the FIFO? You normally check for receive fifo non-empty and as long as that condition you can pick up one more character.

    Here, you pick up two characters - why?

            RxBuffer[RxCounter++] = UART0->DR;
            RxBuffer[RxCounter++] = UART0->DR;
    

  • >Thanks Westermark for paying attention

    >I am using STR912FA.

    >No. of bytes to be received is declared in first two bytes.

    >Actually for the assurance of receiving the correct no. of bytes i used the above way of implementation.

    >I have taken help from the examples given.

    >Firstly I was using the below code but i was not able to receive more than 255 bytes

    void UART0_IRQHandler(void)
    {
    if((UART_GetFlagStatus(UART0, UART_FLAG_RxFIFOEmpty) != SET)&&(RxCounter < RxBufferSize))
                {
                  RxBuffer[RxCounter++] = UART0->DR;
                }
    
    }
    

  • You just can't assume there are two characters in the FIFO, unless you happen to know that it was a watermark interrupt and not a timeout interrupt.

    Remember that if you send a large message - larger than the FIFO can handle - then the UART must generate multiple interrupts. The first interrupt is likely to happen when there are two or more characters in the FIFO (i.e. a FIFO watermark interrupt where the interrupt happens to let you empty it before it overflows) but the last interrupt may happen for a single byte. When you don't get enough characters to reach the FIFO watermark level, you will get a last FIFO timeout interrupt, to let your code pick up the remaining part of a transfer.

    You can receive as big message as your buffer can handle - or even larger in case you have a state machine that starts to consume data on-the-fly.

    But your interrupt code should contain something like:

    while (UART_GetFlagStatus(UART0,UART_FLAG_RxFIFOEmpty) != SET) {
        c = UART0->DR;
        if (my_rx_buffer_full)
            my_rx_overflows++;
        else
            RxBuffer[InsertPos++] = c;
    }
    


    Your interrupt routine is of course free to look at received data to figure out where a message starts/ends. But that is totally separate from how the interrupt routine should check the status flags to figure out if it can pick up more data or not.

    It would be considered a bug in your program, if you can't consume data fast enough from your receive buffer, so the UART interrupt handler gets a buffer overflow.

    Another thing - you do not want the receive buffer to insert like that. It's way better to have a ring buffer, where one counter is insert position (producer) and one counter is remove position (consumer). Then you get the lucky situation that the interrupt only modifies the insert (write) position, and the main program only modifies the remove (read) position. The world is full of sample implementations. Go for one where the buffer size is 2^n large and where the two indices are allowed to use the full numeric range - it has the advantage that you can have 0 to n characters in the buffer. The variant that folds the indices when they reaches the full size of the buffer can only store n-1 entries to avoid the duality that rx-idx == tx-idx would happen both for a full or for an empty buffer.