Skip to content

Commit

Permalink
feat(hepa-uv): Add external IRQ handling and HEPA fan task to drive …
Browse files Browse the repository at this point in the history
…the HEPA fan. (#742)

* Added GPIO EXTI interrupt configuration.
* Added irq router for door_open, reed_switch, hepa_push_button, and uv_push_button
* Added HepaTask that is responsible for handling 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
* The hepa/uv simulator is broken right now, add a todo to fix this later in RET-1408
  • Loading branch information
vegano1 authored Jan 18, 2024
1 parent eb17a01 commit 05f9090
Show file tree
Hide file tree
Showing 12 changed files with 307 additions and 31 deletions.
22 changes: 21 additions & 1 deletion hepa-uv/core/tasks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,46 @@
#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"
#pragma GCC diagnostic pop

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

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) {
void hepauv_tasks::start_tasks(
can::bus::CanBus& can_bus,
gpio_drive_hardware::GpioDrivePins& gpio_drive_pins) {
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
60 changes: 59 additions & 1 deletion hepa-uv/firmware/main_rev1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "common/firmware/gpio.hpp"
#include "common/firmware/iwdg.hpp"
#include "common/firmware/utility_gpio.h"
#include "hepa-uv/core/messages.hpp"
#include "hepa-uv/core/tasks.hpp"
#include "hepa-uv/firmware/utility_gpio.h"

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

static auto gpio_drive_pins = gpio_drive_hardware::GpioDrivePins{
.door_open =
gpio::PinConfig{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
.port = DOOR_OPEN_MCU_PORT,
.pin = DOOR_OPEN_MCU_PIN,
.active_setting = DOOR_OPEN_MCU_AS},
.reed_switch =
gpio::PinConfig{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
.port = REED_SW_MCU_PORT,
.pin = REED_SW_MCU_PIN,
.active_setting = REED_SW_MCU_AS},
.hepa_push_button =
gpio::PinConfig{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
.port = HEPA_NO_MCU_PORT,
.pin = HEPA_NO_MCU_PIN,
},
.uv_push_button =
gpio::PinConfig{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
.port = UV_NO_MCU_PORT,
.pin = UV_NO_MCU_PIN,
},
.hepa_on_off =
gpio::PinConfig{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
.port = HEPA_ON_OFF_PORT,
.pin = HEPA_ON_OFF_PIN,
.active_setting = HEPA_ON_OFF_AS},
.uv_on_off = gpio::PinConfig{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
.port = UV_ON_OFF_MCU_PORT,
.pin = UV_ON_OFF_MCU_PIN,
.active_setting = UV_ON_OFF_AS}};

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 All @@ -62,7 +120,7 @@ auto main() -> int {

canbus.start(can_bit_timings);

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

iWatchdog.start(6);

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
77 changes: 69 additions & 8 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 @@ -44,10 +44,10 @@ void door_open_input_gpio_init() {
void reed_switch_input_gpio_init() {
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
/*Configure GPIO pin DOOR_OPEN_MCU : PC11 */
/*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,11 +100,72 @@ 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
* @retval None
*/
static void nvic_priority_enable_init() {
/* EXTI interrupt init DOOR_OPEN_MCU : PC7*/
// PC7 -> GPIO_EXTI6 (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_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_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();
uv_push_button_input_gpio_init();
hepa_on_off_output_init();
uv_on_off_output_init();
}
4 changes: 0 additions & 4 deletions hepa-uv/simulator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ target_can_simlib(hepa-uv-simulator)

target_hepa_uv_core(hepa-uv-simulator)

target_ot_motor_control(hepa-uv-simulator)

target_i2c_simlib(hepa-uv-simulator)

target_link_libraries(hepa-uv-simulator PRIVATE can-core common-simulation freertos-hepa-uv pthread Boost::boost Boost::program_options state_manager)

set_target_properties(hepa-uv-simulator
Expand Down
6 changes: 5 additions & 1 deletion hepa-uv/simulator/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "common/core/freertos_task.hpp"
#include "common/simulation/state_manager.hpp"
#include "hepa-uv/core/tasks.hpp"
#include "hepa-uv/firmware/gpio_drive_hardware.hpp"
#include "task.h"

namespace po = boost::program_options;
Expand Down Expand Up @@ -65,7 +66,10 @@ auto handle_options(int argc, char** argv) -> po::variables_map {
return vm;
}

static auto gpio_drive_pins = gpio_drive_hardware::GpioDrivePins{};

int main(int argc, char** argv) {
// TODO: (ba, 2024-01-18): Fix the simulator later on
signal(SIGINT, signal_handler);

LOG_INIT("HEPA/UV", []() -> const char* {
Expand All @@ -80,7 +84,7 @@ int main(int argc, char** argv) {

static auto canbus =
can::sim::bus::SimCANBus(can::sim::transport::create(options));
hepauv_tasks::start_tasks(canbus);
hepauv_tasks::start_tasks(canbus, gpio_drive_pins);

vTaskStartScheduler();
}
Loading

0 comments on commit 05f9090

Please sign in to comment.