Skip to content

Commit

Permalink
- Added irq router for door_open, reed_switch, hepa_push_button, and …
Browse files Browse the repository at this point in the history
…uv_push_button

- Added HepaTask that is responsible for handeling irq events received on its message queue to turn the hepa fan on/off
- Fixed up gpio init settings for door_open, reed_switch and others
  • Loading branch information
vegano1 committed Jan 17, 2024
1 parent 86d128b commit 67ec597
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 25 deletions.
51 changes: 51 additions & 0 deletions hepa-uv/core/tasks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,77 @@
#include "common/core/freertos_task.hpp"
#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/utility_gpio.h"


#pragma GCC diagnostic push
// NOLINTNEXTLINE(clang-diagnostic-unknown-warning-option)
#pragma GCC diagnostic ignored "-Wvolatile"
#include "platform_specific_hal_conf.h"
#pragma GCC diagnostic pop

static auto tasks = hepauv_tasks::AllTask{};
static auto queues = hepauv_tasks::QueueClient{can::ids::NodeId::hepa_uv};

static auto gpio_drive_pins = gpio_drive_hardware::GpioDrivePins {
.door_open = gpio::PinConfig{
.port = DOOR_OPEN_MCU_PORT,
.pin = DOOR_OPEN_MCU_PIN,
.active_setting = DOOR_OPEN_MCU_AS
},
.reed_switch = gpio::PinConfig{
.port = REED_SW_MCU_PORT,
.pin = REED_SW_MCU_PIN,
.active_setting = REED_SW_MCU_AS
},
.hepa_push_button = gpio::PinConfig{
.port = HEPA_NO_MCU_PORT,
.pin = HEPA_NO_MCU_PIN,
},
.uv_push_button = gpio::PinConfig{
.port = UV_NO_MCU_PORT,
.pin = UV_NO_MCU_PIN,
},
.hepa_on_off = gpio::PinConfig{
.port = HEPA_ON_OFF_PORT,
.pin = HEPA_ON_OFF_PIN,
.active_setting = HEPA_ON_OFF_AS
},
.uv_on_off = gpio::PinConfig{
.port = UV_ON_OFF_MCU_PORT,
.pin = UV_ON_OFF_MCU_PIN,
.active_setting = UV_ON_OFF_AS
}
};

static auto hepa_task_builder =
freertos_task::TaskStarter<512, hepa_task::HepaTask>{};

/**
* Start hepa_uv tasks.
*/
void hepauv_tasks::start_tasks(can::bus::CanBus& can_bus) {
auto& can_writer = can_task::start_writer(can_bus);
can_task::start_reader(can_bus);

auto& hepa_task = hepa_task_builder.start(5, "hepa_fan", gpio_drive_pins);

tasks.hepa_task_handler = &hepa_task;
tasks.can_writer = &can_writer;

queues.set_queue(&can_writer.get_queue());
queues.hepa_queue = &hepa_task.get_queue();
}

hepauv_tasks::QueueClient::QueueClient(can::ids::NodeId this_fw)
: can::message_writer::MessageWriter{this_fw} {}

void hepauv_tasks::QueueClient::send_interrupt_message(
const hepa_task::TaskMessage& m) {
hepa_queue->try_write(m);
}

/**
* Access to the tasks singleton
* @return
Expand Down
20 changes: 20 additions & 0 deletions hepa-uv/firmware/main_rev1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "common/firmware/utility_gpio.h"
#include "hepa-uv/core/tasks.hpp"
#include "hepa-uv/firmware/utility_gpio.h"
#include "hepa-uv/core/messages.hpp"

static auto iWatchdog = iwdg::IndependentWatchDog{};

Expand Down Expand Up @@ -53,6 +54,25 @@ static constexpr auto can_bit_timings =
can::bit_timings::BitTimings<170 * can::bit_timings::MHZ, 100,
500 * can::bit_timings::KHZ, 800>{};

static auto& hepa_queue_client = 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(
interrupt_task_messages::GPIOInterruptChanged{.pin = GPIO_Pin }));
}
// send to uv queue here
break;
default:
break;
}
}

auto main() -> int {
HardwareInit();
RCC_Peripheral_Clock_Select();
Expand Down
28 changes: 20 additions & 8 deletions hepa-uv/firmware/stm32g4xx_it.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,26 @@ void DebugMon_Handler(void) {}
/* file (startup_stm32g4xxxx.s). */
/******************************************************************************/

/**
* @brief This function handles PPP interrupt request.
* @param None
* @retval None
*/
/*void PPP_IRQHandler(void)
{
}*/
void EXTI2_IRQHandler(void) {
if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_2)) {
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
}
}

void EXTI9_5_IRQHandler(void) {
if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_7)) {
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
}
}

void EXTI15_10_IRQHandler(void) {
if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_10)) {
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
} else if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_11)) {
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
}
}

/**
* @brief This function handles DMA1 channel2 global interrupt.
*/
Expand Down
3 changes: 3 additions & 0 deletions hepa-uv/firmware/stm32g4xx_it.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ void SysTick_Handler(void);
void DMA1_Channel2_IRQHandler(void);
void DMA1_Channel3_IRQHandler(void);
void FDCAN1_IT0_IRQHandler(void);
void EXTI2_IRQHandler(void);
void EXTI9_5_IRQHandler(void);
void EXTI15_10_IRQHandler(void);

