/* * The MIT License (MIT) * * Copyright (c) 2019 N Conrad * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * This file is part of the TinyUSB stack. */ #ifndef _TUSB_USBTMC_H__ #define _TUSB_USBTMC_H__ #include "common/tusb_common.h" /* Implements USBTMC Revision 1.0, April 14, 2003 String descriptors must have a "LANGID=0x409"/US English string. Characters must be 0x20 (' ') to 0x7E ('~') ASCII, But MUST not contain: "/:?\* Also must not have leading or trailing space (' ') Device descriptor must state USB version 0x0200 or greater If USB488DeviceCapabilites.D2 = 1 (SR1), then there must be a INT endpoint. */ #define USBTMC_VERSION 0x0100 #define USBTMC_488_VERSION 0x0100 typedef enum { USBTMC_MSGID_DEV_DEP_MSG_OUT = 1u, USBTMC_MSGID_DEV_DEP_MSG_IN = 2u, USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT = 126u, USBTMC_MSGID_VENDOR_SPECIFIC_IN = 127u, USBTMC_MSGID_USB488_TRIGGER = 128u, } usbtmc_msgid_enum; /// \brief Message header (For BULK OUT and BULK IN); 4 bytes typedef struct TU_ATTR_PACKED { uint8_t MsgID ; ///< Message type ID (usbtmc_msgid_enum) uint8_t bTag ; ///< Transfer ID 1<=bTag<=255 uint8_t bTagInverse ; ///< Complement of the tag uint8_t _reserved ; ///< Must be 0x00 } usbtmc_msg_header_t; typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header; uint8_t data[8]; } usbtmc_msg_generic_t; /* Uses on the bulk-out endpoint: */ // Next 8 bytes are message-specific typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header ; ///< Header uint32_t TransferSize ; ///< Transfer size; LSB first struct TU_ATTR_PACKED { unsigned int EOM : 1 ; ///< EOM set on last byte } bmTransferAttributes; uint8_t _reserved[3]; } usbtmc_msg_request_dev_dep_out; TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_dev_dep_out) == 12u, "struct wrong length"); // Next 8 bytes are message-specific typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header ; ///< Header uint32_t TransferSize ; ///< Transfer size; LSB first struct TU_ATTR_PACKED { unsigned int TermCharEnabled : 1 ; ///< "The Bulk-IN transfer must terminate on the specified TermChar."; CAPABILITIES must list TermChar } bmTransferAttributes; uint8_t TermChar; uint8_t _reserved[2]; } usbtmc_msg_request_dev_dep_in; TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_dev_dep_in) == 12u, "struct wrong length"); /* Bulk-in headers */ typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header; uint32_t TransferSize; struct TU_ATTR_PACKED { uint8_t EOM: 1; ///< Last byte of transfer is the end of the message uint8_t UsingTermChar: 1; ///< Support TermChar && Request.TermCharEnabled && last char in transfer is TermChar } bmTransferAttributes; uint8_t _reserved[3]; } usbtmc_msg_dev_dep_msg_in_header_t; TU_VERIFY_STATIC(sizeof(usbtmc_msg_dev_dep_msg_in_header_t) == 12u, "struct wrong length"); /* Unsupported vendor things.... Are these ever used?*/ typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header ; ///< Header uint32_t TransferSize ; ///< Transfer size; LSB first uint8_t _reserved[4]; } usbtmc_msg_request_vendor_specific_out; TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_out) == 12u, "struct wrong length"); typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header ; ///< Header uint32_t TransferSize ; ///< Transfer size; LSB first uint8_t _reserved[4]; } usbtmc_msg_request_vendor_specific_in; TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_in) == 12u, "struct wrong length"); // Control request type should use tusb_control_request_t /* typedef struct TU_ATTR_PACKED { struct { unsigned int Recipient : 5 ; ///< EOM set on last byte unsigned int Type : 2 ; ///< EOM set on last byte unsigned int DirectionToHost : 1 ; ///< 0 is OUT, 1 is IN } bmRequestType; uint8_t bRequest ; ///< If bmRequestType.Type = Class, see usmtmc_request_type_enum uint16_t wValue ; uint16_t wIndex ; uint16_t wLength ; // Number of bytes in data stage } usbtmc_class_specific_control_req; */ // bulk-in protocol errors enum { USBTMC_BULK_IN_ERR_INCOMPLETE_HEADER = 1u, USBTMC_BULK_IN_ERR_UNSUPPORTED = 2u, USBTMC_BULK_IN_ERR_BAD_PARAMETER = 3u, USBTMC_BULK_IN_ERR_DATA_TOO_SHORT = 4u, USBTMC_BULK_IN_ERR_DATA_TOO_LONG = 5u, }; // bult-in halt errors enum { USBTMC_BULK_IN_ERR = 1u, ///< receives a USBTMC command message that expects a response while a /// Bulk-IN transfer is in progress }; typedef enum { USBTMC_bREQUEST_INITIATE_ABORT_BULK_OUT = 1u, USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS = 2u, USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN = 3u, USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS = 4u, USBTMC_bREQUEST_INITIATE_CLEAR = 5u, USBTMC_bREQUEST_CHECK_CLEAR_STATUS = 6u, USBTMC_bREQUEST_GET_CAPABILITIES = 7u, USBTMC_bREQUEST_INDICATOR_PULSE = 64u, // Optional /****** USBTMC 488 *************/ USB488_bREQUEST_READ_STATUS_BYTE = 128u, USB488_bREQUEST_REN_CONTROL = 160u, USB488_bREQUEST_GO_TO_LOCAL = 161u, USB488_bREQUEST_LOCAL_LOCKOUT = 162u, } usmtmc_request_type_enum; typedef enum { USBTMC_STATUS_SUCCESS = 0x01, USBTMC_STATUS_PENDING = 0x02, USBTMC_STATUS_FAILED = 0x80, USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS = 0x81, USBTMC_STATUS_SPLIT_NOT_IN_PROGRESS = 0x82, USBTMC_STATUS_SPLIT_IN_PROGRESS = 0x83, /****** USBTMC 488 *************/ USB488_STATUS_INTERRUPT_IN_BUSY = 0x20 } usbtmc_status_enum; /************************************************************ * Control Responses */ typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; ///< usbtmc_status_enum uint8_t _reserved; uint16_t bcdUSBTMC; ///< USBTMC_VERSION struct TU_ATTR_PACKED { unsigned int listenOnly :1; unsigned int talkOnly :1; unsigned int supportsIndicatorPulse :1; } bmIntfcCapabilities; struct TU_ATTR_PACKED { unsigned int canEndBulkInOnTermChar :1; } bmDevCapabilities; uint8_t _reserved2[6]; uint8_t _reserved3[12]; } usbtmc_response_capabilities_t; TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_t) == 0x18, "struct wrong length"); typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; struct TU_ATTR_PACKED { unsigned int BulkInFifoBytes :1; } bmClear; } usbtmc_get_clear_status_rsp_t; TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length"); // Used for both abort bulk IN and bulk OUT typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; uint8_t bTag; } usbtmc_initiate_abort_rsp_t; TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length"); // Used for both check_abort_bulk_in_status and check_abort_bulk_out_status typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; struct TU_ATTR_PACKED { unsigned int BulkInFifoBytes : 1; ///< Has queued data or a short packet that is queued } bmAbortBulkIn; uint8_t _reserved[2]; ///< Must be zero uint32_t NBYTES_RXD_TXD; } usbtmc_check_abort_bulk_rsp_t; TU_VERIFY_STATIC(sizeof(usbtmc_check_abort_bulk_rsp_t) == 8u, "struct wrong length"); typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; ///< usbtmc_status_enum uint8_t _reserved; uint16_t bcdUSBTMC; ///< USBTMC_VERSION struct TU_ATTR_PACKED { unsigned int listenOnly :1; unsigned int talkOnly :1; unsigned int supportsIndicatorPulse :1; } bmIntfcCapabilities; struct TU_ATTR_PACKED { unsigned int canEndBulkInOnTermChar :1; } bmDevCapabilities; uint8_t _reserved2[6]; uint16_t bcdUSB488; struct TU_ATTR_PACKED { unsigned int is488_2 :1; unsigned int supportsREN_GTL_LLO :1; unsigned int supportsTrigger :1; } bmIntfcCapabilities488; struct TU_ATTR_PACKED { unsigned int SCPI :1; unsigned int SR1 :1; unsigned int RL1 :1; unsigned int DT1 :1; } bmDevCapabilities488; uint8_t _reserved3[8]; } usbtmc_response_capabilities_488_t; TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_488_t) == 0x18, "struct wrong length"); typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; uint8_t bTag; uint8_t statusByte; } usbtmc_read_stb_rsp_488_t; TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length"); typedef struct TU_ATTR_PACKED { struct TU_ATTR_PACKED { unsigned int bTag : 7; unsigned int one : 1; } bNotify1; uint8_t StatusByte; } usbtmc_read_stb_interrupt_488_t; TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_interrupt_488_t) == 2u, "struct wrong length"); #endif