I'm using F28335 in my active DSP loudspeakers project and I need it to communicate via SPI (as master) with other uC-s in the system. I spent the whole yesterday (10+ hours) trying to make my 28335 send out any SPI but (it seems) with no success. I must be missing sth simple but fundamental. But I have gone through all available examples and I’m lost what I can be missing.
The key observation is it seems to receive data I'm writing into the transmission registers but it is stuck there. I have tried both the plain and the FIFO version. For the non-FIFO in the loopback mode when I put a value into SPIDAT it never gets into the SPIRXBUF (I’m watching the registers section in CCS4 in the debug mode via XDS100). Also the the SPISTS bit 6 never gets to one which I assume should take place when the value has been shifted out and stay so till I read off the SPIRXBUF. In the FIFO mode all the values (with loopback on) I write to SPITXBUF simply increase the counter bits in the SPIFFTX and again no life in SPIRXBUF nor SPISTS.bit_6. I have read the documentation 3-4 times already and I feel I have run out of ideas and power.
I have put all the code that is relevant for the SPI part below maybe you can spot out the omission. Or maybe I should try out some exemplary simple SPI project but I could not find anything fully self-contained (I mean some SPI loopback examples in the sprc530.zip package that I took as the basis still need to be supplemented with some system and interrupts setup and this part may be the culprit).
Pawel
#include "DigAmp4ChSbb-Settings.h" // supplies settings for this project
#include "PeripheralHeaderIncludes.h" // include headers for this used device
main ()
{
DeviceInit();
SPI0();
}
void DeviceInit(void)
{
WDogDisable(); // Disable the watchdog initially
DINT; // Global Disable all Interrupts
IER = 0x0000; // Disable CPU interrupts
IFR = 0x0000; // Clear all CPU interrupt flags
PLLset(0x8); // 25 MHz quartz-driven
// Initialise interrupt controller and Vector Table
// to defaults for now. Application ISR mapping done later.
PieCntlInit();
PieVectTableInit();
EALLOW; // below registers are "protected", allow access.
// HIGH / LOW SPEED CLOCKS prescale register settings
SysCtrlRegs.HISPCP.all = 0x0002; // Sysclk / 4 (25 MHz)
SysCtrlRegs.LOSPCP.all = 0x0002; // Sysclk / 4 (25 MHz)
SysCtrlRegs.PCLKCR0.bit.SPIAENCLK=1; // SPI-A
}
void SPI0(void)
{
int i;
SpiaRegs.SPICCR.all =0x0F; // Reset on, rising edge, 16-bit char bits
SpiaRegs.SPICTL.all =0x0006; // Enable master mode, normal phase,
// enable talk, and SPI int disabled.
SpiaRegs.SPIBRR =0x007F; // LSPCLK/(SPIBRR+ 1)
SpiaRegs.SPIPRI.all = 0x00; // Set so breakpoints don't disturb xmission
// Initialize SPI FIFO registers
SpiaRegs.SPIFFTX.all=0xE040;
SpiaRegs.SPIFFRX.all=0x204F;
SpiaRegs.SPIFFCT.all=0x0;
GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // GPIO16 = SPICLKA
GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // GPIO17 = SPIS0MIA
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // GPIO18 = SPICLKA
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // GPIO19 = SPISTEA
SpiaRegs.SPICCR.all =0x9F; // 0x80 - Leave reset, + 0x10 - loopback mode
SpiaRegs.SPIDAT=12;
spi_xmit(0x34);
}
void spi_xmit(Uint16 a)
{
SpiaRegs.SPITXBUF=a;
}
void PLLset(Uint16 val)
{
volatile Uint16 iVol;
// Make sure the PLL is not running in limp mode
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
{
// Missing external clock has been detected
// Replace this line with a call to an appropriate
// SystemShutdown(); function.
asm(" ESTOP0");
}
if (SysCtrlRegs.PLLCR.bit.DIV != val)
{
EALLOW;
// Before setting PLLCR turn off missing clock detect logic
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
SysCtrlRegs.PLLCR.bit.DIV = val;
EDIS;
WDogDisable();
EALLOW;
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
EDIS;
}
}
void PieCntlInit(void)
{
// Disable Interrupts at the CPU level:
DINT;
// Disable the PIE
PieCtrlRegs.PIECTRL.bit.ENPIE = 0;
// Clear all PIEIER registers:
PieCtrlRegs.PIEIER1.all = 0;
PieCtrlRegs.PIEIER2.all = 0;
PieCtrlRegs.PIEIER3.all = 0;
PieCtrlRegs.PIEIER4.all = 0;
PieCtrlRegs.PIEIER5.all = 0;
PieCtrlRegs.PIEIER6.all = 0;
PieCtrlRegs.PIEIER7.all = 0;
PieCtrlRegs.PIEIER8.all = 0;
PieCtrlRegs.PIEIER9.all = 0;
PieCtrlRegs.PIEIER10.all = 0;
PieCtrlRegs.PIEIER11.all = 0;
PieCtrlRegs.PIEIER12.all = 0;
// Clear all PIEIFR registers:
PieCtrlRegs.PIEIFR1.all = 0;
PieCtrlRegs.PIEIFR2.all = 0;
PieCtrlRegs.PIEIFR3.all = 0;
PieCtrlRegs.PIEIFR4.all = 0;
PieCtrlRegs.PIEIFR5.all = 0;
PieCtrlRegs.PIEIFR6.all = 0;
PieCtrlRegs.PIEIFR7.all = 0;
PieCtrlRegs.PIEIFR8.all = 0;
PieCtrlRegs.PIEIFR9.all = 0;
PieCtrlRegs.PIEIFR10.all = 0;
PieCtrlRegs.PIEIFR11.all = 0;
PieCtrlRegs.PIEIFR12.all = 0;
}
void PieVectTableInit(void)
{
int16 i;
Uint32 *Source = (void *) &ISR_ILLEGAL;
Uint32 *Dest = (void *) &PieVectTable;
EALLOW;
for(i=0; i < 128; i++)
*Dest++ = *Source;
EDIS;
// Enable the PIE Vector Table
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
}