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!