Why RXDATA register gets empty (efr32fg14)

Thread Starter

yef smith

Joined Aug 2, 2020
756
Hello, When we recieve datain RXDATA and we assign this data to some variable R=USART0->RXDATA.
at some stage TXBL rises because RXDATA get empty.
Why it goes empty because of data assignment??
I think it should never go empty and the new data in RXDATA just overruns the old one.
Thanks.
 

Thread Starter

yef smith

Joined Aug 2, 2020
756
Sorry i ment RXDATAV flag.
Ok ,So when do i see the RXDATA empty?
in whatcase the flage of "new data can be recieved" will happen?
Thanks.
 
Last edited:

Papabravo

Joined Feb 24, 2006
21,228
RXDATA goes empty when the register is read in the process of doing the assignment. Many UARTs will have a FIFO buffer associated with RXDATA so that it can be reloaded immediately after it is emptied. If the FIFO buffer is empty, then RXDATA will also remain empty until a new character is received in the Rx Shift Register and transferred to the RX FIFO and then to RXDATA. If the serial data line is running at the synchronous limit, determined by the bitrate, then the processor needs a way to unload RXDATA faster than the rate of character arrival in order to avoid a data overrun condition.
 

Thread Starter

yef smith

Joined Aug 2, 2020
756
Hello Papabravo,I need to specificaly in the code after what stage the RXDATAV flag rises?
from page 537 in the efr32fg14 manual shown bellow there is a line marked by red.
I need to understand where is my code the codition is no longer true?

Thanks.

Assuming i have the example code bellow ,In my interrput handler there is a line
Code:
buffer_var = USART0->RXDATA;
a buffer is just a variable,which copies the the data from USART0->RXDATA.
I cant see,Where in the code i know that RXDATAV flag


https://www.silabs.com/documents/public/reference-manuals/efr32xg14-rm.pdf
1603824577277.png

************************************************
1603825188324.png
Code:
#include "em_device.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_usart.h"
#include "em_chip.h"
#include <stdint.h>
#include <stdbool.h>
#include "em_emu.h"
#include "bsp.h"
#include "bsp_trace.h"


uint8_t received_flag=0;//
// Receive data buffer
uint8_t buffer;
uint8_t tx_buffer=0x6F;
uint8_t tx_buffer_new=0x06;


void USART0_RX_IRQHandler(void)
{
    received_flag=1;
  // Get the character just received
  buffer_var = USART0->RXDATA;

  switch (buffer_var)
        {
        case 'a':

            tx_buffer_new=0x0F;
          break;

        case 'b':
            tx_buffer_new=0x2F;
        break;

        case 'c':
                    tx_buffer_new=0x4F;
         break;

        default:

        break;

        }//end switch
  // Clear the requesting interrupt before exiting the handler
  USART_IntClear(USART0, USART_IF_RXDATAV);
}



int main(void)
{
  uint32_t i;

  // Chip errata
  CHIP_Init();
  CMU_ClockEnable(cmuClock_GPIO, true);
  CMU_ClockEnable(cmuClock_USART0, true);


  //EFR32fg14 LOC2 page 157 data sheet TX P0
  GPIO_PinModeSet(gpioPortA,2, gpioModePushPull, 1);

//EFR32fg14 LOC2 page 157 data sheet RX P2
  GPIO_PinModeSet(gpioPortA,3, gpioModeInput, 0);

  GPIO_PinModeSet(gpioPortA, 5, gpioModePushPull, 1);


  // Default asynchronous initializer (115.2 Kbps, 8N1, no flow control)
  USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;

  // Configure and enable USART0
  USART_InitAsync(USART0, &init);
  //datasheet page 157 location2  rx portA pin3(P2) ,tx port A pin2(P0)
  USART0->ROUTELOC0 = USART_ROUTELOC0_RXLOC_LOC2 | USART_ROUTELOC0_TXLOC_LOC2;
  USART0->ROUTEPEN |= USART_ROUTEPEN_TXPEN | USART_ROUTEPEN_RXPEN;


  // Enable NVIC USART sources
  NVIC_ClearPendingIRQ(USART0_RX_IRQn);
  NVIC_EnableIRQ(USART0_RX_IRQn);
  NVIC_ClearPendingIRQ(USART0_TX_IRQn);
  NVIC_EnableIRQ(USART0_TX_IRQn);



  while (1)
  {

      if (received_flag==1)
      {
          USART_Tx(USART0,tx_buffer_new);
          USART_Tx(USART0,'\n');
          tx_buffer=tx_buffer_new;
          received_flag=0;
      }
      else
      {
          USART_Tx(USART0,tx_buffer);
                    USART_Tx(USART0,'\n');
      }
      for(i=0;i<115;i++)
      {
            GPIO_PinOutSet(gpioPortA,5);
            GPIO_PinOutClear(gpioPortA,5);
       }

    // Enable receive data valid interrupt
    USART_IntEnable(USART0, USART_IEN_RXDATAV);







  }
}
 

Attachments

Last edited:

MrChips

Joined Oct 2, 2009
30,824
When the following code is executed
Code:
buffer_var = USART0->RXDATA;
RXDATAV status flag and interrupt flag are automatically cleared. You don't have to clear it in code.
 

Papabravo

Joined Feb 24, 2006
21,228
Hello Papabravo,I need to specificaly in the code after what stage the RXDATAV flag rises?
from page 537 in the efr32fg14 manual shown bellow there is a line marked by red.
I need to understand where is my code the codition is no longer true?

Thanks.

Assuming i have the example code bellow ,In my interrput handler there is a line
...
The RXFULL flag is cleared in hardware. If you are not using the RXFULL interrupt then you don't need to worry about the RXFULL interrupt in software since the interrupt is always disabled. If you are using the RXFULL flag to trigger an interrupt, then the service routine should empty the buffer and clear the interrupt flag in software before exiting from the RXFULL interrupt service routine. Using this interrupt would only be required if the processing delays allow the buffer to be filled to some threshold. In normal circumstances the buffer (FIFO) should be mostly empty nearly all the time.

The way you do this calculation is to compute the character time for one serial frame. For exampl @ 115,200 bits per second with a serial format of 8N1, each bit takes approximately 8.68+ μsec, so 10 bits will take 86.8+ μsec. So at the synchronous limit you need to unload RXDATA in no more than say 20% of that time or about 17.36 μsec. If this is the case you can be pretty confident that the FIFO will be mostly empty most of the time. Even an occasional hiccup may allow 2 or 3 characters to accumulate in the FIFO.

What you also have to do is ensure that there are no critical sections (interrupts disabled) that last more than say 60% of a character time. These are empirical numbers I have developed over a long period of time and they have no rigorous theoretical basis.

Good Luck with your rockets.
 
Last edited:
Top