summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2018-02-18 14:45:22 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2018-02-18 14:45:22 +0100
commit3ea5d775acdbd62e1194c002c72b83b26052e1a3 (patch)
tree2e5f72e77532b56bcc562f6eba637a8005f8f176
parent652595d813d8f9eb13794cb53b3462d9f667cdc3 (diff)
Added control requests to support autoupgrade.
-rwxr-xr-xhidflash.py3
-rw-r--r--main.cpp62
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
diff --git a/main.cpp b/main.cpp
index 8e267bf..9aae4ee 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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();
}