diff options
| author | Marti Bolivar <mbolivar@leaflabs.com> | 2012-08-22 13:26:43 -0400 | 
|---|---|---|
| committer | Marti Bolivar <mbolivar@leaflabs.com> | 2012-08-22 13:26:43 -0400 | 
| commit | 8f30135db2d6f1c21a64b7815ffcb45958e5b211 (patch) | |
| tree | 8d4ab7e90e2782274a10c742195348fb37bf0fdb /wirish | |
| parent | f168a5b936c1b4b70f73e6b18116b34d1c277480 (diff) | |
| download | librambutan-8f30135db2d6f1c21a64b7815ffcb45958e5b211.tar.gz librambutan-8f30135db2d6f1c21a64b7815ffcb45958e5b211.zip | |
usb_serial.cpp: Neaten up reset signal RX hook.
Move magic bytes from stack to Flash. De-magic-number sizeof magic
byte buffer. Use uintptr_t instead of unsigned int when casting
address of wait_reset().
Based on a patch by Michael Hope.
Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
Diffstat (limited to 'wirish')
| -rw-r--r-- | wirish/usb_serial.cpp | 67 | 
1 files changed, 33 insertions, 34 deletions
| diff --git a/wirish/usb_serial.cpp b/wirish/usb_serial.cpp index bf2ea4e..af0d710 100644 --- a/wirish/usb_serial.cpp +++ b/wirish/usb_serial.cpp @@ -31,6 +31,7 @@  #include <wirish/usb_serial.h>  #include <string.h> +#include <stdint.h>  #include <libmaple/nvic.h>  #include <libmaple/usb_cdcacm.h> @@ -199,46 +200,44 @@ static void rxHook(unsigned hook, void *ignored) {          if (usb_cdcacm_data_available() >= 4) {              // The magic reset sequence is "1EAF". -            uint8 cmpBuf[4] = {'1', 'E', 'A', 'F'}; +            static const uint8 magic[4] = {'1', 'E', 'A', 'F'};              uint8 chkBuf[4]; -            // Peek at the waiting bytes, looking for reset sequence. +            // Peek at the waiting bytes, looking for reset sequence, +            // bailing on mismatch.              usb_cdcacm_peek(chkBuf, 4); -            bool cmpMatch = true; -            for (int i = 0; i < 4; i++) { -                if (chkBuf[i] != cmpBuf[i]) { -                    cmpMatch = false; -                    break; +            for (unsigned i = 0; i < sizeof(magic); i++) { +                if (chkBuf[i] != magic[i]) { +                    return;                  }              } -            // Got the magic sequence? Reset, presumably into the bootloader. -            if (cmpMatch) { -                // Return address is wait_reset, but we must set the thumb bit. -                unsigned int target = (unsigned int)wait_reset | 0x1; -                asm volatile("mov r0, %[stack_top]      \n\t" // Reset stack -                             "mov sp, r0                \n\t" -                             "mov r0, #1                \n\t" -                             "mov r1, %[target_addr]    \n\t" -                             "mov r2, %[cpsr]           \n\t" -                             "push {r2}                 \n\t" // Fake xPSR -                             "push {r1}                 \n\t" // PC target addr -                             "push {r0}                 \n\t" // Fake LR -                             "push {r0}                 \n\t" // Fake R12 -                             "push {r0}                 \n\t" // Fake R3 -                             "push {r0}                 \n\t" // Fake R2 -                             "push {r0}                 \n\t" // Fake R1 -                             "push {r0}                 \n\t" // Fake R0 -                             "mov lr, %[exc_return]     \n\t" -                             "bx lr" -                             : -                             : [stack_top] "r" (STACK_TOP), -                               [target_addr] "r" (target), -                               [exc_return] "r" (EXC_RETURN), -                               [cpsr] "r" (DEFAULT_CPSR) -                             : "r0", "r1", "r2"); -                /* should never get here */ -            } +            // Got the magic sequence -> reset, presumably into the bootloader. +            // Return address is wait_reset, but we must set the thumb bit. +            uintptr_t target = (uintptr_t)wait_reset | 0x1; +            asm volatile("mov r0, %[stack_top]      \n\t" // Reset stack +                         "mov sp, r0                \n\t" +                         "mov r0, #1                \n\t" +                         "mov r1, %[target_addr]    \n\t" +                         "mov r2, %[cpsr]           \n\t" +                         "push {r2}                 \n\t" // Fake xPSR +                         "push {r1}                 \n\t" // PC target addr +                         "push {r0}                 \n\t" // Fake LR +                         "push {r0}                 \n\t" // Fake R12 +                         "push {r0}                 \n\t" // Fake R3 +                         "push {r0}                 \n\t" // Fake R2 +                         "push {r0}                 \n\t" // Fake R1 +                         "push {r0}                 \n\t" // Fake R0 +                         "mov lr, %[exc_return]     \n\t" +                         "bx lr" +                         : +                         : [stack_top] "r" (STACK_TOP), +                           [target_addr] "r" (target), +                           [exc_return] "r" (EXC_RETURN), +                           [cpsr] "r" (DEFAULT_CPSR) +                         : "r0", "r1", "r2"); +            /* Can't happen. */ +            ASSERT_FAULT(0);          }      }  } | 
