2020-06-29 04:19 AM
Im enable pwm output TA1, TA2 and try enable burst mode with changeble BMCMP and BMPER. Im change this registers and try update from timer triggers and software trigger, but pwm output set one burst state and doesnt change. Pwm burst state is updated if turn off and turn on BME bit.
stm32g474ret6
2020-06-29 04:30 AM
This is example of my code
#define PWM_MIN_DUTY_CYCLE_VALUE 700
static int16_t PWMvalueISR = PWM_MIN_DUTY_CYCLE_VALUE;
static int16_t PWMvalueDbg = PWM_MIN_DUTY_CYCLE_VALUE;
static uint32_t pulseIdle[] = {7, 3, 5, 1, 3, 1, 1};
static uint32_t pulsePeriod[] = {8, 4, 8, 2, 8, 4, 8};
static HRTIM_HandleTypeDef hhrtim1 = {0};
static void periph_hrtimPwmOutputInit(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_ADC12_CLK_ENABLE();
__HAL_RCC_HRTIM1_CLK_ENABLE();
GPIO_InitTypeDef gpio;
//HRTIM CHA1 & CHA2
gpio.Alternate = GPIO_AF13_HRTIM1;
gpio.Mode = GPIO_MODE_AF_PP;
gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
gpio.Pin = GPIO_PIN_8 | GPIO_PIN_9;
HAL_GPIO_Init(GPIOA, &gpio);
//ADC
gpio.Alternate = 0;
gpio.Mode = GPIO_MODE_ANALOG;
gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
gpio.Pin = GPIO_PIN_0;
HAL_GPIO_Init(GPIOA, &gpio);
//ADC REGULATOR
hadc1_regulator.Instance = ADC1;
hadc1_regulator.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1_regulator.Init.ContinuousConvMode = DISABLE;
hadc1_regulator.Init.DataAlign = ADC_DATAALIGN_LEFT;
hadc1_regulator.Init.DiscontinuousConvMode = DISABLE;
hadc1_regulator.Init.DMAContinuousRequests = DISABLE;
hadc1_regulator.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1_regulator.Init.ExternalTrigConv = ADC_EXTERNALTRIG_HRTIM_TRG1;
hadc1_regulator.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1_regulator.Init.GainCompensation = 0;
hadc1_regulator.Init.LowPowerAutoWait = DISABLE;
hadc1_regulator.Init.NbrOfConversion = 1;
hadc1_regulator.Init.NbrOfDiscConversion = 0;
hadc1_regulator.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc1_regulator.Init.OversamplingMode = DISABLE;
hadc1_regulator.Init.Resolution = ADC_RESOLUTION_12B;
hadc1_regulator.Init.SamplingMode = ADC_SAMPLING_MODE_BULB;
hadc1_regulator.Init.ScanConvMode = ADC_SCAN_DISABLE;
HAL_ADC_Init(&hadc1_regulator);
HAL_ADCEx_Calibration_Start(&hadc1_regulator, ADC_SINGLE_ENDED);
ADC_MultiModeTypeDef multimode = {0};
multimode.Mode = ADC_MODE_INDEPENDENT;
HAL_ADCEx_MultiModeConfigChannel(&hadc1_regulator, &multimode);
ADC_ChannelConfTypeDef adcChannelCfg = {0};
adcChannelCfg.Channel = ADC_CHANNEL_1;
adcChannelCfg.Offset = 2482; //target
adcChannelCfg.OffsetNumber = ADC_OFFSET_1;
adcChannelCfg.OffsetSaturation = DISABLE;
adcChannelCfg.OffsetSign = ADC_OFFSET_SIGN_NEGATIVE;
adcChannelCfg.Rank = ADC_REGULAR_RANK_1;
adcChannelCfg.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
adcChannelCfg.SingleDiff = ADC_SINGLE_ENDED;
HAL_ADC_ConfigChannel(&hadc1_regulator, &adcChannelCfg);
HAL_NVIC_SetPriority(ADC1_2_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
HAL_ADC_Start_IT(&hadc1_regulator);
hhrtim1.Instance = HRTIM1;
hhrtim1.Init.HRTIMInterruptResquests = HRTIM_IT_NONE;
hhrtim1.Init.SyncInputSource = HRTIM_SYNCINPUTSOURCE_NONE;
hhrtim1.Init.SyncOutputSource = HRTIM_SYNCOUTPUTSOURCE_MASTER_CMP1;
hhrtim1.Init.SyncOutputPolarity = HRTIM_SYNCOUTPUTPOLARITY_POSITIVE;
hhrtim1.Init.SyncOptions = HRTIM_SYNCOPTION_NONE;
HAL_HRTIM_Init(&hhrtim1);
HAL_HRTIM_DLLCalibrationStart(&hhrtim1, HRTIM_CALIBRATIONRATE_3);
HAL_HRTIM_PollForDLLCalibration(&hhrtim1, 100);
//hrtim
HRTIM_TimeBaseCfgTypeDef timeBaseCfg = {0};
timeBaseCfg.PrescalerRatio = HRTIM_PRESCALERRATIO_MUL32;
timeBaseCfg.Period = 54400;
timeBaseCfg.RepetitionCounter = 0;
timeBaseCfg.Mode = HRTIM_MODE_CONTINUOUS;
HAL_HRTIM_TimeBaseConfig(&hhrtim1, HRTIM_TIMERINDEX_MASTER, &timeBaseCfg);
HAL_HRTIM_TimeBaseConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A, &timeBaseCfg);
//hrtimv2 settings
HRTIM_TimerCtlTypeDef timerCtl = {0};
timerCtl.UpDownMode = HRTIM_TIMERUPDOWNMODE_UP;
timerCtl.TrigHalf = HRTIM_TIMERTRIGHALF_DISABLED;
timerCtl.GreaterCMP1 = HRTIM_TIMERGTCMP1_EQUAL;
timerCtl.GreaterCMP3 = HRTIM_TIMERGTCMP3_EQUAL;
timerCtl.DualChannelDacEnable = HRTIM_TIMER_DCDE_DISABLED;
timerCtl.DualChannelDacStep = 0; //not used
timerCtl.DualChannelDacReset = 0; //not used
HAL_HRTIM_WaveformTimerControl(&hhrtim1, HRTIM_TIMERINDEX_MASTER, &timerCtl);
//timers common settings
HRTIM_TimerCfgTypeDef timerCfg = {0};
timerCfg.DMARequests = HRTIM_TIM_DMA_NONE;
timerCfg.DMASrcAddress = 0x0;
timerCfg.DMADstAddress = 0x0;
timerCfg.DMASize = 0x1;
timerCfg.HalfModeEnable = HRTIM_HALFMODE_DISABLED;
timerCfg.StartOnSync = HRTIM_SYNCSTART_DISABLED;
timerCfg.ResetOnSync = HRTIM_SYNCRESET_DISABLED;
timerCfg.DACSynchro = HRTIM_DACSYNC_NONE;
timerCfg.UpdateGating = HRTIM_UPDATEGATING_INDEPENDENT;
timerCfg.BurstMode = HRTIM_TIMERBURSTMODE_MAINTAINCLOCK;
timerCfg.PushPull = HRTIM_TIMPUSHPULLMODE_DISABLED;
timerCfg.FaultLock = HRTIM_TIMFAULTLOCK_READWRITE;
timerCfg.FaultEnable = HRTIM_TIMFAULTENABLE_NONE;
timerCfg.DelayedProtectionMode = HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DISABLED;
timerCfg.PreloadEnable = HRTIM_PRELOAD_ENABLED;
timerCfg.DeadTimeInsertion = HRTIM_TIMDEADTIMEINSERTION_DISABLED;
timerCfg.ResetUpdate = HRTIM_TIMUPDATEONRESET_DISABLED;
timerCfg.RepetitionUpdate = HRTIM_UPDATEONREPETITION_ENABLED;
timerCfg.BalancedIdleAutomaticResume = HRTIM_OUTPUTBIAR_DISABLED;
timerCfg.InterleavedMode = HRTIM_INTERLEAVED_MODE_DISABLED;
timerCfg.ReSyncUpdate = HRTIM_TIMERESYNC_UPDATE_UNCONDITIONAL;
timerCfg.UpdateTrigger = HRTIM_TIMUPDATETRIGGER_MASTER;
timerCfg.ResetTrigger = HRTIM_TIMRESETTRIGGER_NONE;
timerCfg.InterruptRequests = HRTIM_TIM_IT_NONE;
HAL_HRTIM_WaveformTimerConfig(&hhrtim1, HRTIM_TIMERINDEX_MASTER, &timerCfg);
//comparators settings
HRTIM_CompareCfgTypeDef compareCfg = {0};
compareCfg.AutoDelayedMode = HRTIM_AUTODELAYEDMODE_REGULAR;
compareCfg.AutoDelayedTimeout = 0;
compareCfg.CompareValue = 700;
HAL_HRTIM_WaveformCompareConfig(&hhrtim1, HRTIM_TIMERINDEX_MASTER, HRTIM_COMPAREUNIT_1, &compareCfg);
compareCfg.CompareValue = (700/2);
HAL_HRTIM_WaveformCompareConfig(&hhrtim1, HRTIM_TIMERINDEX_MASTER, HRTIM_COMPAREUNIT_2, &compareCfg);
compareCfg.CompareValue = (700/2) + 700;
HAL_HRTIM_WaveformCompareConfig(&hhrtim1, HRTIM_TIMERINDEX_MASTER, HRTIM_COMPAREUNIT_3, &compareCfg);
//output settings
HRTIM_OutputCfgTypeDef outputCfg = {0};
outputCfg.Polarity = HRTIM_OUTPUTPOLARITY_HIGH;
outputCfg.IdleMode = HRTIM_OUTPUTIDLEMODE_IDLE;
outputCfg.IdleLevel = HRTIM_OUTPUTIDLELEVEL_INACTIVE;
outputCfg.FaultLevel = HRTIM_OUTPUTFAULTLEVEL_INACTIVE;
outputCfg.ChopperModeEnable = HRTIM_OUTPUTCHOPPERMODE_DISABLED;
outputCfg.BurstModeEntryDelayed = HRTIM_OUTPUTBURSTMODEENTRY_REGULAR;
outputCfg.SetSource = HRTIM_OUTPUTSET_MASTERPER;
outputCfg.ResetSource = HRTIM_OUTPUTRESET_MASTERCMP1;
HAL_HRTIM_WaveformOutputConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A, HRTIM_OUTPUT_TA1, &outputCfg);
outputCfg.SetSource = HRTIM_OUTPUTSET_MASTERCMP2;
outputCfg.ResetSource = HRTIM_OUTPUTRESET_MASTERCMP3;
HAL_HRTIM_WaveformOutputConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A, HRTIM_OUTPUT_TA2, &outputCfg);
//burst controller
HRTIM_BurstModeCfgTypeDef pBurstModeCfg = {0};
pBurstModeCfg.Mode = HRTIM_BURSTMODE_CONTINOUS;
pBurstModeCfg.ClockSource = HRTIM_BURSTMODECLOCKSOURCE_MASTER;
pBurstModeCfg.Prescaler = HRTIM_BURSTMODEPRESCALER_DIV1;
pBurstModeCfg.PreloadEnable = HRIM_BURSTMODEPRELOAD_ENABLED;
pBurstModeCfg.Trigger = HRTIM_BURSTMODETRIGGER_MASTER_RESET;
pBurstModeCfg.IdleDuration = pulseIdle[6];
pBurstModeCfg.Period = pulsePeriod[6];
HAL_HRTIM_BurstModeConfig(&hhrtim1, &pBurstModeCfg);
//adc trigger
HRTIM_ADCTriggerCfgTypeDef adcTriggerCfg = {0};
adcTriggerCfg.Trigger = HRTIM_ADCTRIGGEREVENT24_MASTER_PERIOD | HRTIM_ADCTRIGGEREVENT24_MASTER_CMP2;
adcTriggerCfg.UpdateSource = HRTIM_ADCTRIGGERUPDATE_MASTER;
HAL_HRTIM_ADCTriggerConfig(&hhrtim1, HRTIM_ADCTRIGGER_1, &adcTriggerCfg);
HAL_HRTIM_WaveformOutputStart(&hhrtim1, HRTIM_OUTPUT_TA1 | HRTIM_OUTPUT_TA2);
HAL_HRTIM_WaveformCountStart(&hhrtim1, HRTIM_TIMERID_TIMER_A) != HAL_OK);
HAL_HRTIM_WaveformCountStart(&hhrtim1, HRTIM_TIMERID_MASTER) != HAL_OK);
}
void ADC1_2_IRQHandler(void)
{
__HAL_ADC_CLEAR_FLAG(&hadc1_regulator, ADC_FLAG_EOC);
if(PWMvalueISR < PWMvalueDbg)
++PWMvalueISR;
else if(PWMvalueISR > PWMvalueDbg)
--PWMvalueISR;
break;
//if < PWM_MIN_DUTY_CYCLE_VALUE ~ turn on burst mode
if(PWMvalueISR < PWM_MIN_DUTY_CYCLE_VALUE)
{
hhrtim1.Instance->sCommonRegs.BMCMPR = pulseIdle[PWMvalueISR / 100];
hhrtim1.Instance->sCommonRegs.BMPER = pulsePeriod[PWMvalueISR / 100];
HAL_HRTIM_BurstModeCtl(&hhrtim1, HRTIM_BURSTMODECTL_ENABLED);
HAL_HRTIM_BurstModeSoftwareTrigger(&hhrtim1);
__HAL_HRTIM_SETCOMPARE(&hhrtim1,HRTIM_TIMERINDEX_MASTER,HRTIM_COMPAREUNIT_1,PWM_MIN_DUTY_CYCLE_VALUE);
__HAL_HRTIM_SETCOMPARE(&hhrtim1,HRTIM_TIMERINDEX_MASTER,HRTIM_COMPAREUNIT_3,27200+PWM_MIN_DUTY_CYCLE_VALUE);
}//if > PWM_MIN_DUTY_CYCLE_VALUE ~ turn off burst mode
else
{
HAL_HRTIM_BurstModeCtl(&hhrtim1, HRTIM_BURSTMODECTL_DISABLED);
HAL_HRTIM_BurstModeSoftwareTrigger(&hhrtim1);
__HAL_HRTIM_SETCOMPARE(&hhrtim1,HRTIM_TIMERINDEX_MASTER,HRTIM_COMPAREUNIT_1,PWMvalueISR);
__HAL_HRTIM_SETCOMPARE(&hhrtim1,HRTIM_TIMERINDEX_MASTER,HRTIM_COMPAREUNIT_3,27200+PWMvalueISR);
}
}