From e48b8b5dd43493c22a489fedcb6c1df10d20f38d Mon Sep 17 00:00:00 2001 From: vegano1 Date: Fri, 31 May 2024 16:26:49 -0400 Subject: [PATCH] - renamed UV_NO_MCU_PIN to nUV_PRESSED_PIN for accuracy - added nSAFETY_ACTIVE_MCU input pin to know the state of the safety relay - added internal safety_relay_active flag in uv_task to keep track of safety relay state - update safety_relay_active state from the nSAFETY_ACTIVE_MCU gpis whenever uv_task handles irq. - added safety_relay_active flag to HepaUVStateResponse - check the safety_relay_active state after turning on the uv light - send safety_relay_inactive 0x11 error code if the relay is not active - added ot_utils::freertos_sleep::sleep to cpp-utils to sleep the task for n milliseconds --- .../ot_utils/freertos/freertos_sleep.hpp | 12 +++++++ hepa-uv/firmware/main_rev1.cpp | 14 +++++--- hepa-uv/firmware/utility_gpio.c | 21 +++++++++-- include/bootloader/core/ids.h | 1 + include/can/core/ids.hpp | 1 + include/can/core/messages.hpp | 2 ++ include/common/core/wtf.hpp | 6 ++++ include/hepa-uv/core/uv_task.hpp | 35 +++++++++++++++++-- .../hepa-uv/firmware/gpio_drive_hardware.hpp | 1 + include/hepa-uv/firmware/utility_gpio.h | 15 ++++---- 10 files changed, 93 insertions(+), 15 deletions(-) create mode 100644 cpp-utils/include/ot_utils/freertos/freertos_sleep.hpp create mode 100644 include/common/core/wtf.hpp diff --git a/cpp-utils/include/ot_utils/freertos/freertos_sleep.hpp b/cpp-utils/include/ot_utils/freertos/freertos_sleep.hpp new file mode 100644 index 000000000..18a589b8e --- /dev/null +++ b/cpp-utils/include/ot_utils/freertos/freertos_sleep.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "FreeRTOS.h" +#include "task.h" + +namespace ot_utils { +namespace freertos_sleep { + +static void sleep(uint32_t time_ms) { if (time_ms > 0) vTaskDelay(pdMS_TO_TICKS(time_ms)); } + +} // namespace freertos_sleep +} // namespace ot_utils diff --git a/hepa-uv/firmware/main_rev1.cpp b/hepa-uv/firmware/main_rev1.cpp index 4bfed1d3a..a3cc0f502 100644 --- a/hepa-uv/firmware/main_rev1.cpp +++ b/hepa-uv/firmware/main_rev1.cpp @@ -114,8 +114,8 @@ static auto gpio_drive_pins = gpio_drive_hardware::GpioDrivePins{ .uv_push_button = gpio::PinConfig{ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) - .port = UV_NO_MCU_PORT, - .pin = UV_NO_MCU_PIN, + .port = nUV_PRESSED_PORT, + .pin = nUV_PRESSED_PIN, }, .hepa_on_off = gpio::PinConfig{ @@ -127,7 +127,13 @@ static auto gpio_drive_pins = gpio_drive_hardware::GpioDrivePins{ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) .port = UV_ON_OFF_MCU_PORT, .pin = UV_ON_OFF_MCU_PIN, - .active_setting = UV_ON_OFF_AS}}; + .active_setting = UV_ON_OFF_AS}, + .safety_relay_active = gpio::PinConfig{ + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) + .port = nSAFETY_ACTIVE_MCU_PORT, + .pin = nSAFETY_ACTIVE_MCU_PIN, + .active_setting = nSAFETY_ACTIVE_AS}, + }; static auto& hepauv_queues = hepauv_tasks::get_main_queues(); @@ -140,7 +146,7 @@ extern "C" void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { case DOOR_OPEN_MCU_PIN: case REED_SW_MCU_PIN: case HEPA_NO_MCU_PIN: - case UV_NO_MCU_PIN: + case nUV_PRESSED_PIN: if (hepauv_queues.hepa_queue != nullptr) { static_cast(hepauv_queues.hepa_queue->try_write_isr( GPIOInterruptChanged{.pin = GPIO_Pin})); diff --git a/hepa-uv/firmware/utility_gpio.c b/hepa-uv/firmware/utility_gpio.c index 405ba81bf..35d3e2485 100644 --- a/hepa-uv/firmware/utility_gpio.c +++ b/hepa-uv/firmware/utility_gpio.c @@ -94,10 +94,10 @@ void uv_push_button_input_gpio_init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); /*Configure GPIO pin UV_NO_MCU : PC2 */ GPIO_InitTypeDef GPIO_InitStruct = {0}; - GPIO_InitStruct.Pin = UV_NO_MCU_PIN; + GPIO_InitStruct.Pin = nUV_PRESSED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(UV_NO_MCU_PORT, &GPIO_InitStruct); + HAL_GPIO_Init(nUV_PRESSED_PORT, &GPIO_InitStruct); } /** @@ -134,6 +134,22 @@ void uv_on_off_output_init() { HAL_GPIO_Init(UV_ON_OFF_MCU_PORT, &GPIO_InitStruct); } +/** + * @brief nSAFETY_ACTIVE_MCU GPIO Initialization Function + * @param None + * @retval None +*/ +void safety_relay_active_input_init() { + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOB_CLK_ENABLE(); + /*Configure GPIO pin nSAFETY_ACTIVE_MCU: PB6 */ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = nSAFETY_ACTIVE_MCU_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(nSAFETY_ACTIVE_MCU_PORT, &GPIO_InitStruct); +} + /** * @brief NVIC EXTI interrupt priority Initialization * @param None @@ -168,4 +184,5 @@ void utility_gpio_init(void) { hepa_on_off_output_init(); uv_push_button_input_gpio_init(); uv_on_off_output_init(); + safety_relay_active_input_init(); } diff --git a/include/bootloader/core/ids.h b/include/bootloader/core/ids.h index b3c7ae1b9..e805bb401 100644 --- a/include/bootloader/core/ids.h +++ b/include/bootloader/core/ids.h @@ -165,6 +165,7 @@ typedef enum { can_errorcode_over_pressure = 0xd, can_errorcode_door_open = 0xe, can_errorcode_reed_open = 0xf, + can_errorcode_safety_relay_inactive = 0x11, } CANErrorCode; /** Tool types detected on Head. */ diff --git a/include/can/core/ids.hpp b/include/can/core/ids.hpp index dad0695f5..a0195eff7 100644 --- a/include/can/core/ids.hpp +++ b/include/can/core/ids.hpp @@ -167,6 +167,7 @@ enum class ErrorCode { over_pressure = 0xd, door_open = 0xe, reed_open = 0xf, + safety_relay_inactive = 0x11, }; /** Error Severity levels. */ diff --git a/include/can/core/messages.hpp b/include/can/core/messages.hpp index a60eedc3c..1b4011965 100644 --- a/include/can/core/messages.hpp +++ b/include/can/core/messages.hpp @@ -1712,6 +1712,7 @@ struct GetHepaUVStateResponse uint8_t uv_light_on; uint32_t remaining_time_s; uint16_t uv_current_ma; + uint8_t safety_relay_active; template auto serialize(Output body, Limit limit) const -> uint8_t { @@ -1720,6 +1721,7 @@ struct GetHepaUVStateResponse iter = bit_utils::int_to_bytes(uv_light_on, iter, limit); iter = bit_utils::int_to_bytes(remaining_time_s, iter, limit); iter = bit_utils::int_to_bytes(uv_current_ma, iter, limit); + iter = bit_utils::int_to_bytes(safety_relay_active, iter, limit); return iter - body; } diff --git a/include/common/core/wtf.hpp b/include/common/core/wtf.hpp new file mode 100644 index 000000000..4a539f642 --- /dev/null +++ b/include/common/core/wtf.hpp @@ -0,0 +1,6 @@ +#pragma once + +#include + + +void something(uint32_t time_ms) { printf("something %lu", time_ms); } diff --git a/include/hepa-uv/core/uv_task.hpp b/include/hepa-uv/core/uv_task.hpp index 317a0644c..586dd2002 100644 --- a/include/hepa-uv/core/uv_task.hpp +++ b/include/hepa-uv/core/uv_task.hpp @@ -10,6 +10,7 @@ #include "hepa-uv/firmware/gpio_drive_hardware.hpp" #include "hepa-uv/firmware/uv_control_hardware.hpp" #include "ot_utils/freertos/freertos_timer.hpp" +#include "ot_utils/freertos/freertos_sleep.hpp" namespace uv_task { @@ -38,6 +39,7 @@ class UVMessageHandler { 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); + safety_relay_active = gpio::is_set(drive_pins.safety_relay_active); // turn off UV Ballast gpio::reset(drive_pins.uv_on_off); } @@ -76,6 +78,9 @@ class UVMessageHandler { reed_switch_set = gpio::is_set(drive_pins.reed_switch); } + // Always update safety relay state + safety_relay_active = gpio::is_set(drive_pins.safety_relay_active); + // Drive the UV light set_uv_light_state(uv_push_button, uv_off_timeout_s); } @@ -95,7 +100,8 @@ class UVMessageHandler { .timeout_s = uv_off_timeout_s, .uv_light_on = uv_light_on, .remaining_time_s = (_timer.get_remaining_time() / 1000), - .uv_current_ma = uv_current_ma}; + .uv_current_ma = uv_current_ma, + .safety_relay_active = safety_relay_active}; can_client.send_can_message(can::ids::NodeId::host, resp); } @@ -153,8 +159,32 @@ class UVMessageHandler { if (_timer.is_running()) _timer.stop(); } - // Update the voltage usage of the uv light + // wait 10ms for safety relay, then update the states + ot_utils::freertos_sleep::sleep(10); + safety_relay_active = gpio::is_set(drive_pins.safety_relay_active); uv_current_ma = uv_hardware.get_uv_light_current(); + if (!safety_relay_active) { + // we tried to set the uv light, but the relay is not active + if (_timer.is_running()) { + gpio::reset(drive_pins.uv_on_off); + _timer.stop(); + led_control_client.send_led_control_message( + led_control_task_messages::PushButtonLED(UV_BUTTON, 0, 0, + 50, 0)); + } + // send error + auto msg = can::messages::ErrorMessage{ + .message_index = 0, + .severity = can::ids::ErrorSeverity::warning, + .error_code = can::ids::ErrorCode::safety_relay_inactive, + }; + can_client.send_can_message(can::ids::NodeId::host, msg); + + uv_push_button = false; + uv_light_on = false; + uv_current_ma = 0; + return; + } // TODO: send state change CAN message to host } @@ -162,6 +192,7 @@ class UVMessageHandler { // state tracking variables bool door_closed = false; bool reed_switch_set = false; + bool safety_relay_active = false; bool uv_push_button = false; bool uv_light_on = false; uint32_t uv_off_timeout_s = DELAY_S; diff --git a/include/hepa-uv/firmware/gpio_drive_hardware.hpp b/include/hepa-uv/firmware/gpio_drive_hardware.hpp index 517f435c9..1c622ccc0 100644 --- a/include/hepa-uv/firmware/gpio_drive_hardware.hpp +++ b/include/hepa-uv/firmware/gpio_drive_hardware.hpp @@ -11,6 +11,7 @@ struct GpioDrivePins { gpio::PinConfig uv_push_button; gpio::PinConfig hepa_on_off; gpio::PinConfig uv_on_off; + gpio::PinConfig safety_relay_active; }; } // namespace gpio_drive_hardware \ No newline at end of file diff --git a/include/hepa-uv/firmware/utility_gpio.h b/include/hepa-uv/firmware/utility_gpio.h index 7c383e1f2..400f96e47 100644 --- a/include/hepa-uv/firmware/utility_gpio.h +++ b/include/hepa-uv/firmware/utility_gpio.h @@ -88,12 +88,9 @@ void utility_gpio_init(); #define UV_ON_OFF_MCU_PORT GPIOA #define UV_ON_OFF_MCU_PIN GPIO_PIN_4 #define UV_ON_OFF_AS GPIO_PIN_RESET -// UV_NO_MCU PC2 -#define UV_NO_MCU_PORT GPIOC -#define UV_NO_MCU_PIN GPIO_PIN_2 -// UV_ADC PA3 -#define UV_ADC_PORT GPIOC -#define UV_ADC_PIN GPIO_PIN_3 +// nUV_PRESSED PC2 +#define nUV_PRESSED_PORT GPIOC +#define nUV_PRESSED_PIN GPIO_PIN_2 // UV_B_CTRL PC5 #define UV_B_CTRL_PORT GPIOC #define UV_B_CTRL_PIN GPIO_PIN_5 @@ -105,4 +102,8 @@ void utility_gpio_init(); #define UV_R_CTRL_PIN GPIO_PIN_1 // UV_W_CTRL PB2 #define UV_W_CTRL_PORT GPIOB -#define UV_W_CTRL_PIN GPIO_PIN_2 \ No newline at end of file +#define UV_W_CTRL_PIN GPIO_PIN_2 +// nSAFETY_ACTIVE_MCU PB6 +#define nSAFETY_ACTIVE_MCU_PORT GPIOB +#define nSAFETY_ACTIVE_MCU_PIN GPIO_PIN_6 +#define nSAFETY_ACTIVE_AS GPIO_PIN_RESET \ No newline at end of file