#ifndef USBTMCLIB_TYPES_H
#define USBTMCLIB_TYPES_H

    #include <stddef.h>
    #include <stdint.h>

    //----------------------------------------------------------------
    // Refer to:
    // [1] USBTMC Standard, rev. 1.0, 14/04/2003
    //     "Universal Serial Bus Test and Measurement Class Specification (USBTMC)"
    // [2] USBTMC-USB488 Standard, rev. 1.0, 14/04/2003
    //     "Universal Serial Bus Test and Measurement Class, Subclass USB488 Specification (USBTMC-USB488)
    // [3] IEEE 488.1 Standard, ANSI/IEEE Std 488.1-1987
    //     "IEEE Standard Digital Interface, ANSI/IEEE Std 488.1-1987"
    // [4] IEEE 488.2 Standard, revision IEEE Std 488.2-1987
    //     "IEEE Standard Codes, Formats, Protocols, and Common Commands for Use With IEEE Std 488.1-1987, IEEE
    //      Standard Digital Interface for Programmable Instrumentation"
    // [5] SCPI Specification, revision 1999.0
    //     "Standard Commands for Programmable Instruments (SCPI), VERSION 1999.0, May 1999"
    //
    //----------------------------------------------------------------
    //----------------------------------------------------------------
    //----------------------------------------------------------------
    #pragma pack( push, 1 )
    typedef union
    {
         // raw bytes of command specific Bulk-Out Header part
         uint8_t rawBytes[8];

         struct
         {
             // @transferSize
             // Total number of USBTMC message data bytes to be
             // sent in this USB transfer. This does not include the
             // number of bytes in this Bulk-OUT Header or
             // alignment bytes. Sent least significant byte first,
             // most significant byte last. TransferSize must be >
             // 0x00000000.
             uint32_t transferSize;

             // @bmTransferAttributes
             // Bitmap: D7..D1 - Reserved. All bits must be 0.
             //         D0 - EOM, see bm_DEV_DEP_MSG_OUT_EOM
             uint8_t  bmTransferAttributes;

             // @Reserved
             // Reserved. Must be 0x000000.
             uint8_t  Reserved[3];
         }
         DevDepMsgOut; // Applicable for command DEV_DEP_MSG_OUT, Refer to 3.2.1.1 [1]

         struct
         {
             // @transferSize
             // Maximum number of USBTMC message data bytes to
             // be sent in response to the command. This does not
             // include the number of bytes in this Bulk-IN Header or
             // alignment bytes. Sent least significant byte first, most
             // significant byte last. TransferSize must be >
             // 0x00000000.
             uint32_t transferSize;

             // @bmTransferAttributes
             // Bitmap: D7..D2 - Reserved. All bits must be 0.
             //         D1 - TermCharEnabled, see bm_REQUEST_DEV_DEP_MSG_IN_TRMCH
             //         D0 - must be 0.
             uint8_t  bmTransferAttributes;

             // @termChar
             // If bmTransferAttributes.D1 = 1, TermChar is an 8-bit
             // value representing a termination character. If
             // supported, the device must terminate the Bulk-IN
             // transfer after this character is sent.
             // If bmTransferAttributes.D1 = 0, the device must ignore
             // this field.
             uint8_t  termChar;

             // @Reserved
             // Reserved. Must be 0x000000.
             uint8_t  Reserved[2];
         }
         ReqDevDepMsgIn; // Applicable for command REQUEST_DEV_DEP_MSG_IN, Refer to 3.2.1.2 [1]

         struct
         {
             // @transferSize
             // Total number of USBTMC message data bytes to be
             // sent in this USB transfer. This does not include the
             // number of bytes in this Bulk-OUT Header or
             // alignment bytes. Sent least significant byte first,
             // most significant byte last. TransferSize must be >
             // 0x00000000.
             uint32_t transferSize;

             // @Reserved
             // Reserved. Must be 0x000000.
             uint8_t  Reserved[4];
         }
         VendorSpecificOut; // Applicable for command VENDOR_SPECIFIC_OUT, Refer to 3.2.1.3 [1]

         struct
         {
             // @transferSize
             // Maximum number of USBTMC message data bytes to
             // be sent in response to the command. This does not
             // include the number of bytes in this Bulk-IN Header or
             // alignment bytes. Sent least significant byte first, most
             // significant byte last. TransferSize must be >
             // 0x00000000.
             uint32_t transferSize;

             // @Reserved
             // Reserved. Must be 0x000000.
             uint8_t  Reserved[4];
         }
         ReqVendorSpecificIn; // Applicable for command REQUEST_VENDOR_SPECIFIC_IN, Refer to 3.2.1.4 [1]

    }
    sUSBTMCBulkOutHeader_CmdSpecific_t;
    #pragma pack(pop)
    //----------------------------------------------------------------
    // @bm_DEV_DEP_MSG_OUT_mask
    // Refer to sUSBTMCBulkOutHeader_CmdSpecific_t::@DevDepMsgOut::@bmTransferAttributes
    #define bm_DEV_DEP_MSG_OUT_mask         (0x01)   // D7..D1 = reserved, must be 0

    // @bm_DEV_DEP_MSG_OUT_EOM
    // Refer to sUSBTMCBulkOutHeader_CmdSpecific_t::@DevDepMsgOut::@bmTransferAttributes
    // 1 - The last USBTMC message data byte in the transfer is the last byte of the USBTMC message.
    // 0 - The last USBTMC message data byte in the transfer is not the last byte of the USBTMC message.
    #define bm_DEV_DEP_MSG_OUT_EOM          (0x01)   // EOM, End of message

    // @bm_REQUEST_DEV_DEP_MSG_IN_mask
    // Refer to sUSBTMCBulkOutHeader_CmdSpecific_t::@ReqDevDepMsgIn::@bmTransferAttributes
    #define bm_REQUEST_DEV_DEP_MSG_IN_mask  (0x02)   // D7..D2, D0 = reserved, must be 0

    // @bm_REQUEST_DEV_DEP_MSG_IN_TRMCH
    // Refer to sUSBTMCBulkOutHeader_CmdSpecific_t::@ReqDevDepMsgIn::@bmTransferAttributes
    // 1 - 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.
    // 0 - The device must ignore TermChar.
    #define bm_REQUEST_DEV_DEP_MSG_IN_TRMCH (0x02)
    //----------------------------------------------------------------
    #pragma pack( push, 1 )
    typedef struct
    {
        // @MsgID: Specifies the USBTMC message
        // and the type of theUSBTMC message.
        // Refer to @eUSBTMCMsgId_t
        uint8_t MsgID;

        // @bTag: 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.
        // The Host must set bTag such that 1<=bTag<=255.
        uint8_t bTag;

        // @bTagInverse: The inverse (one’s complement) of the bTag.
        // For example, the bTagInverse of 0x5B is 0xA4.
        uint8_t bTagInverse;

        // Reserved. Must be 0x00.
        uint8_t Reserved;

        // @cmdSpec: USBTMC command message specific.
        // See section 3.2.1. [1]
        sUSBTMCBulkOutHeader_CmdSpecific_t cmdSpec;
    }
    sUSBTMCBulkOutHeader_t;  // Refer to 3.2 Bulk-OUT endpoint [1]
    #pragma pack(pop)
    //----------------------------------------------------------------
    //----------------------------------------------------------------
    //----------------------------------------------------------------
    #pragma pack( push, 1 )
    typedef union
    {
         // raw bytes of command specific Bulk-In Header part
         uint8_t rawBytes[8];

         struct
         {
             // @transferSize
             // Total number of message data bytes to be sent in this
             // USB transfer. This does not include the number of bytes
             // in this header or alignment bytes. Sent least significant
             // byte first, most significant byte last. TransferSize must be
             // > 0x00000000.
             uint32_t transferSize;

             // @bmTransferAttributes
             // Bitmap: D7..D2 - Reserved. All bits must be 0.
             //         D1 - TC, see bm_DEV_DEP_MSG_IN_TRMCH
             //         D0 - EOM, see bm_DEV_DEP_MSG_IN_EOM
             uint8_t  bmTransferAttributes;

             // @Reserved
             // Reserved. Must be 0x000000.
             uint8_t  Reserved[3];
         }
         DevDepMsgIn; // Applicable for command DEV_DEP_MSG_IN, Refer to 3.3.1.1 [1]

         struct
         {
             // @transferSize
             // Total number of message data bytes to be sent in this
             // USB transfer. This does not include the number of bytes
             // in this header or alignment bytes. Sent least significant
             // byte first, most significant byte last. TransferSize must be
             // > 0x00000000.
             uint32_t transferSize;

             // @Reserved
             // Reserved. Must be 0x000000.
             uint8_t  Reserved[4];
         }
         VendorSpecificIn; // Applicable for command VENDOR_SPECIFIC_IN, Refer to 3.3.1.2 [1]
    }
    sUSBTMCBulkInHeader_CmdSpecific_t;
    #pragma pack(pop)

    // @bm_DEV_DEP_MSG_IN_mask
    // Refer to sUSBTMCBulkInHeader_CmdSpecific_t::@DevDepMsgIn::@bmTransferAttributes
    #define bm_DEV_DEP_MSG_IN_mask          (0x03)   // D7..D2 = reserved, must be 0

    // @bm_DEV_DEP_MSG_IN_TRMCH
    // Refer to sUSBTMCBulkInHeader_CmdSpecific_t::@DevDepMsgIn::@bmTransferAttributes
    // 1 - All of the following are true:
    //     * The USBTMC interface supports TermChar
    //     * The bmTransferAttributes.TermCharEnabled bit was set in the REQUEST_DEV_DEP_MSG_IN.
    //     * The last USBTMC message data byte in this transfer matches the TermChar in the REQUEST_DEV_DEP_MSG_IN.
    // 0 - One or more of the above conditions is not met.
    #define bm_DEV_DEP_MSG_IN_TRMCH         (0x02)   // TermChar

    // @bm_DEV_DEP_MSG_IN_EOM
    // Refer to sUSBTMCBulkInHeader_CmdSpecific_t::@DevDepMsgIn::@bmTransferAttributes
    // 1 - The last USBTMC message data byte in the transfer is the last byte of the USBTMC message.
    // 0 - The last USBTMC message data byte in the transfer is not the last byte of the USBTMC message.
    #define bm_DEV_DEP_MSG_IN_EOM           (0x01)   // EOM, End of message

    #pragma pack( push, 1 )
    typedef union
    {
        uint8_t rawBytes[1];  // per-byte access to the entire structure

        struct
        {
            // @MsgID: Must match MsgID in the USBTMC command
            // message transfer causing this response.
            // Refer to @eUSBTMCMsgId_t
            uint8_t MsgID;

            // @bTag: Must match bTag in the USBTMC command message
            // transfer causing this response.
            uint8_t bTag;

            // @bTagInverse: Must match bTagInverse in the USBTMC command
            // message transfer causing this response.
            uint8_t bTagInverse;

            // Reserved. Must be 0x00.
            uint8_t Reserved;

            // @cmdSpec: USBTMC command message specific.
            // See section 3.2.1. [1]
            sUSBTMCBulkInHeader_CmdSpecific_t cmdSpec;
        };
    }
    sUSBTMCBulkInHeader_t; // Refer to 3.3 Bulk-IN endpoint [1]
    #pragma pack(pop)
    //----------------------------------------------------------------
    //----------------------------------------------------------------
    //----------------------------------------------------------------
    #pragma pack( push, 1 )
    typedef union
    {
        uint8_t rawBytes[1];  // per-byte access to the entire structure

        struct
        {
        // Refer: [1], 3.4 Interrupt-IN, Table 13, Interrupt-IN DATA payload format.
        #define USBTMCInterruptInHeader_Write_SubclassSpecific_Header(bNotify1, NotifyBits)\
                                                                 bNotify1 = (((uint8_t)(NotifyBits)) | 0x80 )
        #define USBTMCInterruptInHeader_Write_VendorSpecific_Header(bNotify1, NotifyBits)\
                                                                 bNotify1 = ((((uint8_t)(NotifyBits)) & 0x80) | 0x40 )
        #define USBTMCNotificationHeader_Read_Header(bNotify1, NotifyBits)\
                                                                 (((bNotify1)&0x80)?((bNotify1)&0x7F):((bNotify1)&0x3F))
        // The notification format depends on the @bNotify bits:
        // If D7 = 1: Format of D6...D0 and all notification bytes are defined in the applicable subclass specification
        // else: if D6 = 1: Format of D5...D0 and all notification bytes are vendor specific. A Host may ignore vendor specific notifications.
        // else: (D7:D6=00) Format of D5...D0 and all notification bytes are reserved for USBTMC use.
        //
        // In according to [2], 3.4.2 Interrupt-IN DATA sent due to READ_STATUS_BYTE request:
        // Byte[0]:
        //  * D7:     Must be 1
        //  * D6..D0: The bTag value must be the same as the bTag value in the READ_STATUS_BYTE request.
        #define USBTMC_USB488NotificationHeader_GetTag(hdr)       USBTMCNotificationHeader_Read_Header((hdr).bNotify1)
        #define USBTMC_USB488NotificationHeader_SetTag(hdr,tag)   USBTMCInterruptInHeader_Write_SubclassSpecific_Header((hdr).bNotify1,tag)

        // @bNotify1
        uint8_t bNotify1;
        
        // @bNotify2[N]
        // Format specified according to D7...D6 in offset 0.
        // Specification places no restriction on N, the number of bytes in the notification.
        // Device must send short packet to terminate the notification payload.
        //
        // In according to [2], 3.4.2 Interrupt-IN DATA sent due to READ_STATUS_BYTE request:
        // Byte[1]:
        //  * D7..D0: For 488.2 USB488 interfaces, the format is the IEEE 488.2 defined Status Byte returned during a serial poll
        uint8_t bNotify2[1];

        #define USBTMC_USB488NotificationHeader_GetSTB_Byte(u8)         (u8)
        #define USBTMC_USB488NotificationHeader_SetSTB_Byte(u8,stb)     u8 = ((uint8_t)stb)
        #define USBTMC_USB488NotificationHeader_GetSTB(hdr)             USBTMC_USB488NotificationHeader_GetSTB_Byte((hdr).bNotify2[0])
        #define USBTMC_USB488NotificationHeader_SetSTB(hdr,stb)         USBTMC_USB488NotificationHeader_SetSTB_Byte((hdr).bNotify2[0],stb)
        };
    }
    sUSBTMCNotificationHeader_t;
    #pragma pack(pop)
    //----------------------------------------------------------------
    //----------------------------------------------------------------
    //----------------------------------------------------------------
    typedef enum
    {
        eUsbtmcMsg_Reserved = 0,

        // @eUsbtmcMsg_DevDepMsgOut
        // Sender: Host, BULK-OUT
        // Macro: DEV_DEP_MSG_OUT
        // The USBTMC message is a USBTMC device dependent
        // command message. See section 3.2.1.1. [1]
        eUsbtmcMsg_DevDepMsgOut = 1,

        // @eUsbtmcMsg_ReqDevDepMsgIn
        // Sender: Host, BULK-OUT
        // Macro: REQUEST_DEV_DEP_MSG_IN
        // The USBTMC message is a USBTMC command message
        // that requests the device to send a USBTMC response
        // message on the Bulk-IN endpoint. See section 3.2.1.2. [1]
        eUsbtmcMsg_ReqDevDepMsgIn = 2,

        // @eUsbtmcMsg_DevDepMsgIn
        // Sender: Device, BULK-IN
        // Macro: DEV_DEP_MSG_IN
        // The USBTMC message is a USBTMC response message to
        // the REQUEST_DEV_DEP_MSG_IN. See section 3.3.1.1. [1]
        eUsbtmcMsg_DevDepMsgIn = 2,

        // @eUsbtmcMsg_VendorSpecificOut
        // Sender: Host, BULK-OUT
        // Macro: VENDOR_SPECIFIC_OUT
        // The USBTMC message is a USBTMC vendor specific
        // command message. See section 3.2.1.3 [1]
        eUsbtmcMsg_VendorSpecificOut = 126,

        // @eUsbtmcMsg_ReqVendorSpecificIn
        // Sender: Host, BULK-OUT
        // Macro: REQUEST_VENDOR_SPECIFIC_IN
        // The USBTMC message is a USBTMC command message
        // that requests the device to send a vendor specific
        // USBTMC response message on the Bulk-IN endpoint.
        // See section 3.2.1.4 [1]
        eUsbtmcMsg_ReqVendorSpecificIn = 127,

        // @eUsbtmcMsg_VendorSpecificIn
        // Sender: Device, BULK-IN
        // Macro: VENDOR_SPECIFIC_IN
        // The USBTMC message is a USBTMC response
        // message to the REQUEST_VENDOR_SPECIFIC_IN.
        // See section 3.3.1.2. [1]
        eUsbtmcMsg_VendorSpecificIn = 127,

        // @eUsbtmcMsg_Usb488_Trigger
        // Sender: Host, BULK-OUT
        // Macro: TRIGGER (USB488)
        // The TRIGGER command message provides a
        // mechanism for the Host to trigger device dependent
        // actions on a device synchronously with other Bulk-OUT
        // messages. Support for this MsgID is optional. See 4.2.2. [2]
        eUsbtmcMsg_Usb488_Trigger = 128,
    }
    eUSBTMCMsgId_t;

    //-------------------------------------------------
    // @sUSBTMC_InitiateAbortBulkInOut_Response_t: 4.2.1.2 INITIATE_ABORT_BULK_OUT, table 19, [1]
    // @sUSBTMC_InitiateAbortBulkInOut_Response_t: 4.2.1.4 INITIATE_ABORT_BULK_IN, table 25, [1]
    #pragma pack( push, 1 )
    typedef struct
    {
        uint8_t USBTMC_status; // Status indication for this request.
        uint8_t bTag;          // The bTag for the the current Bulk-OUT transfer.
    }
    sUSBTMC_InitiateAbortBulkInOut_Response_t;
    #pragma pack( pop )
    //-------------------------------------------------
    // @sUSBTMC_CheckAbortBulkOut_Response_t: 4.2.1.3 CHECK_ABORT_BULK_OUT_STATUS, table 22, [1]
    #pragma pack( push, 1 )
    typedef struct
    {
         uint8_t USBTMC_status; // Status indication for this request.
         uint8_t reserved[3];
         uint32_t NBYTES_RXD;   // The total number of USBTMC message data bytes (not including
                                // Bulk-OUT Header or alignment bytes) in the transfer received,
                                // and not discarded, by the device.
    }
    sUSBTMC_CheckAbortBulkOut_Response_t;
    #pragma pack( pop )
    //-------------------------------------------------
    // @sUSBTMC_CheckAbortBulkIn_Response_t: 4.2.1.5 CHECK_ABORT_BULK_IN_STATUS, table 28, [1]
    #pragma pack( push, 1 )
    typedef struct
    {
         uint8_t USBTMC_status; // Status indication for this request.
         uint8_t bmAbortBulkIn; // Bitmap, see bits assignation:
                                // D7..D1=0, reserved
                                // D0: Bulk-IN FIFO empty flag, see @USBTMC_ABORT_BULKIN_FIFOEMPTY
         uint8_t reserved[2];
         uint32_t NBYTES_TXD;   // The total number of USBTMC message data bytes (not including
                                // Bulk-IN Header or alignment bytes) sent in the transfer.
    }
    sUSBTMC_CheckAbortBulkIn_Response_t;
    #pragma pack( pop )
    //-------------------------------------------------
    // @USBTMC_ABORT_BULKIN_FIFOEMPTY
    // BulkIN Fifo Empty flag
    // 4.2.1.5 CHECK_ABORT_BULK_IN_STATUS, table 28, [1]
    // bmAbortBulkIn.D0
    // D0 = 1: The device either has some queued DATA bytes in
    //         the Bulk-IN FIFO or has a short packet that needs
    //         to be sent to the Host. The USBTMC_status must
    //         not be STATUS_SUCCESS.
    // D0 = 0: The Bulk-IN FIFO is empty.
    #define USBTMC_ABORT_BULKIN_FIFOEMPTY   (1ul << 0)
    //-------------------------------------------------
    // @sUSBTMC_InitiateClear_Response_t: 4.2.1.6 INITIATE_CLEAR, table 31, [1]
    #pragma pack( push, 1 )
    typedef struct
    {
         uint8_t USBTMC_status; // Status indication for this request.
    }
    sUSBTMC_InitiateClear_Response_t;
    #pragma pack( pop )
    //-------------------------------------------------
    // @sUSBTMC_CheckClear_Response_t: 4.2.1.7 CHECK_CLEAR_STATUS, table 34, [1]
    #pragma pack( push, 1 )
    typedef struct
    {
         uint8_t USBTMC_status; // Status indication for this request.
         uint8_t bmClear;       // Bitmap, see bits assignation:
                                // D7..D1 = 0, reserved,
                                // D0: Bulk-IN FIFO empty flag, see @USBTMC_CHECK_CLEAR_FIFOEMPTY
    }
    sUSBTMC_CheckClear_Response_t;
    #pragma pack( pop )
    //-------------------------------------------------
    // @USBTMC_CHECK_CLEAR_FIFOEMPTY
    // BulkIN Fifo Empty flag
    // 4.2.1.7 CHECK_CLEAR_STATUS, table 34, [1]
    // bmClear.D0
    // D0 = 1: The device either has some queued DATA bytes
    //         in the Bulk-IN FIFO that it could not remove,
    //         or has a short packet that needs to be sent to
    //         the Host. The USBTMC_status must not be
    //         STATUS_SUCCESS.
    // D0 = 0: The device has completely removed queued
    //         DATA in the Bulk-IN FIFO and the Bulk-IN
    //         FIFO is empty.
    #define USBTMC_CHECK_CLEAR_FIFOEMPTY   (1ul << 0)
    //-------------------------------------------------
    #pragma pack( push, 1 )
    typedef struct
    {
       uint16_t bcdUSB488;     // BCD version number of the relevant USB488 specification for this USB488 interface.
       uint8_t  ifaceCaps;     // USB488 Interface Capabilities, bitmap, see bits assignation:
                               // D7..D3 = 0, reserved
                               // D2: 488.2 USB488 interface capability, see @USB488_IFACE_CAPABILITIES_4882IF
                               // D1: Remote-Local capability, see @USB488_IFACE_CAPABILITIES_RLSTATE
                               // D0: Device trigger capability, see @USB488_IFACE_CAPABILITIES_TRIGGER

       uint8_t  devCaps;       // USB488 Device Capabilities, bitmap, see bits assignation:
                               // D7..D4 = 0, reserved
                               // D3: SCPI capability, see @USB488_DEVICE_CAPABILITIES_SCPI
                               // D2: Service Request Capability, see @USB488_DEVICE_CAPABILITIES_SERVICE_REQUEST
                               // D1: Remote-Local control capability, see @USB488_DEVICE_CAPABILITIES_REMOTE_LOCAL
                               // D0: Device trigger capability, see @USB488_DEVICE_CAPABILITIES_DEVICE_TRIGGER
       uint8_t  reserved[8];   // must be 0x00
    }
    sUSB488_GetCapabilities_Response_t;
    #pragma pack( pop )
    // -------------------------------------------------------
    // @USB488_IFACE_CAPABILITIES_4882IF
    // IEEE 488.2 compatibility
    // - 4.2.2 GET_CAPABILITIES, table 8, [2]
    // - Appendix 2: IEEE 488.2 compatibility, [2]
    // USB488InterfaceCapabilities.D2
    // 488.2 USB488 interface compatibility
    // D2 = 1: The interface is a 488.2 USB488 interface.
    // D2 = 0: The interface is not a 488.2 USB488 interface.
    #define USB488_IFACE_CAPABILITIES_4882IF   (1ul<<2)
    // -------------------------------------------------------
    // @USB488_IFACE_CAPABILITIES_RLSTATES
    // Remote-controlled / Local-controlled states
    // - 4.2.2 GET_CAPABILITIES, table 8, [2]
    // - 4.3.2 REN_CONTROL, [2]
    // - 4.3.3 GO_TO_LOCAL, [2]
    // - 4.3.4 LOCAL_LOCKOUT, [2]
    // USB488InterfaceCapabilities.D1
    // D1 = 1: The interface accepts REN_CONTROL, GO_TO_LOCAL, and LOCAL_LOCKOUT requests.
    // D1 = 0: The interface does not accept REN_CONTROL, GO_TO_LOCAL, and LOCAL_LOCKOUT requests.
    #define USB488_IFACE_CAPABILITIES_RLSTATES (1ul<<1)
    //-------------------------------------------------
    //@USB488_IFACE_CAPABILITIES_TRIGGER
    // TRIGGER message support
    // - 3.2.1.1 MsgID = TRIGGER, [2]
    // - 4.2.2 GET_CAPABILITIES, table 8, [2]
    // USB488InterfaceCapabilities.D0
    // D0 = 1: The interface accepts the MsgID = TRIGGER USBTMC command message and forwards TRIGGER requests to the Function Layer.
    // D0 = 0: The interface does not accept the TRIGGER USBTMC command message.
    #define USB488_IFACE_CAPABILITIES_TRIGGER  (1ul<<0)
    //-------------------------------------------------
    //@USB488_DEVICE_CAPABILITIES_SCPI
    // SCPI mandatory commands compatibility
    // - 4.2.2 GET_CAPABILITIES, table 8, [2]
    // - 4 SCPI ComplianceCriteria, [5]
    // USB488DeviceCapabilities.D3
    // D3 = 1: DESCRIPTION
    // D3 = 0: DESCRIPTION
    #define USB488_DEVICE_CAPABILITIES_SCPI  (1ul<<3)
    //-------------------------------------------------
    //@USB488_DEVICE_CAPABILITIES_SERVICE_REQUEST
    // IEEE 488.2 Service Request compatibility
    // - 4.2.2 GET_CAPABILITIES, table 8, [2]
    // - 2.7 Service Request (SR) Interface Function, [3]
    // USB488DeviceCapabilities.D2
    // D2 = 1: The device is SR1 capable. The interface must have
    //         an Interrupt-IN endpoint. The device must use the
    //         Interrupt-IN endpoint as described in 3.4.1 to
    //         request service, in addition to the other uses
    //         described in this specification [3].
    // D2 = 0: The device is SR0. If the interface contains an
    //         Interrupt-IN endpoint, the device must not use the
    //         Interrupt-IN endpoint as described in 3.4.1 to
    //         request service. The device must use the endpoint
    //         for all other uses described in this specification.
    #define USB488_DEVICE_CAPABILITIES_SERVICE_REQUEST  (1ul<<2)
    //-------------------------------------------------
    //@USB488_DEVICE_CAPABILITIES_REMOTE_LOCAL
    // Remote-Local control compatibility
    // - 4.2.2 GET_CAPABILITIES, table 8, [2]
    // - 2.1.2.3 Interface Function Repertoire, Table 1, [3]
    // - 2.8 Remote Local (RL) Interface function, [3]
    // USB488DeviceCapabilities.D1
    // D1 = 1: The device is RL1 capable. The device must implement the state machine shown in Figure 2 (4.3.2 REN_CONTROL, [2])
    // D1 = 0: The device is RL0. The device does not implement the state machine shown in Figure 2 (4.3.2 REN_CONTROL, [2])
    #define USB488_DEVICE_CAPABILITIES_REMOTE_LOCAL  (1ul<<1)
    //-------------------------------------------------
    //@USB488_DEVICE_CAPABILITIES_DEVICE_TRIGGER
    // Device Trigger compatibility
    // - 4.2.2 GET_CAPABILITIES, table 8, [2]
    // - 2.7 2.11 Device Trigger (DT) Interface Function, [3]
    // - 5.9 Device Trigger Requirements, [4]
    // USB488DeviceCapabilities.D0
    // D0 = 1: The device is DT1 capable.
    // D0 = 0: The device is DT0.
    #define USB488_DEVICE_CAPABILITIES_DEVICE_TRIGGER  (1ul<<0)
    //-------------------------------------------------
    // @sUSBTMC_GetCapabilities_Response_t: 4.2.1.8 GET_CAPABILITIES, table 37, [1]
    #pragma pack( push, 1 )
    typedef struct
    {
         uint8_t USBTMC_status;         // Status indication for this request.
         uint8_t reserved;              // must be 0x00
         uint16_t bcdUSBTMC;            // BCD version number of the relevant USBTMC specification
         uint8_t ifaceCaps;             // USBTMC Interface Capabilities, see bits assignation:
                                        // D7..D3 = 0, reserved
                                        // D2: INDICATOR_PULSE request compatibility, see @USBTMC_IFACE_CAPABILITIES_INDICATOR_PULSE
                                        // D1: Talk-only restriction, see @USBTMC_IFACE_CAPABILITIES_TALK_ONLY
                                        // D0: Listen-only restriction, see @USBTMC_IFACE_CAPABILITIES_LISTEN_ONLY
         uint8_t devCaps;               // USBTMC Device Capabilities, bitmap, see bits assignation:
                                        // D7..D1 = 0, reserved
                                        // D0: Termination charater support, see @USBTMC_DEVICE_CAPABILITIES_TERM_CHARACTER
         uint8_t reserved_class[6];     // reserved for USBTMC class usage, must be 0x00

         union
         {
            uint8_t subclass[12];       // reserved for USBTMC subclass usage, must be filled in accordance with the subclass used
            sUSB488_GetCapabilities_Response_t usb488;
         };
    }
    sUSBTMC_GetCapabilities_Response_t;
    #pragma pack( pop )
    //-------------------------------------------------
    // @sUSBTMC_IndicatorPulse_Response_t: 4.2.1.9 INDICATOR_PULSE, table 39, [1]
    #pragma pack( push, 1 )
    typedef struct
    {
         uint8_t USBTMC_status;         // Status indication for this request.
    }
    sUSBTMC_IndicatorPulse_Response_t;
    #pragma pack( pop )
    //-------------------------------------------------
    // @sUSBTMC_USB488_ReadStatusByte_Response_t: 4.3.1.1 Response format for USB488 interfaces without an Interrupt-IN endpoint, table 12, [2]
    #pragma pack( push, 1 )
    typedef struct
    {
         uint8_t USBTMC_status;         // Status indication for this request.
         uint8_t bTag;                  // The bTag value from the READ_STATUS_BYTE request.
         uint8_t bStatusByte;           // The format is the IEEE 488.1 defined Status Byte.
    }
    sUSBTMC_USB488_ReadStatusByte_Response_t;
    #pragma pack( pop )
    //-------------------------------------------------
    //@USBTMC_IFACE_CAPABILITIES_INDICATOR_PULSE
    // Indication and Identification request support (INDICATOR_PULSE)
    // - 4.2.1.8 GET_CAPABILITIES, table 37, [1]
    // - 4.2.1.9 INDICATOR_PULSE, [1]
    // USBTMCInterfaceCapabilities.D2
    // D2 = 1: The USBTMC interface accepts the INDICATOR_PULSE request.
    // D2 = 0: The USBTMC interface does not accept the INDICATOR_PULSE request.
    #define USBTMC_IFACE_CAPABILITIES_INDICATOR_PULSE  (1ul<<2)
    //-------------------------------------------------
    //@USBTMC_IFACE_CAPABILITIES_TALK_ONLY
    // Restriction: talk only USBTMC-interface is supported
    // - 1.4 Terms and Abbreviations, [1]
    // - 4.2.1.8 GET_CAPABILITIES, table 37, [1]
    // USBTMCInterfaceCapabilities.D1
    // D1 = 1: The USBTMC interface is talk-only.
    // D1 = 0: The USBTMC interface is not talk-only.
    #define USBTMC_IFACE_CAPABILITIES_TALK_ONLY  (1ul<<1)
    //-------------------------------------------------
    //@USBTMC_IFACE_CAPABILITIES_LISTEN_ONLY
    // Restriction: listen only USBTMC-interface is supported
    // - 1.4 Terms and Abbreviations, [1]
    // - 4.2.1.8 GET_CAPABILITIES, table 37, [1]
    // USBTMCInterfaceCapabilities.D0
    // D0 = 1: The USBTMC interface is listen-only.
    // D0 = 0: The USBTMC interface is not listen-only.
    #define USBTMC_IFACE_CAPABILITIES_LISTEN_ONLY  (1ul<<0)
    //-------------------------------------------------
    //@USBTMC_DEVICE_CAPABILITIES_TERM_CHARACTER
    // Termination character ending on Bulk-IN support
    // 3.2.1.2 MsgID = REQUEST_DEV_DEP_MSG_IN, table 4, [1]
    // - 4.2.1.8 GET_CAPABILITIES, table 37, [1]
    // USBTMCDeviceCapabilities.D0
    // D0 = 1: The device supports ending a Bulk-IN transfer
    //         from this USBTMC interface when a byte
    //         matches a specified TermChar.
    // D0 = 0: The device does not support ending a Bulk-IN
    //         transfer from this USBTMC interface when a
    //         byte matches a specified TermChar.
    #define USBTMC_DEVICE_CAPABILITIES_TERM_CHARACTER  (1ul<<0)
    //-------------------------------------------------
#endif