Skip to content

Commit

Permalink
Cooling fan PWM control (#92)
Browse files Browse the repository at this point in the history
* Starting fan timer init

* Pushing init function

* Starting tach

* Setting fan speed is working, tach is not

* Messing around with prescalar and auto reload

* Second fan tach

* I think I have the tach working now

* RPM calculation should now be correct

* Pushing power settings

* Adding extra functions

* Only setting up PWM control for PR, no tach
  • Loading branch information
ColexDev authored Feb 15, 2024
1 parent b964569 commit 6b9293f
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
61 changes: 61 additions & 0 deletions source/pdu/fan_control/fan_control.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "fan_control.h"
#include "common/phal_F4_F7/gpio/gpio.h"

extern uint32_t APB1ClockRateHz;
extern uint32_t APB2ClockRateHz;

bool fanControlInit()
{
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // Enable clock to TIM1
FAN_PWM_TIM->CR1 &= ~TIM_CR1_CEN; // Disable counter (turn off timer)

/* Solving for PSC:
* PWMfreq = Fclk / ((ARR + 1) × (PSC + 1)).
*
* PWMfreq is known, and we are setting ARR to 99 for ease of calculations.
*
* Therefore we solve for the below formula for the desired PSC based on the
* necessary PWMfreq specified by the fan vendor.
*/

FAN_PWM_TIM->ARR = 100 - 1; // Using this for ease of calculations

FAN_PWM_TIM->PSC = (APB2ClockRateHz / (PWM_FREQUENCY_HZ * (FAN_PWM_TIM -> ARR + 1))) - 1;

FAN_PWM_TIM->CCR1 = 0; // Start with it off
FAN_PWM_TIM->CCR2 = 0; // Start with it off

// Set PWM mode 1 (active while CNT <= CCR1)
FAN_PWM_TIM->CCMR1 &= ~TIM_CCMR1_OC1M;
FAN_PWM_TIM->CCMR1 &= ~TIM_CCMR1_OC2M;
FAN_PWM_TIM->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // PWM Mode 1 ch1
FAN_PWM_TIM->CCMR1 |= TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1; // PWM Mode 1 ch2
FAN_PWM_TIM->CCMR1 |= TIM_CCMR1_OC2PE |TIM_CCMR1_OC1PE; // Enable preload register ch1 & ch2

FAN_PWM_TIM->CCER |= TIM_CCER_CC2E | TIM_CCER_CC1E; // Enable output compare 1 & 2

FAN_PWM_TIM->BDTR |= TIM_BDTR_MOE; // Enable main output

FAN_PWM_TIM->CR1 &= ~TIM_CR1_DIR; // Set to upcounting mode
FAN_PWM_TIM->CR1 |= TIM_CR1_ARPE; // Necessary in upcounting mode

FAN_PWM_TIM->CR1 |= TIM_CR1_CEN; // Enable counter (turn on timer)

FAN_PWM_TIM->CR1 |= TIM_CR1_CEN; // Enable FAN_PWM_TIM

return true;
}

// This speed will be between 0-100%
void setFan1Speed(uint8_t fan_speed)
{
// Duty cycle is (CCR1 / ARR)%. So CCR1 = (ARR / duty cycle)
FAN_PWM_TIM->CCR1 = (FAN_PWM_TIM -> ARR + 1) * (fan_speed / 100.0);
}

// This speed will be between 0-100%
void setFan2Speed(uint8_t fan_speed)
{
// Duty cycle is (CCR1 / ARR)%. So CCR1 = (ARR / duty cycle)
FAN_PWM_TIM->CCR2 = (FAN_PWM_TIM -> ARR + 1) * (fan_speed / 100.0);
}
15 changes: 15 additions & 0 deletions source/pdu/fan_control/fan_control.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef _FAN_CONTROL_H_
#define _FAN_CONTROL_H_

#include <stdbool.h>
#include "stm32f407xx.h"
#include "main.h"

#define PWM_FREQUENCY_HZ (25000) // PWM frequency to be 25kHz
#define FAN_PWM_TIM (FAN_1_PWM_TIM) // Fan 1 and 2 user same timer

bool fanControlInit();
void setFan1Speed(uint8_t fan_speed);
void setFan2Speed(uint8_t fan_speed);

#endif // _FAN_CONTROL_H_

0 comments on commit 6b9293f

Please sign in to comment.