Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions zephyr/modules/owntech_hrtim_driver/zephyr/public_api/hrtim.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,30 @@ void hrtim_init_default_all();
*/
uint16_t hrtim_tu_init(hrtim_tu_number_t tu_number);

/**
* @brief Deinitializes one local timing unit
*
* This function disables both HRTIM outputs, stops the timing unit counter,
* clears the output/reset/ADC trigger configuration, and marks only this
* timing unit as reusable by hrtim_tu_init(). It does not reset the HRTIM
* master timer, the global frequency/min-frequency state, or fully
* deconfigure the timing unit GPIO pins.
*
* @param[in] tu_number Timing unit number:
* `PWMA`, `PWMB`, `PWMC`, `PWMD`, `PWME`, `PWMF`
*/
void hrtim_tu_deinit(hrtim_tu_number_t tu_number);

/**
* @brief Globally resets and deinitializes the whole HRTIM peripheral
*
* This function disables all HRTIM outputs, deinitializes all timing units,
* disables the HRTIM interrupt/burst mode and master timer, resets the
* peripheral registers, and restores the global software state so a later
* initialization can run the master setup and choose a new prescaler.
*/
void hrtim_deinit(void);

/**
* @brief Returns if the timer was initialized with default value or not
* @param[in] tu_number Timing unit number:
Expand Down Expand Up @@ -479,6 +503,10 @@ hrtim_adc_edgetrigger_t hrtim_adc_rollover_get(hrtim_tu_number_t tu_number);

/**
* @brief Configures interrupt on repetition counter for the chosen timing unit
*
* The last configured callback, repetition counter, and timing unit are saved
* so a full HRTIM deinit/reinit can restore the periodic event configuration.
*
* @param tu_src timing unit which will be the source for the ISR:
* `MSTR`, `TIMA`, `TIMB`, `TIMC`, `TIMD`, `TIME`, `TIMF`
* @param repetition value between 1 and 256 for the repetition counter:
Expand All @@ -494,13 +522,15 @@ void hrtim_PeriodicEvent_configure(hrtim_tu_t tu,
/**
* @brief Enables interrupt on repetition counter for the chosen timing unit.
* The periodic event configuration must have been done previously.
* The enabled state is saved for restoration after a full HRTIM reinit.
* @param tu_src timing unit which will be the source for the ISR:
* `MSTR`, `TIMA`, `TIMB`, `TIMC`, `TIMD`, `TIME`, `TIMF`
*/
void hrtim_PeriodicEvent_en(hrtim_tu_t tu);

/**
* @brief Disables interrupt on repetition counter for the chosen timing unit
* and saves the periodic event as disabled.
* @param tu_src timing unit which will be the source for the ISR:
* `MSTR`, `TIMA`, `TIMB`, `TIMC`, `TIMD`, `TIME`, `TIMF`
*/
Expand Down
174 changes: 172 additions & 2 deletions zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ static uint32_t HRTIM_MINIM_FREQUENCY = TU_DEFAULT_FREQ;
/** @brief User callback for ISR */
static hrtim_callback_t user_callback = NULL;

/** @brief Last configured periodic-event callback */
static hrtim_callback_t saved_periodic_event_callback = NULL;
/** @brief Last configured periodic-event repetition counter */
static uint32_t saved_periodic_event_repetition = 0;
/** @brief Last configured periodic-event timer */
static hrtim_tu_t saved_periodic_event_tu = MSTR;
/** @brief Saved periodic-event enable state */
static bool saved_periodic_event_enabled = false;

/* Default values to initialize all the timer */

/** @brief Listing all timing units, TIMA to TIMF */
Expand Down Expand Up @@ -475,6 +484,8 @@ void _CM_init_EEV(void)
*
* - Flags the unit as active in the configuration structure.
*
* - Restores the saved periodic-event configuration, if one exists.
*
*/
void _init_master()
{
Expand Down Expand Up @@ -512,6 +523,19 @@ void _init_master()
LL_HRTIM_TIM_CounterEnable(HRTIM1, LL_HRTIM_TIMER_MASTER);

timerMaster.pwm_conf.unit_on = UNIT_ON;

if ((saved_periodic_event_callback != NULL) &&
(saved_periodic_event_repetition > 0))
{
hrtim_PeriodicEvent_configure(saved_periodic_event_tu,
saved_periodic_event_repetition,
saved_periodic_event_callback);

if (saved_periodic_event_enabled == true)
{
hrtim_PeriodicEvent_en(saved_periodic_event_tu);
}
}
}

/* Public functions */
Expand Down Expand Up @@ -746,6 +770,103 @@ uint16_t hrtim_tu_init(hrtim_tu_number_t tu_number)
return tu_channel[tu_number]->pwm_conf.period;
}

