#ifndef _USBTMC_MAIN_H
#define _USBTMC_MAIN_H

#include "types.h"
#include "queue.h"


#define    USB_EP_LOG_ADDRESS_INT_IN      ((TENDPOINT_LOG_ADDRESS)(0x01 | (1<<7)))
#define    USB_EP_LOG_ADDRESS_BULK_IN     ((TENDPOINT_LOG_ADDRESS)(0x02 | (1<<7)))
#define    USB_EP_LOG_ADDRESS_BULK_OUT    ((TENDPOINT_LOG_ADDRESS)(0x02 | (0<<7)))

#define    USB_EP_PHY_ADDRESS_BULK_IN     ((TENDPOINT_PHY_ADDRESS)(0x05         ))
#define    USB_EP_PHY_ADDRESS_BULK_OUT    ((TENDPOINT_PHY_ADDRESS)(0x04         ))
#define    USB_EP_PHY_ADDRESS_INT_IN      ((TENDPOINT_PHY_ADDRESS)(0x03         ))

#define MAX_INBUFFER_SIZE       1536

//#defineUSB_MAX_PACKET0       64                //-- 8,16,32,64        // for USB2.0 can be only 64 !!!
#define  USB_MAX_PACKET1        2                // -- 1 to 64, выберем 2
#define  USB_MAX_PACKET2       64                //-- Ep4,Ep5 buffer size -- 64  


static inline void USB_INTERRUPT_ENABLE_BULKOUT()
{
  rUSBEpIntEn  |= (1<<(USB_EP_PHY_ADDRESS_BULK_OUT));
}

static inline void USB_INTERRUPT_DISABLE_BULKOUT()
{
  rUSBEpIntEn  &= (~(1<<(USB_EP_PHY_ADDRESS_BULK_OUT)));
}
           
static inline void USB_INTERRUPT_ENABLE_BULKIN()
{
  rUSBEpIntEn  |= (1<<(USB_EP_PHY_ADDRESS_BULK_IN));
}

static inline void USB_INTERRUPT_DISABLE_BULKIN()
{
  rUSBEpIntEn  &= (~(1<<(USB_EP_PHY_ADDRESS_BULK_IN)));
}
/* moved to "endpoints.c"
static inline void USB_INTERRUPT_CLEAR_BULKIN()
{
  // rUSBEpIntClr = 1<<(USB_EP_PHY_ADDRESS_BULK_IN);
  USB_EpIntrClr( USB_EP_PHY_ADDRESS_BULK_IN );
}

static inline void USB_INTERRUPT_CLEAR_BULKOUT()
{
  // rUSBEpIntClr = 1<<(USB_EP_PHY_ADDRESS_BULK_OUT);
  USB_EpIntrClr( USB_EP_PHY_ADDRESS_BULK_OUT );
}

static inline void USB_INTERRUPT_CLEAR_INTIN()
{
  //rUSBEpIntClr = 1<<(USB_EP_PHY_ADDRESS_INT_IN);  
  USB_EpIntrClr( USB_EP_PHY_ADDRESS_INT_IN );
}
*/
/*
#define USB_INTERRUPT_ENABLE_NAK()            ?(usb_lpc_cmd_write(CMD_DEV_SET_MODE,(1<<3)|(1<<5)|(1<<6)))
#define USB_INTERRUPT_DISABLE_NAK()           ?(usb_lpc_cmd_write(CMD_DEV_SET_MODE,(1<<6)))
*/
/*
#define USB_INTERRUPT_DISABLE_INT_NAK()       (usb_lpc_cmd_write(CMD_DEV_SET_MODE,(1<<3)|(1<<5)|(1<<6))) // setup NAK for BULK only
*/
/*
#define USB_INTERRUPT_ENABLE_BULKIN_NAK()     ?(usb_lpc_cmd_write(CMD_DEV_SET_MODE,(1<<5)|(1<<6)))
#define USB_INTERRUPT_DISABLE_BULKIN_NAK()    ?(usb_lpc_cmd_write(CMD_DEV_SET_MODE,(1<<6)))
#define USB_INTERRUPT_ENABLE_INT_NAK()        ?(usb_lpc_cmd_write(CMD_DEV_SET_MODE,(1<<3)|(1<<5)|(1<<6)))
#define USB_INTERRUPT_DISABLE_INT_NAK()       ?(usb_lpc_cmd_write(CMD_DEV_SET_MODE,(1<<5)|(1<<6))) // setup NAK for BULK only, fixed 30/08/18
*/

