Start safety implementation. Completely dumped old stuff
This commit is contained in:
		| @@ -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 += pid-controller.c oven-driver.c | ||||||
| CFILES += settings/settings.c settings/settings-sd-card.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 | DEBUG_DEFINES = -DDEBUGBUILD | ||||||
| RELEASE_DEFINES = | RELEASE_DEFINES = | ||||||
|   | |||||||
| @@ -21,6 +21,31 @@ | |||||||
| #ifndef __SAFETY_CONFIG_H__ | #ifndef __SAFETY_CONFIG_H__ | ||||||
| #define __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 |  * @brief Magic key used to reset the watchdog using the @ref watchdog_ack function | ||||||
|  */ |  */ | ||||||
| @@ -35,4 +60,12 @@ | |||||||
|  |  | ||||||
| #define WATCHDOG_PRESCALER 4 | #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__ */ | #endif /* __SAFETY_CONFIG_H__ */ | ||||||
|   | |||||||
| @@ -1,92 +0,0 @@ | |||||||
| /* Reflow Oven Controller |  | ||||||
| * |  | ||||||
| * Copyright (C) 2020  Mario Hüttel <mario.huettel@gmx.net> |  | ||||||
| * |  | ||||||
| * 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 <http://www.gnu.org/licenses/>. |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * @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 <stdint.h> |  | ||||||
| #include <stdbool.h> |  | ||||||
|  |  | ||||||
| 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__ */ |  | ||||||
|  |  | ||||||
| /** @} */ |  | ||||||
| @@ -27,8 +27,8 @@ | |||||||
| #ifndef __SAFETY_CONTROLLER_H__ | #ifndef __SAFETY_CONTROLLER_H__ | ||||||
| #define __SAFETY_CONTROLLER_H__ | #define __SAFETY_CONTROLLER_H__ | ||||||
|  |  | ||||||
| #include <reflow-controller/safety/safety-controller-config-default.h> | #include <reflow-controller/safety/safety-config.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @brief Initialize the safety controller |  * @brief Initialize the safety controller | ||||||
| @@ -46,8 +46,11 @@ void safety_controller_init(); | |||||||
|  */ |  */ | ||||||
| int safety_controller_handle(); | 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__ */ | #endif /* __SAFETY_CONTROLLER_H__ */ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,51 +0,0 @@ | |||||||
| /* Reflow Oven Controller |  | ||||||
| * |  | ||||||
| * Copyright (C) 2020  Mario Hüttel <mario.huettel@gmx.net> |  | ||||||
| * |  | ||||||
| * 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 <http://www.gnu.org/licenses/>. |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * @defgroup safety-controller-config Safety Controller Setup |  | ||||||
|  * @ingroup safety-controller |  | ||||||
|  * @addtogroup safety-controller-config |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include <reflow-controller/safety/safety-controller-config-default.h> |  | ||||||
|  |  | ||||||
| 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; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /** @} */ |  | ||||||
| @@ -25,8 +25,138 @@ | |||||||
|  |  | ||||||
| #include <reflow-controller/safety/safety-controller.h> | #include <reflow-controller/safety/safety-controller.h> | ||||||
| #include <reflow-controller/safety/safety-config.h> | #include <reflow-controller/safety/safety-config.h> | ||||||
|  | #include <reflow-controller/safety/watchdog.h> | ||||||
|  | #include <reflow-controller/systick.h> | ||||||
|  |  | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stddef.h> | ||||||
|  |  | ||||||
|  | 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; | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user