Skip to content

Commit 306c921

Browse files
committed
atmel-samd: Rework mass storage interaction with underlying block
storage to use micropython's VFS interface. This makes mass storage work with any VFS implementation rather than a single one.
1 parent 6fe8c7b commit 306c921

15 files changed

Lines changed: 506 additions & 111 deletions

File tree

atmel-samd/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ SRC_ASF = $(addprefix asf/sam0/,\
143143
)
144144

145145
SRC_C = \
146+
access_vfs.c \
146147
builtin_open.c \
147148
fatfs_port.c \
148149
main.c \
@@ -156,9 +157,8 @@ SRC_C = \
156157
modutime.c \
157158
mphalport.c \
158159
pin_named_pins.c \
159-
rom_fs.c \
160160
samdneopixel.c \
161-
storage.c \
161+
$(FLASH_IMPL) \
162162
asf/common/services/sleepmgr/samd/sleepmgr.c \
163163
asf/common/services/storage/ctrl_access/ctrl_access.c \
164164
asf/common/services/usb/class/cdc/device/udi_cdc.c \
Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,34 @@
2424
* THE SOFTWARE.
2525
*/
2626

27-
#include "rom_fs.h"
27+
#include "access_vfs.h"
2828

2929
#include "asf/common/services/usb/class/msc/device/udi_msc.h"
30-
#include "storage.h"
30+
#include "extmod/fsusermount.h"
31+
#include "lib/fatfs/diskio.h"
32+
#include "py/mpconfig.h"
33+
#include "py/mpstate.h"
34+
#include "py/misc.h"
35+
36+
#define VFS_INDEX 0
3137

3238
//! This function tests memory state, and starts memory initialization
3339
//! @return Ctrl_status
3440
//! It is ready -> CTRL_GOOD
3541
//! Memory unplug -> CTRL_NO_PRESENT
3642
//! Not initialized or changed -> CTRL_BUSY
3743
//! An error occurred -> CTRL_FAIL
38-
Ctrl_status rom_fs_test_unit_ready(void)
44+
Ctrl_status vfs_test_unit_ready(void)
3945
{
40-
return CTRL_GOOD;
46+
if (VFS_INDEX >= MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) {
47+
return CTRL_FAIL;
48+
}
49+
DSTATUS status = disk_status(VFS_INDEX);
50+
if (status == STA_NOINIT) {
51+
return CTRL_NO_PRESENT;
52+
}
53+
54+
return CTRL_GOOD;
4155
}
4256

4357
//! This function returns the address of the last valid sector
@@ -47,30 +61,38 @@ Ctrl_status rom_fs_test_unit_ready(void)
4761
//! Memory unplug -> CTRL_NO_PRESENT
4862
//! Not initialized or changed -> CTRL_BUSY
4963
//! An error occurred -> CTRL_FAIL
50-
Ctrl_status rom_fs_read_capacity(uint32_t *uint32_t_nb_sector)
64+
Ctrl_status vfs_read_capacity(uint32_t *uint32_t_nb_sector)
5165
{
52-
*uint32_t_nb_sector = storage_get_block_count();
66+
if (disk_ioctl(VFS_INDEX, GET_SECTOR_COUNT, uint32_t_nb_sector) != RES_OK) {
67+
return CTRL_FAIL;
68+
}
5369
return CTRL_GOOD;
5470
}
5571

5672
//! This function returns the write-protected mode
5773
//!
5874
//! @return true if the memory is protected
5975
//!
60-
bool rom_fs_wr_protect(void)
76+
bool vfs_wr_protect(void)
6177
{
62-
return false;
78+
DSTATUS status = disk_status(VFS_INDEX);
79+
return status == STA_NOINIT || status == STA_PROTECT;
6380
}
6481

6582
//! This function informs about the memory type
6683
//!
6784
//! @return true if the memory is removable
6885
//!
69-
bool rom_fs_removal(void)
86+
bool vfs_removal(void)
7087
{
7188
return true;
7289
}
7390

