#ifndef _USBTMC_H_
#define _USBTMC_H_

        #include "usbtmc_main.h"
        // =======================================================================================================
        // see "Gpib Programming Tutorial Programming a GPIB based instrument designed at the Electronics Group PDF"
        // 
        //
        #define PUDI    (udi->usbtmcGpib.StateMachine)
        #define _STB    (PUDI.STB)
        #define _ESR    (PUDI.ESR)
        #define _ESE    (PUDI.ESE)
        #define _SRE    (PUDI.SRE)
 
        //#define GPIB_SETONCOMPLETE_OPC()   (PUDI.SETOPC=1) // флаг того, что нужно дернуть OPC бит по завершении. для комманды *OPC
        //#define GPIB_CLRONCOMPLETE_OPC()   (PUDI.SETOPC=0)
        

        #define USB_MAX_ERROR_QUEUE  RAM_ERRORQUEUE_SIZE  // bytes. нужно учитывать что на управлющие структуры очереди тоже нужно мето

        #define STATE_MACHINE() (USBTMC_StateMachine_Modified( &PUDI ))
        // --------- -- Bits of STB Register --------------
        #define STB_MAV 4      // Message Available
        #define GPIB_SET_MAV() ((_STB |= (1<<STB_MAV))  && STATE_MACHINE() )
        #define GPIB_CLR_MAV() ((_STB &= (~(1<<STB_MAV)))  && STATE_MACHINE() )
        #define GPIB_GET_MAV() (_STB & (1<<STB_MAV) )
        
        #define STB_EAV 2      // Error/Event Available
        #define GPIB_SET_EAV() ((_STB |= (1<<STB_EAV))  && STATE_MACHINE() )
        #define GPIB_CLR_EAV() ((_STB &= (~(1<<STB_EAV)))  && STATE_MACHINE() )
        #define GPIB_GET_EAV() (_STB & (1<<STB_EAV) )
        
        #define STB_ESB 5      // Standart Event status Bit
        #define GPIB_SET_ESB() ((_STB |= (1<<STB_ESB))  && STATE_MACHINE() )
        #define GPIB_CLR_ESB() ((_STB &= (~(1<<STB_ESB)))  && STATE_MACHINE() )
        #define GPIB_GET_ESB() (_STB & (1<<STB_ESB) )
        
        #define STB_RQS_MSS 6      // Service Request or Master Summary Status (MSS)
        #define GPIB_SET_RQS()   ((_STB |= (1<<STB_RQS_MSS))  && STATE_MACHINE() )
        #define GPIB_CLR_RQS__() ((_STB &= (~(1<<STB_RQS_MSS))))
        #define GPIB_CLR_RQS()   ( GPIB_CLR_RQS__()  && STATE_MACHINE() )
        #define GPIB_SET_MSS()   ((_STB |= (1<<STB_RQS_MSS))  && STATE_MACHINE() )
        #define GPIB_CLR_MSS__() ((_STB &= (~(1<<STB_RQS_MSS))))
        #define GPIB_CLR_MSS()   ( GPIB_CLR_RQS__()  && STATE_MACHINE() )

        //#define GPIB_GET_RQS()   ( (_STB & STB_RQS) && (GPIB_CLR_RQS__() || TRUE) )
        #define GPIB_GET_RQS()   ((_STB & (1<<STB_RQS_MSS)) )
        #define GPIB_GET_MSS()   ((_STB & (1<<STB_RQS_MSS)) )
        

        #define GPIB_CLR_ESR() (_ESR = 0, STATE_MACHINE(), TRUE)
        #define GPIB_GET_ESR() (_ESR)

        // ---------- -- Bits of ESR ----------------------
        #define ESR_PWN 7 // Power On cycle
        #define GPIB_SET_PWN() ((_ESR |= (1<<ESR_PWN))  && STATE_MACHINE() )
        #define GPIB_CLR_PWN() ((_ESR &= (~(1<<ESR_PWN)))  && STATE_MACHINE() )
        #define GPIB_GET_PWN() (_ESR & (1<<ESR_PWN) )
        
        #define ESR_URQ 6 // User request
        #define GPIB_SET_URQ() ((_ESR |= (1<<ESR_URQ))  && STATE_MACHINE() )
        #define GPIB_CLR_URQ() ((_ESR &= (~(1<<ESR_URQ)))  && STATE_MACHINE() )
        #define GPIB_GET_URQ() (_ESR & (1<<ESR_URQ) )
        
        #define ESR_CME 5 // Command Error
        #define GPIB_SET_CME() ((_ESR |= (1<<ESR_CME)) && STATE_MACHINE() )
        #define GPIB_CLR_CME() ((_ESR &= (~(1<<ESR_CME)))  && STATE_MACHINE() )
        #define GPIB_GET_CME() (_ESR & (1<<ESR_CME) )
        
        #define ESR_EXE 4 // Execution Error
        #define GPIB_SET_EXE() ((_ESR |= (1<<ESR_EXE)) && STATE_MACHINE() )
        #define GPIB_CLR_EXE() ((_ESR &= (~(1<<ESR_EXE)))  && STATE_MACHINE() )
        #define GPIB_GET_EXE() (_ESR & (1<<ESR_EXE) )
        
        #define ESR_DDE 3 // Dev Dependent Error
        #define GPIB_SET_DDE() ((_ESR |= (1<<ESR_DDE))  && STATE_MACHINE() )
        #define GPIB_CLR_DDE() ((_ESR &= (~(1<<ESR_DDE)))  && STATE_MACHINE() )
        #define GPIB_GET_DDE() (_ESR & (1<<ESR_DDE) )
        
        #define ESR_QRE 2 // Query Error
        #define GPIB_SET_QRE() ((_ESR |= (1<<ESR_QRE))  && STATE_MACHINE() )
        #define GPIB_CLR_QRE() ((_ESR &= (~(1<<ESR_QRE)))  && STATE_MACHINE() )
        #define GPIB_GET_QRE() (_ESR & (1<<ESR_QRE) )
        
        #define ESR_RQE 1 // Request Error
        #define GPIB_SET_RQE() ((_ESR |= (1<<ESR_RQE))  && STATE_MACHINE() )
        #define GPIB_CLR_RQE() ((_ESR &= (~(1<<ESR_RQE)))  && STATE_MACHINE() )
        #define GPIB_GET_RQE() (_ESR & (1<<ESR_RQE) )
        
        #define ESR_OPC 0 // Operation Complete
        #define GPIB_SET_OPC() ((_ESR |= (1<<ESR_OPC))  && STATE_MACHINE() )
        #define GPIB_CLR_OPC() ((_ESR &= (~(1<<ESR_OPC)))  && STATE_MACHINE() )
        #define GPIB_GET_OPC() (_ESR & (1<<ESR_OPC) )
        
        typedef enum
        {
           errClass_Autodetect, // autodetect the class error by error code           
           //------------------
           errClass_Command,    // IEEE 488.2, 11.5.1.1.4
           /*
            Command Errors are detected by the Parser, see 6.1.6. This event bit indicates that one of the following events has
            occurred:
            1) An IEEE 488.2 syntax error has been detected by the parser. That is, a controller-to-device message was
            received that is in violation of this standard. Possible violations include a data element that violates the device
            listening formats or whose type is unacceptable to the device, see 7.1.2.2.
            2) A semantic error has occurred indicating that an unrecognized header was received. Unrecognized headers
            include incorrect device-specific headers and incorrect or unimplemented IEEE 488.2 common commands,
            see Section 10.. A valid macro label, which is not the same as a device-specific <COMMAND PROGRAM
            HEADER> or <QUERY PROGRAM HEADER>, that is received by a device with its macros disabled shall
            be considered an unrecognized header.
            3) A Group Execute Trigger (GET) was entered into the Input Buffer inside of a <PROGRAM MESSAGE>, see
            6.1.6.1.1 and 6.4.3.
            When a device detects a Command Error, parser synchronization may be lost. See 6.1.6.1.1 for discussion of parser
            action after a Command Error.
           */
           errClass_Execution,   // IEEE 488.2, 11.5.1.1.5
           /*
           Execution Errors are detected by the Execution Control Block, see 6.1.7. This event bit indicates that:
           1) A <PROGRAM DATA> element following a header was evaluated by the device as outside of its legal input
           range or is otherwise inconsistent with the device's capabilities.
           2) A valid program message could not be properly executed due to some device condition.
           Following an Execution Error, the device shall continue parsing the input stream. The device may continue executing
           parsed commands or the device may discard parsed commands. Devices shall resume execution of parsed commands
           after a <PROGRAM MESSAGE TERMINATOR>. It is recommended that this choice be documented.
           Execution Errors shall be reported by the device after rounding and expression evaluation operations have taken place.
           Rounding a numeric data element, for example, shall not be reported as an Execution Error.
           Events that generate Execution Errors shall not also generate Command Errors, Query Errors, or Device-Specific
           Errors. See other bit definitions in this section.
           NOTE — The device designer has the responsibility to ensure that devices incorporate effective checking to prevent execution of
           commands after an Execution Error that could result in undesireable conditions. Documentation should indicate any
           known conditions that cannot be checked by the device.
           */
           errClass_Device,      // IEEE 488.2, 11.5.1.1.6 
           /*
           Device-Specific Errors are detected by Device Functions, see 6.1.8. This event bit indicates that an error has occurred
           that is neither a Command Error, a Query Error, nor an Execution Error.
           A Device-Specific Error is any executed device operation that did not properly complete due to some condition, such
           as overrange.
           Following a Device-Specific Error, the device shall continue to process the input stream.
           Device-Specific Errors are to be used at the discretion of the device designer.
           Events that generate Device-Specific Errors shall not also generate Command Errors, Query Errors, or Execution Errors.
           */
           
           errClass_Query,       // IEEE 488.2, 11.5.1.1.7
           /*
           Query Errors are detected by the Output Queue Control, see 6.1.10. This event bit indicates that either
           1) An attempt is being made to read data from the Output Queue when no output is either present or pending, or
           2) Data in the Output Queue has been lost.
           See 6.5.7 for a complete description.
           The Query Error bit shall not be set to report any other condition. Events that generate Query Errors shall not also
           generate Execution Errors, Command Errors, or Device-Specific Errors.
           */
        }
        GPIB_ErrorClass_t;
        
        // ---------------------------------------------------------------------------------------------------------
         // ------ Questinable status
        #define GPIB_QUES_VOLTage 0
        #define GPIB_QUES_CURRent 1
        #define GPIB_QUES_TIME 2
        #define GPIB_QUES_POWer  3
        #define GPIB_QUES_TEMPerature 4
        #define GPIB_QUES_FREQuency 5
        #define GPIB_QUES_PHASe 6
        #define GPIB_QUES_MODulation  7
        #define GPIB_QUES_CALibration  8
        #define GPIB_QUES_INSTrumentSummary 13
        #define GPIB_QUES_COMWarinig 14
         // -------- Operation Status
        #define GPIB_OPER_CALibration  0
        #define GPIB_OPER_SETTing      1
        #define GPIB_OPER_RANGing      2
        #define GPIB_OPER_SWEeping     3
        #define GPIB_OPER_MEASuring    4
        #define GPIB_OPER_WTRGSummary  5
        #define GPIB_OPER_WARMSummary  6
        #define GPIB_OPER_CORRecting   7
        #define GPIB_OPER_INSTSummary  13
        #define GPIB_OPER_PROGRunning  14
        
       
        #define MIN(A1,B2) ((A1<B2)?A1:B2)        
        #define MAX(A2,B1) ((A2>B1)?A2:B1)
                
        
        extern const __root char * GPIBErrors[];
        #define GPIB_ERROR_NOERROR     0
        
        // Size of IDN string is only 72
        #define MAX_USBTMC_IDNSTRING_SIZE         71
        // ---------------------------------------------------------------------------------------------------------
        
        // ============================================= MsgID =============================================================================================================================================
        // --------------- All macroses are defined appropriate USBTMC spec. rev. 1.0, page 6 
        #define DEV_DEP_MSG_OUT                   0x01     // - The USBTMC message is a USBTMC device dependent command message.
        
        #define DEV_DEP_MSG_IN                    0x02     // - The USBTMC message in a USBTMC response message to the REQUEST_DEV_DEP_MSG_IN
        #define REQUEST_DEV_DEP_MSG_IN            0x02     // - The USBTMC message is a USBTMC command message that requests the device to send a USBTMC response message on the Bulk-IN endpoint. 
        
        #define VENDOR_SPECIFIC_OUT               0x7E     // - The USBTMC message in a USBTMC vendor specific command message.
        
        #define REQUEST_VENDOR_SPECIFIC_IN        0x7F     // - The USBTMC message in a USBTMC command message that requests the device sto send a vendor specific USBTMC response message on the Bulk-IN endpoint
        #define VENDOR_SPECIFIC_IN                0x7F     // - The USBTMC message is a USBTMC response message to the REQUEST_VENDOR_SPECIFIC_IN
        
        // See USB488 spec, rev 1.0, 2003, page 4, table 1
        #define TRIGGER                           0x80 
        
        // ===================================== macro: bits in respond GET_CAPABILITES ===================================================================================================================
        
        #define USBTMC_SUPPORT__LISTEN_ONLY       0
        #define USBTMC_SUPPORT__TALK_ONLY         1
        #define USBTMC_SUPPORT__INDICATOR_PULSE   2
        #define USBTMC_SUPPORT__TERMCHAR          0
        
        #define USBTMC_EOM_INDEX   1
        #define USBTMC_BITMAP_EOM  0x01  // mask
        
        
        // =========================================== USBTMC Control-EP-Protocol Requests ================================================================================================================
        // see "USBTMC spec., rev. 1.0, 2003": "page 18":"Table 15"
        #define INITIATE_ABORT_BULK_OUT           0x01  // Aborts a bulk-out TRANSFER
        #define CHECK_ABORT_BULK_OUT_STATUS       0x02  // returns the status of the previously sent INITIATE_ABORT_BULK_OUT request
        #define INITIATE_ABORT_BULK_IN            0x03  // Aborts a bulk-in TRANSFER
        #define CHECK_ABORT_BULK_IN_STATUS        0x04  // returns the status of the previously sent INITIATE_ABORT_BULK_IN request
        #define INITIATE_CLEAR                    0x05  // Clear all previously send pending and unprocessed Bulk-Out USBTMC message content and clears all pending Bulk-In transfers from the USBTMC interface
        #define CHECK_CLEAR_STATUS                0x06  // Returns the status of the previously sent INITIATE_CLEAR request
        #define GET_CAPABILITES                   0x07  // Returns attributes and capabilites of the USBTMC interface
        #define INDICATOR_PULSE                   0x40  // A mechanism to turn on an activity indicator for identification purposes. The device indicate whether or not it support this requesrt in the GET_CAPABILITES response packet
        
        #define READ_STATUS_BYTE                  0x80 // Returns the IEEE 488 status byte
        #define REN_CONTROL                       0xA0 // Mechanism to enable or disable local controls on a device
        #define GO_TO_LOCAL                       0xA1 // Mechanism to enable local controls on a device
        #define LOCAL_LOCKOUT                     0xA2 // Mechanism to disable local controls on a device
        
        
        // =========================================== USBTMC Control-EP-Protocol Status codes ============================================================================================================
        // see "USBTMC spec., rev. 1.0, 2003": "page 19":"Table 16"
        #define STATUS_SUCCESS                    0x01
        #define STATUS_PENDING                    0x02   // This status is valid  if a device has recieved a USBTMC split transaction CHECK_STATUS request and th request is still being processed  
        #define STATUS_FAILED                     0x80   // Failure, unspecified reason, and a more specified USBTMC_status is not defined
        #define STATUS_TRANSFER_NOT_IN_PROGRESS   0x81   // this status is valid if a device has recieved an INITIATE_ABORT_BULK_OUT or INITIATE_ABORT_BULK_IN request and the specified transfer to abort is not in progress 
        #define STATUS_SPLIT_NOT_IN_PROGRESS      0x82   // this status is valid if the device recieved a CHECK_STATUS request ans the device is not processing an INITIATE request
        #define STATUS_SPLIT_IN_PROGRESS          0x83   // this status is valid if the device recieved a new class-specific request and the device is still processing and INITIATE
        #define STATUS_INTERRUPT_IN_BUSY          0x20   // this status is valid if the device recieved READ_STATUS_BYTE request, the USB488 interface has as INterrupt_IN endpoint, and the device is unable to queue the response packe on INTerrupt_IN endpoint because the FIFO is full.
        
        // ================================================================================================================================================================================================
        
        
        // see "USBTMC spec. rev 1.0, 2003": "page 7":"Table 3", "page 9":"Table 4", "page 9":"Table 5", "page 10":"Table 6"
        // структура _USBTMC_COMMAND_MESSAGE
        //
        // +---------------------[4]---------------------------+------------[1]-------+---------------------[3]-----------------------+
        // | TransferSize [4]                                  | bmTransferAttributes |  Reserved                                     |
        // +---------------------------------------------------+----------------------+-----------------------------------------------+
        //
        // +---------------------[4]---------------------------+------------[1]-------+---------[1]---+-------------[2]---------------+
        // | TransferSize [4]                                  | bmTransferAttributes |  TermChar     |  Reserved                     |
        // +---------------------------------------------------+----------------------+---------------+-------------------------------+
        //
        // +---------------------[4]---------------------------+--------------------------------[4]-----------------------------------+
        // | TransferSize [4]                                  | Reserved                                                             |
        // +---------------------------------------------------+----------------------------------------------------------------------+
        
        
        struct _USBTMC_RESPOND_MESSAGE
        {
               DWORD 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 aligment
                                                           //    bytes. Sent least significant bytes first, most significant bytes last. TransferSize must be >0
         //-----------       
                union{
                  
                  BYTE Reserved2[4];                      // -- Reserved in VENDOR_SPECIFIC_IN request. Must be 0 
                  //-------------
                  struct{
                    BYTE bmTransferAttributes;             // -- Bitmap:  
                                                           // ---# DEV_DEP_MSG_IN ------------------------------------------------------------------------------------------------------------------
                                                           //             D0 -- EOM bit:   ( see "USBTMC spec. rev 1.0, 2003": "page 7" )
                                                           //                         # EOM bit = 1 --  The last USBTMC message data byte in this transfer is the last byte of the USBTMC message.
                                                           //                         # EOM bit = 0 --  The last USBTMC message data byte in this transfer is NOT the last byte of the USBTMC message.
                                                           //             D1 -- Multiple bit:
                                                           //                         # bit == 1    -- All of the following are true:    
                                                           //                                          1. The USBTMC interface supports TermChar.
                                                           //                                          2. The bmTransferAttributes.TermCharEnabled bit was set in the REQUEST_DEV_DEP_MSG_IN.
                                                           //                                          3. The last USBTMC message data byte in this transfer matches the TermChar in REQUEST_DEV_DEP_MSG_IN
                                                           //                         # bit == 0    -- Overwise
                                                           //             D2-D7 -- Reserved. Must be 0.                                                   
                                                       
                    BYTE Reserved0[3];                    // -- Reserved in DEV_DEP_MSG_IN request. Must be 0 
                       
                    //------------  
                  };
                  //-----------  
                   
               };
          
        };
        struct _USBTMC_COMMAND_MESSAGE
        {
                DWORD 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 aligment
                                                           //    bytes. Sent least significant bytes first, most significant bytes last. TransferSize must be >0
         //-----------       
                union{
                  
                  BYTE Reserved2[4];                      // -- Reserved in VENDOR_SPECIFIC_OUT request. Must be 0 
                  //-------------
                  struct{
                    BYTE bmTransferAttributes;             // -- Bitmap:  
                                                           // ---# DEV_DEP_MSG_OUT ------------------------------------------------------------------------------------------------------------------
                                                           //             D0 -- EOM bit:   ( see "USBTMC spec. rev 1.0, 2003": "page 7" )
                                                           //                         # EOM bit = 1 --  The last USBTMC message data byte in this transfer is the last byte of the USBTMC message.
                                                           //                         # EOM bit = 0 --  The last USBTMC message data byte in this transfer is NOT the last byte of the USBTMC message.
                                                           //             D1-D7 -- Reserved. Must be 0.
                                                           // ---# REQUEST_DEV_DEP_MSG_OUT ----------------------------------------------------------------------------------------------------------
                                                           //             D0 -- Must be 0
                                                           //             D1 -- TermCharEnabled: ( see "USBTMC spec. rev 1.0, 2003": "page 9" )
                                                           //                         # TermCharEnabled bit = 1 -- The Bulk-IN trnasfer must terminate on the specified TermChar.
                                                           //                                                      The host may only set this bit if the USBTMC interface indicates it supports TermChar in the GET_CAPABILITES response packet
                                                           //                         # TermCharEnabled bit = 0 -- The device must ignore TermChar
                    //-----------
                    union {                                    
                     BYTE Reserved0[3];                    // -- Reserved in DEV_DEP_MSG_OUT request. Must be 0 
                       //-------------- 
                       struct{
                         BYTE TermChar;                    // -- If bmbmTransferAttributes.D1 == 1, TermChar is an 8-bin value representing a termination character. If supported, the device must terminate the Bulk-In transfer after this character is sent.
                         BYTE Reserved1[2];                // -- Reserved in REQUEST_DEV_DEP_MSG_OUT ???????. Must be 0
                       };
                       //-------------- 
                     };
                    //------------  
                  };
                  //-----------  
                   
               };
         //--------     
        };
        
        typedef struct _USBTMC_COMMAND_MESSAGE USBTMC_COMMAND_MESSAGE;
        typedef struct _USBTMC_RESPOND_MESSAGE USBTMC_RESPOND_MESSAGE;
        
