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 1beb3187c1cd04d4af77474572494a27b61e05d0..2c9427593335b2da260469dc81b53c98bcdfd9fa 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.cpp +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.cpp @@ -289,6 +289,27 @@ void HardwareConfiguration::setLeg2PhaseShiftCenterAligned(float32_t phase_shift hrtim_leg2_phase_shift_update_center_aligned(phase_shift); } + +void HardwareConfiguration::setHrtimFrequency(uint32_t frequency_Hz) +{ + hrtim_set_frequency(frequency_Hz); +} + +uint32_t HardwareConfiguration::getHrtimFrequency() +{ + return hrtim_get_frequency(); +} + +void HardwareConfiguration::setHrtimMinDutyCycle(float32_t duty_cycle) +{ + hrtim_set_min_duty_cycle(duty_cycle); +} + +void HardwareConfiguration::setHrtimMaxDutyCycle(float32_t duty_cycle) +{ + hrtim_set_max_duty_cycle(duty_cycle); +} + void HardwareConfiguration::setInterleavedOn() { power_driver_interleaved_on(); 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 f7006e037cee78bd4517606fbf2f11330c09a75f..6272e61ba4ff3cc70911f4532893fdf45ebc21be 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.h +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.h @@ -120,6 +120,10 @@ public: static void setLeg1DeadTime(uint16_t rise_ns, uint16_t fall_ns); static void setLeg2DeadTime(uint16_t rise_ns, uint16_t fall_ns); + static void setHrtimFrequency(uint32_t frequency_Hz); + static uint32_t getHrtimFrequency(); + static void setHrtimMinDutyCycle(float32_t duty_cycle); + static void setHrtimMaxDutyCycle(float32_t duty_cycle); static void setInterleavedOn(); static void setFullBridgeBuckOn(); 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 42d50e79954ebfa2cdaa4b1de58506699d4b5af7..09ac01276de0e27a3e7afe3a76e9ab448e698196 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.cpp +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.cpp @@ -36,10 +36,6 @@ ///// // Defines -// Saturation values used for the PWM duty cycle -#define LOW_DUTY 0.1 -#define HIGH_DUTY 0.9 - ///// // Local variables static uint16_t pwm_period; @@ -74,8 +70,6 @@ void hrtim_init_interleaved_buck_mode() pwm_period = leg_period(); pwm_phase_shift = pwm_period / 2; - pwm_low_pulse_width = pwm_period * LOW_DUTY; - pwm_high_pulse_width = pwm_period * HIGH_DUTY; } /** @@ -87,8 +81,6 @@ void hrtim_init_interleaved_buck_mode_center_aligned() pwm_period = leg_period(); pwm_phase_shift = pwm_period; - pwm_low_pulse_width = pwm_period * LOW_DUTY; - pwm_high_pulse_width = pwm_period * HIGH_DUTY; } /** @@ -100,8 +92,6 @@ void hrtim_init_interleaved_boost_mode() pwm_period = leg_period(); pwm_phase_shift = pwm_period / 2; - pwm_low_pulse_width = pwm_period * LOW_DUTY; - pwm_high_pulse_width = pwm_period * HIGH_DUTY; } void hrtim_init_interleaved_boost_mode_center_aligned() @@ -110,8 +100,6 @@ void hrtim_init_interleaved_boost_mode_center_aligned() pwm_period = leg_period(); pwm_phase_shift = pwm_period; - pwm_low_pulse_width = pwm_period * LOW_DUTY; - pwm_high_pulse_width = pwm_period * HIGH_DUTY; } /** @@ -137,8 +125,6 @@ void hrtim_init_independent_mode(bool leg1_buck_mode, bool leg2_buck_mode) pwm_phase_shift_leg1 = 0; pwm_phase_shift_leg2 = pwm_period / 2; pwm_phase_shift = pwm_period/2; - pwm_low_pulse_width = pwm_period * LOW_DUTY; - pwm_high_pulse_width = pwm_period * HIGH_DUTY; } /** @@ -163,8 +149,6 @@ void hrtim_init_independent_mode_center_aligned(bool leg1_buck_mode, bool leg2_b pwm_period = leg_period(); pwm_phase_shift = pwm_period; - pwm_low_pulse_width = pwm_period * LOW_DUTY; - pwm_high_pulse_width = pwm_period * HIGH_DUTY; } /** @@ -180,9 +164,6 @@ void hrtim_init_full_bridge_buck_mode(bool SPIN_board_V_1_1_2) full_bridge_bipolar_mode = false; //left-aligned inverter is always on unipolar mode pwm_period = leg_period(); - pwm_low_pulse_width = pwm_period * LOW_DUTY; - pwm_high_pulse_width = pwm_period * HIGH_DUTY; - pwm_phase_shift = pwm_period / 2; } @@ -201,8 +182,6 @@ void hrtim_init_full_bridge_buck_mode_center_aligned(bool bipolar_mode,bool SPIN full_bridge_bipolar_mode = bipolar_mode; pwm_period = leg_period(); - pwm_low_pulse_width = pwm_period * LOW_DUTY; - pwm_high_pulse_width = pwm_period * HIGH_DUTY; if (bipolar_mode){ pwm_phase_shift = 0; @@ -223,29 +202,9 @@ void hrtim_interleaved_pwm_update(float32_t pwm_duty_cycle) { uint16_t pwm_pulse_width; - // TESTING PWM VALUE TO AVOID OVERFLOW AND PWM UPDATE// - if (pwm_duty_cycle > HIGH_DUTY) // SATURATION CONDITIONS TO AVOID DIVERGENCE. - { - pwm_duty_cycle = HIGH_DUTY; - pwm_pulse_width = pwm_high_pulse_width; - leg_set(leg1_tu, pwm_pulse_width, 0); - leg_set(leg2_tu, pwm_pulse_width, pwm_phase_shift); - } - - 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(leg1_tu, pwm_pulse_width, 0); - leg_set(leg2_tu, pwm_pulse_width, pwm_phase_shift); - } - - else - { - pwm_pulse_width = (pwm_duty_cycle * pwm_period); - leg_set(leg1_tu, pwm_pulse_width, 0); - leg_set(leg2_tu, pwm_pulse_width, pwm_phase_shift); - } + pwm_pulse_width = (pwm_duty_cycle * pwm_period); + leg_set(leg1_tu, pwm_pulse_width, 0); + leg_set(leg2_tu, pwm_pulse_width, pwm_phase_shift); } @@ -263,55 +222,17 @@ void hrtim_full_bridge_buck_pwm_update(float32_t pwm_duty_cycle) // TESTING PWM VALUE TO AVOID OVERFLOW AND PWM UPDATE// if(full_bridge_bipolar_mode) { - if (pwm_duty_cycle > HIGH_DUTY) // SATURATION CONDITIONS TO AVOID DIVERGENCE. - { - pwm_duty_cycle = HIGH_DUTY; - pwm_pulse_width = pwm_high_pulse_width; - pwm_reverse_pulse_width = (1-pwm_duty_cycle) * pwm_period; - leg_set(leg1_tu, pwm_pulse_width, 0); - leg_set(leg2_tu, pwm_reverse_pulse_width, pwm_period*pwm_duty_cycle); - } - else if (pwm_duty_cycle < LOW_DUTY) // SATURATION CONDITIONS TO AVOID DIVERGENCE. - { - pwm_duty_cycle = LOW_DUTY; - pwm_pulse_width = pwm_low_pulse_width; - pwm_reverse_pulse_width = (1-pwm_duty_cycle) * pwm_period; - leg_set(leg1_tu, pwm_pulse_width, 0); - leg_set(leg2_tu, pwm_reverse_pulse_width, pwm_period*pwm_duty_cycle); - } - else - { - pwm_pulse_width = (pwm_duty_cycle * pwm_period); - pwm_reverse_pulse_width = (1-pwm_duty_cycle) * pwm_period; - leg_set(leg1_tu, pwm_pulse_width, 0); - leg_set(leg2_tu, pwm_reverse_pulse_width, pwm_period*pwm_duty_cycle); - } + pwm_pulse_width = (pwm_duty_cycle * pwm_period); + pwm_reverse_pulse_width = (1-pwm_duty_cycle) * pwm_period; + leg_set(leg1_tu, pwm_pulse_width, 0); + leg_set(leg2_tu, pwm_reverse_pulse_width, pwm_period*pwm_duty_cycle); } else { - if (pwm_duty_cycle > HIGH_DUTY) // SATURATION CONDITIONS TO AVOID DIVERGENCE. - { - pwm_duty_cycle = HIGH_DUTY; - pwm_pulse_width = pwm_high_pulse_width; - pwm_reverse_pulse_width = (1-pwm_duty_cycle) * pwm_period; - leg_set(leg1_tu, pwm_pulse_width, 0); - leg_set(leg2_tu, pwm_reverse_pulse_width, pwm_phase_shift); - } - else if (pwm_duty_cycle < LOW_DUTY) // SATURATION CONDITIONS TO AVOID DIVERGENCE. - { - pwm_duty_cycle = LOW_DUTY; - pwm_pulse_width = pwm_low_pulse_width; - pwm_reverse_pulse_width = (1-pwm_duty_cycle) * pwm_period; - leg_set(leg1_tu, pwm_pulse_width, 0); - leg_set(leg2_tu, pwm_reverse_pulse_width, pwm_phase_shift); - } - else - { - pwm_pulse_width = (pwm_duty_cycle * pwm_period); - pwm_reverse_pulse_width = (1-pwm_duty_cycle) * pwm_period; - leg_set(leg1_tu, pwm_pulse_width, 0); - leg_set(leg2_tu, pwm_reverse_pulse_width, pwm_phase_shift); - } + pwm_pulse_width = (pwm_duty_cycle * pwm_period); + pwm_reverse_pulse_width = (1-pwm_duty_cycle) * pwm_period; + leg_set(leg1_tu, pwm_pulse_width, 0); + leg_set(leg2_tu, pwm_reverse_pulse_width, pwm_phase_shift); } } @@ -325,26 +246,8 @@ void hrtim_leg1_pwm_update(float32_t pwm_duty_cycle) { uint16_t pwm_pulse_width; - // TESTING PWM VALUE TO AVOID OVERFLOW AND PWM UPDATE// - if (pwm_duty_cycle > HIGH_DUTY) // SATURATION CONDITIONS TO AVOID DIVERGENCE. - { - pwm_duty_cycle = HIGH_DUTY; - pwm_pulse_width = pwm_high_pulse_width; - leg_set(leg1_tu, 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(leg1_tu, pwm_pulse_width, pwm_phase_shift_leg1); - } - - else - { - pwm_pulse_width = (pwm_duty_cycle * pwm_period); - leg_set(leg1_tu, pwm_pulse_width, pwm_phase_shift_leg1); - } + pwm_pulse_width = (pwm_duty_cycle * pwm_period); + leg_set(leg1_tu, pwm_pulse_width, pwm_phase_shift_leg1); } /** @@ -356,26 +259,8 @@ void hrtim_leg2_pwm_update(float32_t pwm_duty_cycle) { uint16_t pwm_pulse_width; - // TESTING PWM VALUE TO AVOID OVERFLOW AND PWM UPDATE// - if (pwm_duty_cycle > HIGH_DUTY) // SATURATION CONDITIONS TO AVOID DIVERGENCE. - { - pwm_duty_cycle = HIGH_DUTY; - pwm_pulse_width = pwm_high_pulse_width; - leg_set(leg2_tu, 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(leg2_tu, pwm_pulse_width, pwm_phase_shift_leg2); - } - - else - { - pwm_pulse_width = (pwm_duty_cycle * pwm_period); - leg_set(leg2_tu, pwm_pulse_width, pwm_phase_shift_leg2); - } + pwm_pulse_width = (pwm_duty_cycle * pwm_period); + leg_set(leg2_tu, pwm_pulse_width, pwm_phase_shift_leg2); } /** @@ -511,6 +396,7 @@ void hrtim_set_dead_time_leg1(uint16_t rise_ns, uint16_t fall_ns) { leg_set_dt(leg1_tu, rise_ns, fall_ns); } + /** * This updates the dead time of the leg 2 */ @@ -518,3 +404,36 @@ void hrtim_set_dead_time_leg2(uint16_t rise_ns, uint16_t fall_ns) { leg_set_dt(leg2_tu, rise_ns, fall_ns); } + + +/** + * This sets the frequency of the HRTIMER + */ +void hrtim_set_frequency(uint32_t frequency_Hz) +{ + leg_set_freq(frequency_Hz); +} + +/** + * This gets the frequency of the HRTIMER + */ +uint32_t hrtim_get_frequency() +{ + return leg_get_freq(); +} + +/** + * This updates the minimum duty cycle of both legs + */ +void hrtim_set_min_duty_cycle(float32_t duty_cycle) +{ + leg_set_min_duty_cycle(duty_cycle); +} + +/** + * This updates the minimum duty cycle of both legs + */ +void hrtim_set_max_duty_cycle(float32_t duty_cycle) +{ + leg_set_max_duty_cycle(duty_cycle); +} 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 49a68fa70fbaf5dc6bd4f55217c0efffd40be238..bfc01b251a9e623ac097833f499330eaf36ad08e 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.h +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.h @@ -221,5 +221,26 @@ void hrtim_set_dead_time_leg1(uint16_t rise_ns, uint16_t fall_ns); */ void hrtim_set_dead_time_leg2(uint16_t rise_ns, uint16_t fall_ns); +/** + * @brief Sets the frequency of the HRTIMER + */ +void hrtim_set_frequency(uint32_t frequency_Hz); + +/** + * @brief Gets the frequency of the HRTIMER + */ +uint32_t hrtim_get_frequency(); + +/** + * @brief Updates the minimum duty cycle of both legs + */ +void hrtim_set_min_duty_cycle(float32_t duty_cycle); + +/** + * @brief This updates the minimum duty cycle of both legs + */ +void hrtim_set_max_duty_cycle(float32_t duty_cycle); + + #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 cf4cdadfd4ca0b9098862c1e78a406689dcbe6d5..f99a5e8cdde6597d78408a7ca89b9f993ec286d4 100644 --- a/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/leg.h +++ b/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/leg.h @@ -37,6 +37,7 @@ #include <assert.h> #include <stdint.h> +#include "arm_math.h" #include <zephyr.h> @@ -46,8 +47,8 @@ extern "C" { #endif -#define LEG_DEFAULT_DT (100U) /**< dead-time in ns */ -#define LEG_FREQ KHZ(200U) /**< frequency in Hz*/ +#define LEG_DEFAULT_DT (100U) /**< dead-time in ns */ +#define LEG_DEFAULT_FREQ KHZ(200U) /**< frequency in Hz*/ /** * @brief Inverter leg configuration data structure @@ -115,7 +116,7 @@ void leg_start(hrtim_tu_t timing_unit); /** * @brief period getter * - * @return period value returned by leg_init() + * @return period in micro-seconds value returned by leg_init() */ uint16_t leg_period(void); @@ -136,11 +137,26 @@ uint8_t leg_numof(void); leg_conf_t leg_get_conf(uint8_t leg); /** - * @brief LEG_FREQ getter - * - * @return value of LEG_FREQ in KHz + * @brief Gets the frequency in Hz + */ +uint32_t leg_get_freq(void); + +/** + * @brief Sets the frequency in Hz + */ +void leg_set_freq(uint32_t frequency_Hz); + + +/** + * @brief Minimum duty cycle setter. Minimum of 0.02. + */ +void leg_set_min_duty_cycle(float32_t duty_cycle); + +/** + * @brief Maximum duty cycle setter. Maximum of 0.98. */ -uint16_t leg_get_freq(void); +void leg_set_max_duty_cycle(float32_t duty_cycle); + #ifdef __cplusplus } 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 3292a0c25023c8cc88973542e44e174c183119bc..c61575aa78bb4053fab4c9c626e55e95fb156071 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 @@ -32,8 +32,19 @@ #include "owntech_leg_driver.h" #include "hrtim_voltage_mode.h" +// Saturation values used for the PWM duty cycle +#define LOW_DUTY 0.03 +#define HIGH_DUTY 0.97 + + static uint16_t period, min_pw, max_pw, dead_time; +// default configurations of the HRTIMER +static uint32_t frequency = 200000; +static float32_t min_duty_cycle = 0.1; +static float32_t max_duty_cycle = 0.9; + + static leg_conf_t leg_conf[6]; /* a copy of leg_config with index * corresponding to timing unit */ @@ -73,16 +84,14 @@ static uint8_t _TU_num(hrtim_tu_t tu){ */ uint16_t leg_init(bool leg1_upper_switch_convention, bool leg2_upper_switch_convention, hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu) { - uint32_t freq = LEG_FREQ; - /* ensures that timing_unit can be used as leg identifier */ for (unsigned int i = 0; i < LEG_NUMOF; i++) { leg_conf[_TU_num(leg_config[i].timing_unit)] = leg_config[i]; } - period = hrtim_init(0, &freq, LEG_DEFAULT_DT,leg1_upper_switch_convention,leg2_upper_switch_convention, leg1_tu, leg2_tu); - dead_time = (period*LEG_DEFAULT_DT*leg_get_freq())/1000000; + period = hrtim_init(0, &frequency, LEG_DEFAULT_DT,leg1_upper_switch_convention,leg2_upper_switch_convention, leg1_tu, leg2_tu); + dead_time = (uint16_t)((((double)period)*LEG_DEFAULT_DT*((double)frequency))/1000000000.0); //this line is overflow safe min_pw = (period * 0.1) + dead_time; max_pw = (period * 0.9) + dead_time; return period; @@ -97,18 +106,16 @@ uint16_t leg_init(bool leg1_upper_switch_convention, bool leg2_upper_switch_conv */ uint16_t leg_init_center_aligned(bool leg1_upper_switch_convention, bool leg2_upper_switch_convention,hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu) { - uint32_t freq = LEG_FREQ; - /* ensures that timing_unit can be used as leg identifier */ for (unsigned int i = 0; i < LEG_NUMOF; i++) { leg_conf[_TU_num(leg_config[i].timing_unit)] = leg_config[i]; } - period = hrtim_init_updwn(0, &freq, LEG_DEFAULT_DT,leg1_upper_switch_convention,leg2_upper_switch_convention, leg1_tu, leg2_tu); - dead_time = (period*LEG_DEFAULT_DT*leg_get_freq())/1000000; - min_pw = (period * 0.1) + dead_time; - max_pw = (period * 0.9) + dead_time; + period = hrtim_init_updwn(0, &frequency, LEG_DEFAULT_DT,leg1_upper_switch_convention,leg2_upper_switch_convention, leg1_tu, leg2_tu); + dead_time = (uint16_t)((((double)period)*LEG_DEFAULT_DT*((double)frequency))/1000000000.0); //this line is overflow safe + min_pw = (period * min_duty_cycle) + dead_time; + max_pw = (period * max_duty_cycle) + dead_time; return period; } @@ -120,7 +127,7 @@ void leg_set(hrtim_tu_t timing_unit, uint16_t pulse_width, uint16_t phase_shift) //Second check for duty cycle saturation if (pulse_width<min_pw) { - pulse_width = max_pw; + pulse_width = min_pw; } else if (pulse_width > max_pw) { @@ -172,7 +179,30 @@ leg_conf_t leg_get_conf(uint8_t leg) return leg_conf[leg_config[leg].timing_unit]; } -uint16_t leg_get_freq(void) +uint32_t leg_get_freq(void) +{ + return frequency; +} + +void leg_set_freq(uint32_t frequency_Hz) +{ + frequency = frequency_Hz; +} + +void leg_set_min_duty_cycle(float32_t duty_cycle) { - return LEG_FREQ / 1000; + if (duty_cycle>=LOW_DUTY) { + min_duty_cycle = duty_cycle; + }else{ + min_duty_cycle = LOW_DUTY; + } +} + +void leg_set_max_duty_cycle(float32_t duty_cycle) +{ + if (duty_cycle<=HIGH_DUTY) { + max_duty_cycle = duty_cycle; + }else{ + max_duty_cycle = HIGH_DUTY; + } }