Skip to content

Commit

Permalink
faet(hepa-uv): Add hardware control to drive hepa fan.
Browse files Browse the repository at this point in the history
  • Loading branch information
vegano1 committed Jan 22, 2024
1 parent 93f1b32 commit fd85844
Show file tree
Hide file tree
Showing 15 changed files with 229 additions and 27 deletions.
6 changes: 4 additions & 2 deletions hepa-uv/core/tasks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "common/core/freertos_timer.hpp"
#include "hepa-uv/core/can_task.hpp"
#include "hepa-uv/firmware/gpio_drive_hardware.hpp"
#include "hepa-uv/firmware/hepa_control_hardware.hpp"
#include "hepa-uv/firmware/utility_gpio.h"

#pragma GCC diagnostic push
Expand All @@ -29,13 +30,14 @@ static auto led_control_task_builder =
void hepauv_tasks::start_tasks(
can::bus::CanBus& can_bus,
gpio_drive_hardware::GpioDrivePins& gpio_drive_pins,
led_control_hardware::LEDControlHardware& led_hardware) {
led_control_hardware::LEDControlHardware& led_hardware,
hepa_control_hardware::HepaControlHardware& hepa_hardware) {
auto& can_writer = can_task::start_writer(can_bus);
can_task::start_reader(can_bus);

// TODO: including led_hardware for testing, this should be a AssesorClient
auto& hepa_task =
hepa_task_builder.start(5, "hepa_fan", gpio_drive_pins, led_hardware);
hepa_task_builder.start(5, "hepa_fan", gpio_drive_pins, led_hardware, hepa_hardware);
auto& uv_task =
uv_task_builder.start(5, "uv_ballast", gpio_drive_pins, led_hardware);
auto& led_control_task =
Expand Down
2 changes: 2 additions & 0 deletions hepa-uv/firmware/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ set(REVISIONS hepa-rev1)
set(HEPA_UV_FW_LINTABLE_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/freertos_idle_timer_task.cpp
${CMAKE_CURRENT_SOURCE_DIR}/led_control_task/led_control_hardware.cpp
${CMAKE_CURRENT_SOURCE_DIR}/hepa_control_hardware.cpp
${COMMON_EXECUTABLE_DIR}/system/iwdg.cpp
${CAN_FW_DIR}/hal_can_bus.cpp
${CAN_FW_DIR}/utils.c
Expand All @@ -25,6 +26,7 @@ set(HEPAUV_FW_NON_LINTABLE_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/clocking.c
${CMAKE_CURRENT_SOURCE_DIR}/utility_gpio.c
${CMAKE_CURRENT_SOURCE_DIR}/led_hardware.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware.c
${CMAKE_CURRENT_SOURCE_DIR}/can.c
${CMAKE_CURRENT_SOURCE_DIR}/i2c_setup.c
${COMMON_EXECUTABLE_DIR}/errors/errors.c
Expand Down
114 changes: 114 additions & 0 deletions hepa-uv/firmware/hardware.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#include "hepa-uv/firmware/hardware.h"
#include "hepa-uv/firmware/utility_gpio.h"
#include "common/firmware/errors.h"

#include "platform_specific_hal_conf.h"
#include "system_stm32g4xx.h"

TIM_HandleTypeDef htim3;

TIM_OC_InitTypeDef htim3_sConfigOC = {0};


// void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_pwm) {
// if(htim_pwm->Instance == TIM3) {
// __HAL_RCC_TIM3_CLK_ENABLE();
// }
// }

// void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) {
// GPIO_InitTypeDef GPIO_InitStruct = {0};
// if (htim->Instance == TIM3) {
// __HAL_RCC_GPIOA_CLK_ENABLE();
// /**TIM3 GPIO Configuration
// PA6 ------> TIM3_CH1
// */
// GPIO_InitStruct.Pin = HEPA_PWM_PIN;
// GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
// GPIO_InitStruct.Pull = GPIO_NOPULL;
// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
// GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
// HAL_GPIO_Init(HEPA_PWM_PORT, &GPIO_InitStruct);
// }
// }

/**
* @brief TIM3 Initialization Function for HEPA_PWM
* @param None
* @retval None
*/
static void MX_TIM3_Init(void) {
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

htim3.State = HAL_TIM_STATE_RESET;
htim3.Instance = TIM3;
htim3.Init.Prescaler = 64 - 1;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 40 - 1;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.RepetitionCounter = 0;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK) {
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) {
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) {
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) !=
HAL_OK) {
Error_Handler();
}
htim3_sConfigOC.OCMode = TIM_OCMODE_PWM1;
// 0% duty cycle
htim3_sConfigOC.Pulse = 0;
htim3_sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
htim3_sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
htim3_sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
htim3_sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
htim3_sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &htim3_sConfigOC, TIM_CHANNEL_1) !=
HAL_OK) {
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT;
sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
sBreakDeadTimeConfig.Break2Filter = 0;
sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim3, &sBreakDeadTimeConfig) !=
HAL_OK) {
Error_Handler();
}
// HAL_TIM_MspPostInit(&htim3);
}

