diff options
| -rw-r--r-- | atmel-samd/Makefile | 1 | ||||
| -rw-r--r-- | atmel-samd/flash_api.c | 47 | ||||
| -rw-r--r-- | atmel-samd/flash_api.h | 4 | ||||
| -rw-r--r-- | atmel-samd/internal_flash.c | 2 | ||||
| -rw-r--r-- | atmel-samd/main.c | 73 | ||||
| -rw-r--r-- | atmel-samd/mpconfigport.h | 1 | ||||
| -rw-r--r-- | atmel-samd/mphalport.c | 7 | ||||
| -rw-r--r-- | atmel-samd/mphalport.h | 4 | ||||
| -rw-r--r-- | atmel-samd/spi_flash.c | 2 | ||||
| -rw-r--r-- | extmod/fsusermount.h | 6 |
10 files changed, 118 insertions, 29 deletions
diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile index f4fcbf9a3..0bf3cabd0 100644 --- a/atmel-samd/Makefile +++ b/atmel-samd/Makefile @@ -183,6 +183,7 @@ SRC_C = \ autoreload.c \ builtin_open.c \ fatfs_port.c \ + flash_api.c \ main.c \ moduos.c \ mphalport.c \ diff --git a/atmel-samd/flash_api.c b/atmel-samd/flash_api.c new file mode 100644 index 000000000..ab5de98fb --- /dev/null +++ b/atmel-samd/flash_api.c @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "flash_api.h" + +#include "py/mpstate.h" + +#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; + } + fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[VFS_INDEX]; + if (vfs == NULL) { + return; + } + + if (usb_writeable) { + vfs->flags |= FSUSER_USB_WRITEABLE; + } else { + vfs->flags &= ~FSUSER_USB_WRITEABLE; + } +} diff --git a/atmel-samd/flash_api.h b/atmel-samd/flash_api.h index 2847023d6..e40f1932b 100644 --- a/atmel-samd/flash_api.h +++ b/atmel-samd/flash_api.h @@ -26,7 +26,11 @@ #ifndef __MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H__ #define __MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H__ +#include "extmod/fsusermount.h" + extern void flash_init_vfs(fs_user_mount_t *vfs); extern void flash_flush(void); +void flash_set_usb_writeable(bool usb_writeable); + #endif // __MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H__ diff --git a/atmel-samd/internal_flash.c b/atmel-samd/internal_flash.c index f0ef921d2..98dc92608 100644 --- a/atmel-samd/internal_flash.c +++ b/atmel-samd/internal_flash.c @@ -293,7 +293,7 @@ const mp_obj_type_t internal_flash_type = { }; void flash_init_vfs(fs_user_mount_t *vfs) { - vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL | FSUSER_USB_WRITEABLE; + vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL; vfs->readblocks[0] = (mp_obj_t)&internal_flash_obj_readblocks_obj; vfs->readblocks[1] = (mp_obj_t)&internal_flash_obj; vfs->readblocks[2] = (mp_obj_t)internal_flash_read_blocks; // native version diff --git a/atmel-samd/main.c b/atmel-samd/main.c index 0dfd2d471..19c5575e6 100644 --- a/atmel-samd/main.c +++ b/atmel-samd/main.c @@ -86,11 +86,6 @@ void init_flash_fs(void) { if (res == FR_NO_FILESYSTEM) { // no filesystem so create a fresh one - // We are before USB initializes so temporarily undo the USB_WRITEABLE - // requirement. - bool usb_writeable = (vfs->flags & FSUSER_USB_WRITEABLE) > 0; - vfs->flags &= ~FSUSER_USB_WRITEABLE; - res = f_mkfs("/flash", 0, 0); // Flush the new file system to make sure its repaired immediately. flash_flush(); @@ -101,10 +96,6 @@ void init_flash_fs(void) { // set label f_setlabel("CIRCUITPY"); - - if (usb_writeable) { - vfs->flags |= FSUSER_USB_WRITEABLE; - } } else if (res != FR_OK) { MP_STATE_PORT(fs_user_mount)[0] = NULL; return; @@ -251,21 +242,13 @@ bool start_mp(void) { mp_hal_stdout_tx_str("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\r\n"); } #endif - - new_status_color(BOOT_RUNNING); - pyexec_result_t result; - bool found_boot = maybe_run("settings.txt", &result) || - maybe_run("settings.py", &result) || - maybe_run("boot.py", &result) || - maybe_run("boot.txt", &result); bool found_main = false; - if (!found_boot || !(result.return_code & PYEXEC_FORCED_EXIT)) { - new_status_color(MAIN_RUNNING); - found_main = maybe_run("code.txt", &result) || - maybe_run("code.py", &result) || - maybe_run("main.py", &result) || - maybe_run("main.txt", &result); - } + pyexec_result_t result; + new_status_color(MAIN_RUNNING); + found_main = maybe_run("code.txt", &result) || + maybe_run("code.py", &result) || + maybe_run("main.py", &result) || + maybe_run("main.txt", &result); reset_status_led(); if (result.return_code & PYEXEC_FORCED_EXIT) { @@ -520,6 +503,36 @@ int main(void) { // as current dir. init_flash_fs(); + // Reset everything and prep MicroPython to run boot.py. + reset_samd21(); + reset_mp(); + + // Run boot before initing USB and capture output in a file. + new_status_color(BOOT_RUNNING); + #ifdef CIRCUITPY_BOOT_OUTPUT_FILE + FIL file_pointer; + boot_output_file = &file_pointer; + FRESULT result = f_open(boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS); + if (result != FR_OK) { + while (true) {} + } + #endif + + // TODO(tannewt): Re-add support for flashing boot error output. + bool found_boot = maybe_run("settings.txt", NULL) || + maybe_run("settings.py", NULL) || + maybe_run("boot.py", NULL) || + maybe_run("boot.txt", NULL); + (void) found_boot; + + #ifdef CIRCUITPY_BOOT_OUTPUT_FILE + f_close(boot_output_file); + boot_output_file = NULL; + #endif + + // Turn off local writing in favor of USB writing prior to initializing USB. + flash_set_usb_writeable(true); + usb_hid_init(); // Start USB after getting everything going. @@ -527,14 +540,18 @@ int main(void) { udc_start(); #endif + // Reset to remove any state that boot.py setup. It should only be used to + // change internal state thats not in the heap. + reset_samd21(); + reset_mp(); - // Main script is finished, so now go into REPL mode. - // The REPL mode can change, or it can request a reload. + // Boot script is finished, so now go into REPL/main mode. int exit_code = PYEXEC_FORCED_EXIT; bool skip_repl = true; bool first_run = true; for (;;) { if (!skip_repl) { + // The REPL mode can change, or it can request a reload. autoreload_disable(); new_status_color(REPL_RUNNING); if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { @@ -542,15 +559,17 @@ int main(void) { } else { exit_code = pyexec_friendly_repl(); } + reset_samd21(); + reset_mp(); } if (exit_code == PYEXEC_FORCED_EXIT) { if (!first_run) { mp_hal_stdout_tx_str("soft reboot\r\n"); } - reset_samd21(); - reset_mp(); first_run = false; skip_repl = start_mp(); + reset_samd21(); + reset_mp(); } else if (exit_code != 0) { break; } diff --git a/atmel-samd/mpconfigport.h b/atmel-samd/mpconfigport.h index 48aa192cc..a43a68440 100644 --- a/atmel-samd/mpconfigport.h +++ b/atmel-samd/mpconfigport.h @@ -204,5 +204,6 @@ bool udi_msc_process_trans(void); #define MICROPY_VM_HOOK_RETURN udi_msc_process_trans(); #define CIRCUITPY_AUTORELOAD_DELAY_MS 500 +#define CIRCUITPY_BOOT_OUTPUT_FILE "/flash/boot_out.txt" #endif // __INCLUDED_MPCONFIGPORT_H diff --git a/atmel-samd/mphalport.c b/atmel-samd/mphalport.c index 827e585d2..0694c2b91 100644 --- a/atmel-samd/mphalport.c +++ b/atmel-samd/mphalport.c @@ -191,6 +191,13 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) { usart_write_buffer_wait(&usart_instance, (uint8_t*) str, len); #endif + #ifdef CIRCUITPY_BOOT_OUTPUT_FILE + if (boot_output_file != NULL) { + UINT bytes_written = 0; + f_write(boot_output_file, str, len, &bytes_written); + } + #endif + #ifdef USB_REPL // Always make sure there is enough room in the usb buffer for the outgoing // string. If there isn't we risk getting caught in a loop within the usb diff --git a/atmel-samd/mphalport.h b/atmel-samd/mphalport.h index e2185ae58..6c9392105 100644 --- a/atmel-samd/mphalport.h +++ b/atmel-samd/mphalport.h @@ -29,6 +29,8 @@ #include "py/obj.h" +#include "lib/fatfs/ff.h" + #define USB_RX_BUF_SIZE 128 // Global millisecond tick count (driven by SysTick interrupt). @@ -41,6 +43,8 @@ static inline mp_uint_t mp_hal_ticks_ms(void) { volatile uint8_t usb_rx_count; volatile bool mp_cdc_enabled; +FIL* boot_output_file; + int receive_usb(void); void mp_hal_set_interrupt_char(int c); diff --git a/atmel-samd/spi_flash.c b/atmel-samd/spi_flash.c index da986ecac..a534d2dd9 100644 --- a/atmel-samd/spi_flash.c +++ b/atmel-samd/spi_flash.c @@ -661,7 +661,7 @@ const mp_obj_type_t spi_flash_type = { }; void flash_init_vfs(fs_user_mount_t *vfs) { - vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL | FSUSER_USB_WRITEABLE; + vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL; vfs->readblocks[0] = (mp_obj_t)&spi_flash_obj_readblocks_obj; vfs->readblocks[1] = (mp_obj_t)&spi_flash_obj; vfs->readblocks[2] = (mp_obj_t)spi_flash_read_blocks; // native version diff --git a/extmod/fsusermount.h b/extmod/fsusermount.h index efc68a05d..abfd2d4e3 100644 --- a/extmod/fsusermount.h +++ b/extmod/fsusermount.h @@ -24,6 +24,10 @@ * THE SOFTWARE. */ + +#ifndef __MICROPY_INCLUDED_EXTMOD_FSUSERMOUNT_H__ +#define __MICROPY_INCLUDED_EXTMOD_FSUSERMOUNT_H__ + #include "lib/fatfs/ff.h" #include "py/obj.h" @@ -65,3 +69,5 @@ mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in); MP_DECLARE_CONST_FUN_OBJ_KW(fsuser_mount_obj); MP_DECLARE_CONST_FUN_OBJ_1(fsuser_umount_obj); MP_DECLARE_CONST_FUN_OBJ_KW(fsuser_mkfs_obj); + +#endif // __MICROPY_INCLUDED_EXTMOD_FSUSERMOUNT_H__ |
