I am using TM4C1294 connected launchpad eval board. I'd like to sample an ADC at 1Msps and DMA ping pong 1024 samples into a buffer. I am testing this out using the Temp sensor.
Here is my code. It keeps interrupting the ADCseq0Handler but not with
ROM_uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT) == UDMA_MODE_STOP or
ROM_uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT) == UDMA_MODE_STOP
#include <stdbool.h>
#include <stdint.h>
#include <string.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 "inc/hw_emac.h"
#include "inc/hw_uart.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/adc.h"
#include "driverlib/udma.h"
#include "driverlib/emac.h"
#include "utils/uartstdio.h"
//*****************************************************************************
//
// The control table used by the uDMA controller. This table must be aligned
// to a 1024 byte boundary.
//
//*****************************************************************************
#if defined(ewarm)
#pragma data_alignment=1024
uint8_t pui8ControlTable[1024];
#elif defined(ccs)
#pragma DATA_ALIGN(pui8ControlTable, 1024)
uint8_t pui8ControlTable[1024];
#else
uint8_t pui8ControlTable[1024] __attribute__ ((aligned(1024)));
#endif
//DMA bus error count
uint32_t g_ui32uDMAErrCount = 0;
#define ADC_DMA_SIZE 1024
uint16_t adcbuffer_ping[ADC_DMA_SIZE];
uint16_t adcbuffer_pong[ADC_DMA_SIZE];
//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void __error__(char *pcFilename, uint32_t ui32Line)
{
while (1);
}
#endif
//*****************************************************************************
//
// Configure the UART and its pins. This must be called before UARTprintf().
//
//*****************************************************************************
void ConfigureUART(uint32_t sysclock)
{
//
// Enable the GPIO Peripheral used by the UART.
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//
// Enable UART0
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART0);
//
// Configure GPIO Pins for UART mode.
//
ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//
// Initialize the UART for console I/O.
//
UARTStdioConfig(0, 115200, sysclock);
}
void ConfigureADC(void)
{
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
SysCtlDelay(10);
ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_EIGHTH, 30);
//ADCHardwareOversampleConfigure(ADC0_BASE,64); //here you chose how many oversamples
ROM_ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_TS );
ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_TS );
ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_TS );
ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_TS );
ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_TS );
ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_TS );
ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 6, ADC_CTL_TS );
ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 7, ADC_CTL_TS | ADC_CTL_IE |ADC_CTL_END);
ROM_ADCSequenceEnable(ADC0_BASE, 0);
//
// Enable the uDMA controller error interrupt. This interrupt will occur
// if there is a bus error during a transfer.
//
ROM_IntEnable(INT_UDMAERR);
//
// Enable the uDMA controller.
//
ROM_uDMAEnable();
//
// Point at the control table to use for channel control structures.
//
ROM_uDMAControlBaseSet(pui8ControlTable);
ROM_ADCSequenceDMAEnable(ADC0_BASE, 0);
// disable some bits
ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALTSELECT /*start with ping-pong PRI side*/ |
UDMA_ATTR_HIGH_PRIORITY /*low priority*/ | UDMA_ATTR_REQMASK /*unmask*/);
// enable some bits
ROM_uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC0, UDMA_ATTR_USEBURST /*only allow burst transfers*/);
// set dma params on PRI_ and ALT_SELECT
ROM_uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1024);
ROM_uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1024);
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), &adcbuffer_ping[0], 1024);
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), &adcbuffer_pong[0], 1024);
ROM_IntEnable(INT_ADC0SS0);
ROM_ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS0);
ROM_uDMAChannelEnable(UDMA_CHANNEL_ADC0);
}
//*****************************************************************************
//
// The interrupt handler for uDMA errors. This interrupt will occur if the
// uDMA encounters a bus error while trying to perform a transfer. This
// handler just increments a counter if an error occurs.
//
//*****************************************************************************
void uDMAErrorHandler(void)
{
uint32_t ui32Status;
//
// Check for uDMA error bit
//
ui32Status = ROM_uDMAErrorStatusGet();
//
// If there is a uDMA error, then clear the error and increment
// the error counter.
//
if(ui32Status)
{
ROM_uDMAErrorStatusClear();
g_ui32uDMAErrCount++;
}
while(1);
}
void ADCseq0Handler()
{
uint32_t ui32Status = ADCIntStatus(ADC0_BASE, 0, false);
ROM_ADCIntClear(ADC0_BASE, 0);
if (ROM_uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT) == UDMA_MODE_STOP) {
// re-set up a DMA transfer to the buffer
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), &adcbuffer_ping[0], 1024);
return;
}
if (ROM_uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT) == UDMA_MODE_STOP) {
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), &adcbuffer_pong[0], 1024);
return;
}
}
int main(void)
{
uint32_t sysclock;
do {
sysclock = SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120*1000*1000);
} while (!sysclock);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
ROM_SysCtlDelay(1);
ConfigureUART(sysclock);
ConfigureADC();
while(1)
{
UARTprintf("ADCtemp: test");
SysCtlDelay(20*1000*1000);
}
}