STM32F746 low-layer driver issue: ADC DMA TIM2 trigger
Dear Community,
I am trying to migrate some code of a STM32F4 series µC relying on the StandardPeripheralLib to STM32F7 “low layer� driver concept. Unfortunately the LL-Driver concept is not that identical to StanPeriphLib as I've expected – so with a little help from UM1905 I’ve guessed how to initialize the stuff. With some periphery it worked well however the subsequent code to initialize ADC1 and DMA2 in such a kind that each conversion of ADC1 is triggered by TIM2 and subsequently transferred via DMA2 to a buffer is not working while the original code based on StandardPeripheralLib worked well on STM32F4. I tried so far to test the example
“ADC_SingleConversion_TriggerTimer_DMA� (STM32F767Zi)
which is unfortunatelly also not working. Then I've tried to compare the Register entries of DMA2 and ADC1 obtained from a working STM32F4 with that of the non working STM32F7 with the result that some entries are identical and others are not. I would be glad if someone could give a hint how to solve the problem.[Code]
void ADC1_Init() {LL_DMA_InitTypeDef DMA_InitStructure;
LL_GPIO_InitTypeDef GPIO_InitStructure;// LL_NVIC_InitTypeDef NVIC_InitStructure1; LL_ADC_InitTypeDef ADC_InitStructure; LL_ADC_REG_InitTypeDef ADC_REG_InitStructure; LL_ADC_CommonInitTypeDef ADC_CommonInitStructure;// Enable ADCx, DMA and GPIO clocks ****************************************
// RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2|RCC_AHB1Periph_GPIOA, ENABLE); Enable GPIO Clock LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2); // RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1)// DMA2 Stream0 channel0 configuration **************************************
//DMA_DeInit(DMA2_Stream1); DMA_InitStructure.Channel = LL_DMA_CHANNEL_0; DMA_InitStructure.MemoryOrM2MDstAddress = (uint32_t)&ADC1_Buffer; // DMA_Memory0BaseAddr = DMA_InitStructure.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_HALFWORD; // LL_DMA_MemoryDataSize_HalfWord; //DMA_MemoryDataSize = DMA_InitStructure.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; //DMA_InitStructure.DMA_BufferSize = BLOCK_SIZE; DMA_InitStructure.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; // DMA_PeripheralInc =DMA_PeripheralInc_Disable; DMA_InitStructure.PeriphOrM2MSrcAddress = LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA); DMA_InitStructure.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_HALFWORD ; DMA_InitStructure.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;// LL_DMA_DIR_PeripheralToMemory; DMA_InitStructure.Mode = LL_DMA_MODE_NORMAL;//DMA_Mode_Normal ; DMA_InitStructure.Priority = LL_DMA_PRIORITY_HIGH; // Priority_High; DMA_InitStructure.FIFOMode = LL_DMA_FIFOMODE_DISABLE; // DMA_FIFOMode_Disable; DMA_InitStructure.FIFOThreshold = LL_DMA_FIFOTHRESHOLD_1_2; // FIFO threshold half full configuration // DMA_FIFOThreshold_HalfFull; DMA_InitStructure.MemBurst = LL_DMA_MBURST_SINGLE; // DMA_MemoryBurst_Single; DMA_InitStructure.PeriphBurst = LL_DMA_MBURST_SINGLE; // DMA_PeripheralBurst_Single; DMA_InitStructure.NbData = BLOCK_SIZE; LL_DMA_Init(DMA2, LL_DMA_STREAM_0, &DMA_InitStructure); LL_DMA_EnableStream(LL_DMA_STREAM_0, ENABLE); // Configure ADC1 pin as analog input *********************** GPIO_InitStructure.Mode = LL_GPIO_MODE_ANALOG; GPIO_InitStructure.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStructure.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; GPIO_InitStructure.Pull = LL_GPIO_PULL_NO; GPIO_InitStructure.Pin = LL_GPIO_PIN_2; if(LL_GPIO_Init(GPIOD, &GPIO_InitStructure) != SUCCESS) while(1); // stuck here until the cows come home //DMA NVIR*************************************************************// NVIC_InitStructure1.NVIC_IRQChannel = DMA2_Stream0_IRQn;// NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = ADC1_prio ;// NVIC_InitStructure1.NVIC_IRQChannelSubPriority = ADC1_subPrio;// NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;// NVIC_Init(&NVIC_InitStructure1); NVIC_SetPriority(DMA2_Stream0_IRQn, ADC1_prio); // DMA IRQ lower priority than ADC IRQ NVIC_EnableIRQ(DMA2_Stream0_IRQn);//DMA_ITConfig(DMA2_Stream0, DMA_IT_TC , ENABLE);
LL_DMA_EnableIT_TC(DMA2,LL_DMA_CHANNEL_0); //DMA_Cmd(DMA2_Stream0, ENABLE); LL_DMA_EnableStream(DMA2,LL_DMA_STREAM_0); // ADC Common Init ********************************************************** ADC_CommonInitStructure.Multimode = LL_ADC_MULTI_INDEPENDENT; // LL_ADC_MODE_INDEPENDENT; // ADC_Mode_Independent; ADC_CommonInitStructure.CommonClock = LL_ADC_CLOCK_SYNC_PCLK_DIV2; // ADC_Prescaler_Div2; ADC_CommonInitStructure.MultiDMATransfer = LL_ADC_MULTI_REG_DMA_EACH_ADC; // each ADC uses its own channel - consider this as disabled ADC_DMAAccessMode_Disabled ADC_CommonInitStructure.MultiTwoSamplingDelay = LL_ADC_MULTI_TWOSMP_DELAY_5CYCLES;LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStructure);
// ADC1 Init ****************************************************************
ADC_InitStructure.Resolution = LL_ADC_RESOLUTION_12B; // ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.SequencersScanMode = DISABLE; // just on channel -> otherwise if more than one channel shall be multiplexed this needs to be enabledADC_InitStructure.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
LL_ADC_Init(ADC1, &ADC_InitStructure); ADC_REG_InitStructure.ContinuousMode = DISABLE; ADC_REG_InitStructure.DMATransfer = LL_ADC_REG_DMA_TRANSFER_LIMITED; ADC_REG_InitStructure.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE ; ADC_REG_InitStructure.SequencerLength = LL_ADC_INJ_SEQ_SCAN_DISABLE ; ADC_REG_InitStructure.TriggerSource = LL_ADC_REG_TRIG_EXT_TIM2_CH2; LL_ADC_REG_Init(ADC1, &ADC_REG_InitStructure); // Note:On this STM32 (STM32F746) serie, setting of external trigger edge is performed using function LL_ADC_REG_StartConversionExtTrig(ADC1, LL_ADC_REG_TRIG_EXT_TIM2_CH2);// ADC1 regular channel7 configuration **************************************
//ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_3Cycles); //channel2 == PA2 !
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_2, LL_ADC_SAMPLINGTIME_3CYCLES); // Enable DMA request after last transfer (Single-ADC mode) //ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); LL_DMA_EnableIT_TC(DMA2,LL_DMA_CHANNEL_0);// Enable ADC3 DMA
//ADC_DMACmd(ADC1, ENABLE); LL_DMA_EnableStream(DMA2,LL_DMA_STREAM_0); //ADC_Cmd(ADC1, ENABLE); LL_ADC_Enable(ADC1); //ADC_SoftwareStartConv(ADC1); LL_ADC_REG_StartConversionSWStart(ADC1);}
[~Code]
