I made a similar question in another thread but I thought this deserves it's own. I hope I don't anger anyone by doing this.
My goal is to make an external source initiate DMA SPI transfer without waking the MCU up. I am using MSP432 black launchpad(soon red).
I connected my P2.6 GPIO to P7.0 DMAE0 and this is how I want it to work:
I configure the SPI and I enable it. Then I assign channel 0 source to be EUSCIB0_TX and I assign channel 6 source to be EXTERNAL_PIN.
Now I clear the SPI_TX_INTERRUPT flag so my channel 0 won't initate trasnfer as soon as I enable the channel. For both channels the destination is the SPI_TX_BUFFER. And I just tell channel 6 to write 1 byte to TX_BUFFER and when that gets sent the SPI triggers SPI_TX_INTERRUPT which initiates the channel 0 transfer. After that transef completes I want a interrupt to happen to tell me that the transfer completed.
So after I configured the transfers, I enable the interrupt and enable the channel. Now I put high on P2.6(P7.0) and thats the whole application.
The problem is that as soon as I enable the interrupt it occurs even though no transfer happened and I didn't even put high on P2.6. In the documentation it says that the interrupt happens after the DMA completes the transfer. Even if the SPI triggers the DMA interrupt, I cleared the SP_TX_BUFFER and I cleared the DMA_INTERRUPT flag. Here is the code:
//*****************************************************************************
//
// MSP432 main.c
//
//****************************************************************************
#include "driverlib.h"
#include "IQmathLib.h"
#pragma DATA_ALIGN(MSP_EXP432P401RLP_DMAControlTable, 1024)
static DMA_ControlTable MSP_EXP432P401RLP_DMAControlTable[32];
void InitMCU();
void main(void)
{
InitMCU();
uint8_t buffer = 0x55;
// Clear interrupt status
SPI_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_SPI_TRANSMIT_INTERRUPT);
// Activate DMA SPI transfer with external pin
DMA_setChannelControl(DMA_CH6_EXTERNALPIN | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_1);
DMA_setChannelTransfer(DMA_CH6_EXTERNALPIN | UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
&buffer,
(void *) SPI_getTransmitBufferAddressForDMA(EUSCI_B0_BASE),
1);
// Setup the TX transfer characteristics & buffers
DMA_setChannelControl(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
DMA_setChannelTransfer(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
&buffer,
(void *) SPI_getTransmitBufferAddressForDMA(EUSCI_B0_BASE),
1);
MAP_DMA_clearInterruptFlag(0);
MAP_DMA_enableInterrupt(INT_DMA_INT1);
// Assigning/Enabling Interrupts
MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
MAP_DMA_enableChannel(0);
MAP_DMA_enableChannel(6);
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN6);
while(1);
}
// DMA INT1 ISR
void DMA_INT1_IRQHandler(void)
{
return;
}
// SPI Master Configuration Parameter for CC1200
const eUSCI_SPI_MasterConfig spiMasterConfig =
{
EUSCI_B_SPI_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
6000000, // SMCLK = HFXT/8 = 6MHz
6000000, // SPICLK = 6MHz
EUSCI_B_SPI_MSB_FIRST, // MSB First
EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT, // Phase
EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW, // Low polarity
EUSCI_B_SPI_3PIN // 3Wire SPI Mode
};
// Initialize the MCU
void InitMCU()
{
// Halting the Watchdog
WDT_A_holdTimer();
// Enabling MASTER interrupts
Interrupt_disableMaster();
// Set power state of MCU
PCM_setPowerState(PCM_AM_LDO_VCORE1);
// Configuring pins for peripheral/crystal usage and LED for output
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,
GPIO_PIN3 | GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION);
// Just in case the user wants to use the getACLK, getMCLK, etc. functions,
// let's set the clock frequency in the code
CS_setExternalClockSourceFrequency(32000,48000000);
// Starting HFXT in non-bypass mode without a timeout. Before we start
// we have to change VCORE to 1 to support the 48MHz frequency
//PCM_setCoreVoltageLevel(PCM_VCORE1);
FlashCtl_setWaitState(FLASH_BANK0, 2);
FlashCtl_setWaitState(FLASH_BANK1, 2);
CS_startHFXT(false);
// Initializing MCLK to HFXT (effectively 48MHz)
CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
// Initializing SMCLK to HFXT (effectively 6MHz)
CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_8);
// Selecting pins P1.5, P1.6 and P1.7 in SPI mode
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
GPIO_PIN7 | GPIO_PIN6 | GPIO_PIN5, GPIO_PRIMARY_MODULE_FUNCTION);
GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN6);
GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN6);
// Selecting pin 7.0 in DMAE0
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P7, GPIO_PIN0, GPIO_PRIMARY_MODULE_FUNCTION);
// Configuring SPI in 3wire master mode for CC1200
SPI_initMaster(EUSCI_B0_BASE, &spiMasterConfig);
// Enable SPI module for CC1200
SPI_enableModule(EUSCI_B0_BASE);
// Configuring DMA module
DMA_enableModule();
DMA_setControlBase(MSP_EXP432P401RLP_DMAControlTable);
// Assign DMA channel 0 to EUSCI_B0_TX0, channel 1 to EUSCI_B0_RX0
DMA_assignChannel(DMA_CH0_EUSCIB0TX0);
DMA_assignChannel(DMA_CH6_EXTERNALPIN);
// Enable DMA interrupt
MAP_DMA_assignInterrupt(INT_DMA_INT1, 0);
MAP_DMA_disableInterrupt(INT_DMA_INT1);
MAP_DMA_clearInterruptFlag(0);
// Enabling MASTER interrupts
Interrupt_enableMaster();
}