| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				@@ -1,22 +1,22 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/* 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/>.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				*/
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * 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/>.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * @addtogroup safety-controller
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -215,8 +215,8 @@ static volatile struct error_flag IN_SECTION(.ccm.data) flags[] = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  * @brief All timing monitors
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * @brief All timing monitors
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static volatile struct timing_mon IN_SECTION(.ccm.data) timings[] = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					TIM_MON_ENTRY(ERR_TIMING_PID, 2, 5000, ERR_FLAG_TIMING_PID),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					TIM_MON_ENTRY(ERR_TIMING_MEAS_ADC, 0, 50, ERR_FLAG_TIMING_MEAS_ADC),
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -298,7 +298,7 @@ static const struct crc_monitor_register meas_adc_crc_regs[] = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							       ADC_SQR2_SQ12 | ADC_SQR2_SQ11 | ADC_SQR2_SQ10 | ADC_SQR2_SQ9 |
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							       ADC_SQR2_SQ8 | ADC_SQR2_SQ7, 4),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					CRC_MON_REGISTER_ENTRY(ADC_PT1000_PERIPH->SQR3, ADC_SQR3_SQ6 | ADC_SQR3_SQ5 | ADC_SQR3_SQ4 |
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							       ADC_SQR3_SQ3| ADC_SQR3_SQ2 | ADC_SQR3_SQ1, 4),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							       ADC_SQR3_SQ3 | ADC_SQR3_SQ2 | ADC_SQR3_SQ1, 4),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{NULL, 0, 0}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -314,12 +314,11 @@ static const struct crc_monitor_register safety_adc_crc_regs[] = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							       ADC_SQR2_SQ12 | ADC_SQR2_SQ11 | ADC_SQR2_SQ10 | ADC_SQR2_SQ9 |
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							       ADC_SQR2_SQ8 | ADC_SQR2_SQ7, 4),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					CRC_MON_REGISTER_ENTRY(SAFETY_ADC_ADC_PERIPHERAL->SQR3, ADC_SQR3_SQ6 | ADC_SQR3_SQ5 | ADC_SQR3_SQ4 |
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							       ADC_SQR3_SQ3| ADC_SQR3_SQ2 | ADC_SQR3_SQ1, 4),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							       ADC_SQR3_SQ3 | ADC_SQR3_SQ2 | ADC_SQR3_SQ1, 4),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{NULL, 0, 0}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static struct crc_mon IN_SECTION(.ccm.data) crc_monitors[] =
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static struct crc_mon IN_SECTION(.ccm.data) crc_monitors[] = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						.registers = meas_adc_crc_regs,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						.monitor = ERR_CRC_MON_MEAS_ADC,
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -360,7 +359,8 @@ static void set_overtemp_config(float over_temperature)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					safety_controller_overtemp_config.crc_dummy_seed = 0xA4F5C7E6UL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					safety_controller_overtemp_config.overtemp_deg_celsius = over_temperature;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					safety_controller_overtemp_config.overtemp_equiv_resistance = resistance;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_input_array((const uint32_t *)&safety_controller_overtemp_config, wordsize_of(struct overtemp_config) - 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_input_array((const uint32_t *)&safety_controller_overtemp_config,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							     wordsize_of(struct overtemp_config) - 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					safety_controller_overtemp_config.crc = crc_unit_get_crc();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -369,7 +369,8 @@ static bool over_temperature_config_check(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (safety_controller_overtemp_config.crc_dummy_seed != 0xA4F5C7E6UL)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_reset();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_input_array((const uint32_t *)&safety_controller_overtemp_config, wordsize_of(struct overtemp_config) - 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_input_array((const uint32_t *)&safety_controller_overtemp_config,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							     wordsize_of(struct overtemp_config) - 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (crc_unit_get_crc() != safety_controller_overtemp_config.crc)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -442,7 +443,7 @@ static int flag_weight_table_crc_check(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static int flag_persistence_table_crc_check(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_reset();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_input_array((uint32_t*)flag_persistencies, wordsize_of(flag_persistencies));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_input_array((uint32_t *)flag_persistencies, wordsize_of(flag_persistencies));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (crc_unit_get_crc() != flag_persistencies_crc)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return -1;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -519,9 +520,8 @@ static int safety_controller_check_crc_monitors(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (crc_monitor_calculate_crc(mon->registers, &crc))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return -1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (mon->expected_crc != crc || ~mon->expected_crc_inv != crc) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (mon->expected_crc != crc || ~mon->expected_crc_inv != crc)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							safety_controller_report_error(mon->flag_to_set);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						mon->last_crc = crc;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -548,7 +548,7 @@ static void init_safety_flag_weight_table_from_default(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_reset();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_input_array((uint32_t*)flag_weights, wordsize_of(flag_weights));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_input_array((uint32_t *)flag_weights, wordsize_of(flag_weights));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					flag_weight_crc = crc_unit_get_crc();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -608,16 +608,14 @@ static void apply_config_overrides(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case SAFETY_MEMORY_CONFIG_OVERRIDE_WEIGHT:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							flag_enum = flag_no_to_flag_enum(override.entry.weight_override.flag);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							flag = find_error_flag(flag_enum);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (flag && flag->weight) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (flag && flag->weight)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								flag->weight->weight = override.entry.weight_override.weight;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case SAFETY_MEMORY_CONFIG_OVERRIDE_PERSISTENCE:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							flag_enum = flag_no_to_flag_enum(override.entry.persistence_override.flag);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							flag = find_error_flag(flag_enum);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (flag && flag->persistence) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (flag && flag->persistence)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								flag->persistence->persistence = override.entry.persistence_override.persistence;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						default:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							continue;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -629,7 +627,7 @@ static void apply_config_overrides(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_input_array((uint32_t *)flag_persistencies, wordsize_of(flag_persistencies));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					flag_persistencies_crc = crc_unit_get_crc();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_reset();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_input_array((uint32_t*)flag_weights, wordsize_of(flag_weights));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					crc_unit_input_array((uint32_t *)flag_weights, wordsize_of(flag_weights));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					flag_weight_crc = crc_unit_get_crc();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -647,11 +645,10 @@ static bool error_flag_get_status(const volatile struct error_flag *flag)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (!flag)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (flag->error_state == flag->error_state_inv) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (flag->error_state == flag->error_state_inv)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					} else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return flag->error_state;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -693,7 +690,7 @@ static volatile struct timing_mon *find_timing_mon(enum timing_monitor mon)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * @brief Check the active timing monitors and set the appropriate flags in case of an error.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_process_active_timing_mons()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_process_active_timing_mons(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32_t i;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					volatile struct timing_mon *current_mon;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -716,7 +713,8 @@ static void safety_controller_process_active_timing_mons()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * Process the analog and timing monitors and set the relevant flags in case of a monitor outside its limits.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * Furthermore, the PT1000 resistance is checked for overtemperature
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * The checking of the analog monitors will only be armed after a startup delay of 1000 ms to allow the values to stabilize.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * The checking of the analog monitors will only be armed after a startup delay of 1000 ms to
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * allow the values to stabilize.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_process_monitor_checks(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -731,21 +729,18 @@ static void safety_controller_process_monitor_checks(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (startup_completed) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						analog_mon_count = safety_controller_get_analog_monitor_count();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (idx = 0; idx < analog_mon_count; idx++) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (idx = 0; idx < analog_mon_count; idx++)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (safety_controller_get_analog_mon_by_index(idx, &amon_info)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								panic_mode();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (amon_info.status != ANALOG_MONITOR_OK) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (amon_info.status != ANALOG_MONITOR_OK)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								safety_controller_report_error(amon_info.associated_flag);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					adc_pt1000_get_current_resistance(&pt1000_val);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pt1000_val > safety_controller_overtemp_config.overtemp_equiv_resistance) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pt1000_val > safety_controller_overtemp_config.overtemp_equiv_resistance)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						safety_controller_report_error(ERR_FLAG_OVERTEMP);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					(void)safety_controller_check_crc_monitors();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -779,7 +774,7 @@ static int report_error(enum safety_flag flag, uint32_t key, bool prevent_error_
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							flags[i].error_state_inv = !flags[i].error_state;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							flags[i].key = key;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if ((check_flag_persistent(&flags[i]) && !old_state && !prevent_error_mem_enty) || 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if ((check_flag_persistent(&flags[i]) && !old_state && !prevent_error_mem_enty) ||
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								get_flag_weight(&flags[i]) == SAFETY_FLAG_CONFIG_WEIGHT_PANIC) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								err_mem_entry.counter = 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								err_mem_entry.flag_num = flag_enum_to_flag_no(flags[i].flag);
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -820,9 +815,8 @@ void safety_controller_report_timing(enum timing_monitor monitor)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					tim = find_timing_mon(monitor);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (tim) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (tim->enabled) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (!systick_ticks_have_passed(tim->last, tim->min_delta) && tim->min_delta > 0U) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (!systick_ticks_have_passed(tim->last, tim->min_delta) && tim->min_delta > 0U)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								safety_controller_report_error(tim->associated_flag);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						tim->calculated_delta = timestamp - tim->last;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -870,9 +864,8 @@ static int get_safety_flags_from_error_mem(enum safety_flag *flags)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for (idx = 0; idx < count; idx++) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						res = safety_memory_get_error_entry(idx, &entry);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (entry.type == SAFETY_MEMORY_ERR_ENTRY_FLAG) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (entry.type == SAFETY_MEMORY_ERR_ENTRY_FLAG)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return_flags |= flag_no_to_flag_enum(entry.flag_num);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					*flags = return_flags;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -884,11 +877,12 @@ static int get_safety_flags_from_error_mem(enum safety_flag *flags)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * The external harware watchdog has to be periodically reset or it will reset hte controller.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * Because debugging is not possible, when the watchdog is active, it is only activated, if the application is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * compiled in release mode. Any interruption of the main programm will then trigger the internal and/or the external watchdog.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * compiled in release mode. Any interruption of the main programm will then trigger the internal and/or
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * the external watchdog.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * @note When enabled, execute the @ref external_watchdog_toggle function to reset the external watchdog.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_init_external_watchdog()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_init_external_watchdog(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(SAFETY_EXT_WATCHDOG_RCC_MASK));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					SAFETY_EXT_WATCHDOG_PORT->MODER &= MODER_DELETE(SAFETY_EXT_WATCHDOG_PIN);
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -899,7 +893,7 @@ static void safety_controller_init_external_watchdog()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					__DSB();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void safety_controller_init()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void safety_controller_init(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					enum safety_memory_state found_memory_state;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					enum safety_flag flags_in_err_mem = ERR_FLAG_NO_FLAG;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -967,7 +961,7 @@ void safety_controller_init()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * 1) Checking the remaining free space at the moment between stack pointer and top of heap.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * 2) Checking The CRC of the corruption detect area between heap and stack
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_check_stack()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_check_stack(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					int32_t free_stack;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -975,18 +969,17 @@ static void safety_controller_check_stack()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (free_stack < SAFETY_MIN_STACK_FREE)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						safety_controller_report_error(ERR_FLAG_STACK);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (stack_check_corruption_detect_area()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (stack_check_corruption_detect_area())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						safety_controller_report_error(ERR_FLAG_STACK);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * @brief Handle the Safety ADC
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * This function handles the safety ADC.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * If the safety ADC ius not executing a measurment and the time since the last measurement has
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * passed @ref SAFETY_CONTROLLER_ADC_DELAY_MS, the safety ADC is retriggered and will automatically perform a measurement
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * on all of its channels.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * If the safety ADC is not executing a measurment and the time since the last measurement has
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * passed @ref SAFETY_CONTROLLER_ADC_DELAY_MS, the safety ADC is retriggered and will automatically perform a
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * measurement on all of its channels.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * When called again, this function will retrieve the data from the safety ADC and  converts it into the
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * appropriate analog values for the analog value monitors.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 *
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -995,7 +988,7 @@ static void safety_controller_check_stack()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * The channels, the ssafety ADC will convert is defined in its header file using the define @ref SAFETY_ADC_CHANNELS.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_handle_safety_adc()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_handle_safety_adc(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					static uint64_t last_result_timestamp = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					const uint16_t *channels;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1066,9 +1059,8 @@ static void safety_controller_handle_memory_checks(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						/* Check the safety memory */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (safety_memory_check()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							(void)safety_memory_reinit(&found_state);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (found_state != SAFETY_MEMORY_INIT_VALID_MEMORY) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (found_state != SAFETY_MEMORY_INIT_VALID_MEMORY)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								safety_controller_report_error(ERR_FLAG_SAFETY_MEM_CORRUPT);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						/* If flag weight table is broken, reinit to default and set flag */
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1078,7 +1070,7 @@ static void safety_controller_handle_memory_checks(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						/* If persistence table is broken, reinit to default and set flag */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if(flag_persistence_table_crc_check()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (flag_persistence_table_crc_check()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							safety_controller_report_error(ERR_FLAG_SAFETY_TAB_CORRUPT);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							init_safety_flag_persistencies_from_default();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1097,7 +1089,7 @@ static void safety_controller_handle_memory_checks(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * If the systick stays constant for more than 1000 calls of this function,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * the @ref ERR_FLAG_SYSTICK flag is set.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_do_systick_checking()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_do_systick_checking(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					static uint64_t last_systick;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					static uint32_t same_systick_cnt = 0UL;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1122,7 +1114,7 @@ static void safety_controller_do_systick_checking()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * @note If no flag weigth is present for a given error flag, it is treated as the most critical category
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 * (@ref SAFETY_FLAG_CONFIG_WEIGHT_PANIC)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_handle_weighted_flags()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void safety_controller_handle_weighted_flags(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32_t flag_index;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					volatile struct error_flag *current_flag;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1132,9 +1124,8 @@ static void safety_controller_handle_weighted_flags()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						current_flag = &flags[flag_index];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						/* Continue if this flag is not set */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!error_flag_get_status(current_flag)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!error_flag_get_status(current_flag))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							continue;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						flag_weigth = get_flag_weight(current_flag);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						switch (flag_weigth) {
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1155,13 +1146,13 @@ static void safety_controller_handle_weighted_flags()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#ifndef DEBUGBUILD
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void external_watchdog_toggle()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void external_watchdog_toggle(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					SAFETY_EXT_WATCHDOG_PORT->ODR ^= (1<<SAFETY_EXT_WATCHDOG_PIN);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#endif
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				int safety_controller_handle()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				int safety_controller_handle(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					int ret = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#ifndef DEBUGBUILD
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1273,9 +1264,8 @@ int safety_controller_ack_flag_with_key(enum safety_flag flag, uint32_t key)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					int ret = -1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					volatile struct error_flag *found_flag;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (!is_power_of_two(flag)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (!is_power_of_two(flag))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return -1001;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					found_flag = find_error_flag(flag);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (found_flag) {
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1306,17 +1296,17 @@ bool safety_controller_get_flags_by_mask(enum safety_flag mask)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return ret;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32_t safety_controller_get_flag_count()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32_t safety_controller_get_flag_count(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return COUNT_OF(flags);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32_t safety_controller_get_analog_monitor_count()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32_t safety_controller_get_analog_monitor_count(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return COUNT_OF(analog_mons);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32_t safety_controller_get_timing_monitor_count()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint32_t safety_controller_get_timing_monitor_count(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return COUNT_OF(timings);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1423,9 +1413,8 @@ int safety_controller_get_timing_mon_by_index(uint32_t index, struct timing_moni
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (!info)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return -1002;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (index >= COUNT_OF(timings)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (index >= COUNT_OF(timings))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return -1001;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					mon = &timings[index];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1462,14 +1451,13 @@ extern const uint32_t __ld_sdata;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				extern const uint32_t __ld_edata;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				extern const uint32_t __ld_load_data;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				int safety_controller_trigger_flash_crc_check()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				int safety_controller_trigger_flash_crc_check(void)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					/* This structs needs to be volatile!!
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 * This prevents the compiler form optimizing out the reads to the crcs which will be patched in later by
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 * a separate python script!
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					static volatile const struct flash_crcs IN_SECTION(.flashcrc) crcs_in_flash =
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					static volatile const struct flash_crcs IN_SECTION(.flashcrc) crcs_in_flash = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						.start_magic = 0xA8BE53F9UL,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						.crc_section_ccm_data = 0UL,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						.crc_section_text = 0UL,
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1491,9 +1479,8 @@ int safety_controller_trigger_flash_crc_check()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						crc_unit_reset();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						crc_unit_input_array(&__ld_vectors_start, len);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						crc = crc_unit_get_crc();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (crc != crcs_in_flash.crc_section_vectors) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (crc != crcs_in_flash.crc_section_vectors)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							safety_controller_report_error(ERR_FLAG_FLASH_CRC_CODE);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					/* Perform CRC check over text section */
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1505,9 +1492,8 @@ int safety_controller_trigger_flash_crc_check()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						crc_unit_reset();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						crc_unit_input_array(&__ld_text_start, len);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						crc = crc_unit_get_crc();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (crc != crcs_in_flash.crc_section_text) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (crc != crcs_in_flash.crc_section_text)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							safety_controller_report_error(ERR_FLAG_FLASH_CRC_CODE);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					/* Perform CRC check over data section */
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1519,9 +1505,8 @@ int safety_controller_trigger_flash_crc_check()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						crc_unit_reset();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						crc_unit_input_array(&__ld_load_data, len);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						crc = crc_unit_get_crc();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (crc != crcs_in_flash.crc_section_data) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (crc != crcs_in_flash.crc_section_data)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							safety_controller_report_error(ERR_FLAG_FLASH_CRC_DATA);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					/* Perform CRC check over ccm data section */
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1533,9 +1518,8 @@ int safety_controller_trigger_flash_crc_check()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						crc_unit_reset();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						crc_unit_input_array(&__ld_load_ccm_data, len);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						crc = crc_unit_get_crc();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (crc != crcs_in_flash.crc_section_ccm_data) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (crc != crcs_in_flash.crc_section_ccm_data)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							safety_controller_report_error(ERR_FLAG_FLASH_CRC_DATA);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ret = 0;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				 
 |