From 3ea5d775acdbd62e1194c002c72b83b26052e1a3 Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Sun, 18 Feb 2018 14:45:22 +0100 Subject: Added control requests to support autoupgrade. --- hidflash.py | 3 +++ main.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/hidflash.py b/hidflash.py index a9df48c..a5b4197 100755 --- a/hidflash.py +++ b/hidflash.py @@ -13,6 +13,9 @@ for segment in sorted(e.iter_segments(), key = lambda x: x.header.p_paddr): if segment.header.p_type != 'PT_LOAD': continue + if segment.header.p_paddr >= 0x20000000: + continue + data = segment.data() lma = segment.header.p_paddr diff --git a/main.cpp b/main.cpp index 8e267bf..9aae4ee 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -8,6 +9,17 @@ #include #include +const uint8_t fw_version = 1; + +uint32_t reset_reason __attribute__((section(".bootinfo"))); + +static bool do_reset; + +void reset_bootloader() { + reset_reason = 0xb007; + SCB.AIRCR = (0x5fa << 16) | (1 << 2); // SYSRESETREQ +} + enum tag_type_t { ISO15693, ISO18092, @@ -129,6 +141,52 @@ class USB_keypad : public USB_class_driver { USB_keypad usb_keypad(usb); +class USB_fwver : public USB_class_driver { + private: + USB_generic& usb; + + bool reset_boot(uint16_t wValue, uint16_t wIndex, uint16_t wLength) { + if(wValue != 0xb007) { + return false; + } + + do_reset = true; + + usb.write(0, nullptr, 0); + return true; + } + + bool get_version(uint16_t wValue, uint16_t wIndex, uint16_t wLength) { + if(wLength < 1) { + return false; + } + + uint32_t buf = fw_version; + usb.write(0, &buf, 1); + return true; + } + + public: + USB_fwver(USB_generic& usbd) : usb(usbd) { + usb.register_driver(this); + } + + protected: + virtual SetupStatus handle_setup(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) { + if(bmRequestType == 0xc0 && bRequest == 0xf0) { + return get_version(wValue, wIndex, wLength) ? SetupStatus::Ok : SetupStatus::Stall; + } + + if(bmRequestType == 0x40 && bRequest == 0xff) { + return reset_boot(wValue, wIndex, wLength) ? SetupStatus::Ok : SetupStatus::Stall; + } + + return SetupStatus::Unhandled; + } +}; + +USB_fwver usb_fwver(usb); + int main() { rcc_init(); @@ -269,6 +327,10 @@ int main() { kp_last = kp_state; } + if(do_reset) { + Time::sleep(10); + reset_bootloader(); + } usb.process(); } -- cgit v1.2.3