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 RX FIFO Usage in other Interrupt Routine

Hello 

I would like to use RX FIFO implementation inside other interruupt. The algortithm is like below

How can I do this ? I dont want to break my ADC reading with UART interrupt. I only want to send ADC data after preparing to other device for monitoring. Thanks in advance



void External_ADC_Interrupt()
{

ADC_Data_Read();

ADC_Data_Send_Prepare();
if(RX_FIFO_STATUS == 4) { ReceiveData[1] = RXBUF; ReceiveData[2] = RXBUF; ReceiveData[3] = RXBUF; ReceiveData[4] = RXBUF; send_flag = 1; RXFIFORESET; } Timeout() { RXFIFORESET; } if(ReceivaData[1] == condition1 && send_flag == 1) { SendData[1] = ADC1_CH1; SendData[2] = ADC1_CH2; . . . }

  • Hello Serkan,

    What is this External Interrupt?

    Regards
    Amit
  • Hello Amit

    This External ADC data ready interrupt

    Serkan
  • Hello Serkan

    Your algorithm is structurally unclear. As an example where do you get RX_FIFO_STATUS from? What is RXBUF and what is RXFIFORESET?

    Regards
    Amit
  • Hello Amit

    I only wrote this for give general view. Ok I share my own code. 


    void Comm() { if(UART0_RIS_R&UART_RIS_RXRIS) // hardware RX FIFO >= 2 Bytes { UART0_ICR_R = UART_ICR_RXIC; // acknowledge RX FIFO send_flag = 1; rx_timeout = 0; } rx_timeout++; if(rx_timeout>1000) { UART0_ICR_R = 0x00; // acknowledge RX FIFO rx_timeout = 0; } if(send_flag ==1) { UART_OutChar(ADC_Data); send_flag =0; } }
    void main()
    
    {
    
    while(1)
    {
    
    
    if(DR_Flag ==1)
    {
    
    ADC_Data_Reading(); // When Interrupt comes firstly ADC data will read
    Comm(); // After ADC reading, I would like to check RX FIFO and if it is N1 byte data , I would like to send N2 byte  data
    DR_Flag = 0;
    }
    
    }

  • Hello Sekan,

    You are sending data out of the device then why do you need to check the RXFIFO?

    Regards
    Amit
  • Also if a/d is interrupt driven it could run at a higher priority.

    I get the impression though that you haven't attempted any analysis or determined what latencies you can accept

    Robert
  • Hello

    I was confused about this implementation. Now I have only one problem. Let me explain it.

    I am using RS-485 communication. I get data from terminal program with UART ınterrupt. I see correct data in my receive data register. But when I send it only sends one byte data. I am sharing related code. 

    void UART0_Handler(void)
    {
      if(UART0_RIS_R&UART_RIS_RXRIS)
      {       // hardware RX FIFO >= 2 items
        UART0_ICR_R = UART_ICR_RXIC;        // acknowledge RX FIFO
        // copy from hardware RX FIFO to software RX FIFO
        while((UART0_FR_R&UART_FR_RXFE) == 0)
        {
            ReceiveData[0] = (char)(UART0_DR_R&0xFF);
            ReceiveData[1] = (char)(UART0_DR_R&0xFF);
            send_flag =1;
        }
      }
    }
    
    
    void main()
    {
    while(1)
    {
    if(ReceiveData[0] == 20 && ReceiveData[1] == 30 && send_flag ==1 )
    	        {
                        RS_485_COM = 0x01;  // RS485 Transmitter Mode
    	            UART_OutChar(0x01);
    	            UART_OutChar(0x02);
                        while((UART0_FR_R&UART_FR_TXFE) == 0); // Transmit FIFO empty
    	            RS_485_COM = 0x00;  // RS485 Receiver Mode
    	            send_flag =0;
    	        }
    }
    }

    After runnng, I only see 0x01 value on terminal. But when I send continous data, I see 0x01and 0x02 respectively on terminal screen. 

    Before I make RS-485 to receive mode, How can I be sure N byte data sent and I am ready to switch RS-485 in to receiver mode. This problem is related with it. As I said when I contionus send, there is no problem

    Regards

  • Hello Serkan

    By "continuous data" do you mean in free running mode and not debug mode with the debugger connected?

    Regards
    Amit
  • That's a ccompletely different problem from your initial one. Might be better as a separate thread.

    It's a difficult problem with asynchronous serial devices in general, more difficult if there is a FIFO. The only general solution I know of is to read back what is transmitted. That has the added benefit of letting you detect corrupted transmission at least some of the time

    Robert
  • Hello Amit

    I mean when I siwtch RS-485 to only transmitter mode, It sends 0x01 and 0x02 respectively.

    I now realized that It does not send last byte. When I send 5 byte like 

     if(ReceiveData[0] == 20 && ReceiveData[1] == 30 && send_flag ==1 )
    	        {
    	       setbit(ADC_CS5,6);
                   UART_OutChar(0x01);
                   UART_OutChar(0x02);
                   UART_OutChar(0x03);
                   UART_OutChar(0x04);
                   UART_OutChar(0x05);
                   UART_OutChar(0x06);
                   while((UART0_FR_R&UART_FR_TXFE) == 0);
                   clrbit(ADC_CS5,6);
    	       send_flag =0;
    	        }

    It sends 4-Byte and 5. Byte does not seem on terminal screen like when I send 2 byte, 2. byte didnt seem on terminbal screen.

    I share my UART Initilization code 

    void UART_Init(void)
    {
      SYSCTL_RCGCUART_R |= 0x01;            // activate UART0
      SYSCTL_RCGCGPIO_R |= 0x01;            // activate port A
      UART0_CTL_R &= ~UART_CTL_UARTEN;      // disable UART
      UART0_IBRD_R = 520;                    
      UART0_FBRD_R = 54;                    
                                            // 8 bit word length (no parity bits, one stop bit, FIFOs)
      UART0_LCRH_R = (UART_LCRH_WLEN_8|UART_LCRH_FEN);
      UART0_IFLS_R &= ~0x3F;                // clear TX and RX interrupt FIFO level fields
                                            // configure interrupt for RX FIFO >= 1/8 full
      UART0_IFLS_R += UART_IFLS_RX1_8;
                                            // enabl RX FIFO interrupts and RX time-out interrupt
      UART0_IM_R |= (UART_IM_RXIM|UART_IM_RTIM);
      UART0_CTL_R |= UART_CTL_UARTEN;       // enable UART
      GPIO_PORTA_AFSEL_R |= 0x03;           // enable alt funct on PA1-0
      GPIO_PORTA_DEN_R |= 0x03;             // enable digital I/O on PA1-0
                                            // configure PA1-0 as UART
      GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R&0xFFFFFF00)+0x00000011;
      GPIO_PORTA_AMSEL_R = 0;               // disable analog functionality on PA
                                            // UART0=priority 2
      NVIC_PRI1_R = (NVIC_PRI1_R&0xFFFF00FF)|0x00004000; // bits 13-15
      NVIC_EN0_R = NVIC_EN0_INT5;           // enable interrupt 5 in NVIC
    }

  • Hello Serkan,

    Do you disable the Transmitter when sending the bytes or is it that the last byte does not appear on the terminal? Also before writing the byte to the UART FIFO can you check if the TXFE bit is set to ensure that all bytes to be written shall be held in the FIFO.

    Lastly check the UART lines to see when 2 bytes, the 2 bytes do appear on the UART TX pins.

    Lastly, as in your earlier post and red flag set by , the application code has entered the complexity that will make coding further difficult unless a switch to TivaWare is not done.

    Regards
    Amit
  • Hello Amit

    As in my code block, After I send last byte, I disable transmitter. When I do not disable transmitter I mean when I only send data to terminal, there is no problem. Maybe some delay is required before I disable transmitter.

    I checked two byte shown in my UART TX line.

    This is my first Embedded project, thats why I wanted to learn everything about hardware and software about Tiva thats why I choose step by step coding instead of using Tivaware driver libraries. Maybe I can work with Tivaware in other project.

    Serkan
  • Hello Serkan,

    When the FIFO mode is enabled the TXFE bit shall be cleared when the last byte leaves the FIFO. But it may still be in the holding buffer for serialization. So, you need to add delay or check for the BUSY bit to be clear before disabling the transmitter.

    The best way I have figured out is to use TivaWare to learn the software to reduce 1 variable out of the equation.

    Regards
    Amit
  • Serkan, see my earlier comment. That's probably the only high reliability method. You'll need to add checks in case the end of packet gets corrupted. Less reliably you could use a timer. The caveat with that is you have to be sure you understand any latencies in the transmission from when you set the timer

    Robert
  • Hello Robert

    Thanks for your recommendation. I firstly send one more spare byte in addition to my related bytes and then I receive back what I transmitted and check whether first and last bytes are true. This works fine for now.

    Regards

    Serkan
  • Hello Serkan,

    I would disagree with the approach of adding a spare byte when the conditional checks are not correct.

    Regards
    Amit
  • Hello Amit

    Time delay also worked. Then I can work with this as well

    Serkan
  • Hello Serkan,

    Have you add the check condition before disabling the transmitter (BTW, why disable the transmit, if nothing is going to be sent after that till a new byte is available in the RX path)

    Regards
    Amit
  • You are right. There are many devices in RS-485 line I only disable transmit for secure. Yes I added check condition.

    Serkan

  • Hello Serkan,

    Serkan said:
    There are many devices in RS-485 line I only disable transmit for secure

    For what secure? And after adding the check it did not work surprises me. Code please.

    Regards

    Amit

  • An extra byte shouldn't be necessary I think, and it might be problematic to the bus. You shouldn't need more than 1/2 a bit time at most to be sure the entire character including stop bits are past.

    Work out how long it takes from verifying the last byte to turning around the line, you may not even need additional delay unless the protocol requires the bus have a certain deadtime with the sender active before the protocol turns the bus around

    Robert
  • Hello Robert,

    Exactly. "Secure" what? The BUSY flag should have taken care of the same, else the UARTprintf in the first place would never have succeeded.

    Regards
    Amit