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.

LAUNCHXL-F28379D: issue with IMU SCI communication with interrupts

Part Number: LAUNCHXL-F28379D


Hi,

I am currently using IMU9250 to get readings for Pitch via UAR with LaunchXL-F28379D. The output from this IMU is as follows:

<-8.24>

<-17.44> and so on..

I am able to get the output with basic sci loopback code. However, I want to use interrupts, as I need to call SCI within another protocol.

When I use the following code, I get no proper output but gibberish values.

What am I missing here?

//###########################################################################
//
// FILE:   Example_2837xDSci_FFDLB_int.c
//
// TITLE:  SCI Digital Loop Back with Interrupts.
//
//! \addtogroup cpu01_example_list
//! <h1>SCI Digital Loop Back with Interrupts (sci_loopback_interrupts)</h1>
//!
//!  This program uses the internal loop back test mode of the peripheral.
//!  Other then boot mode pin configuration, no other hardware configuration
//!  is required. Both interrupts and the SCI FIFOs are used.
//!
//!  A stream of data is sent and then compared to the received stream.
//!  The SCI-A sent data looks like this: \n
//!  00 01 \n
//!  01 02 \n
//!  02 03 \n
//!  .... \n
//!  FE FF \n
//!  FF 00 \n
//!  etc.. \n
//!  The pattern is repeated forever.
//!
//!  \b Watch \b Variables \n
//!  - \b sdataA - Data being sent
//!  - \b rdataA - Data received
//!  - \b rdata_pointA - Keep track of where we are in the data stream.
//!    This is used to check the incoming data
//!
//
//###########################################################################
// $TI Release: F2837xD Support Library v3.05.00.00 $
// $Release Date: Thu Oct 18 15:48:42 CDT 2018 $
// $Copyright:
// Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################

//
// Included Files
//
#include "F28x_Project.h"

//
// Defines
//
//
// Globals
//
Uint16 sdataA[2];    // Send data for SCI-A
Uint16 rdataA[2];    // Received data for SCI-A
Uint16 rdata_pointA; // Used for checking the received data

//
// Function Prototypes
//
interrupt void sciaTxFifoIsr(void);
interrupt void sciaRxFifoIsr(void);
void scia_fifo_init(void);
void error(void);
void scia_xmit(Uint16 a);
void scia_msg(Uint16 *msg);

//
// Main
//
void main(void)
{
   Uint16 i;
   Uint16 ReceivedChar;
   Uint16 *msg;
//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xD_SysCtrl.c file.
//
   InitSysCtrl();

//
// Step 2. Initialize GPIO:
// This example function is found in the F2837xD_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//
   InitGpio();

//
// For this example, only init the pins for the SCI-A port.
//  GPIO_SetupPinMux() - Sets the GPxMUX1/2 and GPyMUX1/2 register bits
//  GPIO_SetupPinOptions() - Sets the direction and configuration of the GPIOS
// These functions are found in the F2837xD_Gpio.c file.
//
   //
      GPIO_SetupPinMux(43, GPIO_MUX_CPU1,15);
      GPIO_SetupPinOptions(43, GPIO_INPUT, GPIO_PUSHPULL);
      GPIO_SetupPinMux(42, GPIO_MUX_CPU1,15);
      GPIO_SetupPinOptions(42, GPIO_OUTPUT, GPIO_ASYNC);
      GPIO_SetupPinMux(19, GPIO_MUX_CPU1, 2);
      GPIO_SetupPinOptions(19, GPIO_INPUT, GPIO_PUSHPULL);
      GPIO_SetupPinMux(18, GPIO_MUX_CPU1, 2);
      GPIO_SetupPinOptions(18, GPIO_OUTPUT, GPIO_ASYNC);
   //

//
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
//
   DINT;

//
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the F2837xD_PieCtrl.c file.
//
   InitPieCtrl();

//
// Disable CPU interrupts and clear all CPU interrupt flags:
//
   IER = 0x0000;
   IFR = 0x0000;

//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in F2837xD_DefaultIsr.c.
// This function is found in F2837xD_PieVect.c.
//
   InitPieVectTable();

//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
//
   EALLOW;  // This is needed to write to EALLOW protected registers
   PieVectTable.SCIB_RX_INT = &sciaRxFifoIsr;
  // PieVectTable.SCIA_TX_INT = &sciaTxFifoIsr;
   EDIS;    // This is needed to disable write to EALLOW protected registers

//
// Step 4. Initialize the Device Peripherals:
//
   scia_fifo_init();  // Init SCI-A

//
// Step 5. User specific code, enable interrupts:
//
// Init send data.  After each transmission this data
// will be updated for the next transmission
//
   *msg =(char)ScibRegs.SCIRXBUF.all;
   scia_msg(msg);


//
// Enable interrupts required for this example
//
   PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
   PieCtrlRegs.PIEIER9.bit.INTx1 = 1;   // PIE Group 9, INT1
   PieCtrlRegs.PIEIER9.bit.INTx2 = 1;   // PIE Group 9, INT2
   IER = 0x100;                         // Enable CPU INT
   EINT;
//
// Step 6. IDLE loop. Just sit and loop forever (optional):
//
//    for(;;);
}

