Quantcast
Channel: MSP low-power microcontroller forum - Recent Threads
Viewing all articles
Browse latest Browse all 22733

MSP432 I2S implementation

$
0
0

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


Viewing all articles
Browse latest Browse all 22733

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>