From 5eb51f08b670d03219074bf9407a07ae13972349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Tue, 7 Jul 2020 20:47:22 +0200 Subject: [PATCH] Start safety implementation. Completely dumped old stuff --- stm-firmware/Makefile | 2 +- .../reflow-controller/safety/safety-config.h | 33 +++++ .../safety/safety-controller-config-default.h | 92 ------------- .../safety/safety-controller.h | 9 +- .../safety/safety-controller-config-default.c | 51 ------- stm-firmware/safety/safety-controller.c | 130 ++++++++++++++++++ 6 files changed, 170 insertions(+), 147 deletions(-) delete mode 100644 stm-firmware/include/reflow-controller/safety/safety-controller-config-default.h delete mode 100644 stm-firmware/safety/safety-controller-config-default.c diff --git a/stm-firmware/Makefile b/stm-firmware/Makefile index 758d1d5..f184317 100644 --- a/stm-firmware/Makefile +++ b/stm-firmware/Makefile @@ -47,7 +47,7 @@ CFILES += fatfs/diskio.c fatfs/ff.c fatfs/ffsystem.c fatfs/ffunicode.c fatfs/shi CFILES += pid-controller.c oven-driver.c CFILES += settings/settings.c settings/settings-sd-card.c -CFILES += safety/safety-adc.c safety/safety-controller.c safety/watchdog.c safety/safety-controller-config-default.c +CFILES += safety/safety-adc.c safety/safety-controller.c safety/watchdog.c DEBUG_DEFINES = -DDEBUGBUILD RELEASE_DEFINES = diff --git a/stm-firmware/include/reflow-controller/safety/safety-config.h b/stm-firmware/include/reflow-controller/safety/safety-config.h index c7a496d..6d1ca80 100644 --- a/stm-firmware/include/reflow-controller/safety/safety-config.h +++ b/stm-firmware/include/reflow-controller/safety/safety-config.h @@ -21,6 +21,31 @@ #ifndef __SAFETY_CONFIG_H__ #define __SAFETY_CONFIG_H__ + +enum safety_flag { + ERR_FLAG_MEAS_ADC_OFF = (1<<0), + ERR_FLAG_MEAS_ADC_OVERFLOW = (1<<1), + ERR_FLAG_MEAS_ADC_WATCHDOG = (1<<2), + ERR_FLAG_MEAS_ADC_UNSTABLE = (1<<3), + ERR_FLAG_TIMING_PID = (1<<4), + ERR_FLAG_TIMING_MEAS_ADC = (1<<5), + ERR_FLAG_AMON_VREF = (1<<6), + ERR_FLAG_AMON_UC_TEMP = (1<<7), + ERR_FLAG_STACK = (1<<8), +}; + +enum timing_monitor { + ERR_TIMING_PID = (1<<0), + ERR_TIMING_MEAS_ADC = (1<<1), + ERR_TIMING_SAFETY_ADC = (1<<2), +}; + +enum analog_value_monitor { + ERR_AMON_VREF = (1<<0), + ERR_AMON_UC_TEMP = (1<<1), +}; + + /** * @brief Magic key used to reset the watchdog using the @ref watchdog_ack function */ @@ -35,4 +60,12 @@ #define WATCHDOG_PRESCALER 4 +#define SAFETY_MIN_STACK_FREE 0x100 + +#define PID_CONTROLLER_ERR_CAREMASK (ERR_FLAG_STACK | ERR_FLAG_AMON_UC_TEMP | ERR_FLAG_AMON_VREF | \ + ERR_FLAG_TIMING_PID | ERR_FLAG_TIMING_MEAS_ADC | ERR_FLAG_MEAS_ADC_OFF | \ + ERR_FLAG_MEAS_ADC_OVERFLOW) + +#define HALTING_CAREMASK (ERR_FLAG_STACK | ERR_FLAG_AMON_UC_TEMP) + #endif /* __SAFETY_CONFIG_H__ */ diff --git a/stm-firmware/include/reflow-controller/safety/safety-controller-config-default.h b/stm-firmware/include/reflow-controller/safety/safety-controller-config-default.h deleted file mode 100644 index 3a41bc2..0000000 --- a/stm-firmware/include/reflow-controller/safety/safety-controller-config-default.h +++ /dev/null @@ -1,92 +0,0 @@ -/* Reflow Oven Controller -* -* Copyright (C) 2020 Mario Hüttel -* -* This file is part of the Reflow Oven Controller Project. -* -* The reflow oven controller is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. -* -* The Reflow Oven Control Firmware is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with the reflow oven controller project. -* If not, see . -*/ - -/** - * @defgroup safety-controller-config Safety Controller Setup - * @ingroup safety-controller - * @addtogroup safety-controller-config - * @{ - */ - -#ifndef __SAFETY_CONTROLLER_CONFIG_H__ -#define __SAFETY_CONTROLLER_CONFIG_H__ - -#include -#include - -typedef enum { - ERROR_FLAG_NO_ERR = 0x55, - ERROR_FLAG_ERR = 0xAA, -} error_flag_state; - -enum safety_flag { - ERR_FLAG_MEAS_ADC_OFF = 0, - ERR_FLAG_MEAS_ADC_OVERFLOW, - ERR_FLAG_MEAS_ADC_WATCHDOG, - ERR_FLAG_MEAS_ADC_UNSTABLE, - N_ERR_FLAG, -}; - -enum timing_monitor { - ERR_TIMING_PID = 0, - ERR_TIMING_MEAS_ADC, - N_ERR_TIMING -}; - -enum analog_value_monitor { - ERR_AMON_VREF = 0, - ERR_AMON_UC_TEMP, - N_ERR_AMON -}; - - -struct error_flag_config { - bool clear_by_sw; - bool persistent; -}; - -struct timing_mon_config { - bool clear_by_sw; - bool persistent; - uint64_t max_delta; - uint64_t min_delta; -}; - -struct analog_mon_config { - bool clear_by_sw; - bool persistent; - float min; - float max; -}; - -struct safety_controller_config { - uint32_t flag_cnt; - struct error_flag_config flag_configs[N_ERR_FLAG]; - uint32_t timing_mon_cnt; - struct timing_mon_config timing_configs[N_ERR_FLAG]; - uint32_t analog_mon_cnt; - struct analog_mon_config analog_configs[N_ERR_AMON]; -}; - -const struct safety_controller_config *safety_controller_default_config_get(); - -#endif /* __SAFETY_CONTROLLER_CONFIG_H__ */ - -/** @} */ diff --git a/stm-firmware/include/reflow-controller/safety/safety-controller.h b/stm-firmware/include/reflow-controller/safety/safety-controller.h index f0e7435..2f1ea12 100644 --- a/stm-firmware/include/reflow-controller/safety/safety-controller.h +++ b/stm-firmware/include/reflow-controller/safety/safety-controller.h @@ -27,8 +27,8 @@ #ifndef __SAFETY_CONTROLLER_H__ #define __SAFETY_CONTROLLER_H__ -#include - +#include +#include /** * @brief Initialize the safety controller @@ -46,8 +46,11 @@ void safety_controller_init(); */ int safety_controller_handle(); -int safety_controller_report_error(); +int safety_controller_report_error(enum safety_flag flag); +void safety_controller_report_timing(enum timing_monitor monitor); + +int safety_controller_enable_timing_mon(enum timing_monitor monitor, bool enable); #endif /* __SAFETY_CONTROLLER_H__ */ diff --git a/stm-firmware/safety/safety-controller-config-default.c b/stm-firmware/safety/safety-controller-config-default.c deleted file mode 100644 index 6bb6d92..0000000 --- a/stm-firmware/safety/safety-controller-config-default.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Reflow Oven Controller -* -* Copyright (C) 2020 Mario Hüttel -* -* This file is part of the Reflow Oven Controller Project. -* -* The reflow oven controller is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. -* -* The Reflow Oven Control Firmware is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with the reflow oven controller project. -* If not, see . -*/ - -/** - * @defgroup safety-controller-config Safety Controller Setup - * @ingroup safety-controller - * @addtogroup safety-controller-config - * @{ - */ - -#include - -static const struct safety_controller_config default_conf = { - .flag_cnt = N_ERR_FLAG, - .flag_configs = { - {.clear_by_sw = false, .persistent = false}, /* ERR_FLAG_MEAS_ADC_OFF */ - {.clear_by_sw = true, .persistent = true}, /* ERR_FLAG_MEAS_ADC_OVERFLOW */ - {.clear_by_sw = true, .persistent = true}, /* ERR_FLAG_MEAS_ADC_WATCHDOG */ - {.clear_by_sw = false, .persistent = false}, /* ERR_FLAG_MEAS_ADC_UNSTABLE */ - }, - .timing_mon_cnt = N_ERR_TIMING, - .timing_configs = { - {}, /* ERR_TIMING_PID */ - {}, /* ERR_TIMING_MEAS_ADC */ - } -}; - -const struct safety_controller_config *safety_controller_default_config_get() -{ - return &default_conf; -} - - -/** @} */ diff --git a/stm-firmware/safety/safety-controller.c b/stm-firmware/safety/safety-controller.c index 97113b9..ea7993f 100644 --- a/stm-firmware/safety/safety-controller.c +++ b/stm-firmware/safety/safety-controller.c @@ -25,8 +25,138 @@ #include #include +#include +#include +#include +#include +#include +struct error_flag { + const char *name; + enum safety_flag flag; + bool error_state; + bool persistent; +}; +struct timing_mon { + const char *name; + enum timing_monitor monitor; + uint64_t min_delta; + uint64_t max_delta; + uint64_t last; + bool enabled; +}; + +struct analog_mon { + const char *name; + enum analog_value_monitor monitor; + float min; + float max; + float value; + bool valid; +}; + +#ifdef COUNT_OF +#undef COUNT_OF +#endif + +#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) + +#define ERR_FLAG_ENTRY(errflag, persistency) {.name=#errflag, .flag = (errflag), .error_state = false, .persistent = (persistency)} +#define TIM_MON_ENTRY(mon, min, max) {.name=#mon, .monitor = (mon), .min_delta = (min), .max_delta = (max), .last = 0ULL, .enabled= false} +#define ANA_MON_ENTRY(mon, min_value, max_value) {.name=#mon, .monitor = (mon), .min = (min_value), .max = (max_value), .value = 0.0f, .valid = false} + +static struct error_flag flags[] = { + ERR_FLAG_ENTRY(ERR_FLAG_MEAS_ADC_OFF, false), + ERR_FLAG_ENTRY(ERR_FLAG_MEAS_ADC_WATCHDOG, false), + ERR_FLAG_ENTRY(ERR_FLAG_MEAS_ADC_UNSTABLE, false), + ERR_FLAG_ENTRY(ERR_FLAG_MEAS_ADC_OVERFLOW, true), + ERR_FLAG_ENTRY(ERR_FLAG_TIMING_MEAS_ADC, false), + ERR_FLAG_ENTRY(ERR_FLAG_TIMING_PID, false), + ERR_FLAG_ENTRY(ERR_FLAG_AMON_UC_TEMP, true), + ERR_FLAG_ENTRY(ERR_FLAG_AMON_VREF, false), + ERR_FLAG_ENTRY(ERR_FLAG_STACK, true), +}; + +static struct timing_mon timings[] = { + TIM_MON_ENTRY(ERR_TIMING_PID, 1, 800), + TIM_MON_ENTRY(ERR_TIMING_MEAS_ADC, 1, 50), + TIM_MON_ENTRY(ERR_TIMING_SAFETY_ADC, 220, 500), +}; + +static struct analog_mon analog_mons[] = { + ANA_MON_ENTRY(ERR_AMON_VREF, 2480.0f, 2520.0f), + ANA_MON_ENTRY(ERR_AMON_UC_TEMP, 0.0f, 55.0f), +}; + +int safety_controller_report_error(enum safety_flag flag) +{ + uint32_t i; + int ret = -1; + + for (i = 0; i < COUNT_OF(flags); i++) { + if (flags[i].flag & flag) { + flags[i].error_state = true; + ret = 0; + } + } + + return ret; +} /** @} */ + +void safety_controller_report_timing(enum timing_monitor monitor) +{ + uint32_t i; + struct timing_mon *tim; + uint64_t timestamp; + + timestamp = systick_get_global_tick(); + + for (i = 0; i < COUNT_OF(timings); i++) { + tim = &timings[i]; + if (tim->monitor & monitor) { + tim->enabled = true; + tim->last = timestamp; + } + } +} + +void safety_controller_init() +{ + watchdog_setup(WATCHDOG_PRESCALER); +} + +int safety_controller_handle() +{ + int ret = 0; + + /* TODO: Handle safety ADC */ + + /* TODO: Check flags for PID and HALT */ + + ret |= watchdog_ack(WATCHDOG_MAGIC_KEY); + + return (ret ? -1 : 0); +} + +int safety_controller_enable_timing_mon(enum timing_monitor monitor, bool enable) +{ + uint32_t i; + struct timing_mon *tim; + + if (enable) { + safety_controller_report_timing(monitor); + } else { + for (i = 0; i < COUNT_OF(timings); i++) { + tim = &timings[i]; + if (tim->monitor & monitor) { + tim->enabled = false; + } + } + } + + return 0; +}