Question
Triggering injected conversion start with TIM1_CH4
Posted on August 23, 2016 at 21:01
In my STM32F2 application, I need to trigger the conversion start of several injected channels using TIM_CH4. The documents are a little bit unclear as to how to configure the timer for this.
It seems like I need to configure TIM1_CH4 as a PWM output, but if that's the case, the wave would go high immediately on timer reset and the conversion would start. To address this, I invert the polarity of the CH4 PWM wave, but keep the ADC injected start trigger set to a rising edge. this would mean that the wave would go high on compare, and then the conversion would be triggered. Can anyone comment if I'm on the right track with this?// Init ADC for current sampling
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);
// NVIC configuration for DMA Input data interrupt
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
// 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_RISING; //
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);
// Start the conversion
//HAL_ADC_Start_DMA(&adcHandle, conversionResults, 2);
}
void InitMotorControl()
{
// Enable clocks
__TIM1_CLK_ENABLE();
// [[ .. Code to configure PWM channels ommited .. ]]
// Configure the timer
pwmOutTimer.Instance = TIM1;
pwmOutTimer.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
pwmOutTimer.Init.CounterMode = TIM_COUNTERMODE_UP;
pwmOutTimer.Init.Period = MOTOR_CONTROL_PWM_PERIOD;
// Commit the timer
HAL_TIM_PWM_Init(&pwmOutTimer);
// ADC sync channel
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;
// Commit ADC sync config
//HAL_TIM_OC_ConfigChannel(&pwmOutTimer, &adcSyncConfig, TIM_CHANNEL_4);
HAL_TIM_PWM_ConfigChannel(&pwmOutTimer, &adcSyncConfig, TIM_CHANNEL_4);
// Configure break and deadtime
TIM_BreakDeadTimeConfigTypeDef TIM_BreakDeadTimeConfig;
TIM_BreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
TIM_BreakDeadTimeConfig.DeadTime = 10;
TIM_BreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;
TIM_BreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
TIM_BreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1;
TIM_BreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
TIM_BreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;
// Commit the break/deadtime config
HAL_TIMEx_ConfigBreakDeadTime(&pwmOutTimer, &TIM_BreakDeadTimeConfig);
// Commit the timer sync
//HAL_TIM_OC_Start(&pwmOutTimer, TIM_CHANNEL_4);
HAL_TIM_PWM_Start(&pwmOutTimer, TIM_CHANNEL_4);
}