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.

MSP432 and MCP2515

Other Parts Discussed in Thread: ENERGIA

Hey all,


I've been working on getting CAN communication for a project that uses the MSP432. Our team has some Seeed Studio CAN shields for the Arduino laying around from before, so we've been using the shields as a test bench for the MCP2515. This is probably not the best way, but due to time constraints, we don't really have another option (if you have a better testing method, I'm all ears).

Now, we've been able to get SPI and CAN communication with the MCP via Seeed's Arduino libraries and Energia, but we haven't been successful with just Driverlib. We have been able to modify some example code to get SPI between two MSP launchpads and simulate the bytes that we're sending to the MCP (reset and read):

/*
 * -------------------------------------------
 *    MSP432 DriverLib - v3_10_00_09 
 * -------------------------------------------
 *
 * --COPYRIGHT--,BSD,BSD
 * Copyright (c) 2014, 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)
 * Author: Timothy Logan
*******************************************************************************/
/* DriverLib Includes */
#include "driverlib.h"

/* Standard Includes */
#include <stdint.h>

#include <stdbool.h>

/* Statics */
static volatile uint_fast8_t RXData = 0;
static uint8_t TXData = 0;

/* 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_CAPTURED_ONFIRST_CHANGED_ON_NEXT,    // Phase
        EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH, // High polarity
        EUSCI_B_SPI_3PIN                           // 3Wire SPI Mode
};

inline void chip_select(){
    GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN5);
}

inline void chip_deselect(){
    GPIO_setOutputHighOnPin(GPIO_PORT_P6, GPIO_PIN5);
}

int main(void)
{
    volatile uint32_t ii;
    uint32_t jj;

    /* Halting WDT  */
    WDT_A_holdTimer();

    GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
    GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
    
    chip_deselect();
    GPIO_setAsOutputPin(GPIO_PORT_P6, GPIO_PIN5);

    /* 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();
    // TXData = 0x01;
    
    // PCM_gotoLPM0();
    // __no_operation();
    TXData = 0xC0;          // Reset

    /* Polling to see if the TX buffer is ready */
    while (!(SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_B_SPI_TRANSMIT_INTERRUPT)));

    chip_select();
    
    /* Transmitting data to slave */
    SPI_transmitData(EUSCI_B0_BASE, TXData);
    
    chip_deselect();
    for(ii = 0; ii < 1000; ii++);
    
    // GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
    //TXData = 0x03;
    while (!(SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_B_SPI_TRANSMIT_INTERRUPT)));

    chip_select();
    TXData = 0x03;          // Read
    SPI_transmitData(EUSCI_B0_BASE, TXData);
    
    while (!(SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_B_SPI_TRANSMIT_INTERRUPT)));
    TXData = 0x0F;          // CANCTRL      (should be non-zero after reset)
    
    SPI_transmitData(EUSCI_B0_BASE, TXData);
    
    while(1) {
       
        
    }
}

//******************************************************************************
//
//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);
        chip_deselect();
        // GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
        if (RXData != 0x00) {
            GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
        // } else {
        //     GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
        }

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

}

The slave code basically just looks for 0xC0 and 0x03 and responds accordingly.

The LED is supposed to turn on when it receives a valid response from the read command, 0x03, (non-zero). Does anyone have experience working with the MCP2515 and the MSP432?

Thanks in advance!

  • Hi Ryan!

    What exactly does work / not work with your setup? It would be easier if you could narrow down your problem a little bit. From your explanation I don't really get an idea of the issue you are facing - only that it does not work as expected. Do you have an oscilloscope to look at the signals going out and coming in?

    Dennis
  • Hi Dennis,


    Sorry I wasn't more clear. We did hook up an oscilloscope and have verified that the clock is working and that chip select is going high and low when required. One thing we didn't check was the MISO line to see if there was any response from the MCP.

    What we're trying to do is see if we can read anything at all from the MCP since the CANCTRL register should have a non-zero value after reset (page 58 of this datasheet). So, we're sending reset (0xC0) and then read (0x03) and then the address of CANCTRL (0x0F) and then reading back the response to see if it's non-zero (page 65 of the datasheet). If it is, then the LED on P1.0 should light up. However, we seem to get only 0 as the response.

    Now, the same wiring setup between the launchpad and the shield works for the Energia version of the project (we get a response from the MCP), so we're pretty sure it's not a hardware/wiring issue. We've also been able to send the same data between two MSPs. Could it be a problem with the clock frequency or the SPI config? We've been trying to see how Energia does it, but it isn't clear where the SPI hardware is initialized.

    Thanks again!

**Attention** This is a public forum