Skip to content

Commit 05f9090

Browse files
authored
feat(hepa-uv): Add external IRQ handling and HEPA fan task to drive 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
1 parent eb17a01 commit 05f9090

File tree

12 files changed

+307
-31
lines changed

12 files changed

+307
-31
lines changed

hepa-uv/core/tasks.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,46 @@
33
#include "common/core/freertos_task.hpp"
44
#include "common/core/freertos_timer.hpp"
55
#include "hepa-uv/core/can_task.hpp"
6+
#include "hepa-uv/firmware/gpio_drive_hardware.hpp"
7+
#include "hepa-uv/firmware/utility_gpio.h"
68

79
#pragma GCC diagnostic push
810
// NOLINTNEXTLINE(clang-diagnostic-unknown-warning-option)
11+
#pragma GCC diagnostic ignored "-Wvolatile"
12+
#pragma GCC diagnostic pop
913

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

17+
static auto hepa_task_builder =
18+
freertos_task::TaskStarter<512, hepa_task::HepaTask>{};
19+
1320
/**
1421
* Start hepa_uv tasks.
1522
*/
16-
void hepauv_tasks::start_tasks(can::bus::CanBus& can_bus) {
23+
void hepauv_tasks::start_tasks(
24+
can::bus::CanBus& can_bus,
25+
gpio_drive_hardware::GpioDrivePins& gpio_drive_pins) {
1726
auto& can_writer = can_task::start_writer(can_bus);
1827
can_task::start_reader(can_bus);
28+
29+
auto& hepa_task = hepa_task_builder.start(5, "hepa_fan", gpio_drive_pins);
30+
31+
tasks.hepa_task_handler = &hepa_task;
1932
tasks.can_writer = &can_writer;
33+
2034
queues.set_queue(&can_writer.get_queue());
35+
queues.hepa_queue = &hepa_task.get_queue();
2136
}
2237

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

41+
void hepauv_tasks::QueueClient::send_interrupt_message(
42+
const hepa_task::TaskMessage& m) {
43+
hepa_queue->try_write(m);
44+
}
45+
2646
/**
2747
* Access to the tasks singleton
2848
* @return

hepa-uv/firmware/main_rev1.cpp

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "common/firmware/gpio.hpp"
2121
#include "common/firmware/iwdg.hpp"
2222
#include "common/firmware/utility_gpio.h"
23+
#include "hepa-uv/core/messages.hpp"
2324
#include "hepa-uv/core/tasks.hpp"
2425
#include "hepa-uv/firmware/utility_gpio.h"
2526

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

57+
static auto gpio_drive_pins = gpio_drive_hardware::GpioDrivePins{
58+
.door_open =
59+
gpio::PinConfig{
60+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
61+
.port = DOOR_OPEN_MCU_PORT,
62+
.pin = DOOR_OPEN_MCU_PIN,
63+
.active_setting = DOOR_OPEN_MCU_AS},
64+
.reed_switch =
65+
gpio::PinConfig{
66+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
67+
.port = REED_SW_MCU_PORT,
68+
.pin = REED_SW_MCU_PIN,
69+
.active_setting = REED_SW_MCU_AS},
70+
.hepa_push_button =
71+
gpio::PinConfig{
72+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
73+
.port = HEPA_NO_MCU_PORT,
74+
.pin = HEPA_NO_MCU_PIN,
75+
},
76+
.uv_push_button =
77+
gpio::PinConfig{
78+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
79+
.port = UV_NO_MCU_PORT,
80+
.pin = UV_NO_MCU_PIN,
81+
},
82+
.hepa_on_off =
83+
gpio::PinConfig{
84+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
85+
.port = HEPA_ON_OFF_PORT,
86+
.pin = HEPA_ON_OFF_PIN,
87+
.active_setting = HEPA_ON_OFF_AS},
88+
.uv_on_off = gpio::PinConfig{
89+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
90+
.port = UV_ON_OFF_MCU_PORT,
91+
.pin = UV_ON_OFF_MCU_PIN,
92+
.active_setting = UV_ON_OFF_AS}};
93+
94+
static auto& hepa_queue_client = hepauv_tasks::get_main_queues();
95+
96+
extern "C" void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
97+
switch (GPIO_Pin) {
98+
case DOOR_OPEN_MCU_PIN:
99+
case REED_SW_MCU_PIN:
100+
case HEPA_NO_MCU_PIN:
101+
case UV_NO_MCU_PIN:
102+
if (hepa_queue_client.hepa_queue != nullptr) {
103+
static_cast<void>(hepa_queue_client.hepa_queue->try_write_isr(
104+
interrupt_task_messages::GPIOInterruptChanged{
105+
.pin = GPIO_Pin}));
106+
}
107+
// send to uv queue here
108+
break;
109+
default:
110+
break;
111+
}
112+
}
113+
56114
auto main() -> int {
57115
HardwareInit();
58116
RCC_Peripheral_Clock_Select();
@@ -62,7 +120,7 @@ auto main() -> int {
62120

63121
canbus.start(can_bit_timings);
64122

65-
hepauv_tasks::start_tasks(canbus);
123+
hepauv_tasks::start_tasks(canbus, gpio_drive_pins);
66124

67125
iWatchdog.start(6);
68126

hepa-uv/firmware/stm32g4xx_it.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,26 @@ void DebugMon_Handler(void) {}
115115
/* file (startup_stm32g4xxxx.s). */
116116
/******************************************************************************/
117117

118-
/**
119-
* @brief This function handles PPP interrupt request.
120-
* @param None
121-
* @retval None
122-
*/
123-
/*void PPP_IRQHandler(void)
124-
{
125-
}*/
118+
void EXTI2_IRQHandler(void) {
119+
if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_2)) {
120+
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
121+
}
122+
}
123+
124+
void EXTI9_5_IRQHandler(void) {
125+
if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_7)) {
126+
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
127+
}
128+
}
129+
130+
void EXTI15_10_IRQHandler(void) {
131+
if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_10)) {
132+
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
133+
} else if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_11)) {
134+
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
135+
}
136+
}
137+
126138
/**
127139
* @brief This function handles DMA1 channel2 global interrupt.
128140
*/

