Update cloud build defines (#14080)
[betaflight.git] / src / main / cms / cms_menu_blackbox.c
blob8fee46608acc0fd41a86c4631d33c9f2625e80a1
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
22 // CMS things for blackbox and flashfs.
25 #include <stdbool.h>
26 #include <stdint.h>
27 #include <string.h>
28 #include <ctype.h>
30 #include "platform.h"
32 #if defined(USE_CMS) && defined(USE_BLACKBOX)
34 #include "build/debug.h"
35 #include "build/version.h"
37 #include "blackbox/blackbox.h"
38 #include "blackbox/blackbox_io.h"
40 #include "cms/cms.h"
41 #include "cms/cms_types.h"
42 #include "cms/cms_menu_blackbox.h"
44 #include "common/printf.h"
45 #include "common/utils.h"
46 #include "common/time.h"
48 #include "config/feature.h"
50 #include "drivers/flash/flash.h"
51 #include "drivers/time.h"
52 #include "drivers/sdcard.h"
53 #include "drivers/usb_msc.h"
55 #include "config/config.h"
57 #include "io/asyncfatfs/asyncfatfs.h"
58 #include "io/flashfs.h"
59 #include "io/beeper.h"
60 #include "io/usb_msc.h"
62 #include "pg/pg.h"
64 #include "flight/pid.h"
66 static const char * const cmsx_BlackboxDeviceNames[] = {
67 "NONE",
68 "FLASH",
69 "SDCARD",
70 "SERIAL"
73 static const char * const cmsx_BlackboxRateNames[] = {
74 "1/1",
75 "1/2",
76 "1/4",
77 "1/8",
78 "1/16"
81 static uint8_t cmsx_BlackboxDevice;
82 static OSD_TAB_t cmsx_BlackboxDeviceTable = { &cmsx_BlackboxDevice, 3, cmsx_BlackboxDeviceNames };
83 static uint8_t cmsx_BlackboxRate;
84 static OSD_TAB_t cmsx_BlackboxRateTable = { &cmsx_BlackboxRate, 4, cmsx_BlackboxRateNames };
85 static debugType_e systemConfig_debug_mode;
87 #define CMS_BLACKBOX_STRING_LENGTH 8
88 static char cmsx_BlackboxStatus[CMS_BLACKBOX_STRING_LENGTH];
89 static char cmsx_BlackboxDeviceStorageUsed[CMS_BLACKBOX_STRING_LENGTH];
90 static char cmsx_BlackboxDeviceStorageFree[CMS_BLACKBOX_STRING_LENGTH];
91 static char cmsx_pidFreq[CMS_BLACKBOX_STRING_LENGTH];
93 static void cmsx_Blackbox_GetDeviceStatus(void)
95 char * unit = "B";
96 #if defined(USE_SDCARD) || defined(USE_FLASHFS)
97 bool storageDeviceIsWorking = false;
98 #endif
99 uint32_t storageUsed = 0;
100 uint32_t storageFree = 0;
102 switch (blackboxConfig()->device)
104 #ifdef USE_SDCARD
105 case BLACKBOX_DEVICE_SDCARD:
106 unit = "MB";
108 if (!sdcard_isInserted()) {
109 tfp_sprintf(cmsx_BlackboxStatus, "NO CARD");
110 } else if (!sdcard_isFunctional()) {
111 tfp_sprintf(cmsx_BlackboxStatus, "FAULT");
112 } else {
113 switch (afatfs_getFilesystemState()) {
114 case AFATFS_FILESYSTEM_STATE_READY:
115 tfp_sprintf(cmsx_BlackboxStatus, "READY");
116 storageDeviceIsWorking = true;
117 break;
118 case AFATFS_FILESYSTEM_STATE_INITIALIZATION:
119 tfp_sprintf(cmsx_BlackboxStatus, "INIT");
120 break;
121 case AFATFS_FILESYSTEM_STATE_FATAL:
122 case AFATFS_FILESYSTEM_STATE_UNKNOWN:
123 default:
124 tfp_sprintf(cmsx_BlackboxStatus, "FAULT");
125 break;
129 if (storageDeviceIsWorking) {
130 storageFree = afatfs_getContiguousFreeSpace() / 1024000;
131 storageUsed = (sdcard_getMetadata()->numBlocks / 2000) - storageFree;
134 break;
135 #endif
137 #ifdef USE_FLASHFS
138 case BLACKBOX_DEVICE_FLASH:
139 unit = "KB";
141 storageDeviceIsWorking = flashfsIsSupported();
142 if (storageDeviceIsWorking) {
143 tfp_sprintf(cmsx_BlackboxStatus, "READY");
145 const flashPartition_t *flashPartition = flashPartitionFindByType(FLASH_PARTITION_TYPE_FLASHFS);
146 const flashGeometry_t *flashGeometry = flashGetGeometry();
148 storageUsed = flashfsGetOffset() / 1024;
149 storageFree = ((FLASH_PARTITION_SECTOR_COUNT(flashPartition) * flashGeometry->sectorSize) / 1024) - storageUsed;
150 } else {
151 tfp_sprintf(cmsx_BlackboxStatus, "FAULT");
154 break;
155 #endif
157 default:
158 tfp_sprintf(cmsx_BlackboxStatus, "---");
161 /* Storage counters */
162 tfp_sprintf(cmsx_BlackboxDeviceStorageUsed, "%ld%s", storageUsed, unit);
163 tfp_sprintf(cmsx_BlackboxDeviceStorageFree, "%ld%s", storageFree, unit);
166 #ifdef USE_FLASHFS
167 static const void *cmsx_EraseFlash(displayPort_t *pDisplay, const void *ptr)
169 UNUSED(ptr);
171 if (!flashfsIsSupported()) {
172 return NULL;
175 displayClearScreen(pDisplay, DISPLAY_CLEAR_WAIT);
176 displayWrite(pDisplay, 5, 3, DISPLAYPORT_SEVERITY_INFO, "ERASING FLASH...");
177 displayRedraw(pDisplay);
179 flashfsEraseCompletely();
180 while (!flashfsIsReady()) {
181 //TODO: Make this non-blocking!
182 delay(100);
185 beeper(BEEPER_BLACKBOX_ERASE);
186 displayClearScreen(pDisplay, DISPLAY_CLEAR_WAIT);
187 displayRedraw(pDisplay);
189 // Update storage device status to show new used space amount
190 cmsx_Blackbox_GetDeviceStatus();
192 return MENU_CHAIN_BACK;
194 #endif // USE_FLASHFS
196 #ifdef USE_USB_MSC
197 static const void *cmsx_StorageDevice(displayPort_t *pDisplay, const void *ptr)
199 UNUSED(ptr);
201 if (mscCheckFilesystemReady()) {
202 displayClearScreen(pDisplay, DISPLAY_CLEAR_WAIT);
203 displayWrite(pDisplay, 2, 4, DISPLAYPORT_SEVERITY_INFO, "USB MASS STORAGE MODE IS ON");
204 displayWrite(pDisplay, 4, 5, DISPLAYPORT_SEVERITY_INFO, "CONNECT YOUR GADGET");
205 displayRedraw(pDisplay);
206 #ifdef USE_RTC_TIME
207 int timezoneOffsetMinutes = timeConfig()->tz_offsetMinutes;
208 #else
209 int timezoneOffsetMinutes = 0;
210 #endif
211 beeper(BEEPER_USB);
212 systemResetToMsc(timezoneOffsetMinutes);
213 return NULL;
214 } else {
215 displayWrite(pDisplay, 5, 3, DISPLAYPORT_SEVERITY_INFO, "STORAGE NOT PRESENT OR FAILED TO INITIALIZE!");
216 displayRedraw(pDisplay);
217 beeper(BEEPER_USB);
218 return MENU_CHAIN_BACK;
221 #endif //USE_USB_MSC
223 static const void *cmsx_Blackbox_onEnter(displayPort_t *pDisp)
225 UNUSED(pDisp);
227 cmsx_Blackbox_GetDeviceStatus();
228 cmsx_BlackboxDevice = blackboxConfig()->device;
229 cmsx_BlackboxRate = blackboxConfig()->sample_rate;
230 systemConfig_debug_mode = systemConfig()->debug_mode;
232 const uint16_t pidFreq = (uint16_t)pidGetPidFrequency();
233 if (pidFreq > 1000) {
234 tfp_sprintf(cmsx_pidFreq, "%1d.%02dKHZ", (pidFreq / 10) / 100, (pidFreq / 10) % 100);
235 } else {
236 tfp_sprintf(cmsx_pidFreq, "%3dHZ", pidFreq);
238 return NULL;
241 static const void *cmsx_Blackbox_onExit(displayPort_t *pDisp, const OSD_Entry *self)
243 UNUSED(pDisp);
244 UNUSED(self);
246 if (blackboxMayEditConfig()) {
247 blackboxConfigMutable()->device = cmsx_BlackboxDevice;
248 blackboxValidateConfig();
250 blackboxConfigMutable()->sample_rate = cmsx_BlackboxRate;
251 systemConfigMutable()->debug_mode = systemConfig_debug_mode;
253 return NULL;
256 // Check before erase flash
257 #ifdef USE_FLASHFS
258 static const OSD_Entry menuEraseFlashCheckEntries[] = {
259 { "CONFIRM ERASE", OME_Label, NULL, NULL},
260 { "NO", OME_Back, NULL, NULL },
262 { "YES", OME_Funcall, cmsx_EraseFlash, NULL },
263 { NULL, OME_END, NULL, NULL }
266 static CMS_Menu cmsx_menuEraseFlashCheck = {
267 #ifdef CMS_MENU_DEBUG
268 .GUARD_text = "MENUERASEFLASH",
269 .GUARD_type = OME_MENU,
270 #endif
271 .onEnter = NULL,
272 .onExit = NULL,
273 .onDisplayUpdate = NULL,
274 .entries = menuEraseFlashCheckEntries
276 #endif //USE_FLASHFS
278 #ifdef USE_USB_MSC
279 static const OSD_Entry menuStorageDeviceCheckEntries[] = {
280 { "CONFIRM USB MASS STORAGE", OME_Label, NULL, NULL},
281 { "NO", OME_Back, NULL, NULL },
283 { "YES", OME_Funcall, cmsx_StorageDevice, NULL },
284 { NULL, OME_END, NULL, NULL }
287 static CMS_Menu cmsx_menuStorageDeviceCheck = {
288 #ifdef CMS_MENU_DEBUG
289 .GUARD_text = "STORAGEDEVICE",
290 .GUARD_type = OME_MENU,
291 #endif
292 .onEnter = NULL,
293 .onExit = NULL,
294 .onDisplayUpdate = NULL,
295 .entries = menuStorageDeviceCheckEntries
297 #endif //USE_USB_MSC
299 static const OSD_Entry cmsx_menuBlackboxEntries[] =
301 { "-- BLACKBOX --", OME_Label, NULL, NULL},
302 { "(PID FREQ)", OME_String, NULL, &cmsx_pidFreq },
303 { "SAMPLERATE", OME_TAB | REBOOT_REQUIRED, NULL, &cmsx_BlackboxRateTable },
304 { "DEVICE", OME_TAB | REBOOT_REQUIRED, NULL, &cmsx_BlackboxDeviceTable },
305 { "(STATUS)", OME_String, NULL, &cmsx_BlackboxStatus },
306 { "(USED)", OME_String, NULL, &cmsx_BlackboxDeviceStorageUsed },
307 { "(FREE)", OME_String, NULL, &cmsx_BlackboxDeviceStorageFree },
308 { "DEBUG MODE", OME_TAB | REBOOT_REQUIRED, NULL, &(OSD_TAB_t) { &systemConfig_debug_mode, DEBUG_COUNT - 1, debugModeNames } },
310 #ifdef USE_USB_MSC
311 { "USB MASS STORAGE", OME_Submenu, cmsMenuChange, &cmsx_menuStorageDeviceCheck },
312 #endif // USE_USB_MSC
313 #ifdef USE_FLASHFS
314 { "ERASE FLASH", OME_Submenu, cmsMenuChange, &cmsx_menuEraseFlashCheck },
315 #endif // USE_FLASHFS
317 { "BACK", OME_Back, NULL, NULL },
318 { NULL, OME_END, NULL, NULL}
321 CMS_Menu cmsx_menuBlackbox = {
322 #ifdef CMS_MENU_DEBUG
323 .GUARD_text = "MENUBB",
324 .GUARD_type = OME_MENU,
325 #endif
326 .onEnter = cmsx_Blackbox_onEnter,
327 .onExit = cmsx_Blackbox_onExit,
328 .onDisplayUpdate = NULL,
329 .entries = cmsx_menuBlackboxEntries
332 #endif