void hepa_fan_hw_update_pwm(uint32_t duty_cycle) {
// update hepa fan speed
htim3.Instance->CCR1 = duty_cycle;
}

void initialize_hardware() {
MX_TIM3_Init();

// Set the hepa fan speed to 0
hepa_fan_hw_update_pwm(0);

// Activate the channels
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
}
9 changes: 9 additions & 0 deletions hepa-uv/firmware/hepa_control_hardware.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "hepa-uv/firmware/hepa_control_hardware.hpp"
#include "hepa-uv/firmware/hardware.h"

using namespace hepa_control_hardware;


void HepaControlHardware::set_hepa_fan_speed(uint32_t duty_cycle) {
hepa_fan_hw_update_pwm(duty_cycle);
}
2 changes: 1 addition & 1 deletion hepa-uv/firmware/led_control_task/led_control_hardware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using namespace led_control_hardware;

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
auto LEDControlHardware::initialize() -> void {
button_led_hw_initialize_leds();
button_hw_initialize_leds();
}

void LEDControlHardware::set_button_led_power(uint8_t button, uint32_t r,
Expand Down
2 changes: 1 addition & 1 deletion hepa-uv/firmware/led_hardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ void set_button_led_pwm(PUSH_BUTTON_TYPE button, uint32_t red, uint32_t green, u
button_led_hw_update_pwm(white, WHITE_LED, button);
}

void button_led_hw_initialize_leds() {
void button_hw_initialize_leds() {
MX_TIM1_Init();
MX_TIM8_Init();
MX_TIM16_Init();
Expand Down
8 changes: 6 additions & 2 deletions hepa-uv/firmware/main_rev1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "hepa-uv/core/tasks.hpp"
#include "hepa-uv/firmware/led_control_hardware.hpp"
#include "hepa-uv/firmware/led_hardware.h"
#include "hepa-uv/firmware/hardware.h"
#include "hepa-uv/firmware/hepa_control_hardware.hpp"
#include "hepa-uv/firmware/utility_gpio.h"

static auto iWatchdog = iwdg::IndependentWatchDog{};
Expand Down Expand Up @@ -118,18 +120,20 @@ extern "C" void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
}

static auto led_hardware = led_control_hardware::LEDControlHardware();
static auto hepa_hardware = hepa_control_hardware::HepaControlHardware();

auto main() -> int {
HardwareInit();
RCC_Peripheral_Clock_Select();
utility_gpio_init();
button_led_hw_initialize_leds();
button_hw_initialize_leds();
initialize_hardware();

app_update_clear_flags();

canbus.start(can_bit_timings);

hepauv_tasks::start_tasks(canbus, gpio_drive_pins, led_hardware);
hepauv_tasks::start_tasks(canbus, gpio_drive_pins, led_hardware, hepa_hardware);

iWatchdog.start(6);

Expand Down
14 changes: 10 additions & 4 deletions include/hepa-uv/core/hepa_task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "hepa-uv/core/messages.hpp"
#include "hepa-uv/firmware/gpio_drive_hardware.hpp"
#include "hepa-uv/firmware/led_control_hardware.hpp"
#include "hepa-uv/firmware/hepa_control_hardware.hpp"

namespace hepa_task {

Expand All @@ -18,8 +19,9 @@ class HepaMessageHandler {
public:
explicit HepaMessageHandler(
gpio_drive_hardware::GpioDrivePins &drive_pins,
led_control_hardware::LEDControlHardware &led_hardware)
: drive_pins{drive_pins}, led_hardware{led_hardware} {
led_control_hardware::LEDControlHardware &led_hardware,
hepa_control_hardware::HepaControlHardware &hepa_hardware)
: drive_pins{drive_pins}, led_hardware{led_hardware}, hepa_hardware{hepa_hardware} {
// get current state
hepa_push_button = gpio::is_set(drive_pins.hepa_push_button);
// turn off the HEPA fan
Expand All @@ -45,9 +47,11 @@ class HepaMessageHandler {
hepa_push_button = !hepa_push_button;
// handle state changes here
if (hepa_push_button) {
hepa_hardware.set_hepa_fan_speed(50);
gpio::set(drive_pins.hepa_on_off);
led_hardware.set_button_led_power(HEPA_BUTTON, 0, 50, 0, 0);
} else {
hepa_hardware.set_hepa_fan_speed(0);
gpio::reset(drive_pins.hepa_on_off);
led_hardware.set_button_led_power(HEPA_BUTTON, 0, 0, 0, 50);
}
Expand All @@ -62,6 +66,7 @@ class HepaMessageHandler {

gpio_drive_hardware::GpioDrivePins &drive_pins;
led_control_hardware::LEDControlHardware &led_hardware;
hepa_control_hardware::HepaControlHardware &hepa_hardware;
};

/**
Expand All @@ -85,8 +90,9 @@ class HepaTask {
*/
[[noreturn]] void operator()(
gpio_drive_hardware::GpioDrivePins *drive_pins,
led_control_hardware::LEDControlHardware *led_hardware) {
auto handler = HepaMessageHandler{*drive_pins, *led_hardware};
led_control_hardware::LEDControlHardware *led_hardware,
hepa_control_hardware::HepaControlHardware *hepa_hardware) {
auto handler = HepaMessageHandler{*drive_pins, *led_hardware, *hepa_hardware};
TaskMessage message{};
for (;;) {
if (queue.try_read(&message, queue.max_delay)) {
Expand Down
35 changes: 35 additions & 0 deletions include/hepa-uv/core/interfaces.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include "hepa-uv/core/constants.h"

namespace led_control {

class LEDControlInterface {
public:
LEDControlInterface() = default;
LEDControlInterface(const LEDControlInterface&) = delete;
LEDControlInterface(LEDControlInterface&&) = delete;
auto operator=(LEDControlInterface&&) -> LEDControlInterface& = delete;
auto operator=(const LEDControlInterface&) -> LEDControlInterface& = delete;
virtual ~LEDControlInterface() = default;

virtual auto set_button_led_power(uint8_t button, uint32_t r, uint32_t g,
uint32_t b, uint32_t w) -> void = 0;
};

} // led_control namespace

namespace hepa_control {

class HepaControlInterface {
public:
HepaControlInterface() = default;
HepaControlInterface(const HepaControlInterface&) = delete;
HepaControlInterface(HepaControlInterface&&) = delete;
auto operator=(HepaControlInterface&&) -> HepaControlInterface& = delete;
auto operator=(const HepaControlInterface&) -> HepaControlInterface& = delete;
virtual ~HepaControlInterface() = default;

virtual void set_hepa_fan_speed(uint32_t duty_cycle);
};
} // hepa_control namespace
16 changes: 3 additions & 13 deletions include/hepa-uv/core/led_control_task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,13 @@
#include "common/core/message_queue.hpp"
#include "hepa-uv/core/constants.h"
#include "hepa-uv/core/messages.hpp"
#include "hepa-uv/core/interfaces.hpp"

namespace led_control_task {

using TaskMessage = led_control_task_messages::TaskMessage;
using namespace led_control;

class LEDControlInterface {
public:
LEDControlInterface() = default;
LEDControlInterface(const LEDControlInterface&) = delete;
LEDControlInterface(LEDControlInterface&&) = delete;
auto operator=(LEDControlInterface&&) -> LEDControlInterface& = delete;
auto operator=(const LEDControlInterface&) -> LEDControlInterface& = delete;
virtual ~LEDControlInterface() = default;

virtual auto set_button_led_power(uint8_t button, uint32_t r, uint32_t g,
uint32_t b, uint32_t w) -> void = 0;
};
using TaskMessage = led_control_task_messages::TaskMessage;

class LEDControlMessageHandler {
public:
Expand Down
4 changes: 3 additions & 1 deletion include/hepa-uv/core/tasks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "hepa-uv/core/uv_task.hpp"
#include "hepa-uv/firmware/gpio_drive_hardware.hpp"
#include "hepa-uv/firmware/led_control_hardware.hpp"
#include "hepa-uv/firmware/hepa_control_hardware.hpp"

namespace hepauv_tasks {

Expand All @@ -14,7 +15,8 @@ namespace hepauv_tasks {
*/
void start_tasks(can::bus::CanBus& can_bus,
gpio_drive_hardware::GpioDrivePins& gpio_drive_pins,
led_control_hardware::LEDControlHardware& led_hardware);
led_control_hardware::LEDControlHardware& led_hardware,
hepa_control_hardware::HepaControlHardware& hepa_hardware);

/**
* Access to all the message queues in the system.
Expand Down
16 changes: 16 additions & 0 deletions include/hepa-uv/firmware/hardware.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include <stdint.h>

#include "hepa-uv/core/constants.h"

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void hepa_fan_hw_update_pwm(uint32_t duty_cycle);
void initialize_hardware();

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
22 changes: 22 additions & 0 deletions include/hepa-uv/firmware/hepa_control_hardware.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include "hepa-uv/core/interfaces.hpp"

namespace hepa_control_hardware {

using namespace hepa_control;

class HepaControlHardware : public HepaControlInterface {
public:
HepaControlHardware() = default;
HepaControlHardware(const HepaControlHardware&) = delete;
HepaControlHardware(HepaControlHardware&&) = delete;
auto operator=(HepaControlHardware&&) -> HepaControlHardware& = delete;
auto operator=(const HepaControlHardware&) -> HepaControlHardware& = delete;
~HepaControlHardware() final = default;

auto initialize() -> void;
void set_hepa_fan_speed(uint32_t duty_cycle);
};

} // namespace led_control_hardware
Loading

0 comments on commit fd85844

Please sign in to comment.