cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 ADC DMA Transfer Error

simon239955
Associate II
Posted on February 06, 2016 at 18:06

I am using STM32F407VGT-6 chips.

I use the DMA2 Stream0 with the ADC1 to read analog values. On two of my Boards, the code is working fine and I am not having any problems. On a third Board I programmed today, the DMA does not work (The Transfer Error Interrupt Flag TEIF is set). I then placed the function in which I do my ''ADC_Setup()'' (Look at the code below) at another place in the code on a working Board and it also stopped working. So depending on which functions I call before and after the ADC_Setup() the DMA works fine or does not, although I do not change anything in the ADC_Setup() at all. I tried clearing the DMA EN bit before doing the DMA configuration and clearing the flags before starting the DMA. This did not change anything. It seems that the only thing that influences if the DMA is running or not, is where I place the ADC_Setup() function in the code. And unfortunately on one Board I do not find a place where it works at all. Can someone help me understand this problem?

void ADC_Setup(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_initStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_AHB1PeriphClockCmd((RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
RCC_AHB1Periph_GPIOC), ENABLE);
// DMA2 Stream0 channel0 configuration
DMA_Cmd(DMA2_Stream0, DISABLE);
while (DMA2_Stream0->CR & DMA_SxCR_EN);
DMA_InitStructure.DMA_Channel = DMA_Channel_0; //DMA channel 0..7
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; //ADC1 Address
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC_Buffer; //uint16_t ADC_Buffer
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; // Data from Peripheral to memory
DMA_InitStructure.DMA_BufferSize = NBR_OF_CHANNELS; //Number of Data
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //increment peripheral pointer
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //increment address pointer
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //size of data .. 16bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //size of data
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //start from beginning when end is reached
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //high - only adc exists
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //FIFO or direct
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; //FIFO specific
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //specifies the amount of data to be transferred in a single non interruptable transaction
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //specifies the amount of data to be transferred in a single non interruptable transaction
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
NVIC_Init(&NVIC_InitStructure);
DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_FEIF2|DMA_FLAG_DMEIF2|DMA_FLAG_TEIF2|DMA_FLAG_HTIF2|DMA_FLAG_TCIF2);
DMA_Cmd(DMA2_Stream0, ENABLE);
// Configure ADC1 Pins
GPIO_initStruct.GPIO_Mode = GPIO_Mode_AN;
GPIO_initStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_initStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOA, &GPIO_initStruct);
GPIO_initStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
GPIO_Init(GPIOC, &GPIO_initStruct);
// ADC1 Init
ADC_DeInit();
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; //single, dual, triple
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div6; //max 14MHz aus APB2? (Diller)
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; //Delay between to ADC-cycles
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //Enable: Multiplexing
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //Start next Conv. immediately
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //this case: Software trigger
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = NBR_OF_CHANNELS; //number of channels in regular group
ADC_Init(ADC1, &ADC_InitStructure);
// ADC1 regular channel config
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 5, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 6, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 7, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 8, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 9, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 10, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 11, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 12, ADC_SampleTime_480Cycles);
// Enable DMA request after last transfer (Single-ADC mode)
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
// Enable ADC1 DMA
ADC_DMACmd(ADC1, ENABLE);
// Enable ADC1
ADC_Cmd(ADC1, ENABLE);
ADC_SoftwareStartConv(ADC1);
}

10 REPLIES 10
Posted on July 01, 2016 at 01:05

DMA2_Stream0.M0AR = 0x10000000

You can't DMA in/out of CCM RAM

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..