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.

TMS320F28388D: Issue in configuring SPIA registers for TMS320F28388D control card

Part Number: TMS320F28388D
Other Parts Discussed in Thread: TMS320F28377D, C2000WARE

Hello,

We have interfaced TMC5130A motor driver IC with TMS320F28388D and TMS320F28377D controller Card via SPI to rotate a Stepper Motor.

We have done SPI Configuration as mentioned in the datasheet of the TMC5130A Driver IC  as mentioned below

SPI Mode : 3 

Clock Speed : 1MHz

SPI word Length : 8

Chip select becomes low during data transmission

SPI A : GPIO16 - MISO

            GPIO17 - MOSI

            GPIO18 - CLK

            GPIO20 - CSN

We are able to see the data on the MOSI lines of the controller.

But Motor is rotating when interfaced TMS320F28377D controller not with TMS320F28388D even though we have migrated the same code from control suit to C2000.

Initially we tried to configure the SPI with inbuilt APIs provided in C2000 ware but then changed to direct register settings taking into reference the example code spi_ex1_loopback .

SPI Code for TMS320F28377D:

void InitSpiaGpio()  //setting the SPIA GPIO Registers
{

EALLOW;

/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; // Enable pull-up on GPIO16 (SPISIMOA)
// GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0; // Enable pull-up on GPIO5 (SPISIMOA)
GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; // Enable pull-up on GPIO17 (SPISOMIA)
// GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0; // Enable pull-up on GPIO3 (SPISOMIA)
GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0; // Enable pull-up on GPIO18 (SPICLKA)
GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0; // Enable pull-up on GPIO19 (SPISTEA)

/* Set qualification for selected pins to asynch only */
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.

GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; // Asynch input GPIO16 (SPISIMOA)
// GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 3; // Asynch input GPIO5 (SPISIMOA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch input GPIO17 (SPISOMIA)
// GpioCtrlRegs.GPAQSEL1.bit.GPIO3 = 3; // Asynch input GPIO3 (SPISOMIA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch input GPIO18 (SPICLKA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3; // Asynch input GPIO19 (SPISTEA)

/* Configure SPI-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be SPI functional pins.
// Comment out other unwanted lines.

GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
// GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 2; // Configure GPIO5 as SPISIMOA
GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
// GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 2; // Configure GPIO3 as SPISOMIA
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA

EDIS;
}

void spi_fifo_init()
{
// Initialize SPI FIFO registers
SpiaRegs.SPIFFTX.all=0xE040;
SpiaRegs.SPIFFRX.all=0x2044;
SpiaRegs.SPIFFCT.all=0x0;
}

void spi_init()    This function initializes the SPI to a known state
{

// Set reset low before configuration changes
// Clock polarity (0 == rising, 1 == falling)
// 8-bit character
// disable loop-back
SpiaRegs.SPICCR.bit.SPISWRESET = 0;
SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
SpiaRegs.SPICCR.bit.SPICHAR = 7; //8 bit
SpiaRegs.SPICCR.bit.SPILBK = 0;

// Enable master (0 == slave, 1 == master)
// Enable transmission (Talk)
// Clock phase (0 == normal, 1 == delayed)
// SPI interrupts are disabled
SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
SpiaRegs.SPICTL.bit.TALK = 1;
SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
SpiaRegs.SPICTL.bit.SPIINTENA = 0;

// Set the baud rate
SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 0x31; //1 MHz

// Set FREE bit
// Halting on a breakpoint will not halt the SPI
SpiaRegs.SPIPRI.bit.FREE = 1;

// Release the SPI from reset
SpiaRegs.SPICCR.bit.SPISWRESET = 1;
}

SPI Code for TMS320F28388D:

void spi_gpio(void)
{
EALLOW;

/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; // Enable pull-up on GPIO16 (SPISIMOA)
GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; // Enable pull-up on GPIO17 (SPISOMIA)
GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0; // Enable pull-up on GPIO18 (SPICLKA)
GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0; // Enable pull-up on GPIO19 (SPISTEA)

/* Set qualification for selected pins to asynch only */
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.

GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; // Asynch input GPIO16 (SPISIMOA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch input GPIO17 (SPISOMIA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch input GPIO18 (SPICLKA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3; // Asynch input GPIO19 (SPISTEA)

/* Configure SPI-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be SPI functional pins.
// Comment out other unwanted lines.

GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA

EDIS;
}

void initSPIFIFO(void)
{
//
// Initialize SPI FIFO registers
//
SpiaRegs.SPIFFTX.all = 0xE040;
SpiaRegs.SPIFFRX.all = 0x2044;
SpiaRegs.SPIFFCT.all = 0x0;

//
// Initialize core SPI registers
//
InitSpi();
}

//
// InitSPI - This function initializes the SPI to a known state
//
void InitSpi(void)
{
//
// Initialize SPI-A
//

//
// Set reset low before configuration changes
// Clock polarity (0 == rising, 1 == falling)
// 8-bit character
// Disable loop-back
//
SpiaRegs.SPICCR.bit.SPISWRESET = 0;
SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
SpiaRegs.SPICCR.bit.SPICHAR = 7;
SpiaRegs.SPICCR.bit.SPILBK = 0;

//
// Enable master (0 == slave, 1 == master)
// Enable transmission (Talk)
// Clock phase (0 == normal, 1 == delayed)
// SPI interrupts are disabled
//
SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
SpiaRegs.SPICTL.bit.TALK = 1;
SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
SpiaRegs.SPICTL.bit.SPIINTENA = 0;

//
// Set the baud rate using a 1 MHz SPICLK
// BRR = (LSPCLK / SPICLK) - 1
//
SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 0x31;

// Set FREE bit
// Halting on a breakpoint will not halt the SPI
//
SpiaRegs.SPIPRI.bit.FREE = 1;

//
// Release the SPI from reset
//
SpiaRegs.SPICCR.bit.SPISWRESET = 1;
}

Is there any changes that we need to take into account while migrating from TMS320F28377D to TMS320F28377D with respect to SPIA configuration?

Code for TMS320F28377D is below

//###########################################################################
// FILE:   Example_2837xDSpi_FFDLB.c
// TITLE:  SPI Digital Loop Back program.
//
//! \addtogroup cpu01_example_list
//! <h1>SPI Digital Loop Back (spi_loopback)</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. Interrupts are not used.
//!
//!  A stream of data is sent and then compared to the received stream.
//!  The sent data looks like this: \n
//!  0000 0001 0002 0003 0004 0005 0006 0007 .... FFFE FFFF \n
//!  This pattern is repeated forever.
//!
//!  \b Watch \b Variables \n
//!  - \b sdata - sent data
//!  - \b rdata - received data
//
//###########################################################################
// $TI Release: F2837xD Support Library v190 $
// $Release Date: Mon Feb  1 16:51:57 CST 2016 $
// $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated -
//             http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################

#include "F28x_Project.h"     // Device Headerfile and Examples Include File
#include "stdio.h"
// Prototype statements for functions found within this file.
// __interrupt void ISRTimer2(void);
void delay_loop(void);
void spi_xmit(Uint16 a);
void spi_fifo_init(void);
void spi_init(void);
void error(void);
void sendDataToDriver(Uint16 address, Uint32 sdata);
void main(void)
{
    //Uint8  addres;
    Uint32 sdata;  // send data


// 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();  // Skipped for this example
// Setup only the GP I/O only for SPI-A functionality
// This function is found in F2837xD_Spi.c
   InitSpiaGpio();

// 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();

// Step 4. Initialize the Device Peripherals:
   spi_fifo_init();   // Initialize the Spi FIFO
   spi_init();        // init SPI

// Step 5. User specific code:
// Interrupts are not used in this example.
   sdata = 0x1122FF55;
/*
   sendDataToDriver(0xEC00,0x000100C3);  //CHOPCONF: TOFF=3, HSTRT=4, HEND=1, TBL=2, CHM=0 (SpreadCycle)
   delay_loop();
   sendDataToDriver(0X9000,0x00060603); // IHOLD_IRUN: IHOLD=03, IRUN=06 , IHOLDDELAY=6
   delay_loop();
   sendDataToDriver(0x9100,0x0000000A); // TPOWERDOWN=10: Delay before power down in stand still
   delay_loop();
   sendDataToDriver(0x8000,0x00000004); // EN_PWM_MODE=1 enables StealthChop (with default PWMCONF)
   delay_loop();
   sendDataToDriver(0x9300,0x000001F4); // TPWM_THRS=500 yields a switching velocity about 35000 = ca. 30RPM
   delay_loop();
   sendDataToDriver(0xF000,0x000401C8);  // PWMCONF: AUTO=1, 2/1024 Fclk, Switch amplitude limit=200, Grad=1
   delay_loop();


     sendDataToDriver(0xA400,0x000003E8); // A1 = 1000 First acceleration
   //sendDataToDriver(0xA400,0x000000E8); // A1 = 1000 First acceleration
   delay_loop();
    sendDataToDriver(0xA500,0x0000C350); // V1 = 50000 Acceleration threshold velocity V1
 //  sendDataToDriver(0xA500,0x00000100);
   delay_loop();
    sendDataToDriver(0xA600,0X000001F4); // AMAX = 500 Acceleration above V1
  // sendDataToDriver(0xA600,0X00000125); // A = 500 Acceleration above V1
   delay_loop();
     sendDataToDriver(0XA700,0x00030D40); // VMAX = 200000
  // sendDataToDriver(0XA700,0x0000D167); // V = 500
   delay_loop();
     sendDataToDriver(0xA800,0x000002BC); // DMAX = 700 Deceleration above V1
 // sendDataToDriver(0xA800,0x000002BC);
   delay_loop();
     sendDataToDriver(0xAA00,0x00000578); // D1 = 1400 Deceleration below V1
  // sendDataToDriver(0xAA00,0x000001E8); // D1 = 1400 Deceleration below V1
   delay_loop();
    sendDataToDriver(0xAB00,0x0000000A); // VSTOP = 10 Stop velocity (Near to zero)
   delay_loop();
   sendDataToDriver(0xA000,0x000000000); // RAMPMODE = 0 (Target position move)
   delay_loop();
  // sendDataToDriver(0xAD00,0x7FFFFFFF);  MAX No of ROTATION
   sendDataToDriver(0xAD00,0xFFFF3800); // XTARGET
   delay_loop();

   sendDataToDriver(0x2100,0x00000000); // Query XACTUAL – The next read access delivers XACTUAL
   delay_loop();
 //  sendDataToDriver(0xA600,0X00000125); // A = 500 Acceleration above V1
  //   delay_loop();
   //  sendDataToDriver(0XA700,0x00000000); // VMAX = 500
  //   delay_loop();
  // sendDataToDriver(0xAD00,0x00000000); // XTARGET
  // delay_loop();
 //  sendDataToDriver(0x2100,0x00000000);
 //  delay_loop();
 //  sendDataToDriver(0xAD00,0xFFFF9C00);
  // delay_loop();
 //  sendDataToDriver(0x2100,0x00000000);
 //  delay_loop();
 //  sendDataToDriver(0xAD00,0x00000000);
   delay_loop();
*/
   sendDataToDriver(0xEC00,0x000100C3);
    delay_loop();
    sendDataToDriver(0X9000,0x00060603);
    delay_loop();
    sendDataToDriver(0x9100,0x0000000A);
    delay_loop();
    sendDataToDriver(0x8000,0x00000004);
    delay_loop();
    sendDataToDriver(0x9300,0x000001F4);
    delay_loop();
    sendDataToDriver(0xF000,0x000401C8);
    delay_loop();
    sendDataToDriver(0xA400,0x000003E8);
    delay_loop();
    sendDataToDriver(0xA500,0x0000C350);
    delay_loop();
    sendDataToDriver(0xA600,0X000001F4);
    delay_loop();
    sendDataToDriver(0XA700,0x00030D40);
    delay_loop();
    sendDataToDriver(0xA800,0x000002BC);
    delay_loop();
    sendDataToDriver(0xAA00,0x00000578);
    delay_loop();
    sendDataToDriver(0xAB00,0x0000000A);
    delay_loop();
    sendDataToDriver(0xA000,0x00000000);
    delay_loop();
    sendDataToDriver(0xAD00,0xFFFF3800);
    delay_loop();
    sendDataToDriver(0x2100,0x00000000);
    delay_loop();
    sendDataToDriver(0x2100,0x00000000);
    delay_loop();
    sendDataToDriver(0x2100,0x00000000);
    delay_loop();
    sendDataToDriver(0xAD00,0x00000000);
    delay_loop();
/*   for(;;)
   {
     // Transmit data
       spi_xmit(sdata1);
       spi_xmit(sdata2);
       spi_xmit(sdata3);
       spi_xmit(sdata4);
       //spi_xmit(0X2288);

     // Wait until data is received
    // while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
     rdata = SpiaRegs.SPIRXBUF;
     printf("Rdata = %X\n", rdata);
     // Check against sent data

     delay_loop();
    // if(rdata != sdata) error();
  //   sdata++;
   }
   */
}

