Tool/software: TI-RTOS
I am having a problem writing SPI code for my MSP430 to talk to a FLASH chip.
I've tried writing both a polling routine, and an Interrupt ISR, and result is the same. No matter what I try, UCB1RXBUF is always zero.
Here is my init routine:
void hal_spi_init(void)
{
////////////////////////////////////////////////////////////////////////////
// Here are all the relevant IO Pins:
// FLASH_SS P3.6 UCB1STE/CS# (active low)
// FLASH_MOSI P3.7 UCB1SIMO/SI
// FLASH_MISO P5.4 UCB1SOMI/SO
// FLASH_SCLK P5.5 UCB1CLK/SCK
P3DIR |= FLASH_SS; // P3.6 FLASH_SS is an output pin
P3OUT |= FLASH_SS; // active low, (disable)
// set special mode for MOSI (P3.7), MISO (P5.4), SCLK (P5.5)
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, FLASH_MOSI);
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, FLASH_MISO);
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, FLASH_SCLK);
// Initialize SPI in Master mode
USCI_B_SPI_initMasterParam param = {0};
param.selectClockSource = USCI_B_SPI_CLOCKSOURCE_SMCLK;
param.clockSourceFrequency = UCS_getSMCLK();
param.desiredSpiClock = 1000000;
param.msbFirst = USCI_B_SPI_MSB_FIRST;
param.clockPhase = USCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT;
param.clockPolarity = USCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW; //or USCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH;
bool rc = USCI_B_SPI_initMaster(USCI_B1_BASE, ¶m);
assert(rc == STATUS_SUCCESS);
// Enable SPI module
USCI_B_SPI_enable(USCI_B1_BASE);
// Disable interrupts
USCI_B_SPI_clearInterrupt(USCI_B1_BASE,
USCI_B_SPI_RECEIVE_INTERRUPT|USCI_B_SPI_TRANSMIT_INTERRUPT);
USCI_B_SPI_disableInterrupt(USCI_B1_BASE,
USCI_B_SPI_RECEIVE_INTERRUPT|USCI_B_SPI_TRANSMIT_INTERRUPT);
}
Next, here is the spi_transfer routine:
void hal_spi_transfer(
uint8_t *txbuf, uint8_t *rxbuf, size_t txrxlen, uint8_t flags)
{
if (flags & SPI_CS_ENABLE)
flash_ss_active();
// initiate the first byte transmit
for ( ; txrxlen; --txrxlen) {
uint8_t tbyte = txbuf ? *txbuf++ : 0;
// USCI_B_SPI_transmitData(USCI_B1_BASE, tbyte);
UCB1TXBUF = tbyte;
UCB1IFG &= ~UCRXIFG; // Clear RXIFG as transmit always sets the RX flag
// wait until the RX byte is completely received
while (!(UCB1IFG & UCRXIFG))
;
uint8_t rbyte = UCB1RXBUF; // USCI_B_SPI_receiveData(USCI_B1_BASE);
if (rxbuf != NULL)
*rxbuf++ = rbyte;
}
if (flags & SPI_CS_DISABLE)
flash_ss_inactive();
}
When this routine is called, only zeros are read.
On the logic analyzer, I can see that data is properly on the SPI bus. In the following example, we send the FLASH_READID command (hex 9F), and then read the 0x56 bytes of the chip configuration info:
hal_spi_send_byte(FLASH_READID, SPI_CS_ENABLE);
hal_spi_transfer(NULL, flash_CFI, sizeof flash_CFI, SPI_CS_DISABLE);
On the Logic Analyzer, we see all the SPI data:
And we can see on the blue line (probe 6) that the Flash chip received the command, and is returning the CFI data. I can zoom in and examine the data, and it is absolutely correct.
I've also put an oscilloscope probe on the CPU pin (pin 51), and I get the same result. The voltage levels look ok (3v or so).
However, the 'flash_CFI[]' array is always zero.
Is it possibly my hardware is damaged and the SPI receiver doesn't work?
-allan schwartz