#pragma pack( push, 1 )
        __pkd__ struct _BULKOUT_HEADER
        {
           BYTE MsgID;               // -- Specifies the USBTMC message and the type fo the USBTMC message.
           BYTE 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 1each time it sends a new Bulk-Out Header.
                                     //    The Host must set bTag such that:   1<=bTag<=255
           BYTE bTagInverse;         // -- The inverse (one`s complement) of the bTag.
           BYTE Reserved;            // -- Reserved. Must be 0x00
           
           // -------------  USBTMC command message specific ---------------------------------------
           USBTMC_COMMAND_MESSAGE  stCommandMessage;   // -- USBTMC command message specific
           // ----------------------------------------------------------------------------------------
        }__pk__;                                                                                                
        typedef struct _BULKOUT_HEADER BULKOUT_HEADER;
#pragma pack( pop )  
        
#pragma pack( push, 1 )
        __pkd__ struct _BULKIN_HEADER
        {
           BYTE MsgID;               // -- Must match MsgID in the USBTMC command message transfer causing this response
           BYTE bTag;                // -- Must match bTag in the USBTMC command message transfer causing this response                             
           BYTE bTagInverse;         // -- Must match bTagInverse in the USBTMC command message transfer causing this response
           BYTE Reserved;            // -- Reserved. Must be 0x00
           
           // -------------  USBTMC command message specific ---------------------------------------
           USBTMC_RESPOND_MESSAGE  stRespondMessage;   // -- USBTMC respond message specific
           // ----------------------------------------------------------------------------------------
        }__pk__;
        typedef struct _BULKIN_HEADER BULKIN_HEADER;
