8000 rp2: MSC exclusive access support. · micropython/micropython@f22cf66 · GitHub
[go: up one dir, main page]

Skip to content

Commit f22cf66

Browse files
committed
rp2: MSC exclusive access support.
1 parent e22b7fb commit f22cf66

File tree

6 files changed

+56
-6
lines changed

6 files changed

+56
-6
lines changed

extmod/vfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#define MP_BLOCKDEV_IOCTL_BLOCK_COUNT (4)
5252
#define MP_BLOCKDEV_IOCTL_BLOCK_SIZE (5)
5353
#define MP_BLOCKDEV_IOCTL_BLOCK_ERASE (6)
54+
#define MP_BLOCKDEV_IOCTL_STATUS (7)
5455

5556
// At the moment the VFS protocol just has import_stat, but could be extended to other methods
5657
typedef struct _mp_vfs_proto_t {

extmod/vfs_fat_diskio.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ DRESULT disk_ioctl(
114114
[GET_SECTOR_COUNT] = MP_BLOCKDEV_IOCTL_BLOCK_COUNT,
115115
[GET_SECTOR_SIZE] = MP_BLOCKDEV_IOCTL_BLOCK_SIZE,
116116
[IOCTL_INIT] = MP_BLOCKDEV_IOCTL_INIT,
117+
[IOCTL_STATUS] = MP_BLOCKDEV_IOCTL_STATUS,
117118
};
118119
uint8_t bp_op = op_map[cmd & 7];
119120
mp_obj_t ret = mp_const_none;
@@ -147,8 +148,7 @@ DRESULT disk_ioctl(
147148
*((DWORD *)buff) = 1; // erase block size in units of sector size
148149
return RES_OK;
149150

150-
case IOCTL_INIT:
151-
case IOCTL_STATUS: {
151+
case IOCTL_INIT: {
152152
DSTATUS stat;
153153
if (ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE(ret) != 0) {
154154
// error initialising
@@ -162,6 +162,16 @@ DRESULT disk_ioctl(
162162
return RES_OK;
163163
}
164164

165+
case IOCTL_STATUS: {
166+
DSTATUS stat = 0;
167+
if (vfs->blockdev.writeblocks[0] == MP_OBJ_NULL ||
168+
(ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE(ret) != 0)) {
169+
stat = STA_PROTECT;
170+
}
171+
*((DSTATUS *)buff) = stat;
172+
return RES_OK;
173+
}
174+
165175
default:
166176
return RES_PARERR;
167177
}

ports/rp2/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
#if MICROPY_HW_USB_MSC
117117
#define MICROPY_FATFS_USE_LABEL (1)
118118
#define MICROPY_FATFS_MULTI_PARTITION (1)
119+
#define MICROPY_HW_USB_MSC_EXCLUSIVE_ACCESS (1)
119120
// Set FatFS block size to flash sector size to avoid caching
120121
// the flash sector in memory to support smaller block sizes.
121122
#define MICROPY_FATFS_MAX_SS (FLASH_SECTOR_SIZE)

ports/rp2/msc_disk.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
#define FLASH_BASE_ADDR (PICO_FLASH_SIZE_BYTES - MICROPY_HW_FLASH_STORAGE_BYTES)
4040
#define FLASH_MMAP_ADDR (XIP_BASE + FLASH_BASE_ADDR)
4141

42-
static bool ejected = false;
42+
bool tud_msc_ejected = false;
43+
extern void tud_msc_remount(void);
4344

4445
// Invoked when received SCSI_CMD_INQUIRY
4546
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
@@ -56,7 +57,7 @@ void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16
5657
// Invoked when received Test Unit Ready command.
5758
// return true allowing host to read/write this LUN e.g SD card inserted
5859
bool tud_msc_test_unit_ready_cb(uint8_t lun) {
59-
if (ejected) {
60+
if (tud_msc_ejected) {
6061
tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00);
6162
return false;
6263
}
@@ -77,10 +78,13 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, boo
7778
if (load_eject) {
7879
if (start) {
7980
// load disk storage
80-
ejected = false;
81+
tud_msc_ejected = false;
8182
} else {
8283
// unload disk storage
83-
ejected = true;
84+
tud_msc_ejected = true;
85+
#if MICROPY_HW_USB_MSC_EXCLUSIVE_ACCESS
86+
tud_msc_remount();
87+
#endif
8488
}
8589
}
8690
return true;

ports/rp2/rp2_flash.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
#define MICROPY_HW_FLASH_STORAGE_BASE (PICO_FLASH_SIZE_BYTES - MICROPY_HW_FLASH_STORAGE_BYTES)
4343
#endif
4444

45+
extern bool tud_msc_ejected;
46+
4547
static_assert(MICROPY_HW_FLASH_STORAGE_BYTES <= PICO_FLASH_SIZE_BYTES, "MICROPY_HW_FLASH_STORAGE_BYTES too big");
4648
static_assert(MICROPY_HW_FLASH_STORAGE_BASE + MICROPY_HW_FLASH_STORAGE_BYTES <= PICO_FLASH_SIZE_BYTES, "MICROPY_HW_FLASH_STORAGE_BYTES too big");
4749

@@ -137,6 +139,12 @@ STATIC mp_obj_t rp2_flash_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg_
137139
// TODO check return value
138140
return MP_OBJ_NEW_SMALL_INT(0);
139141
}
142+
case MP_BLOCKDEV_IOCTL_STATUS:
143+
#if MICROPY_HW_USB_MSC
144+
return MP_OBJ_NEW_SMALL_INT(!tud_msc_ejected);
145+
#else
146+
return MP_OBJ_NEW_SMALL_INT(false);
147+
#endif
140148
default:
141149
return mp_const_none;
142150
}

shared/runtime/tinyusb_helpers.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,29 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
5252
}
5353

5454
#endif
55+
56+
#if MICROPY_HW_USB_MSC_EXCLUSIVE_ACCESS
57+
#include "tusb.h"
58+
#include "extmod/vfs.h"
59+
static mp_sched_node_t mp_remount_sched_node;
60+
61+
STATIC void tud_msc_remount_task(mp_sched_node_t *node) {
62+
mp_vfs_mount_t *vfs = NULL;
63+
for (vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
64+
if (vfs->len == 1) {
65+
nlr_buf_t nlr;
66+
if (nlr_push(&nlr) == 0) {
67+
mp_vfs_umount(vfs->obj);
68+
nlr_pop();
69+
}
70+
mp_obj_t path = mp_obj_new_str(vfs->str, strlen(vfs->str));
71+
mp_vfs_mount_and_chdir_protected(vfs->obj, path);
72+
break;
73+
}
74+
}
75+
}
76+
77+
void tud_msc_remount(void) {
78+
mp_sched_schedule_node(&mp_remount_sched_node, tud_msc_remount_task);
79+
}
80+
#endif

0 commit comments

Comments
 (0)
0