diff options
Diffstat (limited to 'main.cpp')
-rw-r--r-- | main.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
@@ -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(); } |