This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Part Number: MSP432P401M
Tool/software: Code Composer Studio
Hello Team,
I have attached piece of schematics and my SPI code, i tried in many ways but not getting any luck in getting through. Problem is we are unable to communicate with SPI IO expander chip. I would need to help to review the code and let me know for any wrong settings or any other issues.
I am using 48MHz crystal on hardware side. I can provide full schematics if required for deeper analysis. In the schematics DNI indicates, do not install.
Thanks.
- Jagdish G
#ifdef REQUIRED /* --COPYRIGHT--,BSD * Copyright (c) 2017, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --/COPYRIGHT--*/ /****************************************************************************** * MSP432 SPI - 3-wire Master Incremented Data * * This example shows how SPI master talks to SPI slave using 3-wire mode. * Incrementing data is sent by the master starting at 0x01. Received data is * expected to be same as the previous transmission. eUSCI RX ISR is used to * handle communication with the CPU, normally in LPM0. Because all execution * after LPM0 is in ISRs, initialization waits for DCO to stabilize against * ACLK. * * Note that in this example, EUSCIB0 is used for the SPI port. If the user * wants to use EUSCIA for SPI operation, they are able to with the same APIs * with the EUSCI_AX parameters. * * ACLK = ~32.768kHz, MCLK = SMCLK = DCO 3MHz * * Use with SPI Slave Data Echo code example. * * MSP432P401 * ----------------- * | | * | | * | | * | P1.6|-> Data Out (UCB0SIMO) * | | * | P1.7|<- Data In (UCB0SOMI) * | | * | P1.5|-> Serial Clock Out (UCB0CLK) *******************************************************************************/ /* DriverLib Includes */ #include <ti/devices/msp432p4xx/driverlib/driverlib.h> /* Standard Includes */ #include <stdint.h> #include <stdbool.h> void msdelay(unsigned int time); /* Statics */ static volatile uint8_t RXData = 0; static uint8_t TXData = 0; //For Bank 0 #define SLAVE_WRITE 0 #define SLAVE_READ 1 #define IODIRA 0x00 #define IODIRB 0x01 #define IOCONA 0x0A #define GPIOA 0x12 #define GPIOB 0x13 #define SLAVE_ADDR 0x40 //![Simple SPI Config] /* SPI Master Configuration Parameter */ const eUSCI_SPI_MasterConfig spiMasterConfig = { EUSCI_B_SPI_CLOCKSOURCE_SMCLK, // SMCLK Clock Source 3000000, // SMCLK = DCO = 3MHZ 500000, // SPICLK = 500khz EUSCI_B_SPI_MSB_FIRST, // MSB First EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT, // Phase EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH, // High polarity EUSCI_B_SPI_3PIN // 3Wire SPI Mode }; //![Simple SPI Config] int main(void) { /* Halting WDT */ WDT_A_holdTimer(); P1->SEL0 &= ~BIT0; P1->SEL1 |= BIT0; P1->DIR |= BIT0; //![Simple SPI Example] /* Selecting P1.5 P1.6 and P1.7 in SPI mode */ GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION); /* Configuring SPI in 3wire master mode */ SPI_initMaster(EUSCI_B0_BASE, &spiMasterConfig); /* Enable SPI module */ SPI_enableModule(EUSCI_B0_BASE); /* Enabling interrupts */ SPI_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_SPI_RECEIVE_INTERRUPT); Interrupt_enableInterrupt(INT_EUSCIB0); Interrupt_enableSleepOnIsrExit(); //![Simple SPI Example] TXData = 0x55; while(1) { P1->OUT &= ~BIT0; // while (!(SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_B_SPI_TRANSMIT_INTERRUPT))); // SPI_transmitData(EUSCI_B0_BASE, 0x00); msdelay(2); //while (!(SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_B_SPI_TRANSMIT_INTERRUPT))); SPI_transmitData(EUSCI_B0_BASE, ++TXData); P1->OUT |= BIT0; msdelay(2); } /* Polling to see if the TX buffer is ready */ /* Transmitting data to slave */ SPI_transmitData(EUSCI_B0_BASE, TXData); PCM_gotoLPM0(); __no_operation(); } //****************************************************************************** // //This is the EUSCI_B0 interrupt vector service routine. // //****************************************************************************** void EUSCIB0_IRQHandler(void) { uint32_t status = SPI_getEnabledInterruptStatus(EUSCI_B0_BASE); uint32_t jj; SPI_clearInterruptFlag(EUSCI_B0_BASE, status); if(status & EUSCI_B_SPI_RECEIVE_INTERRUPT) { /* USCI_B0 TX buffer ready? */ while (!(SPI_getInterruptStatus(EUSCI_B0_BASE, EUSCI_B_SPI_TRANSMIT_INTERRUPT))); //RXData = SPI_receiveData(EUSCI_B0_BASE); /* Send the next data packet */ //SPI_transmitData(EUSCI_B0_BASE, ++TXData); /* Delay between transmissions for slave to process information */ for(jj=50;jj<50;jj++); } } void msdelay(unsigned int time) { int i,j; for(i=0;i<time;i++) for(j=0;j<1000;j++); } #endif /* --COPYRIGHT--,BSD * Copyright (c) 2017, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --/COPYRIGHT--*/ /****************************************************************************** * MSP432 SPI - 3-wire Master Incremented Data * * This example shows how SPI master talks to SPI slave using 3-wire mode. * Incrementing data is sent by the master starting at 0x01. Received data is * expected to be same as the previous transmission. eUSCI RX ISR is used to * handle communication with the CPU, normally in LPM0. Because all execution * after LPM0 is in ISRs, initialization waits for DCO to stabilize against * ACLK. * * Note that in this example, EUSCIB0 is used for the SPI port. If the user * wants to use EUSCIA for SPI operation, they are able to with the same APIs * with the EUSCI_AX parameters. * * ACLK = ~32.768kHz, MCLK = SMCLK = DCO 3MHz * * Use with SPI Slave Data Echo code example. * * MSP432P401 * ----------------- * | | * | P1.0|-> CS * | | * | P1.2|-> Data Out (UCA0MISO) * | | * | P1.3|<- Data In (UCA0MOSI) * | | * | P1.1|-> Serial Clock Out (UCB0CLK) *******************************************************************************/ /* DriverLib Includes */ #include <ti/devices/msp432p4xx/driverlib/driverlib.h> /* Standard Includes */ #include <stdint.h> #include <stdbool.h> void msdelay(unsigned int time); /* Statics */ static volatile uint8_t RXData = 52; static volatile uint8_t RXData1 = 0x52; static volatile uint8_t RXData2 = 0x32; static uint8_t TXData = 0; #define SLAVE_ADDR 0x40 //For Bank 1 #define B1_SLAVE_WRITE 0 #define B1_SLAVE_READ 1 #define B1_IODIRA 0x00 #define B1_IODIRB 0x10 //#define IOCONA 0x0A #define B1_IOCONA 0x05 #define B1_GPIOA 0x09 #define B1_GPIOB 0x19 //For Bank 0 #define SLAVE_WRITE 0 #define SLAVE_READ 1 #define B0_IODIRA 0x00 #define B0_IODIRB 0x01 #define B0_IOCONA 0x0A //#define IOCONA 0x05 #define B0_GPIOA 0x12 #define B0_GPIOB 0x13 char buf[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff}; //![Simple SPI Config] /* SPI Master Configuration Parameter */ const eUSCI_SPI_MasterConfig spiMasterConfig = { EUSCI_A_SPI_CLOCKSOURCE_SMCLK, // SMCLK Clock Source 3000000, // SMCLK = DCO = 3MHZ 500000, // SPICLK = 500khz EUSCI_A_SPI_MSB_FIRST, // MSB First EUSCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT, // Phase EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_HIGH, // High polarity //EUSCI_A_SPI_3PIN // 3Wire SPI Mode EUSCI_A_SPI_4PIN_UCxSTE_ACTIVE_LOW|(1<<13) // 4Wire SPI Mode }; //![Simple SPI Config] char out = 0xff; int main(void) { int i; /* Halting WDT */ WDT_A_holdTimer(); //![Simple SPI Example] /* Selecting P1.1 P1.2 and P1.3 in SPI mode */ GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION); GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION); P1->SEL0 &= ~BIT0; P1->SEL1 &= ~BIT0; //P1->REN &= ~BIT2; P1->DIR |= BIT0; // GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, // GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION); /* Configuring SPI in 4wire master mode */ SPI_initMaster(EUSCI_A0_BASE, &spiMasterConfig); /* Enable SPI module */ SPI_enableModule(EUSCI_A0_BASE); /* Enabling interrupts */ //SPI_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_SPI_RECEIVE_INTERRUPT); ///SPI_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_SPI_RECEIVE_INTERRUPT); //Interrupt_enableInterrupt(INT_EUSCIA0); //Interrupt_enableSleepOnIsrExit(); //![Simple SPI Example] // TXData = 0x01; /* Polling to see if the TX buffer is ready */ // P1->OUT &= ~BIT0; #ifdef re //Select BANK1 SPI_transmitData(EUSCI_A0_BASE, SLAVE_ADDR|SLAVE_WRITE); // while (!(SPI_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT))); msdelay(1); SPI_transmitData(EUSCI_A0_BASE, B0_IOCONA); //while (!(SPI_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT))); msdelay(1); SPI_transmitData(EUSCI_A0_BASE, 0x80); // while (!(SPI_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT))); msdelay(1); // P1->OUT |= BIT0; #endif #ifdef re P1->OUT &= ~BIT0; msdelay(2); SPI_transmitData(EUSCI_A0_BASE, SLAVE_ADDR|SLAVE_WRITE); msdelay(1); SPI_transmitData(EUSCI_A0_BASE, B0_IOCONA); msdelay(1); SPI_transmitData(EUSCI_A0_BASE, 0x38); msdelay(2); P1->OUT |= BIT0; #endif P1->OUT &= ~BIT0; msdelay(5); SPI_transmitData(EUSCI_A0_BASE, SLAVE_ADDR|SLAVE_READ); // msdelay(10); SPI_transmitData(EUSCI_A0_BASE, 0x00); // msdelay(10); //SPI_transmitData(EUSCI_A0_BASE, 0xff); //msdelay(2); RXData = SPI_receiveData(EUSCI_A0_BASE); P1->OUT |= BIT0; while(1); #ifdef re SPI_transmitData(EUSCI_A0_BASE, SLAVE_ADDR|SLAVE_WRITE); // while (!(SPI_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT))); msdelay(1); SPI_transmitData(EUSCI_A0_BASE, B1_IODIRA); //while (!(SPI_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT))); msdelay(1); SPI_transmitData(EUSCI_A0_BASE, 0x00); // while (!(SPI_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT))); msdelay(1); // P1->OUT |= BIT0; SPI_transmitData(EUSCI_A0_BASE, SLAVE_ADDR|SLAVE_WRITE); // while (!(SPI_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT))); msdelay(1); SPI_transmitData(EUSCI_A0_BASE, B1_GPIOA); //while (!(SPI_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT))); msdelay(1); SPI_transmitData(EUSCI_A0_BASE, 0xff); // while (!(SPI_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT))); msdelay(1); // P1->OUT |= BIT0; #endif } //****************************************************************************** // //This is the EUSCI_B0 interrupt vector service routine. // //****************************************************************************** void EUSCIA0_IRQHandler(void) { uint32_t status = SPI_getEnabledInterruptStatus(EUSCI_A0_BASE); uint32_t jj; SPI_clearInterruptFlag(EUSCI_A0_BASE, status); if(status & EUSCI_A_SPI_RECEIVE_INTERRUPT) { /* USCI_B0 TX buffer ready? */ while (!(SPI_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT))); RXData = SPI_receiveData(EUSCI_A0_BASE); for(jj=50;jj<50;jj++); } } void msdelay(unsigned int time) { int i,j; for(i=0;i<time;i++) for(j=0;j<1000;j++); }
Chris,
Looks like SPI is transmitting, we did captured master data out scope traces. Since we had multiple hardware setup, we tried all to ensure its not single board problem. Firmware engineer did started with example code from beginning but no luck. Slave is not responding.
-Jagdish g
**Attention** This is a public forum