void hrtim_tu_deinit(hrtim_tu_number_t tu_number)
{
hrtim_tu_t tu = tu_channel[tu_number]->pwm_conf.pwm_tu;

/* Local timing-unit deinit only.*/
hrtim_out_dis(tu_number);
hrtim_adc_trigger_dis(tu_number);
hrtim_cnt_dis(tu_number);

LL_HRTIM_TIM_SetResetTrig(HRTIM1, tu, LL_HRTIM_RESETTRIG_NONE);
LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1,
tu_channel[tu_number]->gpio_conf.OUT_H,
LL_HRTIM_OUTPUTSET_NONE);
LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1,
tu_channel[tu_number]->gpio_conf.OUT_H,
LL_HRTIM_OUTPUTRESET_NONE);
LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1,
tu_channel[tu_number]->gpio_conf.OUT_L,
LL_HRTIM_OUTPUTSET_NONE);
LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1,
tu_channel[tu_number]->gpio_conf.OUT_L,
LL_HRTIM_OUTPUTRESET_NONE);
LL_HRTIM_DisableSwapOutputs(HRTIM1, tu);

LL_HRTIM_TIM_SetCompare1(HRTIM1, tu, 0);
LL_HRTIM_TIM_SetCompare2(HRTIM1, tu, 0);
LL_HRTIM_TIM_SetCompare3(HRTIM1, tu, 0);
LL_HRTIM_TIM_SetCompare4(HRTIM1, tu, 0);

tu_channel[tu_number]->pwm_conf.duty_cycle = 0;
tu_channel[tu_number]->pwm_conf.duty_swap = false;
tu_channel[tu_number]->phase_shift.value = 0;
tu_channel[tu_number]->comp_usage.cmp1 = FREE;
tu_channel[tu_number]->comp_usage.cmp1_value = 0;
tu_channel[tu_number]->comp_usage.cmp2 = FREE;
tu_channel[tu_number]->comp_usage.cmp2_value = 0;
tu_channel[tu_number]->comp_usage.cmp3 = FREE;
tu_channel[tu_number]->comp_usage.cmp3_value = 0;
tu_channel[tu_number]->comp_usage.cmp4 = FREE;
tu_channel[tu_number]->comp_usage.cmp4_value = 0;
tu_channel[tu_number]->pwm_conf.unit_on = UNIT_OFF;
}

void hrtim_deinit(void)
{
/* Global HRTIM reset/deinit. */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_HRTIM1);
__DSB();

irq_disable(HRTIM_IRQ_NUMBER);
user_callback = NULL;

for (uint8_t tu_count = 0; tu_count < HRTIM_CHANNELS; tu_count++)
{
hrtim_out_dis(tu_count);
}

hrtim_burst_dis();

for (uint8_t tu_count = 0; tu_count < HRTIM_CHANNELS; tu_count++)
{
hrtim_tu_deinit(tu_count);
tu_channel[tu_count]->pwm_conf.frequency = TU_DEFAULT_FREQ;
tu_channel[tu_count]->pwm_conf.min_frequency = TU_DEFAULT_FREQ;
}

LL_HRTIM_DisableIT_REP(HRTIM1, LL_HRTIM_TIMER_MASTER);
LL_HRTIM_DisableIT_SYNC(HRTIM1);
LL_HRTIM_TIM_CounterDisable(HRTIM1, LL_HRTIM_TIMER_MASTER);

LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_HRTIM1);
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_HRTIM1);
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_HRTIM1);

HRTIM_MINIM_FREQUENCY = TU_DEFAULT_FREQ;

timerMaster.pwm_conf.frequency = TU_DEFAULT_FREQ;
timerMaster.pwm_conf.min_frequency = TU_DEFAULT_FREQ;
timerMaster.pwm_conf.period = TU_DEFAULT_PERIOD;
timerMaster.pwm_conf.ckpsc = 0;
timerMaster.pwm_conf.duty_cycle = 0;
timerMaster.pwm_conf.duty_swap = false;
timerMaster.pwm_conf.unit_on = UNIT_OFF;

timerMaster.comp_usage.cmp1 = FREE;
timerMaster.comp_usage.cmp1_value = 0;
timerMaster.comp_usage.cmp2 = FREE;
timerMaster.comp_usage.cmp2_value = 0;
timerMaster.comp_usage.cmp3 = FREE;
timerMaster.comp_usage.cmp3_value = 0;
timerMaster.comp_usage.cmp4 = FREE;
timerMaster.comp_usage.cmp4_value = 0;
timerMaster.phase_shift.value = 0;
timerMaster.phase_shift.compare_tu = MSTR;
timerMaster.phase_shift.reset_trig = MSTR_PER;
}