void USB_INTERRUPT_DISABLE_NAK();        // fixed 30/08/18, see "usb_hardware.c"
void USB_INTERRUPT_ENABLE_BULKIN_NAK();  // fixed 30/08/18, see "usb_hardware.c"
void USB_INTERRUPT_DISABLE_BULKIN_NAK(); // fixed 30/08/18, see "usb_hardware.c"
void USB_INTERRUPT_ENABLE_BULKOUT_NAK();  // added 30/08/18, see "usb_hardware.c"
void USB_INTERRUPT_DISABLE_BULKOUT_NAK(); // added 30/08/18, see "usb_hardware.c"
void USB_INTERRUPT_ENABLE_INTIN_NAK();   // fixed 30/08/18, see "usb_hardware.c"
void USB_INTERRUPT_DISABLE_INTIN_NAK();  // fixed 30/08/18, see "usb_hardware.c"

#include "critical.h"

struct __sScpiCommand; // forward declaration

typedef struct _USB_BULKMESSAGE_STATUS
{
  BOOL bEOM;                             // see USBTMC spec, rev 1.0, 2003, page 7, table 3, description of bmTransferAttributes.D0
  BYTE MsgID;                            // see usbtmc.h
  BYTE bTag;                             // see usbtmc.h
  //----------------------------------------
  BYTE bTagLast;
  BOOL OUTTransferInProgress;            // показывает, что происходит передача данных с кешированием. нужно для обработки запроса INITIATE_ABORT_BULK_OUT
  BYTE bBulkHeaderRecieved;              // true = принят заголовок BULK-OUT
  DWORD nBytesRecieved;                  // количество байт уже принятых в этом сообщении
  BYTE * pData;                          // указатель на буфер, содержащий принятое сообщение (полностью принятое)
  int OutTransferSize;                   // количество байт передаваемых в этом сообщении, берется из заголовка
} 
USB_BULKMESSAGE_STATUS;

typedef struct _USB_BULKRESPOND_STATUS
{
  BOOL bEOM;                              // see USBTMC spec, rev 1.0, 2003, page 7, table 3, description of bmTransferAttributes.D0
  BYTE MsgID;                             // see usbtmc.h
  BYTE bTag;                              // see usbtmc.h
  //----------------------------------------
  BOOL INTransferInProgress;              // показывает, что происходит передача данных от Device к Host и она не завершена
  BOOL INTransferTerminating;             // показывает, что Bulk-In передача находится в процессе завершения (пришел пакет INITIATE_ABORT_BULK_IN)
  DWORD nBytesSent;                       // количество байт, уже отосланых в этом сообщении (для передач Bulk-IN)
  
  int InTransferSize;                     // количество байт, которые хост запросил из устройства, берется из заголовка
  unsigned int dwDeviceOut;               // количество байт, которое собирается передать устройство
  int RespondBufferSize;                  // доступное количество байт в выходном буфере устройста. инициализируется в usbtmc_DEV_DEP_MSG_OUT()

  BOOL bIsLastTransfer;                   // TRUE если это последняя Transfer в этом USBTMC-message
  
  BOOL bEndOfMessage;                     // 27/08/18
} 
USB_BULKRESPOND_STATUS;


typedef struct _USB_USBTMC_GPIBEMULATION_STATEMACHINE
{
  //--------------------
  BYTE bTag_Interrupt;
  //---------------------
  BYTE STB;
  BYTE SRE;
  // -----------------
  BYTE ESR;
  BYTE ESE;
  // -----------------
  QUEUE qErrorQueue;
  QUEUE qErrorQueue_backup;
  
} 
USB_USBTMC_GPIBEMULATION_STATEMACHINE;


typedef struct _GPIB_COMMAND_TREE
{
  struct __sScpiCommand * gpib_root;                 // root комманда древа GPIB комманд
  struct __sScpiCommand * gpib_search;               // указатель на нод где ищем 
  struct __sScpiCommand * gpib_owner;                //  указатель на нод-владельца текущей комманды
  char * sgpib_current;                 // текущая выполняемая комманда
  BYTE * pData;                         // указатель на буфер, куда складывать ответы
  
  USB_USBTMC_GPIBEMULATION_STATEMACHINE StateMachine;

  int cRequestCountSupport;  

} 
GPIB_COMMAND_TREE;    
  

typedef struct _USB_USBTMC_CLASS_STATUS
{
  
  BYTE USBTMC_status;                 // STATUS_SUCCESS, STATUS_PENDING, ...
  BOOL USBTMC_InitiateRecieved;       // true/false
  
  // volatile FLAG_PROTECTED USBTMC_RequestPending;         // хост ожидает ответа // #!#  
} 
USB_USBTMC_CLASS_STATUS; 


typedef struct _USB_TRANSFER_CONTEXT
{
  void *    LastFunction;
  QUEUE     Context;
  BOOL      bEnable;
} 
USB_TRANSFER_CONTEXT;

#endif