#ifdef __cplusplus
}
Expand Down
56 changes: 46 additions & 10 deletions hepa-uv/firmware/utility_gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void door_open_input_gpio_init() {
/*Configure GPIO pin DOOR_OPEN_MCU : PC7 */
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = DOOR_OPEN_MCU_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DOOR_OPEN_MCU_PORT, &GPIO_InitStruct);
}
Expand All @@ -47,7 +47,7 @@ void reed_switch_input_gpio_init() {
/*Configure GPIO pin REED_SW_MCU : PC11 */
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = REED_SW_MCU_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(REED_SW_MCU_PORT, &GPIO_InitStruct);
}
Expand All @@ -59,7 +59,7 @@ void reed_switch_input_gpio_init() {
*/
void aux_input_gpio_init(void) {
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/*Configure GPIO pin AUX_ID_MCU : PC12 */
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = AUX_ID_MCU_PIN;
Expand All @@ -79,7 +79,7 @@ void hepa_push_button_input_gpio_init(void) {
/*Configure GPIO pin HEPA_NO_MCU : PB10 */
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = HEPA_NO_MCU_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(HEPA_NO_MCU_PORT, &GPIO_InitStruct);
}
Expand All @@ -89,9 +89,9 @@ void hepa_push_button_input_gpio_init(void) {
* @param None
* @retval None
*/
void uv_push_button_gpio_init(void) {
void uv_push_button_input_gpio_init(void) {
/*Configure Ports Clock Enable*/
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/*Configure GPIO pin UV_NO_MCU : PC2 */
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = UV_NO_MCU_PIN;
Expand All @@ -100,6 +100,40 @@ void uv_push_button_gpio_init(void) {
HAL_GPIO_Init(UV_NO_MCU_PORT, &GPIO_InitStruct);
}

/**
* @brief HEPA ON/OFF GPIO Initialization Function
* @param None
* @retval None
*/
void hepa_on_off_output_init() {
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin LED_DRIVE : PA7 */
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = HEPA_ON_OFF_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(HEPA_ON_OFF_PORT, &GPIO_InitStruct);
}

/**
* @brief UV ON/OFF GPIO Initialization Function
* @param None
* @retval None
*/
void uv_on_off_output_init() {
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin LED_DRIVE : PA4 */
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = UV_ON_OFF_MCU_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(UV_ON_OFF_MCU_PORT, &GPIO_InitStruct);
}

/**
* @brief NVIC EXTI interrupt priority Initialization
* @param None
Expand All @@ -115,21 +149,23 @@ static void nvic_priority_enable_init() {
/* 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, 7, 0);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

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

void utility_gpio_init(void) {
LED_drive_gpio_init();
nvic_priority_enable_init();
door_open_input_gpio_init();
reed_switch_input_gpio_init();
aux_input_gpio_init();
hepa_push_button_input_gpio_init();
uv_push_button_gpio_init();
nvic_priority_enable_init();
uv_push_button_input_gpio_init();
hepa_on_off_output_init();
uv_on_off_output_init();
}
92 changes: 92 additions & 0 deletions include/hepa-uv/core/hepa_task.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#pragma once

#include "can/core/ids.hpp"
#include "common/core/bit_utils.hpp"
#include "common/core/logging.h"
#include "common/core/message_queue.hpp"
#include "messages.hpp"
#include "hepa-uv/firmware/gpio_drive_hardware.hpp"

namespace hepa_task {

using TaskMessage = interrupt_task_messages::TaskMessage;

class HepaMessageHandler {
public:
explicit HepaMessageHandler(
gpio_drive_hardware::GpioDrivePins& drive_pins)
: drive_pins{drive_pins} {}
HepaMessageHandler(const HepaMessageHandler &) = delete;
HepaMessageHandler(const HepaMessageHandler &&) = delete;
auto operator=(const HepaMessageHandler &)
-> HepaMessageHandler & = delete;
auto operator=(const HepaMessageHandler &&)
-> HepaMessageHandler && = delete;
~HepaMessageHandler() { }

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

private:
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) {
hepa_push_button = !hepa_push_button;
// handle state changes here
if (hepa_push_button) {
gpio::set(drive_pins.hepa_on_off);
} else {
gpio::reset(drive_pins.hepa_on_off);
}
}

// TODO: send CAN message to host
}

// state tracking variables
bool hepa_push_button = false;
bool hepa_fan_on = false;

gpio_drive_hardware::GpioDrivePins& drive_pins;
};

/**
* The task type.
*/
template <template <class> class QueueImpl>
requires MessageQueue<QueueImpl<TaskMessage>, TaskMessage>
class HepaTask {
public:
using Messages = TaskMessage;
using QueueType = QueueImpl<TaskMessage>;
HepaTask(QueueType &queue)
: queue{queue} {}
HepaTask(const HepaTask &c) = delete;
HepaTask(const HepaTask &&c) = delete;
auto operator=(const HepaTask &c) = delete;
auto operator=(const HepaTask &&c) = delete;
~HepaTask() = default;

/**
* Task entry point.
*/
[[noreturn]] void operator()(
gpio_drive_hardware::GpioDrivePins* drive_pins) {
auto handler = HepaMessageHandler{*drive_pins};
TaskMessage message{};
for (;;) {
if (queue.try_read(&message, queue.max_delay)) {
handler.handle_message(message);
}
}
}

[[nodiscard]] auto get_queue() const -> QueueType & { return queue; }

private:
QueueType &queue;
};
}; // namespace hepa_task
19 changes: 19 additions & 0 deletions include/hepa-uv/core/messages.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include "can/core/messages.hpp"
#include "hepa-uv/firmware/gpio_drive_hardware.hpp"

namespace interrupt_task_messages {

/**
* A message sent when external interurpts are triguered
*/
struct GPIOInterruptChanged {
uint16_t pin;
uint8_t state;
};

using TaskMessage =
std::variant<std::monostate, GPIOInterruptChanged>;

} // namespace interrupt_task_messages
Loading

0 comments on commit 67ec597

Please sign in to comment.