8000 Merge pull request #10129 from tannewt/automount_sd · carlossless/circuitpython@1d51d95 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1d51d95

Browse files
authored
Merge pull request adafruit#10129 from tannewt/automount_sd
Automount SD cards
2 parents 71a023c + 2e41242 commit 1d51d95

File tree

16 files changed

+303
-66
lines changed

16 files changed

+303
-66
lines changed

docs/workflows.md

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,30 @@ The workflow APIs are documented here.
1919
These USB interfaces are enabled by default on boards with USB support. They are usable once the
2020
device has been plugged into a host.
2121

22-
### CIRCUITPY drive
22+
### Mass Storage
2323
CircuitPython exposes a standard mass storage (MSC) interface to enable file manipulation over a
24-
standard interface. This interface works underneath the file system at the block level so using it
25-
excludes other types of workflows from manipulating the file system at the same time.
24+
standard interface. (This is how USB drives work.) This interface works underneath the file system at
25+
the block level so using it excludes other types of workflows from manipulating the file system at
26+
the same time.
27+
28+
CircuitPython 10.x adds multiple Logical Units (LUNs) to the mass storage interface. This allows for
29+
multiple drives to be accessed and ejected independently.
30+
31+
#### CIRCUITPY drive
32+
The CIRCUITPY drive is the main drive that CircuitPython uses. It is writable by the host by default
33+
and read-only to CircuitPython. `storage.remount()` can be used to remount the drive to
34+
CircuitPython as read-write.
35+
36+
#### CPSAVES drive
37+
The board may also expose a CPSAVES drive. (This is based on the ``CIRCUITPY_SAVES_PARTITION_SIZE``
38+
setting in ``mpconfigboard.h``.) It is a portion of the main flash that is writable by CircuitPython
39+
by default. It is read-only to the host. `storage.remount()` can be used to remount the drive to the
40+
host as read-write.
41+
42+
#### SD card drive
43+
A few boards have SD card automounting. (This is based on the ``DEFAULT_SD`` settings in
44+
``mpconfigboard.h``.) The card is writable from CircuitPython by default and read-only to the host.
45+
`storage.remount()` can be used to remount the drive to the host as read-write.
2646

2747
### CDC serial
2848
CircuitPython exposes one CDC USB interface for CircuitPython serial. This is a standard serial

extmod/vfs.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@
4747
#include "extmod/vfs_posix.h"
4848
#endif
4949

