we also become a kernel module so we can receive the on idle event. This would be an ideal place to do shutdown tasks, eg save position somewhere
usb->addInterface(&dfu_interface);
usb->addDescriptor(&dfu_descriptor);
dfu_interface.iInterface = usb->addString(&dfu_string);
+
+ prep_for_detach = 0;
}
bool DFU::USBEvent_Request(CONTROL_TRANSFER &control)
{
case DFU_DETACH:
{
- usb->disconnect();
+// usb->disconnect();
+ prep_for_detach = 128;
WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET);
- WDT_Start(1000000); // 1 second?
-// for (;;);
+ WDT_Start(250000); // 0.25 seconds
+ // for (;;);
return true;
}
case DFU_GETSTATUS:
{
return false;
}
+
+void DFU::on_module_loaded()
+{
+ register_for_event(ON_IDLE);
+}
+
+void DFU::on_idle(void* argument)
+{
+ if (prep_for_detach)
+ {
+ prep_for_detach--;
+ if (prep_for_detach == 0)
+ {
+ usb->disconnect();
+ for (;;);
+ }
+ }
+}
#include "USBDescriptor.h"
#include "USBDevice_Types.h"
+#include "Module.h"
+
#include <stdint.h>
#define REQ_DFU_DETACH 0x0
} DFU_Status_Response;
-class DFU : public USB_Class_Receiver {
+class DFU : public USB_Class_Receiver, public Module {
public:
DFU(USB *);
virtual bool USBEvent_Request(CONTROL_TRANSFER&);
virtual bool USBEvent_RequestComplete(CONTROL_TRANSFER&, uint8_t *buf, uint32_t length);
+ void on_module_loaded(void);
+ void on_idle(void*);
+
protected:
USB *usb;
usbdesc_string_l(12) dfu_string;
DFU_Status_Response dfu_status;
+
+ int prep_for_detach;
};
#endif /* _DFU_H */
kernel->add_module( &msc );
kernel->add_module( &usbserial );
kernel->add_module( &usbserial2 );
+ kernel->add_module( &dfu );
kernel->add_module( &u );
struct SerialMessage message;