I have the SPI set up in polling mode as discussed in my recent thread.
From the MSP430 user guide slau445i, transmit and receive operations happen concurrently. If a response is expected from the slave, when will this receive byte show up on MISO? In the scope view, I can see all transmitted bytes, but no activity on the MISO line.
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <driverlib.h> #include <msp430.h> #include "clock~.h" // Clock configurations static uint8_t TXData = 0; //transaction count static uint8_t RXData = 0; //SPI receive byte typedef struct { uint8_t Len; uint8_t Data[5]; uint8_t RxFlag; } spi_MaximTrans_t; static spi_MaximTrans_t DCInit_transactions[15]; uint8_t SPI_TX_index = 0; //byte count in transaction /** * Initialize system clocks */ static void init_clock(void) { // Configure one FRAM waitstate as required by the device datasheet for MCLK // operation beyond 8MHz _before_ configuring the clock system. FRAMCtl_configureWaitStateControl(FRAMCTL_ACCESS_TIME_CYCLES_1); //Set DCO FLL reference = REFO CS_initClockSignal(CS_FLLREF, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1); //Set ACLK = REFO CS_initClockSignal(CS_ACLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1); CS_initFLLParam param = {0}; //Set Ratio/Desired MCLK Frequency, initialize DCO, save trim values CS_initFLLCalculateTrim(CS_MCLK_DESIRED_FREQUENCY_IN_KHZ, CS_MCLK_FLLREF_RATIO, ¶m); //Set MCLK = REFO CS_initClockSignal(CS_MCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1); //Set SMCLK = DCO CS_initClockSignal(CS_SMCLK, CS_DCOCLKDIV_SELECT, CS_CLOCK_DIVIDER_1); //Clear all OSC fault flag CS_clearAllOscFlagsWithTimeout(1000); } /** * Initialize all of the IO pins per their configuration */ static void init_gpio(void) { // Set all GPIO pins to output low to prevent floating input and reduce power consumption GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN_ALL8); GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN_ALL8); GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN_ALL8); GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN_ALL8); GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN_ALL8); GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2); GPIO_setAsOutputPin( GPIO_PORT_P1, GPIO_PIN_ALL8); GPIO_setAsOutputPin( GPIO_PORT_P2, GPIO_PIN_ALL8); GPIO_setAsOutputPin( GPIO_PORT_P3, GPIO_PIN_ALL8); GPIO_setAsOutputPin( GPIO_PORT_P4, GPIO_PIN_ALL8); GPIO_setAsOutputPin( GPIO_PORT_P5, GPIO_PIN_ALL8); GPIO_setAsOutputPin( GPIO_PORT_P6, GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2); } /* * Initialize the SPI peripheral on EUSCI A1 */ void init_spi_peripheral() { //Initialize Master EUSCI_A_SPI_initMasterParam param = {0}; param.selectClockSource = EUSCI_A_SPI_CLOCKSOURCE_SMCLK; param.clockSourceFrequency = CS_getSMCLK(); param.desiredSpiClock = 1000000; param.msbFirst = UCMSB; param.clockPhase = 0; param.clockPolarity = EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW; param.spiMode = EUSCI_A_SPI_3PIN; EUSCI_A_SPI_initMaster(EUSCI_A1_BASE, ¶m); EUSCI_A_SPI_enable(EUSCI_A1_BASE); } void SetUpTransactions(void){ //All transactions padded to 4 bytes //Enable keep alive mode DCInit_transactions[0].Len = 4; DCInit_transactions[0].Data[0] = 0x10; DCInit_transactions[0].Data[1] = 0x5; DCInit_transactions[0].Data[2] = 0x11; DCInit_transactions[0].Data[3] = 0x0; DCInit_transactions[0].RxFlag = 0x0; //No Receive //Enable Rx Interrupt flags DCInit_transactions[1].Len = 4; DCInit_transactions[1].Data[0] = 0x4; DCInit_transactions[1].Data[1] = 0x88; DCInit_transactions[1].Data[2] = 0x0; DCInit_transactions[1].Data[3] = 0x0; DCInit_transactions[1].RxFlag = 0x0; //No Receive //Clear receive buffer DCInit_transactions[2].Len = 4; DCInit_transactions[2].Data[0] = 0xe0; DCInit_transactions[2].Data[1] = 0x0; DCInit_transactions[2].Data[2] = 0x0; DCInit_transactions[2].Data[3] = 0x0; DCInit_transactions[2].RxFlag = 0x0; //No Receive //Wakeup UART slave devices DCInit_transactions[3].Len = 4; DCInit_transactions[3].Data[0] = 0xe0; DCInit_transactions[3].Data[1] = 0x30; DCInit_transactions[3].Data[2] = 0x0; DCInit_transactions[3].Data[3] = 0x0; DCInit_transactions[3].RxFlag = 0x0; //No Receive //2ms delay for each slave to wake up //Wait for all UART slave devices to wake up DCInit_transactions[4].Len = 4; DCInit_transactions[4].Data[0] = 0x01; DCInit_transactions[4].Data[1] = 0x0; DCInit_transactions[4].Data[2] = 0x0; DCInit_transactions[4].Data[3] = 0x91; DCInit_transactions[4].RxFlag = 0x1; //Receive of 0x21 expected //Read message command. This was added to see a SPI receive byte on the MSP430 //Without this, there was no change in the SPI receive buffer. //End of UART slave device wake-up period DCInit_transactions[5].Len = 4; DCInit_transactions[5].Data[0] = 0x0e; DCInit_transactions[5].Data[1] = 0x10; DCInit_transactions[5].Data[2] = 0x0; DCInit_transactions[5].Data[3] = 0x0; DCInit_transactions[5].RxFlag = 0x0; //No Receive //2ms delay for each slave to report null message //Wait for null message to be received DCInit_transactions[6].Len = 4; DCInit_transactions[6].Data[0] = 0x01; DCInit_transactions[6].Data[1] = 0x0; DCInit_transactions[6].Data[2] = 0x0; DCInit_transactions[6].Data[3] = 0x0; DCInit_transactions[6].RxFlag = 0x1; //Receive 0x10 or 0x12 //Clear transmit buffer DCInit_transactions[7].Len = 4; DCInit_transactions[7].Data[0] = 0x20; DCInit_transactions[7].Data[1] = 0x0; DCInit_transactions[7].Data[2] = 0x0; DCInit_transactions[7].Data[3] = 0x0; DCInit_transactions[7].RxFlag = 0x0; //No Receive //Clear receive buffer DCInit_transactions[8].Len = 4; DCInit_transactions[8].Data[0] = 0xe0; DCInit_transactions[8].Data[1] = 0x0; DCInit_transactions[8].Data[2] = 0x0; DCInit_transactions[8].Data[3] = 0x0; DCInit_transactions[8].RxFlag = 0x0; //No Receive } /** * main.c */ int main(void) { uint32_t i; WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer init_clock(); init_gpio(); // Set up IO pins GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN1); // Configure SPI Pins for UCA1CLK, UCA1TXD/UCA1SIMO and UCA1RXD/UCA1SOMI /* * Select Port 2 * Set Pin 4, Pin 5 and Pin 6 to input Secondary Module Function */ GPIO_setAsPeripheralModuleFunctionInputPin( GPIO_PORT_P2, GPIO_PIN4 + GPIO_PIN5 + GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION ); // Set P1.0 to output direction GPIO_setAsOutputPin (GPIO_PORT_P1, GPIO_PIN0); GPIO_setAsInputPinWithPullUpResistor (GPIO_PORT_P4, GPIO_PIN2); GPIO_enableInterrupt (GPIO_PORT_P4, GPIO_PIN2); GPIO_selectInterruptEdge (GPIO_PORT_P4, GPIO_PIN2, GPIO_HIGH_TO_LOW_TRANSITION); GPIO_clearInterrupt (GPIO_PORT_P4, GPIO_PIN2); PMM_unlockLPM5(); SetUpTransactions(); TXData = 0x0; // Holds transaction number // Setup peripheral(s) now that gpio and clocks are setup init_spi_peripheral(); // Init Maxim spi peripheral GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN1); //Maxim chip select low for(i=10000; i>0; i--); //idle time between SPI transactions for(SPI_TX_index = 0; SPI_TX_index < DCInit_transactions[TXData].Len; SPI_TX_index++){ while(!(UCA1IFG & UCTXIFG)); UCA1TXBUF = DCInit_transactions[TXData].Data[SPI_TX_index]; while (!(UCA1IFG & UCRXIFG)); RXData = UCA1RXBUF; } TXData = 1; for(SPI_TX_index = 0; SPI_TX_index < DCInit_transactions[TXData].Len; SPI_TX_index++){ while(!(UCA1IFG & UCTXIFG)); UCA1TXBUF = DCInit_transactions[TXData].Data[SPI_TX_index]; while (!(UCA1IFG & UCRXIFG)); RXData = UCA1RXBUF; } TXData = 2; for(SPI_TX_index = 0; SPI_TX_index < DCInit_transactions[TXData].Len; SPI_TX_index++){ while(!(UCA1IFG & UCTXIFG)); UCA1TXBUF = DCInit_transactions[TXData].Data[SPI_TX_index]; while (!(UCA1IFG & UCRXIFG)); RXData = UCA1RXBUF; } TXData = 3; for(SPI_TX_index = 0; SPI_TX_index < DCInit_transactions[TXData].Len; SPI_TX_index++){ while(!(UCA1IFG & UCTXIFG)); UCA1TXBUF = DCInit_transactions[TXData].Data[SPI_TX_index]; while (!(UCA1IFG & UCRXIFG)); RXData = UCA1RXBUF; } __delay_cycles(64000); TXData = 4; for(SPI_TX_index = 0; SPI_TX_index < DCInit_transactions[TXData].Len; SPI_TX_index++){ while(!(UCA1IFG & UCTXIFG)); UCA1TXBUF = DCInit_transactions[TXData].Data[SPI_TX_index]; while (!(UCA1IFG & UCRXIFG)); RXData = UCA1RXBUF; } if ((TXData == 4) && (RXData == 0x21)){ DCInit_transactions[TXData].RxFlag = 0; TXData = 5; } // GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN1); //Maxim chip select high } //****************************************************************************** // //This is the PORT2_VECTOR interrupt vector service routine // //****************************************************************************** #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=PORT4_VECTOR __interrupt #elif defined(__GNUC__) __attribute__((interrupt(PORT2_VECTOR))) #endif void P4_ISR (void) { // GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN1); GPIO_clearInterrupt (GPIO_PORT_P4, GPIO_PIN2); // Toggle P1.0 output GPIO_toggleOutputOnPin (GPIO_PORT_P1, GPIO_PIN0); GPIO_disableInterrupt (GPIO_PORT_P4, GPIO_PIN2); }