cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 HAL 1.1.0 ADC Migration Problem

keaven
Associate II
Posted on December 06, 2016 at 20:55

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!

5 REPLIES 5
Imen.D
ST Employee
Posted on December 07, 2016 at 15:13

Dear

Pineau.Keaven

‌,

Could you please try thelatestversion of

http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-embedded-software/stm32cubef7.html

firmware package

which 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-

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Walid FTITI_O
Senior II
Posted on December 07, 2016 at 16:57

Hi, 

You should take into account the change/updates

implemented

in each new driver version by

checking

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.

    • You should use the last version of STM32CubeF7 which integrates the last version of driver 1.1.2 . It may fix the issue
    • If a response is useful, you would mention that by clicking the correct botton. Thank you for the contribution

-Walid F-

Posted on December 07, 2016 at 16:59

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

Posted on December 07, 2016 at 17:06

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

Posted on March 26, 2018 at 20:21

Dear Walid,

this bug is still valid as of today with the latest version of Cube HAL.

Scenario:

  1. start DMA transfer with HAL_ADC_Start_DMA(&hadc3, (uint32_t*)CV_Buffer, 8);
  2. wait for transfer to finish and get callback in HAL_ADC_ConvCpltCallback(). The data is valid, fine.

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