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.
I am trying to implement a round robin ADC scheme where 4 channels are continuously read in around robin and the values updated to an array using DMA. I have cobbled this together using examples from the MSP430ware driver library.
The round robin works as expected, with the expected values in the array when main() is permitted to terminate and the DMA is allowed to run on its own. If there are contents in main(), like a while(1) to perform some operation on this ADC data, the ADC values found in the array are always very low. 0 or near to zero where the expectation is around 1000. The values do change, so are being updated, just incorrectly.
I honestly don't understand why there are unexpected values being written to the array when the MCU is doing something; I would have an easier time understand no values or unchanging values.
Thanks in advance for any help.
#include "driverlib.h" #include <dma.h> volatile uint16_t adcDmaTarget[NUMDMAWORDS]; //***************************************************************************** // //Configure DMA // //***************************************************************************** void configDma(void) { DMA_enableRoundRobinPriority(); DMA_initParam dmaParam0 = {0}; dmaParam0.channelSelect = DMA_CHANNEL_0; dmaParam0.transferModeSelect = DMA_TRANSFER_REPEATED_SINGLE; dmaParam0.transferSize = NUMDMAWORDS; dmaParam0.triggerSourceSelect = DMA_TRIGGERSOURCE_24; dmaParam0.transferUnitSelect = DMA_SIZE_SRCWORD_DSTWORD; dmaParam0.triggerTypeSelect = DMA_TRIGGER_RISINGEDGE; DMA_init(&dmaParam0); DMA_setSrcAddress(DMA_CHANNEL_0, ADC12_A_getMemoryAddressForDMA(ADC12_A_BASE,ADC12_A_MEMORY_0), DMA_DIRECTION_UNCHANGED); DMA_setDstAddress(DMA_CHANNEL_0, (uint32_t)(uintptr_t)&adcDmaTarget, DMA_DIRECTION_INCREMENT); DMA_clearInterrupt(DMA_CHANNEL_0); DMA_enableInterrupt(DMA_CHANNEL_0); DMA_enableTransfers(DMA_CHANNEL_0);
void configAdc(void) { //Enable A/D channel inputs GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6, GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2 | GPIO_PIN3 ); //Initialize the ADC12_A Module /* * Base address of ADC12_A Module * Use internal ADC12_A bit as sample/hold signal to start conversion * USE MODOSC 5MHZ Digital Oscillator as clock source * Use default clock divider of 1 */ ADC12_A_init(ADC12_A_BASE, ADC12_A_SAMPLEHOLDSOURCE_SC, ADC12_A_CLOCKSOURCE_ACLK, ADC12_A_CLOCKDIVIDER_1); ADC12_A_enable(ADC12_A_BASE); /* * Base address of ADC12_A Module * For memory buffers 0-7 sample/hold for 256 clock cycles * For memory buffers 8-15 sample/hold for 4 clock cycles (default) * Enable Multiple Sampling */ ADC12_A_setupSamplingTimer(ADC12_A_BASE, ADC12_A_CYCLEHOLD_64_CYCLES, ADC12_A_CYCLEHOLD_64_CYCLES, ADC12_A_MULTIPLESAMPLESENABLE); //Configure Memory Buffers /* * Base address of the ADC12_A Module * Configure memory buffer 0 * Map input A0 to memory buffer 0 * Vref+ = AVcc * Vref- = AVss * Memory buffer 0 is not the end of a sequence */ ADC12_A_configureMemoryParam param0 = {0}; param0.memoryBufferControlIndex = ADC12_A_MEMORY_0; param0.inputSourceSelect = ADC12_A_INPUT_A0; param0.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC; param0.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS; param0.endOfSequence = ADC12_A_NOTENDOFSEQUENCE; ADC12_A_configureMemory(ADC12_A_BASE ,¶m0); /* * Base address of the ADC12_A Module * Configure memory buffer 1 * Map input A1 to memory buffer 1 * Vref+ = AVcc * Vref- = AVss * Memory buffer 1 is not the end of a sequence * */ ADC12_A_configureMemoryParam param1 = {0}; param1.memoryBufferControlIndex = ADC12_A_MEMORY_1; param1.inputSourceSelect = ADC12_A_INPUT_A1; param1.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC; param1.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS; param1.endOfSequence = ADC12_A_NOTENDOFSEQUENCE; ADC12_A_configureMemory(ADC12_A_BASE ,¶m1); /* * Base address of the ADC12_A Module * Configure memory buffer 2 * Map input A2 to memory buffer 2 * Vref+ = AVcc * Vref- = AVss * Memory buffer 2 is not the end of a sequence */ ADC12_A_configureMemoryParam param2 = {0}; param2.memoryBufferControlIndex = ADC12_A_MEMORY_2; param2.inputSourceSelect = ADC12_A_INPUT_A2; param2.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC; param2.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS; param2.endOfSequence = ADC12_A_NOTENDOFSEQUENCE; ADC12_A_configureMemory(ADC12_A_BASE ,¶m2); /* * Base address of the ADC12_A Module * Configure memory buffer 3 * Map input A3 to memory buffer 3 * Vr+ = AVcc * Vr- = AVss * Memory buffer 3 IS the end of a sequence */ ADC12_A_configureMemoryParam param3 = {0}; param3.memoryBufferControlIndex = ADC12_A_MEMORY_3; param3.inputSourceSelect = ADC12_A_INPUT_A3; param3.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC; param3.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS; param3.endOfSequence = ADC12_A_ENDOFSEQUENCE; ADC12_A_configureMemory(ADC12_A_BASE ,¶m3); //Using DMA transfer instead! //Enable memory buffer 3 interrupt /* ADC12_A_clearInterrupt(ADC12_A_BASE, ADC12IFG3); ADC12_A_enableInterrupt(ADC12_A_BASE, ADC12IE3); */ //Enable/Start first sampling and conversion cycle /* * Base address of ADC12_A Module * Start the conversion into memory buffer 0 * Use the repeated sequence of channels */ ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_0, ADC12_A_REPEATED_SEQOFCHANNELS); }
Hi Hardy,
Could you try to perform some operation to the array in the DMA interrupt?
Stupid mistake...
I was not incrementing the DMA source. OOPS! Changing NOCHANGE to INCREMENT fixed it up.
Thank you.
DMA_setSrcAddress(DMA_CHANNEL_0,
ADC12_A_getMemoryAddressForDMA(ADC12_A_BASE, ADC12_A_MEMORY_0),
DMA_DIRECTION_INCREMENT);
DMA_setDstAddress(DMA_CHANNEL_0,
(uint32_t)(uintptr_t)&adcDmaTarget,
DMA_DIRECTION_INCREMENT);
**Attention** This is a public forum