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!