u8 process_dfu_request(StandardRequest *request) { u8 currentState = dfu_status.bState; dfu_status.bStatus = OK; // debug2(" rtyp: %d\n", request->bmRequestType); // debug2(" rqst: %d\n", request->bRequest); // debug2("DFU Index : %d\r\n", request->wIndex); dfuBusy = 1; if (currentState == dfuIDLE) { dfuBusy = 1; if (request->bRequest == DFU_DNLOAD) { if (request->wLength > 0) { dfu_status.bState = dfuDNLOAD_SYNC; if (request->wIndex == 0) { if (request->wValue == 0) { dfuSubCommand = DFU_WAIT_CMD; } else { dfuSubCommand = DFU_CMD_DOWNLOAD; } } else { dfu_status.bState = dfuERROR; dfu_status.bStatus = errUNKNOWN; } } else { dfu_status.bState = dfuERROR; dfu_status.bStatus = errNOTDONE; } } else if (request->bRequest == DFU_UPLOAD) { dfu_status.bState = dfuUPLOAD_IDLE; if (request->wIndex == 0) { if (request->wValue == 0) { dfuSubCommand = DFU_CMD_GET_CMD; } else { dfuSubCommand = DFU_CMD_UPLOAD; address = ENTRY; } } else { dfu_status.bState = dfuERROR; dfu_status.bStatus = errUNKNOWN; } } else if (request->bRequest == DFU_ABORT) { dfu_status.bState = dfuIDLE; dfu_status.bStatus = OK; } else if (request->bRequest == DFU_GETSTATUS) { dfu_status.bState = dfuIDLE; } else if (request->bRequest == DFU_GETSTATE) { dfu_status.bState = dfuIDLE; } else { dfu_status.bState = dfuERROR; dfu_status.bStatus = errSTALLEDPKT; } } else if (currentState == dfuDNLOAD_SYNC) { /* device received block, waiting for DFU_GETSTATUS request */ if (request->bRequest == DFU_GETSTATUS) { /* todo, add routine to wait for last block write to finish */ if (dfu_op_state == INIT) { dfu_op_state = BEGIN; if (dfuSubCommand == DFU_CMD_MASS_ERASE) { dfu_status.bwPollTimeout0 = LOWB(MASS_ERASE_TIME); dfu_status.bwPollTimeout1 = HIGHB(MASS_ERASE_TIME); dfu_status.bwPollTimeout2 = 0x00; } else { dfu_status.bwPollTimeout0 = LOWB(WRITE_TIME); dfu_status.bwPollTimeout1 = HIGHB(WRITE_TIME); dfu_status.bwPollTimeout2 = 0x00; } dfu_status.bState = dfuDNBUSY; } else if (dfu_op_state == BEGIN) { dfu_status.bState = dfuDNLOAD_SYNC; } else if (dfu_op_state == MIDDLE) { dfu_status.bState = dfuDNLOAD_SYNC; } else if (dfu_op_state == END) { dfu_status.bwPollTimeout0 = 0x00; dfu_status.bwPollTimeout1 = 0x00; dfu_status.bwPollTimeout2 = 0x00; dfu_op_state = INIT; dfu_status.bState = dfuDNLOAD_IDLE; } } else if (request->bRequest == DFU_GETSTATE) { dfu_status.bState = dfuDNLOAD_SYNC; } else { dfu_status.bState = dfuERROR; dfu_status.bStatus = errSTALLEDPKT; } } else if (currentState == dfuDNBUSY) { /* if were actually done writing, goto sync, else stay busy */ if (dfu_op_state == END) { dfu_status.bwPollTimeout0 = 0x00; dfu_status.bwPollTimeout1 = 0x00; dfu_status.bwPollTimeout2 = 0x00; dfu_op_state = INIT; dfu_status.bState = dfuDNLOAD_IDLE; } else { dfu_status.bState = dfuDNBUSY; } } else if (currentState == dfuDNLOAD_IDLE) { /* device is expecting dfu_dnload requests */ if (request->bRequest == DFU_DNLOAD) { if (request->wLength > 0) { dfu_status.bState = dfuDNLOAD_SYNC; if (request->wValue == 0) { dfuSubCommand = DFU_WAIT_CMD; } else { dfuSubCommand = DFU_CMD_DOWNLOAD; } } else { dfu_status.bState = dfuMANIFEST_SYNC; } } else if (request->bRequest == DFU_ABORT) { dfu_status.bState = dfuIDLE; address = 0; } else if (request->bRequest == DFU_GETSTATUS) { dfu_status.bState = dfuDNLOAD_IDLE; } else if (request->bRequest == DFU_GETSTATE) { dfu_status.bState = dfuDNLOAD_IDLE; } else { dfu_status.bState = dfuERROR; dfu_status.bStatus = errSTALLEDPKT; } } else if (currentState == dfuMANIFEST_SYNC) { /* device has received last block, waiting DFU_GETSTATUS request */ if (request->bRequest == DFU_GETSTATUS) { dfu_status.bState = dfuMANIFEST; dfu_status.bStatus = OK; } else if (request->bRequest == DFU_GETSTATE) { dfu_status.bState = dfuMANIFEST_SYNC; } else { dfu_status.bState = dfuERROR; dfu_status.bStatus = errSTALLEDPKT; } } else if (currentState == dfuMANIFEST) { /* device is in manifestation phase */ dfu_status.bState = dfuMANIFEST; dfu_status.bStatus = OK; } else if (currentState == dfuMANIFEST_WAIT_RESET) { dfu_status.bState = dfuMANIFEST_WAIT_RESET; } else if (currentState == dfuUPLOAD_IDLE) { /* device expecting further dfu_upload requests */ if (request->bRequest == DFU_UPLOAD) { if (request->wLength > 0) { if (request->wValue == 0) { dfuSubCommand = DFU_CMD_GET_CMD; } else { dfuSubCommand = DFU_CMD_UPLOAD; } } else { dfuSubCommand = DFU_CMD_UPLOAD; } } else if (request->bRequest == DFU_ABORT) { dfu_status.bState = dfuIDLE; address = 0; } else if (request->bRequest == DFU_GETSTATUS) { dfu_status.bState = dfuUPLOAD_IDLE; } else if (request->bRequest == DFU_GETSTATE) { dfu_status.bState = dfuUPLOAD_IDLE; } else { dfu_status.bState = dfuERROR; dfu_status.bStatus = errSTALLEDPKT; } } else if (currentState == dfuERROR) { /* status is in error, awaiting DFU_CLRSTATUS request */ if (request->bRequest == DFU_GETSTATUS) { /* todo, add routine to wait for last block write to finish */ dfu_status.bState = dfuERROR; } else if (request->bRequest == DFU_GETSTATE) { dfu_status.bState = dfuERROR; } else if (request->bRequest == DFU_CLRSTATUS) { init_dfu(); } else { dfu_status.bState = dfuERROR; dfu_status.bStatus = errSTALLEDPKT; } } else { /* some kind of error... */ dfu_status.bState = dfuERROR; dfu_status.bStatus = errSTALLEDPKT; } if (dfu_status.bStatus == OK) { return TRUE; } else { return FALSE; } }
#include "cdc_descriptors.h" const unsigned char const cdc_device_descriptor[] = { 0x12, // bLength USB_DEVICE_DESCRIPTOR_TYPE, // bDescriptorType 0x0, // bcdUSB (low byte) 0x2, // bcdUSB (high byte) 0x02, // bDeviceClass 0x00, // bDeviceSubClass Abstract Control Model 0x00, // bDeviceProtocol USB_EP0_BUFFER_SIZE, // bMaxPacketSize LOWB(USB_VID), // idVendor (low byte) HIGHB(USB_VID), // idVendor (high byte) LOWB(USB_PID), // idProduct (low byte) HIGHB(USB_PID), // idProduct (high byte) LOWB(USB_DEV), // bcdDevice (low byte) HIGHB(USB_DEV), // bcdDevice (high byte) USB_iManufacturer, // iManufacturer USB_iProduct, // iProduct USB_iSerialNum, // iSerialNumber (none) USB_NUM_CONFIGURATIONS // bNumConfigurations }; #define USB_CONFIG_DESC_TOT_LENGTH 67 const unsigned char const cdc_config_descriptor[] = { 0x09, // bLength USB_CONFIGURATION_DESCRIPTOR_TYPE, // bDescriptorType LOWB(USB_CONFIG_DESC_TOT_LENGTH), // wTotalLength (low byte), TODO: Automatic calculation - sizeof doesn't work here HIGHB(USB_CONFIG_DESC_TOT_LENGTH), // wTotalLength (high byte) USB_NUM_INTERFACES, // bNumInterfaces 0x01, // bConfigurationValue