atmel-samd: Reboot to bootloader when a 1200 baud serial connection is

closed. This is how Arduino triggers the bootloader.
This commit is contained in:
Scott Shawcroft 2017-07-06 13:41:13 -07:00
parent 0c4b273f24
commit 5d732f45bb
12 changed files with 127 additions and 26 deletions

View File

@ -190,6 +190,7 @@ SRC_C = \
main.c \ main.c \
moduos.c \ moduos.c \
mphalport.c \ mphalport.c \
reset.c \
samd21_pins.c \ samd21_pins.c \
shared_dma.c \ shared_dma.c \
rgb_led_status.c \ rgb_led_status.c \

View File

@ -2,6 +2,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef CONF_USB_H_INCLUDED #ifndef CONF_USB_H_INCLUDED
#define CONF_USB_H_INCLUDED #define CONF_USB_H_INCLUDED
@ -55,7 +57,8 @@ extern void mp_cdc_disable(uint8_t port);
#define UDI_CDC_RX_NOTIFY(port) usb_rx_notify() #define UDI_CDC_RX_NOTIFY(port) usb_rx_notify()
void usb_rx_notify(void); void usb_rx_notify(void);
#define UDI_CDC_SET_CODING_EXT(port,cfg) #define UDI_CDC_SET_CODING_EXT(port,cfg) usb_coding_notify(port, cfg)
void usb_coding_notify(uint8_t port, usb_cdc_line_coding_t* coding);
#define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set) #define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set)
void usb_dtr_notify(uint8_t port, bool set); void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set) #define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef CONF_USB_H_INCLUDED #ifndef CONF_USB_H_INCLUDED
#define CONF_USB_H_INCLUDED #define CONF_USB_H_INCLUDED
@ -55,7 +57,8 @@ extern void mp_cdc_disable(uint8_t port);
#define UDI_CDC_RX_NOTIFY(port) usb_rx_notify() #define UDI_CDC_RX_NOTIFY(port) usb_rx_notify()
void usb_rx_notify(void); void usb_rx_notify(void);
#define UDI_CDC_SET_CODING_EXT(port,cfg) #define UDI_CDC_SET_CODING_EXT(port,cfg) usb_coding_notify(port, cfg)
void usb_coding_notify(uint8_t port, usb_cdc_line_coding_t* coding);
#define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set) #define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set)
void usb_dtr_notify(uint8_t port, bool set); void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set) #define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef CONF_USB_H_INCLUDED #ifndef CONF_USB_H_INCLUDED
#define CONF_USB_H_INCLUDED #define CONF_USB_H_INCLUDED
@ -55,7 +57,8 @@ extern void mp_cdc_disable(uint8_t port);
#define UDI_CDC_RX_NOTIFY(port) usb_rx_notify() #define UDI_CDC_RX_NOTIFY(port) usb_rx_notify()
void usb_rx_notify(void); void usb_rx_notify(void);
#define UDI_CDC_SET_CODING_EXT(port,cfg) #define UDI_CDC_SET_CODING_EXT(port,cfg) usb_coding_notify(port, cfg)
void usb_coding_notify(uint8_t port, usb_cdc_line_coding_t* coding);
#define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set) #define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set)
void usb_dtr_notify(uint8_t port, bool set); void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set) #define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef CONF_USB_H_INCLUDED #ifndef CONF_USB_H_INCLUDED
#define CONF_USB_H_INCLUDED #define CONF_USB_H_INCLUDED
@ -55,7 +57,8 @@ extern void mp_cdc_disable(uint8_t port);
#define UDI_CDC_RX_NOTIFY(port) usb_rx_notify() #define UDI_CDC_RX_NOTIFY(port) usb_rx_notify()
void usb_rx_notify(void); void usb_rx_notify(void);
#define UDI_CDC_SET_CODING_EXT(port,cfg) #define UDI_CDC_SET_CODING_EXT(port,cfg) usb_coding_notify(port, cfg)
void usb_coding_notify(uint8_t port, usb_cdc_line_coding_t* coding);
#define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set) #define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set)
void usb_dtr_notify(uint8_t port, bool set); void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set) #define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef CONF_USB_H_INCLUDED #ifndef CONF_USB_H_INCLUDED
#define CONF_USB_H_INCLUDED #define CONF_USB_H_INCLUDED
@ -55,7 +57,8 @@ extern void mp_cdc_disable(uint8_t port);
#define UDI_CDC_RX_NOTIFY(port) usb_rx_notify() #define UDI_CDC_RX_NOTIFY(port) usb_rx_notify()
void usb_rx_notify(void); void usb_rx_notify(void);
#define UDI_CDC_SET_CODING_EXT(port,cfg) #define UDI_CDC_SET_CODING_EXT(port,cfg) usb_coding_notify(port, cfg)
void usb_coding_notify(uint8_t port, usb_cdc_line_coding_t* coding);
#define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set) #define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set)
void usb_dtr_notify(uint8_t port, bool set); void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set) #define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef CONF_USB_H_INCLUDED #ifndef CONF_USB_H_INCLUDED
#define CONF_USB_H_INCLUDED #define CONF_USB_H_INCLUDED
@ -55,7 +57,8 @@ extern void mp_cdc_disable(uint8_t port);
#define UDI_CDC_RX_NOTIFY(port) usb_rx_notify() #define UDI_CDC_RX_NOTIFY(port) usb_rx_notify()
void usb_rx_notify(void); void usb_rx_notify(void);
#define UDI_CDC_SET_CODING_EXT(port,cfg) #define UDI_CDC_SET_CODING_EXT(port,cfg) usb_coding_notify(port, cfg)
void usb_coding_notify(uint8_t port, usb_cdc_line_coding_t* coding);
#define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set) #define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set)
void usb_dtr_notify(uint8_t port, bool set); void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set) #define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef CONF_USB_H_INCLUDED #ifndef CONF_USB_H_INCLUDED
#define CONF_USB_H_INCLUDED #define CONF_USB_H_INCLUDED
@ -19,7 +21,7 @@
#endif #endif
#ifndef USB_DEVICE_PRODUCT_NAME #ifndef USB_DEVICE_PRODUCT_NAME
# define USB_DEVICE_PRODUCT_NAME "Metro M0 with Flash (Experimental)" # define USB_DEVICE_PRODUCT_NAME "Metro M0 Express"
#endif #endif
// #define USB_DEVICE_SERIAL_NAME "12...EF" // #define USB_DEVICE_SERIAL_NAME "12...EF"
#define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number
@ -55,7 +57,8 @@ extern void mp_cdc_disable(uint8_t port);
#define UDI_CDC_RX_NOTIFY(port) usb_rx_notify() #define UDI_CDC_RX_NOTIFY(port) usb_rx_notify()
void usb_rx_notify(void); void usb_rx_notify(void);
#define UDI_CDC_SET_CODING_EXT(port,cfg) #define UDI_CDC_SET_CODING_EXT(port,cfg) usb_coding_notify(port, cfg)
void usb_coding_notify(uint8_t port, usb_cdc_line_coding_t* coding);
#define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set) #define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set)
void usb_dtr_notify(uint8_t port, bool set); void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set) #define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef CONF_USB_H_INCLUDED #ifndef CONF_USB_H_INCLUDED
#define CONF_USB_H_INCLUDED #define CONF_USB_H_INCLUDED
@ -55,7 +57,9 @@ extern void mp_cdc_disable(uint8_t port);
#define UDI_CDC_RX_NOTIFY(port) usb_rx_notify() #define UDI_CDC_RX_NOTIFY(port) usb_rx_notify()
void usb_rx_notify(void); void usb_rx_notify(void);
#define UDI_CDC_SET_CODING_EXT(port,cfg)
#define UDI_CDC_SET_CODING_EXT(port,cfg) usb_coding_notify(port, cfg)
void usb_coding_notify(uint8_t port, usb_cdc_line_coding_t* coding);
#define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set) #define UDI_CDC_SET_DTR_EXT(port,set) usb_dtr_notify(port, set)
void usb_dtr_notify(uint8_t port, bool set); void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set) #define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -39,38 +39,42 @@ extern struct usart_module usart_instance;
// Read by main to know when USB is connected. // Read by main to know when USB is connected.
volatile bool mp_msc_enabled = false; volatile bool mp_msc_enabled = false;
bool mp_msc_enable() bool mp_msc_enable() {
{ mp_msc_enabled = true;
mp_msc_enabled = true; return true;
return true;
} }
void mp_msc_disable() void mp_msc_disable() {
{ mp_msc_enabled = false;
mp_msc_enabled = false;
} }
bool mp_cdc_enable(uint8_t port) bool mp_cdc_enable(uint8_t port) {
{ mp_cdc_enabled = false;
mp_cdc_enabled = false; return true;
return true;
} }
void mp_cdc_disable(uint8_t port) void mp_cdc_disable(uint8_t port) {
{ mp_cdc_enabled = false;
mp_cdc_enabled = false;
} }
volatile bool reset_on_disconnect = false;
void usb_dtr_notify(uint8_t port, bool set) { void usb_dtr_notify(uint8_t port, bool set) {
mp_cdc_enabled = set; mp_cdc_enabled = set;
if (!set && reset_on_disconnect) {
reset_to_bootloader();
}
} }
void usb_rts_notify(uint8_t port, bool set) { void usb_rts_notify(uint8_t port, bool set) {
return; return;
} }
void usb_rx_notify(void) void usb_coding_notify(uint8_t port, usb_cdc_line_coding_t* coding) {
{ reset_on_disconnect = coding->dwDTERate == 1200;
}
void usb_rx_notify(void) {
irqflags_t flags; irqflags_t flags;
if (mp_cdc_enabled) { if (mp_cdc_enabled) {
while (udi_cdc_is_rx_ready()) { while (udi_cdc_is_rx_ready()) {

40
atmel-samd/reset.c Normal file
View File

@ -0,0 +1,40 @@
/*
* 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 "reset.h"
#include "asf/sam0/utils/cmsis/samd21/include/samd21.h"
// Copied from inc/uf2.h in https://github.com/Microsoft/uf2-samd21
#define DBL_TAP_PTR ((volatile uint32_t *)(HMCRAMC0_ADDR + HMCRAMC0_SIZE - 4))
#define DBL_TAP_MAGIC 0xf01669ef // Randomly selected, adjusted to have first and last bit set
void reset_to_bootloader(void) {
flash_flush();
*DBL_TAP_PTR = DBL_TAP_MAGIC;
NVIC_SystemReset();
}

31
atmel-samd/reset.h Normal file
View File

@ -0,0 +1,31 @@
/*
* 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.
*/
#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_RESET_H__
#define __MICROPY_INCLUDED_ATMEL_SAMD_RESET_H__
void reset_to_bootloader(void);
#endif // __MICROPY_INCLUDED_ATMEL_SAMD_RESET_H__