#pragma pack( pop )   
      

        struct _USBTMC_INFO_HEADER
        {
          int  IDNStringLength;
          char IDNString[MAX_USBTMC_IDNSTRING_SIZE];
        };
        typedef struct _USBTMC_INFO_HEADER USBTMC_INFO_HEADER;
        

        typedef enum
        {
          USB_INTERFACE_SCPI = 0,
          USB_INTERFACE_CONT = 1,

          USB_INTERFACE_INV  = 0xffffffff
        } USB_INTERFACE;         

        #define  USB_MAX_BULKIN_BUFFERSIZE   RAM_BULKINBUFFER_SIZE
        #define USB_MAX_BULKOUT_BUFFERSIZE   RAM_BULKOUTBUFFER_SIZE
        #define USB_MAX_FUNCCONTEXT          RAM_GPIBTRANSFERCONTEXT_SIZE
        // --------------------------------------------------------------------------------
        #define USB_MAX_BULK_PAYLOAD    (USB_MAX_PACKET2-sizeof(BULKOUT_HEADER))
        // USB_MAX_BULK_PAYLOAD - макс количество байт, передаваемых в одной OUT транзакции
        // вместе с BULKOUT_HEADER. Если длинна Payload больще этого числа, имеет место
        // разделение посылки данных на несколько транзакций.
        // --------------------------------------------------------------------------------
        
        #ifndef _USBTMC_C_
        extern const __root USBTMC_INFO_HEADER USBTMCInfo;
        extern BYTE  gEP2BufIn[];
        extern BYTE  gEP2BufOut[];
        #endif
                   
#endif


// =============================================================================
// =============================================================================
// ===       -= APPENDIX 1. Describing of the BULKOUT_HEADER =-              ===
// =============================================================================
// =============================================================================
//  See "USBTMC spec., rev 1.0, 2003": "page 7":"Figure 2", "page 8":"Figure 3", 
//  "page 9":"last paragraph".
//
//  Хост может передавать комманду с данными раздельно как в разных транзакциях,
//  так и в разных передачах.  Поэтому,  заголовок Bulk-Out  header  имеет  поле 
//  TransferSize,  которое  и  определяет  реальную  длинну сообщения с данными.
//  Хост не должен (читай ОБЯЗАН НЕ)  посылать новый  заголовок Bulk-Out header,
//  если еще не передал оставшуюся часть  сообщения.  Исключение:  хост  передал
//  на EP0 запрос  INITIATE_ABORT_BULK_OUT.  Он,  конечно, может,  только device
//  воспримет это не как Bulk-Out header,  а как данные,  собьется синхронизация
//  Host-Out-Device-In Messages и все полетит.