hrtim_tu_ON_OFF_t hrtim_get_status(hrtim_tu_number_t tu_number)
{
return tu_channel[tu_number]->pwm_conf.unit_on;
Expand Down Expand Up @@ -1424,8 +1545,19 @@ hrtim_adc_edgetrigger_t hrtim_adc_rollover_get(hrtim_tu_number_t tu_number)
void hrtim_PeriodicEvent_configure(hrtim_tu_t tu, uint32_t repetition,
hrtim_callback_t callback)
{
/* Memorize user callback */
user_callback = callback;
/* Save the last configured event so it can be restored after HRTIM reset. */
saved_periodic_event_callback = callback;
saved_periodic_event_repetition = repetition;
saved_periodic_event_tu = tu;

if (timerMaster.pwm_conf.unit_on == UNIT_OFF)
{
user_callback = NULL;
return;
}

/* Active callback used by the ISR while the periodic event is enabled. */
user_callback = saved_periodic_event_enabled == true ? callback : NULL;

/* Set repetition counter to repetition-1 so that an event
* is triggered every "repetition" number of periods.
Expand All @@ -1435,6 +1567,16 @@ void hrtim_PeriodicEvent_configure(hrtim_tu_t tu, uint32_t repetition,

void hrtim_PeriodicEvent_en(hrtim_tu_t tu)
{
saved_periodic_event_enabled = true;

if (timerMaster.pwm_conf.unit_on == UNIT_OFF)
{
user_callback = NULL;
return;
}

user_callback = saved_periodic_event_callback;

if (LL_HRTIM_GetSyncInSrc(HRTIM1) == LL_HRTIM_SYNCIN_SRC_NONE)
{
/* Enabling the interrupt on repetition counter event*/
Expand All @@ -1459,13 +1601,31 @@ void hrtim_PeriodicEvent_en(hrtim_tu_t tu)

void hrtim_PeriodicEvent_dis(hrtim_tu_t tu)
{
saved_periodic_event_enabled = false;

irq_disable(HRTIM_IRQ_NUMBER);
user_callback = NULL;

if (timerMaster.pwm_conf.unit_on == UNIT_OFF)
{
return;
}

/* Disabling the interrupt on repetition counter event */
LL_HRTIM_DisableIT_REP(HRTIM1, tu);
LL_HRTIM_DisableIT_SYNC(HRTIM1);
}

void hrtim_PeriodicEvent_SetRep(hrtim_tu_t tu, uint32_t repetition)
{
saved_periodic_event_repetition = repetition;
saved_periodic_event_tu = tu;

if (timerMaster.pwm_conf.unit_on == UNIT_OFF)
{
return;
}

/* Set repetition counter to repetition-1 so that an event
* is triggered every "repetition" number of periods.
*/
Expand All @@ -1474,6 +1634,16 @@ void hrtim_PeriodicEvent_SetRep(hrtim_tu_t tu, uint32_t repetition)

uint32_t hrtim_PeriodicEvent_GetRep(hrtim_tu_t tu)
{
if (timerMaster.pwm_conf.unit_on == UNIT_OFF)
{
if (tu == saved_periodic_event_tu)
{
return saved_periodic_event_repetition;
}

return 0;
}

return LL_HRTIM_TIM_GetRepetition(HRTIM1, tu) + 1;
}

Expand Down
19 changes: 18 additions & 1 deletion zephyr/modules/owntech_spin_api/zephyr/src/PwmHAL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,23 @@ void PwmHAL::initUnit(hrtim_tu_number_t pwmX)
period[pwmX] = hrtim_tu_init(pwmX);
}

void PwmHAL::deInitUnit(hrtim_tu_number_t pwmX)
{
hrtim_tu_deinit(pwmX);
period[pwmX] = 0;
}

void PwmHAL::deInit()
{
hrtim_deinit();

for (uint8_t channel = 0; channel < HRTIM_CHANNELS; channel++)
{
period[channel] = 0;
swap_state[channel] = false;
}
}

void PwmHAL::startDualOutput(hrtim_tu_number_t pwmX)
{
hrtim_out_en(pwmX);
Expand Down Expand Up @@ -545,4 +562,4 @@ void PwmHAL::stopBurstMode()
void PwmHAL::deInitBurstMode()
{
hrtim_burst_dis();
}
}
20 changes: 20 additions & 0 deletions zephyr/modules/owntech_spin_api/zephyr/src/PwmHAL.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,26 @@ class PwmHAL
*/
void initUnit(hrtim_tu_number_t pwmX);

/**
* @brief This function deinitializes a timing unit
*
* @param[in] pwmX PWM Unit: `PWMA`,`PWMB`,`PWMC`,`PWMD`,`PWME`,`PWMF`
*
* @warning Stop power conversion before calling this function. Use
* deInit() instead when changing the HRTIM prescaler.
*/
void deInitUnit(hrtim_tu_number_t pwmX);

/**
* @brief This function deinitializes the HRTIM peripheral
*
* Use this before reconfiguring the PWM frequency range when the new
* range requires a different HRTIM prescaler.
*
* @warning Stop power conversion before calling this function.
*/
void deInit();

/**
* @brief This function starts both outputs of the selected HRTIM channel
*
Expand Down
Loading