From dd50d5c446e6d1fb9cbfd93b5d579604038a3125 Mon Sep 17 00:00:00 2001
From: Cristian Maglie <c.maglie@arduino.cc>
Date: Fri, 15 Aug 2014 12:10:50 +0200
Subject: [PATCH]  Implemented 1200bps-touch to restart bootloader when
 connected from native port

---
 boards.txt              |  4 ++--
 cores/arduino/Reset.cpp | 18 +++++++++++++++++-
 cores/arduino/delay.c   |  3 +++
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/boards.txt b/boards.txt
index 411bda3b..70eaa9ae 100644
--- a/boards.txt
+++ b/boards.txt
@@ -28,8 +28,8 @@ arduino_zero_native.pid.0=0x004d
 arduino_zero_native.upload.tool=bossac
 arduino_zero_native.upload.protocol=sam-ba
 arduino_zero_native.upload.maximum_size=262144
-arduino_zero_native.upload.use_1200bps_touch=false
-arduino_zero_native.upload.wait_for_upload_port=false
+arduino_zero_native.upload.use_1200bps_touch=true
+arduino_zero_native.upload.wait_for_upload_port=true
 arduino_zero_native.upload.native_usb=true
 arduino_zero_native.build.mcu=cortex-m0plus
 arduino_zero_native.build.f_cpu=48000000L
diff --git a/cores/arduino/Reset.cpp b/cores/arduino/Reset.cpp
index afb30d2f..679e0341 100644
--- a/cores/arduino/Reset.cpp
+++ b/cores/arduino/Reset.cpp
@@ -23,12 +23,28 @@
 extern "C" {
 #endif
 
+#define NVM_MEMORY ((volatile uint16_t *)0x000000)
+#define APP_START 0x00002004
+
+static inline bool nvmReady(void) {
+        return NVMCTRL->INTFLAG.reg & NVMCTRL_INTFLAG_READY;
+}
+
 __attribute__ ((long_call, section (".ramfunc")))
 static void banzai() {
 	// Disable all interrupts
 	__disable_irq();
 
-  // Reset the device
+	// Erase application
+	while (!nvmReady())
+		;
+	NVMCTRL->STATUS.reg |= NVMCTRL_STATUS_MASK;
+	NVMCTRL->ADDR.reg  = (uintptr_t)&NVM_MEMORY[APP_START / 4];
+	NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_ER | NVMCTRL_CTRLA_CMDEX_KEY;
+	while (!nvmReady())
+		;
+
+	// Reset the device
 	NVIC_SystemReset() ;
 
 	while (true);
diff --git a/cores/arduino/delay.c b/cores/arduino/delay.c
index 2548f91e..b9126c42 100644
--- a/cores/arduino/delay.c
+++ b/cores/arduino/delay.c
@@ -58,10 +58,13 @@ void delay( uint32_t ms )
   } while ( _ulTickCount - start <= ms ) ;
 }
 
+#include "Reset.h" // for tickReset()
+
 void SysTick_Handler( void )
 {
   // Increment tick count each ms
   _ulTickCount++ ;
+  tickReset();
 }
 
 #ifdef __cplusplus
-- 
GitLab