Hello All,
I am working on developing SPI communication between two TMS320F28335 devices, one acts as the master and the other as a slave.
I have set up message counters on both, the Master as well as the Slave module. I observe that the Slave consistently misses one third of the messages sent by the Master. This ratio remains pretty constant, irrespective of the actual number of messages (from a few hundreds to several thousands), indicating that it's a systematic problem .
Could some one take a look at the codes below and suggest where am I going wrong ?
28335 - Master :
// In main()
SPI_Initialize();
sdata = 0x0000;
for(;;)
{
sdata++;
//DELAY_US(1000);
SPI_Transmit(&sdata, 1);
//DELAY_US(1000);
SPI_Receive(&rdata, 1);
}
//SPI Drivers for Master:
void SPI_Transmit (Uint16* tx_buff, Uint16 len)
{
Uint16 byte_ctr = 0;
volatile Uint16 dummy_rx = 0;
ASSERT_CS();
//DELAY_US(100);
for (byte_ctr = 0; byte_ctr < len; byte_ctr ++)
{
SpiaRegs.SPITXBUF = *(tx_buff + byte_ctr);
while (SpiaRegs.SPISTS.bit.INT_FLAG == 0)
{}// Wait for transmission to complete!
dummy_rx = SpiaRegs.SPIRXBUF;
}
//DELAY_US(100);
RELEASE_CS();
msg_ctr += len;
}
void SPI_Receive (Uint16* rx_buff, Uint16 len)
{
Uint16 byte_ctr = 0;
Uint16 dummy_tx = 0xFFFF;
ASSERT_CS();
//DELAY_US(100);
for (byte_ctr = 0; byte_ctr < len; byte_ctr ++)
{
SpiaRegs.SPITXBUF = dummy_tx;
while (SpiaRegs.SPISTS.bit.INT_FLAG == 0)
{}// Wait for transmission to complete!
*(rx_buff + byte_ctr) = SpiaRegs.SPIRXBUF;
}
//DELAY_US(100);
RELEASE_CS();
msg_ctr += len;
}
void SPI_Initialize()
{
SpiaRegs.SPICCR.bit.SPISWRESET = 0; // Reset SPI
SpiaRegs.SPICCR.bit.SPICHAR = (DATA_LEN - 1);
SpiaRegs.SPICCR.bit.SPILBK = 0;
SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
SpiaRegs.SPIBRR = BAUD_RATE; // Baud rate = ((Crystal) * PLLCR / DIVSEL) / (2 * LOSPCP) / (SPIBRR + 1) = (30MHz * 10 /2 )/ (2*2) /(99 + 1) = 375kHz
SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
SpiaRegs.SPICTL.bit.MASTER_SLAVE= 1; //Master
SpiaRegs.SPICTL.bit.OVERRUNINTENA = 0; //Disable Overrun interrupt
SpiaRegs.SPICTL.bit.TALK = 1;
SpiaRegs.SPICTL.bit.SPIINTENA = 0; //Disable interrupt
SpiaRegs.SPICCR.bit.SPISWRESET = 1; // Reset SPI
}
28335 - Slave:
//In Main
SPI_Initialize_Slave();
// Dummy operations, used only for debug
for(;;)
{
if (data_updt_flag == SET)
{
data_updt_flag = CLEAR;
rx_data = 0;
}
}
// Slave SPI Init and ISR
void SPI_Initialize_Slave()
{
SpiaRegs.SPICCR.bit.SPISWRESET = 0; // Reset SPI
SpiaRegs.SPICCR.bit.SPICHAR = (DATA_LEN - 1);
SpiaRegs.SPICCR.bit.SPILBK = 0;
SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
SpiaRegs.SPIBRR = BAUD_RATE; // Baud rate = ((Crystal) * PLLCR / DIVSEL) / (2 * LOSPCP) / (SPIBRR + 1) = (30MHz * 10 /2 )/ (2*2) /(99 + 1) = 375kHz
SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
SpiaRegs.SPICTL.bit.MASTER_SLAVE= 0; //Slave
SpiaRegs.SPICTL.bit.OVERRUNINTENA = 0; //Disable Overrun interrupt
SpiaRegs.SPICTL.bit.TALK = 1;
SpiaRegs.SPICTL.bit.SPIINTENA = 1; //Enable interrupt
SpiaRegs.SPICCR.bit.SPISWRESET = 1; // Reset SPI
}
interrupt void spiRxTxIsr (void)
{
rx_data = SpiaRegs.SPIRXBUF;
SpiaRegs.SPITXBUF = 65535 - rx_data;
data_updt_flag = SET;
msg_ctr ++;
SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1; // Clear Overflow flag
SpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
PieCtrlRegs.PIEACK.all|=0x20; // Issue PIE ack
}
Also, I am controlling the chip select functionality of Master by using the corresponding pin as a GPIO (GPIO19) and not as SPISTEA/.
The character length is defined as 16 bits (DATA_LEN) and the baud rate is 375 kHz (verified).
Any help would be appreciated.
Thanks!