From b65d94b0e887b9bde2bc2f1bf4b4fde6e2429f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Tue, 28 Jul 2020 22:55:02 +0200 Subject: [PATCH] Fix ADC measurement to run at 1000 Hz and fix wrong error handling for PT1000 Watchdog. Add function for flags to shell --- stm-firmware/adc-meas.c | 9 +-- .../reflow-controller/safety/safety-config.h | 2 + .../safety/safety-controller.h | 7 ++ stm-firmware/safety/safety-adc.c | 2 +- stm-firmware/safety/safety-controller.c | 53 +++++++++++++-- stm-firmware/shell.c | 66 +++++++++++++++++-- 6 files changed, 122 insertions(+), 17 deletions(-) diff --git a/stm-firmware/adc-meas.c b/stm-firmware/adc-meas.c index 0ee5c06..a4c25ef 100644 --- a/stm-firmware/adc-meas.c +++ b/stm-firmware/adc-meas.c @@ -53,8 +53,8 @@ static inline void adc_pt1000_setup_sample_frequency_timer() { rcc_manager_enable_clock(&RCC->APB1ENR, BITMASK_TO_BITNO(RCC_APB1ENR_TIM2EN)); - /* Divide 42 MHz peripheral clock by 42 */ - TIM2->PSC = (42UL-1UL); + /* Divide 2*42 MHz peripheral clock by 42 */ + TIM2->PSC = (84UL-1UL); /* Reload value */ TIM2->ARR = ADC_PT1000_SAMPLE_CNT_DELAY; @@ -73,7 +73,7 @@ static inline void adc_pt1000_disable_adc() DMA2_Stream0->CR = 0; safety_controller_report_error_with_key(ERR_FLAG_MEAS_ADC_OFF, MEAS_ADC_SAFETY_FLAG_KEY); - + safety_controller_enable_timing_mon(ERR_TIMING_MEAS_ADC, false); rcc_manager_disable_clock(&RCC->APB2ENR, BITMASK_TO_BITNO(RCC_APB2ENR_ADC3EN)); rcc_manager_disable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(ADC_PT1000_PORT_RCC_MASK)); } @@ -296,6 +296,7 @@ static inline __attribute__((optimize("O3"))) void adc_pt1000_filter(float adc_p } pt1000_res_raw_lf = (1.0f-filter_alpha) * pt1000_res_raw_lf + filter_alpha * ADC_TO_RES(adc_prefiltered_value); + safety_controller_report_timing(ERR_TIMING_MEAS_ADC); } static inline __attribute__((optimize("O3"))) float adc_pt1000_dma_avg_pre_filter() @@ -340,7 +341,7 @@ void ADC_IRQHandler(void) if (adc1_sr & ADC_SR_AWD) { ADC_PT1000_PERIPH->SR &= ~ADC_SR_AWD; adc_watchdog_counter++; - if (adc_watchdog_counter >= ADC_PT1000_WATCHDOG_SAMPLE_COUNT && 0) + if (adc_watchdog_counter >= ADC_PT1000_WATCHDOG_SAMPLE_COUNT) safety_controller_report_error(ERR_FLAG_MEAS_ADC_WATCHDOG); } } diff --git a/stm-firmware/include/reflow-controller/safety/safety-config.h b/stm-firmware/include/reflow-controller/safety/safety-config.h index 74feb90..4d2e22b 100644 --- a/stm-firmware/include/reflow-controller/safety/safety-config.h +++ b/stm-firmware/include/reflow-controller/safety/safety-config.h @@ -87,4 +87,6 @@ enum analog_value_monitor { */ #define MEAS_ADC_SAFETY_FLAG_KEY 0xe554dac3UL +#define SAFETY_CONTROLLER_ADC_DELAY_MS 120 + #endif /* __SAFETY_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 cd462b6..9d886a7 100644 --- a/stm-firmware/include/reflow-controller/safety/safety-controller.h +++ b/stm-firmware/include/reflow-controller/safety/safety-controller.h @@ -30,6 +30,7 @@ #include #include #include +#include enum analog_monitor_status {ANALOG_MONITOR_OK = 0, ANALOG_MONITOR_ERROR, @@ -73,6 +74,12 @@ int safety_controller_ack_flag_with_key(enum safety_flag flag, uint32_t key); bool safety_controller_get_flags_by_mask(enum safety_flag mask); +uint32_t safety_controller_get_flag_count(); + +int safety_controller_get_flag_name_by_index(uint32_t index, char *buffer, size_t buffsize); + +int safety_controller_get_flag_by_index(uint32_t index, bool *status, enum safety_flag *flag_enum); + #endif /* __SAFETY_CONTROLLER_H__ */ /** @} */ diff --git a/stm-firmware/safety/safety-adc.c b/stm-firmware/safety/safety-adc.c index 152414e..53e2bff 100644 --- a/stm-firmware/safety/safety-adc.c +++ b/stm-firmware/safety/safety-adc.c @@ -59,7 +59,7 @@ float safety_adc_convert_channel(enum safety_adc_meas_channel channel, uint16_t switch (channel) { case SAFETY_ADC_MEAS_TEMP: - converted_val = (((float)channel / 4095.0f * 2500.0f - SAFETY_ADC_TEMP_NOM_MV) / + converted_val = (((float)analog_value / 4095.0f * 2500.0f - SAFETY_ADC_TEMP_NOM_MV) / SAFETY_ADC_TEMP_MV_SLOPE) + SAFETY_ADC_TEMP_NOM; break; case SAFETY_ADC_MEAS_VREF: diff --git a/stm-firmware/safety/safety-controller.c b/stm-firmware/safety/safety-controller.c index 46675d6..2a7ad95 100644 --- a/stm-firmware/safety/safety-controller.c +++ b/stm-firmware/safety/safety-controller.c @@ -31,6 +31,7 @@ #include #include #include +#include struct error_flag { const char *name; @@ -87,9 +88,9 @@ static volatile struct error_flag flags[] = { }; static volatile struct timing_mon timings[] = { - TIM_MON_ENTRY(ERR_TIMING_PID, 1, 800, ERR_FLAG_TIMING_PID), - TIM_MON_ENTRY(ERR_TIMING_MEAS_ADC, 1, 50, ERR_FLAG_TIMING_MEAS_ADC), - TIM_MON_ENTRY(ERR_TIMING_SAFETY_ADC, 1, 250, ERR_FLAG_SAFETY_ADC), + TIM_MON_ENTRY(ERR_TIMING_PID, 2, 1000, ERR_FLAG_TIMING_PID), + TIM_MON_ENTRY(ERR_TIMING_MEAS_ADC, 0, 50, ERR_FLAG_TIMING_MEAS_ADC), + TIM_MON_ENTRY(ERR_TIMING_SAFETY_ADC, 10, SAFETY_CONTROLLER_ADC_DELAY_MS + 70, ERR_FLAG_SAFETY_ADC), }; static volatile struct analog_mon analog_mons[] = { @@ -209,7 +210,7 @@ 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)) { + if (!systick_ticks_have_passed(tim->last, tim->min_delta) && tim->min_delta > 0U) { safety_controller_report_error(tim->associated_flag); } } @@ -261,11 +262,15 @@ static void safety_controller_check_stack() static void safety_controller_handle_safety_adc() { static enum safety_adc_meas_channel current_channel = SAFETY_ADC_MEAS_TEMP; + static uint64_t last_result_timestamp = 0; int poll_result; uint16_t result; float analog_value; poll_result = safety_adc_poll_result(&result); + if (!systick_ticks_have_passed(last_result_timestamp, SAFETY_CONTROLLER_ADC_DELAY_MS) && poll_result != 1) + return; + if (poll_result) { if (poll_result == -1) { switch (current_channel) { @@ -278,9 +283,9 @@ static void safety_controller_handle_safety_adc() current_channel = SAFETY_ADC_MEAS_TEMP; break; } - safety_adc_trigger_meas(current_channel); } else if (poll_result == 1) { + last_result_timestamp = systick_get_global_tick(); analog_value = safety_adc_convert_channel(current_channel, result); safety_controller_report_timing(ERR_TIMING_SAFETY_ADC); switch (current_channel) { @@ -441,4 +446,42 @@ bool safety_controller_get_flags_by_mask(enum safety_flag mask) return ret; } +uint32_t safety_controller_get_flag_count() +{ + return COUNT_OF(flags); +} + +int safety_controller_get_flag_name_by_index(uint32_t index, char *buffer, size_t buffsize) +{ + if (index >= COUNT_OF(flags)) + return -1; + + if (buffsize == 0 || !buffer) + return -1000; + + strncpy(buffer, flags[index].name, buffsize); + buffer[buffsize - 1] = 0; + + return 0; +} + +int safety_controller_get_flag_by_index(uint32_t index, bool *status, enum safety_flag *flag_enum) +{ + int ret = -1; + + if (!status && !flag_enum) + return -1000; + + if (index < COUNT_OF(flags)) { + if (status) + *status = flags[index].error_state; + if (flag_enum) + *flag_enum = flags[index].flag; + + ret = 0; + } + + return ret; +} + /** @} */ diff --git a/stm-firmware/shell.c b/stm-firmware/shell.c index fa4339d..b87c401 100644 --- a/stm-firmware/shell.c +++ b/stm-firmware/shell.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #ifndef GIT_VER #define GIT_VER "VERSION NOT SET" @@ -59,8 +59,8 @@ static shellmatta_retCode_t shell_cmd_ver(const shellmatta_handle_t handle, unique_id_get(&high_id, &mid_id, &low_id); shellmatta_printf(handle, "Reflow Oven Controller Firmware " xstr(GIT_VER) "\r\n" - "Compiled: " __DATE__ " at " __TIME__ "\r\n" - "Serial: %08X-%08X-%08X", high_id, mid_id, low_id); + "Compiled: " __DATE__ " at " __TIME__ "\r\n"); + shellmatta_printf(handle, "Serial: %08X-%08X-%08X", high_id, mid_id, low_id); return SHELLMATTA_OK; } @@ -339,11 +339,55 @@ static shellmatta_retCode_t shell_cmd_safety_adc(const shellmatta_handle_t handl { (void)length; (void)arguments; + enum analog_monitor_status status_vref, status_temp; + float vref, uc_temp; - shellmatta_printf(handle, "VREF:\t%8.2f\tmV\r\n", 2500.0f); - shellmatta_printf(handle, "TEMP:\t%8.2f\tdeg. Celsius\r\n", 25.0f); + status_vref = safety_controller_get_analog_mon_value(ERR_AMON_VREF, &vref); + status_temp = safety_controller_get_analog_mon_value(ERR_AMON_UC_TEMP, &uc_temp); - shellmatta_printf(handle, "Errors:\t%X", 0); + shellmatta_printf(handle, "VREF:\t%8.2f\tmV\r\n", vref); + shellmatta_printf(handle, "TEMP:\t%8.2f\tdeg. Celsius\r\n", uc_temp); + + if (status_temp != ANALOG_MONITOR_OK) { + shellmatta_printf(handle, "TEMP channel error!\r\n"); + } + if (status_vref != ANALOG_MONITOR_OK) { + shellmatta_printf(handle, "VREF channel error!\r\n"); + } + + return SHELLMATTA_OK; +} + +static shellmatta_retCode_t shell_cmd_read_flags(const shellmatta_handle_t handle, const char *arguments, + uint32_t length) +{ + (void)length; + (void)arguments; + uint32_t flag_count; + uint32_t i; + char name[64]; + bool flag; + int status; + + shellmatta_printf(handle, "Error flags\r\n" + "-----------\r\n"); + + flag_count = safety_controller_get_flag_count(); + for (i = 0; i < flag_count; i++) { + status = safety_controller_get_flag_name_by_index(i, name, sizeof(name)); + if (status) { + shellmatta_printf(handle, "Error getting flag name %lu\r\n", i); + continue; + } + + status = safety_controller_get_flag_by_index(i, &flag, NULL); + if (status) { + shellmatta_printf(handle, "Error getting flag value %lu\r\n", i); + continue; + } + + shellmatta_printf(handle, "%2lu) %-20s\t[%s]\r\n", i+1, name, (flag ? "ERR" : "OK")); + } return SHELLMATTA_OK; } @@ -461,8 +505,16 @@ static shellmatta_cmd_t cmd[14] = { .helpText = "", .usageText = "", .cmdFct = shell_cmd_safety_adc, - .next = NULL, + .next = &cmd[13], }, + { + .cmd = "safety-flags", + .cmdAlias = "flags", + .helpText = "", + .usageText = "", + .cmdFct = shell_cmd_read_flags, + .next = NULL, + } }; shellmatta_handle_t shell_init(shellmatta_write_t write_func)