cancel
Showing results for 
Search instead for 
Did you mean: 

Multichannel ADC DMA solution NOT working on stm32l4xx specifically ST32L496

shami
Associate

I am aware of the TIMER4 ADC_EXTERNALTRIG_T4_TRGO definition bug and have modified the file accordinginly . I have had this code working in single channel mode ( non DMA) but cannot get it working in multichannel DMA mode .

ADC_INIT()
{
   hadc3.Instance = ADC3;
 
    HAL_ADC_DeInit(&hadc3);
 
    hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
    hadc3.Init.Resolution = ADC_RESOLUTION_12B;
    hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;
    hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
    hadc3.Init.LowPowerAutoWait = DISABLE;
    hadc3.Init.ContinuousConvMode = DISABLE;
    hadc3.Init.NbrOfConversion = 4;
    hadc3.Init.DiscontinuousConvMode = DISABLE;
    hadc3.Init.NbrOfDiscConversion = 1;
    hadc3.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T4_TRGO;
    hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
    hadc3.Init.DMAContinuousRequests = DISABLE;
    hadc3.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
    hadc3.Init.OversamplingMode = DISABLE;
    if (HAL_ADC_Init(&hadc3) != HAL_OK) {
        _Error_Handler(__FILE__, __LINE__);
    }
 
 
    /**Configure Regular Channel
     */
    sConfig.Channel = ADC_CHANNEL_1;
    sConfig.Rank = ADC_REGULAR_RANK_1;
    sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
    sConfig.SingleDiff = ADC_SINGLE_ENDED;
    sConfig.OffsetNumber = ADC_OFFSET_NONE;
    sConfig.Offset = 0;
    if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) {
        _Error_Handler(__FILE__, __LINE__);
    }
    /**Configure Regular Channel
     */
    sConfig.Channel = ADC_CHANNEL_6;
    sConfig.Rank = ADC_REGULAR_RANK_2;
    if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) {
        _Error_Handler(__FILE__, __LINE__);
    }
    /**Configure Regular Channel
     */
    sConfig.Channel = ADC_CHANNEL_8;
    sConfig.Rank = ADC_REGULAR_RANK_3;
    if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) {
        _Error_Handler(__FILE__, __LINE__);
    }
    /**Configure Regular Channel
     */
    sConfig.Channel = ADC_CHANNEL_10;
    sConfig.Rank = ADC_REGULAR_RANK_4;
    if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) {
        _Error_Handler(__FILE__, __LINE__);
    }
}
 
In hal_msp.cpp
 
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) {
 
    GPIO_InitTypeDef GPIO_InitStruct = { 0 };
 
       /* Peripheral clock enable */
        HAL_RCC_ADC_CLK_ENABLED++;
        if (HAL_RCC_ADC_CLK_ENABLED == 1) {
            __HAL_RCC_ADC_CLK_ENABLE()
            ;
        }
 
        __HAL_RCC_GPIOC_CLK_ENABLE()
        ;
      __HAL_RCC_GPIOF_CLK_ENABLE()
        ;
 
        /* Enable clock of DMA associated to the peripheral */
        __HAL_RCC_DMA1_CLK_ENABLE()
        ;
 
        /**ADC3 GPIO Configuration
         PF3     ------> ADC3_IN6
         PF5     ------> ADC3_IN8
         PF7     ------> ADC3_IN10
         PC0     ------> ADC3_IN1
         */
        GPIO_InitStruct.Pin = Reference_voltage_for_A_Pin | Spare_temp_sensor_channel_Pin
                | Temperature_Sensor_on_Heat_sink_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
 
        GPIO_InitStruct.Pin = Reference_voltage_for_B_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(Reference_voltage_for_B_GPIO_Port, &GPIO_InitStruct);
 
        /* ADC3 DMA Init */
        /* ADC3 Init */
        hdma_adc3.Instance = DMA1_Channel3;
        hdma_adc3.Init.Request = DMA_REQUEST_0;
        hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY;
        hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_adc3.Init.MemInc = DMA_MINC_ENABLE;
        hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
        hdma_adc3.Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD;
        hdma_adc3.Init.Mode = DMA_CIRCULAR;
        hdma_adc3.Init.Priority = DMA_PRIORITY_HIGH;
        HAL_DMA_DeInit(&hdma_adc3);
        HAL_DMA_Init(&hdma_adc3);
        __HAL_LINKDMA(hadc, DMA_Handle, hdma_adc3);
 
 
}
 
Time init code not inserted .  I do know the timer is running correctly 
 
Then To start the process
   MX_TIM_Init();
   ADC_INIT();
    HAL_TIM_Base_Start(&htim4);
 
   HAL_ADC_Start_DMA(&hadc3, (uint32_t *) aADCxConvertedValues, ADCCONVERTEDVALUES_BUFFER_SIZE);

1 ACCEPTED SOLUTION

Accepted Solutions
shami
Associate

Found my own mistake.  

In the process of testing other modes I have copied and pasted

hdma_adc3.Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD;

It should be

hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

View solution in original post

1 REPLY 1
shami
Associate

Found my own mistake.  

In the process of testing other modes I have copied and pasted

hdma_adc3.Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD;

It should be

hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;