This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C123GH6PM: when configured ADC with DMA channel gives output 0 but rest of channels working fine

Part Number: TM4C123GH6PM

O'm using tm4c123gh6pm controller to measure some adc inputs, i configured the adc with dma operation for all eight channels. the problem i face is i get the data of all the channels except channel 0, the value in this is always 0. When i run the code without configuring dma it works perfectly fine. here is snippet of my code.

initialize adc

{

	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
	SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_ADC0);
	ADCHardwareOversampleConfigure(ADC0_BASE, 64);
	ADCClockConfigSet(ADC0_BASE,ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1);
	ROM_ADCSequenceDisable(ADC0_BASE, 0); //DISABLE SEQUENCE 3
	ADCSequenceConfigure(ADC0_BASE, 0 /*SS0*/, ADC_TRIGGER_ALWAYS, 0 /*priority*/);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); //ENABLE GPOI E
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); //ENABLE GPOI E
	ROM_GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_2); //ENABLE GPIO E AS ADC PIN 0,1,2,3
	//PE2-->CH1,PE3-->CH0,PE1-->CH2,PE0-->CH3
	ROM_GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_2); //ENABLE GPIO D AS ADC PIN 0,1,2,3
	//PD3-->CH4,PD2-->CH5,PD1-->CH6,PD0-->CH7
	ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 0, ADC_CTL_CH0);
	ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 1, ADC_CTL_CH1);
	ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 2, ADC_CTL_CH2);
	ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 3, ADC_CTL_CH3);
	ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 4, ADC_CTL_CH4);
	ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 5, ADC_CTL_CH5);
	ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 6, ADC_CTL_CH6);
	ADCSequenceStepConfigure(ADC0_BASE, 0 /*SS0*/, 7, ADC_CTL_CH7 | ADC_CTL_END | ADC_CTL_IE);
	ADC0_CTL_R |= 0x00000040;
	ADCSequenceEnable(ADC0_BASE, 0);
	ADCSequenceDMAEnable(ADC0_BASE, 0);
	uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0,
			UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
			UDMA_ATTR_HIGH_PRIORITY |
			UDMA_ATTR_REQMASK);
	uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
			UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 |
			UDMA_ARB_8);
	uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
			UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 |
			UDMA_ARB_8);
	uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
			UDMA_MODE_PINGPONG,
			(void *)(ADC0_BASE + ADC_O_SSFIFO0),
			g_ui8RxBufA, MEM_BUFFER_SIZE);
	uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
			UDMA_MODE_PINGPONG,
			(void *)(ADC0_BASE + ADC_O_SSFIFO0),
			g_ui8RxBufB, MEM_BUFFER_SIZE);
	uDMAChannelEnable(UDMA_CHANNEL_ADC0);
	ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS0);
	IntEnable(INT_ADC0SS0);

}

and in adc sequencer handler

{

	uint32_t ui32Status;
	uint32_t ui32Mode;

	ROM_ADCIntClear(ADC0_BASE, 0);
	ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS0);
	ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT);
	if(ui32Mode == UDMA_MODE_STOP)
	{
		uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
				UDMA_MODE_PINGPONG,
				(void *)(ADC0_BASE + ADC_O_SSFIFO0),
				g_ui8RxBufA, MEM_BUFFER_SIZE);
		uDMAChannelEnable(UDMA_CHANNEL_ADC0);
	}

	ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT);
	if(ui32Mode == UDMA_MODE_STOP)
	{
		uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
				UDMA_MODE_PINGPONG,
				(void *)(ADC0_BASE + ADC_O_SSFIFO0),
				g_ui8RxBufB, MEM_BUFFER_SIZE);
		uDMAChannelEnable(UDMA_CHANNEL_ADC0);
	}

}

  • Hello Lakshay,

    I'm not seeing anything glaringly obvious right now so have a few suggestions to try out:

    1) This API is used in the ADC uDMA example put together by one of our engineers recently:

        //
        // Set the USEBURST attribute for the uDMA ADC0 channel.  This will force
        // the controller to always use a burst when transferring data from the
        // TX buffer to the UART.  This is somewhat more efficient bus usage than
        // the default which allows single or burst transfers.
        //
        uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC0, UDMA_ATTR_USEBURST);
    

    2) In that example, the DMA is configured before the ADC, can you try and swap the order of configuration?

    3) For uDMAChannelControlSet why use 32 bit wide? ADC result is only 12 bits. I would suggest to use UDMA_SIZE_16 and UDMA_DST_INC_16.

    Also just to be sure, have you verified the input signal at PE3?

    Lastly, have you tried only use AIN0 and see if that works on it's own with DMA before adding in the other channel?