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.

CCS/MSP432P401M: SPI Code || MCP23S17

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++);
}

**Attention** This is a public forum