Commit cd13dd01 authored by Ayoub Farah Hassan's avatar Ayoub Farah Hassan Committed by Clément Foucher
Browse files

Revision of HRTIM.

Rewrote hrtim driver with LL APIs. Added Up-down mode (center aligned PWM) for buck, boost and independent mode. Corrected initialization errors for independent mode.
parent a6d5fcf1
......@@ -22,6 +22,7 @@
*
* @author Clément Foucher <clement.foucher@laas.fr>
* @author Luiz Villa <luiz.villa@laas.fr>
* @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr>
*/
......@@ -130,26 +131,51 @@ void HardwareConfiguration::initInterleavedBuckMode()
hrtim_init_interleaved_buck_mode();
}
void HardwareConfiguration::initInterleavedBuckModeCenterAligned()
{
hrtim_init_interleaved_buck_mode_center_aligned();
}
void HardwareConfiguration::initInterleavedBoostMode()
{
hrtim_init_interleaved_boost_mode();
}
void HardwareConfiguration::initInterleavedBoostModeCenterAligned()
{
hrtim_init_interleaved_boost_mode_center_aligned();
}
void HardwareConfiguration::initFullBridgeBuckMode()
{
hrtim_init_interleaved_buck_mode();
}
void HardwareConfiguration::initFullBridgeBuckModeCenterAligned()
{
hrtim_init_interleaved_buck_mode_center_aligned();
}
void HardwareConfiguration::initFullBridgeBoostMode()
{
hrtim_init_interleaved_boost_mode();
}
void HardwareConfiguration::initFullBridgeBoostModeCenterAligned()
{
hrtim_init_interleaved_boost_mode_center_aligned();
}
void HardwareConfiguration::initIndependentMode(bool leg1_buck_mode, bool leg2_buck_mode)
{
hrtim_init_independent_mode(leg1_buck_mode, leg2_buck_mode);
}
void HardwareConfiguration::initIndependentModeCenterAligned(bool leg1_buck_mode, bool leg2_buck_mode)
{
hrtim_init_independent_mode_center_aligned(leg1_buck_mode, leg2_buck_mode);
}
void HardwareConfiguration::setInterleavedDutyCycle(float32_t duty_cycle)
{
hrtim_interleaved_pwm_update(duty_cycle);
......
......@@ -22,6 +22,7 @@
*
* @author Clément Foucher <clement.foucher@laas.fr>
* @author Luiz Villa <luiz.villa@laas.fr>
* @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr>
*/
......@@ -78,10 +79,15 @@ public:
// Power converter
static void initInterleavedBuckMode();
static void initInterleavedBuckModeCenterAligned();
static void initInterleavedBoostMode();
static void initInterleavedBoostModeCenterAligned();
static void initFullBridgeBuckMode();
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 setInterleavedDutyCycle(float32_t duty_cycle);
static void setFullBridgeDutyCycle(float32_t duty_cycle);
......
......@@ -21,6 +21,7 @@
* @date 2022
* @author Luiz Villa <luiz.villa@laas.fr>
* @author Clément Foucher <clement.foucher@laas.fr>
* @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr>
*/
......@@ -60,6 +61,19 @@ void hrtim_init_interleaved_buck_mode()
pwm_high_pulse_width = pwm_period * HIGH_DUTY;
}
/**
* This function initializes both legs in buck mode in up-down mode
*/
void hrtim_init_interleaved_buck_mode_center_aligned()
{
hrtim_init_voltage_buck_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;
}
/**
* This function initializes both legs in boost mode
*/
......@@ -73,6 +87,16 @@ void hrtim_init_interleaved_boost_mode()
pwm_high_pulse_width = pwm_period * HIGH_DUTY;
}
void hrtim_init_interleaved_boost_mode_center_aligned()
{
hrtim_init_voltage_boost_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;
}
/**
* This leg initializes each leg independently. It receives the modes of each leg and triggers them accordingly.
*/
......@@ -85,6 +109,12 @@ void hrtim_init_independent_mode(bool leg1_buck_mode, bool leg2_buck_mode)
else if (!leg1_buck_mode && leg2_buck_mode){
hrtim_init_voltage_leg1_boost_leg2_buck();
}
else if (leg1_buck_mode && leg2_buck_mode){
hrtim_init_voltage_buck();
}
else if (!leg1_buck_mode && !leg2_buck_mode){
hrtim_init_voltage_boost();
}
pwm_period = leg_period();
pwm_phase_shift = pwm_period / 2;
......@@ -92,6 +122,31 @@ void hrtim_init_independent_mode(bool leg1_buck_mode, bool leg2_buck_mode)
pwm_high_pulse_width = pwm_period * HIGH_DUTY;
}
/**
* This leg initializes each leg independently. It receives the modes of each leg and triggers them accordingly.
* The counting mode is set to up-down (center aligned).
*/
void hrtim_init_independent_mode_center_aligned(bool leg1_buck_mode, bool leg2_buck_mode)
{
// High resolution timer initialization
if (leg1_buck_mode && !leg2_buck_mode){
hrtim_init_voltage_leg1_buck_leg2_boost_center_aligned();
}
else if (!leg1_buck_mode && leg2_buck_mode){
hrtim_init_voltage_leg1_boost_leg2_buck_center_aligned();
}
else if (leg1_buck_mode && leg2_buck_mode){
hrtim_init_voltage_buck_center_aligned();
}
else if (!leg1_buck_mode && !leg2_buck_mode){
hrtim_init_voltage_boost_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;
}
/**
......
......@@ -36,18 +36,39 @@
*/
void hrtim_init_interleaved_buck_mode();
/**
* @brief This function initializes the converter in interleaved buck mode
* with the input on the high side and the output on the low side. The counting mode
* is set to up-down (center aligned).
*/
void hrtim_init_interleaved_buck_mode_center_aligned();
/**
* @brief This function initializes the converter in interleaved boost mode
* with the input on the low side and the output on the high side
*/
void hrtim_init_interleaved_boost_mode();
/**
* @brief This function initializes the converter in interleaved boost mode
* with the input on the low side and the output on the high side. The counting mode
* is set to up-down (center aligned).
*/
void hrtim_init_interleaved_boost_mode_center_aligned();
/**
* @brief This function initializes the converter in independent mode
* the user must define the mode for each leg separetely
*/
void hrtim_init_independent_mode(bool leg1_buck_mode, bool leg2_buck_mode);
/**
* @brief This function initializes the converter in independent mode
* the user must define the mode for each leg separetely. The counting mode
* is set to up-down (center aligned).
*/
void hrtim_init_independent_mode_center_aligned(bool leg1_buck_mode, bool leg2_buck_mode);
/**
* @brief This function transfer the calculated PWM value to the
* HRTIM peripheral and make sure it is between saturation
......
......@@ -20,6 +20,7 @@
/**
* @author Clément Foucher <clement.foucher@laas.fr>
* @author Luiz Villa <luiz.villa@laas.fr>
* @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr>
*/
#ifndef HRTIM_H_
......@@ -28,6 +29,8 @@
#include <stdint.h>
#include <stm32_ll_hrtim.h>
#ifdef __cplusplus
extern "C" {
......@@ -53,15 +56,15 @@ typedef unsigned int hrtim_t;
* @brief HRTIM timing units definition
*/
typedef enum {
TIMA,
TIMB,
TIMC,
TIMD,
TIME,
TIMA = LL_HRTIM_TIMER_A,
TIMB = LL_HRTIM_TIMER_B,
TIMC = LL_HRTIM_TIMER_C,
TIMD = LL_HRTIM_TIMER_D,
TIME = LL_HRTIM_TIMER_E,
#if (HRTIM_STU_NUMOF == 6)
TIMF,
TIMF = LL_HRTIM_TIMER_F,
#endif
MSTR
MSTR = LL_HRTIM_TIMER_MASTER
} hrtim_tu_t;
......@@ -80,9 +83,13 @@ void hrtim_pwm_set(hrtim_t dev, hrtim_tu_t tu, uint16_t value, uint16_t shift);
void hrtim_init_current();
void hrtim_init_voltage_buck();
void hrtim_init_voltage_buck_center_aligned();
void hrtim_init_voltage_boost();
void hrtim_init_voltage_boost_center_aligned();
void hrtim_init_voltage_leg1_buck_leg2_boost();
void hrtim_init_voltage_leg1_buck_leg2_boost_center_aligned();
void hrtim_init_voltage_leg1_boost_leg2_buck();
void hrtim_init_voltage_leg1_boost_leg2_buck_center_aligned();
void hrtim_update_adc_trig_interleaved(uint16_t new_trig);
......
......@@ -29,6 +29,7 @@
* @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>
*/
#ifndef LEG_H_
......@@ -68,6 +69,16 @@ typedef struct {
*/
uint16_t leg_init(bool leg1_upper_switch_convention, bool leg2_upper_switch_convention);
/**
* @brief Initializes all the configured devices with up-down mode and the chosen switch convention
*
* @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_center_aligned(bool leg1_upper_switch_convention, bool leg2_upper_switch_convention);
/**
* @brief Set the PWM pulse width for a given leg device
*
......
......@@ -22,6 +22,7 @@
*
* @author Clément Foucher <clement.foucher@laas.fr>
* @author Luiz Villa <luiz.villa@laas.fr>
* @author Ayoub Farah Hassan <ayoub.farah-hassan@laas.fr>
*/
#include <stm32_ll_hrtim.h>
......@@ -38,6 +39,18 @@ void _hrtim_init_events()
hrtim_update_adc_trig_interleaved(1);
}
void _hrtim_init_events_center_aligned()
{
// setting the adc roll-over mode on period event
LL_HRTIM_TIM_SetADCRollOverMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_ROLLOVER_MODE_PER);
LL_HRTIM_TIM_SetADCRollOverMode(HRTIM1, LL_HRTIM_TIMER_B, LL_HRTIM_ROLLOVER_MODE_PER);
// setting adc trigger
hrtim_adc_trigger_en(1, 1, LL_HRTIM_ADCTRIG_SRC13_TIMAPER);
hrtim_adc_trigger_en(3, 2, LL_HRTIM_ADCTRIG_SRC13_TIMBPER);
}
void hrtim_update_adc_trig_interleaved(uint16_t new_trig)
{
hrtim_cmp_set(0, TIMA, CMP3xR, new_trig);
......@@ -58,20 +71,44 @@ void hrtim_init_voltage_buck()
_hrtim_init_events();
}
void hrtim_init_voltage_buck_center_aligned()
{
leg_init_center_aligned(true,true);
_hrtim_init_events_center_aligned();
}
void hrtim_init_voltage_boost()
{
leg_init(false,false);
_hrtim_init_events();
}
void hrtim_init_voltage_boost_center_aligned()
{
leg_init_center_aligned(false,false);
_hrtim_init_events_center_aligned();
}
void hrtim_init_voltage_leg1_buck_leg2_boost()
{
leg_init(true,false);
_hrtim_init_events();
}
void hrtim_init_voltage_leg1_buck_leg2_boost_center_aligned()
{
leg_init_center_aligned(true,false);
_hrtim_init_events_center_aligned();
}
void hrtim_init_voltage_leg1_boost_leg2_buck()
{
leg_init(false,true);
_hrtim_init_events();
}
void hrtim_init_voltage_leg1_boost_leg2_buck_center_aligned()
{
leg_init_center_aligned(false,true);
_hrtim_init_events_center_aligned();
}
......@@ -25,6 +25,7 @@
* @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>
*/
#include "leg.h"
......@@ -36,6 +37,34 @@ static uint16_t period, min_pw, max_pw, dead_time;
static leg_conf_t leg_conf[6]; /* a copy of leg_config with index
* corresponding to timing unit */
static uint8_t _TU_num(hrtim_tu_t tu){
switch(tu){
case TIMA:
return 0;
case TIMB:
return 1;
case TIMC:
return 2;
case TIMD:
return 3;
break;
case TIME:
return 4;
case TIMF:
return 5;
default:
return 100;
}
}
/**
* This function Initialize the hrtim and all the legs
* with the chosen convention for the switch controlled
......@@ -49,7 +78,7 @@ uint16_t leg_init(bool leg1_upper_switch_convention, bool leg2_upper_switch_conv
/* ensures that timing_unit can be used as leg identifier */
for (unsigned int i = 0; i < LEG_NUMOF; i++)
{
leg_conf[leg_config[i].timing_unit] = leg_config[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);
......@@ -59,6 +88,30 @@ uint16_t leg_init(bool leg1_upper_switch_convention, bool leg2_upper_switch_conv
return period;
}
/**
* This function Initialize the hrtim and all the legs
* with the chosen convention for the switch controlled
* on the power converter to a frequency of 200kHz
* with the counter on up-down mode (center-alligned)
* Must be initialized in first position
*/
uint16_t leg_init_center_aligned(bool leg1_upper_switch_convention, bool leg2_upper_switch_convention)
{
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);
dead_time = (period*LEG_DEFAULT_DT*leg_get_freq())/1000000;
min_pw = (period * 0.1) + dead_time;
max_pw = (period * 0.9) + dead_time;
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()
......@@ -74,24 +127,24 @@ void leg_set(hrtim_tu_t timing_unit, uint16_t pulse_width, uint16_t phase_shift)
pulse_width = max_pw;
}
hrtim_pwm_set( leg_conf[timing_unit].hrtim,
hrtim_pwm_set( leg_conf[_TU_num(timing_unit)].hrtim,
timing_unit,
pulse_width,
phase_shift);
/* save the pulse_width */
leg_conf[timing_unit].pulse_width = pulse_width;
leg_conf[_TU_num(timing_unit)].pulse_width = pulse_width;
}
void leg_stop(hrtim_tu_t timing_unit)
{
hrtim_out_dis(leg_conf[timing_unit].hrtim, leg_conf[timing_unit].timing_unit, OUT1);
hrtim_out_dis(leg_conf[timing_unit].hrtim, leg_conf[timing_unit].timing_unit, OUT2);
hrtim_out_dis(leg_conf[_TU_num(timing_unit)].hrtim, leg_conf[_TU_num(timing_unit)].timing_unit, OUT1);
hrtim_out_dis(leg_conf[_TU_num(timing_unit)].hrtim, leg_conf[_TU_num(timing_unit)].timing_unit, OUT2);
}
void leg_start(hrtim_tu_t timing_unit)
{
hrtim_out_en(leg_conf[timing_unit].hrtim, leg_conf[timing_unit].timing_unit, OUT1);
hrtim_out_en(leg_conf[timing_unit].hrtim, leg_conf[timing_unit].timing_unit, OUT2);
hrtim_out_en(leg_conf[_TU_num(timing_unit)].hrtim, leg_conf[_TU_num(timing_unit)].timing_unit, OUT1);
hrtim_out_en(leg_conf[_TU_num(timing_unit)].hrtim, leg_conf[_TU_num(timing_unit)].timing_unit, OUT2);
}
uint16_t leg_period(void)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment