I wish to configure one of the ADCs to read several values, then trigger the uDMA to store those values in memory.
After reading the datasheet on triggering uDMA transfers, it seemed that all I needed to do was to enable the ADC1 uDMA channel with some basic configurations to get the uDMA to trigger from the interrupt flags generated by an ADC sequence.
I have had success with getting software initiated requests to work, as well as UART requests triggered by an empty TxBuffer.
If I set up the uDMA and ADC as shown below, transfers occur as desired when initiated by a software request, but do not automatically get triggered by the ADC.
I should also mention that the ADC seems to be working as desired: when
ADCSequenceDataGet(ADC1_BASE, 0, adc1value);
is uncommented, the function
Print_ADC1_indefinitely(void)
prints the expected values.
Here is the most relevant code:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//*****************************************************************************
//
// Initialize ADC1
//
//*****************************************************************************
void
Initialize_ADC1(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
ADCHardwareOversampleConfigure(ADC1_BASE, 4);
GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4);
ADCSequenceConfigure(ADC1_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
//ADCIntEnable(ADC1_BASE, 0);
ADCSequenceStepConfigure(ADC1_BASE, 0, 0, ADC_CTL_CH10);
ADCSequenceStepConfigure(ADC1_BASE, 0, 1, ADC_CTL_CH10);
ADCSequenceStepConfigure(ADC1_BASE, 0, 2, ADC_CTL_CH10);
ADCSequenceStepConfigure(ADC1_BASE, 0, 3, ADC_CTL_CH10);
ADCSequenceStepConfigure(ADC1_BASE, 0, 4, ADC_CTL_CH10);
ADCSequenceStepConfigure(ADC1_BASE, 0, 5, ADC_CTL_CH10);
ADCSequenceStepConfigure(ADC1_BASE, 0, 6, ADC_CTL_CH10);
ADCSequenceStepConfigure(ADC1_BASE, 0, 7, ADC_CTL_CH10 | ADC_CTL_IE | ADC_CTL_END);
ADCSequenceEnable(ADC1_BASE, 0);
ADCIntClear(ADC1_BASE, 0);
}
//*****************************************************************************
//
// Initialize ADC1 for DMA operation
//
//*****************************************************************************
void
Initialize_ADC1_DMA(void)
{
int i;
for (i=0;i<8;i++){
DMA_SrcBuf[i] = i+50;
}
//
// Configure ADC1 channel
//
ROM_uDMAChannelControlSet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT,
UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 |
UDMA_ARB_8);
//
// Pull values from a visible source buffer
//
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, (void *) DMA_SrcBuf,
(void *) adc1value,
8);
//
// TODO: Pull values from SSFIFO0 instead
//
/*
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, (void *)(ADC1_BASE + ADC_O_SSFIFO0),
(void *) adc1value,
8);
*/
//
// Enable ADC1 channel, and perform 1 request just to prove the channel can transfer correctly
//
ROM_uDMAChannelEnable(UDMA_CHANNEL_ADC1);
ROM_uDMAChannelRequest(UDMA_CHANNEL_ADC1);
}
//*****************************************************************************
//
// Triggers ADC1, waits til it's ready, prints it. repeat.
//
//*****************************************************************************
void
Print_ADC1_indefinitely(void)
{
while(1) {
ADCProcessorTrigger(ADC1_BASE, 0);
while(!ADCIntStatus(ADC1_BASE, 0, false)) { }
//ADCSequenceDataGet(ADC1_BASE, 0, adc1value);
ADCIntClear(ADC1_BASE, 0);
UARTprintf("%4d\n", adc1value[0]);
UARTprintf("%4d\n", adc1value[1]);
UARTprintf("%4d\n", adc1value[2]);
UARTprintf("%4d\n", adc1value[3]);
UARTprintf("%4d\n", adc1value[4]);
UARTprintf("%4d\n", adc1value[5]);
UARTprintf("%4d\n", adc1value[6]);
UARTprintf("%4d\n", adc1value[7]);
}
}