8000 mimxrt: Add a simple mimxrt.usb_mode() method. · micropython/micropython@43f8bae · GitHub
[go: up one dir, main page]

Skip to content

Commit 43f8bae

Browse files
committed
mimxrt: Add a simple mimxrt.usb_mode() method.
To enble/disable MSC at boot time. The calls are a simplified version if pyb.usb_mode(): mimxrt.usb_mode(modestr) with modestr being either "vcp" or "vcp+msc". The call has to be placed in boot.py and requires a hard reset to get effective, since tusb_init() is executed only once after reset.
1 parent f88d611 commit 43f8bae

File tree

5 files changed

+88
-27
lines changed

5 files changed

+88
-27
lines changed

docs/mimxrt/quickref.rst

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,36 @@ port and LAN(1) for the 1G port.
537537

538538
For details of the network interface refer to the class :ref:`network.LAN <network.LAN>`.
539539

540+
541+
External drive mode
542+
-------------------
543+
544+
On some boards a mode is enabled, that mounts the board's internal file system as
545+
external USB drive, called MSC support. Data of that drive can be accessed and changed by the PC.
546+
In that state, access to the internal drive by the MicroPython is limited to
547+
readonly mode, avoiding file corruption. Changes made by the PC to the file system may not be visible
548+
at the board until the drive is ejected by the PC or a soft reset of the board
549+
is made.
550+
551+
To enable write access to by the board, eject the drive at the PC **and** perform
552+
a soft-reset on the board, either by pushing Ctrl-D at REPL or calling machine.soft_reset().
553+
554+
The external drive mode can be enabled of disabled by calling mimxrt.usb_mode(). Examples::
555+
556+
# disable MSC support
557+
import mimxrt
558+
mimxrt.usb_mode("vcp")
559+
560+
::
561+
562+
# enable MSC support
563+
import mimxrt
564+
mimxrt.usb_mode("vcp+msc") # enable VCP and MSC support
565+
566+
These command must be placed into boot.py. They get effective after the next hard reset or
567+
power cycle.
568+
569+
540570
Transferring files
541571
------------------
542572

ports/mimxrt/main.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,15 @@ int main(void) {
8585
// Execute _boot.py to set up the filesystem.
8686
pyexec_frozen_module("_boot.py");
8787

88-
// deferred tusb_init allowing a fs to be created before MSC access
89-
if (!tusb_inited()) {
90-
tusb_init();
91-
}
92-
9388
// Execute user scripts.
9489
int ret = pyexec_file_if_exists("boot.py");
9590
if (ret & PYEXEC_FORCED_EXIT) {
9691
goto soft_reset_exit;
9792
}
93+
94+
// deferred tusb_init allowing a fs to be created before MSC access
95+
tusb_init();
96+
9897
// Do not execute main.py if boot.py failed
9998
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL && ret != 0) {
10099
ret = pyexec_file_if_exists("main.py");

ports/mimxrt/modmimxrt.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,35 @@
2929
#include "drivers/dht/dht.h"
3030
#include "modmimxrt.h"
3131

32+
#if MICROPY_HW_USB_MSC
33+
34+
#define USB_MODE_VCP "vcp"
35+
#define USB_MODE_VCP_MSC "vcp+msc"
36+
37+
extern void set_msc_enabled(bool state);
38+
39+
STATIC mp_obj_t mimxrt_usb_mode(mp_obj_t mode_in) {
40+
size_t slen;
41+
const char *s = mp_obj_str_get_data(mode_in, &slen);
42+
if (strncmp(s, USB_MODE_VCP, slen) == 0) {
43+
set_msc_enabled(false);
44+
} else if (strncmp(s, USB_MODE_VCP_MSC, slen) == 0) {
45+
set_msc_enabled(true);
46+
} else {
47+
mp_raise_ValueError("Invalid usb_mode");
48+
}
49+
return mp_const_none;
50+
}
51+
MP_DEFINE_CONST_FUN_OBJ_1(mimxrt_usb_mode_obj, mimxrt_usb_mode);
52+
#endif
53+
3254
STATIC const mp_rom_map_elem_t mimxrt_module_globals_table[] = {
3355
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_mimxrt) },
3456
{ MP_ROM_QSTR(MP_QSTR_Flash), MP_ROM_PTR(&mimxrt_flash_type) },
3557