hepa-uv/firmware/stm32g4xx_it.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ void SysTick_Handler(void);
4343
void DMA1_Channel2_IRQHandler(void);
4444
void DMA1_Channel3_IRQHandler(void);
4545
void FDCAN1_IT0_IRQHandler(void);
46+
void EXTI2_IRQHandler(void);
47+
void EXTI9_5_IRQHandler(void);
48+
void EXTI15_10_IRQHandler(void);
4649

4750
#ifdef __cplusplus
4851
}

hepa-uv/firmware/utility_gpio.c

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void door_open_input_gpio_init() {
3131
/*Configure GPIO pin DOOR_OPEN_MCU : PC7 */
3232
GPIO_InitTypeDef GPIO_InitStruct = {0};
3333
GPIO_InitStruct.Pin = DOOR_OPEN_MCU_PIN;
34-
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
34+
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
3535
GPIO_InitStruct.Pull = GPIO_NOPULL;
3636
HAL_GPIO_Init(DOOR_OPEN_MCU_PORT, &GPIO_InitStruct);
3737
}
@@ -44,10 +44,10 @@ void door_open_input_gpio_init() {
4444
void reed_switch_input_gpio_init() {
4545
/* GPIO Ports Clock Enable */
4646
__HAL_RCC_GPIOC_CLK_ENABLE();
47-
/*Configure GPIO pin DOOR_OPEN_MCU : PC11 */
47+
/*Configure GPIO pin REED_SW_MCU : PC11 */
4848
GPIO_InitTypeDef GPIO_InitStruct = {0};
4949
GPIO_InitStruct.Pin = REED_SW_MCU_PIN;
50-
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
50+
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
5151
GPIO_InitStruct.Pull = GPIO_NOPULL;
5252
HAL_GPIO_Init(REED_SW_MCU_PORT, &GPIO_InitStruct);
5353
}
@@ -59,7 +59,7 @@ void reed_switch_input_gpio_init() {
5959
*/
6060
void aux_input_gpio_init(void) {
6161
/* GPIO Ports Clock Enable */
62-
__HAL_RCC_GPIOB_CLK_ENABLE();
62+
__HAL_RCC_GPIOC_CLK_ENABLE();
6363
/*Configure GPIO pin AUX_ID_MCU : PC12 */
6464
GPIO_InitTypeDef GPIO_InitStruct = {0};
6565
GPIO_InitStruct.Pin = AUX_ID_MCU_PIN;
@@ -79,7 +79,7 @@ void hepa_push_button_input_gpio_init(void) {
7979
/*Configure GPIO pin HEPA_NO_MCU : PB10 */
8080
GPIO_InitTypeDef GPIO_InitStruct = {0};
8181
GPIO_InitStruct.Pin = HEPA_NO_MCU_PIN;
82-
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
82+
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
8383
GPIO_InitStruct.Pull = GPIO_NOPULL;
8484
HAL_GPIO_Init(HEPA_NO_MCU_PORT, &GPIO_InitStruct);
8585
}
@@ -89,9 +89,9 @@ void hepa_push_button_input_gpio_init(void) {
8989
* @param None
9090
* @retval None
9191
*/
92-
void uv_push_button_gpio_init(void) {
92+
void uv_push_button_input_gpio_init(void) {
9393
/*Configure Ports Clock Enable*/
94-
__HAL_RCC_GPIOB_CLK_ENABLE();
94+
__HAL_RCC_GPIOC_CLK_ENABLE();
9595
/*Configure GPIO pin UV_NO_MCU : PC2 */
9696
GPIO_InitTypeDef GPIO_InitStruct = {0};
9797
GPIO_InitStruct.Pin = UV_NO_MCU_PIN;
@@ -100,11 +100,72 @@ void uv_push_button_gpio_init(void) {
100100
HAL_GPIO_Init(UV_NO_MCU_PORT, &GPIO_InitStruct);
101101
}
102102

103+
/**
104+
* @brief HEPA ON/OFF GPIO Initialization Function
105+
* @param None
106+
* @retval None
107+
*/
108+
void hepa_on_off_output_init() {
109+
/* GPIO Ports Clock Enable */
110+
__HAL_RCC_GPIOA_CLK_ENABLE();
111+
/*Configure GPIO pin LED_DRIVE : PA7 */
112+
GPIO_InitTypeDef GPIO_InitStruct = {0};
113+
GPIO_InitStruct.Pin = HEPA_ON_OFF_PIN;
114+
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
115+
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
116+
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
117+
HAL_GPIO_Init(HEPA_ON_OFF_PORT, &GPIO_InitStruct);
118+
}
119+
120+
/**
121+
* @brief UV ON/OFF GPIO Initialization Function
122+
* @param None
123+
* @retval None
124+
*/
125+
void uv_on_off_output_init() {
126+
/* GPIO Ports Clock Enable */
127+
__HAL_RCC_GPIOA_CLK_ENABLE();
128+
/*Configure GPIO pin LED_DRIVE : PA4 */
129+
GPIO_InitTypeDef GPIO_InitStruct = {0};
130+
GPIO_InitStruct.Pin = UV_ON_OFF_MCU_PIN;
131+
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
132+
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
133+
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
134+
HAL_GPIO_Init(UV_ON_OFF_MCU_PORT, &GPIO_InitStruct);
135+
}
136+
137+
/**
138+
* @brief NVIC EXTI interrupt priority Initialization
139+
* @param None
140+
* @retval None
141+
*/
142+
static void nvic_priority_enable_init() {
143+
/* EXTI interrupt init DOOR_OPEN_MCU : PC7*/
144+
// PC7 -> GPIO_EXTI6 (EXTI9_5_IRQn)
145+
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0);
146+
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
147+
148+
/* EXTI interrupt init REED_SW_MCU : PC11*/
149+
/* EXTI interrupt init HEPA_NO_MCU : PB10*/
150+
// PC11 -> GPIO_EXTI11 (EXTI15_10_IRQn)
151+
// PB11 -> GPIO_EXTI11 (EXTI15_10_IRQn)
152+
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
153+
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
154+
155+
/* EXTI interrupt init UV_NO_MCU : PC2*/
156+
// PC2 -> GPIO_EXTI2 (EXTI2_IRQn)
157+
HAL_NVIC_SetPriority(EXTI2_IRQn, 5, 0);
158+
HAL_NVIC_EnableIRQ(EXTI2_IRQn);
159+
}
160+
103161
void utility_gpio_init(void) {
104162
LED_drive_gpio_init();
163+
nvic_priority_enable_init();
105164
door_open_input_gpio_init();
106165
reed_switch_input_gpio_init();
107166
aux_input_gpio_init();
108167
hepa_push_button_input_gpio_init();
109-
uv_push_button_gpio_init();
168+
uv_push_button_input_gpio_init();
169+
hepa_on_off_output_init();
170+
uv_on_off_output_init();
110171
}

hepa-uv/simulator/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@ target_can_simlib(hepa-uv-simulator)
4949

5050
target_hepa_uv_core(hepa-uv-simulator)
5151

52-
target_ot_motor_control(hepa-uv-simulator)
53-
54-
target_i2c_simlib(hepa-uv-simulator)
55-
5652
target_link_libraries(hepa-uv-simulator PRIVATE can-core common-simulation freertos-hepa-uv pthread Boost::boost Boost::program_options state_manager)
5753

5854
set_target_properties(hepa-uv-simulator

hepa-uv/simulator/main.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "common/core/freertos_task.hpp"
1212
#include "common/simulation/state_manager.hpp"
1313
#include "hepa-uv/core/tasks.hpp"
14+
#include "hepa-uv/firmware/gpio_drive_hardware.hpp"
1415
#include "task.h"
1516

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

69+
static auto gpio_drive_pins = gpio_drive_hardware::GpioDrivePins{};
70+
6871
int main(int argc, char** argv) {
72+
// TODO: (ba, 2024-01-18): Fix the simulator later on
6973
signal(SIGINT, signal_handler);
7074

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

8185
static auto canbus =
8286
can::sim::bus::SimCANBus(can::sim::transport::create(options));
83-
hepauv_tasks::start_tasks(canbus);
87+
hepauv_tasks::start_tasks(canbus, gpio_drive_pins);
8488

8589
vTaskStartScheduler();
8690
}

0 commit comments

Comments
 (0)