Merge pull request #6382 from mikeller/fix_smartport_delay
[betaflight.git] / src / main / cms / cms_menu_blackbox.c
blobf0e99df030552c88bb12ada9bd69555c0f2e23eb
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/version.h"
36 #include "blackbox/blackbox.h"
37 #include "blackbox/blackbox_io.h"
39 #include "cms/cms.h"
40 #include "cms/cms_types.h"
41 #include "cms/cms_menu_blackbox.h"
43 #include "common/printf.h"
44 #include "common/utils.h"
46 #include "config/feature.h"
48 #include "drivers/flash.h"
49 #include "drivers/time.h"
50 #include "drivers/sdcard.h"
52 #include "fc/config.h"
54 #include "io/asyncfatfs/asyncfatfs.h"
55 #include "io/flashfs.h"
56 #include "io/beeper.h"
58 #include "pg/pg.h"
60 static const char * const cmsx_BlackboxDeviceNames[] = {
61 "NONE",
62 "FLASH ",
63 "SDCARD",
64 "SERIAL"
67 static uint16_t blackboxConfig_p_ratio;
69 static uint8_t cmsx_BlackboxDevice;
70 static OSD_TAB_t cmsx_BlackboxDeviceTable = { &cmsx_BlackboxDevice, 2, cmsx_BlackboxDeviceNames };
72 #define CMS_BLACKBOX_STRING_LENGTH 8
73 static char cmsx_BlackboxStatus[CMS_BLACKBOX_STRING_LENGTH];
74 static char cmsx_BlackboxDeviceStorageUsed[CMS_BLACKBOX_STRING_LENGTH];
75 static char cmsx_BlackboxDeviceStorageFree[CMS_BLACKBOX_STRING_LENGTH];
77 static void cmsx_Blackbox_GetDeviceStatus(void)
79 char * unit = "B";
80 #if defined(USE_SDCARD) || defined(USE_FLASHFS)
81 bool storageDeviceIsWorking = false;
82 #endif
83 uint32_t storageUsed = 0;
84 uint32_t storageFree = 0;
86 switch (blackboxConfig()->device)
88 #ifdef USE_SDCARD
89 case BLACKBOX_DEVICE_SDCARD:
90 unit = "MB";
92 if (!sdcard_isInserted()) {
93 tfp_sprintf(cmsx_BlackboxStatus, "NO CARD");
94 } else if (!sdcard_isFunctional()) {
95 tfp_sprintf(cmsx_BlackboxStatus, "FAULT");
96 } else {
97 switch (afatfs_getFilesystemState()) {
98 case AFATFS_FILESYSTEM_STATE_READY:
99 tfp_sprintf(cmsx_BlackboxStatus, "READY");
100 storageDeviceIsWorking = true;
101 break;
102 case AFATFS_FILESYSTEM_STATE_INITIALIZATION:
103 tfp_sprintf(cmsx_BlackboxStatus, "INIT");
104 break;
105 case AFATFS_FILESYSTEM_STATE_FATAL:
106 case AFATFS_FILESYSTEM_STATE_UNKNOWN:
107 default:
108 tfp_sprintf(cmsx_BlackboxStatus, "FAULT");
109 break;
113 if (storageDeviceIsWorking) {
114 storageFree = afatfs_getContiguousFreeSpace() / 1024000;
115 storageUsed = (sdcard_getMetadata()->numBlocks / 2000) - storageFree;
118 break;
119 #endif
121 #ifdef USE_FLASHFS
122 case BLACKBOX_DEVICE_FLASH:
123 unit = "KB";
125 storageDeviceIsWorking = flashfsIsSupported();
126 if (storageDeviceIsWorking) {
127 tfp_sprintf(cmsx_BlackboxStatus, "READY");
129 const flashGeometry_t *geometry = flashfsGetGeometry();
130 storageUsed = flashfsGetOffset() / 1024;
131 storageFree = (geometry->totalSize / 1024) - storageUsed;
132 } else {
133 tfp_sprintf(cmsx_BlackboxStatus, "FAULT");
136 break;
137 #endif
139 default:
140 tfp_sprintf(cmsx_BlackboxStatus, "---");
143 /* Storage counters */
144 tfp_sprintf(cmsx_BlackboxDeviceStorageUsed, "%ld%s", storageUsed, unit);
145 tfp_sprintf(cmsx_BlackboxDeviceStorageFree, "%ld%s", storageFree, unit);
148 #ifdef USE_FLASHFS
149 static long cmsx_EraseFlash(displayPort_t *pDisplay, const void *ptr)
151 UNUSED(ptr);
153 if (!flashfsIsSupported()) {
154 return 0;
157 displayClearScreen(pDisplay);
158 displayWrite(pDisplay, 5, 3, "ERASING FLASH...");
159 displayResync(pDisplay); // Was max7456RefreshAll(); Why at this timing?
161 flashfsEraseCompletely();
162 while (!flashfsIsReady()) {
163 delay(100);
166 beeper(BEEPER_BLACKBOX_ERASE);
167 displayClearScreen(pDisplay);
168 displayResync(pDisplay); // Was max7456RefreshAll(); wedges during heavy SPI?
170 // Update storage device status to show new used space amount
171 cmsx_Blackbox_GetDeviceStatus();
173 return 0;
175 #endif // USE_FLASHFS
177 static long cmsx_Blackbox_onEnter(void)
179 cmsx_Blackbox_GetDeviceStatus();
180 cmsx_BlackboxDevice = blackboxConfig()->device;
182 blackboxConfig_p_ratio = blackboxConfig()->p_ratio;
183 return 0;
186 static long cmsx_Blackbox_onExit(const OSD_Entry *self)
188 UNUSED(self);
190 if (blackboxMayEditConfig()) {
191 blackboxConfigMutable()->device = cmsx_BlackboxDevice;
192 blackboxValidateConfig();
194 blackboxConfigMutable()->p_ratio = blackboxConfig_p_ratio;
195 return 0;
198 static OSD_Entry cmsx_menuBlackboxEntries[] =
200 { "-- BLACKBOX --", OME_Label, NULL, NULL, 0},
201 { "DEVICE", OME_TAB, NULL, &cmsx_BlackboxDeviceTable, 0 },
202 { "(STATUS)", OME_String, NULL, &cmsx_BlackboxStatus, 0 },
203 { "(USED)", OME_String, NULL, &cmsx_BlackboxDeviceStorageUsed, 0 },
204 { "(FREE)", OME_String, NULL, &cmsx_BlackboxDeviceStorageFree, 0 },
205 { "P RATIO", OME_UINT16, NULL, &(OSD_UINT16_t){ &blackboxConfig_p_ratio, 1, INT16_MAX, 1 },0 },
207 #ifdef USE_FLASHFS
208 { "ERASE FLASH", OME_Funcall, cmsx_EraseFlash, NULL, 0 },
209 #endif // USE_FLASHFS
211 { "BACK", OME_Back, NULL, NULL, 0 },
212 { NULL, OME_END, NULL, NULL, 0 }
215 CMS_Menu cmsx_menuBlackbox = {
216 #ifdef CMS_MENU_DEBUG
217 .GUARD_text = "MENUBB",
218 .GUARD_type = OME_MENU,
219 #endif
220 .onEnter = cmsx_Blackbox_onEnter,
221 .onExit = cmsx_Blackbox_onExit,
222 .entries = cmsx_menuBlackboxEntries
225 #endif