// Step 7. Insert all local Interrupt Service Routines (ISRs) and functions here:

void delay_loop()
{
    long      i;
    for (i = 0; i < 1000000; i++) {}
}

void error(void)
{
    asm("     ESTOP0");                     // Test failed!! Stop!
    for (;;);
}

void spi_init()
{
   /* SpiaRegs.SPICCR.all =0x000F;                 // Reset on, rising edge, 16-bit char bits
    SpiaRegs.SPICTL.all =0x0006;                 // Enable master mode, normal phase,
                                                 // enable talk, and SPI int disabled.
    SpiaRegs.SPIBRR.all =0x0031;
    SpiaRegs.SPICCR.all =0x009F;                 // Relinquish SPI from Reset
    SpiaRegs.SPIPRI.bit.FREE = 1;                // Set so breakpoints don't disturb xmission
    */
    // Set reset low before configuration changes
       // Clock polarity (0 == rising, 1 == falling)
       // 16-bit character
       // Enable loop-back
       SpiaRegs.SPICCR.bit.SPISWRESET = 0;
       SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;//navya //0
      // SpiaRegs.SPICCR.bit.SPICHAR = (16-1);
       SpiaRegs.SPICCR.bit.SPICHAR = 7; //8 bit
       SpiaRegs.SPICCR.bit.SPILBK = 0;

       // Enable master (0 == slave, 1 == master)
       // Enable transmission (Talk)
       // Clock phase (0 == normal, 1 == delayed)
       // SPI interrupts are disabled
       SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
       SpiaRegs.SPICTL.bit.TALK = 1;
       SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
       SpiaRegs.SPICTL.bit.SPIINTENA = 0;

       // Set the baud rate
       SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 0x31; //navya

       // Set FREE bit
       // Halting on a breakpoint will not halt the SPI
       SpiaRegs.SPIPRI.bit.FREE = 1;

       // Release the SPI from reset
       SpiaRegs.SPICCR.bit.SPISWRESET = 1;
}

