Skip to content

Commit 7fd84e9

Browse files
committed
atmel-samd: Support raw repl and soft reset to support ampy.
Closes #1. Also adds TX and RX led support on the Arduino Zero.
1 parent 7d8929c commit 7fd84e9

File tree

6 files changed

+108
-66
lines changed

6 files changed

+108
-66
lines changed

atmel-samd/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ SRC_C = \
150150
asf/sam0/utils/cmsis/samd21/source/gcc/startup_samd21.c \
151151
asf/sam0/utils/cmsis/samd21/source/system_samd21.c \
152152
asf/sam0/utils/syscalls/gcc/syscalls.c \
153+
boards/$(BOARD)/init.c \
153154
boards/$(BOARD)/pins.c \
154155
lib/fatfs/ff.c \
155156
lib/fatfs/option/ccsbcs.c \

atmel-samd/boards/arduino_zero/init.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,24 @@
88
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
99
*/
1010

11-
#include <asf.h>
12-
#include <board.h>
13-
#include <conf_board.h>
11+
#include "board.h"
12+
#include "conf_board.h"
13+
#include "mpconfigboard.h"
14+
#include "asf/sam0/drivers/port/port.h"
1415

1516
void board_init(void)
1617
{
17-
/* This function is meant to contain board-specific initialization code
18-
* for, e.g., the I/O pins. The initialization can rely on application-
19-
* specific board configuration, found in conf_board.h.
20-
*/
18+
/* This function is meant to contain board-specific initialization code
19+
* for, e.g., the I/O pins. The initialization can rely on application-
20+
* specific board configuration, found in conf_board.h.
21+
*/
22+
struct port_config pin_conf;
23+
port_get_config_defaults(&pin_conf);
24+
25+
pin_conf.direction = PORT_PIN_DIR_OUTPUT;
26+
port_pin_set_config(MICROPY_HW_LED_TX, &pin_conf);
27+
port_pin_set_output_level(MICROPY_HW_LED_TX, true);
28+
29+
port_pin_set_config(MICROPY_HW_LED_RX, &pin_conf);
30+
port_pin_set_output_level(MICROPY_HW_LED_RX, true);
2131
}

atmel-samd/boards/arduino_zero/mpconfigboard.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@
55

66
#define MICROPY_HW_BOARD_NAME "Arduino Zero"
77
#define MICROPY_HW_MCU_NAME "samd21g18"
8+
9+
#define MICROPY_HW_LED_TX PIN_PA27
10+
#define MICROPY_HW_LED_RX PIN_PB03

atmel-samd/boards/feather_m0_bluefruit_le/init.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
99
*/
1010

11-
#include <asf.h>
12-
#include <board.h>
13-
#include <conf_board.h>
11+
#include "board.h"
12+
#include "conf_board.h"
1413

