Skip to content

Commit

Permalink
feat(hepa-uv): add tachometer support to read hepa fan rpm.
Browse files Browse the repository at this point in the history
  • Loading branch information
vegano1 committed Mar 21, 2024
1 parent a6476b3 commit 32039fc
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 5 deletions.
4 changes: 4 additions & 0 deletions hepa-uv/firmware/hepa_control_task/hepa_control_hardware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ using namespace hepa_control_hardware;

void HepaControlHardware::set_hepa_fan_speed(uint32_t duty_cycle) {
set_hepa_fan_pwm(duty_cycle);
}

uint32_t HepaControlHardware::get_hepa_fan_rpm() {
return get_hepa_fan_rpm();
}
103 changes: 102 additions & 1 deletion hepa-uv/firmware/hepa_hardware.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,67 @@
#include "hepa-uv/firmware/hepa_hardware.h"
#include "hepa-uv/firmware/utility_gpio.h"
#include "common/firmware/errors.h"
#include "timer_hardware.h"

TIM_HandleTypeDef htim2;
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};

void tachometer_gpio_init(void) {
/* Peripheral clock enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
/* HEPA_FG GPIO Configuration
PA5 ------> TIM2_CH1
*/
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = HEPA_FG_MCU_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
HAL_GPIO_Init(HEPA_FG_MCU_PORT, &GPIO_InitStruct);
}

static void TIM2_Tachometer_Init(void) {
htim2.Instance = TIM2;
htim2.State = HAL_TIM_STATE_RESET;
htim2.Init.Prescaler = 2;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 4.294967295E9;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK) {
Error_Handler();
}
/* Initialize Input Capture mode */
if (HAL_TIM_IC_Init(&htim2) != HAL_OK) {
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_ENABLE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) !=
HAL_OK) {
Error_Handler();
}
/* Initialize TIM2 input capture channel */
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV4;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) {
Error_Handler();
}
/* The update event of the enable timer is interrupted */
__HAL_TIM_ENABLE_IT(&htim2, TIM_IT_UPDATE);
/* Start the input capture measurement */
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);

// /* TIM2 interrupt Init */
HAL_NVIC_SetPriority(TIM2_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
}

static uint32_t clamp(uint32_t val, uint32_t min, uint32_t max) {
if (val < min) return min;
if (val > max) return max;
Expand All @@ -9,5 +70,45 @@ static uint32_t clamp(uint32_t val, uint32_t min, uint32_t max) {

void set_hepa_fan_pwm(uint32_t duty_cycle) {
// calculate the pulse width from the duty cycle
htim3.Instance->CCR1 = clamp(duty_cycle, 0, 100) * htim3.Init.Period / 100;
uint32_t clamped_dc = clamp(duty_cycle, 0, 100) * htim3.Init.Period / 100;
htim3.Instance->CCR1 = clamped_dc;
}

uint32_t val1 = 0;
uint32_t val2 = 0;
uint32_t tach_period = 0;
uint8_t captured_val1 = 0;

uint32_t get_hepa_fan_rpm(void) {
if (tach_period == 0) return 0;
uint32_t rpm = ((uint32_t)HEPA_TACHOMETER_TIMER_FREQ * 60) \
/ ((uint32_t)tach_period);
return rpm;
}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim2) {
uint32_t count = __HAL_TIM_GET_COUNTER((TIM_HandleTypeDef*)htim);
if (captured_val1 == 0) {
val1 = count;
captured_val1 = 1;
} else {
val2 = count;
}

if (val2 > val1) {
tach_period = val2 - val1;
captured_val1 = 0;
__HAL_TIM_SET_COUNTER(htim, 0);
} else {
tach_period = 0;
}

__HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_UPDATE);
}
}

void initialize_tachometer() {
tachometer_gpio_init();
TIM2_Tachometer_Init();
}
2 changes: 2 additions & 0 deletions hepa-uv/firmware/main_rev1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "hepa-uv/firmware/hepa_control_hardware.hpp"
#include "hepa-uv/firmware/led_control_hardware.hpp"
#include "hepa-uv/firmware/utility_gpio.h"
#include "hepa-uv/firmware/hepa_hardware.h"
#include "i2c/firmware/i2c_comms.hpp"
#include "timer_hardware.h"

Expand Down Expand Up @@ -155,6 +156,7 @@ auto main() -> int {
RCC_Peripheral_Clock_Select();
utility_gpio_init();
initialize_pwm_hardware();
initialize_tachometer();
// set push button leds white
led_hardware.set_button_led_power(HEPA_BUTTON, 0, 0, 0, 50);
led_hardware.set_button_led_power(UV_BUTTON, 0, 0, 0, 50);
Expand Down
7 changes: 7 additions & 0 deletions hepa-uv/firmware/stm32g4xx_it.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
/* Private functions ---------------------------------------------------------*/

/* External variables --------------------------------------------------------*/
extern TIM_HandleTypeDef htim2;
DMA_HandleTypeDef hdma_spi1_tx;
DMA_HandleTypeDef hdma_spi1_rx;

Expand Down Expand Up @@ -135,6 +136,12 @@ void EXTI15_10_IRQHandler(void) {
}
}

/**
* @brief This function handles TIM2 global interrupt.
*/
__attribute__((section(".ccmram")))
void TIM2_IRQHandler(void) { HAL_TIM_IRQHandler(&htim2); }

/**
* @brief This function handles DMA1 channel2 global interrupt.
*/
Expand Down
1 change: 1 addition & 0 deletions hepa-uv/firmware/stm32g4xx_it.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void FDCAN1_IT0_IRQHandler(void);
void EXTI2_IRQHandler(void);
void EXTI9_5_IRQHandler(void);
void EXTI15_10_IRQHandler(void);
void TIM2_IRQHandler(void);

#ifdef __cplusplus
}
Expand Down
2 changes: 2 additions & 0 deletions hepa-uv/firmware/timer_hardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ uint32_t calc_prescaler(uint32_t timer_clk_freq, uint32_t counter_clk_freq) {
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim) {
if(htim->Instance == TIM1) {
__HAL_RCC_TIM1_CLK_ENABLE();
} else if(htim->Instance == TIM2) {
__HAL_RCC_TIM2_CLK_ENABLE();
} else if(htim->Instance == TIM3) {
__HAL_RCC_TIM3_CLK_ENABLE();
} else if(htim->Instance == TIM8) {
Expand Down
2 changes: 2 additions & 0 deletions hepa-uv/firmware/timer_hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ extern "C" {

extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim3;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim8;
extern TIM_HandleTypeDef htim16;
extern TIM_HandleTypeDef htim20;

extern TIM_OC_InitTypeDef htim1_sConfigOC;
extern TIM_OC_InitTypeDef htim2_sConfigOC;
extern TIM_OC_InitTypeDef htim3_sConfigOC;
extern TIM_OC_InitTypeDef htim8_sConfigOC;
extern TIM_OC_InitTypeDef htim16_sConfigOC;
Expand Down
6 changes: 3 additions & 3 deletions hepa-uv/firmware/utility_gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,20 +141,20 @@ void uv_on_off_output_init() {
*/
static void nvic_priority_enable_init() {
/* EXTI interrupt init DOOR_OPEN_MCU : PC7*/
// PC7 -> GPIO_EXTI6 (EXTI9_5_IRQn)
// PC7 -> GPIO_EXTI7 (EXTI9_5_IRQn)
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

/* EXTI interrupt init REED_SW_MCU : PC11*/
/* EXTI interrupt init HEPA_NO_MCU : PB10*/
// PC11 -> GPIO_EXTI11 (EXTI15_10_IRQn)
// PB11 -> GPIO_EXTI11 (EXTI15_10_IRQn)
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

/* EXTI interrupt init UV_NO_MCU : PC2*/
// PC2 -> GPIO_EXTI2 (EXTI2_IRQn)
HAL_NVIC_SetPriority(EXTI2_IRQn, 5, 0);
HAL_NVIC_SetPriority(EXTI2_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(EXTI2_IRQn);
}

Expand Down
3 changes: 2 additions & 1 deletion include/hepa-uv/core/interfaces.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ class HepaControlInterface {
virtual ~HepaControlInterface() = default;

virtual auto set_hepa_fan_speed(uint32_t duty_cycle) -> void = 0;
virtual auto get_hepa_fan_rpm() -> uint32_t = 0;
};
} // namespace hepa_control
} // namespace hepa_control
1 change: 1 addition & 0 deletions include/hepa-uv/firmware/hepa_control_hardware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class HepaControlHardware : public hepa_control::HepaControlInterface {
~HepaControlHardware() final = default;

void set_hepa_fan_speed(uint32_t duty_cycle) final;
uint32_t get_hepa_fan_rpm() final;
};

} // namespace hepa_control_hardware
4 changes: 4 additions & 0 deletions include/hepa-uv/firmware/hepa_hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
extern "C" {
#endif // __cplusplus

#define HEPA_TACHOMETER_TIMER_FREQ (20000U)

void initialize_tachometer();
void set_hepa_fan_pwm(uint32_t duty_cycle);
uint32_t get_hepa_fan_rpm();

#ifdef __cplusplus
} // extern "C"
Expand Down

0 comments on commit 32039fc

Please sign in to comment.