From f64c74b22c8fa45e31cd03ba5fe8f68c42a5d815 Mon Sep 17 00:00:00 2001 From: Ayoub Farah Hassan <afarahhass@laas.fr> Date: Tue, 21 Feb 2023 09:41:52 +0000 Subject: [PATCH] Current mode update This commit updates owntech modules to implement the current mode. ## Update of HRTIM module - Deleting unnecessary LL function generated by cubeMX, and replacing with clear functions. - The adc for leg2 was triggered previously by the timing unit's CMP4, this commit replace it with CMP3 as CMP4 is used for current mode. ## Update of DAC module - Adding more trigger for sawtooth generation. - Adding "External and Internal" mode for DAC output mode. - Update dac_stm32_function_update_reset and dac_stm32_function_update_step to delete the lines disabling/enabling the DACs. ## Update of Comparator module - Comparator 1 is now linked to DAC3 and comparator 3 to DAC1. ## Update of Hardware Configuration module - Adding essential functions to set the current mode. - Adding comparator_configuration files, adding changes to cmake and Kconfig in hardware configuration to include the comparator drivers. --- .../zephyr/src/comparator_driver.c | 9 +- .../zephyr/public_api/dac.h | 15 +- .../zephyr/src/stm32_dac_driver.c | 74 ++- .../zephyr/CMakeLists.txt | 1 + .../zephyr/Kconfig | 1 + .../public_api/HardwareConfiguration.cpp | 39 +- .../zephyr/public_api/HardwareConfiguration.h | 8 +- .../zephyr/src/comparator_configuration.cpp | 33 + .../zephyr/src/comparator_configuration.h | 32 + .../zephyr/src/dac_configuration.cpp | 198 ++++-- .../zephyr/src/dac_configuration.h | 17 +- .../zephyr/src/hrtim_configuration.cpp | 17 +- .../zephyr/src/hrtim_configuration.h | 28 +- .../zephyr/public_api/hrtim.h | 2 +- .../zephyr/public_api/leg.h | 19 + .../src/current_mode/hrtim_current_mode.c | 583 +++++++++++------- .../src/current_mode/hrtim_current_mode.h | 70 ++- .../zephyr/src/hrtim_common.c | 15 +- .../src/voltage_mode/owntech_leg_driver.cpp | 26 +- 19 files changed, 867 insertions(+), 320 deletions(-) create mode 100644 zephyr/modules/owntech_hardware_configuration/zephyr/src/comparator_configuration.cpp create mode 100644 zephyr/modules/owntech_hardware_configuration/zephyr/src/comparator_configuration.h diff --git a/zephyr/modules/owntech_comparator_driver/zephyr/src/comparator_driver.c b/zephyr/modules/owntech_comparator_driver/zephyr/src/comparator_driver.c index 42f3a39..63867d8 100644 --- a/zephyr/modules/owntech_comparator_driver/zephyr/src/comparator_driver.c +++ b/zephyr/modules/owntech_comparator_driver/zephyr/src/comparator_driver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 LAAS-CNRS + * Copyright (c) 2021-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,8 +18,9 @@ */ /** - * @date 2022 + * @date 2023 * @author Clément Foucher <clement.foucher@laas.fr> + * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> */ @@ -63,7 +64,7 @@ void comparator_gpio_init() void comparator_comp1_init() { - LL_COMP_ConfigInputs(COMP1, LL_COMP_INPUT_MINUS_DAC1_CH1, LL_COMP_INPUT_PLUS_IO1); + LL_COMP_ConfigInputs(COMP1, LL_COMP_INPUT_MINUS_DAC3_CH1, LL_COMP_INPUT_PLUS_IO1); LL_COMP_SetInputHysteresis(COMP1, LL_COMP_HYSTERESIS_NONE); LL_COMP_SetOutputPolarity(COMP1, LL_COMP_OUTPUTPOL_NONINVERTED); LL_COMP_SetOutputBlankingSource(COMP1, LL_COMP_BLANKINGSRC_NONE); @@ -78,7 +79,7 @@ void comparator_comp1_init() void comparator_comp3_init() { - LL_COMP_ConfigInputs(COMP3, LL_COMP_INPUT_MINUS_DAC3_CH1, LL_COMP_INPUT_PLUS_IO2); + LL_COMP_ConfigInputs(COMP3, LL_COMP_INPUT_MINUS_DAC1_CH1, LL_COMP_INPUT_PLUS_IO2); LL_COMP_SetInputHysteresis(COMP3, LL_COMP_HYSTERESIS_NONE); LL_COMP_SetOutputPolarity(COMP3, LL_COMP_OUTPUTPOL_NONINVERTED); LL_COMP_SetOutputBlankingSource(COMP3, LL_COMP_BLANKINGSRC_NONE); diff --git a/zephyr/modules/owntech_dac_driver/zephyr/public_api/dac.h b/zephyr/modules/owntech_dac_driver/zephyr/public_api/dac.h index 158c19c..73eed1c 100644 --- a/zephyr/modules/owntech_dac_driver/zephyr/public_api/dac.h +++ b/zephyr/modules/owntech_dac_driver/zephyr/public_api/dac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 LAAS-CNRS + * Copyright (c) 2021-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,8 +18,9 @@ */ /** - * @date 2022 + * @date 2023 * @author Clément Foucher <clement.foucher@laas.fr> + * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> */ @@ -62,7 +63,11 @@ typedef enum typedef enum { hrtim_trig1, - hrtim_trig2 + hrtim_trig2, + hrtim_trig3, + hrtim_trig4, + hrtim_trig5, + hrtim_trig6 } dac_trigger_t; typedef struct @@ -78,7 +83,8 @@ typedef struct typedef enum { dac_pin_internal, - dac_pin_external + dac_pin_external, + dac_pin_internal_and_external } dac_pin_config_t; ///// @@ -152,7 +158,6 @@ static inline void dac_stop(const struct device* dev, uint8_t channel) api->stop(dev, channel); } - #ifdef __cplusplus } #endif diff --git a/zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.c b/zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.c index 0786b94..6f15f88 100644 --- a/zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.c +++ b/zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 LAAS-CNRS + * Copyright (c) 2021-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,9 +18,10 @@ */ /** - * @date 2022 + * @date 2023 * * @author Clément Foucher <clement.foucher@laas.fr> + * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> */ @@ -114,12 +115,44 @@ static void dac_stm32_set_function(const struct device* dev, uint8_t channel, co { reset_trigger_source = LL_DAC_TRIG_EXT_HRTIM_RST_TRG2; } + else if (function_config->reset_trigger_source == hrtim_trig3) + { + reset_trigger_source = LL_DAC_TRIG_EXT_HRTIM_RST_TRG3; + } + else if (function_config->reset_trigger_source == hrtim_trig4) + { + reset_trigger_source = LL_DAC_TRIG_EXT_HRTIM_RST_TRG4; + } + else if (function_config->reset_trigger_source == hrtim_trig5) + { + reset_trigger_source = LL_DAC_TRIG_EXT_HRTIM_RST_TRG5; + } + else if (function_config->reset_trigger_source == hrtim_trig6) + { + reset_trigger_source = LL_DAC_TRIG_EXT_HRTIM_RST_TRG6; + } uint32_t step_trigger_source = LL_DAC_TRIG_EXT_HRTIM_STEP_TRG1; if (function_config->step_trigger_source == hrtim_trig2) { step_trigger_source = LL_DAC_TRIG_EXT_HRTIM_STEP_TRG2; } + else if (function_config->step_trigger_source == hrtim_trig3) + { + step_trigger_source = LL_DAC_TRIG_EXT_HRTIM_STEP_TRG3; + } + else if (function_config->step_trigger_source == hrtim_trig4) + { + step_trigger_source = LL_DAC_TRIG_EXT_HRTIM_STEP_TRG4; + } + else if (function_config->step_trigger_source == hrtim_trig5) + { + step_trigger_source = LL_DAC_TRIG_EXT_HRTIM_STEP_TRG5; + } + else if (function_config->step_trigger_source == hrtim_trig6) + { + step_trigger_source = LL_DAC_TRIG_EXT_HRTIM_STEP_TRG6; + } uint32_t polarity = LL_DAC_SAWTOOTH_POLARITY_DECREMENT; if (function_config->polarity == dac_polarity_increment) @@ -152,22 +185,7 @@ static void dac_stm32_function_update_reset(const struct device* dev, uint8_t ch { data->dac_config->function_config.reset_data = reset_data; - if (data->started[channel-1] == 1) - { - LL_DAC_Disable(dac_dev, dac_channel); - } - LL_DAC_SetWaveSawtoothResetData(dac_dev, dac_channel, reset_data); - - if (data->started[channel-1] == 1) - { - LL_DAC_Enable(dac_dev, dac_channel); - - while (LL_DAC_IsReady(dac_dev, dac_channel) == 0) - { - // Wait - } - } } } @@ -182,22 +200,7 @@ static void dac_stm32_function_update_step(const struct device* dev, uint8_t cha { data->dac_config->function_config.step_data = step_data; - if (data->started[channel-1] == 1) - { - LL_DAC_Disable(dac_dev, dac_channel); - } - - LL_DAC_SetWaveSawtoothStepData(dac_dev, dac_channel, step_data); - - if (data->started[channel-1] == 1) - { - LL_DAC_Enable(dac_dev, dac_channel); - - while (LL_DAC_IsReady(dac_dev, dac_channel) == 0) - { - // Wait - } - } + LL_DAC_SetWaveSawtoothStepData(dac_dev, dac_channel, step_data); } } @@ -216,6 +219,11 @@ static void dac_stm32_pin_configure(const struct device* dev, uint8_t channel, d { LL_DAC_ConfigOutput(dac_dev, dac_channel, LL_DAC_OUTPUT_MODE_NORMAL, LL_DAC_OUTPUT_BUFFER_ENABLE, LL_DAC_OUTPUT_CONNECT_GPIO); } + else if (pin_config == dac_pin_internal_and_external) + { + LL_DAC_ConfigOutput(dac_dev, dac_channel, LL_DAC_OUTPUT_MODE_NORMAL, LL_DAC_OUTPUT_BUFFER_ENABLE, LL_DAC_OUTPUT_CONNECT_INTERNAL); + } + } static void dac_stm32_start(const struct device* dev, uint8_t channel) diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/CMakeLists.txt b/zephyr/modules/owntech_hardware_configuration/zephyr/CMakeLists.txt index e9dd0be..f335a34 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/CMakeLists.txt +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/CMakeLists.txt @@ -17,5 +17,6 @@ if(CONFIG_OWNTECH_HARDWARE_CONFIGURATION) src/adc_configuration.cpp src/power_driver_configuration.cpp public_api/HardwareConfiguration.cpp + src/comparator_configuration.cpp ) endif() diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/Kconfig b/zephyr/modules/owntech_hardware_configuration/zephyr/Kconfig index 1480614..8b7128a 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/Kconfig +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/Kconfig @@ -7,3 +7,4 @@ config OWNTECH_HARDWARE_CONFIGURATION depends on OWNTECH_NGND_DRIVER depends on OWNTECH_TIMER_DRIVER depends on OWNTECH_GPIO_API + depends on OWNTECH_COMPARATOR_DRIVER 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 e3984c0..948406a 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.cpp +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 LAAS-CNRS + * Copyright (c) 2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,7 +18,7 @@ */ /** - * @date 2022 + * @date 2023 * * @author Clément Foucher <clement.foucher@laas.fr> * @author Luiz Villa <luiz.villa@laas.fr> @@ -35,6 +35,7 @@ #include "../src/uart_configuration.h" #include "../src/adc_configuration.h" #include "../src/power_driver_configuration.h" +#include "../src/comparator_configuration.h" // Current class header #include "HardwareConfiguration.h" @@ -89,11 +90,6 @@ void HardwareConfiguration::setBoardVersion(hardware_version_t hardware_version) ///// // DAC -void HardwareConfiguration::initDac1Dac3CurrentMode() -{ - dac_config_dac1_dac3_current_mode_init(); -} - void HardwareConfiguration::initDacConstValue(uint8_t dac_number) { dac_config_const_value_init(dac_number); @@ -104,6 +100,17 @@ void HardwareConfiguration::setDacConstValue(uint8_t dac_number, uint8_t channel dac_set_const_value(dac_number, channel, const_value); } +void HardwareConfiguration::slopeCompensationLeg1(float32_t peak_voltage, float32_t low_voltage) +{ + set_satwtooth_DAC3(peak_voltage, low_voltage); +} + +void HardwareConfiguration::slopeCompensationLeg2(float32_t peak_voltage, float32_t low_voltage) +{ + set_satwtooth_DAC1(peak_voltage, low_voltage); +} + + ///// // NGND @@ -259,6 +266,24 @@ void HardwareConfiguration::initIndependentModeCenterAligned(leg_operation_t leg hrtim_init_independent_mode_center_aligned(leg1_mode, leg2_mode); } +void HardwareConfiguration::initBuckCurrentMode() +{ + if(HardwareConfiguration::hardware_version == TWIST_v_1_1_2) + { + hrtim_init_CurrentMode(false,true,TIMA,TIMC); + dac_config_dac3_current_mode_init(TIMA); + dac_config_dac1_current_mode_init(TIMC); + } + else + { + hrtim_init_CurrentMode(true,true,TIMA,TIMB); + dac_config_dac3_current_mode_init(TIMA); + dac_config_dac1_current_mode_init(TIMB); + } + + comparator_initialization(); +} + void HardwareConfiguration::setInterleavedDutyCycle(float32_t duty_cycle) { hrtim_interleaved_pwm_update(duty_cycle); 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 283edf6..21b5dcf 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.h +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/public_api/HardwareConfiguration.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 LAAS-CNRS + * Copyright (c) 2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,7 +18,7 @@ */ /** - * @date 2022 + * @date 2023 * * @author Clément Foucher <clement.foucher@laas.fr> * @author Luiz Villa <luiz.villa@laas.fr> @@ -81,9 +81,10 @@ public: static void setBoardVersion(hardware_version_t hardware_version); // DAC - static void initDac1Dac3CurrentMode(); static void initDacConstValue(uint8_t dac_number); static void setDacConstValue(uint8_t dac_number, uint8_t channel, uint32_t const_value); + static void slopeCompensationLeg1(float32_t peak_voltage, float32_t low_voltage); + static void slopeCompensationLeg2(float32_t peak_voltage, float32_t low_voltage); // NGND static void setNgndOn(); @@ -109,6 +110,7 @@ public: static void initFullBridgeBoostModeCenterAligned(); static void initIndependentMode(leg_operation_t leg1_operation_type, leg_operation_t leg2_operation_type); static void initIndependentModeCenterAligned(leg_operation_t leg1_operation_type, leg_operation_t leg2_operation_type); + static void initBuckCurrentMode(); static void setInterleavedDutyCycle(float32_t duty_cycle); static void setFullBridgeBuckDutyCycle(float32_t duty_cycle); diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/src/comparator_configuration.cpp b/zephyr/modules/owntech_hardware_configuration/zephyr/src/comparator_configuration.cpp new file mode 100644 index 0000000..d546b4d --- /dev/null +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/comparator_configuration.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 LAAS-CNRS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * SPDX-License-Identifier: LGLPV2.1 + */ + +/** + * @date 2023 + * + * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> + */ + +// OwnTech api + +#include "comparator.h" +#include "comparator_configuration.h" + +void comparator_initialization(){ + comparator_init(); +} diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/src/comparator_configuration.h b/zephyr/modules/owntech_hardware_configuration/zephyr/src/comparator_configuration.h new file mode 100644 index 0000000..2d2b94f --- /dev/null +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/comparator_configuration.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 LAAS-CNRS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * SPDX-License-Identifier: LGLPV2.1 + */ + +/** + * @date 2023 + * + * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> + */ + +#ifndef COMPARATOR_CONFIGURATION_H_ +#define COMPARATOR_CONFIGURATION_H_ + +void comparator_initialization(); + + +#endif // COMPARATOR_CONFIGURATION_H_ diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/src/dac_configuration.cpp b/zephyr/modules/owntech_hardware_configuration/zephyr/src/dac_configuration.cpp index 0ae089b..179ae48 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/src/dac_configuration.cpp +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/dac_configuration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 LAAS-CNRS + * Copyright (c) 2021-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,54 +18,31 @@ */ /** - * @date 2022 + * @date 2023 * * @author Clément Foucher <clement.foucher@laas.fr> * @author Luiz Villa <luiz.villa@laas.fr> + * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> */ - // Zephyr #include <zephyr.h> // Owntech driver #include "dac.h" +// Header +#include "dac_configuration.h" + +// Define the voltage reference used for ADC. +// It depends on the board used (On nucleo, choose Vref = 2.48V). + +#define VREF 2.048f static const struct device* dac1 = DEVICE_DT_GET(DAC1_DEVICE); static const struct device* dac2 = DEVICE_DT_GET(DAC2_DEVICE); static const struct device* dac3 = DEVICE_DT_GET(DAC3_DEVICE); - -void dac_config_dac1_dac3_current_mode_init() -{ - if ( (device_is_ready(dac1) == true) && (device_is_ready(dac3) == true) ) - { - // DAC 1 - dac_function_config_t function_config = - { - .dac_function = dac_function_sawtooth, - .reset_trigger_source = hrtim_trig1, - .step_trigger_source = hrtim_trig1, - .polarity = dac_polarity_decrement, - .reset_data = 4000, - .step_data = 200 - }; - - dac_set_function(dac1, 1, &function_config); - dac_pin_configure(dac1, 1, dac_pin_internal); - dac_start(dac1, 1); - - // DAC 3 - function_config.reset_trigger_source = hrtim_trig2; - function_config.step_trigger_source = hrtim_trig2; - - dac_set_function(dac3, 1, &function_config); - dac_pin_configure(dac3, 1, dac_pin_internal); - dac_start(dac3, 1); - } -} - void dac_config_const_value_init(uint8_t dac_number) { const struct device* dac_dev; @@ -80,12 +57,12 @@ void dac_config_const_value_init(uint8_t dac_number) } else { - dac_dev = dac2; //sets the dac 2 as default + dac_dev = dac2; // sets the dac 2 as default } if (device_is_ready(dac_dev) == true) { - dac_set_const_value(dac_dev,1,0); + dac_set_const_value(dac_dev, 1, 0); dac_pin_configure(dac_dev, 1, dac_pin_external); dac_start(dac_dev, 1); } @@ -105,11 +82,158 @@ void dac_set_const_value(uint8_t dac_number, uint8_t channel, uint32_t const_val } else { - dac_dev = dac2; //sets the dac 2 as default + dac_dev = dac2; // sets the dac 2 as default } if (device_is_ready(dac_dev) == true) { - dac_set_const_value(dac_dev,channel,const_value); + dac_set_const_value(dac_dev, channel, const_value); + } +} + +void dac_config_dac1_current_mode_init(hrtim_tu_t tu_src) +{ + // DAC 1 + dac_function_config_t function_config = + { + .dac_function = dac_function_sawtooth, + .reset_trigger_source = hrtim_trig1, + .step_trigger_source = hrtim_trig1, + .polarity = dac_polarity_decrement, + .reset_data = 4000, + .step_data = 200}; + + switch (tu_src) + { + case TIMB: + function_config.reset_trigger_source = hrtim_trig2; + function_config.step_trigger_source = hrtim_trig2; + break; + + case TIMC: + function_config.reset_trigger_source = hrtim_trig3; + function_config.step_trigger_source = hrtim_trig3; + break; + + case TIMD: + function_config.reset_trigger_source = hrtim_trig4; + function_config.step_trigger_source = hrtim_trig4; + break; + + case TIME: + function_config.reset_trigger_source = hrtim_trig5; + function_config.step_trigger_source = hrtim_trig5; + break; + + case TIMF: + function_config.reset_trigger_source = hrtim_trig6; + function_config.step_trigger_source = hrtim_trig6; + break; + + default: + break; } + + dac_set_function(dac1, 1, &function_config); + dac_pin_configure(dac1, 1, dac_pin_internal_and_external); + dac_start(dac1, 1); +} + +void dac_config_dac3_current_mode_init(hrtim_tu_t tu_src) +{ + // DAC 3 + dac_function_config_t function_config = + { + .dac_function = dac_function_sawtooth, + .reset_trigger_source = hrtim_trig1, + .step_trigger_source = hrtim_trig1, + .polarity = dac_polarity_decrement, + .reset_data = 4000, + .step_data = 200}; + + switch (tu_src) + { + case TIMB: + function_config.reset_trigger_source = hrtim_trig2; + function_config.step_trigger_source = hrtim_trig2; + break; + + case TIMC: + function_config.reset_trigger_source = hrtim_trig3; + function_config.step_trigger_source = hrtim_trig3; + break; + + case TIMD: + function_config.reset_trigger_source = hrtim_trig4; + function_config.step_trigger_source = hrtim_trig4; + break; + + case TIME: + function_config.reset_trigger_source = hrtim_trig5; + function_config.step_trigger_source = hrtim_trig5; + break; + + case TIMF: + function_config.reset_trigger_source = hrtim_trig6; + function_config.step_trigger_source = hrtim_trig6; + break; + + default: + break; + } + + dac_set_function(dac3, 1, &function_config); + dac_pin_configure(dac3, 1, dac_pin_internal); + dac_start(dac3, 1); +} + +void set_satwtooth_DAC3(float32_t set_voltage, float32_t reset_voltage) +{ + float32_t Dv = set_voltage - reset_voltage; + + if (Dv < 0) + Dv = 0; + + if (Dv > set_voltage) + { + Dv = set_voltage; + if (Dv > VREF) + Dv = VREF; + } + + uint32_t set_data = (uint32_t)(4096U * set_voltage) / (VREF); + + if (set_data > 4095U) + set_data = 4095U; + + dac_function_update_reset(dac3, 1, set_data); + + uint32_t reset_data = (uint32_t)(Dv * 65536) / (VREF * 100); // divided by 100 because we have 100 voltage steps + + dac_function_update_step(dac3, 1, reset_data); +} + +void set_satwtooth_DAC1(float32_t set_voltage, float32_t reset_voltage) +{ + float32_t Dv = set_voltage - reset_voltage; + + if (Dv < 0) + Dv = 0; + + if (Dv > set_voltage) + Dv = set_voltage; + + if (Dv > VREF) + Dv = VREF; + + uint32_t set_data = (uint32_t)(4096U * set_voltage) / (VREF); + + if (set_data > 4095U) + set_data = 4095U; + + dac_function_update_reset(dac1, 1, set_data); + + uint32_t reset_data = (uint32_t)(Dv * 65536U) / (VREF * 100); // divided by 100 because we have 100 voltage steps + + dac_function_update_step(dac1, 1, reset_data); } diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/src/dac_configuration.h b/zephyr/modules/owntech_hardware_configuration/zephyr/src/dac_configuration.h index fff576e..66e6618 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/src/dac_configuration.h +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/dac_configuration.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 LAAS-CNRS + * Copyright (c) 2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,9 +18,10 @@ */ /** - * @date 2022 + * @date 2023 * @author Clément Foucher <clement.foucher@laas.fr> * @author Luiz Villa <luiz.villa@laas.fr> + * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> */ @@ -30,10 +31,18 @@ // Stdlib #include <stdint.h> +//ARM_MATH +#include <arm_math.h> + +// hrtim.h is important to configure the DAC for current mode +#include "hrtim.h" + -void dac_config_dac1_dac3_current_mode_init(); void dac_config_const_value_init(uint8_t dac_number); void dac_set_const_value(uint8_t dac_number, uint8_t channel, uint32_t const_value); - +void dac_config_dac3_current_mode_init(hrtim_tu_t tu_src); +void dac_config_dac1_current_mode_init(hrtim_tu_t tu_src); +void set_satwtooth_DAC3(float32_t set_voltage, float32_t reset_voltage); +void set_satwtooth_DAC1(float32_t set_voltage, float32_t reset_voltage); #endif // DAC_CONFIGURATION_H_ 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 6cc97be..675a414 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.cpp +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 LAAS-CNRS + * Copyright (c) 2021-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,7 +18,7 @@ */ /** - * @date 2022 + * @date 2023 * @author Luiz Villa <luiz.villa@laas.fr> * @author Clément Foucher <clement.foucher@laas.fr> * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> @@ -188,6 +188,19 @@ void hrtim_init_full_bridge_buck_mode_center_aligned(bool bipolar_mode,bool SPIN } +/** + * This function initializes both legs in Current Mode configuration + */ +void hrtim_init_CurrentMode(bool leg1_buck, bool leg2_buck, hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu) +{ + hrtim_init_current(leg1_buck, leg2_buck, leg1_tu, leg2_tu); + pwm_period = leg_period(); + pwm_phase_shift = 0; + CM_leg_set(leg1_tu, 0); + CM_leg_set(leg2_tu, pwm_phase_shift); +} + + /** * This function transfer the calculated PWM value to the * HRTIM peripheral and make sure it is between saturation 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 bfc01b2..595c316 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.h +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/hrtim_configuration.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 LAAS-CNRS + * Copyright (c) 2021-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,9 +18,10 @@ */ /** - * @date 2022 + * @date 2023 * @author Luiz Villa <luiz.villa@laas.fr> * @author Clément Foucher <clement.foucher@laas.fr> + * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> */ #ifndef HRTIM_CONFIGURATION_H_ @@ -94,6 +95,29 @@ void hrtim_init_independent_mode(bool leg1_buck_mode, bool leg2_buck_mode); */ void hrtim_init_independent_mode_center_aligned(bool leg1_buck_mode, bool leg2_buck_mode); + +/** + * @brief initialize the converter in current mode + * @param[in] leg1_buck bool parameter, 0->leg1 in boost mode 1->leg1 in buck mode + * @param[in] leg2_buck bool parameter, 0->leg2 in boost mode 1->leg2 in buck mode + * @param[in] leg1_tu one of the timing unit, from TIMA to TIMF : + * @arg @ref TIMA + * @arg @ref TIMB + * @arg @ref TIMC + * @arg @ref TIMD + * @arg @ref TIME + * @arg @ref TIMF + * @param[in] leg2_tu one of the timing unit, from TIMA to TIMF : + * @arg @ref TIMA + * @arg @ref TIMB + * @arg @ref TIMC + * @arg @ref TIMD + * @arg @ref TIME + * @arg @ref TIMF +*/ +void hrtim_init_CurrentMode(bool leg1_buck, bool leg2_buck, hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu); + + /** * @brief This function transfer the calculated PWM value to the * HRTIM peripheral and make sure it is between saturation diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/hrtim.h b/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/hrtim.h index 3075af4..51f514a 100644 --- a/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/hrtim.h +++ b/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/hrtim.h @@ -85,7 +85,7 @@ void hrtim_pwm_set(hrtim_t dev, hrtim_tu_t tu, uint16_t value, uint16_t shift); -void hrtim_init_current(); +void hrtim_init_current(bool leg1_convention, bool leg2_convention, hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu); void hrtim_init_voltage_buck(hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu); void hrtim_init_voltage_buck_center_aligned(hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu); void hrtim_init_voltage_boost(hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu); 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 6060846..4c30c3b 100644 --- a/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/leg.h +++ b/zephyr/modules/owntech_hrtim_driver/zephyr/public_api/leg.h @@ -165,6 +165,25 @@ void leg_set_min_duty_cycle(float32_t duty_cycle); */ void leg_set_max_duty_cycle(float32_t duty_cycle); +/** + * @brief Set the timer and phase shift for given leg device with current mode initialization + * + * @param[in] timing_unit timing_unit from TIMA to TIMF + * @param[in] pulse_width pulse width to set + * @param[in] phase_shift phase shift + */ +void CM_leg_set(hrtim_tu_t timing_unit, uint16_t phase_shift); + +/** + * @brief Initializes all the configured devices with the chosen switch convention with current mode initialization + * + * @param[in] leg1_upper_switch_convention Choice of the switch convention for leg 1 + * @param[in] leg2_upper_switch_convention Choice of the switch convention for leg 2 + * + * @return HRTIM period + */ +uint16_t leg_init_CM(bool leg1_upper_switch_convention, bool leg2_upper_switch_convention, hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu); + #ifdef __cplusplus } diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/src/current_mode/hrtim_current_mode.c b/zephyr/modules/owntech_hrtim_driver/zephyr/src/current_mode/hrtim_current_mode.c index 341ec09..2e58ece 100644 --- a/zephyr/modules/owntech_hrtim_driver/zephyr/src/current_mode/hrtim_current_mode.c +++ b/zephyr/modules/owntech_hrtim_driver/zephyr/src/current_mode/hrtim_current_mode.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 LAAS-CNRS + * Copyright (c) 2020-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,231 +18,398 @@ */ /** + * @date 2023 * @author Clément Foucher <clement.foucher@laas.fr> + * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> */ - // STM32 LL -#include <stm32_ll_hrtim.h> -#include <stm32_ll_gpio.h> +#include <stm32_ll_rcc.h> #include <stm32_ll_bus.h> -#include <stm32_ll_dmamux.h> +#include <stm32_ll_hrtim.h> + +// header +#include "hrtim_current_mode.h" + +static uint8_t _CM_TU_num(hrtim_tu_t tu) /* Return the number associated to the timing unit */ +{ + + switch (tu) + { + case TIMA: + return 0; + + case TIMB: + return 1; + case TIMC: + return 2; -void hrtim_cm_init() + case TIMD: + return 3; + + case TIME: + return 4; + + #if (HRTIM_STU_NUMOF == 6) + case TIMF: + return 5; + #endif + + default: + return 100; + } +} + +void _CM_init_EEV(void) { - /* Peripheral clock enable */ - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_HRTIM1); - - LL_HRTIM_ConfigDLLCalibration(HRTIM1, LL_HRTIM_DLLCALIBRATION_MODE_CONTINUOUS, LL_HRTIM_DLLCALIBRATION_RATE_3); - - while(LL_HRTIM_IsActiveFlag_DLLRDY(HRTIM1) == RESET) - { - // Wait - } - - LL_HRTIM_EE_SetPrescaler(HRTIM1, LL_HRTIM_EE_PRESCALER_DIV1); - LL_HRTIM_EE_SetSrc(HRTIM1, LL_HRTIM_EVENT_4, LL_HRTIM_EEV4SRC_COMP1_OUT); - LL_HRTIM_EE_SetPolarity(HRTIM1, LL_HRTIM_EVENT_4, LL_HRTIM_EE_POLARITY_HIGH); - LL_HRTIM_EE_SetSensitivity(HRTIM1, LL_HRTIM_EVENT_4, LL_HRTIM_EE_SENSITIVITY_LEVEL); - LL_HRTIM_EE_SetFastMode(HRTIM1, LL_HRTIM_EVENT_4, LL_HRTIM_EE_FASTMODE_DISABLE); - LL_HRTIM_EE_SetSrc(HRTIM1, LL_HRTIM_EVENT_5, LL_HRTIM_EEV5SRC_COMP3_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_MASTER, LL_HRTIM_ADCTRIG_SRC13_MCMP3); - LL_HRTIM_SetADCPostScaler(HRTIM1, LL_HRTIM_ADCTRIG_1, 0); - LL_HRTIM_TIM_SetPrescaler(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_PRESCALERRATIO_MUL16); - LL_HRTIM_TIM_SetCounterMode(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_MODE_CONTINUOUS); - LL_HRTIM_TIM_SetPeriod(HRTIM1, LL_HRTIM_TIMER_MASTER, 13600); - LL_HRTIM_TIM_SetRepetition(HRTIM1, LL_HRTIM_TIMER_MASTER, 0x00); - LL_HRTIM_TIM_DisableHalfMode(HRTIM1, LL_HRTIM_TIMER_MASTER); - LL_HRTIM_TIM_SetInterleavedMode(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_INTERLEAVED_MODE_DISABLED); - LL_HRTIM_TIM_DisableStartOnSync(HRTIM1, LL_HRTIM_TIMER_MASTER); - LL_HRTIM_TIM_DisableResetOnSync(HRTIM1, LL_HRTIM_TIMER_MASTER); - LL_HRTIM_TIM_SetDACTrig(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_DACTRIG_NONE); - LL_HRTIM_TIM_DisablePreload(HRTIM1, LL_HRTIM_TIMER_MASTER); - LL_HRTIM_TIM_SetUpdateGating(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_UPDATEGATING_INDEPENDENT); - LL_HRTIM_TIM_SetUpdateTrig(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_UPDATETRIG_NONE); - LL_HRTIM_TIM_SetBurstModeOption(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_BURSTMODE_MAINTAINCLOCK); - LL_HRTIM_ForceUpdate(HRTIM1, LL_HRTIM_TIMER_MASTER); - LL_HRTIM_TIM_SetCompare1(HRTIM1, LL_HRTIM_TIMER_MASTER, 1360); - LL_HRTIM_TIM_SetCompare2(HRTIM1, LL_HRTIM_TIMER_MASTER, 6800); - LL_HRTIM_TIM_SetCompare3(HRTIM1, LL_HRTIM_TIMER_MASTER, 2700); - - while(LL_HRTIM_IsActiveFlag_DLLRDY(HRTIM1) == RESET) - { - // Wait - } - - LL_HRTIM_TIM_SetPrescaler(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_PRESCALERRATIO_MUL16); - LL_HRTIM_TIM_SetCounterMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_MODE_CONTINUOUS); - LL_HRTIM_TIM_SetPeriod(HRTIM1, LL_HRTIM_TIMER_A, 13600); - LL_HRTIM_TIM_SetRepetition(HRTIM1, LL_HRTIM_TIMER_A, 0x00); - LL_HRTIM_TIM_SetUpdateGating(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_UPDATEGATING_INDEPENDENT); - LL_HRTIM_TIM_SetCountingMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_COUNTING_MODE_UP); - LL_HRTIM_TIM_SetTriggeredHalfMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_TRIGHALF_DISABLED); - LL_HRTIM_TIM_SetComp1Mode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_GTCMP1_EQUAL); - LL_HRTIM_TIM_SetComp3Mode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_GTCMP3_EQUAL); - LL_HRTIM_TIM_SetDualDacResetTrigger(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_DCDR_COUNTER); - LL_HRTIM_TIM_SetDualDacStepTrigger(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_DCDS_CMP2); - LL_HRTIM_TIM_EnableDualDacTrigger(HRTIM1, LL_HRTIM_TIMER_A); - LL_HRTIM_TIM_SetDACTrig(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_DACTRIG_NONE); - LL_HRTIM_TIM_DisableHalfMode(HRTIM1, LL_HRTIM_TIMER_A); - LL_HRTIM_TIM_SetInterleavedMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_INTERLEAVED_MODE_DISABLED); - LL_HRTIM_TIM_DisableStartOnSync(HRTIM1, LL_HRTIM_TIMER_A); - LL_HRTIM_TIM_DisableResetOnSync(HRTIM1, LL_HRTIM_TIMER_A); - LL_HRTIM_TIM_DisablePreload(HRTIM1, LL_HRTIM_TIMER_A); - LL_HRTIM_TIM_DisableResyncUpdate(HRTIM1, LL_HRTIM_TIMER_A); - LL_HRTIM_TIM_SetUpdateTrig(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_UPDATETRIG_NONE|LL_HRTIM_UPDATETRIG_NONE); - LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_RESETTRIG_MASTER_PER); - LL_HRTIM_TIM_DisablePushPullMode(HRTIM1, LL_HRTIM_TIMER_A); - LL_HRTIM_TIM_EnableDeadTime(HRTIM1, LL_HRTIM_TIMER_A); - LL_HRTIM_TIM_SetBurstModeOption(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_BURSTMODE_MAINTAINCLOCK); - LL_HRTIM_ForceUpdate(HRTIM1, LL_HRTIM_TIMER_A); - LL_HRTIM_TIM_SetCompare1(HRTIM1, LL_HRTIM_TIMER_A, 544); - LL_HRTIM_TIM_SetCompareMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_COMPAREUNIT_2, LL_HRTIM_COMPAREMODE_REGULAR); - LL_HRTIM_TIM_SetCompare2(HRTIM1, LL_HRTIM_TIMER_A, 100); - LL_HRTIM_TIM_SetCompare3(HRTIM1, LL_HRTIM_TIMER_A, 1360); - LL_HRTIM_TIM_SetCompare4(HRTIM1, LL_HRTIM_TIMER_A, 10880); - LL_HRTIM_TIM_SetCompareMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_COMPAREUNIT_4, LL_HRTIM_COMPAREMODE_REGULAR); - LL_HRTIM_TIM_SetEventFilter(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_EVENT_4, LL_HRTIM_EEFLTR_BLANKINGCMP3); - LL_HRTIM_TIM_SetEventLatchStatus(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_EVENT_4, LL_HRTIM_EELATCH_DISABLED); - LL_HRTIM_DT_SetPrescaler(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_DT_PRESCALER_DIV1); - LL_HRTIM_DT_SetRisingValue(HRTIM1, LL_HRTIM_TIMER_A, 16); - LL_HRTIM_DT_SetRisingSign(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_DT_RISING_POSITIVE); - LL_HRTIM_DT_SetFallingValue(HRTIM1, LL_HRTIM_TIMER_A, 16); - LL_HRTIM_DT_SetFallingSign(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_DT_FALLING_POSITIVE); - LL_HRTIM_OUT_SetPolarity(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUT_POSITIVE_POLARITY); - LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUTPUTSET_TIMCMP1); - LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUTPUTRESET_TIMCMP4|LL_HRTIM_OUTPUTSET_EEV_5); - LL_HRTIM_OUT_SetIdleMode(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUT_NO_IDLE); - LL_HRTIM_OUT_SetIdleLevel(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUT_IDLELEVEL_INACTIVE); - LL_HRTIM_OUT_SetFaultState(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUT_FAULTSTATE_NO_ACTION); - LL_HRTIM_OUT_SetChopperMode(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUT_CHOPPERMODE_DISABLED); - LL_HRTIM_OUT_SetPolarity(HRTIM1, LL_HRTIM_OUTPUT_TA2, LL_HRTIM_OUT_POSITIVE_POLARITY); - LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA2, LL_HRTIM_OUTPUTSET_NONE); - LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA2, LL_HRTIM_OUTPUTRESET_NONE); - LL_HRTIM_OUT_SetIdleMode(HRTIM1, LL_HRTIM_OUTPUT_TA2, LL_HRTIM_OUT_NO_IDLE); - LL_HRTIM_OUT_SetIdleLevel(HRTIM1, LL_HRTIM_OUTPUT_TA2, LL_HRTIM_OUT_IDLELEVEL_INACTIVE); - LL_HRTIM_OUT_SetFaultState(HRTIM1, LL_HRTIM_OUTPUT_TA2, LL_HRTIM_OUT_FAULTSTATE_NO_ACTION); - LL_HRTIM_OUT_SetChopperMode(HRTIM1, LL_HRTIM_OUTPUT_TA2, LL_HRTIM_OUT_CHOPPERMODE_DISABLED); - - while(LL_HRTIM_IsActiveFlag_DLLRDY(HRTIM1) == RESET) - { - // Wait - } - - LL_HRTIM_TIM_SetPrescaler(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_PRESCALERRATIO_MUL16); - LL_HRTIM_TIM_SetCounterMode(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_MODE_CONTINUOUS); - LL_HRTIM_TIM_SetPeriod(HRTIM1, LL_HRTIM_TIMER_B, 13600); - LL_HRTIM_TIM_SetRepetition(HRTIM1, LL_HRTIM_TIMER_B, 0x00); - LL_HRTIM_TIM_SetUpdateGating(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_UPDATEGATING_INDEPENDENT); - LL_HRTIM_TIM_SetCountingMode(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_COUNTING_MODE_UP); - LL_HRTIM_TIM_SetTriggeredHalfMode(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_TRIGHALF_DISABLED); - LL_HRTIM_TIM_SetComp1Mode(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_GTCMP1_EQUAL); - LL_HRTIM_TIM_SetComp3Mode(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_GTCMP3_EQUAL); - LL_HRTIM_TIM_SetDualDacResetTrigger(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_DCDR_COUNTER); - LL_HRTIM_TIM_SetDualDacStepTrigger(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_DCDS_CMP2); - LL_HRTIM_TIM_EnableDualDacTrigger(HRTIM1, LL_HRTIM_TIMER_B); - LL_HRTIM_TIM_SetDACTrig(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_DACTRIG_NONE); - LL_HRTIM_TIM_DisableHalfMode(HRTIM1, LL_HRTIM_TIMER_B); - LL_HRTIM_TIM_SetInterleavedMode(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_INTERLEAVED_MODE_DISABLED); - LL_HRTIM_TIM_DisableStartOnSync(HRTIM1, LL_HRTIM_TIMER_B); - LL_HRTIM_TIM_DisableResetOnSync(HRTIM1, LL_HRTIM_TIMER_B); - LL_HRTIM_TIM_DisablePreload(HRTIM1, LL_HRTIM_TIMER_B); - LL_HRTIM_TIM_DisableResyncUpdate(HRTIM1, LL_HRTIM_TIMER_B); - LL_HRTIM_TIM_SetUpdateTrig(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_UPDATETRIG_NONE|LL_HRTIM_UPDATETRIG_NONE); - LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_RESETTRIG_MASTER_CMP2); - LL_HRTIM_TIM_DisablePushPullMode(HRTIM1, LL_HRTIM_TIMER_B); - LL_HRTIM_TIM_EnableDeadTime(HRTIM1, LL_HRTIM_TIMER_B); - LL_HRTIM_TIM_SetBurstModeOption(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_BURSTMODE_MAINTAINCLOCK); - LL_HRTIM_ForceUpdate(HRTIM1, LL_HRTIM_TIMER_B); - LL_HRTIM_TIM_SetCompare1(HRTIM1, LL_HRTIM_TIMER_B, 544); - LL_HRTIM_TIM_SetCompareMode(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_COMPAREUNIT_2, LL_HRTIM_COMPAREMODE_REGULAR); - LL_HRTIM_TIM_SetCompare2(HRTIM1, LL_HRTIM_TIMER_B, 100); - LL_HRTIM_TIM_SetCompare3(HRTIM1, LL_HRTIM_TIMER_B, 1360); - LL_HRTIM_TIM_SetCompare4(HRTIM1, LL_HRTIM_TIMER_B, 10880); - LL_HRTIM_TIM_SetCompareMode(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_COMPAREUNIT_4, LL_HRTIM_COMPAREMODE_REGULAR); - LL_HRTIM_TIM_SetEventFilter(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_EVENT_5, LL_HRTIM_EEFLTR_BLANKINGCMP3); - LL_HRTIM_TIM_SetEventLatchStatus(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_EVENT_5, LL_HRTIM_EELATCH_DISABLED); - LL_HRTIM_DT_SetPrescaler(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_DT_PRESCALER_DIV1); - LL_HRTIM_DT_SetRisingValue(HRTIM1, LL_HRTIM_TIMER_B, 16); - LL_HRTIM_DT_SetRisingSign(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_DT_RISING_POSITIVE); - LL_HRTIM_DT_SetFallingValue(HRTIM1, LL_HRTIM_TIMER_B, 16); - LL_HRTIM_DT_SetFallingSign(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_DT_FALLING_POSITIVE); - LL_HRTIM_OUT_SetPolarity(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUT_POSITIVE_POLARITY); - LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUTPUTSET_TIMCMP1); - LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUTPUTRESET_TIMCMP4|LL_HRTIM_OUTPUTRESET_EEV_4); - LL_HRTIM_OUT_SetIdleMode(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUT_NO_IDLE); - LL_HRTIM_OUT_SetIdleLevel(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUT_IDLELEVEL_INACTIVE); - LL_HRTIM_OUT_SetFaultState(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUT_FAULTSTATE_NO_ACTION); - LL_HRTIM_OUT_SetChopperMode(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUT_CHOPPERMODE_DISABLED); - LL_HRTIM_OUT_SetPolarity(HRTIM1, LL_HRTIM_OUTPUT_TB2, LL_HRTIM_OUT_POSITIVE_POLARITY); - LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TB2, LL_HRTIM_OUTPUTSET_NONE); - LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TB2, LL_HRTIM_OUTPUTRESET_NONE); - LL_HRTIM_OUT_SetIdleMode(HRTIM1, LL_HRTIM_OUTPUT_TB2, LL_HRTIM_OUT_NO_IDLE); - LL_HRTIM_OUT_SetIdleLevel(HRTIM1, LL_HRTIM_OUTPUT_TB2, LL_HRTIM_OUT_IDLELEVEL_INACTIVE); - LL_HRTIM_OUT_SetFaultState(HRTIM1, LL_HRTIM_OUTPUT_TB2, LL_HRTIM_OUT_FAULTSTATE_NO_ACTION); - LL_HRTIM_OUT_SetChopperMode(HRTIM1, LL_HRTIM_OUTPUT_TB2, LL_HRTIM_OUT_CHOPPERMODE_DISABLED); + // Initialization of external event 4 linked to COMP1 output + LL_HRTIM_EE_SetSrc(HRTIM1, LL_HRTIM_EVENT_4, LL_HRTIM_EEV4SRC_COMP1_OUT); + LL_HRTIM_EE_SetPolarity(HRTIM1, LL_HRTIM_EVENT_4, LL_HRTIM_EE_POLARITY_HIGH); + LL_HRTIM_EE_SetSensitivity(HRTIM1, LL_HRTIM_EVENT_4, LL_HRTIM_EE_SENSITIVITY_LEVEL); + LL_HRTIM_EE_SetFastMode(HRTIM1, LL_HRTIM_EVENT_4, LL_HRTIM_EE_FASTMODE_DISABLE); + + // Initialization of external event 5 linked to COMP3 output + LL_HRTIM_EE_SetSrc(HRTIM1, LL_HRTIM_EVENT_5, LL_HRTIM_EEV5SRC_COMP3_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); } -void hrtim_cm_init_gpio() +uint16_t CM_hrtim_init(uint32_t *freq, uint16_t dead_time_ns, uint8_t leg1_upper_switch_convention, uint8_t leg2_upper_switch_convention, hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu) { - /* - HRTIM1 GPIO Configuration - PA8 ------> HRTIM1_CHA1 - PA9 ------> HRTIM1_CHA2 - PA10 ------> HRTIM1_CHB1 - PA11 ------> HRTIM1_CHB2 - */ - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); - - LL_GPIO_SetPinMode (GPIOA, LL_GPIO_PIN_8, LL_GPIO_MODE_ALTERNATE); - LL_GPIO_SetPinSpeed (GPIOA, LL_GPIO_PIN_8, LL_GPIO_SPEED_FREQ_VERY_HIGH); - LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_8, LL_GPIO_OUTPUT_PUSHPULL); - LL_GPIO_SetPinPull (GPIOA, LL_GPIO_PIN_8, LL_GPIO_PULL_NO); - LL_GPIO_SetAFPin_8_15 (GPIOA, LL_GPIO_PIN_8, LL_GPIO_AF_13); - - LL_GPIO_SetPinMode (GPIOA, LL_GPIO_PIN_9, LL_GPIO_MODE_ALTERNATE); - LL_GPIO_SetPinSpeed (GPIOA, LL_GPIO_PIN_9, LL_GPIO_SPEED_FREQ_VERY_HIGH); - LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_9, LL_GPIO_OUTPUT_PUSHPULL); - LL_GPIO_SetPinPull (GPIOA, LL_GPIO_PIN_9, LL_GPIO_PULL_NO); - LL_GPIO_SetAFPin_8_15 (GPIOA, LL_GPIO_PIN_9, LL_GPIO_AF_13); - - LL_GPIO_SetPinMode (GPIOA, LL_GPIO_PIN_10, LL_GPIO_MODE_ALTERNATE); - LL_GPIO_SetPinSpeed (GPIOA, LL_GPIO_PIN_10, LL_GPIO_SPEED_FREQ_VERY_HIGH); - LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_10, LL_GPIO_OUTPUT_PUSHPULL); - LL_GPIO_SetPinPull (GPIOA, LL_GPIO_PIN_10, LL_GPIO_PULL_NO); - LL_GPIO_SetAFPin_8_15 (GPIOA, LL_GPIO_PIN_10, LL_GPIO_AF_13); - - LL_GPIO_SetPinMode (GPIOA, LL_GPIO_PIN_11, LL_GPIO_MODE_ALTERNATE); - LL_GPIO_SetPinSpeed (GPIOA, LL_GPIO_PIN_11, LL_GPIO_SPEED_FREQ_VERY_HIGH); - LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_11, LL_GPIO_OUTPUT_PUSHPULL); - LL_GPIO_SetPinPull (GPIOA, LL_GPIO_PIN_11, LL_GPIO_PULL_NO); - LL_GPIO_SetAFPin_8_15 (GPIOA, LL_GPIO_PIN_11, LL_GPIO_AF_13); + /* Master timer initialization */ + uint16_t period = hrtim_init_master(0, freq); + + /* External event initialization */ + _CM_init_EEV(); + + /* Dual DAC trigger initialization */ + CM_DualDAC_init(leg1_tu); + CM_DualDAC_init(leg2_tu); + + /* Timer initialization for leg 1 */ + hrtim_init_tu(0, leg1_tu, freq, Lft_aligned); + hrtim_pwm_dt(0, leg1_tu, dead_time_ns, dead_time_ns); // Set the dead time. Note: this must be done before enable counter + hrtim_cnt_en(0, leg1_tu); // Enable counter + hrtim_rst_evt_en(0, leg1_tu, LL_HRTIM_RESETTRIG_MASTER_PER); // We synchronize the leg1 with the master timer, with a reset on period event + + /* Timer initialization for leg 2 */ + hrtim_init_tu(0, leg2_tu, freq, Lft_aligned); + hrtim_pwm_dt(0, leg2_tu, dead_time_ns, dead_time_ns); // Set the dead time. Note: this must be done before enable counter + hrtim_cnt_en(0, leg2_tu); // Enable the counter + hrtim_rst_evt_en(0, leg2_tu, LL_HRTIM_RESETTRIG_MASTER_PER); // We synchronize the leg2 with the master timer, with a reset on period event + + CM_hrtim_pwm_leg1(leg1_tu, leg1_upper_switch_convention, Lft_aligned); // Set the convention for leg 1 + CM_hrtim_pwm_leg2(leg2_tu, leg2_upper_switch_convention, Lft_aligned); // Set the convention for leg 2 + + return period; +} + +void CM_hrtim_pwm_set(hrtim_tu_t tu, uint16_t shift) +{ + static uint16_t prev_shift[HRTIM_STU_NUMOF]; + + uint8_t tu_n = _CM_TU_num(tu); // timing unit number + uint32_t duty_cycle_max; // Duty_cycle max set to 0.9 + uint32_t Sawtooth_step; // Fix the number of step for the sawtooth + + /* Set the duty_cycle max with comparator 1 */ + duty_cycle_max = LL_HRTIM_TIM_GetPeriod(HRTIM1, tu) * 0.9; + LL_HRTIM_TIM_SetCompare1(HRTIM1, tu, duty_cycle_max); + + /* Set the number of step with comparator 2 */ + Sawtooth_step = LL_HRTIM_TIM_GetPeriod(HRTIM1, tu) / 100; // divided by 100 to have hundred steps + LL_HRTIM_TIM_SetCompare2(HRTIM1, tu, Sawtooth_step); + + /* Compare 4 is used to set the PWM */ + LL_HRTIM_TIM_SetCompare4(HRTIM1, tu, 1088); + + if (shift != prev_shift[tu_n]) + { + prev_shift[tu_n] = shift; + + /* Set reset comparator for phase positioning */ + if (shift) + { + LL_HRTIM_TIM_SetResetTrig(HRTIM1, tu, LL_HRTIM_TIM_GetResetTrig(HRTIM1, tu) & ~LL_HRTIM_RESETTRIG_MASTER_PER); + switch (tu) + { + /* Timer A is the phase shift reference so it can't be phase + * shifted */ + case TIMB: /* Timer B reset on master cmp1 */ + LL_HRTIM_TIM_SetCompare1(HRTIM1, LL_HRTIM_TIMER_MASTER, shift); + LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_RESETTRIG_MASTER_CMP1); + break; + case TIMC: /* Timer C reset on master cmp2 */ + LL_HRTIM_TIM_SetCompare2(HRTIM1, LL_HRTIM_TIMER_MASTER, shift); + LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_C, LL_HRTIM_RESETTRIG_MASTER_CMP2); + break; + case TIMD: /* Timer D reset on master cmp3 */ + LL_HRTIM_TIM_SetCompare3(HRTIM1, LL_HRTIM_TIMER_MASTER, shift); + LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_D, LL_HRTIM_RESETTRIG_MASTER_CMP3); + break; + case TIME: /* Timer E reset on master cmp4 */ + LL_HRTIM_TIM_SetCompare4(HRTIM1, LL_HRTIM_TIMER_MASTER, shift); + LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_E, LL_HRTIM_RESETTRIG_MASTER_CMP4); + break; + #if (HRTIM_STU_NUMOF == 6) + case TIMF: /* Timer F reset on timerA cmp2 */ + LL_HRTIM_TIM_SetCompare2(HRTIM1, LL_HRTIM_TIMER_A, shift); + LL_HRTIM_TIM_SetResetTrig(HRTIM1, tu, LL_HRTIM_RESETTRIG_OTHER1_CMP2); + break; + #endif + default: + break; + } + } + else if (LL_HRTIM_TIM_GetPeriod(HRTIM1, LL_HRTIM_TIMER_MASTER) == LL_HRTIM_TIM_GetPeriod(HRTIM1, tu) && LL_HRTIM_TIM_GetPrescaler(HRTIM1, LL_HRTIM_TIMER_MASTER) == LL_HRTIM_TIM_GetPrescaler(HRTIM1, tu)) + { + /* shift == 0 and timing unit run at the same frequency as master */ + switch (tu) + { + case TIMB: + LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_TIM_GetResetTrig(HRTIM1, LL_HRTIM_TIMER_B) & ~LL_HRTIM_RESETTRIG_MASTER_CMP1); + break; + case TIMC: + LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_C, LL_HRTIM_TIM_GetResetTrig(HRTIM1, LL_HRTIM_TIMER_C) & ~LL_HRTIM_RESETTRIG_MASTER_CMP2); + break; + case TIMD: + LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_D, LL_HRTIM_TIM_GetResetTrig(HRTIM1, LL_HRTIM_TIMER_D) & ~LL_HRTIM_RESETTRIG_MASTER_CMP3); + break; + case TIME: + LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_E, LL_HRTIM_TIM_GetResetTrig(HRTIM1, LL_HRTIM_TIMER_E) & ~LL_HRTIM_RESETTRIG_MASTER_CMP4); + break; + #if (HRTIM_STU_NUMOF == 6) + case TIMF: + LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_TIM_GetResetTrig(HRTIM1, LL_HRTIM_TIMER_F) & ~LL_HRTIM_RESETTRIG_OTHER1_CMP2); + break; + #endif + default: + break; + } + LL_HRTIM_TIM_SetResetTrig(HRTIM1, tu, LL_HRTIM_RESETTRIG_MASTER_PER); + } + else + { + /* timing unit do not run at the same frequency as master so + * phase positioning is not applicable */ + LL_HRTIM_TIM_SetResetTrig(HRTIM1, tu, LL_HRTIM_TIM_GetResetTrig(HRTIM1, tu) & ~LL_HRTIM_RESETTRIG_MASTER_PER); + } + } +} + +void CM_hrtim_pwm_leg1(hrtim_tu_t tu, bool leg_upper_switch_convention, hrtim_cnt_t cnt_mode) +{ + // Configuration for the upper switch convention in buck mode + // For a selected timing unit, leg1 will set on CMP4 and reset on CMP1 (max duty_cyle) or EEV4 (COMP1 output) + if (leg_upper_switch_convention == true) + { + switch (tu) + { + case TIMA: + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_4); + break; + + case TIMB: + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_4); + break; + + case TIMC: + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TC1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TC1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_4); + break; + + case TIMD: + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TD1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TD1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_4); + break; + + case TIME: + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TE1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TE1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_4); + break; + + case TIMF: + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_4); + break; + + default: + break; + } + } + + // Configuration for the upper switch convention in boost mode + // For a selected timing unit, leg1 will reset on CMP4 and set on CMP1 (max duty_cyle) or EEV4 (COMP1 output) + else if (leg_upper_switch_convention == false) + { + switch (tu) + { + case TIMA: + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_4); + break; + + case TIMB: + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_4); + break; + + case TIMC: + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TC1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TC1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_4); + break; + + case TIMD: + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TD1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TD1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_4); + break; + + case TIME: + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TE1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TE1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_4); + break; + + case TIMF: + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_4); + break; + + default: + break; + } + } +} + +void CM_hrtim_pwm_leg2(hrtim_tu_t tu, bool leg_upper_switch_convention, hrtim_cnt_t cnt_mode) +{ + // Configuration for the upper switch convention in buck mode + // For a selected timing unit, leg1 will set on CMP4 and reset on CMP1 (max duty_cyle) or EEV5 (COMP3 output) + if (leg_upper_switch_convention == true) + { + switch (tu) + { + case TIMA: + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_5); + break; + + case TIMB: + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_5); + break; + + case TIMC: + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TC1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TC1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_5); + break; + + case TIMD: + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TD1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TD1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_5); + break; + + case TIME: + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TE1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TE1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_5); + break; + + case TIMF: + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_5); + break; + + default: + break; + } + } + + // Configuration for the upper switch convention in boost mode + // For a selected timing unit, leg1 will reset on CMP4 and set on CMP1 (max duty_cyle) or EEV5 (COMP3 output) + else if (leg_upper_switch_convention == false) + { + switch (tu) + { + case TIMA: + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_5); + break; + + case TIMB: + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TB1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_5); + break; + + case TIMC: + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TC1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TC1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_5); + break; + + case TIMD: + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TD1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TD1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_5); + break; + + case TIME: + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TE1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TE1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_5); + break; + + case TIMF: + LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUTPUTSET_TIMCMP4); + LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TF1, LL_HRTIM_OUTPUTRESET_TIMCMP1 | LL_HRTIM_OUTPUTRESET_EEV_5); + break; + + default: + break; + } + } } -void hrtim_cm_enable() +void CM_DualDAC_init(hrtim_tu_t tu) { - /* Start Master Timer counter*/ - LL_HRTIM_TIM_CounterEnable(HRTIM1, LL_HRTIM_TIMER_MASTER); + switch (tu) + { + case TIMA: + LL_HRTIM_TIM_SetDualDacResetTrigger(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_DCDR_COUNTER); + LL_HRTIM_TIM_SetDualDacStepTrigger(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_DCDS_CMP2); + LL_HRTIM_TIM_EnableDualDacTrigger(HRTIM1, LL_HRTIM_TIMER_A); + break; - /* Start PWM output counter */ - LL_HRTIM_TIM_CounterEnable(HRTIM1, LL_HRTIM_TIMER_A); + case TIMB: + LL_HRTIM_TIM_SetDualDacResetTrigger(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_DCDR_COUNTER); + LL_HRTIM_TIM_SetDualDacStepTrigger(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_DCDS_CMP2); + LL_HRTIM_TIM_EnableDualDacTrigger(HRTIM1, LL_HRTIM_TIMER_B); + break; - /* Start PWM output signal TA1 */ - LL_HRTIM_EnableOutput(HRTIM1, LL_HRTIM_OUTPUT_TA1); + case TIMC: + LL_HRTIM_TIM_SetDualDacResetTrigger(HRTIM1, LL_HRTIM_TIMER_C, LL_HRTIM_DCDR_COUNTER); + LL_HRTIM_TIM_SetDualDacStepTrigger(HRTIM1, LL_HRTIM_TIMER_C, LL_HRTIM_DCDS_CMP2); + LL_HRTIM_TIM_EnableDualDacTrigger(HRTIM1, LL_HRTIM_TIMER_C); + break; - /* Start PWM output signal TA2 */ - LL_HRTIM_EnableOutput(HRTIM1, LL_HRTIM_OUTPUT_TA2); + case TIMD: + LL_HRTIM_TIM_SetDualDacResetTrigger(HRTIM1, LL_HRTIM_TIMER_D, LL_HRTIM_DCDR_COUNTER); + LL_HRTIM_TIM_SetDualDacStepTrigger(HRTIM1, LL_HRTIM_TIMER_D, LL_HRTIM_DCDS_CMP2); + LL_HRTIM_TIM_EnableDualDacTrigger(HRTIM1, LL_HRTIM_TIMER_D); + break; - /* Start PWM output counter */ - LL_HRTIM_TIM_CounterEnable(HRTIM1, LL_HRTIM_TIMER_B); + case TIME: + LL_HRTIM_TIM_SetDualDacResetTrigger(HRTIM1, LL_HRTIM_TIMER_E, LL_HRTIM_DCDR_COUNTER); + LL_HRTIM_TIM_SetDualDacStepTrigger(HRTIM1, LL_HRTIM_TIMER_E, LL_HRTIM_DCDS_CMP2); + LL_HRTIM_TIM_EnableDualDacTrigger(HRTIM1, LL_HRTIM_TIMER_E); + break; - /* Start PWM output signal TB1 */ - LL_HRTIM_EnableOutput(HRTIM1, LL_HRTIM_OUTPUT_TB1); + case TIMF: + LL_HRTIM_TIM_SetDualDacResetTrigger(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_DCDR_COUNTER); + LL_HRTIM_TIM_SetDualDacStepTrigger(HRTIM1, LL_HRTIM_TIMER_F, LL_HRTIM_DCDS_CMP2); + LL_HRTIM_TIM_EnableDualDacTrigger(HRTIM1, LL_HRTIM_TIMER_F); + break; - /* Start PWM output signal TB2 */ - LL_HRTIM_EnableOutput(HRTIM1, LL_HRTIM_OUTPUT_TB2); + default: + break; + } } diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/src/current_mode/hrtim_current_mode.h b/zephyr/modules/owntech_hrtim_driver/zephyr/src/current_mode/hrtim_current_mode.h index 39c4c6b..725b2ae 100644 --- a/zephyr/modules/owntech_hrtim_driver/zephyr/src/current_mode/hrtim_current_mode.h +++ b/zephyr/modules/owntech_hrtim_driver/zephyr/src/current_mode/hrtim_current_mode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 LAAS-CNRS + * Copyright (c) 2020-2023 LAAS-CNRS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,19 +18,79 @@ */ /** + * @date 2023 * @author Clément Foucher <clement.foucher@laas.fr> + * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> */ +// voltage_mode header +#include "../voltage_mode/hrtim_voltage_mode.h" + #ifndef HRTIM_CURRENT_MODE_H_ #define HRTIM_CURRENT_MODE_H_ -#ifdef __cplusplus + +#ifdef __cplusplus extern "C" { #endif -void hrtim_cm_init(); -void hrtim_cm_init_gpio(); -void hrtim_cm_enable(); +/** + * @brief Initialize dual DAC reset and trigger. The selected timing unit CMP2 + * will trigger the step (Decrement/Increment of sawtooth) and the reset + * (return to initial value). + * + * @param[in] tu timing unit + */ +void CM_DualDAC_init(hrtim_tu_t tu); + + +/** + * @brief This function manage the set/reset crossbar of a timing unit, according to the leg + * convention (buck or boost). The leg1 is linked to EEV4 (COMP1 output) + * + * @param[in] tu timing unit + * @param[in] leg_upper_switch_convention 1-->buck and 0-->boost + * @param[in] cnt_mode left aligned or center aligned + * + */ +void CM_hrtim_pwm_leg1(hrtim_tu_t tu, bool leg_upper_switch_convention, hrtim_cnt_t cnt_mode); + +/** + * @brief This function manage the set/reset crossbar of a timing unit, according to the leg + * convention (buck or boost). The leg2 is linked to EEV5 (COMP3 output) + * + * @param[in] tu timing unit + * @param[in] leg_upper_switch_convention 1-->buck and 0-->boost + * @param[in] cnt_mode left aligned or center aligned + * + */ +void CM_hrtim_pwm_leg2(hrtim_tu_t tu, bool leg_upper_switch_convention, hrtim_cnt_t cnt_mode); + + +/** + * @brief Initialize an HRTIM device and all these timing units for + * complementary pwm outputs with a dead time. + * + * @param[inout] freq HRTIM frequency in Hz + * @param[in] dt 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: + * @param[in] leg2_upper_switch_convention Choice of the switch convention for leg 2, can be one of the following values: + * @param[in] leg1_tu Timer for leg 1 + * @param[in] leg2_tu Timer for leg 2 + * @return actual HRTIM resolution on success + * @return 0 on error + */ +uint16_t CM_hrtim_init(uint32_t *freq, uint16_t dead_time_ns, uint8_t leg1_upper_switch_convention, uint8_t leg2_upper_switch_convention, hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu); + +/** + * @brief Set the phase shift for a given + * timing unit + * + * @param[in] dev HRTIM device + * @param[in] tu Timing unit + * @param[in] shift Phase shifting + */ +void CM_hrtim_pwm_set(hrtim_tu_t tu, uint16_t shift); #ifdef __cplusplus } diff --git a/zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim_common.c b/zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim_common.c index b724b24..f0e1887 100644 --- a/zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim_common.c +++ b/zephyr/modules/owntech_hrtim_driver/zephyr/src/hrtim_common.c @@ -43,10 +43,10 @@ void _hrtim_init_events(hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu) { if(leg1_tu == TIMA && leg2_tu == TIMB){ hrtim_adc_trigger_en(1, 1, LL_HRTIM_ADCTRIG_SRC13_TIMACMP3); - hrtim_adc_trigger_en(3, 2, LL_HRTIM_ADCTRIG_SRC13_TIMBCMP4); + hrtim_adc_trigger_en(3, 2, LL_HRTIM_ADCTRIG_SRC13_TIMBCMP3); }else if(leg1_tu == TIMA && leg2_tu == TIMC){ hrtim_adc_trigger_en(3, 1, LL_HRTIM_ADCTRIG_SRC13_TIMACMP3); - hrtim_adc_trigger_en(1, 3, LL_HRTIM_ADCTRIG_SRC13_TIMCCMP4); + hrtim_adc_trigger_en(1, 3, LL_HRTIM_ADCTRIG_SRC13_TIMCCMP3); } hrtim_update_adc_trig_interleaved(1, leg1_tu, leg2_tu); @@ -86,10 +86,10 @@ void hrtim_update_adc_trig_interleaved(uint16_t new_trig, hrtim_tu_t leg1_tu, hr { if(leg1_tu == TIMA && leg2_tu == TIMB){ hrtim_cmp_set(0, TIMA, CMP3xR, new_trig); - hrtim_cmp_set(0, TIMB, CMP4xR, new_trig); + hrtim_cmp_set(0, TIMB, CMP3xR, new_trig); }else if(leg1_tu == TIMA && leg2_tu == TIMC){ hrtim_cmp_set(0, TIMA, CMP3xR, new_trig); - hrtim_cmp_set(0, TIMC, CMP4xR, new_trig); + hrtim_cmp_set(0, TIMC, CMP3xR, new_trig); } } @@ -131,11 +131,10 @@ uint32_t hrtim_PeriodicEvent_GetRep(hrtim_tu_t tu_src) return LL_HRTIM_TIM_GetRepetition(HRTIM1, tu_src)+1; } -void hrtim_init_current() +void hrtim_init_current(bool leg1_convention, bool leg2_convention, hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu) { - hrtim_cm_init(); - hrtim_cm_init_gpio(); - hrtim_cm_enable(); + leg_init_CM(leg1_convention, leg2_convention, leg1_tu, leg2_tu); + _hrtim_init_events(leg1_tu, leg2_tu); } void hrtim_init_voltage_buck(hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu) 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 0874fe2..bd61df1 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 @@ -25,13 +25,14 @@ * @author Hugues Larrive <hugues.larrive@laas.fr> * @author Antoine Boche <antoine.boche@laas.fr> * @author Luiz Villa <luiz.villa@laas.fr> - * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> * @author Clément Foucher <clement.foucher@laas.fr> + * @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr> */ #include "leg.h" #include "owntech_leg_driver.h" #include "hrtim_voltage_mode.h" +#include "../current_mode/hrtim_current_mode.h" // Saturation values used for the PWM duty cycle #define LOW_DUTY 0.03 @@ -120,6 +121,24 @@ uint16_t leg_init_center_aligned(bool leg1_upper_switch_convention, bool leg2_up return period; } +/** + * This function Initialize in current mode the hrtim and all the legs + * with the chosen convention for the switch controlled on the power + * converter to a frequency of 200kHz + */ +uint16_t leg_init_CM(bool leg1_upper_switch_convention, bool leg2_upper_switch_convention, hrtim_tu_t leg1_tu, hrtim_tu_t leg2_tu) +{ + /* 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 = CM_hrtim_init(&frequency, LEG_DEFAULT_DT,leg1_upper_switch_convention,leg2_upper_switch_convention, leg1_tu, leg2_tu); + + return period; +} + void leg_set(hrtim_tu_t timing_unit, uint16_t pulse_width, uint16_t phase_shift) { //addition of the dead time for the rectification of the centered dead time configuration cf:hrtim_pwm_dt() @@ -143,6 +162,11 @@ 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 CM_leg_set(hrtim_tu_t timing_unit, uint16_t phase_shift) +{ + CM_hrtim_pwm_set( timing_unit,phase_shift); +} + 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() -- GitLab