Skip to content

Commit 3e1441e

Browse files
committed
allow enable/disable of presenting SD card to USB; suppress auto-reload when writing dirty bit
1 parent 3472567 commit 3e1441e

File tree

6 files changed

+44
-12
lines changed

6 files changed

+44
-12
lines changed

ports/atmel-samd/mpconfigport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111

1212
// Definitions that control circuitpy_mpconfig.h:
1313

14+
// On SAMD, presenting the SD card as a second LUN causes USB disconnect. This needs to be fixed eventually.
15+
#define CIRCUITPY_SDCARD_USB (0)
16+
1417
////////////////////////////////////////////////////////////////////////////////////////////////////
1518

1619
#ifdef SAMD21

ports/cxd56/mpconfigport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
#define MICROPY_PY_SYS_PLATFORM "CXD56"
1010

11+
// SD card socket on board is configured for sdioio, which is not supported for automatic USB presentation.
12+
#define CIRCUITPY_SDCARD_USB (0)
13+
1114
// 64kiB stack
1215
#define CIRCUITPY_DEFAULT_STACK_SIZE (0x10000)
1316

ports/espressif/mpconfigport.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717

1818
#define CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY (1)
1919

20+
// // Present SD card as USB MSC device by default
21+
// #ifndef CIRCUITPY_SDCARD_USB
22+
// #define CIRCUITPY_SDCARD_USB (1)
23+
// #endif
24+
2025
#include "py/circuitpy_mpconfig.h"
2126

2227
#define MICROPY_NLR_SETJMP (1)

shared-module/sdcardio/__init__.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,5 +123,5 @@ void automount_sd_card(void) {
123123
sdcard_vfs->next = MP_STATE_VM(vfs_mount_table);
124124
MP_STATE_VM(vfs_mount_table) = sdcard_vfs;
125125
_mounted = true;
126-
#endif
126+
#endif // DEFAULT_SD_CARD_DETECT
127127
}

supervisor/shared/filesystem.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,7 @@ bool filesystem_init(bool create_allowed, bool force_create) {
148148
res = f_mkdir(&circuitpy->fatfs, "/sd");
149149
#if CIRCUITPY_FULL_BUILD
150150
MAKE_FILE_WITH_OPTIONAL_CONTENTS(&circuitpy->fatfs, "/sd/placeholder.txt",
151-
"SD cards mounted at /sd will hide this file from Python."
152-
" SD cards are not visible via USB CIRCUITPY.\n");
151+
"SD cards mounted at /sd will hide this file from Python.\n");
153152
#endif
154153
#endif
155154

supervisor/shared/usb/usb_msc_flash.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ static bool ejected[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = true};
4545
static bool eject_once[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = false};
4646
static bool locked[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = false};
4747

48+
// Set to true if a write was in a file data or metadata area,
49+
// as opposed to in the filesystem metadata area (e.g., dirty bit).
50+
// Used to determine if an auto-reload is warranted.
51+
static bool content_write[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = false};
52+
4853
#include "tusb.h"
4954

5055
static const uint8_t usb_msc_descriptor_template[] = {
@@ -141,6 +146,7 @@ static fs_user_mount_t *get_vfs(int lun) {
141146
if (lun == SDCARD_LUN) {
142147
const char *path_under_mount;
143148
fs_user_mount_t *sdcard = filesystem_for_path("/sd", &path_under_mount);
149+
// If "/sd" is on the root filesystem, nothing has been mounted there.
144150
if (sdcard != root && (sdcard->blockdev.flags & MP_BLOCKDEV_FLAG_NATIVE) != 0) {
145151
return sdcard;
146152
} else {
@@ -290,34 +296,50 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *
290296
if (vfs == NULL) {
291297
return -1;
292298
}
299+
293300
disk_write(vfs, buffer, lba, block_count);
294301
// Since by getting here we assume the mount is read-only to
295-
// MicroPython let's update the cached FatFs sector if it's the one
302+
// CircuitPython let's update the cached FatFs sector if it's the one
296303
// we just wrote.
304+
if
297305
#if FF_MAX_SS != FF_MIN_SS
298-
if (vfs->fatfs.ssize == MSC_FLASH_BLOCK_SIZE) {
306+
(vfs->fatfs.ssize == MSC_FLASH_BLOCK_SIZE)
299307
#else
300308
// The compiler can optimize this away.
301-
if (FF_MAX_SS == FILESYSTEM_BLOCK_SIZE) {
302-
#endif
309+
(FF_MAX_SS == FILESYSTEM_BLOCK_SIZE)
310+
#endif
311+
{
303312
if (lba == vfs->fatfs.winsect && lba > 0) {
304313
memcpy(vfs->fatfs.win,
305314
buffer + MSC_FLASH_BLOCK_SIZE * (vfs->fatfs.winsect - lba),
306315
MSC_FLASH_BLOCK_SIZE);
307316
}
308317
}
309318

319+
// A write to an lba below fatbase is in the filesystem metadata (BPB) area or the "Reserved Region",
320+
// and is probably setting or clearing the dirty bit. This should not trigger auto-reload.
321+
// All other writes will trigger auto-reload.
322+
if (lba >= vfs->fatfs.fatbase) {
323+
content_write[lun] = true;
324+
}
325+
310326
return block_count * MSC_FLASH_BLOCK_SIZE;
311327
}
312328

313329
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
314330
// used to flush any pending cache.
315331
void tud_msc_write10_complete_cb(uint8_t lun) {
316-
(void)lun;
317-
318-
// This write is complete; initiate an autoreload.
319332
autoreload_resume(AUTORELOAD_SUSPEND_USB);
320-
autoreload_trigger();
333+
334+
// This write is complete; initiate an autoreload if this was a file data or metadata write,
335+
// not just a dirty-bit write.
336+
if (content_write[lun] &&
337+
// Fast path: lun == 0 is CIRCUITPY, which can always trigger auto-reload if enabled.
338+
// Don't autoreload if this lun was mounted by the user: that will cause a VM stop and an unmount.
339+
(lun == 0 || !gc_ptr_on_heap(get_vfs(lun)))) {
340+
autoreload_trigger();
341+
content_write[lun] = false;
342+
}
321343
}
322344

323345
// Invoked when received SCSI_CMD_INQUIRY
@@ -337,7 +359,7 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) {
337359
return false;
338360
}
339361

340-
#if CIRCUITPY_SDCARDIO
362+
#if CIRCUITPY_SDCARD_USB
341363
if (lun == SDCARD_LUN) {
342364
automount_sd_card();
343365
}

0 commit comments

Comments
 (0)