Skip to content

Commit d872814

Browse files
committed
🚑️ Fix Filesystem bug in V2
1 parent 1b2c10b commit d872814

File tree

3 files changed

+71
-114
lines changed

3 files changed

+71
-114
lines changed

src/provisioning/tinyusb/Wippersnapper_FS.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -606,17 +606,17 @@ void qspi_msc_flush_cb(void) {
606606
//--------------------------------------------------------------------+
607607
extern "C" {
608608

609-
DSTATUS disk_status(BYTE pdrv) {
609+
DSTATUS fdisk_status(BYTE pdrv) {
610610
(void)pdrv;
611611
return 0;
612612
}
613613

614-
DSTATUS disk_initialize(BYTE pdrv) {
614+
DSTATUS fdisk_initialize(BYTE pdrv) {
615615
(void)pdrv;
616616
return 0;
617617
}
618618

619-
DRESULT disk_read(BYTE pdrv, /* Physical drive nmuber to identify the drive */
619+
DRESULT fdisk_read(BYTE pdrv, /* Physical drive nmuber to identify the drive */
620620
BYTE *buff, /* Data buffer to store read data */
621621
DWORD sector, /* Start sector in LBA */
622622
UINT count /* Number of sectors to read */
@@ -625,7 +625,7 @@ DRESULT disk_read(BYTE pdrv, /* Physical drive nmuber to identify the drive */
625625
return flash.readBlocks(sector, buff, count) ? RES_OK : RES_ERROR;
626626
}
627627

628-
DRESULT disk_write(BYTE pdrv, /* Physical drive nmuber to identify the drive */
628+
DRESULT fdisk_write(BYTE pdrv, /* Physical drive nmuber to identify the drive */
629629
const BYTE *buff, /* Data to be written */
630630
DWORD sector, /* Start sector in LBA */
631631
UINT count /* Number of sectors to write */
@@ -634,7 +634,7 @@ DRESULT disk_write(BYTE pdrv, /* Physical drive nmuber to identify the drive */
634634
return flash.writeBlocks(sector, buff, count) ? RES_OK : RES_ERROR;
635635
}
636636

637-
DRESULT disk_ioctl(BYTE pdrv, /* Physical drive nmuber (0..) */
637+
DRESULT fdisk_ioctl(BYTE pdrv, /* Physical drive nmuber (0..) */
638638
BYTE cmd, /* Control code */
639639
void *buff /* Buffer to send/receive control data */
640640
) {

src/provisioning/tinyusb/Wippersnapper_FS_V2.cpp

Lines changed: 64 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
Adafruit_FlashTransport_QSPI flashTransport_v2;
3737
#elif defined(EXTERNAL_FLASH_USE_SPI)
3838
Adafruit_FlashTransport_SPI flashTransport_v2(EXTERNAL_FLASH_USE_CS,
39-
EXTERNAL_FLASH_USE_SPI);
39+
EXTERNAL_FLASH_USE_SPI);
4040
#elif defined(ARDUINO_ARCH_ESP32)
4141
// ESP32-S2 uses same flash device that stores code.
4242
// Therefore there is no need to specify the SPI and SS
@@ -59,61 +59,27 @@ Adafruit_USBD_MSC usb_msc_v2; /*!< USB mass storage object */
5959
FATFS elmchamFatfs_v2; ///< Elm Cham's fatfs object
6060
uint8_t workbuf_v2[4096]; ///< Working buffer for f_fdisk function.
6161

62-
FRESULT mk_fs(void) {
62+
FRESULT format_fs_fat12(void) {
6363
// Make filesystem
6464
FRESULT r = f_mkfs("", FM_FAT | FM_SFD, 0, workbuf_v2, sizeof(workbuf_v2));
65-
return r;
66-
}
6765

68-
bool mk_mount_disk_label(void) {
6966
// mount to set disk label
70-
FRESULT r = f_mount(&elmchamFatfs_v2, "0:", 1);
71-
if (r != FR_OK) {
72-
return false;
73-
}
74-
return true;
75-
}
67+
r = f_mount(&elmchamFatfs_v2, "0:", 1);
68+
if (r != FR_OK)
69+
return r;
7670

77-
bool mk_set_disk_label(void) {
7871
// set label
79-
FRESULT r = f_setlabel("WIPPER");
80-
if (r != FR_OK) {
81-
return false;
82-
}
72+
r = f_setlabel("WIPPER");
73+
if (r != FR_OK)
74+
return r;
8375

8476
// unmount
8577
f_unmount("0:");
8678

8779
// sync to make sure all data is written to flash
8880
flash_v2.syncBlocks();
8981

90-
return true;
91-
}
92-
93-
String getFRESULTMessage(FRESULT result) {
94-
switch(result) {
95-
case FR_OK: return "Succeeded";
96-
case FR_DISK_ERR: return "A hard error occurred in the low level disk I/O layer";
97-
case FR_INT_ERR: return "Assertion failed";
98-
case FR_NOT_READY: return "The physical drive cannot work";
99-
case FR_NO_FILE: return "Could not find the file";
100-
case FR_NO_PATH: return "Could not find the path";
101-
case FR_INVALID_NAME: return "The path name format is invalid";
102-
case FR_DENIED: return "Access denied due to prohibited access or directory full";
103-
case FR_EXIST: return "Access denied due to prohibited access";
104-
case FR_INVALID_OBJECT: return "The file/directory object is invalid";
105-
case FR_WRITE_PROTECTED: return "The physical drive is write protected";
106-
case FR_INVALID_DRIVE: return "The logical drive number is invalid";
107-
case FR_NOT_ENABLED: return "The volume has no work area";
108-
case FR_NO_FILESYSTEM: return "There is no valid FAT volume";
109-
case FR_MKFS_ABORTED: return "The f_mkfs() aborted due to any problem";
110-
case FR_TIMEOUT: return "Could not get a grant to access the volume within defined period";
111-
case FR_LOCKED: return "The operation is rejected according to the file sharing policy";
112-
case FR_NOT_ENOUGH_CORE: return "LFN working buffer could not be allocated";
113-
case FR_TOO_MANY_OPEN_FILES: return "Number of open files > FF_FS_LOCK";
114-
case FR_INVALID_PARAMETER: return "Given parameter is invalid";
115-
default: return "Unknown error";
116-
}
82+
return r;
11783
}
11884

11985
/**************************************************************************/
@@ -135,49 +101,51 @@ Wippersnapper_FS_V2::Wippersnapper_FS_V2() {
135101

136102
// Check if the filesystem is formatted
137103
_isFormatted = wipperFatFs_v2.begin(&flash_v2);
138-
_isFormatted = false;
139104

140105
// If we are not formatted, attempt to format the filesystem as fat12
141106
if (!_isFormatted) {
142-
FRESULT rc = mk_fs();
143-
fsHalt(getFRESULTMessage(rc));
107+
FRESULT rc = format_fs_fat12();
144108

145-
if (! mk_mount_disk_label() ) {
146-
setStatusLEDColor(RED);
147-
fsHalt("L125: Failed to mount the filesystem!");
148-
}
149-
if (! mk_set_disk_label() ) {
109+
if (format_fs_fat12() != FR_OK) {
150110
setStatusLEDColor(RED);
151-
fsHalt("Failed to set the disk label!");
111+
fsHalt("FATAL ERROR: Failed to format the filesystem!");
152112
}
153113

154114
// now that we formatted, we need to re-init the filesystem
155-
if (!wipperFatFs_v2.begin(&flash_v2)){
115+
if (!wipperFatFs_v2.begin(&flash_v2)) {
156116
setStatusLEDColor(RED);
157-
fsHalt("Failed to mount new filesystem!");
117+
fsHalt("FATAL ERROR: Failed to mount newly created filesystem!");
158118
}
159-
// Signal to the user that we've formatted the FS and they need to modify its contents
160-
_freshFS = true;
161119
}
162120

163-
if (!wipperFatFs_v2.begin(&flash_v2)) {
121+
// Write contents to the formatted filesystem
122+
if (!writeFSContents()) {
164123
setStatusLEDColor(RED);
165-
// pass res to the fsHalt
166-
fsHalt("L143: Failed to mount the filesystem");
167-
}
168-
169-
// Write contents to the filesystem
170-
if (! writeFSContents()) {
171-
setStatusLEDColor(RED);
172-
fsHalt("ERROR: Could not write filesystem contents!");
124+
fsHalt("FATAL ERROR: Could not write filesystem contents!");
173125
}
174126

175127
// Initialize USB-MSC
176128
initUSBMSC();
177129

178-
// If we created a new filesystem, halt until user RESETs device.
179-
if (_freshFS)
180-
fsHalt("New filesystem created! Press the reset button on your board.");
130+
// If we wrote a fresh secrets.json file, halt until user edits the file and
131+
// RESETs the device Signal to user that action must be taken (edit
132+
// secrets.json)
133+
if (_is_secrets_file_empty) {
134+
writeToBootOut(
135+
"Please edit the secrets.json file. Then, reset your board.\n");
136+
#ifdef USE_DISPLAY
137+
WsV2._ui_helper->show_scr_error(
138+
"INVALID SETTINGS FILE",
139+
"The settings.json file on the WIPPER drive contains default values. "
140+
"Please edit it to reflect your Adafruit IO and network credentials. "
141+
"When you're done, press RESET on the board.");
142+
#endif
143+
fsHalt(
144+
"INVALID SETTINGS FILE",
145+
"The settings.json file on the WIPPER drive contains default values. "
146+
"Please edit it to reflect your Adafruit IO and network credentials. "
147+
"When you're done, press RESET on the board.");
148+
}
181149
}
182150

183151
/************************************************************/
@@ -216,7 +184,8 @@ bool disableMacOSIndexing() {
216184
*/
217185
/**************************************************************************/
218186
bool Wippersnapper_FS_V2::writeFSContents() {
219-
// If CircuitPython was previously installed - erase CircuitPython's default filesystem
187+
// If CircuitPython was previously installed - erase CircuitPython's default
188+
// filesystem
220189
eraseCPFS();
221190

222191
// If WipperSnapper was previously installed - remove the old
@@ -231,11 +200,11 @@ bool Wippersnapper_FS_V2::writeFSContents() {
231200
return false;
232201

233202
// Check if secrets.json file already exists
234-
if (!configFileExists()) {
203+
if (!getSecretsFile()) {
235204
// Create new secrets.json file and halt
236205
createSecretsFile();
206+
_is_secrets_file_empty = true;
237207
}
238-
239208
return true;
240209
}
241210

@@ -250,7 +219,7 @@ void Wippersnapper_FS_V2::initUSBMSC() {
250219
usb_msc_v2.setID("Adafruit", "External Flash", "1.0");
251220
// Set callback
252221
usb_msc_v2.setReadWriteCallback(qspi_msc_read_cb_v2, qspi_msc_write_cb_v2,
253-
qspi_msc_flush_cb_v2);
222+
qspi_msc_flush_cb_v2);
254223

255224
// Set disk size, block size should be 512 regardless of spi flash page size
256225
usb_msc_v2.setCapacity(flash_v2.pageSize() * flash_v2.numPages() / 512, 512);
@@ -261,7 +230,8 @@ void Wippersnapper_FS_V2::initUSBMSC() {
261230
// init MSC
262231
usb_msc_v2.begin();
263232

264-
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
233+
// If already enumerated, additional class driverr begin() e.g msc, hid, midi
234+
// won't take effect until re-enumeration
265235
if (TinyUSBDevice.mounted()) {
266236
TinyUSBDevice.detach();
267237
delay(10);
@@ -275,7 +245,7 @@ void Wippersnapper_FS_V2::initUSBMSC() {
275245
@returns True if secrets.json file exists, False otherwise.
276246
*/
277247
/**************************************************************************/
278-
bool Wippersnapper_FS_V2::configFileExists() {
248+
bool Wippersnapper_FS_V2::getSecretsFile() {
279249
// Does secrets.json file exist?
280250
if (!wipperFatFs_v2.exists("/secrets.json"))
281251
return false;
@@ -328,20 +298,20 @@ bool Wippersnapper_FS_V2::createBootFile() {
328298
bootFile.println(BOARD_ID);
329299

330300
sprintf(sMAC, "%02X:%02X:%02X:%02X:%02X:%02X", WsV2._macAddrV2[0],
331-
WsV2._macAddrV2[1], WsV2._macAddrV2[2], WsV2._macAddrV2[3], WsV2._macAddrV2[4],
332-
WsV2._macAddrV2[5]);
301+
WsV2._macAddrV2[1], WsV2._macAddrV2[2], WsV2._macAddrV2[3],
302+
WsV2._macAddrV2[4], WsV2._macAddrV2[5]);
333303
bootFile.print("MAC Address: ");
334304
bootFile.println(sMAC);
335305

336-
// Print ESP-specific info to boot file
337-
#ifdef ARDUINO_ARCH_ESP32
306+
// Print ESP-specific info to boot file
307+
#ifdef ARDUINO_ARCH_ESP32
338308
// Get version of ESP-IDF
339309
bootFile.print("ESP-IDF Version: ");
340310
bootFile.println(ESP.getSdkVersion());
341311
// Get version of this core
342312
bootFile.print("ESP32 Core Version: ");
343313
bootFile.println(ESP.getCoreVersion());
344-
#endif
314+
#endif
345315

346316
bootFile.flush();
347317
bootFile.close();
@@ -380,18 +350,6 @@ void Wippersnapper_FS_V2::createSecretsFile() {
380350
secretsFile.flush();
381351
secretsFile.close();
382352
delay(2500);
383-
384-
// Signal to user that action must be taken (edit secrets.json)
385-
writeToBootOut(
386-
"ERROR: Please edit the secrets.json file. Then, reset your board.\n");
387-
#ifdef USE_DISPLAY
388-
WsV2._ui_helper->show_scr_error(
389-
"INVALID SETTINGS FILE",
390-
"The settings.json file on the WIPPER drive contains default values. "
391-
"Please edit it to reflect your Adafruit IO and network credentials. "
392-
"When you're done, press RESET on the board.");
393-
#endif
394-
fsHalt("ERROR: Please edit the secrets.json file. Then, reset your board.");
395353
}
396354

397355
/**************************************************************************/
@@ -497,14 +455,13 @@ void Wippersnapper_FS_V2::parseSecrets() {
497455
"credentials!");
498456
}
499457

500-
writeToBootOut("Secrets Contents\n");
501-
writeToBootOut("Network Info\n: ");
502-
writeToBootOut(WsV2._configV2.network.ssid);
503-
writeToBootOut(WsV2._configV2.network.pass);
504-
writeToBootOut("IO Creds.\n: ");
505-
writeToBootOut(WsV2._configV2.aio_user);
506-
writeToBootOut(WsV2._configV2.aio_key);
507-
458+
writeToBootOut("Secrets Contents\n");
459+
writeToBootOut("Network Info\n: ");
460+
writeToBootOut(WsV2._configV2.network.ssid);
461+
writeToBootOut(WsV2._configV2.network.pass);
462+
writeToBootOut("IO Creds.\n: ");
463+
writeToBootOut(WsV2._configV2.aio_user);
464+
writeToBootOut(WsV2._configV2.aio_key);
508465

509466
// Close secrets.json file
510467
secretsFile.close();
@@ -543,7 +500,7 @@ void Wippersnapper_FS_V2::fsHalt(String msg) {
543500
delay(500);
544501
statusLEDSolid(WS_LED_STATUS_FS_WRITE);
545502
while (1) {
546-
WS_DEBUG_PRINTLN("Fatal Error: Halted execution!");
503+
WS_DEBUG_PRINT("Execution Halted: ");
547504
WS_DEBUG_PRINTLN(msg.c_str());
548505
delay(1000);
549506
yield();
@@ -628,7 +585,8 @@ int32_t qspi_msc_read_cb_v2(uint32_t lba, void *buffer, uint32_t bufsize) {
628585
// Note: SPIFLash Bock API: readBlocks/writeBlocks/syncBlocks
629586
// already include 4K sector caching internally. We don't need to cache it,
630587
// yahhhh!!
631-
return flash_v2.readBlocks(lba, (uint8_t *)buffer, bufsize / 512) ? bufsize : -1;
588+
return flash_v2.readBlocks(lba, (uint8_t *)buffer, bufsize / 512) ? bufsize
589+
: -1;
632590
}
633591

634592
/**************************************************************************/
@@ -669,17 +627,17 @@ void qspi_msc_flush_cb_v2(void) {
669627
//--------------------------------------------------------------------+
670628
extern "C" {
671629

672-
DSTATUS disk_status_v2(BYTE pdrv) {
630+
DSTATUS disk_status(BYTE pdrv) {
673631
(void)pdrv;
674632
return 0;
675633
}
676634

677-
DSTATUS disk_initialize_v2(BYTE pdrv) {
635+
DSTATUS disk_initialize(BYTE pdrv) {
678636
(void)pdrv;
679637
return 0;
680638
}
681639

682-
DRESULT disk_read_v2(BYTE pdrv, /* Physical drive nmuber to identify the drive */
640+
DRESULT disk_read(BYTE pdrv, /* Physical drive nmuber to identify the drive */
683641
BYTE *buff, /* Data buffer to store read data */
684642
DWORD sector, /* Start sector in LBA */
685643
UINT count /* Number of sectors to read */
@@ -688,7 +646,7 @@ DRESULT disk_read_v2(BYTE pdrv, /* Physical drive nmuber to identify the drive
688646
return flash_v2.readBlocks(sector, buff, count) ? RES_OK : RES_ERROR;
689647
}
690648

691-
DRESULT disk_write_v2(BYTE pdrv, /* Physical drive nmuber to identify the drive */
649+
DRESULT disk_write(BYTE pdrv, /* Physical drive nmuber to identify the drive */
692650
const BYTE *buff, /* Data to be written */
693651
DWORD sector, /* Start sector in LBA */
694652
UINT count /* Number of sectors to write */
@@ -697,7 +655,7 @@ DRESULT disk_write_v2(BYTE pdrv, /* Physical drive nmuber to identify the drive
697655
return flash_v2.writeBlocks(sector, buff, count) ? RES_OK : RES_ERROR;
698656
}
699657

700-
DRESULT disk_ioctl_v2(BYTE pdrv, /* Physical drive nmuber (0..) */
658+
DRESULT disk_ioctl(BYTE pdrv, /* Physical drive nmuber (0..) */
701659
BYTE cmd, /* Control code */
702660
void *buff /* Buffer to send/receive control data */
703661
) {

src/provisioning/tinyusb/Wippersnapper_FS_V2.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ class Wippersnapper_FS_V2 {
5050
void eraseCPFS();
5151
void eraseBootFile();
5252

53-
bool configFileExists();
5453
void createSecretsFile();
54+
bool getSecretsFile();
5555
bool createBootFile();
5656
void writeToBootOut(PGM_P str);
5757
void fsHalt(String msg);
@@ -63,9 +63,8 @@ class Wippersnapper_FS_V2 {
6363
void createDisplayConfig();
6464
#endif
6565
private:
66-
bool _freshFS = false; /*!< True if filesystem was initialized by
67-
WipperSnapper, False otherwise. */
6866
bool _isFormatted = false;
67+
bool _is_secrets_file_empty = false;
6968
};
7069

7170
extern Wippersnapper_V2 WsV2;

0 commit comments

Comments
 (0)