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.

TMS320F28379D: Problem with duplex SPI data communication

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Tool/software:

I am trying to perform a two way communication between 28379D, one as a master and the other as a slave.

I have been successful to perform one way communication (master -> transmission and slave -> receiver)

But when I try to perform two way communication, i am running into a problem.

Both the master and slave receives correct value sometimes and wrong value sometimes. The wrong values are either the value i am trying to send or some random values.

Code for Master

#include "F28x_Project.h"

void delay_loop(void);
void spi_xmit(Uint16 a);
void spi_fifo_init(void);
void spi_init(void);
void error(void);

volatile Uint16 datasend=40;
void main(void)
{
Uint16 sdata;
Uint16 rdata;

InitSysCtrl();

InitSpiaGpio();

DINT;

InitPieCtrl();

IER = 0x0000;
IFR = 0x0000;

InitPieVectTable();

spi_fifo_init();
InitSpi();

sdata = 1;
for(;;)
{
// Transmit data
spi_xmit(datasend);
DELAY_US(100);
if(SpiaRegs.SPIFFRX.bit.RXFFST != 0) {
rdata = SpiaRegs.SPIRXBUF; // Read received data
}


}
}

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

void error(void)
{
asm(" ESTOP0");
for (;;);
}

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

void spi_fifo_init()
{
SpiaRegs.SPIFFRX.bit.RXFFIL = 0x00;
SpiaRegs.SPIFFRX.bit.RXFFIENA = 0x00; 
SpiaRegs.SPIFFRX.bit.RXFFINTCLR = 0x00;
SpiaRegs.SPIFFRX.bit.RXFFINT = 0x00;
SpiaRegs.SPIFFRX.bit.RXFFST = 0x00; 
SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0x00;
SpiaRegs.SPIFFRX.bit.RXFFOVFCLR = 0x00; 
SpiaRegs.SPIFFRX.bit.RXFFOVF = 0x00; 

SpiaRegs.SPIFFCT.all=0x0;

}


#include "F2837xD_device.h"
#include "F2837xD_Examples.h"

//
// Calculate BRR: 7-bit baud rate register value
// SPI CLK freq = 500 kHz
// LSPCLK freq = CPU freq / 4 (by default)
// BRR = (LSPCLK freq / SPI CLK freq) - 1
//
#if CPU_FRQ_200MHZ
#define SPI_BRR ((200E6 / 4) / 500E3) - 1
#endif

#if CPU_FRQ_150MHZ
#define SPI_BRR ((150E6 / 4) / 500E3) - 1
#endif

#if CPU_FRQ_120MHZ
#define SPI_BRR ((120E6 / 4) / 500E3) - 1
#endif

//
// InitSPI - This function initializes the SPI to a known state
//
void InitSpi(void)
{
// Initialize SPI-A
SpiaRegs.SPICCR.bit.SPISWRESET = 0;

SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
SpiaRegs.SPICTL.bit.CLK_PHASE = 1;
SpiaRegs.SPICCR.bit.CLKPOLARITY = 1;
SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = SPI_BRR;

SpiaRegs.SPICCR.bit.SPICHAR = (16-1);
SpiaRegs.SPIFFTX.bit.SPIFFENA = 0;
SpiaRegs.SPICTL.bit.TALK = 1;
SpiaRegs.SPICTL.bit.SPIINTENA = 1; //Enable SPIINTENA to generate INT_FLAG bit on completion of SPI transmission
SpiaRegs.SPICCR.bit.SPILBK = 0;

SpiaRegs.SPICCR.bit.SPISWRESET = 1;
}

//
void InitSpiGpio()
{
InitSpiaGpio();
}