50+
51+
#if CIRCUITPY_SDCARDIO
52+
#include "shared-module/sdcardio/__init__.h"
53+
#endif
54+
5055
// For mp_vfs_proxy_call, the maximum number of additional args that can be passed.
5156
// A fixed maximum size is used to avoid the need for a costly variable array.
5257
#define PROXY_MAX_ARGS (2)
@@ -67,6 +72,10 @@ mp_vfs_mount_t *mp_vfs_lookup_path(const char *path, const char **path_out) {
6772
// path is "" or "/" so return virtual root
6873
return MP_VFS_ROOT;
6974
}
75+
// CIRCUITPY-CHANGE: Try and automount the SD card.
76+
#if CIRCUITPY_SDCARDIO
77+
automount_sd_card();
78+
#endif
7079
for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
7180
size_t len = vfs->len - 1;
7281
if (len == 0) {
@@ -367,8 +376,18 @@ mp_obj_t mp_vfs_getcwd(void) {
367376
}
368377
MP_DEFINE_CONST_FUN_OBJ_0(mp_vfs_getcwd_obj, mp_vfs_getcwd);
369378

370-
// CIRCUITPY-CHANGE: accessible from shared-module/os/__init__.c
371-
mp_obj_t mp_vfs_ilistdir_it_iternext(mp_obj_t self_in) {
379+
typedef struct _mp_vfs_ilistdir_it_t {
380+
mp_obj_base_t base;
381+
mp_fun_1_t iternext;
382+
union {
383+
mp_vfs_mount_t *vfs;
384+
mp_obj_t iter;
385+
} cur;
386+
bool is_str;
387+
bool is_iter;
388+
} mp_vfs_ilistdir_it_t;
389+
390+
static mp_obj_t mp_vfs_ilistdir_it_iternext(mp_obj_t self_in) {
372391
mp_vfs_ilistdir_it_t *self = MP_OBJ_TO_PTR(self_in);
373392
if (self->is_iter) {
374393
// continue delegating to root dir

extmod/vfs.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,19 +94,6 @@ typedef struct _mp_vfs_mount_t {
9494
struct _mp_vfs_mount_t *next;
9595
} mp_vfs_mount_t;
9696

97-
// CIRCUITPY-CHANGE: allow outside use of ilistdir_it_iternext
98-
typedef struct _mp_vfs_ilistdir_it_t {
99-
mp_obj_base_t base;
100-
mp_fun_1_t iternext;
101-
union {
102-
mp_vfs_mount_t *vfs;
103-
mp_obj_t iter;
104-
} cur;
105-
bool is_str;
106-
bool is_iter;
107-
} mp_vfs_ilistdir_it_t;
108-
109-
mp_obj_t mp_vfs_ilistdir_it_iternext(mp_obj_t self_in);
11097
void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev);
11198
int mp_vfs_blockdev_read(mp_vfs_blockdev_t *self, size_t block_num, size_t num_blocks, uint8_t *buf);
11299
int mp_vfs_blockdev_read_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t block_off, size_t len, uint8_t *buf);

locale/circuitpython.pot

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ msgstr ""
8282
msgid "%q and %q contain duplicate pins"
8383
msgstr ""
8484

85-
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
85+
#: shared-bindings/audioio/AudioOut.c
8686
msgid "%q and %q must be different"
8787
msgstr ""
8888

@@ -154,7 +154,7 @@ msgstr ""
154154
msgid "%q length must be >= %d"
155155
msgstr ""
156156

157-
#: py/modsys.c py/objmodule.c py/runtime.c
157+
#: py/modsys.c py/runtime.c
158158
msgid "%q moved from %q to %q"
159159
msgstr ""
160160

@@ -789,7 +789,7 @@ msgid "Cannot record to a file"
789789
msgstr ""
790790

791791
#: shared-module/storage/__init__.c
792-
msgid "Cannot remount '/' when visible via USB."
79 111C 2+
msgid "Cannot remount path when visible via USB."
793793
msgstr ""
794794

795795
#: shared-bindings/digitalio/DigitalInOut.c

ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030
#define DEFAULT_DVI_BUS_BLUE_DN (&pin_GPIO18)
3131
#define DEFAULT_DVI_BUS_BLUE_DP (&pin_GPIO19)
3232

33+
#define DEFAULT_SD_SCK (&pin_GPIO34)
34+
#define DEFAULT_SD_MOSI (&pin_GPIO35)
35+
#define DEFAULT_SD_MISO (&pin_GPIO36)
36+
#define DEFAULT_SD_CS (&pin_GPIO39)
37+
#define DEFAULT_SD_CARD_DETECT (&pin_GPIO33)
38+
#define DEFAULT_SD_CARD_INSERTED true
39+
3340
#define CIRCUITPY_PSRAM_CHIP_SELECT (&pin_GPIO47)
3441

3542
// #define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO44)

ports/raspberrypi/boards/adafruit_metro_rp2350/mpconfigboard.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,10 @@
3535
#define DEFAULT_DVI_BUS_GREEN_DP (&pin_GPIO16)
3636
#define DEFAULT_DVI_BUS_BLUE_DN (&pin_GPIO13)
3737
#define DEFAULT_DVI_BUS_BLUE_DP (&pin_GPIO12)
38+
39+
#define DEFAULT_SD_SCK (&pin_GPIO34)
40+
#define DEFAULT_SD_MOSI (&pin_GPIO35)
41+
#define DEFAULT_SD_MISO (&pin_GPIO36)
42+
#define DEFAULT_SD_CS (&pin_GPIO39)
43+
#define DEFAULT_SD_CARD_DETECT (&pin_GPIO40)
44+
#define DEFAULT_SD_CARD_INSERTED false

shared-bindings/storage/__init__.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ MP_DEFINE_CONST_FUN_OBJ_1(storage_umount_obj, storage_umount);
9797
//| ) -> None:
9898
//| """Remounts the given path with new parameters.
9999
//|
100+
//| This can always be done from boot.py. After boot, it can only be done when the host computer
101+
//| doesn't have write access and CircuitPython isn't currently writing to the filesystem. An
102+
//| exception will be raised if this is the case. Some host OSes allow you to eject a drive which
103+
//| will allow for remounting.
104+
//|
105+
//| Remounting after USB is active may take a little time because it "ejects" the drive for one
106+
//| query from the host. These queries happen every second or so.
107+
//|
100108
//| :param str mount_path: The path to remount.
101109
//| :param bool readonly: True when the filesystem should be readonly to CircuitPython.
102110
//| :param bool disable_concurrent_write_protection: When True, the check that makes sure the

shared-module/os/__init__.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,21 +90,19 @@ mp_obj_t common_hal_os_getcwd(void) {
9090
mp_obj_t common_hal_os_listdir(const char *path) {
9191
mp_obj_t path_out;
9292
mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out);
93-
94-
mp_vfs_ilistdir_it_t iter;
95-
mp_obj_t iter_obj = MP_OBJ_FROM_PTR(&iter);
96-
9793
if (vfs == MP_VFS_ROOT) {
98-
// list the root directory
99-
iter.base.type = &mp_type_polymorph_iter;
100-
iter.iternext = mp_vfs_ilistdir_it_iternext;
101-
iter.cur.vfs = MP_STATE_VM(vfs_mount_table);
102-
iter.is_str = true;
103-
iter.is_iter = false;
104-
} else {
105-
iter_obj = mp_vfs_proxy_call(vfs, MP_QSTR_ilistdir, 1, &path_out);
94+
vfs = MP_STATE_VM(vfs_mount_table);
95+
while (vfs != NULL) {
96+
if (vfs->len == 1) {
97+
break;
98+
}
99+
vfs = vfs->next;
100+
}
101+
path_out = MP_OBJ_NEW_QSTR(MP_QSTR__slash_);
106102
}
107103

104+
mp_obj_t iter_obj = mp_vfs_proxy_call(vfs, MP_QSTR_ilistdir, 1, &path_out);
105+
108106
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
109107
mp_obj_t next;
110108
while ((next = mp_iternext(iter_obj)) != MP_OBJ_STOP_ITERATION) {

shared-module/sdcardio/SDCard.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ static mp_rom_error_text_t init_card(sdcardio_sdcard_obj_t *self) {
294294
return NULL;
295295
}
296296

297-
void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, const mcu_pin_obj_t *cs, int baudrate) {
297+
mp_rom_error_text_t sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, const mcu_pin_obj_t *cs, int baudrate) {
298298
self->bus = bus;
299299
common_hal_digitalio_digitalinout_construct(&self->cs, cs);
300300
common_hal_digitalio_digitalinout_switch_to_output(&self->cs, true, DRIVE_MODE_PUSH_PULL);
@@ -309,10 +309,19 @@ void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi
309309

310310
if (result != NULL) {
311311
common_hal_digitalio_digitalinout_deinit(&self->cs);
312-
mp_raise_OSError_msg(result);
312+
return result;
313313
}
314314

315315
self->baudrate = baudrate;
316+
return NULL;
317+
}
318+
319+
320+
void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, const mcu_pin_obj_t *cs, int baudrate) {
321+
mp_rom_error_text_t result = sdcardio_sdcard_construct(self, bus, cs, baudrate);
322+
if (result != NULL) {
323+
mp_raise_OSError_msg(result);
324+
}
316325
}
317326

318327
void common_hal_sdcardio_sdcard_deinit(sdcardio_sdcard_obj_t *self) {

shared-module/sdcardio/SDCard.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,5 @@ typedef struct {
2424
uint32_t next_block;
2525
bool in_cmd25;
2626
} sdcardio_sdcard_obj_t;
27+
28+
mp_rom_error_text_t sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, const mcu_pin_obj_t *cs, int baudrate);

0 commit comments

Comments
 (0)
0