From 4130ab0212bfbf769215578b79c3db383de479ed Mon Sep 17 00:00:00 2001
From: Luiz Fernando Lavado Villa <lflavado@laas.fr>
Date: Tue, 19 Jul 2022 10:34:57 +0000
Subject: [PATCH] The HRTIM still lacks some functions needed for a fine
 management of the PWM generation. This PR adds several functions.

Deadtime management
The deadtime can now be managed separately from the rising and falling edges.

Phase shifting
The phase of the second leg can now be updated dynamicall

Bug fixes:
Readable Independent mode
The independent mode can now be set as buck or boost instead of true or false, making it more readable.

Extra features:
There is now a board version support for the SPIN board
---
 .../public_api/HardwareConfiguration.cpp      | 49 +++++++++++--
 .../zephyr/public_api/HardwareConfiguration.h | 23 +++++-
 .../zephyr/src/hrtim_configuration.cpp        | 71 +++++++++++++++++--
 .../zephyr/src/hrtim_configuration.h          | 42 +++++++++++
 .../zephyr/public_api/leg.h                   | 12 +++-
 .../src/voltage_mode/hrtim_voltage_mode.c     | 50 +++++++++----
 .../src/voltage_mode/hrtim_voltage_mode.h     | 24 +++++--
 .../src/voltage_mode/owntech_leg_driver.cpp   | 10 +++
 .../src/voltage_mode/owntech_leg_driver.h     | 18 +++--
 9 files changed, 259 insertions(+), 40 deletions(-)

diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.cpp b/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.cpp
index fc0a128..8cf63fc 100644
--- a/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.cpp
+++ b/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.cpp
@@ -60,7 +60,7 @@ HardwareConfiguration hwConfig;
  */
 void HardwareConfiguration::setBoardVersion(hardware_version_t hardware_version)
 {
-	if (hardware_version == v_1_1_2)
+	if (hardware_version == v_1_1_2 || hardware_version == SPIN)
 	{
 		uart_lpuart1_swap_rx_tx();
 	}
@@ -166,14 +166,22 @@ void HardwareConfiguration::initFullBridgeBoostModeCenterAligned()
 	hrtim_init_interleaved_boost_mode_center_aligned();
 }
 
-void HardwareConfiguration::initIndependentMode(bool leg1_buck_mode, bool leg2_buck_mode)
+void HardwareConfiguration::initIndependentMode(hardware_conversion_t leg1_conversion_type, hardware_conversion_t leg2_conversion_type)
 {
-	hrtim_init_independent_mode(leg1_buck_mode, leg2_buck_mode);
+	bool leg1_mode, leg2_mode;
+	if (leg1_conversion_type == buck) leg1_mode = true; else leg1_mode = false;
+	if (leg2_conversion_type == buck) leg2_mode = true; else leg2_mode = false;
+
+	hrtim_init_independent_mode(leg1_mode, leg2_mode);
 }
 
-void HardwareConfiguration::initIndependentModeCenterAligned(bool leg1_buck_mode, bool leg2_buck_mode)
+void HardwareConfiguration::initIndependentModeCenterAligned(hardware_conversion_t leg1_conversion_type, hardware_conversion_t leg2_conversion_type)
 {
-	hrtim_init_independent_mode_center_aligned(leg1_buck_mode, leg2_buck_mode);
+	bool leg1_mode, leg2_mode;
+	if (leg1_conversion_type == buck) leg1_mode = true; else leg1_mode = false;
+	if (leg2_conversion_type == buck) leg2_mode = true; else leg2_mode = false;
+
+	hrtim_init_independent_mode_center_aligned(leg1_mode, leg2_mode);
 }
 
 void HardwareConfiguration::setInterleavedDutyCycle(float32_t duty_cycle)
@@ -196,6 +204,26 @@ void HardwareConfiguration::setLeg2DutyCycle(float32_t duty_cycle)
 	hrtim_leg2_pwm_update(duty_cycle);
 }
 
