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.

TMS320F28335: SCIA RX interrupt - fundamental question?!?

Part Number: TMS320F28335


Hello and merry Christmas,

During these days, I am trying to get familiar and understand the SCI (UART) interface between the F28335 DSP and my laptop using the ISR. Since I have never worked with UART, I am a little bit struggling. In particular, I attempt to read the data I send from my laptop to the DSP within the ISR. The minimum working example shall receive the data in the ISR and convert the ASCII information (variable named "ReceivedChar") into an integer (named "bla"). It also kind of works, but only kind of. What is happening:

1. When the code is running, I initially need to press a key 17 times (I press the key "1" on my keyboard, which shows me the equivalent of "49" in integer) until the ISR is called for the first time.

2. The code inside the ISR works fine, such that the ASCII "1" and the converterted ASCII into integer (49) give me the correct values. I leave the ISR again to come back to my main() function

3. I need to press a key 2 more times (I press key "2" on my keyboard which is equivalent to "50") until the ISR is called again. However, the value in "SciaRegs.SCIRXBUF.all" is not updated (SCIRXBUF.all has still the ASCII "1" information, i.e. "49").

4. I need to call the ISR 7 more times (i.e. 8 in total, i.e. pressing the key 16 times in total) until SCIRXBUF.all is updated to the new value. The new value is now 50 which matches with the ASCII table for the ASCII sign "2".

From now on, the whole procedure repeats to update the buffer to the new value, i.e. the ISR needs to be called 8 times until SCIRXBUF.all is updated to the new value.

I strongly believe that it is a software issue and I am messing up with variables, registers etc, as software development is not my strongest area. Any ideas on what is happening in my code?

Below the code, and thank for any help - much appreciated.

/*
 * This example sets up the UART to send data to and receive data from the laptop
 * When the data is received, an interrupt occurs and the data will then be taken from the buffer
 */
#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
__interrupt void UART_isr(void);

void scia_init();
Uint16 bla;
Uint16 ReceivedChar;



void main(void) {

  ReceivedChar=0;
    bla=0;

  // Step 1: Setting the PLL, Watchdog, enable peripheral clocks
  InitSysCtrl();

  // Step 3: Initialize the PIE control registers
//  DINT; // Only necessary here if InitPieCtrl() does not have DINT; included
  InitPieCtrl();

  IER = 0x0000;
  IFR = 0x0000;

  // Step 4: Initialize the PIE vector table to default ISR
  InitPieVectTable();

  // Configure the interrupt handling
  // Setting up the XINT1 trigger, Table 112
  EALLOW;
  PieVectTable.SCIRXINTA = &UART_isr;
  EDIS;

  // Enable XINT1 in the PIE
//  PieCtrlRegs.PIECTRL.bit.ENPIE = 1;  // Enables the PIE interrupt table. Already done in InitPieVectTable();
  PieCtrlRegs.PIEIER9.bit.INTx1 = 1;  // Figure 87
  IER |= M_INT9;            // Sets the interrupt enable bit of group 9
  EINT;                // Enable global interrupts INTM
  // Step 5: Initialize other device peripherals

  // We need to initialize our SCI
  InitSciGpio();

  // Step 6: Write your code
  scia_init();  // Initialize Sci FIFO

  for(;;)
  {
         // Wait for inc character
         while(SciaRegs.SCIFFRX.bit.RXFFST !=1) { } // wait for XRDY =1 for empty state
  }
}