void spi_xmit(Uint16 a)
{
    SpiaRegs.SPITXBUF=a;
}

void spi_fifo_init()
{
// Initialize SPI FIFO registers
    SpiaRegs.SPIFFTX.all=0xE040;
    SpiaRegs.SPIFFRX.all=0x2044;
    SpiaRegs.SPIFFCT.all=0x0;
}

void sendDataToDriver(Uint16 address, Uint32 sdata)
{
    Uint16 sdata1;
    Uint16 sdata2;
    Uint16 sdata3;
    Uint16 sdata4;
    Uint16 rdata=0xFFFF;  // received data
    sdata1 =(sdata>>16) & 0XFF00;
    sdata2 =(sdata>>8) & 0XFF00;
    sdata3 =(sdata) & 0XFF00;
    sdata4 = (sdata<<8) & 0XFF00;


    spi_xmit(address);
   //  Wait until data is received
  //  while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
 //   rdata = SpiaRegs.SPIRXBUF;
    spi_xmit(sdata1);
    // Wait until data is received
  //  while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
  //  rdata = SpiaRegs.SPIRXBUF;
    spi_xmit(sdata2);
   //  Wait until data is received
  //  while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
  //  rdata = SpiaRegs.SPIRXBUF;
    spi_xmit(sdata3);
   //  Wait until data is received
  //  while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
   // rdata = SpiaRegs.SPIRXBUF;
    spi_xmit(sdata4);
   //  Wait until data is received
  //  while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
  // rdata = SpiaRegs.SPIRXBUF;
// delay_loop();

}
//===========================================================================
// No more.
//===========================================================================


