Hello,
I'm tesing the SPI communication between two DSPs(28069). I got a quite confusing problem.
If the master and the slave send the same data to each other, there is no problem, both can receive correct data.
For example, both of them send 0,1,2,...,1000,... to each other.
However, if one of them send 100,101,102,...1100,..., the other send 0,1,2,...,1000,..., then I got problem, the received data on both sides were completly wrong after several correct cycles.
Can someone explain this problem?
I copy my code here:
----------------Master--------------------
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
// Prototype statements for functions found within this file.
interrupt void spiTxFifoIsr(void);
interrupt void spiRxFifoIsr(void);
void delay_loop(void);
void spi_fifo_init(void);
void error();
Uint16 sdata[2]; // Send data buffer
Uint16 rdata[2]; // Receive data buffer
Uint16 revData[1024] = {0};
int revSeq=0;
Uint16 sedData[1024] = {0};
int sedSeq=0;
void main(void)
{
Uint16 i;
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2806x_SysCtrl.c file.
InitSysCtrl();
// Step 2. Initalize GPIO:
// This example function is found in the F2806x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example
// Setup only the GP I/O only for SPI-A functionality
InitSpiaGpio();
// Step 3. Initialize PIE vector table:
// Disable and clear all CPU interrupts
DINT;
IER = 0x0000;
IFR = 0x0000;
// Initialize PIE control registers to their default state:
// This function is found in the F2806x_PieCtrl.c file.
InitPieCtrl();
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2806x_DefaultIsr.c.
// This function is found in F2806x_PieVect.c.
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.SPIRXINTA = &spiRxFifoIsr;
PieVectTable.SPITXINTA = &spiTxFifoIsr;
EDIS; // This is needed to disable write to EALLOW protected registers
// Step 4. Initialize all the Device Peripherals:
// This function is found in F2806x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
spi_fifo_init(); // Initialize the SPI only
// Step 5. User specific code, enable interrupts:
// Initalize the send data buffer
for(i=0; i<2; i++)
{
sdata[i] = i;
}
// Enable interrupts required for this example
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
PieCtrlRegs.PIEIER6.bit.INTx1=1; // Enable PIE Group 6, INT 1
PieCtrlRegs.PIEIER6.bit.INTx2=1; // Enable PIE Group 6, INT 2
IER=0x20; // Enable CPU INT6
EINT; // Enable Global Interrupts
// Step 6. IDLE loop. Just sit and loop forever (optional):
for(;;){
if (revSeq>1000) break;
}
}
// Some Useful local functions
void delay_loop()
{
long i;
for (i = 0; i < 1000000; i++) {}
}
void error(void)
{
asm(" ESTOP0"); //Test failed!! Stop!
for (;;);
}
void spi_fifo_init()
{
// Initialize SPI FIFO registers
SpiaRegs.SPICCR.bit.SPISWRESET=0; // Reset SPI
SpiaRegs.SPICCR.all=0x000F; //16-bit character, Loopback mode
SpiaRegs.SPICTL.all=0x0017; //Interrupt enabled, Master/Slave XMIT enabled
SpiaRegs.SPISTS.all=0x0000;
SpiaRegs.SPIBRR=0x0063; // Baud rate
SpiaRegs.SPIFFTX.all=0xC022; // Enable FIFO's, set TX FIFO level to 4
SpiaRegs.SPIFFRX.all=0x0022; // Set RX FIFO level to 4
SpiaRegs.SPIFFCT.all=0x00;
SpiaRegs.SPIPRI.all=0x0010;
SpiaRegs.SPICCR.bit.SPISWRESET=1; // Enable SPI
SpiaRegs.SPIFFTX.bit.TXFIFO=1;
SpiaRegs.SPIFFRX.bit.RXFIFORESET=1;
}
interrupt void spiTxFifoIsr(void)
{
Uint16 i;
for(i=0;i<2;i++)
{
SpiaRegs.SPITXBUF=sdata[i]; // Send data
sedData[sedSeq]=sdata[i];
sedSeq++;
}
for(i=0;i<2;i++) // Increment data for next cycle
{
sdata[i]+=2;
}
SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1; // Clear Interrupt flag
PieCtrlRegs.PIEACK.all|=0x20; // Issue PIE ACK
}
interrupt void spiRxFifoIsr(void)
{
Uint16 i;
for(i=0;i<2;i++)
{
rdata[i]=SpiaRegs.SPIRXBUF; // Read data
revData[revSeq]=rdata[i];
revSeq++;
}
SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1; // Clear Overflow flag
SpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
PieCtrlRegs.PIEACK.all|=0x20; // Issue PIE ack
}
----------------Slave--------------------
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
// Prototype statements for functions found within this file.
interrupt void spiTxFifoIsr(void);
interrupt void spiRxFifoIsr(void);
void delay_loop(void);
void spi_fifo_init(void);
void error();
Uint16 sdata[2]; // Send data buffer
Uint16 rdata[2]; // Receive data buffer
Uint16 revData[1024] = {0};
int revSeq=0;
Uint16 sedData[1024] = {0};
int sedSeq=0;
void main(void)
{
Uint16 i;
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2806x_SysCtrl.c file.
InitSysCtrl();
// Step 2. Initalize GPIO:
// This example function is found in the F2806x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example
// Setup only the GP I/O only for SPI-A functionality
InitSpiaGpio();
// Step 3. Initialize PIE vector table:
// Disable and clear all CPU interrupts
DINT;
IER = 0x0000;
IFR = 0x0000;
// Initialize PIE control registers to their default state:
// This function is found in the F2806x_PieCtrl.c file.
InitPieCtrl();
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2806x_DefaultIsr.c.
// This function is found in F2806x_PieVect.c.
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.SPIRXINTA = &spiRxFifoIsr;
PieVectTable.SPITXINTA = &spiTxFifoIsr;
EDIS; // This is needed to disable write to EALLOW protected registers
// Step 4. Initialize all the Device Peripherals:
// This function is found in F2806x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
spi_fifo_init(); // Initialize the SPI only
// Step 5. User specific code, enable interrupts:
// Initalize the send data buffer
for(i=0; i<2; i++)
{
sdata[i] = i+100;
}
// Enable interrupts required for this example
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
PieCtrlRegs.PIEIER6.bit.INTx1=1; // Enable PIE Group 6, INT 1
PieCtrlRegs.PIEIER6.bit.INTx2=1; // Enable PIE Group 6, INT 2
IER=0x20; // Enable CPU INT6
EINT; // Enable Global Interrupts
// Step 6. IDLE loop. Just sit and loop forever (optional):
for(;;){
if (revSeq>1000) break;
}
}
// Some Useful local functions
void delay_loop()
{
long i;
for (i = 0; i < 1000000; i++) {}
}
void error(void)
{
asm(" ESTOP0"); //Test failed!! Stop!
for (;;);
}
void spi_fifo_init()
{
// Initialize SPI FIFO registers
SpiaRegs.SPICCR.bit.SPISWRESET=0; // Reset SPI
SpiaRegs.SPICCR.all=0x000F; //16-bit character, Loopback mode
SpiaRegs.SPICTL.all=0x0013; //Interrupt enabled, Master/Slave XMIT enabled
SpiaRegs.SPISTS.all=0x0000;
SpiaRegs.SPIBRR=0x0063; // Baud rate
SpiaRegs.SPIFFTX.all=0xC022; // Enable FIFO's, set TX FIFO level to 4
SpiaRegs.SPIFFRX.all=0x0022; // Set RX FIFO level to 4
SpiaRegs.SPIFFCT.all=0x00;
SpiaRegs.SPIPRI.all=0x0010;
SpiaRegs.SPICCR.bit.SPISWRESET=1; // Enable SPI
SpiaRegs.SPIFFTX.bit.TXFIFO=1;
SpiaRegs.SPIFFRX.bit.RXFIFORESET=1;
}
interrupt void spiTxFifoIsr(void)
{
Uint16 i;
for(i=0;i<2;i++)
{
SpiaRegs.SPITXBUF=sdata[i]; // Send data
sedData[sedSeq]=sdata[i];
sedSeq++;
}
for(i=0;i<2;i++) // Increment data for next cycle
{
sdata[i]+=2;
}
SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1; // Clear Interrupt flag
PieCtrlRegs.PIEACK.all|=0x20; // Issue PIE ACK
}
interrupt void spiRxFifoIsr(void)
{
Uint16 i;
for(i=0;i<2;i++)
{
rdata[i]=SpiaRegs.SPIRXBUF; // Read data
revData[revSeq]=rdata[i];
revSeq++;
}
SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1; // Clear Overflow flag
SpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
PieCtrlRegs.PIEACK.all|=0x20; // Issue PIE ack
}
I really appreciate your help.
Best Regards,
Jin