diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2018-02-18 14:45:22 +0100 |
---|---|---|
committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2018-02-18 14:45:22 +0100 |
commit | 3ea5d775acdbd62e1194c002c72b83b26052e1a3 (patch) | |
tree | 2e5f72e77532b56bcc562f6eba637a8005f8f176 | |
parent | 652595d813d8f9eb13794cb53b3462d9f667cdc3 (diff) |
Added control requests to support autoupgrade.
-rwxr-xr-x | hidflash.py | 3 | ||||
-rw-r--r-- | main.cpp | 62 |
2 files changed, 65 insertions, 0 deletions
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 @@ -1,6 +1,7 @@ #include <rcc/flash.h> #include <rcc/rcc.h> #include <rcc/crs.h> +#include <interrupt/interrupt.h> #include <syscfg/syscfg.h> #include <gpio/gpio.h> #include <os/time.h> @@ -8,6 +9,17 @@ #include <usb/usb.h> #include <usb/descriptor.h> +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(); } |