summaryrefslogtreecommitdiff
path: root/atmel-samd
diff options
context:
space:
mode:
Diffstat (limited to 'atmel-samd')
-rw-r--r--atmel-samd/Makefile13
-rw-r--r--atmel-samd/access_vfs.c49
-rw-r--r--atmel-samd/builtin_open.c30
-rw-r--r--atmel-samd/common-hal/audioio/AudioOut.c1
-rw-r--r--atmel-samd/fatfs_port.c15
-rw-r--r--atmel-samd/flash_api.c12
-rw-r--r--atmel-samd/flash_api.h2
-rw-r--r--atmel-samd/internal_flash.c5
-rw-r--r--atmel-samd/main.c67
-rw-r--r--atmel-samd/moduos.c291
-rw-r--r--atmel-samd/mpconfigport.h11
-rw-r--r--atmel-samd/mphalport.h2
-rw-r--r--atmel-samd/spi_flash.c5
13 files changed, 117 insertions, 386 deletions
diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile
index fbd89cc5a..43312fc56 100644
--- a/atmel-samd/Makefile
+++ b/atmel-samd/Makefile
@@ -125,7 +125,7 @@ CFLAGS_CORTEX_M0 = \
-DCIRCUITPY_CANARY_WORD=0xADAF00 \
-DCIRCUITPY_SAFE_RESTART_WORD=0xDEADBEEF \
--param max-inline-insns-single=500
-CFLAGS = $(INC) -Wall -Werror -std=gnu11 -nostdlib $(CFLAGS_CORTEX_M0) $(COPT)
+CFLAGS = $(INC) -Wall -Werror -std=gnu11 -nostdlib $(CFLAGS_CORTEX_M0) $(CFLAGS_MOD) $(COPT)
#Debugging/Optimization
# TODO(tannewt): Figure out what NDEBUG does. Adding it to the debug build
@@ -184,7 +184,6 @@ SRC_C = \
access_vfs.c \
autoreload.c \
background.c \
- builtin_open.c \
fatfs_port.c \
flash_api.c \
main.c \
@@ -213,17 +212,15 @@ SRC_C = \
boards/$(BOARD)/board.c \
boards/$(BOARD)/pins.c \
freetouch/adafruit_ptc.c \
- lib/fatfs/ff.c \
- lib/fatfs/option/ccsbcs.c \
+ lib/oofatfs/ff.c \
+ lib/oofatfs/option/ccsbcs.c \
lib/timeutils/timeutils.c \
lib/utils/buffer_helper.c \
lib/utils/context_manager_helpers.c \
lib/utils/interrupt_char.c \
lib/utils/pyexec.c \
- lib/utils/pyhelp.c \
lib/utils/stdout_helpers.c \
lib/libc/string0.c \
- lib/mp-readline/builtin_input.c \
lib/mp-readline/readline.c
STM_SRC_C = $(addprefix stmhal/,\
@@ -261,14 +258,14 @@ SRC_COMMON_HAL = \
SRC_BINDINGS_ENUMS = \
digitalio/Direction.c \
digitalio/DriveMode.c \
- digitalio/Pull.c
+ digitalio/Pull.c \
+ help.c
SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
$(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
$(addprefix common-hal/, $(SRC_COMMON_HAL))
SRC_SHARED_MODULE = \
- help.c \
bitbangio/__init__.c \
bitbangio/I2C.c \
bitbangio/OneWire.c \
diff --git a/atmel-samd/access_vfs.c b/atmel-samd/access_vfs.c
index ecdc94e44..72b56526b 100644
--- a/atmel-samd/access_vfs.c
+++ b/atmel-samd/access_vfs.c
@@ -30,8 +30,11 @@
#include "autoreload.h"
#include "asf/common/services/usb/class/msc/device/udi_msc.h"
-#include "extmod/fsusermount.h"
-#include "lib/fatfs/diskio.h"
+#include "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
+#include "lib/oofatfs/ff.h"
+#include "lib/oofatfs/diskio.h"
+#include "lib/oofatfs/ffconf.h"
#include "py/mpconfig.h"
#include "py/mphal.h"
#include "py/mpstate.h"
@@ -47,15 +50,14 @@
//! An error occurred -> CTRL_FAIL
Ctrl_status vfs_test_unit_ready(void)
{
- if (VFS_INDEX >= MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) {
- return CTRL_FAIL;
- }
- DSTATUS status = disk_status(VFS_INDEX);
- if (status == STA_NOINIT) {
- return CTRL_NO_PRESENT;
+ mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
+ for (uint8_t i = 0; current_mount != NULL; i++) {
+ if (i == VFS_INDEX) {
+ return CTRL_GOOD;
+ }
+ current_mount = current_mount->next;
}
-
- return CTRL_GOOD;
+ return CTRL_NO_PRESENT;
}
//! This function returns the address of the last valid sector
@@ -81,13 +83,17 @@ Ctrl_status vfs_read_capacity(uint32_t *last_valid_sector)
//!
bool vfs_wr_protect(void)
{
- if (VFS_INDEX >= MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) {
- return true;
+ mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
+ for (uint8_t i = 0; current_mount != NULL; i++) {
+ if (i == VFS_INDEX) {
+ break;
+ }
+ current_mount = current_mount->next;
}
- fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[VFS_INDEX];
- if (vfs == NULL) {
+ if (current_mount == NULL) {
return true;
}
+ fs_user_mount_t *vfs = (fs_user_mount_t *) current_mount->obj;
// This is used to determine the writeability of the disk from USB.
if (vfs->writeblocks[0] == MP_OBJ_NULL ||
@@ -170,9 +176,18 @@ Ctrl_status vfs_usb_write_10(uint32_t addr, volatile uint16_t nb_sector)
}
// Since by getting here we assume the mount is read-only to MicroPython
// lets update the cached FatFs sector if its the one we just wrote.
- fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[VFS_INDEX];
- volatile uint16_t x = addr;
- (void) x;
+ mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
+ for (uint8_t i = 0; current_mount != NULL; i++) {
+ if (i == VFS_INDEX) {
+ break;
+ }
+ current_mount = current_mount->next;
+ }
+ if (current_mount == NULL) {
+ return CTRL_NO_PRESENT;
+ }
+ fs_user_mount_t *vfs = (fs_user_mount_t *) current_mount->obj;
+
#if _MAX_SS != _MIN_SS
if (vfs->ssize == FILESYSTEM_BLOCK_SIZE) {
#else
diff --git a/atmel-samd/builtin_open.c b/atmel-samd/builtin_open.c
deleted file mode 100644
index 697eec8ea..000000000
--- a/atmel-samd/builtin_open.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2013, 2014 Damien P. George
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "py/runtime.h"
-#include "extmod/vfs_fat_file.h"
-
-MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, fatfs_builtin_open);
diff --git a/atmel-samd/common-hal/audioio/AudioOut.c b/atmel-samd/common-hal/audioio/AudioOut.c
index 9fb1a6ebe..cd840b4f8 100644
--- a/atmel-samd/common-hal/audioio/AudioOut.c
+++ b/atmel-samd/common-hal/audioio/AudioOut.c
@@ -27,6 +27,7 @@
#include <stdint.h>
#include <string.h>
+#include "extmod/vfs_fat_file.h"
#include "py/gc.h"
#include "py/mperrno.h"
#include "py/runtime.h"
diff --git a/atmel-samd/fatfs_port.c b/atmel-samd/fatfs_port.c
index d47b9d6af..e1eba350a 100644
--- a/atmel-samd/fatfs_port.c
+++ b/atmel-samd/fatfs_port.c
@@ -26,19 +26,8 @@
#include "py/mphal.h"
#include "py/runtime.h"
-#include "lib/fatfs/ff.h" /* FatFs lower layer API */
-#include "lib/fatfs/diskio.h" /* FatFs lower layer API */
-
-const PARTITION VolToPart[MICROPY_FATFS_VOLUMES] = {
- {0, 1}, // Logical drive 0 ==> Physical drive 0, 1st partition
- {1, 0}, // Logical drive 1 ==> Physical drive 1 (auto detection)
- {2, 0}, // Logical drive 2 ==> Physical drive 2 (auto detection)
- {3, 0}, // Logical drive 3 ==> Physical drive 3 (auto detection)
- /*
- {0, 2}, // Logical drive 2 ==> Physical drive 0, 2nd partition
- {0, 3}, // Logical drive 3 ==> Physical drive 0, 3rd partition
- */
-};
+#include "lib/oofatfs/ff.h" /* FatFs lower layer API */
+#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */
DWORD get_fattime(void) {
// TODO(tannewt): Support the RTC.
diff --git a/atmel-samd/flash_api.c b/atmel-samd/flash_api.c
index ab5de98fb..724d22e75 100644
--- a/atmel-samd/flash_api.c
+++ b/atmel-samd/flash_api.c
@@ -31,13 +31,17 @@
#define VFS_INDEX 0
void flash_set_usb_writeable(bool usb_writeable) {
- if (VFS_INDEX >= MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) {
- return;
+ mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
+ for (uint8_t i = 0; current_mount != NULL; i++) {
+ if (i == VFS_INDEX) {
+ break;
+ }
+ current_mount = current_mount->next;
}
- fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[VFS_INDEX];
- if (vfs == NULL) {
+ if (current_mount == NULL) {
return;
}
+ fs_user_mount_t *vfs = (fs_user_mount_t *) current_mount->obj;
if (usb_writeable) {
vfs->flags |= FSUSER_USB_WRITEABLE;
diff --git a/atmel-samd/flash_api.h b/atmel-samd/flash_api.h
index e40f1932b..91bf7dc8b 100644
--- a/atmel-samd/flash_api.h
+++ b/atmel-samd/flash_api.h
@@ -26,7 +26,7 @@
#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H__
#define __MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H__
-#include "extmod/fsusermount.h"
+#include "extmod/vfs_fat.h"
extern void flash_init_vfs(fs_user_mount_t *vfs);
extern void flash_flush(void);
diff --git a/atmel-samd/internal_flash.c b/atmel-samd/internal_flash.c
index 98dc92608..bd5963e11 100644
--- a/atmel-samd/internal_flash.c
+++ b/atmel-samd/internal_flash.c
@@ -28,11 +28,12 @@
#include <stdint.h>
#include <string.h>
+#include "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
#include "py/mphal.h"
#include "py/obj.h"
#include "py/runtime.h"
-#include "lib/fatfs/ff.h"
-#include "extmod/fsusermount.h"
+#include "lib/oofatfs/ff.h"
#include "asf/sam0/drivers/nvm/nvm.h"
#include "asf/sam0/drivers/port/port.h"
diff --git a/atmel-samd/main.c b/atmel-samd/main.c
index 563237a3c..1f3c3405c 100644
--- a/atmel-samd/main.c
+++ b/atmel-samd/main.c
@@ -9,11 +9,11 @@
#include "py/gc.h"
#include "py/stackctrl.h"
-#include "lib/fatfs/ff.h"
-#include "lib/fatfs/diskio.h"
+#include "extmod/vfs_fat.h"
+#include "lib/oofatfs/ff.h"
+#include "lib/oofatfs/diskio.h"
#include "lib/mp-readline/readline.h"
#include "lib/utils/pyexec.h"
-#include "extmod/fsusermount.h"
#include "asf/common/services/sleepmgr/sleepmgr.h"
#include "asf/common/services/usb/udc/udc.h"
@@ -48,6 +48,7 @@
#include "tick.h"
fs_user_mount_t fs_user_mount_flash;
+mp_vfs_mount_t mp_vfs_mount_flash;
typedef enum {
NO_SAFE_MODE = 0,
@@ -80,39 +81,42 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) {
// want it to be executed without using stack within main() function
void init_flash_fs(void) {
// init the vfs object
- fs_user_mount_t *vfs = &fs_user_mount_flash;
- vfs->str = "/flash";
- vfs->len = 6;
- vfs->flags = 0;
- flash_init_vfs(vfs);
-
- // put the flash device in slot 0 (it will be unused at this point)
- MP_STATE_PORT(fs_user_mount)[0] = vfs;
+ fs_user_mount_t *vfs_fat = &fs_user_mount_flash;
+ vfs_fat->flags = 0;
+ flash_init_vfs(vfs_fat);
// try to mount the flash
- FRESULT res = f_mount(&vfs->fatfs, vfs->str, 1);
+ FRESULT res = f_mount(&vfs_fat->fatfs);
if (res == FR_NO_FILESYSTEM) {
// no filesystem so create a fresh one
- res = f_mkfs("/flash", 0, 0);
+ uint8_t working_buf[_MAX_SS];
+ res = f_mkfs(&vfs_fat->fatfs, FM_FAT, 0, working_buf, sizeof(working_buf));
// Flush the new file system to make sure its repaired immediately.
flash_flush();
if (res != FR_OK) {
- MP_STATE_PORT(fs_user_mount)[0] = NULL;
return;
}
// set label
- f_setlabel("CIRCUITPY");
+ f_setlabel(&vfs_fat->fatfs, "CIRCUITPY");
} else if (res != FR_OK) {
- MP_STATE_PORT(fs_user_mount)[0] = NULL;
return;
}
+ mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
+ if (vfs == NULL) {
+ return;
+ }
+ vfs->str = "/";
+ vfs->len = 1;
+ vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
+ vfs->next = NULL;
+ MP_STATE_VM(vfs_mount_table) = vfs;
// The current directory is used as the boot up directory.
// It is set to the internal flash filesystem by default.
- f_chdrive("/flash");
+ MP_STATE_PORT(vfs_cur) = vfs;
}
static char heap[16384];
@@ -124,9 +128,7 @@ void reset_mp(void) {
// Sync the file systems in case any used RAM from the GC to cache. As soon
// as we re-init the GC all bets are off on the cache.
- disk_ioctl(0, CTRL_SYNC, NULL);
- disk_ioctl(1, CTRL_SYNC, NULL);
- disk_ioctl(2, CTRL_SYNC, NULL);
+ flash_flush();
// Clear the readline history. It references the heap we're about to destroy.
readline_init0();
@@ -230,13 +232,8 @@ void reset_samd21(void) {
}
bool maybe_run(const char* filename, pyexec_result_t* exec_result) {
- FILINFO fno;
-#if _USE_LFN
- fno.lfname = NULL;
- fno.lfsize = 0;
-#endif
- FRESULT res = f_stat(filename, &fno);
- if (res != FR_OK || fno.fattrib & AM_DIR) {
+ mp_import_stat_t stat = mp_import_stat(filename);
+ if (stat != MP_IMPORT_STAT_FILE) {
return false;
}
mp_hal_stdout_tx_str(filename);
@@ -607,7 +604,8 @@ int main(void) {
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
FIL file_pointer;
boot_output_file = &file_pointer;
- f_open(boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS);
+ f_open(&((fs_user_mount_t *) MP_STATE_VM(vfs_mount_table)->obj)->fatfs,
+ boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS);
#endif
// TODO(tannewt): Re-add support for flashing boot error output.
@@ -688,17 +686,8 @@ void gc_collect(void) {
gc_collect_end();
}
-mp_import_stat_t fat_vfs_import_stat(const char *path);
-mp_import_stat_t mp_import_stat(const char *path) {
- #if MICROPY_VFS_FAT
- return fat_vfs_import_stat(path);
- #else
- (void)path;
- return MP_IMPORT_STAT_NO_EXIST;
- #endif
-}
-
-void nlr_jump_fail(void *val) {
+void NORETURN nlr_jump_fail(void *val) {
+ while (1);
}
void NORETURN __fatal_error(const char *msg) {
diff --git a/atmel-samd/moduos.c b/atmel-samd/moduos.c
index f30d85ecd..cdc6325f2 100644
--- a/atmel-samd/moduos.c
+++ b/atmel-samd/moduos.c
@@ -32,11 +32,11 @@
#include "py/objstr.h"
#include "py/runtime.h"
#include "genhdr/mpversion.h"
-#include "lib/fatfs/ff.h"
-#include "lib/fatfs/diskio.h"
+#include "lib/oofatfs/ff.h"
+#include "lib/oofatfs/diskio.h"
+#include "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
#include "timeutils.h"
-#include "extmod/vfs_fat_file.h"
-#include "extmod/fsusermount.h"
/// \module os - basic "operating system" services
///
@@ -76,285 +76,42 @@ STATIC mp_obj_t os_uname(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname);
-/// \function chdir(path)
-/// Change current directory.
-STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
- const char *path;
- path = mp_obj_str_get_str(path_in);
-
- FRESULT res = f_chdrive(path);
-
- if (res == FR_OK) {
- res = f_chdir(path);
- }
-
- if (res != FR_OK) {
- // TODO should be mp_type_FileNotFoundError
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path));
- }
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_chdir_obj, os_chdir);
-
-/// \function getcwd()
-/// Get the current directory.
-STATIC mp_obj_t os_getcwd(void) {
- char buf[MICROPY_ALLOC_PATH_MAX + 1];
- FRESULT res = f_getcwd(buf, sizeof buf);
-
- if (res != FR_OK) {
- mp_raise_OSError(fresult_to_errno_table[res]);
- }
-
- return mp_obj_new_str(buf, strlen(buf), false);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd);
-
-/// \function listdir([dir])
-/// With no argument, list the current directory. Otherwise list the given directory.
-STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
- bool is_str_type = true;
- const char *path;
- if (n_args == 1) {
- if (mp_obj_get_type(args[0]) == &mp_type_bytes) {
- is_str_type = false;
- }
- path = mp_obj_str_get_str(args[0]);
- } else {
- path = "";
- }
-
- // "hack" to list root directory
- if (path[0] == '/' && path[1] == '\0') {
- mp_obj_t dir_list = mp_obj_new_list(0, NULL);
- for (size_t i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
- fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
- if (vfs != NULL) {
- mp_obj_list_append(dir_list, mp_obj_new_str(vfs->str + 1, vfs->len - 1, false));
- }
- }
- return dir_list;
- }
-
- return fat_vfs_listdir(path, is_str_type);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir);
-
-/// \function mkdir(path)
-/// Create a new directory.
-STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
- const char *path = mp_obj_str_get_str(path_o);
- FRESULT res = f_mkdir(path);
- switch (res) {
- case FR_OK:
- return mp_const_none;
- case FR_EXIST:
- // TODO should be FileExistsError
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "File exists: '%s'", path));
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error creating directory '%s'", path));
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
-
-/// \function remove(path)
-/// Remove a file.
-STATIC mp_obj_t os_remove(mp_obj_t path_o) {
- const char *path = mp_obj_str_get_str(path_o);
- // TODO check that path is actually a file before trying to unlink it
- FRESULT res = f_unlink(path);
- switch (res) {
- case FR_OK:
- return mp_const_none;
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing file '%s'", path));
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
-
-/// \function rename(old_path, new_path)
-/// Rename a file
-STATIC mp_obj_t os_rename(mp_obj_t path_in, mp_obj_t path_out) {
- const char *old_path = mp_obj_str_get_str(path_in);
- const char *new_path = mp_obj_str_get_str(path_out);
- FRESULT res = f_rename(old_path, new_path);
- switch (res) {
- case FR_OK:
- return mp_const_none;
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error renaming file '%s' to '%s'", old_path, new_path));
- }
-
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
-
-/// \function rmdir(path)
-/// Remove a directory.
-STATIC mp_obj_t os_rmdir(mp_obj_t path_o) {
- const char *path = mp_obj_str_get_str(path_o);
- // TODO check that path is actually a directory before trying to unlink it
- FRESULT res = f_unlink(path);
- switch (res) {
- case FR_OK:
- return mp_const_none;
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing directory '%s'", path));
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir);
-
-// Checks for path equality, ignoring trailing slashes:
-// path_equal(/, /) -> true
-// path_equal(/flash//, /flash) -> true
-// second argument must be in canonical form (meaning no trailing slash, unless it's just /)
-STATIC bool path_equal(const char *path, const char *path_canonical) {
- for (; *path_canonical != '\0' && *path == *path_canonical; ++path, ++path_canonical) {
- }
- if (*path_canonical != '\0') {
- return false;
- }
- for (; *path == '/'; ++path) {
- }
- return *path == '\0';
-}
-
-/// \function stat(path)
-/// Get the status of a file or directory.
-STATIC mp_obj_t os_stat(mp_obj_t path_in) {
- const char *path = mp_obj_str_get_str(path_in);
-
- FILINFO fno;
-#if _USE_LFN
- fno.lfname = NULL;
- fno.lfsize = 0;
-#endif
-
- FRESULT res;
- if (path_equal(path, "/")) {
- // stat root directory
- fno.fsize = 0;
- fno.fdate = 0;
- fno.ftime = 0;
- fno.fattrib = AM_DIR;
- } else {
- res = FR_NO_PATH;
- for (size_t i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
- fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
- if (vfs != NULL && path_equal(path, vfs->str)) {
- // stat mounted device directory
- fno.fsize = 0;
- fno.fdate = 0;
- fno.ftime = 0;
- fno.fattrib = AM_DIR;
- res = FR_OK;
- }
- }
- if (res == FR_NO_PATH) {
- // stat normal file
- res = f_stat(path, &fno);
- }
- if (res != FR_OK) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError,
- MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
- }
- }
-
- mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
- mp_int_t mode = 0;
- if (fno.fattrib & AM_DIR) {
- mode |= 0x4000; // stat.S_IFDIR
- } else {
- mode |= 0x8000; // stat.S_IFREG
- }
- mp_int_t seconds = timeutils_seconds_since_2000(
- 1980 + ((fno.fdate >> 9) & 0x7f),
- (fno.fdate >> 5) & 0x0f,
- fno.fdate & 0x1f,
- (fno.ftime >> 11) & 0x1f,
- (fno.ftime >> 5) & 0x3f,
- 2 * (fno.ftime & 0x1f)
- );
- t->items[0] = MP_OBJ_NEW_SMALL_INT(mode); // st_mode
- t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino
- t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev
- t->items[3] = MP_OBJ_NEW_SMALL_INT(0); // st_nlink
- t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid
- t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid
- t->items[6] = MP_OBJ_NEW_SMALL_INT(fno.fsize); // st_size
- t->items[7] = MP_OBJ_NEW_SMALL_INT(seconds); // st_atime
- t->items[8] = MP_OBJ_NEW_SMALL_INT(seconds); // st_mtime
- t->items[9] = MP_OBJ_NEW_SMALL_INT(seconds); // st_ctime
-
- return t;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
-
-STATIC mp_obj_t os_statvfs(mp_obj_t path_in) {
- const char *path = mp_obj_str_get_str(path_in);
-
- DWORD nclst;
- FATFS *fatfs;
- FRESULT res = f_getfree(path, &nclst, &fatfs);
- if (res != FR_OK) {
- goto error;
- }
-
- mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
-
- t->items[0] = MP_OBJ_NEW_SMALL_INT(fatfs->csize * 512); // f_bsize - block size
- t->items[1] = t->items[0]; // f_frsize - fragment size
- t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // f_blocks - total number of blocks
- t->items[3] = MP_OBJ_NEW_SMALL_INT(nclst); // f_bfree - number of free blocks
- t->items[4] = t->items[3]; // f_bavail - free blocks avail to unpriviledged users
- t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // f_files - # inodes
- t->items[6] = MP_OBJ_NEW_SMALL_INT(0); // f_ffree - # free inodes
- t->items[7] = MP_OBJ_NEW_SMALL_INT(0); // f_favail - # free inodes avail to unpriviledges users
- t->items[8] = MP_OBJ_NEW_SMALL_INT(0); // f_flags
- t->items[9] = MP_OBJ_NEW_SMALL_INT(_MAX_LFN); // f_namemax
-
- return t;
-
-error:
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_statvfs_obj, os_statvfs);
-
/// \function sync()
/// Sync all filesystems.
STATIC mp_obj_t os_sync(void) {
- disk_ioctl(0, CTRL_SYNC, NULL);
- disk_ioctl(1, CTRL_SYNC, NULL);
- disk_ioctl(2, CTRL_SYNC, NULL);
+ for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
+ // this assumes that vfs->obj is fs_user_mount_t with block device functions
+ disk_ioctl(MP_OBJ_TO_PTR(vfs->obj), CTRL_SYNC, NULL);
+ }
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(mod_os_sync_obj, os_sync);
-STATIC const mp_map_elem_t os_module_globals_table[] = {
+STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uos) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_uname), (mp_obj_t)&os_uname_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_uname), MP_ROM_PTR(&os_uname_obj) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&os_chdir_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&os_getcwd_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_rename),(mp_obj_t)&os_rename_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_rmdir_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_statvfs), (mp_obj_t)&os_statvfs_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
+ { MP_OBJ_NEW_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mp_vfs_rename_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&mp_vfs_remove_obj) }, // unlink aliases to remove
- { MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&mod_os_sync_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mod_os_sync_obj) },
/// \constant sep - separation character used in paths
{ MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) },
// these are MicroPython extensions
- { MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&fsuser_mount_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_umount), (mp_obj_t)&fsuser_umount_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mkfs), (mp_obj_t)&fsuser_mkfs_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },
};
STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
diff --git a/atmel-samd/mpconfigport.h b/atmel-samd/mpconfigport.h
index 926bff72b..b6175edb9 100644
--- a/atmel-samd/mpconfigport.h
+++ b/atmel-samd/mpconfigport.h
@@ -38,6 +38,10 @@
#define MICROPY_PY_BUILTINS_BYTEARRAY (1)
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
#define MICROPY_PY_BUILTINS_ENUMERATE (1)
+#define MICROPY_PY_BUILTINS_HELP (1)
+#define MICROPY_PY_BUILTINS_HELP_MODULES (1)
+#define MICROPY_PY_BUILTINS_HELP_TEXT circuitpython_help_text
+#define MICROPY_PY_BUILTINS_INPUT (1)
#define MICROPY_PY_BUILTINS_FILTER (1)
#define MICROPY_PY_BUILTINS_SET (1)
#define MICROPY_PY_BUILTINS_SLICE (1)
@@ -69,13 +73,13 @@
#define MICROPY_FATFS_VOLUMES (4)
#define MICROPY_FATFS_MULTI_PARTITION (1)
#define MICROPY_FATFS_NUM_PERSISTENT (1)
-#define MICROPY_FSUSERMOUNT (1)
// Only enable this if you really need it. It allocates a byte cache of this
// size.
// #define MICROPY_FATFS_MAX_SS (4096)
#define FILESYSTEM_BLOCK_SIZE (512)
+#define MICROPY_VFS (1)
#define MICROPY_VFS_FAT (1)
#define MICROPY_PY_MACHINE (1)
#define MICROPY_MODULE_WEAK_LINKS (0)
@@ -85,7 +89,7 @@
#define MICROPY_USE_INTERNAL_PRINTF (1)
#define MICROPY_PY_SYS_STDFILES (1)
#define MICROPY_PY_IO_FILEIO (1)
-#define MICROPY_READER_FATFS (1)
+#define MICROPY_READER_VFS (1)
#define MICROPY_PERSISTENT_CODE_LOAD (1)
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
@@ -112,6 +116,9 @@ typedef long mp_off_t;
#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)
+#define mp_import_stat mp_vfs_import_stat
+#define mp_builtin_open_obj mp_vfs_open_obj
+
// extra built in names to add to the global namespace
#define MICROPY_PORT_BUILTINS \
{ MP_OBJ_NEW_QSTR(MP_QSTR_help), (mp_obj_t)&mp_builtin_help_obj }, \
diff --git a/atmel-samd/mphalport.h b/atmel-samd/mphalport.h
index 6c9392105..4848e1404 100644
--- a/atmel-samd/mphalport.h
+++ b/atmel-samd/mphalport.h
@@ -29,7 +29,7 @@
#include "py/obj.h"
-#include "lib/fatfs/ff.h"
+#include "lib/oofatfs/ff.h"
#define USB_RX_BUF_SIZE 128
diff --git a/atmel-samd/spi_flash.c b/atmel-samd/spi_flash.c
index a534d2dd9..7f3c8984c 100644
--- a/atmel-samd/spi_flash.c
+++ b/atmel-samd/spi_flash.c
@@ -30,11 +30,12 @@
#include "asf/sam0/drivers/sercom/spi/spi.h"
+#include "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
#include "py/gc.h"
#include "py/obj.h"
#include "py/runtime.h"
-#include "lib/fatfs/ff.h"
-#include "extmod/fsusermount.h"
+#include "lib/oofatfs/ff.h"
#include "rgb_led_status.h"
#include "shared_dma.h"