cancel
Showing results for 
Search instead for 
Did you mean: 

HRTIM center-aligned mode with 100% duty?

Asantos
Senior

Is it possible to achieve 100% duty cycle on HRTIM using center-aligned mode?

when HRTIM1->sTimerxRegs[5].CMP1xR = 2124 (PERIOD-1), the duty is almost 100% end when HRTIM1->sTimerxRegs[5].CMP1xR = 2125, the duty drops to zero.

As per the code below, I am not using high resolution. LL_HRTIM_EE_PRESCALER_DIV1

static void MX_HRTIM1_Init(void)

{

 LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

 LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_HRTIM1);

 LL_HRTIM_ConfigDLLCalibration(HRTIM1, LL_HRTIM_DLLCALIBRATION_MODE_CONTINUOUS, LL_HRTIM_DLLCALIBRATION_RATE_3);

 /* Poll for DLL end of calibration */

#if (USE_TIMEOUT == 1)

 uint32_t Timeout = 10; /* Timeout Initialization */

#endif /*USE_TIMEOUT*/

 while(LL_HRTIM_IsActiveFlag_DLLRDY(HRTIM1) == RESET){

#if (USE_TIMEOUT == 1)

  if (LL_SYSTICK_IsActiveCounterFlag()) /* Check Systick counter flag to decrement the time-out value */

  {

    if(Timeout-- == 0)

    {

     Error_Handler(); /* error management */

    }

  }

#endif /* USE_TIMEOUT */

 }

 LL_HRTIM_EE_SetPrescaler(HRTIM1, LL_HRTIM_EE_PRESCALER_DIV1);

 LL_HRTIM_EE_SetSrc(HRTIM1, LL_HRTIM_EVENT_3, LL_HRTIM_EEV3SRC_COMP6_OUT);

 LL_HRTIM_EE_SetPolarity(HRTIM1, LL_HRTIM_EVENT_3, LL_HRTIM_EE_POLARITY_HIGH);

 LL_HRTIM_EE_SetSensitivity(HRTIM1, LL_HRTIM_EVENT_3, LL_HRTIM_EE_SENSITIVITY_LEVEL);

 LL_HRTIM_EE_SetFastMode(HRTIM1, LL_HRTIM_EVENT_3, LL_HRTIM_EE_FASTMODE_DISABLE);

 LL_HRTIM_EE_SetSrc(HRTIM1, LL_HRTIM_EVENT_5, LL_HRTIM_EEV5SRC_COMP7_OUT);

 LL_HRTIM_EE_SetPolarity(HRTIM1, LL_HRTIM_EVENT_5, LL_HRTIM_EE_POLARITY_HIGH);

 LL_HRTIM_EE_SetSensitivity(HRTIM1, LL_HRTIM_EVENT_5, LL_HRTIM_EE_SENSITIVITY_LEVEL);

 LL_HRTIM_EE_SetFastMode(HRTIM1, LL_HRTIM_EVENT_5, LL_HRTIM_EE_FASTMODE_DISABLE);

 LL_HRTIM_ConfigADCTrig(HRTIM1, LL_HRTIM_ADCTRIG_1, LL_HRTIM_ADCTRIG_UPDATE_TIMER_F, LL_HRTIM_ADCTRIG_SRC13_TIMFRST);

 LL_HRTIM_SetADCPostScaler(HRTIM1, LL_HRTIM_ADCTRIG_1, 0x0);

 LL_HRTIM_TIM_SetPrescaler(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_PRESCALERRATIO_DIV1);

 LL_HRTIM_TIM_SetCounterMode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_MODE_CONTINUOUS);

 LL_HRTIM_TIM_SetPeriod(HRTIM1, LL_HRTIM_TIMER_F, 2125);

 LL_HRTIM_TIM_SetRepetition(HRTIM1, LL_HRTIM_TIMER_F, 0x00);

 LL_HRTIM_TIM_SetUpdateGating(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_UPDATEGATING_INDEPENDENT);

 LL_HRTIM_TIM_SetCountingMode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_COUNTING_MODE_UP_DOWN);

 // LL_HRTIM_TIM_SetCountingMode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_COUNTING_MODE_UP);

 LL_HRTIM_TIM_SetTriggeredHalfMode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_TRIGHALF_DISABLED);

 LL_HRTIM_TIM_SetComp1Mode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_GTCMP1_EQUAL);

 LL_HRTIM_TIM_SetComp3Mode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_GTCMP1_EQUAL);

 LL_HRTIM_TIM_SetRollOverMode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_ROLLOVER_MODE_RST);

 LL_HRTIM_TIM_SetFaultEventRollOverMode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_ROLLOVER_MODE_BOTH);

 LL_HRTIM_TIM_SetBMRollOverMode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_ROLLOVER_MODE_BOTH);

 LL_HRTIM_TIM_SetADCRollOverMode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_ROLLOVER_MODE_RST);

 LL_HRTIM_TIM_SetOutputRollOverMode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_ROLLOVER_MODE_RST);

 LL_HRTIM_TIM_SetDACTrig(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_DACTRIG_NONE);

 LL_HRTIM_TIM_DisableHalfMode(HRTIM1, LL_HRTIM_TIMER_F);

 LL_HRTIM_TIM_SetInterleavedMode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_INTERLEAVED_MODE_DISABLED);

 LL_HRTIM_TIM_DisableStartOnSync(HRTIM1, LL_HRTIM_TIMER_F);

 LL_HRTIM_TIM_DisableResetOnSync(HRTIM1, LL_HRTIM_TIMER_F);

 LL_HRTIM_TIM_EnablePreload(HRTIM1, LL_HRTIM_TIMER_F);

 LL_HRTIM_TIM_DisableResyncUpdate(HRTIM1, LL_HRTIM_TIMER_F);

 LL_HRTIM_TIM_SetUpdateTrig(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_UPDATETRIG_NONE|LL_HRTIM_UPDATETRIG_RESET);

 LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_RESETTRIG_NONE);

 LL_HRTIM_TIM_DisablePushPullMode(HRTIM1, LL_HRTIM_TIMER_F);

 LL_HRTIM_TIM_DisableDeadTime(HRTIM1, LL_HRTIM_TIMER_F);

 LL_HRTIM_TIM_EnableDLYPRT(HRTIM1, LL_HRTIM_TIMER_F);

 LL_HRTIM_TIM_SetBurstModeOption(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_BURSTMODE_MAINTAINCLOCK);

 LL_HRTIM_ForceUpdate(HRTIM1, LL_HRTIM_TIMER_F);

 LL_HRTIM_TIM_EnableResyncUpdate(HRTIM1, LL_HRTIM_TIMER_F);

 LL_HRTIM_TIM_SetCompare1(HRTIM1, LL_HRTIM_TIMER_F, 0);

 LL_HRTIM_TIM_SetCompareMode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_COMPAREUNIT_2, LL_HRTIM_COMPAREMODE_REGULAR);

 LL_HRTIM_TIM_SetCompare3(HRTIM1, LL_HRTIM_TIMER_F, 0);

 LL_HRTIM_OUT_SetPolarity(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUT_POSITIVE_POLARITY);

 //LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUTPUTSET_TIMPER);

 LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUTPUTRESET_TIMCMP1|LL_HRTIM_OUTPUTRESET_EEV_5);

 LL_HRTIM_OUT_SetIdleMode(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUT_NO_IDLE);

 LL_HRTIM_OUT_SetIdleLevel(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUT_IDLELEVEL_INACTIVE);

 LL_HRTIM_OUT_SetFaultState(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUT_FAULTSTATE_NO_ACTION);

 LL_HRTIM_OUT_SetChopperMode(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUT_CHOPPERMODE_DISABLED);

 LL_HRTIM_OUT_SetPolarity(HRTIM1, LL_HRTIM_OUTPUT_TF2, LL_HRTIM_OUT_POSITIVE_POLARITY);

 // LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF2, LL_HRTIM_OUTPUTSET_TIMPER);

 LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF2, LL_HRTIM_OUTPUTRESET_TIMCMP3|LL_HRTIM_OUTPUTRESET_EEV_3);

 LL_HRTIM_OUT_SetIdleMode(HRTIM1, LL_HRTIM_OUTPUT_TF2, LL_HRTIM_OUT_NO_IDLE);

 LL_HRTIM_OUT_SetIdleLevel(HRTIM1, LL_HRTIM_OUTPUT_TF2, LL_HRTIM_OUT_IDLELEVEL_INACTIVE);

 LL_HRTIM_OUT_SetFaultState(HRTIM1, LL_HRTIM_OUTPUT_TF2, LL_HRTIM_OUT_FAULTSTATE_NO_ACTION);

 LL_HRTIM_OUT_SetChopperMode(HRTIM1, LL_HRTIM_OUTPUT_TF2, LL_HRTIM_OUT_CHOPPERMODE_DISABLED);

 /* USER CODE BEGIN HRTIM1_Init 2 */

 /* USER CODE END HRTIM1_Init 2 */

 LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);

 /**HRTIM1 GPIO Configuration

 PC6  ------> HRTIM1_CHF1

 PC7  ------> HRTIM1_CHF2

 */

 GPIO_InitStruct.Pin = LL_GPIO_PIN_6;

 GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;

 GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;

 GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

 GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;

 GPIO_InitStruct.Alternate = LL_GPIO_AF_13;

 LL_GPIO_Init(GPIOC, &GPIO_InitStruct);

 GPIO_InitStruct.Pin = LL_GPIO_PIN_7;

 GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;

 GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;

 GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

 GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;

 GPIO_InitStruct.Alternate = LL_GPIO_AF_13;

 LL_GPIO_Init(GPIOC, &GPIO_InitStruct);

}

2 REPLIES 2
PKolo.1
Associate II

I haven't used center-aligned mode, but PWM mode of the STM32G474 HRTIM before and I could not get it to produce a 100% duty cycle output either. Maybe there actually is a proper solution, but I would recommend to just do a dirty software fix to force a high output whenever the duty cycle goes above 99%, if your application allows it.

Asantos
Senior

PKolo.1

Thanks for your comment.

Adding the below lines to switch to edge-aligned mode:

LL_HRTIM_TIM_SetCountingMode(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_COUNTING_MODE_UP);

LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUTPUTSET_TIMPER);

It is now possible to reach 100% duty.

if HRTIM1->sTimerxRegs[5].CMP1xR = 2124 (PERIOD -1) duty-cycle is almost 100%.

if HRTIM1->sTimerxRegs[5].CMP1xR = 2125 (PERIOD) duty-cycle goes to zero, strange behavior!

if HRTIM1->sTimerxRegs[5].CMP1xR >= 2126 duty is 100%.

I hope that ST will do a new revision on this HRTIM, even version II has shortcomings compared to other high resolution PWM from other manufacturers.