36-
{ MP_ROM_QSTR(MP_QSTR_dht_readinto), MP_ROM_PTR(&dht_readinto_obj) },
58+
{ MP_ROM_QSTR(MP_QSTR_dht_readinto), MP_ROM_PTR(&dht_readinto_obj) },
3759
#if MICROPY_HW_USB_MSC
60+
{ MP_ROM_QSTR(MP_QSTR_usb_mode), MP_ROM_PTR(&mimxrt_usb_mode_obj) },
3861
{ MP_ROM_QSTR(MP_QSTR_MSC), MP_ROM_INT(1) },
3962
#endif
4063
};

ports/mimxrt/modules/_boot.py

Lines changed: 10 additions & 11 deletions
50
Original file line numberDiff line numberDiff line change
@@ -25,28 +25,27 @@ def fs_type(bdev):
2525

2626
bdev = mimxrt.Flash()
2727

28-
# In case of MSC support mount as FAT
29-
# Create a FAT FS if needed
30-
if hasattr(mimxrt, "MSC"):
28+
# try to mount the fs accorfing to the boot sector
29+
# if that fails, (re-)create it with a preference for FAT on
30+
# boards with MSC support.
31+
fs = fs_type(bdev)
32+
33+
if fs == FS_FAT or (fs == FS_UNDEF and hasattr(mimxrt, "MSC")):
3134
try:
3235
vfs = os.VfsFat(bdev)
3336
os.mount(vfs, "/flash")
3437
except:
3538
os.VfsFat.mkfs(bdev)
3639
vfs = os.VfsFat(bdev)
3740
os.mount(vfs, "/flash")
38-
# otherwise analyze the boot sector an mount accordingly
39-
# without a valid boot sector create a LFS file system
4041
else:
41-
fs = fs_type(bdev)
42-
if fs == FS_LITTLEFS:
42+
try:
4343
vfs = os.VfsLfs2(bdev, progsize=256)
44-
elif fs == FS_FAT:
45-
vfs = os.VfsFat(bdev)
46-
else:
44+
os.mount(vfs, "/flash")
45+
except:
4746
os.VfsLfs2.mkfs(bdev, progsize=256)
4847
vfs = os.VfsLfs2(bdev, progsize=256)
49-
os.mount(vfs, "/flash")
48+
os.mount(vfs, "/flash")
5049

51
os.chdir("/flash")
5251
sys.path.append("/flash")

ports/mimxrt/msc_disk.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,31 @@
3636

3737
uint8_t tud_msc_state = EJECTED;
3838

39+
static bool msc_enabled = false;
40+
3941
void update_msc_state(void) {
4042
if (tud_msc_state == TRANSIT) {
4143
tud_msc_state = EJECTED;
4244
}
4345
}
4446

47+
void set_msc_enabled(bool state) {
48+
msc_enabled = state;
49+
}
50+
4551
// Invoked when received SCSI_CMD_INQUIRY
4652
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
4753
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
48-
const char vid[] = "Micropy";
49-
const char pid[] = "Mass Storage";
50-
const char rev[] = "1.0";
54+
if (msc_enabled) {
55+
const char vid[] = "Micropy";
56+
const char pid[] = "Mass Storage";
57+
const char rev[] = "1.0";
5158

52-
strncpy((char *)vendor_id, vid, 8);
53-
strncpy((char *)product_id, pid, 16);
54-
strncpy((char *)product_rev, rev, 4);
55-
tud_msc_state = MOUNTED;
59+
strncpy((char *)vendor_id, vid, 8);
60+
strncpy((char *)product_id, pid, 16);
61+
strncpy((char *)product_rev, rev, 4);
62+
tud_msc_state = MOUNTED;
63+
}
5664
}
5765

5866
// Invoked when received Test Unit Ready command.
@@ -68,15 +76,17 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) {
6876
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
6977
// Application update block count and block size
7078
void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) {
71-
*block_size = BLOCK_SIZE;
72-
*block_count = BLOCK_COUNT;
79+
if (msc_enabled) {
80+
*block_size = BLOCK_SIZE;
81+
*block_count = BLOCK_COUNT;
82+
}
7383
}
7484

7585
// Invoked when received Start Stop Unit command
7686
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
7787
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
7888
bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) {
79-
if (load_eject) {
89+
if (load_eject && msc_enabled) {
8090
if (start) {
8191
// load disk storage
8292
tud_msc_state = MOUNTED;

0 commit comments

Comments
 (0)
0