From 355e81ba44ab0a364aa30ba1b6e4681b766d3475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Sun, 24 May 2020 23:35:17 +0200 Subject: [PATCH 1/5] Add multitone support for loudspeaker --- stm-firmware/digio.c | 70 ++++++++++++++++--- .../include/reflow-controller/digio.h | 5 +- stm-firmware/main.c | 2 +- 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/stm-firmware/digio.c b/stm-firmware/digio.c index 7ec5b9e..4c8f86b 100644 --- a/stm-firmware/digio.c +++ b/stm-firmware/digio.c @@ -27,6 +27,7 @@ static const uint8_t digio_pins[] = {DIGIO_PINS}; static const uint8_t digio_default_io[] = {DIGIO_INOUT_DEFAULT}; static const uint8_t digio_default_altfunc[] = {DIGIO_ALTFUNC_DEFAULT}; +static uint16_t loudspeaker_val; static void digio_setup_pin_int(uint8_t bit_no, uint8_t in_out, uint8_t alt_func) { @@ -118,6 +119,19 @@ int led_get(uint8_t num) return ((LED_PORT->ODR & (1<APB1ENR, BITMASK_TO_BITNO(RCC_APB1ENR_TIM7EN)); + TIM7->CR1 = 0UL; + TIM7->CR2 = 0UL; + TIM7->PSC = 1000; + TIM7->DIER = TIM_DIER_UIE; + NVIC_EnableIRQ(TIM7_IRQn); +#endif +} + void loudspeaker_setup() { rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(LOUDSPEAKER_RCC_MASK)); @@ -125,16 +139,56 @@ void loudspeaker_setup() LOUDSPEAKER_PORT->MODER &= MODER_DELETE(LOUDSPEAKER_PIN); LOUDSPEAKER_PORT->MODER |= OUTPUT(LOUDSPEAKER_PIN); - loudspeaker_set(0); + loudspeaker_freq_timer_init(); + loudspeaker_set(0U); } -void loudspeaker_set(int val) + +static void loudspeaker_start_beep(uint16_t val) { - if (val) - LOUDSPEAKER_PORT->ODR |= (1<ODR &= ~(1<ARR = val; + TIM7->CNT = 0UL; + TIM7->CR1 |= TIM_CR1_CEN; +#else + (void)val; + LOUDSPEAKER_PORT->ODR |= (1<ODR & (1<CR1 &= ~TIM_CR1_CEN; + __DSB(); + TIM7->SR = 0UL; + __DSB(); + LOUDSPEAKER_PORT->ODR &= ~(1<ODR &= ~(1<SR = 0UL; + __DSB(); + LOUDSPEAKER_PORT->ODR ^= (1< Date: Mon, 25 May 2020 01:56:54 +0200 Subject: [PATCH 2/5] make PID controller mathemtaically correct --- .../reflow-controller/pid-controller.h | 6 +++- stm-firmware/main.c | 2 +- stm-firmware/pid-controller.c | 28 ++++++++++++------- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/stm-firmware/include/reflow-controller/pid-controller.h b/stm-firmware/include/reflow-controller/pid-controller.h index 1e64741..c2914cc 100644 --- a/stm-firmware/include/reflow-controller/pid-controller.h +++ b/stm-firmware/include/reflow-controller/pid-controller.h @@ -25,15 +25,19 @@ struct pid_controller { float k_deriv; float k_int; float k_p; + float k_int_t; + float k_deriv_t; float output_sat_max; float output_sat_min; float integral_max; + float sample_period; volatile float control_output; volatile float last_in; volatile float integral; + volatile float derivate; }; -void pid_init(struct pid_controller *pid, float k_deriv, float k_int, float k_p, float output_sat_min, float output_sat_max, float integral_max); +void pid_init(struct pid_controller *pid, float k_deriv, float k_int, float k_p, float output_sat_min, float output_sat_max, float integral_max, float sample_period); void pid_zero(struct pid_controller *pid); diff --git a/stm-firmware/main.c b/stm-firmware/main.c index 0ed1135..e56db8a 100644 --- a/stm-firmware/main.c +++ b/stm-firmware/main.c @@ -221,7 +221,7 @@ int main() shell_handle = shell_init(write_shell_callback); shell_print_motd(shell_handle); - pid_init(&pid, 0.1, 0.1, 4.0, 0.0, 100.0, 40.0); + pid_init(&pid, 0.1, 0.1, 4.0, 0.0, 100.0, 40.0, 0.25); pid_zero(&pid); while (1) { diff --git a/stm-firmware/pid-controller.c b/stm-firmware/pid-controller.c index ef97235..c73d591 100644 --- a/stm-firmware/pid-controller.c +++ b/stm-firmware/pid-controller.c @@ -20,18 +20,22 @@ #include -void pid_init(struct pid_controller *pid, float k_deriv, float k_int, float k_p, float output_sat_min, float output_sat_max, float integral_max) +void pid_init(struct pid_controller *pid, float k_deriv, float k_int, float k_p, float output_sat_min, float output_sat_max, float integral_max, float sample_period) { if (!pid) return; + pid->sample_period = sample_period; pid->k_p = k_p; pid->k_int = k_int; pid->k_deriv = k_deriv; + pid->k_int_t = pid->k_int * pid->sample_period / 2.0f; + pid->k_deriv_t = pid->k_deriv * 2.0f / pid->sample_period; pid->output_sat_max = output_sat_max; pid->output_sat_min = output_sat_min; - pid->control_output = 0; pid->integral_max = integral_max; + + pid_zero(pid); } void pid_zero(struct pid_controller *pid) @@ -43,12 +47,13 @@ void pid_zero(struct pid_controller *pid) static void calculate_integral(struct pid_controller *pid, float deviation) { - pid->integral += deviation * pid->k_int; + pid->integral = pid->integral + pid->k_int_t * (deviation + pid->last_in); + /* Saturate integral term to spoecified maximum */ if (pid->integral > pid->integral_max) { pid->integral = pid->integral_max; - } else if (pid->integral < -pid->integral_max) { - pid->integral = -pid->integral_max; + } else if (pid->integral < -pid->integral_max){ + pid->integral = - pid->integral_max; } } @@ -66,17 +71,20 @@ float pid_sample(struct pid_controller *pid, float deviation) calculate_integral(pid, deviation); } + /* Calculate derivative part */ + pid->derivate = pid->k_deriv_t * (deviation - pid->last_in) - pid->derivate; + + output += pid->derivate; output += pid->integral; - output -= (deviation - pid->last_in) * pid->k_deriv; - pid->last_in = deviation; - - if (output > pid->output_sat_max) - output = pid->output_sat_max; + /* Saturate output */ if (output < pid->output_sat_min) output = pid->output_sat_min; + else if (output > pid->output_sat_max) + output = pid->output_sat_max; pid->control_output = output; + pid->last_in = deviation; return output; } From 1751db31c582ef48ebb7119ce210029bd5ce3ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Mon, 1 Jun 2020 20:44:58 +0200 Subject: [PATCH 3/5] Fix typo --- stm-firmware/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stm-firmware/main.c b/stm-firmware/main.c index e56db8a..623558e 100644 --- a/stm-firmware/main.c +++ b/stm-firmware/main.c @@ -261,7 +261,7 @@ int main() /* Activate loundspeaker permanently */ loudspeaker_set(100); } else if (pid_controller_active) { - /* In case temperature measuremnt is okay and controlelr is working, write output power */ + /* In case temperature measurement is okay and controlelr is working, write output power */ oven_driver_set_power(pid_controller_output < 0 ? 0U : (uint8_t)pid_controller_output); } From f956968cb422879d38caa66e396eb96c98a3e0cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Mon, 1 Jun 2020 20:45:27 +0200 Subject: [PATCH 4/5] Make reading the global ms tick atomic in order to prevent glitches --- stm-firmware/include/reflow-controller/systick.h | 2 +- stm-firmware/systick.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/stm-firmware/include/reflow-controller/systick.h b/stm-firmware/include/reflow-controller/systick.h index 5060096..fa1568c 100644 --- a/stm-firmware/include/reflow-controller/systick.h +++ b/stm-firmware/include/reflow-controller/systick.h @@ -45,7 +45,7 @@ extern volatile uint32_t wait_tick_ms; * @brief Systemclock in milliseconds. * * This value must not be reset during the whole runtime. - * + * @warning In order to use this, you must assure that the read access is atomic. */ extern volatile uint64_t global_tick_ms; diff --git a/stm-firmware/systick.c b/stm-firmware/systick.c index b96c245..c998f6e 100644 --- a/stm-firmware/systick.c +++ b/stm-firmware/systick.c @@ -43,7 +43,13 @@ void systick_wait_ms(uint32_t ms) uint64_t systick_get_global_tick() { - return global_tick_ms; + uint64_t temp; + + __disable_irq(); + temp = global_tick_ms; + __enable_irq(); + + return temp; } bool __attribute__((optimize("O3"))) systick_ticks_have_passed(uint64_t start_timestamp, uint64_t ticks) From 5819a0736c72802b0c1cea01593e8aad68dd90c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Mon, 1 Jun 2020 20:53:28 +0200 Subject: [PATCH 5/5] Add defines for safety adc conversions --- .../reflow-controller/periph-config/safety-adc-hwcfg.h | 7 +++++++ stm-firmware/safety-adc.c | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/stm-firmware/include/reflow-controller/periph-config/safety-adc-hwcfg.h b/stm-firmware/include/reflow-controller/periph-config/safety-adc-hwcfg.h index bd9e6c7..26a23c8 100644 --- a/stm-firmware/include/reflow-controller/periph-config/safety-adc-hwcfg.h +++ b/stm-firmware/include/reflow-controller/periph-config/safety-adc-hwcfg.h @@ -28,4 +28,11 @@ #define TEMP_CHANNEL_NUM (16) #define INT_REF_CHANNEL_NUM (17) +#define SAFETY_ADC_INT_REF_MV 1210.0f + +#define SAFETY_ADC_TEMP_NOM 25.0f +#define SAFETY_ADC_TEMP_NOM_MV 760.0f +#define SAFETY_ADC_TEMP_MV_SLOPE 2.5f + + #endif /* __SAFETY_ADC_HWCFG_H__ */ diff --git a/stm-firmware/safety-adc.c b/stm-firmware/safety-adc.c index fb91b5f..945fc93 100644 --- a/stm-firmware/safety-adc.c +++ b/stm-firmware/safety-adc.c @@ -53,11 +53,12 @@ enum safety_adc_check_result safety_adc_check_results(uint16_t vref_result, uint if (vref_calculated) { - *vref_calculated = (1210.0 * 4095) / (float)vref_result; + *vref_calculated = (SAFETY_ADC_INT_REF_MV * 4095.0f) / (float)vref_result; } if (temp_calculated) { - *temp_calculated = (((float)temp_result / 4095.0f * 2500.0f - 760.0f) / 2.5f) + 25.0f; + *temp_calculated = (((float)temp_result / 4095.0f * 2500.0f - + SAFETY_ADC_TEMP_NOM_MV) / SAFETY_ADC_TEMP_MV_SLOPE) + SAFETY_ADC_TEMP_NOM; } return res;