#include "project.h" const struct usb_dfu_descriptor dfu_function = { .bLength = sizeof (struct usb_dfu_descriptor), .bDescriptorType = DFU_FUNCTIONAL, .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH, .wDetachTimeout = 255, .wTransferSize = 1024, .bcdDFUVersion = 0x011A, }; const struct usb_interface_descriptor dfu_iface = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, .bInterfaceNumber = 1, .bAlternateSetting = 0, .bNumEndpoints = 0, .bInterfaceClass = 0xFE, .bInterfaceSubClass = 1, .bInterfaceProtocol = 1, .iInterface = 4, .extra = &dfu_function, .extralen = sizeof (dfu_function), }; const struct usb_iface_assoc_descriptor dfu_iface_assoc = { .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, .bFirstInterface = 1, .bInterfaceCount = 1, .bFunctionClass = 0xfe, .bFunctionSubClass = 1, .bFunctionProtocol = 1, .iFunction = 5, }; static void dfu_detach_complete (usbd_device *usbd_dev, struct usb_setup_data *req) { (void) req; (void) usbd_dev; dfu_flag = 0xfee1dead; scb_reset_core(); } enum usbd_request_return_codes dfu_control_request (usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete) { (void) buf; (void) len; (void) usbd_dev; if ((req->bmRequestType & 0x7F) != 0x21) return USBD_REQ_NEXT_CALLBACK; switch (req->bRequest) { case DFU_GETSTATUS: { (*buf) [0] = DFU_STATUS_OK; (*buf) [1] = 0; (*buf) [2] = 0; (*buf) [3] = 0; (*buf) [4] = STATE_APP_IDLE; (*buf) [5] = 0; /* iString not used here */ *len = 6; return USBD_REQ_HANDLED; } case DFU_GETSTATE: /* Return state with no state transision. */ *buf[0] = STATE_APP_IDLE; *len = 1; return USBD_REQ_HANDLED; case DFU_DETACH: *complete = dfu_detach_complete; return USBD_REQ_HANDLED; } return USBD_REQ_NEXT_CALLBACK; }