From 7fd84e93f48438ddcff22941286e43df50cd15f0 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 15 Sep 2016 17:01:19 -0700 Subject: [PATCH] atmel-samd: Support raw repl and soft reset to support ampy. Closes #1. Also adds TX and RX led support on the Arduino Zero. --- atmel-samd/Makefile | 1 + atmel-samd/boards/arduino_zero/init.c | 24 ++++-- .../boards/arduino_zero/mpconfigboard.h | 3 + .../boards/feather_m0_bluefruit_le/init.c | 5 +- atmel-samd/main.c | 84 +++++++++++-------- atmel-samd/mphalport.c | 57 ++++++++----- 6 files changed, 108 insertions(+), 66 deletions(-) diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile index bd5bd1e1d1..1acd8f34ee 100644 --- a/atmel-samd/Makefile +++ b/atmel-samd/Makefile @@ -150,6 +150,7 @@ SRC_C = \ asf/sam0/utils/cmsis/samd21/source/gcc/startup_samd21.c \ asf/sam0/utils/cmsis/samd21/source/system_samd21.c \ asf/sam0/utils/syscalls/gcc/syscalls.c \ + boards/$(BOARD)/init.c \ boards/$(BOARD)/pins.c \ lib/fatfs/ff.c \ lib/fatfs/option/ccsbcs.c \ diff --git a/atmel-samd/boards/arduino_zero/init.c b/atmel-samd/boards/arduino_zero/init.c index 32fba3695e..af8b08ff7f 100644 --- a/atmel-samd/boards/arduino_zero/init.c +++ b/atmel-samd/boards/arduino_zero/init.c @@ -8,14 +8,24 @@ * Support and FAQ: visit Atmel Support */ -#include -#include -#include +#include "board.h" +#include "conf_board.h" +#include "mpconfigboard.h" +#include "asf/sam0/drivers/port/port.h" void board_init(void) { - /* This function is meant to contain board-specific initialization code - * for, e.g., the I/O pins. The initialization can rely on application- - * specific board configuration, found in conf_board.h. - */ + /* This function is meant to contain board-specific initialization code + * for, e.g., the I/O pins. The initialization can rely on application- + * specific board configuration, found in conf_board.h. + */ + struct port_config pin_conf; + port_get_config_defaults(&pin_conf); + + pin_conf.direction = PORT_PIN_DIR_OUTPUT; + port_pin_set_config(MICROPY_HW_LED_TX, &pin_conf); + port_pin_set_output_level(MICROPY_HW_LED_TX, true); + + port_pin_set_config(MICROPY_HW_LED_RX, &pin_conf); + port_pin_set_output_level(MICROPY_HW_LED_RX, true); } diff --git a/atmel-samd/boards/arduino_zero/mpconfigboard.h b/atmel-samd/boards/arduino_zero/mpconfigboard.h index 4a2723fc7b..fbebaed2d1 100644 --- a/atmel-samd/boards/arduino_zero/mpconfigboard.h +++ b/atmel-samd/boards/arduino_zero/mpconfigboard.h @@ -5,3 +5,6 @@ #define MICROPY_HW_BOARD_NAME "Arduino Zero" #define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_TX PIN_PA27 +#define MICROPY_HW_LED_RX PIN_PB03 diff --git a/atmel-samd/boards/feather_m0_bluefruit_le/init.c b/atmel-samd/boards/feather_m0_bluefruit_le/init.c index 32fba3695e..88608c0fbe 100644 --- a/atmel-samd/boards/feather_m0_bluefruit_le/init.c +++ b/atmel-samd/boards/feather_m0_bluefruit_le/init.c @@ -8,9 +8,8 @@ * Support and FAQ: visit Atmel Support */ -#include -#include -#include +#include "board.h" +#include "conf_board.h" void board_init(void) { diff --git a/atmel-samd/main.c b/atmel-samd/main.c index c4db134709..4b7cafd4db 100644 --- a/atmel-samd/main.c +++ b/atmel-samd/main.c @@ -19,6 +19,7 @@ #include "asf/sam0/drivers/port/port.h" #include "asf/sam0/drivers/sercom/usart/usart.h" #include "asf/sam0/drivers/system/system.h" +#include #include "mpconfigboard.h" #include "modmachine_pin.h" @@ -158,16 +159,7 @@ void init_flash_fs() { static char *stack_top; static char heap[8192]; -int main(int argc, char **argv) { - // initialise the cpu and peripherals - #if MICROPY_MIN_USE_SAMD21_MCU - void samd21_init(void); - samd21_init(); - #endif - - int stack_dummy; - stack_top = (char*)&stack_dummy; - +void reset_mp() { #if MICROPY_ENABLE_GC gc_init(heap, heap + sizeof(heap)); #endif @@ -176,11 +168,22 @@ int main(int argc, char **argv) { MP_STATE_PORT(mp_kbd_exception) = mp_obj_new_exception(&mp_type_KeyboardInterrupt); pin_init0(); +} + +int main(int argc, char **argv) { + // initialise the cpu and peripherals + #if MICROPY_MIN_USE_SAMD21_MCU + void samd21_init(void); + samd21_init(); + #endif // Initialise the local flash filesystem. // Create it if needed, mount in on /flash, and set it as current dir. init_flash_fs(); + int stack_dummy; + reset_mp(); + #if MICROPY_REPL_EVENT_DRIVEN pyexec_event_repl_init(); for (;;) { @@ -190,10 +193,24 @@ int main(int argc, char **argv) { } } #else - pyexec_friendly_repl(); + // Main script is finished, so now go into REPL mode. + // The REPL mode can change, or it can request a soft reset. + int exit_code = 0; + for (;;) { + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + exit_code = pyexec_raw_repl(); + } else { + exit_code = pyexec_friendly_repl(); + } + if (exit_code == PYEXEC_FORCED_EXIT) { + mp_hal_stdout_tx_str("soft reboot\r\n"); + stack_top = (char*)&stack_dummy; + reset_mp(); + } else if (exit_code != 0) { + break; + } + } #endif - //do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\\n')", MP_PARSE_SINGLE_INPUT); - //do_str("for i in range(10):\r\n print(i)", MP_PARSE_FILE_INPUT); mp_deinit(); return 0; } @@ -239,33 +256,34 @@ void MP_WEAK __assert_func(const char *file, int line, const char *func, const c struct usart_module usart_instance; void samd21_init(void) { + irq_initialize_vectors(); + cpu_irq_enable(); - irq_initialize_vectors(); - cpu_irq_enable(); + // Initialize the sleep manager + sleepmgr_init(); - // Initialize the sleep manager - sleepmgr_init(); + system_init(); - system_init(); + delay_init(); - delay_init(); + board_init(); - // Uncomment to init PIN_PA17 for debugging. - // struct port_config pin_conf; - // port_get_config_defaults(&pin_conf); - // - // pin_conf.direction = PORT_PIN_DIR_OUTPUT; - // port_pin_set_config(MICROPY_HW_LED1, &pin_conf); - // port_pin_set_output_level(MICROPY_HW_LED1, false); + // Uncomment to init PIN_PA17 for debugging. + // struct port_config pin_conf; + // port_get_config_defaults(&pin_conf); + // + // pin_conf.direction = PORT_PIN_DIR_OUTPUT; + // port_pin_set_config(MICROPY_HW_LED1, &pin_conf); + // port_pin_set_output_level(MICROPY_HW_LED1, false); - #ifdef USB_REPL - udc_start(); - #endif + #ifdef USB_REPL + udc_start(); + #endif - // TODO(tannewt): Switch to proper pyb based UARTs. - #ifdef UART_REPL - configure_usart(); - #endif + // TODO(tannewt): Switch to proper pyb based UARTs. + #ifdef UART_REPL + configure_usart(); + #endif } #endif diff --git a/atmel-samd/mphalport.c b/atmel-samd/mphalport.c index 29f29ff1fb..f5002b3031 100644 --- a/atmel-samd/mphalport.c +++ b/atmel-samd/mphalport.c @@ -2,6 +2,7 @@ #include "asf/common/services/usb/class/cdc/device/udi_cdc.h" #include "asf/common2/services/delay/delay.h" +#include "asf/sam0/drivers/port/port.h" #include "asf/sam0/drivers/sercom/usart/usart.h" #include "py/mphal.h" #include "py/mpstate.h" @@ -104,34 +105,44 @@ int receive_usb() { } int mp_hal_stdin_rx_chr(void) { - for (;;) { - #ifdef USB_REPL - if (mp_cdc_enabled && usb_rx_count > 0) { - return receive_usb(); + for (;;) { + #ifdef USB_REPL + if (mp_cdc_enabled && usb_rx_count > 0) { + #ifdef MICROPY_HW_LED_RX + port_pin_toggle_output_level(MICROPY_HW_LED_RX); + #endif + return receive_usb(); + } + #endif + #ifdef UART_REPL + uint16_t temp; + if (usart_read_wait(&usart_instance, &temp) == STATUS_OK) { + #ifdef MICROPY_HW_LED_RX + port_pin_toggle_output_level(MICROPY_HW_LED_RX); + #endif + return temp; + } + #endif + // TODO(tannewt): Figure out how we can sleep while waiting for input and + // add it here. The current UART implementation doesn't cause a wake. + //__WFI(); } - #endif - #ifdef UART_REPL - uint16_t temp; - if (usart_read_wait(&usart_instance, &temp) == STATUS_OK) { - return temp; - } - #endif - // TODO(tannewt): Figure out how we can sleep while waiting for input and - // add it here. The current UART implementation doesn't cause a wake. - //__WFI(); - } } void mp_hal_stdout_tx_strn(const char *str, size_t len) { - #ifdef UART_REPL - usart_write_buffer_wait(&usart_instance, (uint8_t*) str, len); - #endif + #ifdef MICROPY_HW_LED_TX + port_pin_toggle_output_level(MICROPY_HW_LED_TX); + #endif - #ifdef USB_REPL - if (mp_cdc_enabled && udi_cdc_is_tx_ready()) { - udi_cdc_write_buf(str, len); - } - #endif + #ifdef UART_REPL + usart_write_buffer_wait(&usart_instance, (uint8_t*) str, len); + #endif + + #ifdef USB_REPL + if (mp_cdc_enabled && udi_cdc_is_tx_ready()) { + udi_cdc_write_buf(str, len); + } + #endif } void mp_hal_set_interrupt_char(int c) {