75 lines
2 KiB
C
75 lines
2 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);
|
|
|
|
// *** TIM2 ***
|
|
// Configure channel 2 for PWM
|
|
// Ch1 = charge pump output
|
|
|
|
timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
|
|
|
|
// set up PWM channel
|
|
timer_set_oc_mode(TIM2, TIM_OC2, TIM_OCM_PWM1);
|
|
timer_enable_oc_output(TIM2, TIM_OC2);
|
|
timer_enable_oc_preload(TIM2, TIM_OC2);
|
|
timer_set_oc_polarity_high(TIM2, TIM_OC2);
|
|
|
|
// prescaler
|
|
timer_set_prescaler(TIM2, 21 - 1); // Timer runs at 100 kHz
|
|
|
|
// auto-reload value
|
|
timer_set_period(TIM2, 100 - 1); // overflow every 100 cycles = 1 kHz
|
|
|
|
// output compare value
|
|
timer_set_oc_value(TIM2, TIM_OC2, 0); // No PWM output by default
|
|
|
|
// only generate interrupt on overflow
|
|
timer_update_on_overflow(TIM2);
|
|
|
|
// enable main output
|
|
timer_enable_break_main_output(TIM2);
|
|
}
|
|
|
|
|
|
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_mode_setup(FAN_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, FAN_PWM_PIN);
|
|
gpio_set_af(FAN_PORT, GPIO_AF0, FAN_PWM_PIN);
|
|
|
|
// start the PWM timer
|
|
timer_enable_counter(TIM2);
|
|
}
|
|
|
|
|
|
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(TIM2, TIM_OC2, 0);
|
|
timer_disable_counter(TIM2);
|
|
|
|
// configure the PWM GPIO as input so the fan runs full speed if powered
|
|
gpio_mode_setup(FAN_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, FAN_PWM_PIN);
|
|
}
|
|
|
|
|
|
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(TIM2, TIM_OC2, percent);
|
|
}
|