[All] All FourCC changed (o9x changed to otx) (#4214)
[opentx.git] / radio / src / storage / sdcard_raw.cpp
blob6d9fcfab32c67d4ea851c6bf8cbd184dc5150364
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"
23 void getModelPath(char * path, const char * filename)
25 strcpy(path, STR_MODELS_PATH);
26 path[sizeof(MODELS_PATH)-1] = '/';
27 strcpy(&path[sizeof(MODELS_PATH)], filename);
30 const char * writeFile(const char * filename, const uint8_t * data, uint16_t size)
32 TRACE("writeFile(%s)", filename);
34 FIL file;
35 char buf[8];
36 UINT written;
38 FRESULT result = f_open(&file, filename, FA_CREATE_ALWAYS | FA_WRITE);
39 if (result != FR_OK) {
40 return SDCARD_ERROR(result);
43 *(uint32_t*)&buf[0] = OTX_FOURCC;
44 buf[4] = EEPROM_VER;
45 buf[5] = 'M';
46 *(uint16_t*)&buf[6] = size;
48 result = f_write(&file, buf, 8, &written);
49 if (result != FR_OK || written != 8) {
50 f_close(&file);
51 return SDCARD_ERROR(result);
54 result = f_write(&file, data, size, &written);
55 if (result != FR_OK || written != size) {
56 f_close(&file);
57 return SDCARD_ERROR(result);
60 f_close(&file);
61 return NULL;
64 const char * writeModel()
66 char path[256];
67 getModelPath(path, g_eeGeneral.currModelFilename);
68 return writeFile(path, (uint8_t *)&g_model, sizeof(g_model));
71 const char * loadFile(const char * filename, uint8_t * data, uint16_t maxsize)
73 TRACE("loadFile(%s)", filename);
75 FIL file;
76 char buf[8];
77 UINT read;
79 FRESULT result = f_open(&file, filename, FA_OPEN_EXISTING | FA_READ);
80 if (result != FR_OK) {
81 return SDCARD_ERROR(result);
84 if (f_size(&file) < 8) {
85 f_close(&file);
86 return STR_INCOMPATIBLE;
89 result = f_read(&file, (uint8_t *)buf, 8, &read);
90 if (result != FR_OK || read != 8) {
91 f_close(&file);
92 return SDCARD_ERROR(result);
95 uint8_t version = (uint8_t)buf[4];
96 if ((*(uint32_t*)&buf[0] != OTX_FOURCC && *(uint32_t*)&buf[0] != O9X_FOURCC) || version < FIRST_CONV_EEPROM_VER || version > EEPROM_VER || buf[5] != 'M') {
97 f_close(&file);
98 return STR_INCOMPATIBLE;
101 uint16_t size = min<uint16_t>(maxsize, *(uint16_t*)&buf[6]);
102 result = f_read(&file, data, size, &read);
103 if (result != FR_OK || read != size) {
104 f_close(&file);
105 return SDCARD_ERROR(result);
108 f_close(&file);
109 return NULL;
112 const char * readModel(const char * filename, uint8_t * buffer, uint32_t size)
114 char path[256];
115 getModelPath(path, filename);
116 return loadFile(path, buffer, size);
119 const char * loadModel(const char * filename, bool alarms)
121 preModelLoad();
123 const char * error = readModel(filename, (uint8_t *)&g_model, sizeof(g_model));
124 if (error) {
125 TRACE("loadModel error=%s", error);
128 if (error) {
129 modelDefault(0) ;
130 storageCheck(true);
131 alarms = false;
134 postModelLoad(alarms);
136 return error;
139 const char * loadRadioSettingsSettings()
141 const char * error = loadFile(RADIO_SETTINGS_PATH, (uint8_t *)&g_eeGeneral, sizeof(g_eeGeneral));
142 if (error) {
143 TRACE("loadRadioSettingsSettings error=%s", error);
145 // TODO this is temporary, we only have one model for now
146 return error;
149 const char * writeGeneralSettings()
151 return writeFile(RADIO_SETTINGS_PATH, (uint8_t *)&g_eeGeneral, sizeof(g_eeGeneral));
154 void storageCheck(bool immediately)
156 if (storageDirtyMsk & EE_GENERAL) {
157 TRACE("eeprom write general");
158 storageDirtyMsk -= EE_GENERAL;
159 const char * error = writeGeneralSettings();
160 if (error) {
161 TRACE("writeGeneralSettings error=%s", error);
165 if (storageDirtyMsk & EE_MODEL) {
166 TRACE("eeprom write model");
167 storageDirtyMsk -= EE_MODEL;
168 const char * error = writeModel();
169 if (error) {
170 TRACE("writeModel error=%s", error);
175 void storageReadAll()
177 TRACE("storageReadAll");
179 if (loadRadioSettingsSettings() != NULL) {
180 storageEraseAll(true);
183 #if defined(CPUARM)
184 for (uint8_t i=0; languagePacks[i]!=NULL; i++) {
185 if (!strncmp(g_eeGeneral.ttsLanguage, languagePacks[i]->id, 2)) {
186 currentLanguagePackIdx = i;
187 currentLanguagePack = languagePacks[i];
190 #endif
192 loadModel(g_eeGeneral.currModelFilename, false);
195 void storageCreateModelsList()
197 FIL file;
199 FRESULT result = f_open(&file, RADIO_MODELSLIST_PATH, FA_CREATE_ALWAYS | FA_WRITE);
200 if (result == FR_OK) {
201 f_puts("[" DEFAULT_CATEGORY "]\n" DEFAULT_MODEL_FILENAME "\n", &file);
202 f_close(&file);
206 void storageFormat()
208 sdCheckAndCreateDirectory(RADIO_PATH);
209 sdCheckAndCreateDirectory(MODELS_PATH);
210 storageCreateModelsList();
213 const char * createModel()
215 preModelLoad();
217 char filename[LEN_MODEL_FILENAME+1];
218 memset(filename, 0, sizeof(filename));
219 strcpy(filename, "model.bin");
221 int index = findNextFileIndex(filename, LEN_MODEL_FILENAME, MODELS_PATH);
222 if (index > 0) {
223 modelDefault(index);
224 memcpy(g_eeGeneral.currModelFilename, filename, sizeof(g_eeGeneral.currModelFilename));
225 storageDirty(EE_GENERAL);
226 storageDirty(EE_MODEL);
227 storageCheck(true);
229 postModelLoad(false);
231 return g_eeGeneral.currModelFilename;
234 void storageEraseAll(bool warn)
236 TRACE("storageEraseAll");
238 #if defined(COLORLCD)
239 // the theme has not been loaded before
240 theme->load();
241 #endif
243 generalDefault();
244 modelDefault(1);
246 if (warn) {
247 ALERT(STR_STORAGE_WARNING, STR_BAD_RADIO_DATA, AU_BAD_RADIODATA);
250 RAISE_ALERT(STR_STORAGE_WARNING, STR_STORAGE_FORMAT, NULL, AU_NONE);
252 storageFormat();
253 storageDirty(EE_GENERAL|EE_MODEL);
254 storageCheck(true);