Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: EK-TM4C1294XL
Hi,
I want to use multiple channels of ADC with DMA in ping-pong mode, as my app requires multiple analog signal monitoring, and for that case DMA is necessity, I configured ADC and DMA both but, in ISR it stuck in udmatrasferset() function. is there any issue in configuration please help,
Regards,
Sandeep Kore
below is my code
#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 "inc/hw_emac.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/adc.h"
#include "driverlib/udma.h"
#include "driverlib/emac.h"
//#define TARGET_IS_BLIZZARD_RB1
#include "driverlib/rom.h"
#define ADC_SAMPLE_BUF_SIZE (128)
uint32_t udmaCtrlTable[1024] __attribute__ ((aligned(1024)));
uint32_t ADC_OUT_1[8],ADC_OUT_2[8];
static uint32_t g_ui32RxBufACount = 0;
static uint32_t g_ui32RxBufBCount = 0;
enum BUFFER_STATUS
{
EMPTY,
FILLING,
FULL
};
uint32_t pui32ADC0Value[8];
// static enum BUFFER_STATUS pui32BufferStatus[2];
bool bufCtr=0;
static uint32_t g_ui32uDMAErrCount = 0;
void uDMAErrorHandler(void)
{
uint32_t ui32Status;
ui32Status = uDMAErrorStatusGet();
if(ui32Status)
{
uDMAErrorStatusClear();
g_ui32uDMAErrCount++;
}
}
void
UART0IntHandler(void)
{
uint32_t ui32Mode;
ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT);
if(ui32Mode == UDMA_MODE_STOP)
{
g_ui32RxBufACount++;
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0), ADC_OUT_1, 8);
}
ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_ALT_SELECT);
if(ui32Mode == UDMA_MODE_STOP)
{
g_ui32RxBufBCount++;
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0),ADC_OUT_2,8);
}
if(uDMAChannelIsEnabled(UDMA_CHANNEL_ADC0))
{
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,UDMA_MODE_BASIC,(void *)(ADC0_BASE + ADC_O_SSFIFO0), ADC_OUT_1,8);
uDMAChannelEnable(UDMA_CHANNEL_ADC0);
}
}
void ADCSeq0Handler(void)
{
//
// Clear the Interrupt Flag.
//
// ADCIntClear(ADC0_BASE, 0);
uint32_t ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0);
if( ui32Mode == 4)
{
bufCtr = 1;
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0), ADC_OUT_1, 8);
}
else if( ui32Mode == 4)
{
bufCtr = 0;
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0),ADC_OUT_2,8);
}
uDMAChannelEnable(UDMA_CHANNEL_ADC0);
uDMAChannelRequest(UDMA_CHANNEL_ADC0);
}
void InitUDMA(void)
{
uDMAEnable(); // Enables uDMA
uDMAControlBaseSet(udmaCtrlTable);
//IntEnable(INT_UDMA);
uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALL);
// 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
uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC0, UDMA_ATTR_USEBURST );
uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |UDMA_CHCTL_ARBSIZE_1);
uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_NEXT_USEBURST |UDMA_CHCTL_ARBSIZE_1);
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0), ADC_OUT_1, 8);
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0),ADC_OUT_2,8);
// uDMAChannelEnable(UDMA_CHANNEL_ADC0); // Enables DMA channel so it can perform transfers
uDMAChannelEnable(UDMA_CHANNEL_ADC0);
uDMAChannelRequest(UDMA_CHANNEL_ADC0);
//IntEnable(INT_UDMA);
//uDMAIntRegister(INT_UDMA,uDMAIntHandler);
//IntMasterEnable();
}
void InitConsole(void)
{
SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
//SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_0);
GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);
GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_0);
GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_1);
IntDisable(INT_ADC0SS0);
ADCIntDisable(ADC0_BASE, 0);
ADCSequenceDisable(ADC0_BASE, 0);
//ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS0);
ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_ALWAYS, 0);
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_CH14);
ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH15);
ADCSequenceStepConfigure(ADC0_BASE, 0, 6, ADC_CTL_CH16);
ADCSequenceStepConfigure(ADC0_BASE, 0, 7, ADC_CTL_CH17|ADC_CTL_END);
ADCHardwareOversampleConfigure(ADC0_BASE, 64);
ADCSequenceDMAEnable(ADC0_BASE, 0);
ADCSequenceEnable(ADC0_BASE, 0);
ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS0); // Enables ADC interrupt source due to DMA on ADC sample sequence 0
IntEnable(INT_ADC0SS0);
ADCIntRegister(ADC0_BASE,0,ADCSeq0Handler);
IntMasterEnable();
}
int main(void)
{
uint32_t ui32SysClock;
ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |SYSCTL_OSC_MAIN ), 25000000);
//uint32_t ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0);
InitConsole();
InitUDMA();
while(1)
{
//ADCProcessorTrigger(ADC0_BASE, 0);
//ADCIntClear(ADC0_BASE, 1);
//ADCSequenceDataGet(ADC0_BASE, 0, pui32ADC0Value);
//ADCSequenceDataGet(ADC1_BASE, 2, pui32ADC1Value);
// SysCtlDelay(ui32SysClock / 12);
//uint32_t ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0);
}
}