fan_ctrl_dc: bypass the DC/DC when 100% fan speed is requested

This commit is contained in:
Thomas Kolb 2024-02-09 19:06:50 +01:00
parent b818b20099
commit 7a62eb9d11
2 changed files with 42 additions and 5 deletions

View file

@ -3,9 +3,14 @@
#include "fan_ctrl_dc.h" #include "fan_ctrl_dc.h"
#include "pinout.h" #include "pinout.h"
uint8_t m_last_step;
bool m_enabled;
void fan_ctrl_dc_init(void) void fan_ctrl_dc_init(void)
{ {
m_last_step = 0;
m_enabled = false;
// configure the GPIOs: DC/DC disabled by default // configure the GPIOs: DC/DC disabled by default
gpio_clear(DCDC_PORT, DCDC_EN_PIN); gpio_clear(DCDC_PORT, DCDC_EN_PIN);
gpio_mode_setup(DCDC_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, DCDC_EN_PIN); gpio_mode_setup(DCDC_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, DCDC_EN_PIN);
@ -16,20 +21,28 @@ void fan_ctrl_dc_init(void)
gpio_clear(DCDC_PORT, DCDC_CTRL_FB0_PIN | DCDC_CTRL_FB1_PIN | DCDC_CTRL_FB2_PIN | DCDC_CTRL_FB3_PIN); gpio_clear(DCDC_PORT, DCDC_CTRL_FB0_PIN | DCDC_CTRL_FB1_PIN | DCDC_CTRL_FB2_PIN | DCDC_CTRL_FB3_PIN);
gpio_mode_setup(DCDC_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, gpio_mode_setup(DCDC_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE,
DCDC_CTRL_FB0_PIN | DCDC_CTRL_FB1_PIN | DCDC_CTRL_FB2_PIN | DCDC_CTRL_FB3_PIN); DCDC_CTRL_FB0_PIN | DCDC_CTRL_FB1_PIN | DCDC_CTRL_FB2_PIN | DCDC_CTRL_FB3_PIN);
// disable the DC/DC bypass by default (only enabled at 100% PWM)
gpio_clear(DCDC_PORT, DCDC_BYPASS_SWITCH_PIN);
gpio_mode_setup(DCDC_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, DCDC_BYPASS_SWITCH_PIN);
} }
void fan_ctrl_dc_enable(void) void fan_ctrl_dc_enable(void)
{ {
// enable the DC/DC converter // only set the enable flag. Pins will be set on the next call to fan_ctrl_dc_set_duty().
gpio_set(DCDC_PORT, DCDC_EN_PIN); m_enabled = true;
m_last_step = 0;
} }
void fan_ctrl_dc_disable(void) void fan_ctrl_dc_disable(void)
{ {
// shut down the DC/DC converter and disable all feedback resistors. m_enabled = false;
// shut down the DC/DC converter, disable DC/DC bypass and disable all feedback resistors.
gpio_clear(DCDC_PORT, DCDC_EN_PIN); gpio_clear(DCDC_PORT, DCDC_EN_PIN);
gpio_clear(DCDC_PORT, DCDC_BYPASS_SWITCH_PIN);
gpio_mode_setup(DCDC_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, gpio_mode_setup(DCDC_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE,
DCDC_CTRL_FB0_PIN | DCDC_CTRL_FB1_PIN | DCDC_CTRL_FB2_PIN | DCDC_CTRL_FB3_PIN); DCDC_CTRL_FB0_PIN | DCDC_CTRL_FB1_PIN | DCDC_CTRL_FB2_PIN | DCDC_CTRL_FB3_PIN);
} }
@ -37,11 +50,24 @@ void fan_ctrl_dc_disable(void)
void fan_ctrl_dc_set_duty(uint8_t percent) void fan_ctrl_dc_set_duty(uint8_t percent)
{ {
if(!m_enabled) {
return;
}
// note: as we only have 4 switchable feedback resistors, there are only 16 // note: as we only have 4 switchable feedback resistors, there are only 16
// voltage steps available. // voltage steps available.
uint8_t step = 15 * (uint16_t)percent / 100; uint8_t step = 15 * (uint16_t)percent / 100;
if(step == m_last_step) {
// skip adjustment if the target step has not changed.
return;
}
// disable the DC/DC while the feedback resistors are adjusted
gpio_clear(DCDC_PORT, DCDC_EN_PIN);
gpio_clear(DCDC_PORT, DCDC_BYPASS_SWITCH_PIN);
// if a resistor is active, the output voltage increases. The smallest // if a resistor is active, the output voltage increases. The smallest
// resistor (FB0) has the strongest influence on the output voltage. // resistor (FB0) has the strongest influence on the output voltage.
// Therefore, FB0 corresponds to the MSB of the calculated step. // Therefore, FB0 corresponds to the MSB of the calculated step.
@ -70,4 +96,10 @@ void fan_ctrl_dc_set_duty(uint8_t percent)
gpio_mode_setup(DCDC_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, DCDC_CTRL_FB3_PIN); gpio_mode_setup(DCDC_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, DCDC_CTRL_FB3_PIN);
} }
// Feedback resistors are now adjusted. Re-enable the DC/DC or, at 100%, set the bypass.
if(percent >= 100) {
gpio_set(DCDC_PORT, DCDC_BYPASS_SWITCH_PIN);
} else {
gpio_set(DCDC_PORT, DCDC_EN_PIN);
}
} }

View file

@ -53,8 +53,13 @@ int main(void)
uart_init(); uart_init();
temp_sensor_init(); temp_sensor_init();
fan_ctrl_pwm_init(); bool use_dcdc = EEPROM_CONFIG_FLAGS & EEPROM_CONFIG_FLAG_USE_DCDC_CONTROL;
fan_ctrl_dc_init();
if(use_dcdc) {
fan_ctrl_dc_init();
} else {
fan_ctrl_pwm_init();
}
fan_controller_init(); fan_controller_init();