cancel
Showing results for 
Search instead for 
Did you mean: 

ADC+DMA : Problem with Memory Increment and Destination Width

marcel23
Associate II
Posted on May 01, 2017 at 23:05

Hi,

I'm currently trying to use ADC1 + DMA1 + TIM1 on STM32F091CC. I've run into two problems:

1 - DMA is not incrementing the memory buffer('Increment Address' is checked on CubeMX and hdma_adc.Init.MemInc = DMA_MINC_ENABLE). It overwrites every data read on the same address.

2 - Regardless of Data_Width value, DMA is only copying the first byte to the destination address.(overwriting previous values - see 1 and attached pictures).

Generated ADC code:

/**
 ******************************************************************************
 * 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_SINGLE_SEQ_CONV;
 hadc.Init.LowPowerAutoWait = DISABLE;
 hadc.Init.LowPowerAutoPowerOff = DISABLE;
 hadc.Init.ContinuousConvMode = DISABLE;
 hadc.Init.DiscontinuousConvMode = DISABLE;
 hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_TRGO;
 hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
 hadc.Init.DMAContinuousRequests = DISABLE;
 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_5;
 sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
 sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_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_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_VBAT;
 if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
 GPIO_InitTypeDef GPIO_InitStruct;
 if(adcHandle->Instance==ADC1)
 {
 /* USER CODE BEGIN ADC1_MspInit 0 */
 /* USER CODE END ADC1_MspInit 0 */
 /* Peripheral clock enable */
 __HAL_RCC_ADC1_CLK_ENABLE();
 
 /**ADC GPIO Configuration 
 PA5 ------> ADC_IN5
 PA6 ------> ADC_IN6 
 */
 GPIO_InitStruct.Pin = AUDIO_ENVELOPE_IN_Pin|AUDIO_RAW_IN_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 /* Peripheral DMA init*/
 
 hdma_adc.Instance = DMA1_Channel1;
 hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
 hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
 hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
 hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
 hdma_adc.Init.Mode = DMA_NORMAL;
 hdma_adc.Init.Priority = DMA_PRIORITY_MEDIUM;
 if (HAL_DMA_Init(&hdma_adc) != HAL_OK)
 {
 Error_Handler();
 }
 __HAL_DMA1_REMAP(HAL_DMA1_CH1_ADC);
 __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc);
 /* USER CODE BEGIN ADC1_MspInit 1 */
 /* USER CODE END ADC1_MspInit 1 */
 }
}
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{
 if(adcHandle->Instance==ADC1)
 {
 /* USER CODE BEGIN ADC1_MspDeInit 0 */
 /* USER CODE END ADC1_MspDeInit 0 */
 /* Peripheral clock disable */
 __HAL_RCC_ADC1_CLK_DISABLE();
 
 /**ADC GPIO Configuration 
 PA5 ------> ADC_IN5
 PA6 ------> ADC_IN6 
 */
 HAL_GPIO_DeInit(GPIOA, AUDIO_ENVELOPE_IN_Pin|AUDIO_RAW_IN_Pin);
 /* Peripheral DMA DeInit*/
 HAL_DMA_DeInit(adcHandle->DMA_Handle);
 }
 /* USER CODE BEGIN ADC1_MspDeInit 1 */
 /* USER CODE END ADC1_MspDeInit 1 */
} 
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
 * @}
 */
/**
 * @}
 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Calling function:

uint16_t dataBuffer[2000] =
{ 0 };
bool helperFlag = false;
int main()
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC_Init();
MX_USART1_UART_Init();
SB_PowerAudioEnable();
HAL_UART_Transmit(&huart1, 'TEST AUDIO - START\n', 19, 50);
MX_DMA_Init();
MX_TIM1_Init();
SB_Test_Audio_RawChannel_4khz();
while (1)
;
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
helperFlag = true;
}
uint8_t SB_Test_Audio_RawChannel_4khz()
{
uint8_t asd = 0;
HAL_ADC_Start_DMA(&hadc, (uint32_t *) dataBuffer, 30);
HAL_TIM_Base_Start(&htim1);
while (helperFlag == false)
{
asd++;
}
HAL_TIM_Base_Stop(&htim1);
HAL_ADC_Stop_DMA(&hadc);
return HAL_OK;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Has anyone dealt with something similar before?

Regards,

Marcel

#dma #adc
0 REPLIES 0