Skip to content

Commit

Permalink
feat(hepa-uv): add a task to handle the UV ballast state.
Browse files Browse the repository at this point in the history
  • Loading branch information
vegano1 committed Jan 18, 2024
1 parent 389cb2d commit 96b5eb7
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 18 deletions.
3 changes: 1 addition & 2 deletions hepa-uv/core/tasks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ void hepauv_tasks::QueueClient::send_hepa_message(
hepa_queue->try_write(m);
}

void hepauv_tasks::QueueClient::send_uv_message(
const uv_task::TaskMessage& m) {
void hepauv_tasks::QueueClient::send_uv_message(const uv_task::TaskMessage& m) {
uv_queue->try_write(m);
}

Expand Down
12 changes: 8 additions & 4 deletions hepa-uv/firmware/main_rev1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,24 @@ static auto gpio_drive_pins = gpio_drive_hardware::GpioDrivePins{
.pin = UV_ON_OFF_MCU_PIN,
.active_setting = UV_ON_OFF_AS}};

static auto& hepa_queue_client = hepauv_tasks::get_main_queues();
static auto& hepauv_queues = hepauv_tasks::get_main_queues();

extern "C" void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
switch (GPIO_Pin) {
case DOOR_OPEN_MCU_PIN:
case REED_SW_MCU_PIN:
case HEPA_NO_MCU_PIN:
case UV_NO_MCU_PIN:
if (hepa_queue_client.hepa_queue != nullptr) {
static_cast<void>(hepa_queue_client.hepa_queue->try_write_isr(
if (hepauv_queues.hepa_queue != nullptr) {
static_cast<void>(hepauv_queues.hepa_queue->try_write_isr(
interrupt_task_messages::GPIOInterruptChanged{
.pin = GPIO_Pin}));
}
if (hepauv_queues.uv_queue != nullptr) {
static_cast<void>(hepauv_queues.uv_queue->try_write_isr(
interrupt_task_messages::GPIOInterruptChanged{
.pin = GPIO_Pin}));
}
// send to uv queue here
break;
default:
break;
Expand Down
7 changes: 6 additions & 1 deletion include/hepa-uv/core/hepa_task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ using TaskMessage = interrupt_task_messages::TaskMessage;
class HepaMessageHandler {
public:
explicit HepaMessageHandler(gpio_drive_hardware::GpioDrivePins &drive_pins)
: drive_pins{drive_pins} {}
: drive_pins{drive_pins} {
// get current state
hepa_push_button = gpio::is_set(drive_pins.hepa_push_button);
// turn off the HEPA fan
gpio::reset(drive_pins.hepa_on_off);
}
HepaMessageHandler(const HepaMessageHandler &) = delete;
HepaMessageHandler(const HepaMessageHandler &&) = delete;
auto operator=(const HepaMessageHandler &) -> HepaMessageHandler & = delete;
Expand Down
1 change: 0 additions & 1 deletion include/hepa-uv/core/tasks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ struct AllTask {

uv_task::UVTask<freertos_message_queue::FreeRTOSMessageQueue>*
uv_task_handler{nullptr};

};

/**
Expand Down
62 changes: 52 additions & 10 deletions include/hepa-uv/core/uv_task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,92 @@
#include "common/core/message_queue.hpp"
#include "hepa-uv/firmware/gpio_drive_hardware.hpp"
#include "messages.hpp"
#include "ot_utils/freertos/freertos_timer.hpp"

namespace uv_task {

// How long to keep the UV light on in ms.
static constexpr uint32_t DELAY_MS = 1000 * 60 * 15; // 15 minutes

using TaskMessage = interrupt_task_messages::TaskMessage;

class UVMessageHandler {
public:
explicit UVMessageHandler(gpio_drive_hardware::GpioDrivePins &drive_pins)
: drive_pins{drive_pins} {}
: drive_pins{drive_pins},
_timer(
"UVTask", [ThisPtr = this] { ThisPtr->timer_callback(); },
DELAY_MS) {
// get current state
uv_push_button = gpio::is_set(drive_pins.uv_push_button);
door_closed = gpio::is_set(drive_pins.door_open);
reed_switch_set = gpio::is_set(drive_pins.reed_switch);
// turn off UV Ballast
gpio::reset(drive_pins.uv_on_off);
}
UVMessageHandler(const UVMessageHandler &) = delete;
UVMessageHandler(const UVMessageHandler &&) = delete;
auto operator=(const UVMessageHandler &) -> UVMessageHandler & = delete;
auto operator=(const UVMessageHandler &&)
-> UVMessageHandler && = delete;
auto operator=(const UVMessageHandler &&) -> UVMessageHandler && = delete;
~UVMessageHandler() {}

void handle_message(const TaskMessage &m) {
std::visit([this](auto o) { this->visit(o); }, m);
}

private:
// call back to turn off the UV ballast
auto timer_callback() -> void {
gpio::reset(drive_pins.uv_on_off);
uv_push_button = false;
uv_fan_on = false;
}

void visit(const std::monostate &) {}

// Handle GPIO EXTI Interrupts here
void visit(const interrupt_task_messages::GPIOInterruptChanged &m) {
if (m.pin == drive_pins.hepa_push_button.pin) {
// ignore hepa push button presses
return;
}

// update states
if (m.pin == drive_pins.uv_push_button.pin) {
uv_push_button = !uv_push_button;
// handle state changes here
if (uv_push_button) {
gpio::set(drive_pins.uv_on_off);
} else {
gpio::reset(drive_pins.uv_on_off);
}
} else if (m.pin == drive_pins.door_open.pin) {
door_closed = gpio::is_set(drive_pins.door_open);
} else if (m.pin == drive_pins.reed_switch.pin) {
reed_switch_set = gpio::is_set(drive_pins.reed_switch);
}

// reset push button state if the door is opened or the reed switch is
// not set
if (!door_closed || !reed_switch_set) uv_push_button = false;

// set the UV Ballast
if (door_closed && reed_switch_set && uv_push_button) {
gpio::set(drive_pins.uv_on_off);
// start the turn off timer
_timer.start();
uv_fan_on = true;
} else {
gpio::reset(drive_pins.uv_on_off);
_timer.stop();
uv_fan_on = false;
}

// TODO: send CAN message to host
}

// state tracking variables
// TODO: add reed, door_open, etc
bool door_closed = false;
bool reed_switch_set = false;
bool uv_push_button = false;
bool uv_fan_on = false;

gpio_drive_hardware::GpioDrivePins &drive_pins;
ot_utils::freertos_timer::FreeRTOSTimer _timer;
};

/**
Expand Down

0 comments on commit 96b5eb7

Please sign in to comment.