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.

TMS320F28377S: SPI not working as expected

Part Number: TMS320F28377S

Hi all,

I have tried to implement a basic SPI single character read/write without complete success.  I can provide more details if necessary, but let me start off with the basics and we'll see if I can uncover my mistake.

Setup:  I'm using a USB to SPI converter (MCP2210) to send out a character on the SPI channel to the MCU slave.  In firmware, on Rx interrupt, I read the input and then write a character (of whatever value I assign in the debug watch window).  No FIFO buffers.  All muxes are correctly turned on.  Interrupt code is: 

__interrupt void spiRxIsr(void)
{
	SpicRegs.SPIFFRX.bit.RXFFOVFCLR=1;  // Clear Overflow flag
	SpicRegs.SPIFFRX.bit.RXFFINTCLR=1;  // Clear Interrupt flag
	PieCtrlRegs.PIEACK.all |= M_INT6;   // Issue PIE ACK

	spiRxData = SpicRegs.SPIDAT;   //SpiRxData is Uint16
	SpicRegs.SPIDAT = spiTxData;   //spiTxData is Uint16
}

So the results are odd for both the value read and the value written (and read on my PC).  It appears that the the SPIDAT register doesn't get fully flushed after each read and so the values I'm writing in continue to shift bit by bit.  It is inconsistent even, and for several read/write cycles the data read and sent is correct.  Let me know if I'm missing something or should try something in particular.  I have spent a while and tried many combinations of things without seeing an improvement.

Here's my initializing code:

//
// InitSPI - This function initializes the SPI to a known state
//

void SPI_InitSpiC(void)
{
// Initialize SPI-C

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

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

// Halting on a breakpoint will not halt the SPI

SpicRegs.SPIPRI.bit.FREE = 1;


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

//
// InitSpicGpio - Initialize *** GPIOs
//
void SPI_InitSpiCGpio()
{
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.GPCPUD.bit.GPIO69 = 0; // Enable pull-ups
GpioCtrlRegs.GPCPUD.bit.GPIO70 = 0;
GpioCtrlRegs.GPCPUD.bit.GPIO71 = 0;

//
// Set qualification for selected pins to asynch only
//
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.
//
GpioCtrlRegs.GPCQSEL1.bit.GPIO69 = 3; // Asynch input
GpioCtrlRegs.GPCQSEL1.bit.GPIO70 = 3;
GpioCtrlRegs.GPCQSEL1.bit.GPIO71 = 3;

//
//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.
//

//G-Mux
GpioCtrlRegs.GPCGMUX1.bit.GPIO69 = 3; // MOSI
GpioCtrlRegs.GPCGMUX1.bit.GPIO70 = 3; // MISO
GpioCtrlRegs.GPCGMUX1.bit.GPIO71 = 3; // SCLK

//Mux
GpioCtrlRegs.GPCMUX1.bit.GPIO69 = 3; // MOSI
GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 3; // MISO
GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 3; // SCLK

EDIS;
}

  • Hi Eric,

    It's not recommended to access the SPIDAT register directly. Instead, when you want to receive the data, read the SPIRXBUF register. The SPIDAT contents are automatically copied to this upon completion. The SPIDAT register could be corrupted by another transmission before you have a chance to read it. When you want to transmit data, write to SPITXBUF.

    In addition, the SPIFFRX register is for FIFO mode only. So when you're not using the FIFO, you do not need to access this. In non-FIFO mode you can access SPISTS for details about the interrupt. Please let me know if this fixes your issue.

    Regards,
    Kris

  • Kris,

    I still can't seem to make any progress here. My test this time is to send 0x12, 0x34 and attempt to receive 0x56, 0x78.

    My RX interrupt (with SpicRegs.SPICCR.bit.SPICHAR = 7) is as follows:

    __attribute__((ramfunc))
    __interrupt void spiRxFifoIsr(void)
    {
    SpicRegs.SPIFFRX.bit.RXFFOVFCLR=1; // Clear Overflow flag
    SpicRegs.SPIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
    PieCtrlRegs.PIEACK.all |= M_INT6; // Issue PIE ACK

    spiRxData = SpicRegs.SPIRXBUF;
    SpicRegs.SPITXBUF = spiTxData;


    }

    Any thoughts?
  • I should clairfy that I don't expect my spiRxData to receive 0x1234 since I'll be only recording one byte at a time. On the master end I expect to revceive 0x56, with 0x78 not being sent since the tx buffer should only push the left most 8 bits.

    I've also tried to make this work setting the number of bits to 16. Still no luck.
  • Eric,

    What does your transmit function look like now? What data are you receiving?

    Regards,
    Kris
  • Kris,

    Not sure what you mean by transmit function. The MCU is acting as the slave.

    The data is generally garbage. Occasionally correct values come through.

    Thanks,
    Eric
  • Can you post a table of the received vs expected values? I'm interested if they are shifted by a bit or something along those lines.  Please also include the SPIDAT register contents before and after the transfer.

    Regards,

    Kris