I am using the Texas’s example of SPI with DMA driverlib for MSP432. The example works perfectly but I need to change the master port from B3 to B0. When I make this change, the DMA does not interrupt me.
I attached the example of Texas and the .c modified, to see if someone manages to discover or explain me, why doesn’t work, with this change. In the modified file, I add comments indicating which lines change and why, to make the problem easier to find
Thank you very much!!!
/*
* -------------------------------------------
* MSP432 DriverLib - v3_21_00_05
* -------------------------------------------
*
* --COPYRIGHT--,BSD,BSD
* Copyright (c) 2016, 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 DMA - eUSCI SPI Transfer Using DMA
*
* Description: In this code example, the MSP432 's DMA controller is used in
* conjunction with an SPI loopback configuration to demonstrate how to use
* hardware triggered DMA transfers. Four DMA transfers are setup using four
* separate DMA channels. For each SPI instance, a DMA channel is setup to
* receive and transfer from the SIMO and SOMI ports respectively. After an
* arbitrary string is sent through SPI via the loopback configuration, an
* ISR counter is incremented and triggers a NOP condition in the main loop
* where the user can set a breakpoint to examine memory contents.
*
*
* MSP432P401
* ---------------------------
* /|\| |
* | | |
* --|RST P1.5 (CLK) |-------------
* | P1.7 (SIMO) |---------- |
* | P1.6 (SOMI) |-------- | |
* | | | | |
* | | | | |
* | P3.6 (SIMO) |-------- | |
* | P3.7 (SOMI) |---------- |
* | P3.5 (CLK) |-------------
* | |
* | |
*
* Author: Timothy Logan
******************************************************************************/
/* DriverLib Includes */
#include "driverlib.h"
/* Standard Includes */
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
/* SPI Configuration Parameter */
const eUSCI_SPI_MasterConfig spiMasterConfig =
{ EUSCI_B_SPI_CLOCKSOURCE_SMCLK, 12000000, 1000000,
EUSCI_B_SPI_MSB_FIRST,
EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT,
EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH, EUSCI_B_SPI_3PIN };
const eUSCI_SPI_SlaveConfig spiSlaveConfig =
{ EUSCI_B_SPI_MSB_FIRST,
EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT,
EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH,
EUSCI_B_SPI_3PIN
};
/* DMA Control Table */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_ALIGN(MSP_EXP432P401RLP_DMAControlTable, 1024)
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment=1024
#elif defined(__GNUC__)
__attribute__ ((aligned (1024)))
#elif defined(__CC_ARM)
__align(1024)
#endif
static DMA_ControlTable MSP_EXP432P401RLP_DMAControlTable[32];
#define MAP_SPI_MSG_LENGTH 26
uint32_t isrCounter = 0;
uint8_t mstxData[26] = "Hello, this is master SPI";
uint8_t msrxData[26] =
{ 0 };
uint8_t sltxData[26] = "Hello, this is slave SPI";
uint8_t slrxData[26] =
{ 0 };
int main(void)
{
volatile uint32_t ii;
/* Halting Watchdog */
MAP_WDT_A_holdTimer();
/* Configure CLK, MOSI & MISO for SPI0 (EUSCI_B0) */
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1,
GPIO_PIN5 | GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION);
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
/* Configure SLAVE CLK, MOSI and SPMI (EUSCI_B2) */
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3,
GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7,
GPIO_PRIMARY_MODULE_FUNCTION);
/* Configuring SPI module */
MAP_SPI_initSlave(EUSCI_B2_BASE, &spiSlaveConfig);
MAP_SPI_initMaster(EUSCI_B0_BASE, &spiMasterConfig);
/* Enable the SPI module */
MAP_SPI_enableModule(EUSCI_B2_BASE);
MAP_SPI_enableModule(EUSCI_B0_BASE);
/* Configuring DMA module */
MAP_DMA_enableModule();
MAP_DMA_setControlBase(MSP_EXP432P401RLP_DMAControlTable);
/* Assign DMA channel 0 to EUSCI_B0_TX0, channel 1 to EUSCI_B0_RX0 */
MAP_DMA_assignChannel(DMA_CH0_EUSCIB0TX0);
MAP_DMA_assignChannel(DMA_CH1_EUSCIB0RX0);
MAP_DMA_assignChannel(DMA_CH4_EUSCIB2TX0);
MAP_DMA_assignChannel(DMA_CH5_EUSCIB2RX0);
/* Setup the TX transfer characteristics & buffers */
MAP_DMA_setChannelControl(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
MAP_DMA_setChannelTransfer(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, mstxData,
(void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B0_BASE),
MAP_SPI_MSG_LENGTH);
/* Setup the RX transfer characteristics & buffers */
MAP_DMA_setChannelControl(DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
MAP_DMA_setChannelTransfer(DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
(void *) MAP_SPI_getReceiveBufferAddressForDMA(EUSCI_B0_BASE),
msrxData,
MAP_SPI_MSG_LENGTH);
/* Slave Settings */
MAP_DMA_setChannelControl(DMA_CH4_EUSCIB2TX0 | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
MAP_DMA_setChannelTransfer(DMA_CH4_EUSCIB2TX0 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, sltxData,
(void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B2_BASE),
MAP_SPI_MSG_LENGTH);
/* Setup the RX transfer characteristics & buffers */
MAP_DMA_setChannelControl(DMA_CH5_EUSCIB2RX0 | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
MAP_DMA_setChannelTransfer(DMA_CH5_EUSCIB2RX0 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
(void *) MAP_SPI_getReceiveBufferAddressForDMA(EUSCI_B2_BASE),
slrxData,
MAP_SPI_MSG_LENGTH);
/* Enable DMA interrupt */
MAP_DMA_assignInterrupt(INT_DMA_INT1, 1);
MAP_DMA_clearInterruptFlag(DMA_CH1_EUSCIB0RX0 & 0x0F);
/* Assigning/Enabling Interrupts */
MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
MAP_DMA_enableInterrupt(INT_DMA_INT1);
MAP_DMA_enableChannel(5);
MAP_DMA_enableChannel(4);
/* Delaying for forty cycles to let the master catch up with the slave */
for(ii=0;ii<50;ii++);
MAP_DMA_enableChannel(1);
MAP_DMA_enableChannel(0);
/* Polling to see if the master receive is finished */
while (1)
{
if (isrCounter > 0)
{
__no_operation();
}
}
}
void DMA_INT1_IRQHandler(void)
{
isrCounter++;
MAP_DMA_clearInterruptFlag(0);
MAP_DMA_clearInterruptFlag(1);
/* Disable the interrupt to allow execution */
MAP_Interrupt_disableInterrupt(INT_DMA_INT1);
MAP_DMA_disableInterrupt(INT_DMA_INT1);
}
/*
* -------------------------------------------
* MSP432 DriverLib - v3_21_00_05
* -------------------------------------------
*
* --COPYRIGHT--,BSD,BSD
* Copyright (c) 2016, 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 DMA - eUSCI SPI Transfer Using DMA
*
* Description: In this code example, the MSP432 's DMA controller is used in
* conjunction with an SPI loopback configuration to demonstrate how to use
* hardware triggered DMA transfers. Four DMA transfers are setup using four
* separate DMA channels. For each SPI instance, a DMA channel is setup to
* receive and transfer from the SIMO and SOMI ports respectively. After an
* arbitrary string is sent through SPI via the loopback configuration, an
* ISR counter is incremented and triggers a NOP condition in the main loop
* where the user can set a breakpoint to examine memory contents.
*
*
* MSP432P401
* ---------------------------
* /|\| |
* | | |
* --|RST P10.1 (CLK) |------------- //Texas's example says 1.5; 1.7; 1.6 because it uses SPI B0
* | P10.2 (SIMO) |---------- |
* | P10.3 (SOMI) |-------- | |
* | | | | |
* | | | | |
* | P3.6 (SIMO) |-------- | |
* | P3.7 (SOMI) |---------- |
* | P3.5 (CLK) |-------------
* | |
* | |
*
* Author: Timothy Logan
******************************************************************************/
/* DriverLib Includes */
#include "driverlib.h"
/* Standard Includes */
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
/* SPI Configuration Parameter */
const eUSCI_SPI_MasterConfig spiMasterConfig =
{ EUSCI_B_SPI_CLOCKSOURCE_SMCLK, 12000000, 1000000,
EUSCI_B_SPI_MSB_FIRST,
EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT,
EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH, EUSCI_B_SPI_3PIN};
const eUSCI_SPI_SlaveConfig spiSlaveConfig =
{ EUSCI_B_SPI_MSB_FIRST,
EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT,
EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH, EUSCI_B_SPI_3PIN};
/* DMA Control Table */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_ALIGN(MSP_EXP432P401RLP_DMAControlTable, 1024)
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment=1024
#elif defined(__GNUC__)
__attribute__ ((aligned (1024)))
#elif defined(__CC_ARM)
__align(1024)
#endif
static DMA_ControlTable MSP_EXP432P401RLP_DMAControlTable[32];
#define MAP_SPI_MSG_LENGTH 64
uint32_t isrCounter = 0;
uint8_t mstxData[MAP_SPI_MSG_LENGTH];
uint8_t msrxData[MAP_SPI_MSG_LENGTH];
uint8_t sltxData[MAP_SPI_MSG_LENGTH];
uint8_t slrxData[MAP_SPI_MSG_LENGTH];
int main(void)
{
volatile uint32_t i;
for(i=0; i< MAP_SPI_MSG_LENGTH; i++){ //In the Texas's example I did this change without problems
if(i%2 == 0){
mstxData[i] = 0x3F;
} else {
mstxData[i] = 0x00;
}
sltxData[i] = i;
}
/* Halting Watchdog */
MAP_WDT_A_holdTimer();
/* Configure CLK, MOSI & MISO for SPI0 (EUSCI_B3) */
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P10, //I configure the pins of port 10 (SPI B3)
GPIO_PIN1 | GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION);
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P10,
GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
//Original:
/*Configure CLK, MOSI & MISO for SPI0 (EUSCI_B0)
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1,
GPIO_PIN5 | GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION);
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION); */
/* Configure SLAVE CLK, MOSI and SPMI (EUSCI_B2) */
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, //I use the same slave
GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7,
GPIO_PRIMARY_MODULE_FUNCTION);
/* Configuring SPI module */
MAP_SPI_initSlave(EUSCI_B2_BASE, &spiSlaveConfig);
MAP_SPI_initMaster(EUSCI_B3_BASE, &spiMasterConfig); //Original: MAP_SPI_initMaster(EUSCI_B0_BASE, &spiMasterConfig);
/* Enable the SPI module */
MAP_SPI_enableModule(EUSCI_B2_BASE);
MAP_SPI_enableModule(EUSCI_B3_BASE); //Original: MAP_SPI_enableModule(EUSCI_B0_BASE);
/* Configuring DMA module */
MAP_DMA_enableModule();
MAP_DMA_setControlBase(MSP_EXP432P401RLP_DMAControlTable);
/* Assign DMA channel 0 to EUSCI_B0_TX0, channel 1 to EUSCI_B0_RX0 */
MAP_DMA_assignChannel(DMA_CH0_EUSCIB3TX1); //Original: MAP_DMA_assignChannel(DMA_CH0_EUSCIB0TX0);
MAP_DMA_assignChannel(DMA_CH1_EUSCIB3RX1); //Original: MAP_DMA_assignChannel(DMA_CH1_EUSCIB0RX0);
MAP_DMA_assignChannel(DMA_CH4_EUSCIB2TX0);
MAP_DMA_assignChannel(DMA_CH5_EUSCIB2RX0);
/* Setup the TX transfer characteristics & buffers */
MAP_DMA_setChannelControl(DMA_CH0_EUSCIB3TX1 | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
MAP_DMA_setChannelTransfer(DMA_CH0_EUSCIB3TX1 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, mstxData, (void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B3_BASE),
MAP_SPI_MSG_LENGTH);
//Original:
/* MAP_DMA_setChannelControl(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
MAP_DMA_setChannelTransfer(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, mstxData,
(void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B0_BASE),
MAP_SPI_MSG_LENGTH); */
/* Setup the RX transfer characteristics & buffers */
MAP_DMA_setChannelControl(DMA_CH1_EUSCIB3RX1 | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
MAP_DMA_setChannelTransfer(DMA_CH1_EUSCIB3RX1 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, (void *) MAP_SPI_getReceiveBufferAddressForDMA(EUSCI_B3_BASE),
msrxData, MAP_SPI_MSG_LENGTH);
//Original:
/* MAP_DMA_setChannelControl(DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
MAP_DMA_setChannelTransfer(DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
(void *) MAP_SPI_getReceiveBufferAddressForDMA(EUSCI_B0_BASE),
msrxData,
MAP_SPI_MSG_LENGTH); */
/* Slave Settings */
MAP_DMA_setChannelControl(DMA_CH4_EUSCIB2TX0 | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
MAP_DMA_setChannelTransfer(DMA_CH4_EUSCIB2TX0 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, sltxData, (void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B2_BASE),
MAP_SPI_MSG_LENGTH);
/* Setup the RX transfer characteristics & buffers */
MAP_DMA_setChannelControl(DMA_CH5_EUSCIB2RX0 | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
MAP_DMA_setChannelTransfer(DMA_CH5_EUSCIB2RX0 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, (void *) MAP_SPI_getReceiveBufferAddressForDMA(EUSCI_B2_BASE),
slrxData, MAP_SPI_MSG_LENGTH);
/* Enable DMA interrupt */
MAP_DMA_assignInterrupt(INT_DMA_INT1, 1);
MAP_DMA_clearInterruptFlag(DMA_CH1_EUSCIB3RX1 & 0x0F); //Original: MAP_DMA_clearInterruptFlag(DMA_CH1_EUSCIB0RX0 & 0x0F);
/* Assigning/Enabling Interrupts */
MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
MAP_DMA_enableInterrupt(INT_DMA_INT1);
MAP_DMA_enableChannel(5);
MAP_DMA_enableChannel(4);
/* Delaying for forty cycles to let the master catch up with the slave */
for(i=0;i<50;i++);
MAP_DMA_enableChannel(1); //This is not necesarry to changed it because TXB3 and TXB0 use the same channel of DMA
MAP_DMA_enableChannel(0); //This is not necesarry to changed it because RXB3 and RXB0 use the same channel of DMA
/* Polling to see if the master receive is finished */
while (1)
{
if (isrCounter > 0)
{
__no_operation();
}
}
}
void DMA_INT1_IRQHandler(void)
{
isrCounter++;
MAP_DMA_clearInterruptFlag(0);
MAP_DMA_clearInterruptFlag(1);
/* Disable the interrupt to allow execution */
MAP_Interrupt_disableInterrupt(INT_DMA_INT1);
MAP_DMA_disableInterrupt(INT_DMA_INT1);
}