//
// error - Function to halt debugger on error
//
void error(void)
{
    asm("     ESTOP0"); // Test failed!! Stop!
    for (;;);
}

//
// scia_xmit - Transmit a character from the SCI
//
void scia_xmit(Uint16 a)
{
    while (SciaRegs.SCIFFTX.bit.TXFFST != 0) {}
    SciaRegs.SCITXBUF.all =a;
}

//
// scia_msg - Transmit message via SCIA
//
void scia_msg(Uint16 * msg)
{
    int i;
    i = 0;
    while(msg[i] != '\n')
    {
        scia_xmit(msg[i]);
        i++;
    }
}

//
// sciaTxFifoIsr - SCIA Transmit FIFO ISR
//
/*interrupt void sciaTxFifoIsr(void)
{
    Uint16 i;

    for(i=0; i< 2; i++)
    {
       SciaRegs.SCITXBUF.all=sdataA[i];  // Send data
    }
    SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;   // Clear SCI Interrupt flag
    PieCtrlRegs.PIEACK.all|=0x100;       // Issue PIE ACK
}*/

//
// sciaRxFifoIsr - SCIA Receive FIFO ISR
//
interrupt void sciaRxFifoIsr(void)
{
    Uint16 i;
    i=(char)ScibRegs.SCIRXBUF.all;  // Read data
    scia_xmit(i);
    ScibRegs.SCIFFRX.bit.RXFFOVRCLR=1;   // Clear Overflow flag
    ScibRegs.SCIFFRX.bit.RXFFINTCLR=1;   // Clear Interrupt flag
    PieCtrlRegs.PIEACK.all|=0x100;       // Issue PIE ack
}

