Commit fe3d08df authored by Raptor Engineering Development Team's avatar Raptor Engineering Development Team
Browse files

Add basic temperature sensor calibration support

parent 22718e6f
No related merge requests found
Pipeline #862 passed with stage
in 6 minutes and 54 seconds
......@@ -14,6 +14,7 @@ LOG_MODULE_REGISTER(sensors, LOG_LEVEL_INF);
#include <zephyr/drivers/w1.h>
#include "configuration.h"
#include "flash_filesystem.h"
#include "onewire_functions.h"
#include "sensors.h"
......@@ -66,6 +67,75 @@ void zephyr_onewire_search_callback(struct w1_rom rom, void *user_data)
}
}
void apply_temperature_calibration_for_thermal_sensor(struct kestrel_thermal_sensor_data_temp_t * sensor_data)
{
if (sensor_data->temperature_calibration_point_count > 0)
{
// TODO
// Implement more advanced calibration algorithm
// For now, just use the first calibration point pair to determine a fixed offset and apply that
double offset = sensor_data->temperature_calibration_points[0].sensor_reading - sensor_data->temperature_calibration_points[0].observed_value;
sensor_data->temperature_c = sensor_data->temperature_c - offset;
}
}
void load_temperature_calibration_data_for_thermal_sensor(struct kestrel_thermal_sensor_data_temp_t * sensor_data)
{
char * pos1;
char * pos2;
size_t file_len;
size_t len;
// Load any calibration data from the configuration ROM, if present
char temperature_calibration_filename_string[MAX_PATH_LEN];
snprintf(temperature_calibration_filename_string, sizeof(temperature_calibration_filename_string)-1, "temperature-sensor-calibration-data/%x", sensor_data->sensor_id);
temperature_calibration_filename_string[sizeof(temperature_calibration_filename_string)-1] = 0x0;
char * temperature_calibration_file_contents = read_vpd_file_contents(temperature_calibration_filename_string);
if (temperature_calibration_file_contents) {
LOG_INF("Found calibration data for sensor ID 0x%08x, loading...", sensor_data->sensor_id);
}
char temperature_calibration_point_string[64];
file_len = strlen(temperature_calibration_file_contents);
pos1 = temperature_calibration_file_contents;
while ((pos1 - temperature_calibration_file_contents) < file_len) {
pos2 = strstr(pos1, ":");
if (pos2) {
len = pos2 - pos1;
if (len > (sizeof(temperature_calibration_point_string) - 1)) {
len = sizeof(temperature_calibration_point_string) - 1;
}
memcpy(temperature_calibration_point_string, pos1, len);
temperature_calibration_point_string[len] = 0x0;
sensor_data->temperature_calibration_points[sensor_data->temperature_calibration_point_count].sensor_reading = strtoull(temperature_calibration_point_string, NULL, 10) / 100.0;
}
else {
break;
}
pos1 = pos2 + 1;
pos2 = strstr(pos1, "\n");
if (pos2) {
len = pos2 - pos1;
if (len > (sizeof(temperature_calibration_point_string) - 1)) {
len = sizeof(temperature_calibration_point_string) - 1;
}
memcpy(temperature_calibration_point_string, pos1, len);
temperature_calibration_point_string[len] = 0x0;
sensor_data->temperature_calibration_points[sensor_data->temperature_calibration_point_count].observed_value = strtoull(temperature_calibration_point_string, NULL, 10) / 100.0;
}
else {
break;
}
pos1 = pos2 + 1;
sensor_data->temperature_calibration_point_count++;
}
LOG_INF("Loaded %d calibration points for sensor ID 0x%08x", sensor_data->temperature_calibration_point_count, sensor_data->sensor_id);
free(temperature_calibration_file_contents);
}
void scan_onewire_devices(void)
{
onewire_device_list_t detected_onewire_devices = {0};
......@@ -120,6 +190,7 @@ void scan_onewire_devices(void)
kestrel_temp_sensor_data[kestrel_temp_sensor_count].fru_type = FRU_TYPE_THERMAL_ONEWIRE;
kestrel_temp_sensor_data[kestrel_temp_sensor_count].device_handle = detected_onewire_devices.devices[i];
kestrel_temp_sensor_data[kestrel_temp_sensor_count].description[0] = 0x0;
kestrel_temp_sensor_data[kestrel_temp_sensor_count].temperature_calibration_point_count = 0;
// Try to locate this device by handle in the configuration ROM, and assign the correct sensor ID if present
char device_handle_string[64];
......@@ -154,8 +225,12 @@ void scan_onewire_devices(void)
LOG_INF("Found new temperature sensor with serial number 0x%016llx, enabling as ID 0x%08x",
kestrel_temp_sensor_data[kestrel_temp_sensor_count].device_handle,
kestrel_temp_sensor_data[kestrel_temp_sensor_count].sensor_id);
// Load any calibration data from the configuration ROM, if present
load_temperature_calibration_data_for_thermal_sensor(&kestrel_temp_sensor_data[kestrel_temp_sensor_count]);
kestrel_temp_sensor_count++;
}
free(onewire_vpd_map_file_contents);
}
\ No newline at end of file
}
......@@ -28,6 +28,13 @@
#define MAX_THERMAL_SENSORS 255
#define MAX_SENSOR_DESC_LEN 256
#define MAX_SENSOR_CALIBRATION_POINTS 32
typedef struct kestrel_thermal_sensor_calibration_point {
double sensor_reading;
double observed_value;
} kestrel_thermal_sensor_calibration_point_t;
struct kestrel_thermal_sensor_data_temp_t {
uint32_t sensor_id;
uint8_t fru_type;
......@@ -35,6 +42,8 @@ struct kestrel_thermal_sensor_data_temp_t {
double temperature_c;
char description[MAX_SENSOR_DESC_LEN];
bool valid;
kestrel_thermal_sensor_calibration_point_t temperature_calibration_points[MAX_SENSOR_CALIBRATION_POINTS];
int temperature_calibration_point_count;
};
extern struct kestrel_thermal_sensor_data_temp_t kestrel_temp_sensor_data[MAX_THERMAL_SENSORS];
extern int kestrel_temp_sensor_count;
......@@ -54,6 +63,8 @@ extern int kestrel_temp_sensor_count;
void kestrel_sort_temperature_sensors(void);
void apply_temperature_calibration_for_thermal_sensor(struct kestrel_thermal_sensor_data_temp_t * sensor_data);
void load_calibration_data_for_thermal_sensor(struct kestrel_thermal_sensor_data_temp_t * sensor_data);
void scan_onewire_devices(void);
#endif // _SENSORS_H
\ No newline at end of file
#endif // _SENSORS_H
......@@ -172,6 +172,7 @@ static void thermal_service_thread(void)
}
else {
kestrel_temp_sensor_data[i].temperature_c = temperature;
apply_temperature_calibration_for_thermal_sensor(&kestrel_temp_sensor_data[i]);
kestrel_temp_sensor_data[i].valid = 1;
}
}
......
......@@ -17,5 +17,14 @@ with fs.open('vpd/onewire-fru-map', 'w') as file:
file.write('5102129245334128:100:\n')
file.write('8671bbd443f1e628:101:\n')
fs.mkdir("vpd/temperature-sensor-calibration-data")
# Calibration data is stored as an integer pair, scaled by 100, due
# to current limitations of Zephyr's string decode functionality
with fs.open('vpd/temperature-sensor-calibration-data/100', 'w') as file:
file.write('2180:2000\n')
file.write('3410:3000\n')
with open('config.bin', 'wb') as file:
file.write(fs.context.buffer)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment