Other Parts Discussed in Thread: MSP430F2419
I am using an MSP430F2419. I am utilizing UCB1 in SPI mode to communicate with an external DataFlash. I have noticed that very intermittently the MSP430 will read garbage data from the DataFlash. Below is my code for the SPI read/write operations. I am using interrupts to perform the read/write, but am waiting for the SPI busy bit to clear before returning from the SPIReadBytes and SPIWriteBytes functions. The global gSPI1 structure gets setup before these functions are called. The chip select line is handled outside of the read/write functions.
uint16_t SPIReadBytes( void )
{
uint16_t timeout = SPI_TIMEOUT;
gSPI1.nBytesReceived = 0;
UCB1TXBUF = SPI_DUMMY_BYTE;
UC1IE |= UCB1RXIE;
while( SPICheckBusy() && timeout-- );
return timeout;
}
uint16_t SPIWriteBytes( void )
{
uint16_t timeout = SPI_TIMEOUT;
gSPI1.nBytesTransmitted = 0;
UCB1TXBUF = gSPI1.txBytes[gSPI1.nBytesTransmitted++];
UC1IE |= UCB1TXIE;
while( SPICheckBusy() && timeout-- );
return timeout;
}
void serialOut( void ) __interrupt[USCIAB1TX_VECTOR]
{
// SPI interrupt
if( UC1IFG & UCB1TXIFG )
{
if( gSPI1.nBytesTransmitted >= gSPI1.nBytesToTransmit )
{
UC1IE &= ~UCB1TXIE;
}
else
{
UCB1TXBUF = gSPI1.txBytes[gSPI1.nBytesTransmitted++];
}
}
// other serial interrupts
....
}
void serialIn(void) __interrupt[USCIAB1RX_VECTOR]
{
// Check if SPI interrupt
if( UC1IFG & UCB1RXIFG )
{
gSPI1.rxBytes[gSPI1.nBytesReceived++] = UCB1RXBUF;
if( gSPI1.nBytesReceived >= gSPI1.nBytesToReceive )
{
UC1IE &= ~UCB1RXIE;
}
else
{
UCB1TXBUF = SPI_DUMMY_BYTE;
}
}
// other serial interrupts
....
}
This method works great 99% of the time. However, it occasionally reads a garbage value, usually some number of binary 1s. I have tried a bit-banged SPI controller and it does not have the same issue, so the issue doesn't reside in the DataFlash unless I am violating its timing requirements. The DataFlash is capable of 66MHz SPI communications, and the MSP430 I am using is only running at 1MHz. The timeout check I have in the code above has never failed.
Is there any insight as to what may be causing my issue? I have added redundant reads to make sure the same value gets read twice from the DataFlash, and sometimes even that approach results in reading garbage data. I am getting fly-wires soldered onto the SPI signals to check the communications (it isn't done yet), but I thought I'd make sure that my code is at least proper before diving too much deeper.