+void HardwareConfiguration::setLeg1PhaseShift(float32_t phase_shift)
+{
+	hrtim_leg1_phase_shift_update(phase_shift);
+}
+
+void HardwareConfiguration::setLeg2PhaseShift(float32_t phase_shift)
+{
+	hrtim_leg2_phase_shift_update(phase_shift);
+}
+
+void HardwareConfiguration::setLeg1PhaseShiftCenterAligned(float32_t phase_shift)
+{
+	hrtim_leg1_phase_shift_update_center_aligned(phase_shift);
+}
+
+void HardwareConfiguration::setLeg2PhaseShiftCenterAligned(float32_t phase_shift)
+{
+	hrtim_leg2_phase_shift_update_center_aligned(phase_shift);
+}
+
 void HardwareConfiguration::setInterleavedOn()
 {
 	hrtim_start_interleaved();
@@ -287,3 +315,14 @@ void HardwareConfiguration::configureAdcDefaultAllMeasurements()
 {
 	configure_adc_default_all_measurements();
 }
+
+
+void HardwareConfiguration::setLeg1DeadTime(uint16_t rise_ns, uint16_t fall_ns)
+{
+	hrtim_set_dead_time_leg1(rise_ns, fall_ns);
+}
+
+void HardwareConfiguration::setLeg2DeadTime(uint16_t rise_ns, uint16_t fall_ns)
+{
+	hrtim_set_dead_time_leg2(rise_ns, fall_ns);
+}
diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.h b/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.h
index 479e629..1bff9c0 100644
--- a/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.h
+++ b/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.h
@@ -47,9 +47,18 @@ typedef enum
 {
     v_0_0, // No power converter attached, the software is running on Nucleo G474RE
     v_0_9,
-    v_1_1_2
+    v_1_1_2,
+	SPIN
 } hardware_version_t;
 
+/** Switch leg opeation type. 
+ */
+typedef enum
+{
+    buck, // No power converter attached, the software is running on Nucleo G474RE
+    boost
+} hardware_conversion_t;
+
 
 /////
 // Static class definition
@@ -86,13 +95,21 @@ public:
 	static void initFullBridgeBuckModeCenterAligned();
 	static void initFullBridgeBoostMode();
 	static void initFullBridgeBoostModeCenterAligned();
-	static void initIndependentMode(bool leg1_buck_mode, bool leg2_buck_mode);
-	static void initIndependentModeCenterAligned(bool leg1_buck_mode, bool leg2_buck_mode);
+	static void initIndependentMode(hardware_conversion_t leg1_conversion_type, hardware_conversion_t leg2_conversion_type);
+	static void initIndependentModeCenterAligned(hardware_conversion_t leg1_conversion_type, hardware_conversion_t leg2_conversion_type);
 
 	static void setInterleavedDutyCycle(float32_t duty_cycle);
 	static void setFullBridgeDutyCycle(float32_t duty_cycle);
+
 	static void setLeg1DutyCycle(float32_t duty_cycle);
 	static void setLeg2DutyCycle(float32_t duty_cycle);
+	static void setLeg1PhaseShift(float32_t phase_shift);
+	static void setLeg2PhaseShift(float32_t phase_shift);
+	static void setLeg1PhaseShiftCenterAligned(float32_t phase_shift);
+	static void setLeg2PhaseShiftCenterAligned(float32_t phase_shift);
+	static void setLeg1DeadTime(uint16_t rise_ns, uint16_t fall_ns);
+	static void setLeg2DeadTime(uint16_t rise_ns, uint16_t fall_ns);
+
 
 	static void setInterleavedOn();
 	static void setFullBridgeOn();
diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.cpp b/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.cpp
index 521bea9..685782b 100644
--- a/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.cpp
+++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.cpp
@@ -44,6 +44,8 @@
 // Local variables
 static uint16_t pwm_period;
 static uint16_t pwm_phase_shift;
+static uint16_t pwm_phase_shift_leg1;
+static uint16_t pwm_phase_shift_leg2;
 static uint16_t pwm_low_pulse_width;
 static uint16_t pwm_high_pulse_width;
 
@@ -117,7 +119,8 @@ void hrtim_init_independent_mode(bool leg1_buck_mode, bool leg2_buck_mode)
 	}
 
 	pwm_period = leg_period();
