This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Part Number: MSP432P401R
Hi,
i am trying to get an external DMA trigger to read ADC data with SPI.
So this is what i am trying to do. I am using the ADS131A02 and want to read 32Bit values via SPI on my MSP432.
The DRDY Pin from ADS131A02 is connected to the P7.0 from MSP432. This port is configured as PM_DMAE0.
Every time the ADC has a new value the external DMA should trigger the DMA to write to the SPI TX buffer and after 512 transactions, the DMA RX should fired an interrupt to wake the MSP432.
At the moment the DMAE0 is working and it is triggering the DMA TX that writes values to SPI TX buffer. This is only working one time and the next DMAE0 interrupt are ignored.
This is my code:
#include "ADS131A02.h" #include <ti/devices/msp432p4xx/driverlib/driverlib.h> /* DMA Control Table */ #ifdef ewarm #pragma data_alignment=256 #else #pragma DATA_ALIGN(controlTable, 256) #endif uint8_t controlTable[256]; uint8_t DMA_recBuffer[9]; uint8_t DMA_sendBuffer[9]; #define SAMPLE_LENGTH 512 float hann[SAMPLE_LENGTH]; int8_t data_array1[SAMPLE_LENGTH]; int8_t data_array2[SAMPLE_LENGTH]; uint8_t data_array[4]={0x00,0x00,0x00,0x00}; volatile int switch_data = 0; void ADS131A02_SPI_Setup(void) { GPIO_setAsOutputPin(GPIO_PORT_P3, GPIO_PIN0); GPIO_setAsOutputPin(GPIO_PORT_P3, GPIO_PIN6); GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P7, GPIO_PIN0); GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN0); // CS Disable GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN6); // Reset Disable // SPI Master Configuration Parameter const eUSCI_SPI_MasterConfig spiMasterConfig = { EUSCI_A_SPI_CLOCKSOURCE_SMCLK, // SMCLK Clock Source 48000000, // SMCLK = HFXT = 48Mhz 24000000, // SPICLK =12000000 EUSCI_A_SPI_MSB_FIRST, // MSB First EUSCI_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT, // Phase EUSCI_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT / EUSCI_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW, // High polarity EUSCI_A_SPI_3PIN }; /* 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); // Selecting pin 7.0 in DMAE0 GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P7, GPIO_PIN0, GPIO_PRIMARY_MODULE_FUNCTION); /* Configuring SPI in 3wire master mode */ SPI_initMaster(EUSCI_B0_BASE, &spiMasterConfig); SPI_enableModule(EUSCI_B0_BASE); /* Enable Interrupt */ GPIO_clearInterruptFlag(GPIO_PORT_P7, GPIO_PIN0); GPIO_enableInterrupt(GPIO_PORT_P7, GPIO_PIN0); GPIO_interruptEdgeSelect(GPIO_PORT_P7, GPIO_PIN0,GPIO_LOW_TO_HIGH_TRANSITION); //Interrupt_enableInterrupt(INT_PORT7); SPI_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_SPI_TRANSMIT_INTERRUPT); } void ADS131A02_DMASetup(void) { //Assigning DMA to SPI Channels DMA_enableModule(); DMA_setControlBase(controlTable); DMA_assignChannel(DMA_CH0_EUSCIB0TX0); DMA_assignChannel(DMA_CH1_EUSCIB0RX0); DMA_assignChannel(DMA_CH6_EXTERNALPIN); DMA_disableChannelAttribute(DMA_CH6_EXTERNALPIN,UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |UDMA_ATTR_HIGH_PRIORITY |UDMA_ATTR_REQMASK); // Setup the TX transfer characteristics & buffers 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, data_array,(void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B0_BASE), 1); DMA_setChannelControl (DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_1); DMA_setChannelTransfer(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,UDMA_MODE_BASIC, data_array,(void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B0_BASE),512); DMA_setChannelControl (DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1); DMA_setChannelTransfer(DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *) MAP_SPI_getReceiveBufferAddressForDMA(EUSCI_B0_BASE),data_array1,512); DMA_setChannelControl (DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1); DMA_setChannelTransfer(DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *) MAP_SPI_getReceiveBufferAddressForDMA(EUSCI_B0_BASE),data_array2,512); DMA_assignInterrupt(DMA_INT1, 1); DMA_clearInterruptFlag(INT_DMA_INT1); DMA_clearInterruptFlag(1); Interrupt_enableInterrupt(DMA_INT1); Interrupt_enableMaster(); DMA_enableChannel(6); DMA_enableChannel(0); DMA_enableChannel(1); } void DMA_INT1_IRQHandler(void) { DMA_clearInterruptFlag(1); /* Switch between primary and alternate bufferes with DMA's PingPong mode */ if (DMA_getChannelAttribute(1) & UDMA_ATTR_ALTSELECT) { DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH1_EUSCIB0RX0,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1); DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH1_EUSCIB0RX0,UDMA_MODE_PINGPONG, (void*)MAP_SPI_getReceiveBufferAddressForDMA(EUSCI_B0_BASE),data_array1, SAMPLE_LENGTH); switch_data = 1; } else { DMA_setChannelControl(UDMA_ALT_SELECT | DMA_CH1_EUSCIB0RX0,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1); DMA_setChannelTransfer(UDMA_ALT_SELECT | DMA_CH1_EUSCIB0RX0,UDMA_MODE_PINGPONG, (void*)MAP_SPI_getReceiveBufferAddressForDMA(EUSCI_B0_BASE),data_array2, SAMPLE_LENGTH); switch_data = 0; } }
DMAE0 is triggering the SPI TX and SPI will write 511 times to the ADC. I am getting the DMA RX interrupt with 512 values and i change then the pingpong buffer.
After that nothing else happens.
If i change the SPI TX from 512 to 4 Bytes, the SPI send only 4 Bytes and nothing else happens. Why is the TX DMA not writing to the SPI TX after a new DMAE0 trigger has occured?
Do i have to reconfigure the DMA TX again?
Hi Amit,
thanks that was it. But this configuration sends really 512 Bytes to read to the ADC. I only need 4 so i change this:
// Setup the TX transfer characteristics & buffers 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, data_array,(void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B0_BASE), 1); DMA_setChannelControl (DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_1); DMA_setChannelTransfer(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,UDMA_MODE_BASIC, data_array,(void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B0_BASE),3);
Now the problem is that everytime the DMAE0 gets trigger 4 Bytes are send by SPI TX and i have to reconfigure DMA again. So i implemented an interrupt like this to reconfigure DMA every time TX is done:
void DMA_INT2_IRQHandler(void) { ADS131A02_CS_Enable(); DMA_clearInterruptFlag(INT_DMA_INT2); // Setup the TX transfer characteristics & buffers 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, data_array,(void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B0_BASE), 1); 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, data_array,(void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B0_BASE),3); DMA_enableChannel(0); DMA_enableChannel(6); }
So is there a way to avoid this or is this the only way?
**Attention** This is a public forum