diff --git a/src/fan_ctrl_dc.c b/src/fan_ctrl_dc.c index aa29a7e..90c37ba 100644 --- a/src/fan_ctrl_dc.c +++ b/src/fan_ctrl_dc.c @@ -3,9 +3,14 @@ #include "fan_ctrl_dc.h" #include "pinout.h" +uint8_t m_last_step; +bool m_enabled; void fan_ctrl_dc_init(void) { + m_last_step = 0; + m_enabled = false; + // configure the GPIOs: DC/DC disabled by default gpio_clear(DCDC_PORT, 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_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); + + // 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) { - // enable the DC/DC converter - gpio_set(DCDC_PORT, DCDC_EN_PIN); + // only set the enable flag. Pins will be set on the next call to fan_ctrl_dc_set_duty(). + m_enabled = true; + m_last_step = 0; } 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_BYPASS_SWITCH_PIN); 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); } @@ -37,11 +50,24 @@ void fan_ctrl_dc_disable(void) 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 // voltage steps available. 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 // resistor (FB0) has the strongest influence on the output voltage. // 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); } + // 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); + } } diff --git a/src/main.c b/src/main.c index 6324436..ac905d1 100644 --- a/src/main.c +++ b/src/main.c @@ -53,8 +53,13 @@ int main(void) uart_init(); temp_sensor_init(); - fan_ctrl_pwm_init(); - fan_ctrl_dc_init(); + bool use_dcdc = EEPROM_CONFIG_FLAGS & EEPROM_CONFIG_FLAG_USE_DCDC_CONTROL; + + if(use_dcdc) { + fan_ctrl_dc_init(); + } else { + fan_ctrl_pwm_init(); + } fan_controller_init();