Move all configuration variables to the EEPROM

This commit is contained in:
Thomas Kolb 2023-09-30 21:08:54 +02:00
parent 2819ee99d6
commit fd1b4990e2
6 changed files with 186 additions and 18 deletions

View File

@ -0,0 +1,35 @@
# Values for the cooler of the FT-817 radio.
flags:
USE_DCDC_CONTROL: true
config:
# temperature corridor definition
CORRIDOR_MIN_TEMPERATURE: 40.0
CORRIDOR_MAX_TEMPERATURE: 45.0
# The fan is started when temperature rises above this temperature.
FAN_START_TEMPERATURE: 42.0
# The fan is stopped when the temperature falls below this point.
FAN_OFF_TEMPERATURE: 30.0
# Emergency temperature level. If this is reached, the duty cycle is directly
# set to the maximum to skip a long ramp-up phase.
EMERGENCY_TEMPERATURE: 60.0
# The fan PWM duty cycle cannot fall below this limit. It is held until
# temperature falls below the off-temperature.
DUTY_CYCLE_MIN: 30.0
# The fan PWM duty cycle cannot go above this limit. Should be set to 100.
DUTY_CYCLE_MAX: 100.0
# The fan is always started with this duty cycle. Do not set too low.
DUTY_CYCLE_START: 70.0
# gain unit: percent duty cycle change per °C deviation per update cycle (100 ms)
GAIN_T_HIGH_P: 2.000
GAIN_T_HIGH_I: 0.125
GAIN_T_LOW_P: 0.000
GAIN_T_LOW_I: 0.125

60
eeprom_config/config_to_hex.py Executable file
View File

@ -0,0 +1,60 @@
#!/usr/bin/env python3
import sys
import struct
import yaml
from intelhex import IntelHex
def as_fxp(v):
return int(v * 2**16 + 0.5)
BASE_ADDR = 0x08080000
FLAG_NAME_TO_BIT_INDEX = {
'USE_DCDC_CONTROL': 0
}
CONFIG_KEY_TO_OFFSET = {
# note: flags are at 0x0000, but not listed here due to special handling.
'CORRIDOR_MIN_TEMPERATURE': 0x0004,
'CORRIDOR_MAX_TEMPERATURE': 0x0008,
'FAN_START_TEMPERATURE': 0x000C,
'FAN_OFF_TEMPERATURE': 0x0010,
'EMERGENCY_TEMPERATURE': 0x0014,
'DUTY_CYCLE_MIN': 0x0018,
'DUTY_CYCLE_MAX': 0x001C,
'DUTY_CYCLE_START': 0x0020,
'GAIN_T_HIGH_P': 0x0024,
'GAIN_T_HIGH_I': 0x0028,
'GAIN_T_LOW_P': 0x002C,
'GAIN_T_LOW_I': 0x0030,
}
if __name__ == "__main__":
output = IntelHex()
if len(sys.argv) < 3:
print(f"usage: {sys.argv[0]} <yaml-config> <output-hex>")
sys.exit(1)
with open(sys.argv[1], 'r') as configfile:
config = yaml.safe_load(configfile)
flags = 0
for key, bitidx in FLAG_NAME_TO_BIT_INDEX.items():
if config['flags'][key]:
flags |= (1 << bitidx)
enc_bytes = struct.pack('<I', flags)
output.puts(BASE_ADDR + 0x0000, enc_bytes)
for key, offset in CONFIG_KEY_TO_OFFSET.items():
value = as_fxp(config['config'][key])
enc_bytes = struct.pack('<i', value)
output.puts(BASE_ADDR + offset, enc_bytes)
output.write_hex_file(sys.argv[2])

View File

@ -0,0 +1,18 @@
#!/bin/sh
set -euo pipefail
HEXFILE="$1"
if [ ! -f "$HEXFILE" ]; then
echo "$HEXFILE cannot be accessed."
exit 1
fi
JLinkExe -device STM32L010K8 -speed 1000 -if SWD <<EOF
connect
loadfile $HEXFILE
r
g
exit
EOF

42
src/eeprom_config.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef EEPROM_CONFIG_H
#define EEPROM_CONFIG_H
#define EEPROM_BASE_ADDR ((uint8_t*)0x08080000)
// boolean flags. Each bit represents one flag.
#define EEPROM_CONFIG_FLAGS (*(uint32_t*)(EEPROM_BASE_ADDR + 0x0000))
// flag definitions
#define EEPROM_CONFIG_FLAG_USE_DCDC_CONTROL (1 << 0)
// corridor definition
#define EEPROM_CONFIG_CORRIDOR_MIN_TEMPERATURE (*(fxp_t*)(EEPROM_BASE_ADDR + 0x0004))
#define EEPROM_CONFIG_CORRIDOR_MAX_TEMPERATURE (*(fxp_t*)(EEPROM_BASE_ADDR + 0x0008))
// The fan is started when temperature rises above this temperature.
#define EEPROM_CONFIG_FAN_START_TEMPERATURE (*(fxp_t*)(EEPROM_BASE_ADDR + 0x000C))
// The fan is stopped when the temperature falls below this point.
#define EEPROM_CONFIG_FAN_OFF_TEMPERATURE (*(fxp_t*)(EEPROM_BASE_ADDR + 0x0010))
// Emergency temperature level. If this is reached, the duty cycle is directly
// set to the maximum to skip a long ramp-up phase.
#define EEPROM_CONFIG_EMERGENCY_TEMPERATURE (*(fxp_t*)(EEPROM_BASE_ADDR + 0x0014))
// The fan PWM duty cycle cannot fall below this limit. It is held until
// temperature falls below the off-temperature.
#define EEPROM_CONFIG_DUTY_CYCLE_MIN (*(fxp_t*)(EEPROM_BASE_ADDR + 0x0018))
// The fan PWM duty cycle cannot go above this limit. Should be set to 100.
#define EEPROM_CONFIG_DUTY_CYCLE_MAX (*(fxp_t*)(EEPROM_BASE_ADDR + 0x001C))
// The fan is always started with this duty cycle. Do not set too low.
#define EEPROM_CONFIG_DUTY_CYCLE_START (*(fxp_t*)(EEPROM_BASE_ADDR + 0x0020))
// gain unit: percent duty cycle change per °C deviation per update cycle
#define EEPROM_CONFIG_GAIN_T_HIGH_P (*(fxp_t*)(EEPROM_BASE_ADDR + 0x0024))
#define EEPROM_CONFIG_GAIN_T_HIGH_I (*(fxp_t*)(EEPROM_BASE_ADDR + 0x0028))
#define EEPROM_CONFIG_GAIN_T_LOW_P (*(fxp_t*)(EEPROM_BASE_ADDR + 0x002C))
#define EEPROM_CONFIG_GAIN_T_LOW_I (*(fxp_t*)(EEPROM_BASE_ADDR + 0x0030))
#endif // EEPROM_CONFIG_H

