//############################################################################# // FILE: usbdfu.h // TITLE: Definitions related to the USB Device Firmware Upgrade class //############################################################################# //! //! Copyright: Copyright (C) 2023 Texas Instruments Incorporated - //! All rights reserved not granted herein. //! Limited License. //! //! Texas Instruments Incorporated grants a world-wide, royalty-free, //! non-exclusive license under copyrights and patents it now or hereafter //! owns or controls to make, have made, use, import, offer to sell and sell //! ("Utilize") this software subject to the terms herein. With respect to the //! foregoing patent license, such license is granted solely to the extent that //! any such patent is necessary to Utilize the software alone. The patent //! license shall not apply to any combinations which include this software, //! other than combinations with devices manufactured by or for TI //! ("TI Devices"). //! No hardware patent is licensed hereunder. //! //! Redistributions must preserve existing copyright notices and reproduce this //! license (including the above copyright notice and the disclaimer and //! (if applicable) source code license limitations below) in the documentation //! and/or other materials provided with the distribution. //! //! Redistribution and use in binary form, without modification, are permitted //! provided that the following conditions are met: //! //! * No reverse engineering, decompilation, or disassembly of this software is //! permitted with respect to any software provided in binary form. //! * Any redistribution and use are licensed by TI for use only //! with TI Devices. //! * Nothing shall obligate TI to provide you with source code for the //! software licensed and provided to you in object code. //! //! If software source code is provided to you, modification and redistribution //! of the source code are permitted provided that the following conditions //! are met: //! //! * any redistribution and use of the source code, including any resulting //! derivative works, are licensed by TI for use only with TI Devices. //! * any redistribution and use of any object code compiled from the source //! code and any resulting derivative works, are licensed by TI for use //! only with TI Devices. //! //! Neither the name of Texas Instruments Incorporated nor the names of its //! suppliers may be used to endorse or promote products derived from this //! software without specific prior written permission. //############################################################################# #ifndef __USBDFU_H__ #define __USBDFU_H__ //***************************************************************************** // // DFU attributes as published in the functional descriptor. // //***************************************************************************** #define DFU_ATTR_WILL_DETACH 0x08 #define DFU_ATTR_MANIFEST_TOLERANT \ 0x04 #define DFU_ATTR_CAN_UPLOAD 0x02 #define DFU_ATTR_CAN_DOWNLOAD 0x01 //***************************************************************************** // // The states that the DFU device can be in. These values are reported to // the host in response to a USBD_DFU_REQUEST_GETSTATE request. // //***************************************************************************** typedef enum { eDFUStateAppIdle = 0, eDFUStateAppDetach, eDFUStateIdle, eDFUStateDnloadSync, eDFUStateDnBusy, eDFUStateDnloadIdle, eDFUStateManifestSync, eDFUStateManifest, eDFUStateManifestWaitReset, eDFUStateUploadIdle, eDFUStateError } tDFUState; //***************************************************************************** // // The current error status of the DFU device. These values are reported to // the host in response to a USBD_DFU_REQUEST_GETSTATUS request. // //***************************************************************************** typedef enum { eDFUStatusOk = 0, eDFUStatusErrTarget, eDFUStatusErrFile, eDFUStatusErrWrite, eDFUStatusErrErase, eDFUStatusErrCheckErased, eDFUStatusErrProg, eDFUStatusErrVerify, eDFUStatusErrAddress, eDFUStatusErrNotDone, eDFUStatusErrFirmware, eDFUStatusErrVendor, eDFUStatusErrUSBR, eDFUStatusErrPOR, eDFUStatusErrUnknown, eDFUStatusErrStalledPkt } tDFUStatus; //***************************************************************************** // // The descriptor type for the DFU functional descriptor. // //***************************************************************************** #define USB_DFU_FUNC_DESCRIPTOR_TYPE \ 0x21 //***************************************************************************** // // The subclass identifier for DFU as reported to the host in the // bInterfaceSubClass field of the DFU interface descriptor. // //***************************************************************************** #define USB_DFU_SUBCLASS 0x01 //***************************************************************************** // // The protocol identifier for DFU as reported to the host in the // bInterfaceProtocol field of the DFU interface descriptor. // //***************************************************************************** #define USB_DFU_PROTOCOL 0x02 #define USB_DFU_RUNTIME_PROTOCOL \ 0x01 //***************************************************************************** // // DFU class-specific request identifiers. // //***************************************************************************** #define USBD_DFU_REQUEST_DETACH 0 #define USBD_DFU_REQUEST_DNLOAD 1 #define USBD_DFU_REQUEST_UPLOAD 2 #define USBD_DFU_REQUEST_GETSTATUS \ 3 #define USBD_DFU_REQUEST_CLRSTATUS \ 4 #define USBD_DFU_REQUEST_GETSTATE \ 5 #define USBD_DFU_REQUEST_ABORT 6 //***************************************************************************** // // Request 1KB blocks from the host. This value is published in the USB // functional descriptor. // //***************************************************************************** #define DFU_TRANSFER_SIZE 1024 //***************************************************************************** // // USBLib-specific request identifier. This is used to determine whether // the target device supports our DFU command protocol. It is expected that // a device not supporting our extensions will stall this request. This // request is only supported while the DFU device is in eDFUStateIdle. // // An IN request containing the following parameters will result in the device // sending back a tDFUQueryC2000Protocol structure indicating that // USBLib extensions are supported. The actual values in wValue and wIndex // have no meaning other than to act as markers in the unlikely event that // another DFU device also chooses to use request ID 0x42 for some other // purpose. // // wValue - 0x23(REQUEST_C2000_VALUE) // wIndex - Interface number // wLength - sizeof(tDFUQueryC2000Protocol) // //***************************************************************************** #define USBD_DFU_REQUEST_C2000 0x42 #define REQUEST_C2000_VALUE 0x23 #define DFU_PROTOCOL_C2000_MARKER \ 0x4C4D #define DFU_PROTOCOL_C2000_VERSION_1 \ 0x0001 #ifdef __ICCARM__ #pragma pack(1) #endif //***************************************************************************** // // The structure sent to the host when a valid USBD_DFU_REQUEST_C2000 is // received while the DFU device is in idle state. // //***************************************************************************** typedef struct { // // The protocol marker(DFU_PROTOCOL_C2000_MARKER) // uint16_t ui16Marker; // // The protocol version(DFU_PROTOCOL_C2000_VERSION_1) // uint16_t ui16Version; } PACKED tDFUQueryC2000Protocol; //***************************************************************************** // // Structure sent to the host in response to USBD_DFU_REQUEST_GETSTATUS. // //***************************************************************************** typedef struct { uint8_t bStatus; uint8_t bwPollTimeout[3]; uint8_t bState; uint8_t iString; } PACKED tDFUGetStatusResponse; //***************************************************************************** // // Firmware Download Commands // // The data passed on a USBD_DFU_REQUEST_DNLOAD request is comprised of a // header which instructs the boot loader how to interpret the block and // block-specific data. The following definitions relate to the download // block headers. // //***************************************************************************** //***************************************************************************** // // Supported command identifiers // //***************************************************************************** #define DFU_CMD_PROG 0x01 #define DFU_CMD_READ 0x02 #define DFU_CMD_CHECK 0x03 #define DFU_CMD_ERASE 0x04 #define DFU_CMD_INFO 0x05 #define DFU_CMD_BIN 0x06 #define DFU_CMD_RESET 0x07 //***************************************************************************** // // Generic download command header. // //***************************************************************************** typedef struct { // // Command identifier. // uint8_t ui8Command; // // Command-specific data elements. // uint8_t pui8Data[7]; } PACKED tDFUDownloadHeader; //***************************************************************************** // // Header for the DFU_CMD_PROG command. // // This command is used to program a section of the flash with the binary data // which immediately follows the header. The start address of the data is // expressed as a 1KB block number so 0 would represent the bottom of flash // (which, incidentally, the USB boot loader will not let you program) and 0x10 // would represent address 16KB or 16384 (0x4000). The ui32Length field // contains the total number of bytes of data in the following programming // operation. The DFU device will not look for any command header on following // USBD_DFU_REQUEST_DNLOAD requests until the operation is completed or // aborted. // // By using this protocol, the DFU_CMD_PROG command header may be used as a // simple header on the binary files to be sent to the DFU device for // programming. If we enforce the requirement that the DFU_CMD_PROG header is // applied to each USBD_DFU_REQUEST_DNLOAD (one per block), this means that the // host-side DFU application must be aware of the underlying protocol and // insert these headers dynamically during programming operations. This could // be handled by post processing the binary to insert the headers at the // appropriate points but this would then tie the binary structure to the // chosen transfer size and break the operation if the transfer size were to // change in the future. // //***************************************************************************** typedef struct { // // DFU_CMD_PROG // uint8_t ui8Command; // // Reserved - set to 0x00. // uint8_t ui8Reserved; // // Block start address / 1024 // uint16_t ui16StartAddr; // // Total length, in bytes, of following data for the complete download // operation. // uint32_t ui32Length; } PACKED tDFUDownloadProgHeader; //***************************************************************************** // // Header for the DFU_CMD_READ and DFU_CMD_CHECK commands. // // This command may be used to set the address range whose content will be // returned on subsequent USBD_DFU_REQUEST_UPLOAD requests from the host. // // To read back a the contents of a region of flash, the host should send // USBD_DFU_REQUEST_DNLOAD with ui8Command DFU_CMD_READ, ui16StartAddr set to // the 1KB block start address and ui32Length set to the number of bytes to // read. The host should then send one or more USBD_DFU_REQUEST_UPLOAD // requests to receive the current flash contents from the configured // addresses. Data returned will include an 8 byte DFU_CMD_PROG prefix // structure unless the prefix has been disabled by sending a DFU_CMD_BIN // command with the bBinary parameter set to 1. // // To check that a region of flash is erased, the DFU_CMD_CHECK command should // be sent with ui16StartAddr and ui32Length set to describe the region to // check. The host should then send a USBD_DFU_REQUEST_GETSTATUS. If the // erase check was successful, the returned bStatus value will be STATUS_OK, // otherwise it will be STATUS_ERR_CHECK_ERASED. Note that ui32Length passed // must be a multiple of 4. If this is not the case, the value will be // truncated before the check is performed. // //***************************************************************************** typedef struct { // // DFU_CMD_READ or DFU_CMD_CHECK // uint8_t ui8Command; // // Reserved - write to 0 // uint8_t ui8Reserved; // // Block start address / 1024 // uint16_t ui16StartAddr; // // The number of bytes of data to read back or check. // uint32_t ui32Length; } PACKED tDFUDownloadReadCheckHeader; //***************************************************************************** // // Header for the DFU_CMD_ERASE command. // // This command may be used to erase a number of flash blocks. The address of // the first block to be erased is passed in ui16StartAddr with ui16NumBlocks // containing the number of blocks to be erased from this address. The block // size of the device may be determined using the DFU_CMD_INFO command. // //***************************************************************************** typedef struct { // // DFU_CMD_ERASE // uint8_t ui8Command; // // Reserved - set to 0. // uint8_t ui8Reserved; // // Block start address / 1024 // uint16_t ui16StartAddr; // // The number of blocks to erase. // uint16_t ui16NumBlocks; // // Reserved - set to 0. // uint8_t pui8Reserved2[2]; } PACKED tDFUDownloadEraseHeader; //***************************************************************************** // // Header for the DFU_CMD_INFO command. // // This command may be used to query information about the connected device. // After sending the command, the information is returned on the next // USBD_DFU_REQUEST_UPLOAD request. // //***************************************************************************** typedef struct { // // DFU_CMD_INFO // uint8_t ui8Command; // // Reserved - set to 0. // uint8_t pui8Reserved[7]; } PACKED tDFUDownloadInfoHeader; //***************************************************************************** // // Header for the DFU_CMD_BIN command. // // This command may be used to set the format of uploaded data. By default, // images read using USBD_DFU_REQUEST_UPLOAD are formatted with the appropriate // header to allow the same image to be flashed back to the device and have it // located at the address from which it originated. This is a requirement of // the DFU class specification (section 6.2 "the uploaded image must be // usable in a subsequent download") but may not be helpful in some cases where // the application wishes to receive only the binary image from flash. To // instruct the DFU device to omit the position and size header, send this // command with the bBinary field set to \b true prior to issuing a // USBD_DFU_REQUEST_UPLOAD for image data. The format choice remains in effect // until the command is sent once again with bBinary set to \b false. // // Note that the format choice affects only image data sent and not responses // read via USBD_DFU_REQUEST_UPLOAD following USBLib-specific commands such // as DFU_CMD_INFO. // //***************************************************************************** typedef struct { // // DFU_CMD_BIN // uint8_t ui8Command; // // Set to true to omit image header or false to include it (the default). // uint8_t ui8Binary; // // Reserved - set to 0. // uint8_t pui8Reserved[6]; } PACKED tDFUDownloadBinHeader; //***************************************************************************** // // The DFU_CMD_RESET command uses a tDFUDownloadHeader structure since // only the ui8Command field is important. This command causes an immediate // reset of the the target board. // //***************************************************************************** //***************************************************************************** // //! Payload returned in response to the DFU_CMD_INFO command. //! //! This is structure is returned in response to the first //! USBD_DFU_REQUEST_UPLOAD request following a DFU_CMD_INFO command. // //***************************************************************************** typedef struct { // //! The size of a flash block in bytes. // uint16_t ui16FlashBlockSize; // //! The number of blocks of flash in the device. Total flash size is //! ui16NumFlashBlocks * ui16FlashBlockSize. // uint16_t ui16NumFlashBlocks; // //! Information on the part number, family, version and package as //! read from SYSCTL register DID1. // uint32_t ui32PartInfo; // //! Information on the part class and revision as read from SYSCTL DID0. // uint32_t ui32ClassInfo; // //! Address 1 byte above the highest location the boot loader can access. // uint32_t ui32FlashTop; // //! Lowest address the boot loader can write or erase. // uint32_t ui32AppStartAddr; } PACKED tDFUDeviceInfo; #ifdef __ICCARM__ #pragma pack() #endif #endif // __USBDFU_H__