Hello,
I am trying to implement an I2S bus on a MSP432, following this application note : 
I am now trying to configure the SPI and the DMA to provide a continuous flow of data through the SPI lines. This does not work as expected, the SPI sends 16 clock pulses then stops as you can see on my logic analyser screenshot :
I basically copied then modified the DMA_eusci_I2C_loopback example.
If I place a breakpoint in the DMA interrupt function, the debugger regulary stops in it, but the SPI lines don't show any activity.
Here is my code :
/*************************
* Libraries
*************************/
/* DriverLib Includes */
#include "driverlib.h"
/* Audio codec library */
#include "WM8731_Driver.h"
/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>
/************************
* Peripherals
************************/
/* 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];
/* SPI configuration */
const eUSCI_SPI_MasterConfig SPIConfig =
{
EUSCI_SPI_CLOCKSOURCE_SMCLK, //SMCLK Clock Source
12000000, //SMCLK = 12MHz
1500000, //Desired SPI Clock of 1.5MHz
EUSCI_SPI_MSB_FIRST, //Data MSB first
EUSCI_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT, //Rising edge
EUSCI_SPI_CLOCKPOLARITY_INACTIVITY_LOW, //SCLK=0 when inactive
EUSCI_SPI_3PIN //3-pin SPI
};
/*************************************
* Interrupt routines declaration
*************************************/
void DMA_Interrupt();
/************************************
* Global variables
************************************/
//Digital audio buffers, read/wrote by DMA
int8_t AudioDataIn[4], AudioDataOut[4]={0,1,2,3};
//Audio intermediate buffers
int16_t GtrIn, GtrOut=0;
//Data ready flag, to start audio processing
bool AudioDataReady=false;
/***********************************
* Main program
***********************************/
int main(void)
{
/* Stop interrupts for initialisation */
Interrupt_disableMaster();
/* Halting the Watchdog */
MAP_WDT_A_holdTimer();
/***********************************************
* Clocking
***********************************************/
//Pins
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,GPIO_PIN3 | GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION);
//Setting the external clock frequency
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
MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
MAP_FlashCtl_setWaitState(FLASH_BANK0, 2);
MAP_FlashCtl_setWaitState(FLASH_BANK1, 2);
CS_startHFXT(false);
//Initializing clock signals */
MAP_CS_initClockSignal(CS_ACLK, CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);//ACLK=32kHz
MAP_CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);//MCLK=48kHz
MAP_CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_4);//SMCLK=12MHz
/****************************************************
* EUSCI_A3 SPI (for I2S interface)
****************************************************/
//Pins
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P9, GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION);//MISO
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P9, GPIO_PIN5|GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);//SCLK, MOSI
MAP_GPIO_setAsOutputPin(GPIO_PORT_P7, GPIO_PIN5);//External counter reset
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P7, GPIO_PIN5);//Counter reset pin held high
//SPI setup
SPI_initMaster(EUSCI_A3_BASE, &SPIConfig);
//Enable SPI
SPI_enableModule(EUSCI_A3_BASE);
/****************************************************
* DMA (coupled with SPI to make I2S)
****************************************************/
//Enable DMA module
MAP_DMA_enableModule();
MAP_DMA_setControlBase(MSP_EXP432P401RLP_DMAControlTable);
//Assign channel 6 to EUSCI_A3_TX, channel 7 to EUSCI_A3_RX
DMA_assignChannel(DMA_CH6_EUSCIA3TX);
DMA_assignChannel(DMA_CH7_EUSCIA3RX);
//Set TX transfer
DMA_setChannelControl(DMA_CH6_EUSCIA3TX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
DMA_setChannelTransfer(DMA_CH6_EUSCIA3TX | UDMA_PRI_SELECT,
UDMA_MODE_AUTO, AudioDataOut,
(void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_A3_BASE),
4);
//Set RX transfer
DMA_setChannelControl(DMA_CH7_EUSCIA3RX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
DMA_setChannelTransfer(DMA_CH7_EUSCIA3RX | UDMA_PRI_SELECT,
UDMA_MODE_AUTO,
(void *) MAP_SPI_getReceiveBufferAddressForDMA(EUSCI_A3_BASE),
AudioDataOut,
4);
//Assign DMA interrupt : INT1 to TX channel
DMA_assignInterrupt(INT_DMA_INT1, 6);
//Register interrupt to a defined subroutine
DMA_registerInterrupt(INT_DMA_INT1, DMA_Interrupt);
//Flag set by default, so we have to clear it
DMA_clearInterruptFlag(6);
//Enable interrupt
Interrupt_enableInterrupt(INT_DMA_INT1);
DMA_enableInterrupt(INT_DMA_INT1);
//Everything is set up, we can enable the two DMA channels
DMA_enableChannel(6);
DMA_enableChannel(7);
/* Interrupts activation */
Interrupt_enableMaster();
/* Main program loop */
while(1)
{
if(AudioDataReady==true)
{
//Reset flag
AudioDataReady=false;
/*****************************
* Audio processing
*****************************/
//GtrIn : last guitar sample
//GtrOut : next sample to be sent to amp
GtrOut=0x0001;//Debug
/******************************/
//Put audio into DMA
AudioDataOut[0]=(int8_t)(GtrOut>>8);
AudioDataOut[1]=(int8_t)(GtrOut&0x00FF);
}
}
}
/** Interrupt routines */
/* Completion interrupt for DMA */
void DMA_Interrupt()
{
//Set flag for audio processing
AudioDataReady=true;
//Save new audio data
GtrIn=((int16_t)AudioDataIn[0]<<8)+(int16_t)(AudioDataIn[1]);
DMA_clearInterruptFlag(6);
}
I don't understand why SPI sends the first two packets, then suddenly stops ?
Thank you for any help,
David