-	pwm_phase_shift = pwm_period / 2;
+	pwm_phase_shift_leg1 = 0;
+	pwm_phase_shift_leg2 = pwm_period / 2;
 	pwm_low_pulse_width = pwm_period * LOW_DUTY;
 	pwm_high_pulse_width = pwm_period * HIGH_DUTY;
 }
@@ -240,20 +243,20 @@ void hrtim_leg1_pwm_update(float32_t pwm_duty_cycle)
 	{
 		pwm_duty_cycle = HIGH_DUTY;
 		pwm_pulse_width = pwm_high_pulse_width;
-		leg_set(TIMA, pwm_pulse_width, 0);
+		leg_set(TIMA, pwm_pulse_width, pwm_phase_shift_leg1);
 	}
 
 	else if (pwm_duty_cycle < LOW_DUTY) // SATURATION CONDITIONS TO AVOID DIVERGENCE.
 	{
 		pwm_duty_cycle = LOW_DUTY;
 		pwm_pulse_width = pwm_low_pulse_width;
-		leg_set(TIMA, pwm_pulse_width, 0);
+		leg_set(TIMA, pwm_pulse_width, pwm_phase_shift_leg1);
 	}
 
 	else
 	{
 		pwm_pulse_width = (pwm_duty_cycle * pwm_period);
-		leg_set(TIMA, pwm_pulse_width, 0);
+		leg_set(TIMA, pwm_pulse_width, pwm_phase_shift_leg1);
 	}
 }
 
@@ -271,23 +274,60 @@ void hrtim_leg2_pwm_update(float32_t pwm_duty_cycle)
 	{
 		pwm_duty_cycle = HIGH_DUTY;
 		pwm_pulse_width = pwm_high_pulse_width;
-		leg_set(TIMB, pwm_pulse_width, pwm_phase_shift);
+		leg_set(TIMB, pwm_pulse_width, pwm_phase_shift_leg2);
 	}
 
 	else if (pwm_duty_cycle < LOW_DUTY) // SATURATION CONDITIONS TO AVOID DIVERGENCE.
 	{
 		pwm_duty_cycle = LOW_DUTY;
 		pwm_pulse_width = pwm_low_pulse_width;
-		leg_set(TIMB, pwm_pulse_width, pwm_phase_shift);
+		leg_set(TIMB, pwm_pulse_width, pwm_phase_shift_leg2);
 	}
 
 	else
 	{
 		pwm_pulse_width = (pwm_duty_cycle * pwm_period);
-		leg_set(TIMB, pwm_pulse_width, pwm_phase_shift);
+		leg_set(TIMB, pwm_pulse_width, pwm_phase_shift_leg2);
 	}
 }
 