1514
void board_init(void)
1615
{

atmel-samd/main.c

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "asf/sam0/drivers/port/port.h"
2020
#include "asf/sam0/drivers/sercom/usart/usart.h"
2121
#include "asf/sam0/drivers/system/system.h"
22+
#include <board.h>
2223

2324
#include "mpconfigboard.h"
2425
#include "modmachine_pin.h"
@@ -158,16 +159,7 @@ void init_flash_fs() {
158159
static char *stack_top;
159160
static char heap[8192];
160161

161-
int main(int argc, char **argv) {
162-
// initialise the cpu and peripherals
163-
#if MICROPY_MIN_USE_SAMD21_MCU
164-
void samd21_init(void);
165-
samd21_init();
166-
#endif
167-
168-
int stack_dummy;
169-
stack_top = (char*)&stack_dummy;
170-
162+
void reset_mp() {
171163
#if MICROPY_ENABLE_GC
172164
gc_init(heap, heap + sizeof(heap));
173165
#endif
@@ -176,11 +168,22 @@ int main(int argc, char **argv) {
176168
MP_STATE_PORT(mp_kbd_exception) = mp_obj_new_exception(&mp_type_KeyboardInterrupt);
177169

178170
pin_init0();
171+
}
172+
173+
int main(int argc, char **argv) {
174+
// initialise the cpu and peripherals
175+
#if MICROPY_MIN_USE_SAMD21_MCU
176+
void samd21_init(void);
177+
samd21_init();
178+
#endif
179179

180180
// Initialise the local flash filesystem.
181181
// Create it if needed, mount in on /flash, and set it as current dir.
182182
init_flash_fs();
183183

184+
int stack_dummy;
185+
reset_mp();
186+
184187
#if MICROPY_REPL_EVENT_DRIVEN
185188
pyexec_event_repl_init();
186189
for (;;) {
@@ -190,10 +193,24 @@ int main(int argc, char **argv) {
190193
}
191194
}
192195
#else
193-
pyexec_friendly_repl();
196+
// Main script is finished, so now go into REPL mode.
197+
// The REPL mode can change, or it can request a soft reset.
198+
int exit_code = 0;
199+
for (;;) {
200+
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
201+
exit_code = pyexec_raw_repl();
202+
} else {
203+
exit_code = pyexec_friendly_repl();
204+
}
205+
if (exit_code == PYEXEC_FORCED_EXIT) {
206+
mp_hal_stdout_tx_str("soft reboot\r\n");
207+
stack_top = (char*)&stack_dummy;
208+
reset_mp();
209+
} else if (exit_code != 0) {
210+
break;
211+
}
212+
}
194213
#endif
195-
//do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\\n')", MP_PARSE_SINGLE_INPUT);
196-
//do_str("for i in range(10):\r\n print(i)", MP_PARSE_FILE_INPUT);
197214
mp_deinit();
198215
return 0;
199216
}
@@ -239,33 +256,34 @@ void MP_WEAK __assert_func(const char *file, int line, const char *func, const c
239256
struct usart_module usart_instance;
240257

241258
void samd21_init(void) {
259+
irq_initialize_vectors();
260+
cpu_irq_enable();
242261

243-
irq_initialize_vectors();
244-
cpu_irq_enable();
262+
// Initialize the sleep manager
263+
sleepmgr_init();
245264

246-
// Initialize the sleep manager
247-
sleepmgr_init();
265+
system_init();
248266

249-
system_init();
267+
delay_init();
250268

251-
delay_init();
269+
board_init();
252270

253-
// Uncomment to init PIN_PA17 for debugging.
254-
// struct port_config pin_conf;
255-
// port_get_config_defaults(&pin_conf);
256-
//
257-
// pin_conf.direction = PORT_PIN_DIR_OUTPUT;
258-
// port_pin_set_config(MICROPY_HW_LED1, &pin_conf);
259-
// port_pin_set_output_level(MICROPY_HW_LED1, false);
271+
// Uncomment to init PIN_PA17 for debugging.
272+
// struct port_config pin_conf;
273+
// port_get_config_defaults(&pin_conf);
274+
//
275+
// pin_conf.direction = PORT_PIN_DIR_OUTPUT;
276+
// port_pin_set_config(MICROPY_HW_LED1, &pin_conf);
277+
// port_pin_set_output_level(MICROPY_HW_LED1, false);
260278

261-
#ifdef USB_REPL
262-
udc_start();
263-
#endif
279+
#ifdef USB_REPL
280+
udc_start();
281+
#endif
264282

265-
// TODO(tannewt): Switch to proper pyb based UARTs.
266-
#ifdef UART_REPL
267-
configure_usart();
268-
#endif
283+
// TODO(tannewt): Switch to proper pyb based UARTs.
284+
#ifdef UART_REPL
285+
configure_usart();
286+
#endif
269287
}
270288

271289
#endif

atmel-samd/mphalport.c

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "asf/common/services/usb/class/cdc/device/udi_cdc.h"
44
#include "asf/common2/services/delay/delay.h"
5+
#include "asf/sam0/drivers/port/port.h"
56
#include "asf/sam0/drivers/sercom/usart/usart.h"
67
#include "py/mphal.h"
78
#include "py/mpstate.h"
@@ -104,34 +105,44 @@ int receive_usb() {
104105
}
105106

106107
int mp_hal_stdin_rx_chr(void) {
107-
for (;;) {
108-
#ifdef USB_REPL
109-
if (mp_cdc_enabled && usb_rx_count > 0) {
110-
return receive_usb();
108+
for (;;) {
109+
#ifdef USB_REPL
110+
if (mp_cdc_enabled && usb_rx_count > 0) {
111+
#ifdef MICROPY_HW_LED_RX
112+
port_pin_toggle_output_level(MICROPY_HW_LED_RX);
113+
#endif
114+
return receive_usb();
115+
}
116+
#endif
117+
#ifdef UART_REPL
118+
uint16_t temp;
119+
if (usart_read_wait(&usart_instance, &temp) == STATUS_OK) {
120+
#ifdef MICROPY_HW_LED_RX
121+
port_pin_toggle_output_level(MICROPY_HW_LED_RX);
122+
#endif
123+
return temp;
124+
}
125+
#endif
126+
// TODO(tannewt): Figure out how we can sleep while waiting for input and
127+
// add it here. The current UART implementation doesn't cause a wake.
128+
//__WFI();
111129
}
130+
}
131+
132+
void mp_hal_stdout_tx_strn(const char *str, size_t len) {
133+
#ifdef MICROPY_HW_LED_TX
134+
port_pin_toggle_output_level(MICROPY_HW_LED_TX);
112135
#endif
136+
113137
#ifdef UART_REPL
114-
uint16_t temp;
115-
if (usart_read_wait(&usart_instance, &temp) == STATUS_OK) {
116-
return temp;
117-
}
138+
usart_write_buffer_wait(&usart_instance, (uint8_t*) str, len);
118139
#endif
119-
// TODO(tannewt): Figure out how we can sleep while waiting for input and
120-
// add it here. The current UART implementation doesn't cause a wake.
121-
//__WFI();
122-
}
123-
}
124140

125-
void mp_hal_stdout_tx_strn(const char *str, size_t len) {
126-
#ifdef UART_REPL
127-
usart_write_buffer_wait(&usart_instance, (uint8_t*) str, len);
128-
#endif
129-
130-
#ifdef USB_REPL
131-
if (mp_cdc_enabled && udi_cdc_is_tx_ready()) {
132-
udi_cdc_write_buf(str, len);
133-
}
134-
#endif
141+
#ifdef USB_REPL
142+
if (mp_cdc_enabled && udi_cdc_is_tx_ready()) {
143+
udi_cdc_write_buf(str, len);
144+
}
145+
#endif
135146
}
136147

137148
void mp_hal_set_interrupt_char(int c) {

0 commit comments

Comments
 (0)