cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F030 ADC in DMA mode blocking other HAL functions

Piotr Rog
Associate II
Posted on February 07, 2017 at 20:27

Hi all,

I have configured ADC to work in DMA mode for 4 channels. Code was generated via Cube. After I call function HAL_ADC_Start_DMA everything works fine until I trying to call other HAL function. In this case, I lost contact with main loop of program (adc with dma still works, but I cannot debug main loop, it looks like blocked or something like that - I cannot achieve next breakpoint in the loop).

Any suggestions, what goes wrong?

Regards,

Piotr

9 REPLIES 9
T J
Lead
Posted on February 07, 2017 at 21:04

I have the same function, works very well. on the '091

initialization: ADC_ChannelsCounter = ADC_Channels; // 15 ADC channels HAL_ADC_Start_DMA (&hadc,(uint32_t *)ADC_DMABuffer,ADC_Channels);implementation:extern 'C' void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){ if(! ADC_ChannelsCounter--){ ADC_ChannelsCounter = ADC_Channels ; HAL_ADC_CompleteCycle = true; // signal foreground to process ADC values // copy 15 results away now for (int i=0;i<ADC_Channels;i++){ HAL_ADC_Channel_Buffer [i] = ADC_DMABuffer[i]; // AVEColumnSum += HAL_ADC_Channel_Buffer [Ave_ADC_ChannelCounter]; } }}�?�?�?�?�?�?�?�?�?�?�?

my ADC/DMA is set to the lowest speed and they all are updated 212 times per second.

I too have lost some ability. I can no longer single step within uV5, but both 'run to cursor' and breakpoints work.

I have a limitation of only 3 or 4 breakpoints, I have to use the function 'KILL ALL BREAKPOINTS' sometimes.

<ctrl><shift>F9

it seemed to become a problem whilst the CANbus code was being developed. (no dmas in canbus..)

but the code is running very well.

there is a problem when you have several DMAs running at the same time.. you can check on this site..

if you have 2 channels of DMA-2 and 1 channel of DMA-1 running, the occasional DMA interrupt is lost

Posted on February 08, 2017 at 13:37

Hi marsh,

Thank for your reaply. I'll try it out as soon as possible. I use just one DMA channel.

As far I remember that in following code:

//some of init

HAL_ADC_DMA_Start()

while(1){

i++;

HAL_Delay(1000)

}

with breakpoint on the i++ line, i cannot achieve this one.

Posted on February 08, 2017 at 20:07

Unfortunately it still not work. I add this configuration (of ADC and DMA) to properly working program using HAL functions, and it blocked it at all... I have no idea what is going wrong. 

T J
Lead
Posted on February 09, 2017 at 01:08

sometimes the compiler removes redundant code.

so the I++ may not exist.

so the break-point is non functional.

put your break-point on the HAL_Delay(1000); line...

Posted on February 09, 2017 at 11:31

I have turned off optimiaztion of the code. I'm using Atollic TrueStudio. But on the HAL_Delay(1000) there is also the same result.

Posted on February 09, 2017 at 11:45

Atollic is still a little immature...

this may be their bug..

I use uV5...

do they have a forum ?

Maybe you could post your issue there.

Posted on February 09, 2017 at 12:48

I'll try.

But apart from debbugging and stepping, when I make some code which working, and then I put into it ADC cofiguration and just flash device, it also stop to work.

In the worst case, I'll back to std periph library.

Piotr Rog
Associate II
Posted on February 09, 2017 at 20:04

I noticed, that calling ANY function is near to impossible in normal work. But... in debug mode, if I run code forward, and pause it I usually land in DMA handling (HAL_DMA_IRQHandler). When I stepped this function out, I land in last calling function. It looks like MCU has problem with jumping to function (it is always 'captured' by DMA functionality). 

marsh, can you tell how achieve the lowest speed of ADC/DMA as you mentioned? I would to try this solution also.

Posted on February 09, 2017 at 22:22

this is directly from the cube...

/** ****************************************************************************** * File Name : ADC.c * Description : This file provides code for the configuration * of the ADC instances. ****************************************************************************** * * Copyright (c) 2017 STMicroelectronics International N.V. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted, provided that the following conditions are met: * * 1. Redistribution of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of other * contributors to this software may be used to endorse or promote products * derived from this software without specific written permission. * 4. This software, including modifications and/or derivative works of this * software, must execute solely and exclusively on microcontroller or * microprocessor devices manufactured by or for STMicroelectronics. * 5. Redistribution and use of this software other than as permitted under * this license is void and will automatically terminate your rights under * this license. * * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS 'AS IS' * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */
/* Includes ------------------------------------------------------------------*/#include 'adc.h'
#include 'gpio.h'#include 'dma.h'
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
ADC_HandleTypeDef hadc;DMA_HandleTypeDef hdma_adc;
/* ADC init function */void MX_ADC_Init(void){ ADC_ChannelConfTypeDef sConfig;
 /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */ hadc.Instance = ADC1; hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; hadc.Init.Resolution = ADC_RESOLUTION_12B; hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV; hadc.Init.LowPowerAutoWait = DISABLE; hadc.Init.LowPowerAutoPowerOff = DISABLE; hadc.Init.ContinuousConvMode = ENABLE; hadc.Init.DiscontinuousConvMode = DISABLE; hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc.Init.DMAContinuousRequests = ENABLE; hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; if (HAL_ADC_Init(&hadc) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_0; sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_1; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_2; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_3; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_6; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_7; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_8; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_9; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_10; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_11; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_13; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_14; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_15; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_VREFINT; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
 /**Configure for the selected ADC regular channel to be converted. */ sConfig.Channel = ADC_CHANNEL_VBAT; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?