Skip to content

Commit 98c8f2f

Browse files
committed
atmel-samd: Update the FatFs sector cache on USB mass storage write
to the same sector. This fixes #20, the issue where a listdir or import won't work without a reset when it was run before the file was copied.
1 parent b8ef783 commit 98c8f2f

File tree

1 file changed

+34
-4
lines changed

1 file changed

+34
-4
lines changed

atmel-samd/access_vfs.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
* THE SOFTWARE.
2525
*/
2626

27+
#include <string.h>
28+
2729
#include "access_vfs.h"
2830

2931
#include "asf/common/services/usb/class/msc/device/udi_msc.h"
@@ -77,8 +79,20 @@ Ctrl_status vfs_read_capacity(uint32_t *last_valid_sector)
7779
//!
7880
bool vfs_wr_protect(void)
7981
{
80-
DSTATUS status = disk_status(VFS_INDEX);
81-
return status == STA_NOINIT || status == STA_PROTECT;
82+
if (VFS_INDEX >= MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) {
83+
return true;
84+
}
85+
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[VFS_INDEX];
86+
if (vfs == NULL) {
87+
return true;
88+
}
89+
90+
// This is used to determine the writeability of the disk from USB.
91+
if (vfs->writeblocks[0] == MP_OBJ_NULL ||
92+
(vfs->flags & FSUSER_USB_WRITEABLE) == 0) {
93+
return true;
94+
}
95+
return false;
8296
}
8397

8498
//! This function informs about the memory type
@@ -138,20 +152,36 @@ Ctrl_status vfs_usb_read_10(uint32_t addr, volatile uint16_t nb_sector)
138152
//! Not initialized or changed -> CTRL_BUSY
139153
//! An error occurred -> CTRL_FAIL
140154
//!
141-
Ctrl_status vfs_usb_write_10(uint32_t addr, uint16_t nb_sector)
155+
Ctrl_status vfs_usb_write_10(uint32_t addr, volatile uint16_t nb_sector)
142156
{
143157
uint8_t sector_buffer[FLASH_BLOCK_SIZE];
144158
for (uint16_t sector = 0; sector < nb_sector; sector++) {
145159
if (!udi_msc_trans_block(false, sector_buffer, FLASH_BLOCK_SIZE, NULL)) {
146160
return CTRL_FAIL; // transfer aborted
147161
}
148-
DRESULT result = disk_write(VFS_INDEX, sector_buffer, addr + sector, 1);
162+
uint32_t sector_address = addr + sector;
163+
DRESULT result = disk_write(VFS_INDEX, sector_buffer, sector_address, 1);
149164
if (result == RES_PARERR) {
150165
return CTRL_NO_PRESENT;
151166
}
152167
if (result == RES_ERROR) {
153168
return CTRL_FAIL;
154169
}
170+
// Since by getting here we assume the mount is read-only to MicroPython
171+
// lets update the cached FatFs sector if its the one we just wrote.
172+
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[VFS_INDEX];
173+
volatile uint16_t x = addr;
174+
(void) x;
175+
#if _MAX_SS != _MIN_SS
176+
if (vfs->ssize == FLASH_BLOCK_SIZE) {
177+
#else
178+
// The compiler can optimize this away.
179+
if (_MAX_SS == FLASH_BLOCK_SIZE) {
180+
#endif
181+
if (sector_address == vfs->fatfs.winsect && sector_address > 0) {
182+
memcpy(vfs->fatfs.win, sector_buffer, FLASH_BLOCK_SIZE);
183+
}
184+
}
155185
}
156186
return CTRL_GOOD;
157187
}

0 commit comments

Comments
 (0)