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
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

5150
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy