diff options
| author | Scott Shawcroft <scott@chickadee.tech> | 2016-09-15 17:01:19 -0700 |
|---|---|---|
| committer | Scott Shawcroft <scott@chickadee.tech> | 2016-09-15 17:01:19 -0700 |
| commit | 7fd84e93f48438ddcff22941286e43df50cd15f0 (patch) | |
| tree | 0e10b3d446caa04082ad103c9eebc9a597cebb37 | |
| parent | 7d8929c470f7c7215d93cbe90d713e7b60d93dd6 (diff) | |
atmel-samd: Support raw repl and soft reset to support ampy.
Closes #1. Also adds TX and RX led support on the Arduino Zero.
| -rw-r--r-- | atmel-samd/Makefile | 1 | ||||
| -rw-r--r-- | atmel-samd/boards/arduino_zero/init.c | 24 | ||||
| -rw-r--r-- | atmel-samd/boards/arduino_zero/mpconfigboard.h | 3 | ||||
| -rw-r--r-- | atmel-samd/boards/feather_m0_bluefruit_le/init.c | 5 | ||||
| -rw-r--r-- | atmel-samd/main.c | 84 | ||||
| -rw-r--r-- | atmel-samd/mphalport.c | 57 |
6 files changed, 108 insertions, 66 deletions
diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile index bd5bd1e1d..1acd8f34e 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 32fba3695..af8b08ff7 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 <a href="http://www.atmel.com/design-support/">Atmel Support</a> */ -#include <asf.h> -#include <board.h> -#include <conf_board.h> +#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 4a2723fc7..fbebaed2d 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 32fba3695..88608c0fb 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 <a href="http://www.atmel.com/design-support/">Atmel Support</a> */ -#include <asf.h> -#include <board.h> -#include <conf_board.h> +#include "board.h" +#include "conf_board.h" void board_init(void) { diff --git a/atmel-samd/main.c b/atmel-samd/main.c index c4db13470..4b7cafd4d 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 <board.h> #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 29f29ff1f..f5002b303 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(); } +} + +void mp_hal_stdout_tx_strn(const char *str, size_t len) { + #ifdef MICROPY_HW_LED_TX + port_pin_toggle_output_level(MICROPY_HW_LED_TX); #endif + #ifdef UART_REPL - uint16_t temp; - if (usart_read_wait(&usart_instance, &temp) == STATUS_OK) { - return temp; - } + usart_write_buffer_wait(&usart_instance, (uint8_t*) str, len); #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 USB_REPL - if (mp_cdc_enabled && udi_cdc_is_tx_ready()) { - udi_cdc_write_buf(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) { |
