TinyFanControl-Firmware/src/fan_ctrl_pwm.c

74 lines
1.9 KiB
C

#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/timer.h>
#include "fan_ctrl_pwm.h"
#include "pinout.h"
void fan_ctrl_pwm_init(void)
{
// disable the DC/DC bypass until PWM control mode is actually enabled
gpio_clear(DCDC_PORT, DCDC_BYPASS_SWITCH_PIN);
gpio_mode_setup(DCDC_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, DCDC_BYPASS_SWITCH_PIN);
// *** TIM21 ***
// Configure channel 1 for PWM
// Ch1 = charge pump output
timer_set_mode(TIM21, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
// set up PWM channel
timer_set_oc_mode(TIM21, TIM_OC1, TIM_OCM_PWM1);
timer_enable_oc_output(TIM21, TIM_OC1);
timer_enable_oc_preload(TIM21, TIM_OC1);
timer_set_oc_polarity_high(TIM21, TIM_OC1);
// prescaler
timer_set_prescaler(TIM21, 21 - 1); // Timer runs at 100 kHz
// auto-reload value
timer_set_period(TIM21, 100 - 1); // overflow every 100 cycles = 1 kHz
// output compare value
timer_set_oc_value(TIM21, TIM_OC1, 0); // No PWM output by default
// only generate interrupt on overflow
timer_update_on_overflow(TIM21);
// enable main output
timer_enable_break_main_output(TIM21);
}
void fan_ctrl_pwm_enable(void)
{
// enable the DC/DC bypass (power the fan directly from the supply voltage)
gpio_set(DCDC_PORT, DCDC_BYPASS_SWITCH_PIN);
// Enable PWM output on the PWM GPIO
gpio_set_af(FAN_PORT, GPIO_AF0, FAN_PWM_PIN);
// start the PWM timer
timer_enable_counter(TIM21);
}
void fan_ctrl_pwm_disable(void)
{
// disable the DC/DC bypass again
gpio_clear(DCDC_PORT, DCDC_BYPASS_SWITCH_PIN);
// set PWM value to 0 and stop the counter
timer_set_oc_value(TIM21, TIM_OC1, 0);
timer_disable_counter(TIM21);
// configure the PWM GPIO as input so the fan runs full speed if powered
}
void fan_ctrl_pwm_set_duty(uint8_t percent)
{
// as the timer has 100 steps per cycle, we can directly use the percentage value
timer_set_oc_value(TIM21, TIM_OC1, percent);
}