cancel
Showing results for 
Search instead for 
Did you mean: 

The DMA transfer only the first byte from ADC1 (STM32H735)

Saif
Associate II

I configure the ADC1 of the STM32H735 like bellow:

The ADC Clock = 20MHz

ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
 
/* ADC1 init function */
void MX_ADC1_Init(void)
{
 
  /* USER CODE BEGIN ADC1_Init 0 */
 
  /* USER CODE END ADC1_Init 0 */
 
  ADC_MultiModeTypeDef multimode = {0};
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /* USER CODE BEGIN ADC1_Init 1 */
 
  /* USER CODE END ADC1_Init 1 */
 
  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.NbrOfDiscConversion   = 1;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
  hadc1.Init.DMAContinuousRequests = ENABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_8CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  sConfig.OffsetSignedSaturation = DISABLE;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */
 
  /* USER CODE END ADC1_Init 2 */
 
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
 
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */
 
  /* USER CODE END ADC1_MspInit 0 */
 
  /** Initializes the peripherals clock
  */
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
    PeriphClkInitStruct.PLL3.PLL3M = 2;
    PeriphClkInitStruct.PLL3.PLL3N = 40;
    PeriphClkInitStruct.PLL3.PLL3P = 2;
    PeriphClkInitStruct.PLL3.PLL3Q = 5;
    PeriphClkInitStruct.PLL3.PLL3R = 25;
    PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_3;
    PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE;
    PeriphClkInitStruct.PLL3.PLL3FRACN = 0;
    PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL3;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    {
      Error_Handler();
    }
 
    /* ADC1 clock enable */
    __HAL_RCC_ADC12_CLK_ENABLE();
 
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**ADC1 GPIO Configuration
    PA0_C     ------> ADC1_INP0
    */
    HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PA0, SYSCFG_SWITCH_PA0_OPEN);
 
    /* ADC1 DMA Init */
    /* ADC1 Init */
    hdma_adc1.Instance = DMA1_Stream1;
    hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
    hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_adc1.Init.Mode = DMA_CIRCULAR;
    hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM;
    hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
    {
      Error_Handler();
    }
 
    __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
 
  /* USER CODE BEGIN ADC1_MspInit 1 */
 
  /* USER CODE END ADC1_MspInit 1 */
  }
}

The ADC1_DR register = 0xFFE (I put 3.3V in PA0_C pin) it is ok.


_legacyfs_online_stmicro_images_0693W00000biUC8QAM.pngbut in the buffer, the dma transfer only the first byte :


_legacyfs_online_stmicro_images_0693W00000biUKvQAM.pngI did not understand why the DMA always transfers a Byte despite I made several configuration combinations.

Best Regards,

21 REPLIES 21
LCE
Principal

Please show us the buffer declaration and how you start DMA.

LCE
Principal

And you could try:

hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;

Saif
Associate II
extern ADC_HandleTypeDef hadc1;
ALIGN_32BYTES (static uint16_t   aADCxConvertedData[4]);
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
 
static void CPU_CACHE_Enable(void);
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_DMA_Init();
  /* USER CODE BEGIN 2 */
  HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
  HAL_ADC_Start_DMA(&hadc1,(uint32_t*)aADCxConvertedData, 4 );
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
 
  }
  /* USER CODE END 3 */
}

Saif
Associate II

Same problem

Looks exactly like my working H7 ADC code.

LCE
Principal

I'm using ADC3 on a H723 / H735.

I don't see any GPIO init, is that included in HAL_SYSCFG_AnalogSwitchConfig() ?

There's this line in my init concerning ADC data alignment in the data register:

hAdc3.Init.DataAlign = ADC3_DATAALIGN_RIGHT;

Here's my working HAL setup, but I use multiple channels.

uint8_t ADC3_InitStartDma(void)
{
	/* Configure the global features of the ADC:
	 * Clock, Resolution, Data Alignment and number of conversion
	 */
	hAdc3.Instance = ADC3;
 
	hAdc3.Init.ClockPrescaler 			= ADC_CLOCK_ASYNC_DIV32;
	hAdc3.Init.Resolution 				= ADC_RESOLUTION_12B;
	hAdc3.Init.DataAlign 				= ADC3_DATAALIGN_RIGHT;
	hAdc3.Init.ScanConvMode 			= ADC_SCAN_ENABLE;
	hAdc3.Init.ContinuousConvMode 		= ENABLE;
	hAdc3.Init.EOCSelection 			= ADC_EOC_SEQ_CONV;
	hAdc3.Init.LowPowerAutoWait 		= DISABLE;
	hAdc3.Init.NbrOfConversion 			= ADC_CHNL_MAX;
	hAdc3.Init.DiscontinuousConvMode 	= DISABLE;
	hAdc3.Init.ExternalTrigConv 		= ADC_SOFTWARE_START;
	hAdc3.Init.ExternalTrigConvEdge 	= ADC_EXTERNALTRIGCONVEDGE_NONE;
	hAdc3.Init.DMAContinuousRequests 	= ENABLE;
	hAdc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
	hAdc3.Init.SamplingMode 			= ADC_SAMPLING_MODE_NORMAL;
	hAdc3.Init.Overrun 					= ADC_OVR_DATA_OVERWRITTEN;
	//hAdc3.Init.Overrun 					= ADC_OVR_DATA_PRESERVED;
	hAdc3.Init.LeftBitShift 			= ADC_LEFTBITSHIFT_NONE;
	hAdc3.Init.OversamplingMode 		= DISABLE;
 
	if( HAL_ADC_Init(&hAdc3) != HAL_OK ) Error_Handler_FL(__FILE__, __LINE__);
 
	/* self calibration */
	if( HAL_ADCEx_Calibration_Start(&hAdc3, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED ) != HAL_OK ) Error_Handler_FL(__FILE__, __LINE__);
 
	return HAL_ADC_Start_DMA(&hAdc3, (uint32_t *)u16Adc3DmaBuffer, ADC_DMA_BUF_SIZE);
}

LCE
Principal

Man, that's ugly source code with my tab settings, sorry... 😅

SeyyedMohammad
Senior III

I think sharing MX configuration picture can be more readable than codes.

You've just shared the codes. Tell exactly what you expect from hardware. What you've done, and what has been aquired.

I think his description of the problem is pretty good compared to forum average. 8D