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.

How to get all the string (stream) from RXBUFF

Hello !! 

I have a problem, cant find a solution for getting out a full string from UART RX BUFFER, I added small code the size 4 just for this example (trying to get 5 chars), I do enter RX interrupt but only seeing the last char .

With TX BUFFER, I have similar implementation and by using TX register I been able to pass all the string .

// UART interrupt service routine

void eUSCIA0IsrHandler(void)

{

if (UCA0IFG & UCRXIFG){

stringBuffer[j++] = UCA0RXBUF;

if(j >= 4){

UCA0IE &= ~UCRXIE;

}

else

{

UCA0IE |= UCRXIE ;

}

}}

How I get the string ?? All I see is the last char of the stream ?? 

It won't enter the interrupt for each char from the stream .

Thank you !

Feliks

  • I can't see any thing obvious.Paste the part of the code where you are accessing the rx buffer.

    Also UCA0RXBUF is a word register and if your rx buffer is byte buffer.Its probable a direct copy can

    create issues.Try typecasting to a byte before copying.

    Some thing like:

    stringBuffer[j++] = (uint8_t)UCA0RXBUF;

  • You didn't understand the question .
  • To help you, you need to provide a little bit more information;
    Which IDE are you using: IAR, CCS or other?
    Which MCU?
    Software code on; How did you setup the USCI. How did you initialize the ISR (vector). Your ‘main’ (loop). Declaration of Variables. Etc.
  • Feliks,

    if people don't understand the question, then the question might be the problem, not the one that answers it, or at least tries to.

    Anyway - the RX buffer normally isn't a word sized buffer, it has byte size. The USI module in some MSPs can send a word.

    If you only see the last byte, then something with your incrementing fails. Did you declare j as volatile? It is altered during the interrupt - if you declare it outside the ISR, you have to add the attribute volatile to it. Please show more code.

    Dennis

  • MSP432,IAR, UART is working I followed the tutorial, It's all working.
    I just don't understand why I can get only the last char of the stream in RXBUFF and how I get the previous chars .
    The code is standard, I don't see a reason how it can help you .
    When I use TXBUFF I switch the interrupt flag and it sends from eUSCIA0IsrHandler(void) each char.
    How I can retrieve the chars from RXBUFF, in the same method as I used TXBUFF ?? call interrupt for each char ?? or is there another way .
    Who ever used RXBUFF should understand what I am talking about . I Will add my code if it helps you but I don't see how .

    int main(void)
    {
    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

    CSKEY = 0x695A; // Unlock CS module for register access
    CSCTL0 = 0; // Reset tuning parameters
    CSCTL0 = DCORSEL_3; // Set DCO to 12MHz (nominal, center of 8-16MHz range)
    // Select ACLK = REFO, SMCLK = MCLK = DCO
    CSCTL1 = SELA_2 | SELS_3 | SELM_3;
    CSKEY = 0; // Lock CS module from unintended accesses


    /* Enable SysTick Module */
    SYSTICK_STCSR |= SYSTICK_STCSR_CLKSOURCE | SYSTICK_STCSR_ENABLE;

    /* Set SysTick period = 1 ms (24 MHz / 24000 = 1,000 Hz frequency) */
    SYSTICK_STRVR = 128000 - 1;

    /* Enable SysTick interrupt */
    SYSTICK_STCSR |= SYSTICK_STCSR_TICKINT;

    // Configure UART pins
    P1SEL0 |= BIT2 | BIT3; // set 2-UART pin as second function

    __enable_interrupt();
    NVIC_ISER0 = 1 << ((INT_EUSCIA0 - 16) & 31); // Enable eUSCIA0 interrupt in NVIC module

    // Configure UART
    UCA0CTLW0 |= UCSWRST;
    UCA0CTLW0 |= UCSSEL__SMCLK; // Put eUSCI in reset
    // Baud Rate calculation
    // 24000000/(16*230400) = 6.5104166666666666666666666666667
    // Fractional portion = 0.5104166666666666666666666666667
    // User's Guide Table 22-4: UCBRSx = 0xAA
    // UCBRFx = int ( (6.5104166666666666666666666666667 - 6)*16) = 8
    UCA0BR0 = 78; // 24000000/16/9600
    UCA0BR1 = 0x00;
    UCA0MCTLW = 0x1000 | UCOS16 | 0x0020;

    UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI


    // __sleep();
    // __no_operation();

    UCA0IE |= UCRXIE ;

    while(1){
    (***) UCA0IE |= UCRXIE ;

    }
    }

    // UART interrupt service routine
    void eUSCIA0IsrHandler(void)
    {

    if (UCA0IFG & UCRXIFG){

    stringBuffer[j++] = UCA0RXBUF;

    if(j >= 4){

    UCA0IE &= ~UCRXIE;

    }

    else

    {

    UCA0IE |= UCRXIE ;

    }

    }



    // if (UCA0IFG & UCTXIFG)
    // {
    // // UCA0TXBUF = UCA0RXBUF;
    // printLetter();
    // }
    }

    void SysTickIsrHandler(void)
    {

    }


    void printLetter(void){


    printf("TX_PRINT");
    UCA0TXBUF = string[i++];

    if(i == sizeof(string) - 1){
    i=0;
    UCA0IE &= ~UCTXIE;
    }
    }
  • Of course the interrupt has to be called for each individual char. Or you use the DMA for that. You still did not post all of your code and although you think this does not make a difference for troubleshooting, I say: It does. Please jump back to my previous post and read that again.

    Dennis
  • Sorry !! I forgot those lines

    #include <stdio.h>

    #include "msp.h"
    #include "UART/UART_Debug.h"

    char string[] = "Hello World";
    char stringBuffer[10];
    char buffer;
    int i = 0,t = 0;
    volatile int j = 0;
    void printLetter(void);

    Changed to volatile, I get only the last char !! Also the specification states that
    If you will open "MSP432P4xx Technical Reference Manual slau356"

    You will see in :

    For RXBUFF

    "The receive-data buffer is user accessible and contains the last received character from the receive shift register. Reading UCAxRXBUF resets the receive-error bits, the UCADDR or UCIDLE bit, and UCRXIFG. In 7-bit data mode, UCAxRXBUF is LSB justified and the MSB is always reset."

    Is this means that I get only the last character from the string or for every character I get the last received ?? Meaning when I get the character it is the last one that entered shift register for that moment ?

  • The RX buffer can only hold one byte. If you receive a string, you have to fetch the first byte from the RX buffer and store it somewhere while the second byte is already coming into the receive shift register, then fetch the second byte while the third is coming in, then fetch the third, ... So after each byte of the string you will have to store the one byte that was just received before it is overwritten by the next one that is coming in. This is done inside the ISR - move the byte from the RX buffer to another buffer-array and process the data when everything is fetched.

  • Yes exactly :) Now the main Question, How Can I achieve that ?? If you can write a small snippet or show me something similar that was done by someone else .

    Is it done from the interrupt ??

    Thank you !! Your help is appreciated .
    Feliks

  • This is your own code again, let's see what you're doing in there:

    #include <stdio.h>
    #include "msp.h"
    #include "UART/UART_Debug.h"
    
    char string[] = "Hello World";
    char stringBuffer[10];
    char buffer;
    int i = 0, t = 0;
    volatile int j = 0;
    
    void printLetter( void );
    
    int main( void )
    {
      WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
    
      CSKEY = 0x695A; // Unlock CS module for register access
      CSCTL0 = 0; // Reset tuning parameters
      CSCTL0 = DCORSEL_3; // Set DCO to 12MHz (nominal, center of 8-16MHz range)
      
      // Select ACLK = REFO, SMCLK = MCLK = DCO
      CSCTL1 = SELA_2 | SELS_3 | SELM_3;
      CSKEY = 0; // Lock CS module from unintended accesses
    
      /* Enable SysTick Module */
      SYSTICK_STCSR |= SYSTICK_STCSR_CLKSOURCE | SYSTICK_STCSR_ENABLE;
    
      /* Set SysTick period = 1 ms (24 MHz / 24000 = 1,000 Hz frequency) */
      SYSTICK_STRVR = 128000 - 1;
    
      /* Enable SysTick interrupt */
      SYSTICK_STCSR |= SYSTICK_STCSR_TICKINT;
    
      // Configure UART pins
      P1SEL0 |= BIT2 | BIT3; // set 2-UART pin as second function
    
      __enable_interrupt();
      NVIC_ISER0 = 1 << ((INT_EUSCIA0 - 16) & 31); // Enable eUSCIA0 interrupt in NVIC module
    
      // Configure UART
      UCA0CTLW0 |= UCSWRST;
      UCA0CTLW0 |= UCSSEL__SMCLK; // Put eUSCI in reset
      // Baud Rate calculation
      // 24000000/(16*230400) = 6.5104166666666666666666666666667
      // Fractional portion = 0.5104166666666666666666666666667
      // User's Guide Table 22-4: UCBRSx = 0xAA
      // UCBRFx = int ( (6.5104166666666666666666666666667 - 6)*16) = 8
      UCA0BR0 = 78; // 24000000/16/9600
      UCA0BR1 = 0x00;
      UCA0MCTLW = 0x1000 | UCOS16 | 0x0020;
      UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
    
      // __sleep();
      // __no_operation();
    
      UCA0IE |= UCRXIE ;
    
      while( 1 )
      {
        (***) UCA0IE |= UCRXIE ;
      }
    }
    
    
    
    // UART interrupt service routine
    void eUSCIA0IsrHandler( void )
    {
      if( UCA0IFG & UCRXIFG )
      {
        stringBuffer[j++] = UCA0RXBUF;
    
        if( j >= 4 )
        {
          UCA0IE &= ~UCRXIE;
        }
        else
        {
          UCA0IE |= UCRXIE;
        }
      }
    
    //  if( UCA0IFG & UCTXIFG )
    //  {
    //    UCA0TXBUF = UCA0RXBUF;
    //    printLetter();
    //  }
    }
    
    
    
    void SysTickIsrHandler( void )
    {
    
    }
    
    
    void printLetter( void )
    {
      printf( "TX_PRINT" );
      UCA0TXBUF = string[i++];
    
      if( i == sizeof( string ) - 1 )
      {
        i=0;
        UCA0IE &= ~UCTXIE;
      }
    }

    Please use the rich formatting and the code insertion tool next time when posting code.

    What is this one here?

    (***) UCA0IE |= UCRXIE;

    Why do you set

    UCA0IE |= UCRXIE;

    over and over again?

    Dennis

  • Yes I set it :)
    Inside the while was this interrupt before I used it in line 79, to run it over and over . Still all I got, was the last char of the string .
    How it works on msp430 ?? As I used it ??
    Thank you .
  • How does the processor knows where ‘eUSCIA0IsrHandler’ is located?
  • This is (hopefully) set in the startup file.

  • Correct :) someone tried it on msp430 ??
  • This could be some pseudo code:

    #define MESSAGE_LENGTH 10
    
    char rx_buffer[MESSAGE_LENGTH];
    volatile uint8_t rx_counter = 0;
    volatile uint8_t flag = 0;
    
    void main( void )
    {
      // configure everything
      enable_global_interrupts;
      enable_rx_interrupts;
    
      while( 1 )
      {
        if( flag )
        {
          // Process data
          flag = 0;
          clear_pending_rx_interrupt_flag;
          enable_rx_interrupts;
        }
      }
    }
    
    void USCI_ISR( void )
    {
      rx_buffer[rx_counter] = USCI_RX_BUFFER;
    
      if( ++rx_counter >= MESSAGE_LENGTH )
      {
        disable_rx_interrupts;
        rx_counter = 0;
        flag = 1;
      }
    }

    Dennis

  • Nope It was a mistake :)

  • It works now? What have you changed / what was the problem?
  • Nope :) Still doesn't work, I tried to play with driverlib nothing too .
    As I understand, when I send sequence of "hello world" I need to send it like "H" press send ,"e" press send, "l" press send ... etc ?? Then RX_Interrupt will catch it 11 times but what if I want to send "Hello world" as one string and press send only once ??
    I attached USB to Uart module and connected the wires to RX and TX .
    Only If I press after each letter "send" interrupt catches the RX each time but it's not logical solution :(
    Don't know what should I do .
    Feliks
  • No, you can send your complete string by pressing send once. But now I am a little bit confused - do you want to send the message from the PC to the MSP, or from the MSP to the PC?
  • From the PC to MSP :) and now I tried their ECHO project in driverlib so I see that if I use Debug BP or Printf, I loose some DATA on the way :)
    My Mistake It's all fine guys !! It works .
    Thank you !!
    Feliks
  • Hi Dennis

    The "flag" should be used as you defined in this piece of pseudo code? or do you mean the RX flag?

    Thank you

**Attention** This is a public forum