I've successfully integrated the sd24_b driver (24-bit sigma delta ADC) and am starting to use the DMA controller, using code from the TI-provided driver library. I've run the DMA repeated Block example as a unit test and it works. However, I can't seem to get an ADC conversion to trigger a DMA transfer. I've included a version of my code below that should compile and run with the TI library. Even when using a dummy source buffer address, I don't see any data transferred to the destination buffer, so perhaps the interrupts aren't setup correctly?
Quesitons:
1) How should I set the "source address" for the DMA? The ADC12 driver has a "GetMemoryAddress" function and that address is passed into the DMA driver. I think I should just give DMA the address of SD24's 'OFS_SD24BMEML0' output register and transfer 4 bytes at a time.
2) What's wrong with the interrupt/DMA setup such that a transfer is not being triggered?
===========================================
#define ADC24SD_BASE_ADDRESS (TUSIGN16)__MSP430_BASEADDRESS_SD24_B__
#define DMA_BASE_ADDRESS (TUSIGN16)__MSP430_BASEADDRESS_DMAX_3__
#define MIN_CYCLES_FOR_ADC_MEASUREMENT 1000u
#define TEST_BUFFER_SIZE 25u
static TUSIGN32 testDestinationBuffer[TEST_BUFFER_SIZE] = {0};
// 'Unity' unit test wrapper.
TEST(ADCSigmaDelta24Bit, ConfigureDMATrigger_TriggerASingleDMATransfer)
{
// Setup the ADC.
SD24_B_initializeParam adcInitialiseParams =
(SD24_B_initializeParam){.clockSourceSelect = SD24_B_CLOCKSOURCE_MCLK,
.clockPreDivider = SD24_B_PRECLOCKDIVIDER_1,
.clockDivider = SD24_B_CLOCKDIVIDER_1,
.referenceSelect = SD24_B_REF_INTERNAL};
SD24_B_initialize(ADC24SD_BASE_ADDRESS, &adcInitialiseParams);
const TUSIGN8 TEST_CONVERTER = SD24_B_CONVERTER_1;
SD24_B_initConverterParam adcInitConverterParams =
(SD24_B_initConverterParam){.converter = TEST_CONVERTER,
.alignment = SD24_B_ALIGN_RIGHT,
.startSelect = SD24_B_CONVERSION_SELECT_SD24SC,
.conversionMode = SD24_B_SINGLE_MODE};
InitConverter_ADCSigmaDelta24Bit(ADC24SD_BASE_ADDRESS, &adcInitConverterParams);
SD24_B_configureDMATrigger(ADC24SD_BASE_ADDRESS, SD24_B_DMA_TRIGGER_IFG1);
// Do NOT enable interrupts or else only the ISR will see the interrupt flag, not the DMA.
DisableInterrupt_ADCSigmaDelta24Bit(ADC24SD_BASE_ADDRESS, TEST_CONVERTER, SD24_B_CONVERTER_INTERRUPT);
ClearInterrupt_ADCSigmaDelta24Bit(ADC24SD_BASE_ADDRESS, TEST_CONVERTER, SD24_B_CONVERTER_INTERRUPT);
// Setup the DMA.
const TUSIGN8 TEST_DMA_CHANNEL = DMA_CHANNEL_0; // doesn't matter which channel.
const TUSIGN8 TEST_TRANSFER_SIZE = sizeof(TUSIGN32) / sizeof(TUSIGN);
DMA_initializeParam dmaInitialiseParams =
(DMA_initializeParam){.channelSelect = TEST_DMA_CHANNEL,
.transferModeSelect = DMA_TRANSFER_BLOCK,
.transferSize = TEST_TRANSFER_SIZE,
.triggerSourceSelect = DMA_TRIGGER_SOURCE_SD24IFG,
.transferUnitSelect = DMA_SIZE_SRCWORD_DSTWORD,
.triggerTypeSelect = DMA_TRIGGER_RISINGEDGE};
DMA_initialize(&dmaInitialiseParams);
// Calculate address to ADC24SD low word
TUSIGN16 adc24SDAddress = ADC24SD_BASE_ADDRESS + (TUSIGN16)(OFS_SD24BMEML0 + (TEST_CONVERTER << 2u));
SetSourceAddress_DMA(TEST_DMA_CHANNEL, (TUSIGN32)adc24SDAddress, DMA_DIRECTION_UNCHANGED);
// TUSIGN16 testSrcBuffer[TEST_BUFFER_SIZE] = {0xAAAA, 0x5555, 0xDDDD, 0x2222, 0x1111, 0xCCCC};
// SetSourceAddress_DMA(TEST_DMA_CHANNEL, (TUSIGN32)testSrcBuffer, DMA_DIRECTION_UNCHANGED);
SetDestinationAddress_DMA(TEST_DMA_CHANNEL, (TUSIGN32)testDestinationBuffer, DMA_DIRECTION_INCREMENT);
ClearInterrupt_DMA(TEST_DMA_CHANNEL);
EnableInterrupt_DMA(TEST_DMA_CHANNEL);
EnableTransfers_DMA(TEST_DMA_CHANNEL);
// Start the ADC conversion, which will trigger the DMA transfer once it finishes.
SD24_B_startConverterConversion(ADC24SD_BASE_ADDRESS, TEST_CONVERTER);
__delay_cycles(MIN_CYCLES_FOR_ADC_MEASUREMENT);
// Verify that the single ADC result was automatically transferred to the buffer by the DMA.
TUSIGN32 result = SD24_B_getResults(ADC24SD_BASE_ADDRESS, TEST_CONVERTER);
TEST_ASSERT_EQUAL(testDestinationBuffer[0], result);
}
=============================================================