code for TMS320F28388D controller

//###########################################################################
//
// FILE:   spi_ex1_loopback.c
//
// TITLE:  SPI Digital Loop Back Example.
//
//! \addtogroup bitfield_example_list
//! <h1>SPI Digital Loop Back </h1>
//!
//!  This program uses the internal loop back test mode of the peripheral.
//!  Other than boot mode pin configuration, no other hardware configuration
//!  is required. Interrupts are not used.
//!
//!  A stream of data is sent and then compared to the received stream.
//!  The sent data looks like this: \n
//!  0000 0001 0002 0003 0004 0005 0006 0007 .... FFFE FFFF \n
//!  This pattern is repeated forever.
//!
//!  \b Watch \b Variables \n
//!  - \b sdata - sent data
//!  - \b rdata - received data
//!
//
//###########################################################################
//
//
// $Copyright:
// Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.co/
//
// 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"

//
// Function Prototypes
//
void transmitData(uint16_t a);
void initSPIFIFO(void);
void error(void);
void InitSpi(void);
void sendDataToDriver(Uint16 address, Uint32 sdata);
void delay_loop(void);
void spi_gpio(void);
void main(void)
{
    uint16_t sdata;  // sent data
    uint16_t rdata;  // received data

    //
    // Initialize device clock and peripherals
    //
    InitSysCtrl();

    //
    // Disable CPU interrupts
    //
    DINT;
    spi_gpio();
    //
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    //
    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)
    //
    InitPieVectTable();

    //
    // Set up SPI, initializing it for FIFO mode
    //
    initSPIFIFO();

    //
    // Loop forever. Suspend or place breakpoints to observe the buffers.
    //
    sdata = 0x0000;
   ////////////////////////////////////////////////////////////

    sendDataToDriver(0xEC00,0x000100C3);
    delay_loop();
   sendDataToDriver(0X9000,0x00060603);
    delay_loop();
    sendDataToDriver(0x9100,0x0000000A);
    delay_loop();
    sendDataToDriver(0x8000,0x00000004);
    delay_loop();
    sendDataToDriver(0x9300,0x000001F4);
    delay_loop();
    sendDataToDriver(0xF000,0x000401C8);
    delay_loop();
    sendDataToDriver(0xA400,0x000003E8);
    delay_loop();
    sendDataToDriver(0xA500,0x0000C350);
    delay_loop();
    sendDataToDriver(0xA600,0X000001F4);
    delay_loop();
    sendDataToDriver(0XA700,0x00030D40);
    delay_loop();
    sendDataToDriver(0xA800,0x000002BC);
    delay_loop();
    sendDataToDriver(0xAA00,0x00000578);
    delay_loop();
    sendDataToDriver(0xAB00,0x0000000A);
    delay_loop();
    sendDataToDriver(0xA000,0x00000000);
    delay_loop();
    sendDataToDriver(0xAD00,0xFFFF3800);
    delay_loop();
    sendDataToDriver(0x2100,0x00000000);
    delay_loop();
    sendDataToDriver(0x2100,0x00000000);
    delay_loop();
    sendDataToDriver(0x2100,0x00000000);
    delay_loop();
    sendDataToDriver(0xAD00,0x00000000);
    delay_loop();
    //////////////////////////////////////
   /*
   for(;;)
    {
        //
        // Transmit data
        //
        transmitData(sdata);

        //
        // Wait until data is received
        //
        while(SpiaRegs.SPIFFRX.bit.RXFFST != 1)
        {

        }

        //
        // Check against sent data
        //
        rdata = SpiaRegs.SPIRXBUF;
        if(rdata != sdata)
        {
            error();
        }
        sdata++;
    }
*/


}