+/**
+ * This function updates the phase shift between leg 1 and hrtim master
+ */
+void hrtim_leg1_phase_shift_update(float32_t phase_shift)
+{
+	pwm_phase_shift_leg1 = (uint16_t)(pwm_period * (phase_shift/360) );
+}
+
+
+/**
+ * This function updates the phase shift between leg 2 and hrtim master
+ */
+void hrtim_leg2_phase_shift_update(float32_t phase_shift)
+{
+	pwm_phase_shift_leg2 = (uint16_t)(pwm_period * (phase_shift/360) );
+}
+
+/**
+ * This function updates the phase shift between leg 1 and hrtim master for the center aligned application.
+ * In center aligned, the master timer has a frequency 2 times higher than the timers.
+ */
+void hrtim_leg1_phase_shift_update_center_aligned(float32_t phase_shift)
+{
+	pwm_phase_shift_leg1 = (uint16_t)(2*pwm_period * (phase_shift/360) );
+}
+
+
+/**
+ * This function updates the phase shift between leg 2 and hrtim master for the center aligned application
+ * In center aligned, the master timer has a frequency 2 times higher than the timers.
+ */
+void hrtim_leg2_phase_shift_update_center_aligned(float32_t phase_shift)
+{
+	pwm_phase_shift_leg2 = (uint16_t)(2*pwm_period * (phase_shift/360) );
+}
+
+
 /**
  * This stops the converter by putting both timing
  * units outputs low
@@ -343,3 +383,20 @@ void set_adc_trig_interleaved(uint16_t new_trig)
 {
 	hrtim_update_adc_trig_interleaved(new_trig);
 }
+
+
+/**
+ * This updates the dead time of the leg 1
+
+ */
+void hrtim_set_dead_time_leg1(uint16_t rise_ns, uint16_t fall_ns)
+{
+	leg_set_dt(TIMA, rise_ns, fall_ns);
+}
+/**
+ * This updates the dead time of the leg 2
+ */
+void hrtim_set_dead_time_leg2(uint16_t rise_ns, uint16_t fall_ns)
+{
+	leg_set_dt(TIMB, rise_ns, fall_ns);
+}
diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.h b/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.h
index 83614f5..02df682 100644
--- a/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.h
+++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.h
@@ -107,6 +107,38 @@ void hrtim_leg1_pwm_update(float32_t duty_cycle);
 
 void hrtim_leg2_pwm_update(float32_t duty_cycle);
 
+/**
+ * @brief     This function updates the phase shift between the leg 1 and the master hrtim
+ *
+ * @param[in] phase_shift    floating point phase shift of leg_1 in degrees
+ */
+
+void hrtim_leg1_phase_shift_update(float32_t phase_shift);
+/**
+ * @brief     This function updates the phase shift between the leg 1 and the master hrtim
+ *
+ * @param[in] phase_shift    floating point phase shift of leg_2 in degrees
+ */
+
+void hrtim_leg2_phase_shift_update(float32_t phase_shift);
+
+/**
+ * @brief     This function updates the phase shift between the leg 1 and the master hrtim for the center aligned
+ *
+ * @param[in] phase_shift    floating point phase shift of leg_1 in degrees
+ */
+
+void hrtim_leg1_phase_shift_update_center_aligned(float32_t phase_shift);
+/**
+ * @brief     This function updates the phase shift between the leg 1 and the master hrtim for the center aligned
+ *
+ * @param[in] phase_shift    floating point phase shift of leg_2 in degrees
+ */
+
+void hrtim_leg2_phase_shift_update_center_aligned(float32_t phase_shift);
+
+
+
 /**
  * @brief This function stops the converter by putting both timing
  * units outputs low
@@ -145,5 +177,15 @@ void hrtim_start_leg2();
  */
 void set_adc_trig_interleaved(uint16_t new_trig);
 
+/**
+ * @brief This function sets the dead time of the leg 1
+ */
+void hrtim_set_dead_time_leg1(uint16_t rise_ns, uint16_t fall_ns);
+
+/**
+ * @brief This function sets the dead time of the leg 2
+ */
+void hrtim_set_dead_time_leg2(uint16_t rise_ns, uint16_t fall_ns);
+
 
 #endif // HRTIM_CONFIGURATION_H_
diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/leg.h b/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/leg.h
index 71bcdd1..f3978c5 100644
--- a/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/leg.h
+++ b/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/leg.h
@@ -55,7 +55,8 @@ extern "C" {
 typedef struct {
     hrtim_t hrtim;              /**< HRTIM device */
     hrtim_tu_t timing_unit;     /**< Timing unit */
-    uint16_t dead_time;         /**< Dead time */
+    uint16_t rise_dead_time;    /**< Rising Edge Dead time */
+    uint16_t fall_dead_time;    /**< Falling Edge Dead time */
     uint16_t pulse_width;       /**< Pulse width */
 } leg_conf_t;
 
@@ -88,6 +89,15 @@ uint16_t leg_init_center_aligned(bool leg1_upper_switch_convention, bool leg2_up
  */
 void leg_set(hrtim_tu_t timing_unit, uint16_t pulse_width, uint16_t phase_shift);
 
+/**
+ * @brief   Set the dead time for a given leg device
+ *
+ * @param[in]   timing_unit     timing_unit from TIMA to TIMF
+ * @param[in]   rise_ns         rising edge dead time to set in nano seconds
+ * @param[in]   fall_ns         falling edge dead time to set in nano seconds
+ */
+void leg_set_dt(hrtim_tu_t timing_unit, uint16_t rise_ns, uint16_t fall_ns);
+
 /**
  * @brief   Stop the leg (its 2 outputs goes low)
  *
diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/hrtim_voltage_mode.c b/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/hrtim_voltage_mode.c
index e54cd5c..a50c04a 100644
--- a/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/hrtim_voltage_mode.c
+++ b/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/hrtim_voltage_mode.c
@@ -163,20 +163,20 @@ static inline uint32_t _period_ckpsc(hrtim_t hrtim, uint32_t freq,
     return frequency;
 }
 
-uint16_t hrtim_init(hrtim_t hrtim, uint32_t *freq, uint16_t dt, uint8_t leg1_upper_switch_convention, uint8_t leg2_upper_switch_convention)
+uint16_t hrtim_init(hrtim_t hrtim, uint32_t *freq, uint16_t dead_time_ns, uint8_t leg1_upper_switch_convention, uint8_t leg2_upper_switch_convention)
 {
     /* Master timer initialization */
     uint16_t period = hrtim_init_master(hrtim, freq);
 
     /* Timer A initialization for leg 1 */
     hrtim_init_tu(hrtim, TIMA, freq, Lft_aligned);
-    hrtim_pwm_dt(hrtim, TIMA, dt); // Set the dead time. Note: this must be done before enable counter
+    hrtim_pwm_dt(hrtim, TIMA, dead_time_ns, dead_time_ns); // Set the dead time. Note: this must be done before enable counter
     hrtim_cnt_en(hrtim, TIMA); // Enable counter 
     hrtim_rst_evt_en(hrtim, TIMA, LL_HRTIM_RESETTRIG_MASTER_PER); // We synchronize the Timer A with the master timer, with a reset on period event
 
     /* Timer B initialization for leg 2 */
     hrtim_init_tu(hrtim, TIMB, freq, Lft_aligned);
-    hrtim_pwm_dt(hrtim, TIMB, dt);  // Set the dead time. Note: this must be done before enable counter
+    hrtim_pwm_dt(hrtim, TIMB, dead_time_ns, dead_time_ns);  // Set the dead time. Note: this must be done before enable counter
     hrtim_cnt_en(hrtim, TIMB);  // Enable the counter
     hrtim_rst_evt_en(hrtim, TIMB, LL_HRTIM_RESETTRIG_MASTER_PER); // We synchronize the Timer B with the master timer, with a reset on period event
 
@@ -187,6 +187,14 @@ uint16_t hrtim_init(hrtim_t hrtim, uint32_t *freq, uint16_t dt, uint8_t leg1_upp
     return period;
 }
 
+void hrtim_update_dead_time(hrtim_t hrtim, hrtim_tu_t tu, uint16_t rise_ns, uint16_t fall_ns)
+{
+    hrtim_cnt_dis(hrtim, tu);    //Disable the timing unit counter
+    hrtim_pwm_dt(hrtim, tu, rise_ns, fall_ns); // Set the dead time. Note: this must be done before enable counter
+    hrtim_cnt_en(hrtim, tu);     // Enable counter 
+
+}
+
 uint16_t hrtim_init_updwn(hrtim_t hrtim, uint32_t *freq, uint16_t dt, uint8_t leg1_upper_switch_convention, uint8_t leg2_upper_switch_convention)
 {
     /* Master timer and timing unit frequency initialization */
@@ -195,13 +203,13 @@ uint16_t hrtim_init_updwn(hrtim_t hrtim, uint32_t *freq, uint16_t dt, uint8_t le
 
     /* Timer A initialization for leg 1 */
     hrtim_init_tu(hrtim, TIMA, &freq_tu, UpDwn);
-    hrtim_pwm_dt(hrtim, TIMA, dt); // Set the dead time. Note: this must be done before enable counter
+    hrtim_pwm_dt(hrtim, TIMA, dt, dt); // Set the dead time. Note: this must be done before enable counter
     hrtim_cnt_en(hrtim, TIMA); // Enable counter 
     hrtim_rst_evt_en(hrtim, TIMA, LL_HRTIM_RESETTRIG_MASTER_PER); // We synchronize the Timer A with the master timer, with a reset on period event
 
     /* Timer B initialization for leg 2 */
     hrtim_init_tu(hrtim, TIMB, &freq_tu, UpDwn);
-    hrtim_pwm_dt(hrtim, TIMB, dt);  // Set the dead time. Note: this must be done before enable counter
+    hrtim_pwm_dt(hrtim, TIMB, dt, dt);  // Set the dead time. Note: this must be done before enable counter
     hrtim_cnt_en(hrtim, TIMB);  // Enable the counter
     hrtim_rst_evt_en(hrtim, TIMB, LL_HRTIM_RESETTRIG_MASTER_PER); // We synchronize the Timer B with the master timer, with a reset on period event
 
@@ -782,9 +790,10 @@ void hrtim_out_dis(hrtim_t hrtim, hrtim_tu_t tu, hrtim_out_t out)
 /* Note : The dead time is configured centered by default,
  * there are no options available to modify this, so the dead time
  * must be taken into account when calculating the PWM duty cycle */
-void hrtim_pwm_dt(hrtim_t hrtim, hrtim_tu_t tu, uint16_t ns)
+void hrtim_pwm_dt(hrtim_t hrtim, hrtim_tu_t tu, uint16_t rise_ns, uint16_t fall_ns)
 {
-    uint32_t ps = ns * 1000;
+    uint32_t rise_ps = rise_ns * 1000;
+    uint32_t fall_ps = fall_ns * 1000;
     /* t_dtg = (2^dtpsc) * (t_hrtim / 8)
      *       = (2^dtpsc) / (f_hrtim * 8) */
     #if defined(CONFIG_SOC_SERIES_STM32F3X)
@@ -797,21 +806,34 @@ void hrtim_pwm_dt(hrtim_t hrtim, hrtim_tu_t tu, uint16_t ns)
 
     uint8_t dtpsc = 0; // Deadtime clock prescaler set at xx
     uint32_t t_dtg_ps = (1 << dtpsc) * 1000000 / ((f_hrtim * 8) / 1000000); // intermediate gain for dead time calculation
-    uint16_t dt = ps / t_dtg_ps; // calculate the register value based on desired deadtime in picoseconds
-    while (dt > 511 && dtpsc < 7) {
+    uint16_t rise_dt = rise_ps / t_dtg_ps; // calculate the register value based on desired deadtime in picoseconds
+    
+    while (rise_dt > 511 && dtpsc < 7) {
         dtpsc++;
         t_dtg_ps = (1 << dtpsc) * 1000000 / ((f_hrtim * 8) / 1000000);
-        dt = ps / t_dtg_ps;
+        rise_dt = rise_ps / t_dtg_ps;
     }
-    if (dt > 511) {
-        dt = 511;
+    if (rise_dt > 511) {
+        rise_dt = 511;
     }
+
+    uint16_t fall_dt = fall_ps / t_dtg_ps; // calculate the register value based on desired deadtime in picoseconds
     
+    while (fall_dt > 511 && dtpsc < 7) {
+        dtpsc++;
+        t_dtg_ps = (1 << dtpsc) * 1000000 / ((f_hrtim * 8) / 1000000);
+        fall_dt = fall_ps / t_dtg_ps;
+    }
+    if (fall_dt > 511) {
+        fall_dt = 511;
+    }
+
+
     LL_HRTIM_DT_SetPrescaler(HRTIM1, tu, dtpsc ); // Deadtime clock prescaler
 
-    LL_HRTIM_DT_SetFallingValue(HRTIM1, tu, dt); // Deadtime falling edge value
+    LL_HRTIM_DT_SetFallingValue(HRTIM1, tu, fall_dt); // Deadtime falling edge value
 
-    LL_HRTIM_DT_SetRisingValue(HRTIM1, tu, dt); // Deadtime rising edge value
+    LL_HRTIM_DT_SetRisingValue(HRTIM1, tu, rise_dt); // Deadtime rising edge value
 
     // LL_HRTIM_DT_SetFallingSign(hrtim, tu, LL_HRTIM_DT_FALLING_NEGATIVE);  // Change the behavior of the deadtime insertion by overlapping the signals (negative falling edge)
 
diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/hrtim_voltage_mode.h b/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/hrtim_voltage_mode.h
index 8bb51c3..f0977ac 100644
--- a/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/hrtim_voltage_mode.h
+++ b/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/hrtim_voltage_mode.h
@@ -131,7 +131,7 @@ typedef enum {
  * @return              actual HRTIM resolution on success
  * @return              0 on error
  */
-uint16_t hrtim_init(hrtim_t dev, uint32_t *freq, uint16_t dt, uint8_t leg1_upper_switch_convention, uint8_t leg2_upper_switch_convention);
+uint16_t hrtim_init(hrtim_t dev, uint32_t *freq, uint16_t dead_time_ns, uint8_t leg1_upper_switch_convention, uint8_t leg2_upper_switch_convention);
 
 /**
  * @brief   Initialize an HRTIM device and all these timing units for
@@ -139,7 +139,7 @@ uint16_t hrtim_init(hrtim_t dev, uint32_t *freq, uint16_t dt, uint8_t leg1_upper
  *
  * @param[in] dev      HRTIM device to initialize
  * @param[inout] freq  HRTIM frequency in Hz
- * @param[in] dt       Desired dead time in ns
+ * @param[in] dead_time_ns       Desired dead time in ns
  * @param[in] leg1_upper_switch_convention   Choice of the switch convention for leg 1, can be one of the following values:
  *            @arg @ref True (Buck mode)
  *            @arg @ref False (Boost mode)
@@ -151,6 +151,21 @@ uint16_t hrtim_init(hrtim_t dev, uint32_t *freq, uint16_t dt, uint8_t leg1_upper
  */
 uint16_t hrtim_init_updwn(hrtim_t dev, uint32_t *freq, uint16_t dt, uint8_t leg1_upper_switch_convention, uint8_t leg2_upper_switch_convention);
 
+/**
+ * @brief   Updates the duty cycle
+ *
+ * @param[in] dev       HRTIM device to be used
+ * @param[in] tu        Timing unit to updated, can be one of the following values:
+ *            @arg @ref TIMA
+ *            @arg @ref TIMB
+ *            @arg @ref TIMC
+ *            @arg @ref TIMD
+ *            @arg @ref TIME
+ *            @arg @ref TIMF*
+ * @param[in] rise_ns       Rising edge dead time in ns
+ * @param[in] fall_ns       Falling edge dead time in ns
+ */
+void hrtim_update_dead_time(hrtim_t dev, hrtim_tu_t tu, uint16_t rise_ns, uint16_t fall_ns);
 
 /**
  * @brief   Initialize an HRTIM device master timer
@@ -759,9 +774,10 @@ void hrtim_out_dis(hrtim_t dev, hrtim_tu_t tu, hrtim_out_t out);
  *            @arg @ref TIMD
  *            @arg @ref TIME
  *            @arg @ref TIMF          
- * @param[in] ns        The desired dead time in nano second
+ * @param[in] rise_ns        The desired dead time of the rising edge in nano second
+ * @param[in] fall_ns        The desired dead time of the falling edge in nano second
  */
-void hrtim_pwm_dt(hrtim_t dev, hrtim_tu_t tu, uint16_t ns);
+void hrtim_pwm_dt(hrtim_t dev, hrtim_tu_t tu, uint16_t rise_ns, uint16_t fall_ns);
 
 /**
  * @brief   Set the HRTIM event postsaler. Postscaler ratio indicates
diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/owntech_leg_driver.cpp b/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/owntech_leg_driver.cpp
index f646e11..7a11474 100644
--- a/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/owntech_leg_driver.cpp
+++ b/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/owntech_leg_driver.cpp
@@ -135,6 +135,16 @@ void leg_set(hrtim_tu_t timing_unit, uint16_t pulse_width, uint16_t phase_shift)
     leg_conf[_TU_num(timing_unit)].pulse_width = pulse_width;
 }
 
+void leg_set_dt(hrtim_tu_t timing_unit, uint16_t rise_ns, uint16_t fall_ns)
+{
+    //addition of the dead time for the rectification of the centered dead time configuration cf:hrtim_pwm_dt()
+    hrtim_pwm_dt(leg_conf[_TU_num(timing_unit)].hrtim, leg_conf[_TU_num(timing_unit)].timing_unit, rise_ns, fall_ns);
+
+    /* save the pulse_width */
+    leg_conf[_TU_num(timing_unit)].rise_dead_time = rise_ns;
+    leg_conf[_TU_num(timing_unit)].fall_dead_time = fall_ns;
+}
+
 void leg_stop(hrtim_tu_t timing_unit)
 {
     hrtim_out_dis(leg_conf[_TU_num(timing_unit)].hrtim, leg_conf[_TU_num(timing_unit)].timing_unit, OUT1);
diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/owntech_leg_driver.h b/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/owntech_leg_driver.h
index 584cf1e..9e409b8 100644
--- a/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/owntech_leg_driver.h
+++ b/zephyr/modules/owntech_hrtim_driver/zephyr/src/voltage_mode/owntech_leg_driver.h
@@ -39,33 +39,39 @@ static leg_conf_t leg_config[] = {
     {
         .hrtim = 0,
         .timing_unit = TIMA,
-        .dead_time = LEG_DEFAULT_DT
+        .rise_dead_time = LEG_DEFAULT_DT,
+        .fall_dead_time = LEG_DEFAULT_DT
     },
     {
         .hrtim = 0,
         .timing_unit = TIMB,
-        .dead_time = LEG_DEFAULT_DT
+        .rise_dead_time = LEG_DEFAULT_DT,
+        .fall_dead_time = LEG_DEFAULT_DT
     },
     {
         .hrtim = 0,
         .timing_unit = TIMC,
-        .dead_time = LEG_DEFAULT_DT
+        .rise_dead_time = LEG_DEFAULT_DT,
+        .fall_dead_time = LEG_DEFAULT_DT
     },
     {
         .hrtim = 0,
         .timing_unit = TIMD,
-        .dead_time = LEG_DEFAULT_DT
+        .rise_dead_time = LEG_DEFAULT_DT,
+        .fall_dead_time = LEG_DEFAULT_DT
     },
     {
         .hrtim = 0,
         .timing_unit = TIME,
-        .dead_time = LEG_DEFAULT_DT
+        .rise_dead_time = LEG_DEFAULT_DT,
+        .fall_dead_time = LEG_DEFAULT_DT
     },
 #if defined(HRTIM_MCR_TFCEN)
     {
         .hrtim = 0,
         .timing_unit = TIMF,
-        .dead_time = LEG_DEFAULT_DT
+        .rise_dead_time = LEG_DEFAULT_DT,
+        .fall_dead_time = LEG_DEFAULT_DT
     },
 #endif
 };
-- 
GitLab