//
// scia_fifo_init - Configure SCIA FIFO
//
void scia_fifo_init()
{
   SciaRegs.SCICCR.all = 0x0007;      // 1 stop bit,  No loopback
                                      // No parity,8 char bits,
                                      // async mode, idle-line protocol
   SciaRegs.SCICTL1.all = 0x0003;     // enable TX, RX, internal SCICLK,
                                      // Disable RX ERR, SLEEP, TXWAKE
   SciaRegs.SCICTL2.bit.TXINTENA = 1;
   SciaRegs.SCICTL2.bit.RXBKINTENA = 1;
   SciaRegs.SCIHBAUD.all =0x00;  // 9600 baud @LSPCLK = 50MHz
                                   //(200 MHz SYSCLK).
   SciaRegs.SCILBAUD.all =0x0F;
   //SciaRegs.SCICCR.bit.LOOPBKENA = 1; // Enable loop back
   SciaRegs.SCIFFTX.all = 0xC022;
   SciaRegs.SCIFFRX.all = 0x0022;
   SciaRegs.SCIFFCT.all = 0x00;

   SciaRegs.SCICTL1.all = 0x0023;     // Relinquish SCI from Reset
   SciaRegs.SCIFFTX.bit.TXFIFORESET = 1;
   SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;

   ScibRegs.SCICCR.all = 0x0007;   // 1 stop bit,  No loopback
                                   // No parity,8 char bits,
                                   // async mode, idle-line protocol
   ScibRegs.SCICTL1.all = 0x0003;  // enable TX, RX, internal SCICLK,
                                   // Disable RX ERR, SLEEP, TXWAKE
   ScibRegs.SCICTL2.all = 0x0003;
   ScibRegs.SCICTL2.bit.TXINTENA = 1;
   ScibRegs.SCICTL2.bit.RXBKINTENA = 1;
   ScibRegs.SCIHBAUD.all = 0x00;
   ScibRegs.SCILBAUD.all = 0x0F;
   ScibRegs.SCICTL1.all = 0x0023;  // Relinquish SCI from Reset
   ScibRegs.SCIFFTX.all = 0xC022;//0xE040;
   ScibRegs.SCIFFRX.all = 0x0022;//0x2044;
   ScibRegs.SCIFFCT.all = 0x0;
   ScibRegs.SCIFFTX.bit.TXFIFORESET = 1;
   ScibRegs.SCIFFRX.bit.RXFIFORESET = 1;
}

//
// End of file
//

  • Hi silsio,

    I'll try and read through the code a little bit, but it is generally hard for us to debug a full program without much else to go on.

    Can you elaborate a little more on what you've tried and what appears to be working, and what doesn't? Is the ISR occurring? Are you getting the expected number of characters? What are the major differences between your working code and this code?
  • I apologize for being too vague. The working code followed this:
    I had start and end markers which helps in forming packets of data. This packet is then converted into floats using atof function as shown here:

    for(;;)
           {
               recvWithStartEndMarkers();
               tmp=atof(receivedChars);
               while(ScibRegs.SCIFFRX.bit.RXFFST == 0) {}
               while (SciaRegs.SCIFFTX.bit.TXFFST != 0) {}
               SciaRegs.SCITXBUF.all = i;
    
           }
    .
    .
    .
    .
    .
    
    void recvWithStartEndMarkers()
    {
       static int recvInProgress = 0;
       static int ndx = 0;
       //char startMarker = '<';
       //char endMarker = '>';
       i=*msg;
       msg=&i;
       *msg=(char)ScibRegs.SCIRXBUF.all;
       if (recvInProgress == 1)
          {
             if (i != '>')
             {
                receivedChars[ndx] = i;
                ndx++;
                if (ndx >= numChars)
                            {
                               ndx = numChars - 1;
                            }
                }
             else
             {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = 0;
                ndx = 0;
             }
          }
          else if (i == '<')
          {
             recvInProgress = 1;
          }
    }
    

    However, this code has to run forever to keep reading the data coming from SCI. My main code has to perform other tasks as well and hence, i dont want to read it forever. I thought that calling an interrupt when required would read the data from SCI once and then send the control back to the main code. However, I am unable to do so. 

    I hope the explanation is clear now.

  • Hi silsio,

    Sorry for the delay. 

    I am unable to understand the flow of your code.

    I think what you want to do is:

    • Get working ISR code that is strictly echo-back, data collection, or re-transmit.
      • When a new character comes, just operate on that single character
    Once you have working ISR code, you can start working on detecting a message.  Each time you get a new character in the ISR:
    • If this is the first character, should be '<', else fail (or maybe just discard the character)
    • If not fail/discard, then add the character to the temp buffer
    • If the character is '>', copy the whole temp buffer to a final message buffer and set a flag for the main code to go process the message when it is ready

    Definitely you want to make sure your ISR is not spin-waiting on anything or waiting for additional characters.  Each entry into the ISR should process one character (or each character in the FIFO one-at-a-time if using FIFO) and return.  

  • Hi silsio,

    Any luck getting this to work?

  • Yes, I was able to get it working.