//
// error - Error function that halts the debugger
//
void error(void)
{
    asm("     ESTOP0");     // Test failed!! Stop!
    for(;;);
}

//
// transmitData - Transmit value via SPI
//
void transmitData(uint16_t a)
{
    SpiaRegs.SPITXBUF = a;
}

//
// initSPIFIFO - Initialize SPIA FIFO
//
void initSPIFIFO(void)
{
    //
    // Initialize SPI FIFO registers
    //
    SpiaRegs.SPIFFTX.all = 0xE040;
    SpiaRegs.SPIFFRX.all = 0x2044;
    SpiaRegs.SPIFFCT.all = 0x0;

    //
    // Initialize core SPI registers
    //
    InitSpi();
}

//
// InitSPI - This function initializes the SPI to a known state
//
void InitSpi(void)
{
    //
    // Initialize SPI-A
    //

    //
    // Set reset low before configuration changes
    // Clock polarity (0 == rising, 1 == falling)
    // 16-bit character
    // Enable loop-back
    //
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
    SpiaRegs.SPICCR.bit.SPICHAR = 7;
    SpiaRegs.SPICCR.bit.SPILBK = 0;

    //
    // Enable master (0 == slave, 1 == master)
    // Enable transmission (Talk)
    // Clock phase (0 == normal, 1 == delayed)
    // SPI interrupts are disabled
    //
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
    SpiaRegs.SPICTL.bit.TALK = 1;
    SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
    SpiaRegs.SPICTL.bit.SPIINTENA = 0;

    //
    // Set the baud rate using a 1 MHz SPICLK
    // BRR = (LSPCLK / SPICLK) - 1
    //
    SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 0x31;

    // Set FREE bit
    // Halting on a breakpoint will not halt the SPI
    //
    SpiaRegs.SPIPRI.bit.FREE = 1;

    //
    // Release the SPI from reset
    //
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;
}