//
// InitSpiaGpio - Initialize SPIA GPIOs
//
void InitSpiaGpio()
{
EALLOW;

GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0; // Enable pull-up on GPIO16 (SPISIMOA)
GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;
GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;
GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0;

GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO19 (SPISTEA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3; // Asynch input GPIO19 (SPISTEA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3; // Asynch input GPIO19 (SPISTEA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 3; // Asynch input GPIO19 (SPISTEA)

GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3; // Configure GPIO19 as SPISTEA
GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3;
GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3;
GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 3;

GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3; // Configure GPIO19 as SPISTEA
GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3; // Configure GPIO19 as SPISTEA
GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3; // Configure GPIO19 as SPISTEA
GpioCtrlRegs.GPBGMUX2.bit.GPIO61 = 3; // Configure GPIO19 as SPISTEA

EDIS;
}

//
// End of file
//

Code for Slave

#include "F28x_Project.h"

void delay_loop(void);
void spi_xmit(Uint16 a);
void spi_fifo_init(void);
void spi_init(void);
void error(void);
volatile Uint16 datasend = 450; // send data

Uint16 rdata; // received data
void main(void)
{
InitSysCtrl();
InitSpiaGpio();
DINT;

InitPieCtrl();

IER = 0x0000;
IFR = 0x0000;

InitPieVectTable();

spi_fifo_init(); // Initialize the SPI FIFO
InitSpi();
for(;;)
{
spi_xmit(datasend); // Send data
DELAY_US(100);
if(SpiaRegs.SPIFFRX.bit.RXFFST != 0) {
rdata = SpiaRegs.SPIRXBUF; // Read received data to clear RX FIFO
}
}
}


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

void spi_xmit(Uint16 a)
{
// while (SpiaRegs.SPIFFTX.bit.TXFFST >= 16) {} // Wait if TX FIFO is full
SpiaRegs.SPITXBUF = a;
}

void spi_fifo_init()
{

SpiaRegs.SPIFFRX.bit.RXFFIL = 0x00; 
SpiaRegs.SPIFFRX.bit.RXFFIENA = 0x00; 
SpiaRegs.SPIFFRX.bit.RXFFINTCLR = 0x00; 
SpiaRegs.SPIFFRX.bit.RXFFINT = 0x00; 
SpiaRegs.SPIFFRX.bit.RXFFST = 0x00; 
SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0x00;
SpiaRegs.SPIFFRX.bit.RXFFOVFCLR = 0x00; 
SpiaRegs.SPIFFRX.bit.RXFFOVF = 0x00; 

SpiaRegs.SPIFFCT.all=0x0;

}
#include "F2837xD_device.h"
#include "F2837xD_Examples.h"

//
// Calculate BRR: 7-bit baud rate register value
// SPI CLK freq = 500 kHz
// LSPCLK freq = CPU freq / 4 (by default)
// BRR = (LSPCLK freq / SPI CLK freq) - 1
//
#if CPU_FRQ_200MHZ
#define SPI_BRR ((200E6 / 4) / 500E3) - 1
#endif

#if CPU_FRQ_150MHZ
#define SPI_BRR ((150E6 / 4) / 500E3) - 1
#endif

#if CPU_FRQ_120MHZ
#define SPI_BRR ((120E6 / 4) / 500E3) - 1
#endif

//
// InitSPI - This function initializes the SPI to a known state
//
void InitSpi(void)
{
// Initialize SPI-A
SpiaRegs.SPICCR.bit.SPISWRESET = 0;

SpiaRegs.SPICTL.bit.MASTER_SLAVE = 0;
SpiaRegs.SPICTL.bit.CLK_PHASE = 1;
SpiaRegs.SPICCR.bit.CLKPOLARITY = 1;
SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = SPI_BRR;

SpiaRegs.SPICCR.bit.SPICHAR = (16-1);
SpiaRegs.SPIFFTX.bit.SPIFFENA = 0;
SpiaRegs.SPICTL.bit.TALK = 1; //Receiver mode enabled
SpiaRegs.SPICTL.bit.SPIINTENA = 1;
SpiaRegs.SPICCR.bit.SPILBK = 0;

SpiaRegs.SPICCR.bit.SPISWRESET = 1;
}


void InitSpiGpio()
{
InitSpiaGpio();
}

//
// InitSpiaGpio - Initialize SPIA GPIOs
//
void InitSpiaGpio()
{
EALLOW;

GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0; // Enable pull-up on GPIO58 (SPISIMOA)
GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0; // Enable pull-up on GPIO59 (SPISOMIA)
GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0; // Enable pull-up on GPIO60 (SPICLKA)
GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0; // Enable pull-up on GPIO61 (SPISTEA)

GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO58 (SPISIMOA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3; // Asynch input GPIO59 (SPISOMIA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3; // Asynch input GPIO60 (SPICLKA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 3; // Asynch input GPIO61 (SPISTEA)

GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3; // Configure GPIO58 as SPISIMOA
GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3; // Configure GPIO59 as SPISOMIA
GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3; // Configure GPIO60 as SPICLKA
GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 3; // Configure GPIO61 as SPISTEA

GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3; // Configure GPIO58 as SPISIMOA
GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3; // Configure GPIO59 as SPISOMIA
GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3; // Configure GPIO60 as SPICLKA
GpioCtrlRegs.GPBGMUX2.bit.GPIO61 = 3; // Configure GPIO61 as SPISTEA

EDIS;
}

//
// End of file
//

Oscilloscope Data

Yellow : MOSI

Pink: Clock Select

Blue: MISO

The data seems to be mostly correct for MOSI but in MISO, there are more errors.

Could someone help me with this issue?

I tried using FIFO but in that case the slave seems to get stuck.

  • Hello,

    Have you already been referencing our C2000Ware software examples? If not, please be sure to do so as reference.

    • Bitfield-based examples: C:\ti\c2000\C2000Ware_5_02_00_00\device_support\f2837xd\examples\cpu1
    • Driverlib-based examples: C:\ti\c2000\C2000Ware_5_02_00_00\driverlib\f2837xd\examples\cpu1\spi
      • There is an external loopback example here that communicated between two SPI modules that you may find helpful.

    Most of these examples implement FIFO mode as well - what do you mean it "gets stuck" when trying to implement FIFO? Please also be sure to take a look at the configurations to compare your initializations, and debug using the "step into" and "step over" debug buttons while monitoring the SPI registers in CCS (using continuous refresh) to verify your program function - let me know the results/any findings.

    Best Regards,

    Allison

  • Thank you for the suggestion.

    I have taken a look at this example,

    Driverlib-based examples: C:\ti\c2000\C2000Ware_5_02_00_00\driverlib\f2837xd\examples\cpu1\spi


    The loopback example with interrupt works. So, I tried rewriting it for the same setup as before. i.e. Two 28379d communicating with each other.

    The code of Master

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include "F28x_Project.h"
    volatile Uint16 sdata[2]; // Send data buffer
    Uint16 rdata[2]; // Receive data buffer
    Uint16 rdata_point; // Keep track of where we are
    volatile Uint16 send1 = 520;
    volatile Uint16 send2 = 550;
    void delay_loop(void);
    void spi_fifo_init(void);
    void error();
    void main(void)
    {
    Uint16 i;
    InitSysCtrl();
    InitSpiaGpio();
    DINT;
    IER = 0x0000;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    The setup for Master

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include "F2837xD_device.h"
    #include "F2837xD_Examples.h"
    #if CPU_FRQ_200MHZ
    #define SPI_BRR ((200E6 / 4) / 500E3) - 1
    #endif
    #if CPU_FRQ_150MHZ
    #define SPI_BRR ((150E6 / 4) / 500E3) - 1
    #endif
    #if CPU_FRQ_120MHZ
    #define SPI_BRR ((120E6 / 4) / 500E3) - 1
    #endif
    //
    // InitSPI - This function initializes the SPI to a known state
    //
    void InitSpi(void)
    {
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    The code for Slave

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include "F28x_Project.h"
    Uint16 sdata[2]; // Send data buffer
    Uint16 rdata[2]; // Receive data buffer
    Uint16 rdata_point; // Keep track of where we are
    // in the data stream to check received data
    volatile Uint16 send1 = 420;
    volatile Uint16 send2 = 450;
    void delay_loop(void);
    void spi_fifo_init(void);
    void error();
    void main(void)
    {
    Uint16 i;
    InitSysCtrl();
    InitSpiaGpio();
    DINT;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    The setup for Slave

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include "F2837xD_device.h"
    #include "F2837xD_Examples.h"
    #if CPU_FRQ_200MHZ
    #define SPI_BRR ((200E6 / 4) / 500E3) - 1
    #endif
    #if CPU_FRQ_150MHZ
    #define SPI_BRR ((150E6 / 4) / 500E3) - 1
    #endif
    #if CPU_FRQ_120MHZ
    #define SPI_BRR ((120E6 / 4) / 500E3) - 1
    #endif
    void InitSpi(void)
    {
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 1;
    SpiaRegs.SPICCR.bit.SPICHAR = (16-1);
    SpiaRegs.SPICCR.bit.SPILBK = 0;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    The Problem

    The problem now is that both the master and slave receives random value

      

    And the clock select line has some peaks as well.
    Furthermore, in these instances the clock signal as disturbances as well

  • Hi,

    Apologies for some delay, but please allow for another 1-2 days for me to review this information. Thanks for the patience!

    Best Regards,

    Allison

  • Hello,

    I wanted to ask to check if there is any issue with hardware connections/a custom PCB? The signals scoped out in the images do not look clean to me. Also, can you please label the lines so I know which is which? We should clearly see the chip select going low during communication, the clock pulses, and clean data being transmitted on each line.

    Is what you see on the scope matching what you see in the registers? Or are you saying the correct data is being sent on the lines, but wrong data received in software?

    Best Regards,

    Allison

  • Hello,

    I reviewed my connections as per your suggestion and I realized that the two DSP boards should share a common ground. This resolved my noisy signal problem. As for the chip select problem, in the master DSP, I forced GIPO61 low for data transmission and high after the completion of the data transmission.
    Further, I used while loop for monitoring FF registor and set (SpiaRegs.SPIFFRX.bit.RXFFST != 2) because I was sending two data as a time.

    The only part that I dont understand now is why there is some signal in SPISOMIA (blue) when GIPO61 (Clock Select, Yellow) is high. But it is not affecting data transmission so I would say that my issue is resolved!

    Thank you for all your help!

    Warm Regards,

    Bijen Mali

  • Glad to hear it is resolved! I will go ahead and close this thread. Feel free to open a new one should you run into issues.

    Best Regards,

    Allison