TinyFanControl-Firmware/src/fan_ctrl_dc.c

74 lines
2.3 KiB
C

#include <libopencm3/stm32/gpio.h>
#include "fan_ctrl_dc.h"
#include "pinout.h"
void fan_ctrl_dc_init(void)
{
// 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);
// configure the feedback resistor GPIOs. These are used as open-drain
// outputs, so either they are configured as input or as output, but the
// only valid output value is 0.
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);
}
void fan_ctrl_dc_enable(void)
{
// enable the DC/DC converter
gpio_set(DCDC_PORT, DCDC_EN_PIN);
}
void fan_ctrl_dc_disable(void)
{
// shut down the DC/DC converter and disable all feedback resistors.
gpio_clear(DCDC_PORT, DCDC_EN_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);
}
void fan_ctrl_dc_set_duty(uint8_t percent)
{
// 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 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.
if(step & (1 << 3)) {
gpio_mode_setup(DCDC_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, DCDC_CTRL_FB0_PIN);
} else {
gpio_mode_setup(DCDC_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, DCDC_CTRL_FB0_PIN);
}
if(step & (1 << 2)) {
gpio_mode_setup(DCDC_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, DCDC_CTRL_FB1_PIN);
} else {
gpio_mode_setup(DCDC_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, DCDC_CTRL_FB1_PIN);
}
if(step & (1 << 1)) {
gpio_mode_setup(DCDC_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, DCDC_CTRL_FB2_PIN);
} else {
gpio_mode_setup(DCDC_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, DCDC_CTRL_FB2_PIN);
}
if(step & (1 << 0)) {
gpio_mode_setup(DCDC_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, DCDC_CTRL_FB3_PIN);
} else {
gpio_mode_setup(DCDC_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, DCDC_CTRL_FB3_PIN);
}
}