View File

@ -1,5 +1,7 @@
#include "fan_controller.h"
#include "eeprom_config.h"
/*
* The control loop is based on a temperature corridor concept. While the
* temperature is inside the corridor, the PWM duty cycle will not be changed.
@ -26,35 +28,34 @@
*/
// corridor definition
#define CORRIDOR_MIN_TEMPERATURE (40 << POINTPOS)
#define CORRIDOR_MAX_TEMPERATURE (45 << POINTPOS)
#define CORRIDOR_MIN_TEMPERATURE EEPROM_CONFIG_CORRIDOR_MIN_TEMPERATURE
#define CORRIDOR_MAX_TEMPERATURE EEPROM_CONFIG_CORRIDOR_MAX_TEMPERATURE
// The fan is started when temperature rises above this temperature.
#define FAN_START_TEMPERATURE (42 << POINTPOS)
#define FAN_START_TEMPERATURE EEPROM_CONFIG_FAN_START_TEMPERATURE
// The fan is stopped when the temperature falls below this point.
#define FAN_OFF_TEMPERATURE (30 << POINTPOS)
#define FAN_OFF_TEMPERATURE EEPROM_CONFIG_FAN_OFF_TEMPERATURE
// Emergency temperature level. If this is reached, the duty cycle is directly
// set to the maximum to skip a long ramp-up phase.
#define EMERGENCY_TEMPERATURE (60 << POINTPOS)
#define EMERGENCY_TEMPERATURE EEPROM_CONFIG_EMERGENCY_TEMPERATURE
// The fan PWM duty cycle cannot fall below this limit. It is held until
// temperature falls below the off-temperature.
#define DUTY_CYCLE_MIN (5 << POINTPOS)
#define DUTY_CYCLE_MIN EEPROM_CONFIG_DUTY_CYCLE_MIN
// The fan PWM duty cycle cannot go above this limit. Should be set to 100.
#define DUTY_CYCLE_MAX (100 << POINTPOS)
#define DUTY_CYCLE_MAX EEPROM_CONFIG_DUTY_CYCLE_MAX
// The fan is always started with this duty cycle. Do not set too low.
#define DUTY_CYCLE_START (20 << POINTPOS)
#define DUTY_CYCLE_START EEPROM_CONFIG_DUTY_CYCLE_START
// gain unit: percent duty cycle change per °C deviation per update cycle
#define GAIN_T_HIGH_P 0x00020000 // 2.000
#define GAIN_T_HIGH_I 0x00002000 // 0.125
#define GAIN_T_LOW_P 0x00000000 // 0.000
#define GAIN_T_LOW_I 0x00002000 // 0.125
// integer unit ^
#define GAIN_T_HIGH_P EEPROM_CONFIG_GAIN_T_HIGH_P
#define GAIN_T_HIGH_I EEPROM_CONFIG_GAIN_T_HIGH_I
#define GAIN_T_LOW_P EEPROM_CONFIG_GAIN_T_LOW_P
#define GAIN_T_LOW_I EEPROM_CONFIG_GAIN_T_LOW_I
static fxp_t m_duty;

View File

@ -7,6 +7,7 @@
#include "fan_ctrl_pwm.h"
#include "fan_ctrl_dc.h"
#include "fan_controller.h"
#include "eeprom_config.h"
#define SYSTICK_FREQ 10 // Hz
@ -58,9 +59,8 @@ int main(void)
uart_enqueue("TinyFanControl v" VERSION " initialized.\n");
fan_ctrl_pwm_enable(); // TODO: make DC/PWM configurable
uint8_t last_duty = 0;
bool use_dcdc = EEPROM_CONFIG_FLAGS & EEPROM_CONFIG_FLAG_USE_DCDC_CONTROL;
while (1) {
if(systick_triggered) {
@ -81,13 +81,25 @@ int main(void)
// handle fan power-on and power-off
if(last_duty == 0 && duty != 0) {
fan_ctrl_pwm_enable();
if(use_dcdc) {
fan_ctrl_dc_enable();
} else {
fan_ctrl_pwm_enable();
}
} else if(last_duty != 0 && duty == 0) {
fan_ctrl_pwm_disable();
if(use_dcdc) {
fan_ctrl_dc_disable();
} else {
fan_ctrl_pwm_disable();
}
}
// set the updated duty cycle
fan_ctrl_pwm_set_duty(duty);
if(use_dcdc) {
fan_ctrl_dc_set_duty(duty);
} else {
fan_ctrl_pwm_set_duty(duty);
}
last_duty = duty;
}