2016-12-06 11:55 AM
Hello,
we have a project using all the three ADCs of the F7. It runs without any problem on Keil package 2.5.0 which includes HAL 1.0.4. Now, I want to upgrade to version STM32F7 HAL 1.1.0 but I am having problem with ADC3 dma acquisition.
The value isn't good anymore because I am getting this errorHAL_DMA_ERROR_NO_XFER.
What I need to change to get it work?
Here is my initialization code
void InitADCs (void)
{
ADC_ChannelConfTypeDef ChannelConfig;
//ADC3
hADC3.Instance = ADC3;
hADC3.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
hADC3.Init.Resolution = ADC_RESOLUTION12b;
hADC3.Init.ScanConvMode = ENABLE;
hADC3.Init.ContinuousConvMode = DISABLE;
hADC3.Init.DiscontinuousConvMode = DISABLE;
hADC3.Init.NbrOfDiscConversion = 0;
hADC3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hADC3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hADC3.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hADC3.Init.NbrOfConversion = 6;
hADC3.Init.DMAContinuousRequests = ENABLE;
hADC3.Init.EOCSelection = DISABLE;
HAL_ADC_Init(&hADC3);
//Vpeak
ChannelConfig.Channel = ADC_CHANNEL_4;
ChannelConfig.Rank = 1;
ChannelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
ChannelConfig.Offset = 0;
HAL_ADC_ConfigChannel(&hADC3, &ChannelConfig);
//Vdark
ChannelConfig.Channel = ADC_CHANNEL_5;
ChannelConfig.Rank = 2;
ChannelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
ChannelConfig.Offset = 0;
HAL_ADC_ConfigChannel(&hADC3, &ChannelConfig);
//ILamp
ChannelConfig.Channel = ADC_CHANNEL_6;
ChannelConfig.Rank = 3;
ChannelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
ChannelConfig.Offset = 0;
HAL_ADC_ConfigChannel(&hADC3, &ChannelConfig);
//Vmano
ChannelConfig.Channel = ADC_CHANNEL_7;
ChannelConfig.Rank = 4;
ChannelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
ChannelConfig.Offset = 0;
HAL_ADC_ConfigChannel(&hADC3, &ChannelConfig);
//Vsupply
ChannelConfig.Channel = ADC_CHANNEL_8;
ChannelConfig.Rank = 5;
ChannelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
ChannelConfig.Offset = 0;
HAL_ADC_ConfigChannel(&hADC3, &ChannelConfig);
//Temp
ChannelConfig.Channel = ADC_CHANNEL_15;
ChannelConfig.Rank = 6;
ChannelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
ChannelConfig.Offset = 0;
HAL_ADC_ConfigChannel(&hADC3, &ChannelConfig);
return;
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStructure;
//Diagnostics
if(hadc->Instance == ADC3)
{
//##-1- Enable peripherals and GPIO Clocks #################################
__GPIOF_CLK_ENABLE();
__ADC3_CLK_ENABLE();
//##-2- Configure peripheral GPIO ##########################################
//Configure PF6 as analog input for Vpeak Channel4
GPIO_InitStructure.Pin = GPIO_PIN_6;
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Pull = GPIO_NOPULL ;
//GPIO_InitStructure.Alternate = GPIO_AF0_RTC_50Hz; //DONT CARE
HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
//Configure PF7 as analog input for Vdark Channel5
GPIO_InitStructure.Pin = GPIO_PIN_7;
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Pull = GPIO_NOPULL ;
//GPIO_InitStructure.Alternate = GPIO_AF0_RTC_50Hz; //DONT CARE
HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
//Configure PF8 as analog input for ILamp Channel6
GPIO_InitStructure.Pin = GPIO_PIN_8;
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Pull = GPIO_NOPULL ;
//GPIO_InitStructure.Alternate = GPIO_AF0_RTC_50Hz; //DONT CARE
HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
//Configure PF9 as analog input for Vmano Channel7
GPIO_InitStructure.Pin = GPIO_PIN_9;
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Pull = GPIO_NOPULL ;
//GPIO_InitStructure.Alternate = GPIO_AF0_RTC_50Hz; //DONT CARE
HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
//Configure PF10 as analog input for Vsupply Channel8
GPIO_InitStructure.Pin = GPIO_PIN_10;
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Pull = GPIO_NOPULL ;
//GPIO_InitStructure.Alternate = GPIO_AF0_RTC_50Hz; //DONT CARE
HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
//Configure PF5 as analog input for Temp Channel15
GPIO_InitStructure.Pin = GPIO_PIN_5;
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Pull = GPIO_NOPULL ;
//GPIO_InitStructure.Alternate = GPIO_AF0_RTC_50Hz; //DONT CARE
HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
//##-3- Configure the DMA streams ##########################################
//DMA2 Stream 0 Channel 0 ADC1 fixed length transfer of 2140
hDMA2_ADC3.Instance = DMA2_Stream1;
hDMA2_ADC3.Init.Channel = DMA_CHANNEL_2;
hDMA2_ADC3.Init.Direction = DMA_PERIPH_TO_MEMORY;
hDMA2_ADC3.Init.PeriphInc = DMA_PINC_DISABLE;
hDMA2_ADC3.Init.MemInc = DMA_MINC_ENABLE;
hDMA2_ADC3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hDMA2_ADC3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hDMA2_ADC3.Init.Mode = DMA_NORMAL;
hDMA2_ADC3.Init.Priority = DMA_PRIORITY_HIGH;
hDMA2_ADC3.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hDMA2_ADC3.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
hDMA2_ADC3.Init.MemBurst = DMA_MBURST_SINGLE;
hDMA2_ADC3.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_Init(&hDMA2_ADC3);
// Associate the initialized DMA handle to the the ADC handle
__HAL_LINKDMA(hadc, DMA_Handle, hDMA2_ADC3);
//##-4- Configure the NVIC for DMA #########################################
HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0x0F, 0x0F);
HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
}
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
Thank you!
2016-12-07 06:13 AM
Dear
Pineau.Keaven
,Could you please try thelatestversion of
firmware packagewhich includes
STM32F7 HAL version 1.1.2 andcontains updates to fix defects and enhancements implementation.
Then confirm if the problem here still existing with this version.
Best Regards
-Imen-
2016-12-07 07:57 AM
Hi,
You should take into account the change/updates
implemented
in each new driver version bychecking
the release note of the drivers. It is mention , for V1.1.0 :HAL DMA update
Add new APIs HAL_DMA_RegisterCallback() and HAL_DMA_UnRegisterCallback to register/unregister the different callbacks identified by the enum typedef HAL_DMA_CallbackIDTypeDef
Add new API HAL_DMA_Abort_IT() to abort DMA transfer under interrupt context
The new registered Abort callback is called when DMA transfer abortion is completed
Add the check of compatibility between FIFO threshold level and size of the memory burst in the HAL_DMA_Init() API
Add new Error Codes: HAL_DMA_ERROR_PARAM, HAL_DMA_ERROR_NO_XFER and HAL_DMA_ERROR_NOT_SUPPORTED
Remove all DMA states related to MEM0/MEM1 in HAL_DMA_StateTypeDef
You would check where the code is stucked and whey you get
HAL_DMA_ERROR_NO_XFER with new version ( where the update is added ) to figure out what you should do or avoid to do.
If a response is useful, you would mention that by clicking the correct botton. Thank you for the contribution
-Walid F-
2016-12-07 08:59 AM
Thank you Imen,
I found out that if we call the function HAL_ADC_Stop_DMA() and the transfer is already stopped it return an error which cause my first value is not good.
I have removed the call since the transfer will be always finished in my case. I might only reset the DMA pointer to make sure I am always at the start of the buffer when restarting another acquisition.
My code isn't setup to use the generated code from STM32CubeF7 sry .
Keaven
2016-12-07 09:06 AM
Yes I have follow those guidelines. Actually I have the latest HAL 1.1.2 now and it does the same problem. As mentioned above , the HAL_ADC_Stop_DMA() return an error if the transfer is already done. I don't understand to point to get this error but I will not call it in my case.
Thank you for response
2018-03-26 01:21 PM
Dear Walid,
this bug is still valid as of today with the latest version of Cube HAL.
Scenario:
Now, there are two options:
i. Call HAL_ADC_Stop_DMA(&hadc3); to prepare the ADC and HAL State machine for the next call of
HAL_ADC_Start_DMA.
This causes an HAL_Error and HAL_ADC_ErrorCallback() to be called, as no transfer is running and
HAL_ADC_Stop_DMA() faces a HAL_DMA_ERROR_NO_XFER after trying to abort a finished stream with HAL_DMA_Abort().
ii. Do not call anything, which also does not clear the DMA bit in CR2. This causes all following calls to
HAL_ADC_Start_DMA() to stall forever as HAL thinks the ADC is busy.
___
Could you please advise how you propose to fix this issue and/or address it in the next version of HAL?
Best,
Max