void scia_init()
{
  /*
   * FIFO configuration
   */
  // SCIFFTX registers
  SciaRegs.SCIFFTX.bit.SCIRST = 1;  // Sci reset
  SciaRegs.SCIFFTX.bit.SCIFFENA = 1;  // Sci enhancements enabled
  SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1;  // Re-enable transmit FIFO operation
  SciaRegs.SCIFFTX.bit.TXFFST = 0;  // Transmit FIFO is empty
  SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;  // Clears TXFFINT flag
  SciaRegs.SCIFFTX.bit.TXFFIENA = 0;  // TX FIFO interrupt is disabled

  // SCIFFRX registers
  SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;  // Re-enable receive FIFO operation
  SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;  // Clears RXFFINT flag
  SciaRegs.SCIFFRX.bit.RXFFIENA = 1;  // RX FIFO interrupt is enabled
//  SciaRegs.SCIFFRX.bit.RXFFIL = 0x1F; // 1111

  // SCIFFCT registers
  SciaRegs.SCIFFCT.all = 0;      // Lets leave it as it is for now

  /*
   * Echoback configuration
   */
  // SCICCR registers
  SciaRegs.SCICCR.bit.STOPBITS = 0;  // 1 stop bit
  SciaRegs.SCICCR.bit.PARITY = 0;    // Odd Parity - but will be disabled anyways
  SciaRegs.SCICCR.bit.PARITYENA = 0;  // Parity disabled
  SciaRegs.SCICCR.bit.LOOPBKENA = 0;  // Loopback test mode disabled
  SciaRegs.SCICCR.bit.ADDRIDLE_MODE = 0;  // Idle line mode
  SciaRegs.SCICCR.bit.SCICHAR = 7;  // 8 char bits

  // SCICTL1 registers
  SciaRegs.SCICTL1.bit.RXERRINTENA = 0;  // Receive error interrupt disabled
  SciaRegs.SCICTL1.bit.SWRESET = 0;  // Initializing operating flags to the reset condition
  SciaRegs.SCICTL1.bit.TXWAKE = 0;  // Wake-up mode disabled
  SciaRegs.SCICTL1.bit.SLEEP = 0;    // Sleep mode disabled
  SciaRegs.SCICTL1.bit.TXENA = 1;    // Enable transmitter
  SciaRegs.SCICTL1.bit.RXENA = 1;    // Enable receiver

  // SCICTL2 registers
  SciaRegs.SCICTL2.bit.TXRDY = 0;    // SCITXBUF is full
  SciaRegs.SCICTL2.bit.TXEMPTY = 0;  // Transmitter buffer is loaded with data
  SciaRegs.SCICTL2.bit.RXBKINTENA = 1;  // Receiver buffer interrupt enabled
  SciaRegs.SCICTL2.bit.TXINTENA = 1;  // TXRDY interrupt enabled

  // SCIHBAUD registers for BAUD rate
    SciaRegs.SCIHBAUD    =0x0001;  // 9600 baud @LSPCLK = 37.5MHz.
    SciaRegs.SCILBAUD    =0x00E7;

    // SCICTL1 registers again
    SciaRegs.SCICTL1.all = 0x0023;  // WTF?
}

