mynewt app; support additional options to enter serial dfu.

Signed-off-by: Marko Kiiskila <marko@runtime.io>
diff --git a/boot/boot_serial/syscfg.yml b/boot/boot_serial/syscfg.yml
index 84fc39f..e6c8e5f 100644
--- a/boot/boot_serial/syscfg.yml
+++ b/boot/boot_serial/syscfg.yml
@@ -20,9 +20,11 @@
     BOOT_SERIAL_DETECT_PIN:
         description: >
             Start the serial boot loader if this pin is asserted at boot time.
-        value:
+        value: '-1'
         restrictions:
-            - '$notnull'
+            - '(BOOT_SERIAL_DETECT_PIN != -1) ||
+               (BOOT_SERIAL_DETECT_TIMEOUT != 0) ||
+	       (BOOT_SERIAL_NVREG_INDEX != -1)'
 
     BOOT_SERIAL_DETECT_PIN_CFG:
         description: >
@@ -35,6 +37,30 @@
             to start.
         value: 0
 
+    BOOT_SERIAL_DETECT_TIMEOUT:
+        description: >
+            The duration, in milliseconds, to listen on the UART for the
+            management string (BOOT_SERIAL_DETECT_STRING).  If the management
+            string is detected during this period, the serial boot loader is
+            started.  If the period expires without the management string being
+            received, the boot loader runs in the normal (non-serial) mode.
+            Specify 0 to disable listening on the UART for the management
+            string.
+        value: 0
+        restrictions:
+            - '(BOOT_SERIAL_DETECT_PIN != -1) ||
+               (BOOT_SERIAL_DETECT_TIMEOUT != 0) ||
+	       (BOOT_SERIAL_NVREG_INDEX != -1)'
+
+    BOOT_SERIAL_DETECT_STRING:
+        description: >
+            The string to listen for on the UART.  If this management string is
+            detected during the timeout period, the serial boot loader is
+            started.  If the period expires without this string being received,
+            the boot loader runs in the normal (non-serial) mode.  This setting
+            has no effect if BOOT_SERIAL_DETECT_TIMEOUT is set to 0.
+        value: '"nmgr"'
+
     BOOT_SERIAL_REPORT_PIN:
         description: >
             The GPIO to toggle while the serial boot loader is running.  Set to
@@ -45,3 +71,22 @@
         description: >
             The toggle rate, in Hz, of the serial boot loader report pin.
         value: 4
+
+    BOOT_SERIAL_NVREG_MAGIC:
+        description: >
+            Magic number, to be saved in a retained (reset-surviving) register.
+            If the value in the register matches, the serial bootloader will
+            load. Value must not be 0.
+        value: 0xB7
+        restrictions:
+            - '(BOOT_SERIAL_NVREG_MAGIC != 0)'
+
+    BOOT_SERIAL_NVREG_INDEX:
+        description: >
+            Index of retained register to use (using hal_nvreg_read) for reading
+            magic value.
+        value: -1
+        restrictions:
+            - '(BOOT_SERIAL_DETECT_PIN != -1) ||
+               (BOOT_SERIAL_DETECT_TIMEOUT != 0) ||
+	       (BOOT_SERIAL_NVREG_INDEX != -1)'
diff --git a/boot/mynewt/src/main.c b/boot/mynewt/src/main.c
index ebafca3..083d03e 100755
--- a/boot/mynewt/src/main.c
+++ b/boot/mynewt/src/main.c
@@ -33,6 +33,7 @@
 #include <sysinit/sysinit.h>
 #ifdef MCUBOOT_SERIAL
 #include <hal/hal_gpio.h>
+#include <hal/hal_nvreg.h>
 #include <boot_serial/boot_serial.h>
 #endif
 #include <console/console.h>
@@ -44,7 +45,7 @@
 #define AREA_DESC_MAX         (BOOT_AREA_DESC_MAX)
 
 #ifdef MCUBOOT_SERIAL
-#define BOOT_SER_CONS_INPUT   256
+#define BOOT_SERIAL_INPUT_MAX (512)
 #endif
 
 /*
@@ -59,6 +60,53 @@
     return 0;
 }
 
+#ifdef MCUBOOT_SERIAL
+static void
+serial_boot_detect(void)
+{
+    /*
+     * Read retained register and compare with expected magic value.
+     * If it matches, await for download commands from serial.
+     */
+#if MYNEWT_VAL(BOOT_SERIAL_NVREG_INDEX) != -1
+    if (hal_nvreg_read(MYNEWT_VAL(BOOT_SERIAL_NVREG_INDEX)) ==
+        MYNEWT_VAL(BOOT_SERIAL_NVREG_MAGIC)) {
+
+        hal_nvreg_write(MYNEWT_VAL(BOOT_SERIAL_NVREG_INDEX), 0);
+
+        boot_serial_start(BOOT_SERIAL_INPUT_MAX);
+        assert(0);
+    }
+
+#endif
+
+    /*
+     * Configure a GPIO as input, and compare it against expected value.
+     * If it matches, await for download commands from serial.
+     */
+#if MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN) != -1
+    hal_gpio_init_in(MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN),
+                     MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN_CFG));
+    if (hal_gpio_read(MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN)) ==
+                      MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN_VAL)) {
+        boot_serial_start(BOOT_SERIAL_INPUT_MAX);
+        assert(0);
+    }
+#endif
+
+    /*
+     * Listen for management pattern in UART input.  If detected, await for
+     * download commands from serial.
+     */
+#if MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) != 0
+    if (boot_serial_detect_uart_string()) {
+        boot_serial_start(BOOT_SERIAL_INPUT_MAX);
+        assert(0);
+    }
+#endif
+}
+#endif
+
 int
 main(void)
 {
@@ -71,26 +119,16 @@
 #if defined(MCUBOOT_SERIAL) || defined(MCUBOOT_HAVE_LOGGING)
     /* initialize uart without os */
     os_dev_initialize_all(OS_DEV_INIT_PRIMARY);
+    os_dev_initialize_all(OS_DEV_INIT_SECONDARY);
     sysinit();
     console_blocking_mode();
+#if defined(MCUBOOT_SERIAL)
+    serial_boot_detect();
+#endif
 #else
     flash_map_init();
 #endif
 
-#ifdef MCUBOOT_SERIAL
-    /*
-     * Configure a GPIO as input, and compare it against expected value.
-     * If it matches, await for download commands from serial.
-     */
-    hal_gpio_init_in(MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN),
-                     MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN_CFG));
-    if (hal_gpio_read(MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN)) ==
-                      MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN_VAL)) {
-        boot_serial_start(BOOT_SER_CONS_INPUT);
-        assert(0);
-    }
-#endif
-
     rc = boot_go(&rsp);
     assert(rc == 0);