Skip to content

Commit d189a3f

Browse files
committed
atmel-samd: Support auto-reset based on USB write activity.
It will soft-reboot micropython after a burst of writes to the file system. This means that after you save files on your computer they will be automatically rerun. This can be disabled in the build by unsetting AUTORESET_TIMER in mpconfigboard.h. Using the REPL will also prevent the soft resets until you reset with CTRL-D manually.
1 parent 614c1fd commit d189a3f

14 files changed

Lines changed: 207 additions & 2 deletions

File tree

atmel-samd/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ CFLAGS_CORTEX_M0 = \
101101
-DEXTINT_CALLBACK_MODE=true \
102102
-DUDD_ENABLE \
103103
-DUSART_CALLBACK_MODE=true \
104+
-DTC_ASYNC=true \
104105
-DUSB_DEVICE_LPM_SUPPORT
105106
CFLAGS = $(INC) -Wall -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M0) $(COPT)
106107

@@ -135,6 +136,7 @@ SRC_ASF = $(addprefix asf/sam0/,\
135136
drivers/system/interrupt/system_interrupt.c \
136137
drivers/system/pinmux/pinmux.c \
137138
drivers/system/system.c \
139+
drivers/tc/tc_interrupt.c \
138140
drivers/tc/tc_sam_d_r/tc.c \
139141
drivers/tcc/tcc.c \
140142
drivers/usb/stack_interface/usb_device_udd.c \
@@ -144,6 +146,7 @@ SRC_ASF = $(addprefix asf/sam0/,\
144146

145147
SRC_C = \
146148
access_vfs.c \
149+
autoreset.c \
147150
builtin_open.c \
148151
fatfs_port.c \
149152
main.c \

atmel-samd/access_vfs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@
2727
#include <string.h>
2828

2929
#include "access_vfs.h"
30+
#include "autoreset.h"
3031

3132
#include "asf/common/services/usb/class/msc/device/udi_msc.h"
3233
#include "extmod/fsusermount.h"
3334
#include "lib/fatfs/diskio.h"
3435
#include "py/mpconfig.h"
36+
#include "py/mphal.h"
3537
#include "py/mpstate.h"
3638
#include "py/misc.h"
3739

@@ -140,7 +142,6 @@ Ctrl_status vfs_usb_read_10(uint32_t addr, volatile uint16_t nb_sector)
140142
return CTRL_GOOD;
141143
}
142144

143-
144145
//! This function transfers the USB MSC data to the memory
145146
//!
146147
//! @param addr Sector address to start write
@@ -183,5 +184,6 @@ Ctrl_status vfs_usb_write_10(uint32_t addr, volatile uint16_t nb_sector)
183184
}
184185
}
185186
}
187+
autoreset_start();
186188
return CTRL_GOOD;
187189
}

atmel-samd/autoreset.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "autoreset.h"
28+
29+
#include "asf/sam0/drivers/tc/tc_interrupt.h"
30+
#include "lib/mp-readline/readline.h"
31+
#include "py/mphal.h"
32+
33+
struct tc_module autoreset_timer;
34+
35+
static bool autoreset_initialized = false;
36+
37+
static bool autoreset_enabled = false;
38+
39+
extern void inject_character(char);
40+
void mp_keyboard_interrupt(void);
41+
42+
void autoreset_callback(struct tc_module *const module_inst) {
43+
if (autoreset_enabled) {
44+
mp_keyboard_interrupt();
45+
inject_character(CHAR_CTRL_D);
46+
}
47+
48+
tc_stop_counter(&autoreset_timer);
49+
}
50+
51+
void autoreset_init() {
52+
#ifdef AUTORESET_TIMER
53+
struct tc_config config_tc;
54+
tc_get_config_defaults(&config_tc);
55+
config_tc.counter_size = TC_COUNTER_SIZE_16BIT;
56+
config_tc.clock_prescaler = TC_CLOCK_PRESCALER_DIV256;
57+
config_tc.counter_16_bit.compare_capture_channel[0] = 0xFFFF;
58+
tc_init(&autoreset_timer, AUTORESET_TIMER, &config_tc);
59+
tc_enable(&autoreset_timer);
60+
tc_register_callback(&autoreset_timer, autoreset_callback, TC_CALLBACK_CC_CHANNEL0);
61+
tc_enable_callback(&autoreset_timer, TC_CALLBACK_CC_CHANNEL0);
62+
tc_stop_counter(&autoreset_timer);
63+
64+
autoreset_initialized = true;
65+
#endif
66+
}
67+
68+
void autoreset_enable() {
69+
autoreset_enabled = true;
70+
}
71+
72+
void autoreset_disable() {
73+
autoreset_enabled = false;
74+
}
75+
76+
void autoreset_start() {
77+
if (!autoreset_initialized) return;
78+
79+
tc_stop_counter(&autoreset_timer);
80+
tc_start_counter(&autoreset_timer);
81+
}
82+
83+
void autoreset_stop() {
84+
if (!autoreset_initialized) return;
85+
86+
tc_stop_counter(&autoreset_timer);
87+
}