__interrupt void UART_isr(void)
{
    // Get character
    ReceivedChar = SciaRegs.SCIRXBUF.all;
    bla = ReceivedChar-'0';

  SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1;   // Clear Overflow flag
  SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;  // Clears RXFFINT flag to enable new incoming interrupts
  // Acknowledge this interrupt to get more from group 1
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}

  • Alexander,

    it sounds like you may only be reading 2 values out of the FIFO and leaving the ISR. You can read until the FIFO is empty, then exit the ISR. To check how many values are in the FIFO you can read bits 12-8(RXFFST4-0) of "SCIFFRX". Knowing this you should be able to setup a simple bit of code to read the FIFO data into an array or another data structure of your choice.

    SCIFFRX can be found in the SCI user guide.

    Regards,
    Cody

  • Hi Cody,

    thank you for coming back to me. I am not quite sure if we talk about the same thing. To me, it seems much more an issue with entering the ISR rather than whatever happens within the ISR.

    In particular, the SCI user guide says on p. 21:

    "If the RX/BK INT ENA bit (SCICTL2, bit 1) is set, the receiver peripheral interrupt request is asserted when one of the following events occurs:

    – The SCI receives a complete frame and transfers the data in the RXSHF register to the SCIRXBUF

    register. This action sets the RXRDY flag (SCIRXST, bit 6) and initiates an interrupt."

    So, when using HypterTerminal, I would expect the ISR to be called every time I hit a key and the content is written to the SCIRXBUF register.

    Is my understanding correct?

    If yes, why do I need to hit the key 17 times until the ISR is called? I set a breakpoint in the ISR to see when I enter it. And it happens after hitting the key for 17 times.

    So I believe that there is a fundamental mistake in a setting (in my code or maybe even in HyperTerminal?). I use 8N1 and set the settings in Hyperterminal according to the picture I uploaded.

    Also, the updated, minimalistic code:

    /*
     * This example sets up the UART to send data to and receive data from the laptop
     * When the data is received, an interrupt occurs and the data will then be taken from the buffer
     */
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    __interrupt void UART_isr(void);
    
    void scia_init();
    #define CR "\r\n"
    Uint16 bla;
    //Uint16 ReceivedChar;
    //volatile Uint16 uart_str_count = 0;
    //volatile char uart_string[10 + 1] = "";
    
    
    
    void main(void) {
    
    //  ReceivedChar=0;
    //    bla=0;
    
      // Step 1: Setting the PLL, Watchdog, enable peripheral clocks
      InitSysCtrl();
    
      // Step 3: Initialize the PIE control registers
    //  DINT; // Only necessary here if InitPieCtrl() does not have DINT; included
      InitPieCtrl();
    
      IER = 0x0000;
      IFR = 0x0000;
    
      // Step 4: Initialize the PIE vector table to default ISR
      InitPieVectTable();
    
      // Configure the interrupt handling
      // Setting up the XINT1 trigger, Table 112
      EALLOW;
      PieVectTable.SCIRXINTA = &UART_isr;
      EDIS;
    
      // Enable XINT1 in the PIE
    //  PieCtrlRegs.PIECTRL.bit.ENPIE = 1;  // Enables the PIE interrupt table. Already done in InitPieVectTable();
      PieCtrlRegs.PIEIER9.bit.INTx1 = 1;  // Figure 87
      IER |= M_INT9;            // Sets the interrupt enable bit of group 9
      EINT;                // Enable global interrupts INTM
      // Step 5: Initialize other device peripherals
    
      // We need to initialize our SCI
      InitSciGpio();
    
      // Step 6: Write your code
      scia_init();  // Initialize Sci FIFO
    
      for(;;)
      {
             // Wait for inc character
    //         while(SciaRegs.SCIFFRX.bit.RXFFST !=1) { } // wait for XRDY =1 for empty state
      }
    }
    
    void scia_init()
    {
      /*
       * FIFO configuration
       */
      // SCIFFTX registers
      SciaRegs.SCIFFTX.bit.SCIRST = 1;  // Sci reset
      SciaRegs.SCIFFTX.bit.SCIFFENA = 1;  // Sci enhancements enabled
      SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1;  // Re-enable transmit FIFO operation
      SciaRegs.SCIFFTX.bit.TXFFST = 0;  // Transmit FIFO is empty
      SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;  // Clears TXFFINT flag
      SciaRegs.SCIFFTX.bit.TXFFIENA = 0;  // TX FIFO interrupt is disabled
    
      // SCIFFRX registers
      SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;  // Re-enable receive FIFO operation
      SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;  // Clears RXFFINT flag
      SciaRegs.SCIFFRX.bit.RXFFIENA = 1;  // RX FIFO interrupt is enabled
    //  SciaRegs.SCIFFRX.bit.RXFFIL = 0x1F; // 1111
    
      // SCIFFCT registers
      SciaRegs.SCIFFCT.all = 0;      // Lets leave it as it is for now
    
      /*
       * Echoback configuration
       */
      // SCICCR registers
      SciaRegs.SCICCR.bit.STOPBITS = 0;  // 1 stop bit
      SciaRegs.SCICCR.bit.PARITY = 0;    // Odd Parity - but will be disabled anyways
      SciaRegs.SCICCR.bit.PARITYENA = 0;  // Parity disabled
      SciaRegs.SCICCR.bit.LOOPBKENA = 0;  // Loopback test mode disabled
      SciaRegs.SCICCR.bit.ADDRIDLE_MODE = 0;  // Idle line mode
      SciaRegs.SCICCR.bit.SCICHAR = 7;  // 8 char bits
    
      // SCICTL1 registers
      SciaRegs.SCICTL1.bit.RXERRINTENA = 0;  // Receive error interrupt disabled
      SciaRegs.SCICTL1.bit.SWRESET = 0;  // Initializing operating flags to the reset condition
      SciaRegs.SCICTL1.bit.TXWAKE = 0;  // Wake-up mode disabled
      SciaRegs.SCICTL1.bit.SLEEP = 0;    // Sleep mode disabled
      SciaRegs.SCICTL1.bit.TXENA = 1;    // Enable transmitter
      SciaRegs.SCICTL1.bit.RXENA = 1;    // Enable receiver
    
      // SCICTL2 registers
      SciaRegs.SCICTL2.bit.TXRDY = 0;    // SCITXBUF is full
      SciaRegs.SCICTL2.bit.TXEMPTY = 0;  // Transmitter buffer is loaded with data
      SciaRegs.SCICTL2.bit.RXBKINTENA = 1;  // Receiver buffer interrupt enabled
      SciaRegs.SCICTL2.bit.TXINTENA = 1;  // TXRDY interrupt enabled
    
      // SCIHBAUD registers for BAUD rate
        SciaRegs.SCIHBAUD    =0x0001;  // 9600 baud @LSPCLK = 37.5MHz.
        SciaRegs.SCILBAUD    =0x00E7;
    
        // SCICTL1 registers again
        SciaRegs.SCICTL1.all = 0x0023;  // WTF?
    }
    
    __interrupt void UART_isr(void)
    {
    	/*
    		unsigned char ReceivedChar;
        // Get character
        ReceivedChar = SciaRegs.SCIRXBUF.all;
    
        if( ReceivedChar != '\n' &&
        		ReceivedChar != '\r' )
        {
          uart_string[uart_str_count] = ReceivedChar;
          uart_str_count++;
        }
        else {
          uart_string[uart_str_count] = '\0';
          uart_str_count = 0;
        }
    //    bla = ReceivedChar-'0';
    	 */
    
      SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1;   // Clear Overflow flag
      SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;  // Clears RXFFINT flag to enable new incoming interrupts
      // Acknowledge this interrupt to get more from group 1
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
    }
    

  • Alex,

    I have not closely gone over you code, but it looks like you have setup the FIFO enhancements. This means that the value in RXFFIL4–0 will determine when an RX interrupt is asserted. Reading section 1.2.10.1 "SCI FIFO Description" in the SCI users guide should hopefully help you. You can also find a description of RXFFIL4-0 in Table 2-10 "SCI FIFO Receive (SCIFFRX) Register Field Descriptions" of the same document.

    Hope it helps, and let me know if you have anymore questions.

    Regards,
    Cody

  • Hello,

    In initialization, set SciaRegs.SCIFFRX.bit.RXFFIL = 1, so that the mcu enters to ISR routine when it receives 1 byte. Moreover, in ISR, continue reading bytes until the FIFO is empty. it is simply done by adding a code to your ISR like this one:
    while(SciaRegs.SCIFFRX.bit.RXFFST>0)
    {
    //get char (maybe its better to pass incoming bytes to an array, so you don't lose any incoming byte)
    ReceivedChar = SciaRegs.SCIRXBUF.all;
    }

    I hope this will help.
  • Hi Cody and Kadir,
    thank you both for your responses. They helped me in better understanding the UART functionality on the particular DSP. In fact, since I am only receiving the new setpoints for my control from my laptop, I decided to disable the FIFO enhancement and store every incoming byte into an array.
    This seems to be equivalent to setting the FIFO level to 1 as mentioned by Kadir, i.e. entering the ISR every time a key is pressed.

    Thank you both for your help, much appreciated.