/* Reflow Oven Controller * * Copyright (C) 2020 Mario Hüttel * * This file is part of the Reflow Oven Controller Project. * * The reflow oven controller is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * The Reflow Oven Control Firmware is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the reflow oven controller project. * If not, see . */ #include #include #include #include #include #include #include static void get_controller_folder_path(char *path, size_t size) { uint32_t high; uint32_t mid; uint32_t low; if (!path) return; unique_id_get(&high, &mid, &low); snprintf(path, size, "/%08X-%08X-%08X", (unsigned int)high, (unsigned int)mid, (unsigned int)low); } static void get_controller_settings_path(char *path, size_t size, const char *setting) { char folder[48]; get_controller_folder_path(folder, sizeof(folder)); snprintf(path, size, "%s/%s.dat", folder, setting); } /** * @brief Open or create the controller folder on the SD Card. * @param[in,out] controller_folder * @return 0 if opened, 1 if created and opened, -1 if error. */ static int create_controller_folder(void) { char foldername[48]; int ret = -1; FRESULT filesystem_result; FILINFO fno; get_controller_folder_path(foldername, sizeof(foldername)); /* Check if folder is present */ filesystem_result = f_stat(foldername, &fno); if (filesystem_result == FR_OK && fno.fattrib & AM_DIR) { ret = 0; } else { filesystem_result = f_mkdir(foldername); if (filesystem_result == FR_OK) { ret = 1; } else { ret = -1; } } return ret; } static int read_settings_file_float(const char *path, float *value) { FRESULT res; FIL file; int ret = 0; char buff[32]; UINT read_count; if (!value) return -1002; res = f_open(&file, path, FA_READ); if (res == FR_OK) { memset(buff, 0, sizeof(buff)); res = f_read(&file, buff, sizeof(buff)-1, &read_count); if (res != FR_OK) { ret = -1; goto close_file; } *value = strtof(buff, NULL); close_file: f_close(&file); } else { ret = -2; } return ret; } int sd_card_settings_save_calibration(float sens_deviation, float offset, bool active) { int status; char path[128]; char buff[64]; UINT bw; FIL file; FRESULT res; int ret = 0; status = create_controller_folder(); if (status < 0) return -2; get_controller_settings_path(path, sizeof(path), "offset"); if (active) { res = f_open(&file, path, FA_CREATE_ALWAYS | FA_WRITE); if (res != FR_OK) { ret = -2; goto exit_offset; } status = snprintf(buff, sizeof(buff), "%f\n", offset); f_write(&file, buff, status, &bw); f_close(&file); } else { f_unlink(path); } exit_offset: get_controller_settings_path(path, sizeof(path), "sens"); if (active) { res = f_open(&file, path, FA_CREATE_ALWAYS | FA_WRITE); if (res != FR_OK) { ret = -2; goto exit_sens; } status = snprintf(buff, sizeof(buff), "%f\n", sens_deviation); f_write(&file, buff, status, &bw); f_close(&file); } else { f_unlink(path); } exit_sens: return ret; } int sd_card_settings_try_load_calibration(float *sens_deviation, float *offset) { char path[128]; int status; int ret = 0; if (!sens_deviation || !offset) return -1000; get_controller_settings_path(path, sizeof(path), "offset"); status = read_settings_file_float(path, offset); if (status) { ret = status; goto exit; } get_controller_settings_path(path, sizeof(path), "sens"); status = read_settings_file_float(path, sens_deviation); if (status) { ret = status; goto exit; } exit: return ret; }