Fix 2.2.2RC1 no gvar compile (#5961)
[opentx.git] / radio / src / storage / sdcard_raw.cpp
blob877f9ee7cb9c1959aae5eeb556eca6f6a56c54bb
1 /*
2 * Copyright (C) OpenTX
4 * Based on code named
5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #include "opentx.h"
22 #include "modelslist.h"
24 void getModelPath(char * path, const char * filename)
26 strcpy(path, STR_MODELS_PATH);
27 path[sizeof(MODELS_PATH)-1] = '/';
28 strcpy(&path[sizeof(MODELS_PATH)], filename);
31 const char * writeFile(const char * filename, const uint8_t * data, uint16_t size)
33 TRACE("writeFile(%s)", filename);
35 FIL file;
36 unsigned char buf[8];
37 UINT written;
39 FRESULT result = f_open(&file, filename, FA_CREATE_ALWAYS | FA_WRITE);
40 if (result != FR_OK) {
41 return SDCARD_ERROR(result);
44 *(uint32_t*)&buf[0] = OTX_FOURCC;
45 buf[4] = EEPROM_VER;
46 buf[5] = 'M';
47 *(uint16_t*)&buf[6] = size;
49 result = f_write(&file, buf, 8, &written);
50 if (result != FR_OK || written != 8) {
51 f_close(&file);
52 return SDCARD_ERROR(result);
55 result = f_write(&file, data, size, &written);
56 if (result != FR_OK || written != size) {
57 f_close(&file);
58 return SDCARD_ERROR(result);
61 f_close(&file);
62 return NULL;
65 const char * writeModel()
67 char path[256];
68 getModelPath(path, g_eeGeneral.currModelFilename);
69 return writeFile(path, (uint8_t *)&g_model, sizeof(g_model));
72 const char * openFile(const char * fullpath, FIL* file, uint16_t* size)
74 FRESULT result = f_open(file, fullpath, FA_OPEN_EXISTING | FA_READ);
75 if (result != FR_OK) {
76 return SDCARD_ERROR(result);
79 if (f_size(file) < 8) {
80 f_close(file);
81 return STR_INCOMPATIBLE;
84 UINT read;
85 char buf[8];
87 result = f_read(file, (uint8_t *)buf, sizeof(buf), &read);
88 if ((result != FR_OK) || (read != sizeof(buf))) {
89 f_close(file);
90 return SDCARD_ERROR(result);
93 uint8_t version = (uint8_t)buf[4];
94 if ((*(uint32_t*)&buf[0] != OTX_FOURCC && *(uint32_t*)&buf[0] != O9X_FOURCC) || version < FIRST_CONV_EEPROM_VER || version > EEPROM_VER || buf[5] != 'M') {
95 f_close(file);
96 return STR_INCOMPATIBLE;
99 *size = *(uint16_t*)&buf[6];
100 return NULL;
103 const char * loadFile(const char * fullpath, uint8_t * data, uint16_t maxsize)
105 FIL file;
106 UINT read;
107 uint16_t size;
109 TRACE("loadFile(%s)", fullpath);
111 const char* err = openFile(fullpath, &file, &size);
112 if (err) return err;
114 size = min<uint16_t>(maxsize, size);
115 FRESULT result = f_read(&file, data, size, &read);
116 if (result != FR_OK || read != size) {
117 f_close(&file);
118 return SDCARD_ERROR(result);
121 f_close(&file);
122 return NULL;
125 const char * readModel(const char * filename, uint8_t * buffer, uint32_t size)
127 char path[256];
128 getModelPath(path, filename);
129 return loadFile(path, buffer, size);
132 const char * loadModel(const char * filename, bool alarms)
134 preModelLoad();
136 const char * error = readModel(filename, (uint8_t *)&g_model, sizeof(g_model));
137 if (error) {
138 TRACE("loadModel error=%s", error);
141 if (error) {
142 modelDefault(0) ;
143 storageCheck(true);
144 alarms = false;
147 postModelLoad(alarms);
149 return error;
152 const char * loadRadioSettingsSettings()
154 const char * error = loadFile(RADIO_SETTINGS_PATH, (uint8_t *)&g_eeGeneral, sizeof(g_eeGeneral));
155 if (error) {
156 TRACE("loadRadioSettingsSettings error=%s", error);
159 return error;
162 const char * writeGeneralSettings()
164 return writeFile(RADIO_SETTINGS_PATH, (uint8_t *)&g_eeGeneral, sizeof(g_eeGeneral));
167 void storageCheck(bool immediately)
169 if (storageDirtyMsk & EE_GENERAL) {
170 TRACE("eeprom write general");
171 storageDirtyMsk -= EE_GENERAL;
172 const char * error = writeGeneralSettings();
173 if (error) {
174 TRACE("writeGeneralSettings error=%s", error);
178 if (storageDirtyMsk & EE_MODEL) {
179 TRACE("eeprom write model");
180 storageDirtyMsk -= EE_MODEL;
181 const char * error = writeModel();
182 if (error) {
183 TRACE("writeModel error=%s", error);
188 void storageReadAll()
190 TRACE("storageReadAll");
192 if (loadRadioSettingsSettings() != NULL) {
193 storageEraseAll(true);
196 #if defined(CPUARM)
197 for (uint8_t i=0; languagePacks[i]!=NULL; i++) {
198 if (!strncmp(g_eeGeneral.ttsLanguage, languagePacks[i]->id, 2)) {
199 currentLanguagePackIdx = i;
200 currentLanguagePack = languagePacks[i];
203 #endif
205 if (loadModel(g_eeGeneral.currModelFilename, false) != NULL) {
206 sdCheckAndCreateDirectory(MODELS_PATH);
207 createModel();
210 modelslist.load();
213 void storageCreateModelsList()
215 FIL file;
217 FRESULT result = f_open(&file, RADIO_MODELSLIST_PATH, FA_CREATE_ALWAYS | FA_WRITE);
218 if (result == FR_OK) {
219 f_puts("[" DEFAULT_CATEGORY "]\n" DEFAULT_MODEL_FILENAME "\n", &file);
220 f_close(&file);
224 void storageFormat()
226 sdCheckAndCreateDirectory(RADIO_PATH);
227 sdCheckAndCreateDirectory(MODELS_PATH);
228 storageCreateModelsList();
231 const char * createModel()
233 preModelLoad();
235 char filename[LEN_MODEL_FILENAME+1];
236 memset(filename, 0, sizeof(filename));
237 strcpy(filename, "model.bin");
239 int index = findNextFileIndex(filename, LEN_MODEL_FILENAME, MODELS_PATH);
240 if (index > 0) {
241 modelDefault(index);
242 memcpy(g_eeGeneral.currModelFilename, filename, sizeof(g_eeGeneral.currModelFilename));
243 storageDirty(EE_GENERAL);
244 storageDirty(EE_MODEL);
245 storageCheck(true);
247 postModelLoad(false);
249 return g_eeGeneral.currModelFilename;
252 void storageEraseAll(bool warn)
254 TRACE("storageEraseAll");
256 #if defined(COLORLCD)
257 // the theme has not been loaded before
258 theme->load();
259 #endif
261 generalDefault();
262 modelDefault(1);
264 if (warn) {
265 ALERT(STR_STORAGE_WARNING, STR_BAD_RADIO_DATA, AU_BAD_RADIODATA);
268 RAISE_ALERT(STR_STORAGE_WARNING, STR_STORAGE_FORMAT, NULL, AU_NONE);
270 storageFormat();
271 storageDirty(EE_GENERAL|EE_MODEL);
272 storageCheck(true);