void sendDataToDriver(Uint16 address, Uint32 sdata)
{
    Uint16 sdata1;
    Uint16 sdata2;
    Uint16 sdata3;
    Uint16 sdata4;
    Uint16 rdata=0xFFFF;  // received data
    sdata1 =(sdata>>16) & 0XFF00;
    sdata2 =(sdata>>8) & 0XFF00;
    sdata3 =(sdata) & 0XFF00;
    sdata4 = (sdata<<8) & 0XFF00;


    transmitData(address);
   //  Wait until data is received
  //  while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
 //   rdata = SpiaRegs.SPIRXBUF;
    transmitData(sdata1);
    // Wait until data is received
  //  while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
  //  rdata = SpiaRegs.SPIRXBUF;
    transmitData(sdata2);
   //  Wait until data is received
  //  while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
  //  rdata = SpiaRegs.SPIRXBUF;
    transmitData(sdata3);
   //  Wait until data is received
  //  while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
   // rdata = SpiaRegs.SPIRXBUF;
    transmitData(sdata4);
   //  Wait until data is received
  //  while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
  // rdata = SpiaRegs.SPIRXBUF;
// delay_loop();

}
void delay_loop()
{
    long      i;
    for (i = 0; i < 1000000; i++) {}
}

void spi_gpio(void)
{
    EALLOW;

    /* Enable internal pull-up for the selected pins */
    // Pull-ups can be enabled or disabled by the user.
    // This will enable the pullups for the specified pins.
    // Comment out other unwanted lines.

        GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;   // Enable pull-up on GPIO16 (SPISIMOA)
    //  GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0;    // Enable pull-up on GPIO5 (SPISIMOA)
        GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;   // Enable pull-up on GPIO17 (SPISOMIA)
    //  GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0;    // Enable pull-up on GPIO3 (SPISOMIA)
        GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;   // Enable pull-up on GPIO18 (SPICLKA)
        GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;   // Enable pull-up on GPIO19 (SPISTEA)

    /* Set qualification for selected pins to asynch only */
    // This will select asynch (no qualification) for the selected pins.
    // Comment out other unwanted lines.

        GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; // Asynch input GPIO16 (SPISIMOA)
    //  GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 3;  // Asynch input GPIO5 (SPISIMOA)
        GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch input GPIO17 (SPISOMIA)
    //  GpioCtrlRegs.GPAQSEL1.bit.GPIO3 = 3;  // Asynch input GPIO3 (SPISOMIA)
        GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch input GPIO18 (SPICLKA)
        GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3; // Asynch input GPIO19 (SPISTEA)

    /* Configure SPI-A pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be SPI functional pins.
    // Comment out other unwanted lines.

        GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
    //  GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 2;  // Configure GPIO5 as SPISIMOA
        GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
    //  GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 2;  // Configure GPIO3 as SPISOMIA
        GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
        GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA

        EDIS;
}
//
// End of file
//

Also Attaching the oscilloscope image:

Any input will be really helpful.

Thanks in advance

Navya Anna Prince

  • Navya,

    SPI module is pretty much the same between F28377D and F28388. So, the same configuration code work the same for both the devices. From SPI perspective, it should work same.

    But, F28377D and F28388 are two different devices, please check Migration Between TMS320F2837x and TMS320F2838x

    What exactly are you trying to transmit and what are you expecting to receive? I also don't know what to make out of your oscilloscope picture.

    Regards,

    Manoj

  • Hello manoj,

    Thanks for the reply.

    I understand from SPI perspective there is no difference between  F28377D and F28388.

    I have used SPI loopBack example code provided in C2000 for building my code. I assume any extra configuration needed for F28388 will be dealt there.

    I also checked the document you mentioned above for any extra device configuration that needed to be enabled.

    We are trying to transmit 40 bytes (8 Bytes Address + 32 Byte Data) of data by transmitting 8 bytes five times. We have configured SPI word length as 8 and speed as 1MHz. But we are not receiving the expected result in MISO lines.

    One more thing we observed is that example code spi_ex1_loopback.c present in the following path \ti\c2000\c2000\C2000Ware_4_00_00_00\device_support\f2838x\examples\cpu1\spi does not have any function to enable the SPI_GPIOs. Why is that?

    Thanks

    Navya Anna Prince

  • spi_ex1_loopback.c example doesn't require SPI GPIO to be configured because SPIMOSI and SPIMISO signals get internally connected. This example is generally used for validating SPI in self test mode. It is not used in typical usecase.

    I would encourage you to use SPI driverlib function available in C:\ti\c2000\C2000Ware_4_00_00_00\driverlib\f2838x\

    and check functions like SPI_transmitNBytes(base, txBuffer, numOfWords, txDelay). This would allow you not worry about SPI configurations etc as it is taken care for you.

    With regards to you receiving unexpected value on MISO lines, I cannot be of any help as I don't have access to your hardware. You need do debug to understand what is going wrong.

    Regards,

    Manoj