91+
bool vfs_unload(bool unload)
92+
{
93+
return unload;
94+
}
95+
7496
// TODO(tannewt): Transfer more than a single sector at a time if we need more
7597
// speed.
7698
//! This function transfers the memory data to the USB MSC interface
@@ -84,11 +106,17 @@ bool rom_fs_removal(void)
84106
//! Not initialized or changed -> CTRL_BUSY
85107
//! An error occurred -> CTRL_FAIL
86108
//!
87-
Ctrl_status rom_fs_usb_read_10(uint32_t addr, volatile uint16_t nb_sector)
109+
Ctrl_status vfs_usb_read_10(uint32_t addr, volatile uint16_t nb_sector)
88110
{
89111
uint8_t sector_buffer[FLASH_BLOCK_SIZE];
90112
for (uint16_t sector = 0; sector < nb_sector; sector++) {
91-
storage_read_block(sector_buffer, addr + sector);
113+
DRESULT result = disk_read(VFS_INDEX, sector_buffer, addr + sector, 1);
114+
if (result == RES_PARERR) {
115+
return CTRL_NO_PRESENT;
116+
}
117+
if (result == RES_ERROR) {
118+
return CTRL_FAIL;
119+
}
92120
if (!udi_msc_trans_block(true, sector_buffer, FLASH_BLOCK_SIZE, NULL)) {
93121
return CTRL_FAIL; // transfer aborted
94122
}
@@ -108,14 +136,18 @@ Ctrl_status rom_fs_usb_read_10(uint32_t addr, volatile uint16_t nb_sector)
108136
//! Not initialized or changed -> CTRL_BUSY
109137
//! An error occurred -> CTRL_FAIL
110138
//!
111-
Ctrl_status rom_fs_usb_write_10(uint32_t addr, uint16_t nb_sector)
139+
Ctrl_status vfs_usb_write_10(uint32_t addr, uint16_t nb_sector)
112140
{
113141
uint8_t sector_buffer[FLASH_BLOCK_SIZE];
114142
for (uint16_t sector = 0; sector < nb_sector; sector++) {
115143
if (!udi_msc_trans_block(false, sector_buffer, FLASH_BLOCK_SIZE, NULL)) {
116144
return CTRL_FAIL; // transfer aborted
117145
}
118-
if (!storage_write_block(sector_buffer, addr + sector)) {
146+
DRESULT result = disk_write(VFS_INDEX, sector_buffer, addr + sector, 1);
147+
if (result == RES_PARERR) {
148+
return CTRL_NO_PRESENT;
149+
}
150+
if (result == RES_ERROR) {
119151
return CTRL_FAIL;
120152
}
121153
}
Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,20 @@
2424
* THE SOFTWARE.
2525
*/
2626

27+
// This adapts the ASF access API to MicroPython's VFS API so we can expose all
28+
// VFS block devices as Lun's over USB mass storage control.
29+
2730
#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_ROM_FS_H__
2831
#define __MICROPY_INCLUDED_ATMEL_SAMD_ROM_FS_H__
2932

3033
#include "asf/common/services/storage/ctrl_access/ctrl_access.h"
3134

32-
33-
Ctrl_status rom_fs_test_unit_ready(void);
34-
Ctrl_status rom_fs_read_capacity(uint32_t *u32_nb_sector);
35-
bool rom_fs_wr_protect(void);
36-
bool rom_fs_removal(void);
37-
Ctrl_status rom_fs_usb_read_10(uint32_t addr, uint16_t nb_sector);
38-
Ctrl_status rom_fs_usb_write_10(uint32_t addr, uint16_t nb_sector);
35+
Ctrl_status vfs_test_unit_ready(void);
36+
Ctrl_status vfs_read_capacity(uint32_t *u32_nb_sector);
37+
bool vfs_wr_protect(void);
38+
bool vfs_removal(void);
39+
bool vfs_unload(bool);
40+
Ctrl_status vfs_usb_read_10(uint32_t addr, uint16_t nb_sector);
41+
Ctrl_status vfs_usb_write_10(uint32_t addr, uint16_t nb_sector);
3942

4043
#endif // __MICROPY_INCLUDED_ATMEL_SAMD_ROM_FS_H__

atmel-samd/boards/arduino_zero/conf_access.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,15 @@
6868
/*! \name LUN 0 Definitions
6969
*/
7070
//! @{
71-
#define LUN_0_INCLUDE "rom_fs.h"
72-
#define Lun_0_test_unit_ready rom_fs_test_unit_ready
73-
#define Lun_0_read_capacity rom_fs_read_capacity
74-
#define Lun_0_unload NULL /* Can not be unloaded */
75-
#define Lun_0_wr_protect rom_fs_wr_protect
76-
#define Lun_0_removal rom_fs_removal
77-
#define Lun_0_usb_read_10 rom_fs_usb_read_10
78-
#define Lun_0_usb_write_10 rom_fs_usb_write_10
79-
#define LUN_0_NAME "\"On-Chip ROM\""
71+
#define LUN_0_INCLUDE "access_vfs.h"
72+
#define Lun_0_test_unit_ready vfs_test_unit_ready
73+
#define Lun_0_read_capacity vfs_read_capacity
74+
#define Lun_0_unload NULL
75+
#define Lun_0_wr_protect vfs_wr_protect
76+
#define Lun_0_removal vfs_removal
77+
#define Lun_0_usb_read_10 vfs_usb_read_10
78+
#define Lun_0_usb_write_10 vfs_usb_write_10
79+
#define LUN_0_NAME "\"MicroPython VFS[0]\""
8080
//! @}
8181

8282
#define MEM_USB LUN_USB
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
LD_FILE = boards/samd21x18-bootloader.ld
22
USB_VID = 0x2341
33
USB_PID = 0x824D
4+
5+
FLASH_IMPL = internal_flash.c
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
LD_FILE = boards/samd21x18-bootloader.ld
22
USB_VID = 0x239A
33
USB_PID = 0x8015
4+
5+
FLASH_IMPL = internal_flash.c

0 commit comments

Comments
 (0)