AnsweredAssumed Answered

STM32F2 ADC: No regular channels, 2 Injected channels, with DMA. Is this configuration right?

Question asked by Seto.Chris on Aug 16, 2016
Hi,

I have the attached code. This is supposed to set up the ADC for 2 injected channels, 0 regular channels and DMA. Additionally, this is supposed to use TIM1_CH4 to trigger the conversion start of the injected channels I'm wondering this configuration is correct, mainly because there is a note in the definition for ADC_InitTypeDef for NbrOfConversion specifying that the minimum value is 1, though the ADC_InitTypeDef is a required parameter to configure an injected channel.

EDIT: I just noticed the note on ScanConvMode:
"[If disabled] Parameters 'NbrOfConversion' and 'InjectedNbrOfConversion' are discarded (equivalent to set to 1)." So, I'm guessing I just need to have ScanConvMode disable then?


Additionally, I'm wondering about the configuration of TIM1_CH4. Do I need to configure this as OC or PWM?

(Snippet taken out of context, assuming the code to configure pwmOutTimer is correct)
    adcSyncConfig.OCMode        = TIM_OCMODE_PWM1;
    adcSyncConfig.OCFastMode    = TIM_OCFAST_DISABLE;
    adcSyncConfig.OCIdleState   = TIM_OCIDLESTATE_SET;
    adcSyncConfig.OCNIdleState  = TIM_OCNIDLESTATE_RESET;
    adcSyncConfig.OCPolarity    = TIM_OCPOLARITY_LOW;
    adcSyncConfig.OCNPolarity   = TIM_OCNPOLARITY_LOW;
    adcSyncConfig.Pulse = 0;
HAL_TIM_PWM_ConfigChannel(&pwmOutTimer, &adcSyncConfig, TIM_CHANNEL_4);
HAL_TIM_PWM_Start(&pwmOutTimer, TIM_CHANNEL_4);


ADC setup:
void InitAdc()
{
    // Enable Clocks
    __GPIOC_CLK_ENABLE();
    __ADC1_CLK_ENABLE();
    __DMA2_CLK_ENABLE();
 
    // Common current sense GPIO
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
 
    // Gate driver 1: SO1
    GPIO_InitStruct.Pin = GPIO_PIN_1;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
     
    // Gate driver 2: SO2
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
     
    // Configure the ADC
    adcHandle.Instance = ADC1;
    adcHandle.Init.ClockPrescaler               = ADC_CLOCK_SYNC_PCLK_DIV2;
    adcHandle.Init.Resolution                   = ADC_RESOLUTION_12B;
    adcHandle.Init.ScanConvMode                 = DISABLE;         
    adcHandle.Init.DataAlign                    = ADC_DATAALIGN_RIGHT;
    adcHandle.Init.ContinuousConvMode           = DISABLE;
    adcHandle.Init.DiscontinuousConvMode        = DISABLE;
    adcHandle.Init.ExternalTrigConv             = ADC_SOFTWARE_START;
    adcHandle.Init.ExternalTrigConvEdge         = ADC_EXTERNALTRIGCONVEDGE_NONE;
    adcHandle.Init.EOCSelection                 = DISABLE;
    adcHandle.Init.DMAContinuousRequests        = DISABLE;
    adcHandle.Init.NbrOfConversion              = 0;
    adcHandle.Init.NbrOfDiscConversion          = 0;
     
    // Commit the ADC
    HAL_ADC_Init(&adcHandle);
     
    // Configure for injected channels
    ADC_InjectionConfTypeDef adcInjectedConfig;
    adcInjectedConfig.AutoInjectedConv                  = DISABLE;                          // As per note in driver
    adcInjectedConfig.ExternalTrigInjecConv             = ADC_EXTERNALTRIGINJECCONV_T1_CC4; // TIM1 compare
    adcInjectedConfig.ExternalTrigInjecConvEdge         = ADC_EXTERNALTRIGCONVEDGE_NONE;    //
    adcInjectedConfig.InjectedDiscontinuousConvMode     = DISABLE;                          // Because we are using main seq
    adcInjectedConfig.InjectedSamplingTime              = ADC_SAMPLETIME_3CYCLES;
    adcInjectedConfig.InjectedOffset                    = 0;
     
    // Channel 11 :: SO1
    adcInjectedConfig.InjectedChannel = ADC_CHANNEL_11;
    adcInjectedConfig.InjectedRank = ADC_INJECTED_RANK_1;
    HAL_ADCEx_InjectedConfigChannel(&adcHandle, &adcInjectedConfig);
     
    // Channel 12 :: SO2
    adcInjectedConfig.InjectedChannel = ADC_CHANNEL_11;
    adcInjectedConfig.InjectedRank = ADC_INJECTED_RANK_2;
    HAL_ADCEx_InjectedConfigChannel(&adcHandle, &adcInjectedConfig);
     
    // Configure DMA
    adcDmaHandle.Instance                   = DMA2_Stream0;
    adcDmaHandle.Init.Channel               = DMA_CHANNEL_0;
    adcDmaHandle.Init.Direction             = DMA_PERIPH_TO_MEMORY;
    adcDmaHandle.Init.PeriphInc             = DMA_PINC_DISABLE;
    adcDmaHandle.Init.MemInc                = DMA_MINC_ENABLE;
    adcDmaHandle.Init.PeriphDataAlignment   = DMA_PDATAALIGN_WORD;
    adcDmaHandle.Init.MemDataAlignment      = DMA_MDATAALIGN_WORD;
    adcDmaHandle.Init.Mode                  = DMA_CIRCULAR;
    adcDmaHandle.Init.Priority              = DMA_PRIORITY_HIGH;
    adcDmaHandle.Init.MemBurst              = DMA_MBURST_SINGLE;
    adcDmaHandle.Init.PeriphBurst           = DMA_PBURST_SINGLE;
 
    // Bring DMA up
    HAL_DMA_Init(&adcDmaHandle);
     
    // Associate the DMA handle
    __HAL_LINKDMA(&adcHandle, DMA_Handle, adcDmaHandle);
     
    // NVIC configuration for DMA Input data interrupt
    HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
     
    // Start the conversion
    HAL_ADC_Start_DMA(&adcHandle, conversionResults, 2);
}


Outcomes