atmel-samd/autoreset.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_AUTORESET_H__
28+
#define __MICROPY_INCLUDED_ATMEL_SAMD_AUTORESET_H__
29+
30+
#include "asf/sam0/drivers/tc/tc.h"
31+
32+
void autoreset_callback(struct tc_module *const module_inst);
33+
void autoreset_init();
34+
void autoreset_start();
35+
void autoreset_stop();
36+
void autoreset_enable();
37+
void autoreset_disable();
38+
39+
#endif // __MICROPY_INCLUDED_ATMEL_SAMD_AUTORESET_H__

atmel-samd/boards/arduino_zero/mpconfigboard.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88

99
#define MICROPY_HW_LED_TX PIN_PA27
1010
#define MICROPY_HW_LED_RX PIN_PB03
11+
12+
#define AUTORESET_TIMER TC5

atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h

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

66
#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 Adalogger"
77
#define MICROPY_HW_MCU_NAME "samd21g18"
8+
9+
#define AUTORESET_TIMER TC5

atmel-samd/boards/feather_m0_basic/mpconfigboard.h

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

66
#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 Basic"
77
#define MICROPY_HW_MCU_NAME "samd21g18"
8+
9+
#define AUTORESET_TIMER TC5

atmel-samd/boards/metro_m0_flash/mpconfigboard.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,5 @@
2929
#define SPI_FLASH_PAD3_PINMUX PINMUX_PB11D_SERCOM4_PAD3 // SCK
3030
#define SPI_FLASH_CS PIN_PA13
3131
#define SPI_FLASH_SERCOM SERCOM4
32+
33+
#define AUTORESET_TIMER TC5

atmel-samd/internal_flash.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <stdint.h>
2828
#include <string.h>
2929

30+
#include "py/mphal.h"
3031
#include "py/obj.h"
3132
#include "py/runtime.h"
3233
#include "lib/fatfs/ff.h"
@@ -40,7 +41,7 @@
4041
#define TOTAL_INTERNAL_FLASH_SIZE 0x010000
4142

4243
#define INTERNAL_FLASH_MEM_SEG1_START_ADDR (0x00040000 - TOTAL_INTERNAL_FLASH_SIZE)
43-
#define INTERNAL_FLASH_PART1_START_BLOCK (0x100)
44+
#define INTERNAL_FLASH_PART1_START_BLOCK (0x1)
4445
#define INTERNAL_FLASH_PART1_NUM_BLOCKS (TOTAL_INTERNAL_FLASH_SIZE / INTERNAL_FLASH_BLOCK_SIZE)
4546

4647
static bool internal_flash_is_initialised = false;

atmel-samd/main.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "asf/sam0/drivers/system/system.h"
2323
#include <board.h>
2424

25+
#include "autoreset.h"
2526
#include "mpconfigboard.h"
2627
#include "modmachine_pin.h"
2728

@@ -172,6 +173,9 @@ static char *stack_top;
172173
static char heap[16384];
173174

174175
void reset_mp() {
176+
autoreset_stop();
177+
autoreset_enable();
178+
175179
// Sync the file systems in case any used RAM from the GC to cache. As soon
176180
// as we re-init the GC all bets are off on the cache.
177181
disk_ioctl(0, CTRL_SYNC, NULL);
@@ -191,8 +195,18 @@ void reset_mp() {
191195
MP_STATE_PORT(mp_kbd_exception) = mp_obj_new_exception(&mp_type_KeyboardInterrupt);
192196

193197
pin_init0();
198+
}
199+
200+
void start_mp() {
201+
#ifdef AUTORESET_TIMER
202+
mp_hal_stdout_tx_str("\r\n");
203+
mp_hal_stdout_tx_str("Auto-soft reset is on. Simply save files over USB to run them.\r\n");
204+
mp_hal_stdout_tx_str("Type anything into the REPL to disable and manually reset (CTRL-D) to re-enable.\r\n");
205+
#endif
194206

207+
mp_hal_stdout_tx_str("boot.py output:\r\n");
195208
pyexec_file("boot.py");
209+
mp_hal_stdout_tx_str("\r\nmain.py output:\r\n");
196210
pyexec_file("main.py");
197211
}
198212

@@ -216,11 +230,18 @@ int main(int argc, char **argv) {
216230
// as current dir.
217231
init_flash_fs();
218232

233+
// Initialize the autoreset timer. It will automatically reset the repl
234+
// after a burst of writes to the FS.
235+
autoreset_init();
236+
219237
// Start USB after getting everything going.
220238
#ifdef USB_REPL
221239
udc_start();
222240
#endif
223241

242+
// Run boot and main.
243+
start_mp();
244+
224245
// Main script is finished, so now go into REPL mode.
225246
// The REPL mode can change, or it can request a soft reset.
226247
int exit_code = 0;
@@ -233,6 +254,7 @@ int main(int argc, char **argv) {
233254
if (exit_code == PYEXEC_FORCED_EXIT) {
234255
mp_hal_stdout_tx_str("soft reboot\r\n");
235256
reset_mp();
257+
start_mp();
236258
} else if (exit_code != 0) {
237259
break;
238260
}

0 commit comments

Comments
 (0)