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.

TMS320F28035: Mysterious SPIFFRX.bit.RXFFST words

Part Number: TMS320F28035

I have slightly altered a loopback SPI example provided by TI to remove the loopback and access a MCP23S08 (IOExpander) chip. I have some initial setup of the 23S08 and then I loop thru all the outputs turning on some leds. All works as expected except I am getting an increment in the SPIFFRX.bit.RXFFST field for the first 4 SPI writes to the 23S08 and then it stops incrementing. If I do the reads of the SpiaRegs.SPIRXBUF, I get just 0xFF and the RXFFST will decrement to 0. RXFFST only counts to 4 and if I do not read them on the next cycle, the value will not increment any further. So after I read all the buffer data and RXFFST = 0, RXFFST will increment to 4 again based on the next 4 SPI writes.
I will supply images that show no activity on the SOMI line to the F28035.
As a means of troubleshooting, I even disconnected the SOMI line from the 23S08 and get the same result - RXFFST counts to 4 based on the next 4 SPI writes to the 23S08.
The SPI writes are:
0x40 - 23S08 address and Wr command - RXFFST increments to 1
0x10 - 23S08 OLAT register - RXFFST increments to 2
0xyy - yy is the bit pattern for the OLAT register - turn LED on or off - RXFFST increments to 3
0x40 - 23S08 address and Wr command - start of another series of SPI writes - RXFFST increments to 4
0x10 - 23S08 OLAT register - RXFFST remains at 4
0xyy - yy is the bit pattern for the OLAT register - RXFFST remains at 4
...

1 image is a complete cycle of 14 23S08 SPI writes, 1 image shows first 5 SPI writes and 1 image shows 1 SPI write with the channel names.

Important code:

void main(void)
{
Uint16 rdata; // received data
int i = 0;
int readbytes = 0;

InitSysCtrl();

InitSpiaGpio();

DINT;

InitPieCtrl();

IER = 0x0000;
IFR = 0x0000;

InitPieVectTable();

spi_fifo_init(); // Initialize the Spi FIFO
spi_init(); // init SPI
mcp23s08_init(); // init mcp23s08

for(;;)
{
// Transmit data
led_flash( );

while(SpiaRegs.SPIFFRX.bit.RXFFST == 0 ) { }
readbytes = SpiaRegs.SPIFFRX.bit.RXFFST;
for (i = 0; i < readbytes; i++)
{
// Check against sent data
rdata = SpiaRegs.SPIRXBUF;
// if(rdata != sdata) error();
}
}
}

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

void spi_init()
{
// If only sending a byte at a time, CCR.SPICHAR = 7 (8 bits = 1 byte)
// so to populate SPITXBUF, left-justify the byte so to send 0x41, SPITXBUF = 0x4100
SpiaRegs.SPICCR.all =0x0007; // Reset on, rising edge, 8-bit char bits
SpiaRegs.SPICTL.all =0x0006; // Enable master mode, normal phase,
// enable talk, and SPI int disabled.
SpiaRegs.SPIBRR = 0x001D; // 1Mhz SPI clk
SpiaRegs.SPICCR.bit.SPISWRESET = 1; // Relinquish SPI from Reset
SpiaRegs.SPIPRI.bit.FREE = 1; // Set so breakpoints don't disturb xmission
}

void spi_fifo_init()
{
// Initialize SPI FIFO registers
SpiaRegs.SPIFFTX.bit.TXFIFORESET= 0;
SpiaRegs.SPIFFRX.bit.RXFIFORESET= 0;
SpiaRegs.SPIFFTX.all=0xC040;
SpiaRegs.SPIFFRX.all=0x6040;
SpiaRegs.SPIFFCT.all=0x0;
SpiaRegs.SPIFFTX.bit.TXFIFORESET= 1;
SpiaRegs.SPIFFRX.bit.RXFIFORESET= 1;
}

void mcp23s08_init( )
{
// Set all GPIO as outputs
SpiaRegs.SPITXBUF= WRITE_CMD << 8;
SpiaRegs.SPITXBUF= MCP_IODIR << 8;
SpiaRegs.SPITXBUF= 0x0000;
delay_loop(200);
// Set all GPIO polarity
SpiaRegs.SPITXBUF= WRITE_CMD << 8;
SpiaRegs.SPITXBUF= MCP_IPOL << 8;
SpiaRegs.SPITXBUF= 0x0000;
delay_loop(200);
}

void led_flash( )
{
int led = 0;
// Turn off/on LEDs
for (led = 0; led <= 6; led++)
{
SpiaRegs.SPITXBUF= WRITE_CMD << 8;
SpiaRegs.SPITXBUF= MCP_OLAT << 8;
SpiaRegs.SPITXBUF= 1 << (8 + led);
DELAY_US(200000);
}
for (led = 7; led >= 1; led--)
{
SpiaRegs.SPITXBUF= WRITE_CMD << 8;
SpiaRegs.SPITXBUF= MCP_OLAT << 8;
SpiaRegs.SPITXBUF= 1 << (8 + led);
DELAY_US(200000);
}
// Read 23S08 GPIO pins
/*
SpiaRegs.SPITXBUF= READ_CMD << 8;
SpiaRegs.SPITXBUF= MCP_GPIO << 8;
SpiaRegs.SPITXBUF= 0x0000;
delay_loop(200);
*/
}

  • Additional data:

    /**
    * Define all the registers for the 23S08
    */
    #define MCP_IODIR 0x00
    #define MCP_IPOL 0x01
    #define MCP_OLAT 0x0a
    #define READ_CMD 0x41
    #define WRITE_CMD 0x40

  • Hi Jeffrey,

    A couple of things to keep in mind:

    - The TX and RX FIFO size is 4, so it makes sense that the RXFFST stops counting at 4 (basically FIFO is full).

    - The SPI operates off a single shift register. Whenever you shift something out (write), something will get shifted back in (read). 

    - If you want to generate some SPI clocks for your slave device to send data to the master, you must write a dummy data to the SPI.

    Based on your description it seems the SPI is operating exactly as expected. Let me know if this doesn't answer your question.

  • Ok that did bring some clarity but I have a couple more questions to understand:

    1. So for every byte transferred via SPITXBUF, I will need to read SPIRXBUF even if there is not any data expected such as the first SPI byte is the address. This is needed to ensure when I do a SPI read, the read data in the SPIRXBUF is as expected. (via a dummy SPI wr byte)
    2. What's the difference between the FIFO 4 word buffer (11.3.7 SPI FIFO Description - SPRUI10) and the SPIFFRX/SPIFFTX registers (SPRUG72) which indicate up to 16 words are allowed for FIFO?
  • Jeffrey,

    So for every byte transferred via SPITXBUF, I will need to read SPIRXBUF even if there is not any data expected such as the first SPI byte is the address. This is needed to ensure when I do a SPI read, the read data in the SPIRXBUF is as expected. (via a dummy SPI wr byte)

    Yes, this is correct. 

    What's the difference between the FIFO 4 word buffer (11.3.7 SPI FIFO Description - SPRUI10) and the SPIFFRX/SPIFFTX registers (SPRUG72) which indicate up to 16 words are allowed for FIFO?

    Different C2000 MCU devices have different FIFO sizes. The two documents you referenced are for different device families. SPRUI10 applies TMS320F28035, the device you specified you are using. 

  • Thanks - the SPIFFRX/SPIFFTX registers are device dependent and need to refer to the TRM for the specifics.