I am using an MSP430 of the 5xx family, and currently implementing the SPI interface as master.
I concentrated on burst mode so far. My strategy is to use the TXIFG interrupt flag and associated ISR to fill in the TX buffer as soon as it is free. Setting the /CS signal back up is my problem.
What I tested was to set /CS inactive as soon as the last transmission was done (RXIFG). This does not work, since the interrupt occurs before the last clock signal goes back down (the SPI interface is setup with clock low when inactive, data line valid on the clock's rising edges). It is a requirement that the /CS does not go back to inactive before the last falling edge of the clock (plus a margin).
The example code from TI looks like this:
---
void TI_CC_SPIWriteBurstReg(char addr, char *buffer, char count)
{
unsigned int i;
TI_CC_CSn_PxOUT &= ~TI_CC_CSn_PIN; // /CS enable
while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready
UCB0TXBUF = addr | TI_CCxxx0_WRITE_BURST; // Send address
for (i = 0; i < count; i++)
{
while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready
UCB0TXBUF = buffer[i]; // Send data
}
while (UCB0STAT & UCBUSY); // Wait for TX to complete
TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; // /CS disable
}
---
Polling while writing is nothing I want to do (urk!), and polling UCBUSY at the end feels also bad.
Is there any other way? I would love to have an interrupt on UCBUSY, or any other interrupt telling me that the last clock cycle is finished.
---
EDIT: worse than that: UCBUSY resets before the clock goes back to low, therefore the requirement is not fulfilled (clock low before /CS inactive). Checking the level on the clocks IO pin works, but it is still polling:
while (PxIN & BITx);
I am not even sure if reading the input register for a pin that is configured as output and SPI-clock is a specified behavior.
