Fix ADC measurement to run at 1000 Hz and fix wrong error handling for PT1000 Watchdog. Add function for flags to shell

This commit is contained in:
Mario Hüttel 2020-07-28 22:55:02 +02:00
parent 97fc04399e
commit b65d94b0e8
6 changed files with 122 additions and 17 deletions

View File

@ -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)); rcc_manager_enable_clock(&RCC->APB1ENR, BITMASK_TO_BITNO(RCC_APB1ENR_TIM2EN));
/* Divide 42 MHz peripheral clock by 42 */ /* Divide 2*42 MHz peripheral clock by 42 */
TIM2->PSC = (42UL-1UL); TIM2->PSC = (84UL-1UL);
/* Reload value */ /* Reload value */
TIM2->ARR = ADC_PT1000_SAMPLE_CNT_DELAY; TIM2->ARR = ADC_PT1000_SAMPLE_CNT_DELAY;
@ -73,7 +73,7 @@ static inline void adc_pt1000_disable_adc()
DMA2_Stream0->CR = 0; DMA2_Stream0->CR = 0;
safety_controller_report_error_with_key(ERR_FLAG_MEAS_ADC_OFF, MEAS_ADC_SAFETY_FLAG_KEY); 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->APB2ENR, BITMASK_TO_BITNO(RCC_APB2ENR_ADC3EN));
rcc_manager_disable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(ADC_PT1000_PORT_RCC_MASK)); 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); 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() 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) { if (adc1_sr & ADC_SR_AWD) {
ADC_PT1000_PERIPH->SR &= ~ADC_SR_AWD; ADC_PT1000_PERIPH->SR &= ~ADC_SR_AWD;
adc_watchdog_counter++; 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); safety_controller_report_error(ERR_FLAG_MEAS_ADC_WATCHDOG);
} }
} }

View File

