How to empty RX buffer on nrf52840 UARTE0

Hi

I want to read in a sequenze of character over UARTE0 pheripheral on the NRF52840. I use the function getchar() but the first two characters I get is always the last two characters received which is always \n and \r. I solve this by running getchar() 2 times to empty the RX buffer before I start receiving new characters but is there a more elegant way to solve this, empty the buffer withput knowing hov many characters there is left in the buffer. The code below works, but is there a more elegant way to check UARTE0 events, or start/stop RX buffer or something?

else if ( strcmp(string2, "send_binary_lpc_code") == 0 ) {
char a;
int b = 0;
getchar();
getchar();
do {
printf("type new character:");
a = getchar();
printf("\r\ncharacter %i: %c\r\n", b+1, a);
b = b + 1;
} while ( b < 6 );
}

Parents
  •         memset(string1, 0, sizeof(string1));
            memset(string2, 0, sizeof(string2));  
            scanf("%s", string1);
            i=0;
    
            while( (i < 256) && (string1[i]!='(') && (string1[i]!=0) ) {
              string2[i] = string1[i];
              i=i+1;
            }

    I use nRF5_SDK_17.1.0_ddde560, use the UART pheripheral example/PCA10056 as a start base for my project and develped it from there.

    I use scanf function to read in te command string which always is appended with \n\r by my UART serial terminal program (REALTERM)

    I am not completly sure about this but as I understand it, SCANF function reads in all characters until a whitepspace, or \r, or \n is sent. So the last two characters sent \n\r is never read out from the RX buffer. So thats why always the first two characters I read in when I run

    else if ( strcmp(string2, "send_binary_lpc_code") == 0 ) 

    are always \r\n, and I would like to clear the RX buffer before using getchar(). I have solved it for this use case bu just running getchar two times first, but is there some smarter low level UARTE0 register I can set to clear RX buffer. This times I know its two bytes, but maybe next time in some other program it may be 10 bytes. I would like to run a routine that check how many unread bytes there is and clear all of them?

  • Thanks for the additional information. It sounds like our CLI library might be more suitable for what you are trying do. Anyway, scanf will call __getchar() -> app_uart_get() in a loop until it has read the first termination character from the UART driver’s FIFO buffer before exiting.  Because of this I woud only expect \n to remain in your FIFO. It may also be worth adding that not all terminals use the same line endings by default.

    Oystein said:
    This times I know its two bytes, but maybe next time in some other program it may be 10 bytes. I would like to run a routine that check how many unread bytes there is and clear all of them?

    The app uart library which is used by the stdio functions does not expose any functions to peek into the FIFO buffer unfortunately.

    Oystein said:
    smarter low level UARTE0 register I can set to clear RX buffer

    It seems like you have scanf ignore a leading newline by inserting a whitespace before the format specifier. So scanf(" %s", string1); instead of scanf("%s", string1);

    https://cplusplus.com/reference/cstdio/scanf/ 

    Oystein said:
    program it may be 10 bytes.

    I would consider setting a max width for scanf to not allow the string buffer to potentially overflow.

Reply
  • Thanks for the additional information. It sounds like our CLI library might be more suitable for what you are trying do. Anyway, scanf will call __getchar() -> app_uart_get() in a loop until it has read the first termination character from the UART driver’s FIFO buffer before exiting.  Because of this I woud only expect \n to remain in your FIFO. It may also be worth adding that not all terminals use the same line endings by default.

    Oystein said:
    This times I know its two bytes, but maybe next time in some other program it may be 10 bytes. I would like to run a routine that check how many unread bytes there is and clear all of them?

    The app uart library which is used by the stdio functions does not expose any functions to peek into the FIFO buffer unfortunately.

    Oystein said:
    smarter low level UARTE0 register I can set to clear RX buffer

    It seems like you have scanf ignore a leading newline by inserting a whitespace before the format specifier. So scanf(" %s", string1); instead of scanf("%s", string1);

    https://cplusplus.com/reference/cstdio/scanf/ 

    Oystein said:
    program it may be 10 bytes.

    I would consider setting a max width for scanf to not allow the string buffer to potentially overflow.

Children
  • Hi

    Thansk a lot, the information about scanf, I was not aware of all the smart features. I will implemt as needed.

    Vidar wrote:

    Because of this I woud only expect \n to remain in your FIFO

    yes, when I read the FIFO buffer (using the RXD:PTR pointer there is only one characters \n, but there is also a static bufffer

    static app_fifo_t                  m_rx_fifo;                               /**< RX FIFO buffer for storing data received on the UART until the application fetches them using app_uart_get(). */
     

    I guess this static buffer contains the last two characters. I did not investiage it anymore. I just run getchar 2 times to solve it.

    //Run getchar() 2 times to empty the UARTE0 RX buffer. 
        getchar();
        getchar();

    kr

    Øystein

Related