Hello, I have an issue related to Mary West's posting of 10/6/11. I replied to that post but as I haven't heard anything back I concluded that a new thread might be warranted.
I modified the example code to try to control a chip select by asserting it before loading the FIFO and deasserting it once the FIFO had emptied and generated a TX interrupt (I realize that the FIFO emptying means that there are still bits in the SPIDAT register that haven't been sent yet but I can pad the message to accommodate this, but I can also deassert CS early without ill effect as long as the device has gotten its first clock).
The problem I am encountering is that even when I load the FIFO up with 4 words of data I get the interrupt almost immediately even though I have TXFFIL set to 0, i.e. give me the interrupt when there are 0 words left in the FIFO (I have also tried values of 1, 2, and 3). The system seems designed to do exactly what I want, it just doesn't happen to work. Here's the code. Note that I read 3 to the local variable count when I set a breakpoint at the following line. SPIFFCT is set to 0, and the transmit interrupt is not enabled
If I replace the interrupt-enabling statement with a hard loop while ((count = SpiaRegs.SPIFFTX.bit.TXFFST) > 0); and then de-assert the line it works as expected: the line is asserted for 3 bytes and deasserted when the last byte is loaded into the shift register bringing the TXFFST to 0. Clearly I don't want to do the hard loop in real code though. Why doesn't TXFFIL work as advertised regarding the interrupt, having been careful to shut off the source of interrupt and clear any pending status?
Thanks very much!
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:
// 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 RX
PieCtrlRegs.PIEIER6.bit.INTx2=1; // Enable PIE Group 6, INT 2 TX
IER=0x20; // Enable CPU INT6
EINT; // Enable Global Interrupts
GpioDataRegs.GPADAT.bit.GPIO15 = 1; // disable nCS
GpioDataRegs.GPADAT.bit.GPIO16 = 1; // disable nCS
GpioDataRegs.GPADAT.bit.GPIO17 = 1; // disable nCS
EALLOW;
GpioCtrlRegs.GPADIR.bit.GPIO15 = 1; // SPI bus SEL0
GpioCtrlRegs.GPADIR.bit.GPIO16 = 1; // SPI bus SEL1
GpioCtrlRegs.GPADIR.bit.GPIO17 = 1; // SPI bus SEL2
EDIS;
// Step 6. IDLE loop. Just sit and loop forever (optional):
for(;;)
{
// SpiaRegs.SPICCR.bit.SPISWRESET = 0;
GpioDataRegs.GPADAT.bit.GPIO15 = 0; // assert nCS
SpiaRegs.SPIFFTX.bit.TXFFIENA = 0; // disable FIFO interrupt before loading
SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1; // Clear any interrupt that may be pending
SpiaRegs.SPITXBUF= 0xA500; // LEFT-justified 16-bit value
SpiaRegs.SPITXBUF= 0xA500; // LEFT-justified 16-bit value
SpiaRegs.SPITXBUF= 0xA500; // LEFT-justified 16-bit value
SpiaRegs.SPITXBUF= 0xA500; // LEFT-justified 16-bit value
SpiaRegs.SPIFFTX.bit.TXFFIENA = 1;
int count = SpiaRegs.SPIFFTX.bit.TXFFST;
// SpiaRegs.SPIFFTX.bit.TXFIFO = 1;
SpiaRegs.SPICCR.bit.SPISWRESET = 1;
PieCtrlRegs.PIEIER6.bit.INTx2=1; // Enable PIE Group 6, INT 2 TX
delay_loop();
}
}
// 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, no Loopback mode
SpiaRegs.SPICTL.all=0x0017; //Interrupt enabled, Master/Slave XMIT enabled
SpiaRegs.SPISTS.all=0x0000;
SpiaRegs.SPIBRR=6; // Baud rate divider
// SpiaRegs.SPIFFTX.all=0xC022; // Enable FIFO's, set TX FIFO level to 4
SpiaRegs.SPIFFTX.all=0xC020; // Enable FIFO's, set TX FIFO level to 4
// SpiaRegs.SPIFFTX.all=0xC024; // Enable FIFO's, set TX FIFO level to 4
SpiaRegs.SPIFFCT.bit.TXDLY = 0;
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)
{
// Disable SPI CLK
PieCtrlRegs.PIEIER6.bit.INTx2=0; // Disable PIE Group 6, INT 2 TX
GpioDataRegs.GPADAT.bit.GPIO15 = 1; // de-assert nCS
SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1; // Clear Interrupt flag
PieCtrlRegs.PIEACK.all|=0x20; // Issue PIE ACK
}
interrupt void spiRxFifoIsr(void)
{
rdata[0]=SpiaRegs.SPIRXBUF; // Read data
SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1; // Clear Overflow flag
SpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
PieCtrlRegs.PIEACK.all|=0x20; // Issue PIE ack
}
//===========================================================================
// No more.