@ -87,4 +87,6 @@ enum analog_value_monitor {
*/ */
#define MEAS_ADC_SAFETY_FLAG_KEY 0xe554dac3UL #define MEAS_ADC_SAFETY_FLAG_KEY 0xe554dac3UL
#define SAFETY_CONTROLLER_ADC_DELAY_MS 120
#endif /* __SAFETY_CONFIG_H__ */ #endif /* __SAFETY_CONFIG_H__ */

View File

@ -30,6 +30,7 @@
#include <reflow-controller/safety/safety-config.h> #include <reflow-controller/safety/safety-config.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h>
enum analog_monitor_status {ANALOG_MONITOR_OK = 0, enum analog_monitor_status {ANALOG_MONITOR_OK = 0,
ANALOG_MONITOR_ERROR, 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); 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__ */ #endif /* __SAFETY_CONTROLLER_H__ */
/** @} */ /** @} */

View File

@ -59,7 +59,7 @@ float safety_adc_convert_channel(enum safety_adc_meas_channel channel, uint16_t
switch (channel) { switch (channel) {
case SAFETY_ADC_MEAS_TEMP: 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; SAFETY_ADC_TEMP_MV_SLOPE) + SAFETY_ADC_TEMP_NOM;
break; break;
case SAFETY_ADC_MEAS_VREF: case SAFETY_ADC_MEAS_VREF:

View File

@ -31,6 +31,7 @@
#include <helper-macros/helper-macros.h> #include <helper-macros/helper-macros.h>
#include <reflow-controller/systick.h> #include <reflow-controller/systick.h>
#include <stddef.h> #include <stddef.h>
#include <string.h>
struct error_flag { struct error_flag {
const char *name; const char *name;
@ -87,9 +88,9 @@ static volatile struct error_flag flags[] = {
}; };
static volatile struct timing_mon timings[] = { static volatile struct timing_mon timings[] = {
TIM_MON_ENTRY(ERR_TIMING_PID, 1, 800, ERR_FLAG_TIMING_PID), TIM_MON_ENTRY(ERR_TIMING_PID, 2, 1000, ERR_FLAG_TIMING_PID),
TIM_MON_ENTRY(ERR_TIMING_MEAS_ADC, 1, 50, ERR_FLAG_TIMING_MEAS_ADC), TIM_MON_ENTRY(ERR_TIMING_MEAS_ADC, 0, 50, ERR_FLAG_TIMING_MEAS_ADC),
TIM_MON_ENTRY(ERR_TIMING_SAFETY_ADC, 1, 250, ERR_FLAG_SAFETY_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[] = { 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); tim = find_timing_mon(monitor);
if (tim) { if (tim) {
if (tim->enabled) { 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); 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 void safety_controller_handle_safety_adc()
{ {
static enum safety_adc_meas_channel current_channel = SAFETY_ADC_MEAS_TEMP; static enum safety_adc_meas_channel current_channel = SAFETY_ADC_MEAS_TEMP;
static uint64_t last_result_timestamp = 0;
int poll_result; int poll_result;
uint16_t result; uint16_t result;
float analog_value; float analog_value;
poll_result = safety_adc_poll_result(&result); 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) {
if (poll_result == -1) { if (poll_result == -1) {
switch (current_channel) { switch (current_channel) {
@ -278,9 +283,9 @@ static void safety_controller_handle_safety_adc()
current_channel = SAFETY_ADC_MEAS_TEMP; current_channel = SAFETY_ADC_MEAS_TEMP;
break; break;
} }
safety_adc_trigger_meas(current_channel); safety_adc_trigger_meas(current_channel);
} else if (poll_result == 1) { } else if (poll_result == 1) {
last_result_timestamp = systick_get_global_tick();
analog_value = safety_adc_convert_channel(current_channel, result); analog_value = safety_adc_convert_channel(current_channel, result);
safety_controller_report_timing(ERR_TIMING_SAFETY_ADC); safety_controller_report_timing(ERR_TIMING_SAFETY_ADC);
switch (current_channel) { switch (current_channel) {
@ -441,4 +446,42 @@ bool safety_controller_get_flags_by_mask(enum safety_flag mask)
return ret; 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;
}
/** @} */ /** @} */

View File

@ -35,7 +35,7 @@
#include <fatfs/ff.h> #include <fatfs/ff.h>
#include <reflow-controller/stack-check.h> #include <reflow-controller/stack-check.h>
#include <reflow-controller/rotary-encoder.h> #include <reflow-controller/rotary-encoder.h>
#include <reflow-controller/safety/safety-adc.h> #include <reflow-controller/safety/safety-controller.h>
#ifndef GIT_VER #ifndef GIT_VER
#define GIT_VER "VERSION NOT SET" #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); unique_id_get(&high_id, &mid_id, &low_id);
shellmatta_printf(handle, "Reflow Oven Controller Firmware " xstr(GIT_VER) "\r\n" shellmatta_printf(handle, "Reflow Oven Controller Firmware " xstr(GIT_VER) "\r\n"
"Compiled: " __DATE__ " at " __TIME__ "\r\n" "Compiled: " __DATE__ " at " __TIME__ "\r\n");
"Serial: %08X-%08X-%08X", high_id, mid_id, low_id); shellmatta_printf(handle, "Serial: %08X-%08X-%08X", high_id, mid_id, low_id);
return SHELLMATTA_OK; return SHELLMATTA_OK;
} }
@ -339,11 +339,55 @@ static shellmatta_retCode_t shell_cmd_safety_adc(const shellmatta_handle_t handl
{ {
(void)length; (void)length;
(void)arguments; (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); status_vref = safety_controller_get_analog_mon_value(ERR_AMON_VREF, &vref);
shellmatta_printf(handle, "TEMP:\t%8.2f\tdeg. Celsius\r\n", 25.0f); 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; return SHELLMATTA_OK;
} }
@ -461,8 +505,16 @@ static shellmatta_cmd_t cmd[14] = {
.helpText = "", .helpText = "",
.usageText = "", .usageText = "",
.cmdFct = shell_cmd_safety_adc, .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) shellmatta_handle_t shell_init(shellmatta_write_t write_func)