Example #1
0
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