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 \
moduos.c \
mphalport.c \
reset.c \
samd21_pins.c \
shared_dma.c \
rgb_led_status.c \

View File

@ -2,6 +2,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef 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()
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)
void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef 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()
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)
void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef 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()
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)
void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef 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()
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)
void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef 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()
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)
void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef 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()
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)
void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef CONF_USB_H_INCLUDED
#define CONF_USB_H_INCLUDED
@ -19,7 +21,7 @@
#endif
#ifndef USB_DEVICE_PRODUCT_NAME
# define USB_DEVICE_PRODUCT_NAME "Metro M0 with Flash (Experimental)"
# define USB_DEVICE_PRODUCT_NAME "Metro M0 Express"
#endif
// #define USB_DEVICE_SERIAL_NAME "12...EF"
#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()
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)
void usb_dtr_notify(uint8_t port, bool set);
#define UDI_CDC_SET_RTS_EXT(port,set) usb_rts_notify(port, set)

View File

@ -2,6 +2,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "asf/common/services/usb/class/cdc/usb_protocol_cdc.h"
#ifndef 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()
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)
void usb_dtr_notify(uint8_t port, bool 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.
volatile bool mp_msc_enabled = false;
bool mp_msc_enable()
{
mp_msc_enabled = true;
return true;
bool mp_msc_enable() {
mp_msc_enabled = true;
return true;
}
void mp_msc_disable()
{
mp_msc_enabled = false;
void mp_msc_disable() {
mp_msc_enabled = false;
}
bool mp_cdc_enable(uint8_t port)
{
mp_cdc_enabled = false;
return true;
bool mp_cdc_enable(uint8_t port) {
mp_cdc_enabled = false;
return true;
}
void mp_cdc_disable(uint8_t port)
{
mp_cdc_enabled = false;
void mp_cdc_disable(uint8_t port) {
mp_cdc_enabled = false;
}
volatile bool reset_on_disconnect = false;
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) {
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;
if (mp_cdc_enabled) {
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__