What I am trying to do is sample with the ADC at 1 MSPS in 8 of the analog channels, while oversampling them. After sampling the eight analog pin of the sequence I would like to create an interrupt and use the uDMA to transfer the values to a global variable. I pieced together a code from some examples and would like to ask several questions. If I am trying to use uDMAChannelTransferSet to point to the address where the values are to be stored ( the global variable) what address this would be? Also what would be the correct size of my ADC ui32TransferSize. Finally, am I missing some important initialization?
Thank you very much,
Michelle
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_adc.h"
#include "inc/hw_types.h"
#include "inc/hw_udma.h""
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/adc.h"
#include "driverlib/udma.h"
#define TARGET_IS_BLIZZARD_RB1
#include "driverlib/rom.h"
uint32_t udmaCtrlTable[1024/sizeof(uint32_t)]__attribute__((aligned(1024)));
int main(void)
{
ROM_SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
SysCtlDelay(10);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);
GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_0);
GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_1);
GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_2);
GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_3);
init_ADC();
while(1)
{
}
}
void init_ADC()
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
SysCtlDelay(10);
ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1);
// ADCClockConfigSet(uint32_t ui32Base, uint32_t ui32Config, uint32_t ui32ClockDiv)
ADCHardwareOversampleConfigure(ADC0_BASE, 4);
SysCtlDelay(10); // Time for the clock configuration to set
ADCSequenceDisable(ADC0_BASE,0);
// With sequence disabled, it is now safe to load the new configuration parameters
ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_ALWAYS, 0);
// ADCSequenceConfigure(uint32_t ui32Base, uint32_t ui32SequenceNum, uint32_t ui32Trigger,
// uint32_t ui32Priority)
ADCSequenceStepConfigure(ADC0_BASE,0,0,ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE,0,1,ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC0_BASE,0,2,ADC_CTL_CH2);
ADCSequenceStepConfigure(ADC0_BASE,0,3,ADC_CTL_CH3);
ADCSequenceStepConfigure(ADC0_BASE,0,4,ADC_CTL_CH4);
ADCSequenceStepConfigure(ADC0_BASE,0,5,ADC_CTL_CH5);
ADCSequenceStepConfigure(ADC0_BASE,0,6,ADC_CTL_CH6);
ADCSequenceStepConfigure(ADC0_BASE,0,7,ADC_CTL_CH7 | ADC_CTL_END | ADC_CTL_IE);
// ADCSequenceStepConfigure(uint32_t ui32Base, uint32_t ui32SequenceNum, uint32_t ui32Step, uint32_t ui32Config)
ADCSequenceEnable(ADC0_BASE,0); //Once configuration is set, re-enable the sequencer
uDMAEnable(); // Enables uDMA
uDMAControlBaseSet(udmaCtrlTable);
// Configures the base address of the channel control table. Table resides in system memory and holds control
// information for each uDMA channel. Table must be aligned on a 1024-byte boundary. Base address must be
// configured before any of the channel functions can be used
ADCSequenceDMAEnable(ADC0_BASE,0);
// Allows DMA requests to be generated based on the FIFO level of the sample sequencer (SS0)
uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
// Start with Ping-pong PRI side, low priority, unmask
uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC0, UDMA_ATTR_USEBURST);
// Only allow burst transfers
uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_128);
uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_128);
// uDMAChannelControlSet(uint32_t ui32ChannelStructIndex, uint32_t ui32Control)
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), ?, ?);
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), ?, ?);
// uDMAChannelTransferSet(uint32_t ui32ChannelStructIndex, uint32_t ui32Mode, void *pvSrcAddr, void *pvDstAddr, uint32_t ui32TransferSize)
// pvSrcAddr is the source address for the transfer in this case from hw_adc.h ADC_O_SSFIFO0 is the result of the FIFO 0 register
// pvDstAddr is the destination address for the transfer
// ui32TransferSize is the number of data items to transfer
IntEnable(INT_ADC0SS0);
ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS0); // Enables ADC interrupt source due to DMA on ADC sample sequence 0
uDMAChannelEnable(UDMA_CHANNEL_ADC0); // Enables DMA channel so it can perform transfers
}