diff --git a/class/dfu/usbd_dfu.c b/class/dfu/usbd_dfu.c new file mode 100644 index 00000000..58e94f6a --- /dev/null +++ b/class/dfu/usbd_dfu.c @@ -0,0 +1,72 @@ +#include "usbd_core.h" +#include "usbd_dfu.h" + +/* Device data structure */ +struct dfu_cfg_private { + struct dfu_info info; +} usbd_dfu_cfg; + +int dfu_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) +{ + USBD_LOG_DBG("DFU Class request: " + "bRequest 0x%02x\r\n", + setup->bRequest); + + switch (setup->bRequest) { + case DFU_REQUEST_DETACH: + + break; + + case DFU_REQUEST_DNLOAD: + + break; + case DFU_REQUEST_UPLOAD: + + break; + case DFU_REQUEST_GETSTATUS: + + break; + case DFU_REQUEST_CLRSTATUS: + + break; + case DFU_REQUEST_GETSTATE: + + break; + case DFU_REQUEST_ABORT: + + break; + default: + USBD_LOG_ERR("Unhandled request 0x%02x", setup->bRequest); + break; + } + + return 0; +} + +void dfu_notify_handler(uint8_t event, void *arg) +{ + switch (event) { + case USB_EVENT_RESET: + + break; + + default: + break; + } +} + +void usbd_dfu_add_interface(usbd_class_t *class, usbd_interface_t *intf) +{ + static usbd_class_t *last_class = NULL; + + if (last_class != class) { + last_class = class; + usbd_class_register(class); + } + + intf->class_handler = dfu_class_request_handler; + intf->custom_handler = NULL; + intf->vendor_handler = NULL; + intf->notify_handler = dfu_notify_handler; + usbd_class_add_interface(class, intf); +} \ No newline at end of file diff --git a/class/dfu/usbd_dfu.h b/class/dfu/usbd_dfu.h new file mode 100644 index 00000000..c5f7a045 --- /dev/null +++ b/class/dfu/usbd_dfu.h @@ -0,0 +1,113 @@ +/** + * @file + * @brief USB DFU Device Class public header + * + */ + +#ifndef _USBD_DFU_H_ +#define _USBD_DFU_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/**\addtogroup USB_MODULE_DFU USB DFU class + * \brief This module contains USB Device Firmware Upgrade class definitions. + * \details This module based on + * + [USB Device Firmware Upgrade Specification, Revision 1.1] + * (https://www.usb.org/sites/default/files/DFU_1.1.pdf) + * @{ */ + +/** DFU Specification release */ +#define DFU_VERSION 0x0110 + +/** DFU Class Subclass */ +#define DFU_SUBCLASS_DFU 0x01 + +/** DFU Class runtime Protocol */ +#define DFU_PROTOCOL_RUNTIME 0x01 + +/** DFU Class DFU mode Protocol */ +#define DFU_PROTOCOL_MODE 0x02 + +/** + * @brief DFU Class Specific Requests + */ +#define DFU_REQUEST_DETACH 0x00 +#define DFU_REQUEST_DNLOAD 0x01 +#define DFU_REQUEST_UPLOAD 0x02 +#define DFU_REQUEST_GETSTATUS 0x03 +#define DFU_REQUEST_CLRSTATUS 0x04 +#define DFU_REQUEST_GETSTATE 0x05 +#define DFU_REQUEST_ABORT 0x06 + +/** DFU FUNCTIONAL descriptor type */ +#define DFU_FUNC_DESC 0x21 + +/** DFU attributes DFU Functional Descriptor */ +#define DFU_ATTR_WILL_DETACH 0x08 +#define DFU_ATTR_MANIFESTATION_TOLERANT 0x04 +#define DFU_ATTR_CAN_UPLOAD 0x02 +#define DFU_ATTR_CAN_DNLOAD 0x01 + +/** bStatus values for the DFU_GETSTATUS response */ +#define DFU_STATUS_OK 0x00U +#define DFU_STATUS_ERR_TARGET 0x01U +#define DFU_STATUS_ERR_FILE 0x02U +#define DFU_STATUS_ERR_WRITE 0x03U +#define DFU_STATUS_ERR_ERASE 0x04U +#define DFU_STATUS_ERR_CHECK_ERASED 0x05U +#define DFU_STATUS_ERR_PROG 0x06U +#define DFU_STATUS_ERR_VERIFY 0x07U +#define DFU_STATUS_ERR_ADDRESS 0x08U +#define DFU_STATUS_ERR_NOTDONE 0x09U +#define DFU_STATUS_ERR_FIRMWARE 0x0AU +#define DFU_STATUS_ERR_VENDOR 0x0BU +#define DFU_STATUS_ERR_USB 0x0CU +#define DFU_STATUS_ERR_POR 0x0DU +#define DFU_STATUS_ERR_UNKNOWN 0x0EU +#define DFU_STATUS_ERR_STALLEDPKT 0x0FU + +/** bState values for the DFU_GETSTATUS response */ +#define DFU_STATE_APP_IDLE 0U +#define DFU_STATE_APP_DETACH 1U +#define DFU_STATE_DFU_IDLE 2U +#define DFU_STATE_DFU_DNLOAD_SYNC 3U +#define DFU_STATE_DFU_DNLOAD_BUSY 4U +#define DFU_STATE_DFU_DNLOAD_IDLE 5U +#define DFU_STATE_DFU_MANIFEST_SYNC 6U +#define DFU_STATE_DFU_MANIFEST 7U +#define DFU_STATE_DFU_MANIFEST_WAIT_RESET 8U +#define DFU_STATE_DFU_UPLOAD_IDLE 9U +#define DFU_STATE_DFU_ERROR 10U + +/** Run-Time Functional Descriptor */ +struct dfu_runtime_descriptor { + uint8_t bLength; /**<\brief Descriptor length in bytes.*/ + uint8_t bDescriptorType; /**<\brief DFU functional descriptor type.*/ + uint8_t bmAttributes; /**<\brief USB DFU capabilities \ref USB_DFU_CAPAB*/ + uint16_t wDetachTimeout; /**<\brief USB DFU detach timeout in ms.*/ + uint16_t wTransferSize; /**<\brief USB DFU maximum transfer block size in bytes.*/ + uint16_t bcdDFUVersion; /**<\brief USB DFU version \ref VERSION_BCD utility macro.*/ +} __packed; + +/**\brief Payload packet to response in DFU_GETSTATUS request */ +struct dfu_info { + uint8_t bStatus; /**<\brief An indication of the status resulting from the + * execution of the most recent request.*/ + uint8_t bPollTimeout; /**<\brief Minimum time (LSB) in ms, that the host should wait + * before sending a subsequent DFU_GETSTATUS request.*/ + uint16_t wPollTimeout; /**<\brief Minimum time (MSB) in ms, that the host should wait + * before sending a subsequent DFU_GETSTATUS request.*/ + uint8_t bState; /**<\brief An indication of the state that the device is going + * to enter immediately following transmission of this response.*/ + uint8_t iString; /**<\brief Index of the status string descriptor.*/ +}; + +void usbd_dfu_add_interface(usbd_class_t *class, usbd_interface_t *intf); + +#ifdef __cplusplus +} +#endif + +#endif /* _USBD_DFU_H_ */ diff --git a/class/tmc/usbd_tmc.h b/class/tmc/usbd_tmc.h new file mode 100644 index 00000000..1ee8a663 --- /dev/null +++ b/class/tmc/usbd_tmc.h @@ -0,0 +1,138 @@ +/** + * @file + * @brief USB TMC Device Class public header + * + */ + +#ifndef _USBD_TMC_H_ +#define _USBD_TMC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup MODULE_TMC USB TMC class + * @brief This module contains USB Device Test and Measurement Class definitions. + * @details This module based on + * [USB Device Test and Measurement Class Specification, Revision 1.0] + * (https://www.usb.org/sites/default/files/USBTMC_1_006a.zip) + * @{*/ + +/**@name USB TMC class, subclass and protocol definitions + * @{*/ +#define TMC_SUBCLASS_TMC 0x03 +#define TMC_PROTOCOL_NONE 0x00 /**< No subclass specification applies. */ +#define TMC_PROTOCOL_USB488 0x01 /**< USBTMC USB488 subclass interface. */ +/** @}*/ + +/**@name USBTMC requests + * @{*/ +#define TMC_REQUEST_INITIATE_ABORT_BULK_OUT 1 +#define TMC_REQUEST_CHECK_ABORT_BULK_OUT_STATUS 2 +#define TMC_REQUEST_INITIATE_ABORT_BULK_IN 3 +#define TMC_REQUEST_CHECK_ABORT_BULK_IN_STATUS 4 +#define TMC_REQUEST_INITIATE_CLEAR 5 +#define TMC_REQUEST_CHECK_CLEAR_STATUS 6 +#define TMC_REQUEST_GET_CAPABILITIES 7 +#define TMC_REQUEST_INDICATOR_PULSE 64 +/**@}*/ + +/**@name USBTMC status values + * @{*/ +#define TMC_STATUS_SUCCESS 0x01 +#define TMC_STATUS_PENDING 0x02 +#define TMC_STATUS_FAILED 0x80 +#define TMC_STATUS_TRANSFER_NOT_IN_PROGRESS 0x81 +#define TMC_STATUS_SPLIT_NOT_IN_PROGRESS 0x82 +#define TMC_STATUS_SPLIT_IN_PROGRESS 0x83 +/**@}*/ + +/** GET_CAPABILITIES request response */ +struct tmc_get_capabilities_response { + uint8_t USBTMC_status; + uint8_t Reserved0; + uint16_t bcdUSBTMC; + uint8_t InterfaceCapabilities; + uint8_t DeviceCapabilities; + uint8_t Reserved1[18]; +} __packed; + +/**@name MsgId values + * @{*/ +#define TMC_DEV_DEP_MSG_OUT 1 +#define TMC_REQUEST_DEV_DEP_MSG_IN 2 +#define TMC_DEV_DEP_MSG_IN 2 +#define TMC_VENDOR_SPECIFIC_OUT 126 +#define TMC_REQUEST_VENDOR_SPECIFIC_IN 127 +#define TMC_VENDOR_SPECIFIC_IN 127 +/**@}*/ + +/**@name Transfer Attributes + * @{*/ +/** The last USBTMC message data byte in the transfer is the last byte of the + * USBTMC message. */ +#define TMC_TRANSFER_ATTR_EOM 0x01 +/** The Bulk-IN transfer must terminate on the specified TermChar. The Host may + * only set this bit if the USBTMC interface indicates it supports TermChar in + * the GET_CAPABILITIES response packet */ +#define TMC_TRANSFER_ATTR_TERM_CHAR 0x02 +/**@}*/ + +/** Message specific part of bulk header */ +union usb_tmc_bulk_header_specific { + struct { + uint32_t TransferSize; + uint8_t bmTransferAttributes; + uint8_t Reserved[3]; + } dev_dep_msg_out; + + struct { + uint32_t TransferSize; + uint8_t bmTransferAttributes; + uint8_t TermChar; + uint8_t Reserved[2]; + } request_dev_dep_msg_in; + + struct { + uint32_t TransferSize; + uint8_t bmTransferAttributes; + uint8_t Reserved[3]; + } dev_dep_msg_in; + + struct { + uint32_t TransferSize; + uint8_t Reserved[4]; + } vendor_specific_out; + + struct { + uint32_t TransferSize; + uint8_t Reserved[4]; + } request_vendor_specific_in; + + struct { + uint32_t TransferSize; + uint8_t Reserved[4]; + } vendor_specific_in; +}; + +/** Host must begin the first USB transaction in each Bulk transfer of + * command message content with a Bulk Header. */ +struct usb_tmc_bulk_header { + /** Specifies the USBTMC message and the type of the USBTMC message. */ + uint8_t MsgId; + /** A transfer identifier. The Host must set bTag different than the + * bTag used in the previous Bulk-OUT Header. The Host should increment + * the bTag by 1 each time it sends a new Bulk-OUT Header. */ + uint8_t bTag; + /** The inverse (one's complement) of the bTag */ + uint8_t bTagInverse; + uint8_t Reserved; + /** USBTMC command message specific */ + union usb_tmc_bulk_header_specific MsgSpecific; +} __packed; + +#ifdef __cplusplus +} +#endif + +#endif /* _USBD_TMC_H_ */