#ifndef SCPI_GPIB_CORE_H
#define SCPI_GPIB_CORE_H

  #include <stdint.h>
  #include <stdbool.h>
  #include "app/scpi/scpi_base.h"

  // Reference:
  // [1] SCPI Specification, revision 1999.0
  //     "Standard Commands for Programmable Instruments (SCPI), VERSION 1999.0, May 1999"
  // [2], Gpib Programming Tutorial, Electronics Group (http://www.few.vu.nl/~elec), 11 January 2000 Electronics Group, (http://g2pc1.bu.edu/~qzpeng/gpib/manual/GpibProgTut.pdf)
  // [3] USBTMC-USB488 Standard, rev. 1.0, 14/04/2003
  //     "Universal Serial Bus Test and Measurement Class, Subclass USB488 Specification (USBTMC-USB488)
  // [4] IEEE 488.2 Standard, revision IEEE Std 488.2-1987 (1992)
  //     "IEEE Standard Codes, Formats, Protocols, and Common Commands for Use With IEEE Std 488.1-1987, IEEE

  #pragma pack(push,1)
  typedef struct
  {
     const void * private[2];
  }
  xGPIBRegisters_t;
  #pragma pack(pop)
  // --------------------------------------------------------------------------------------------------------
  typedef struct
  {
     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_get_event_status_register
     // Returns GPIB event status register
     // Reference:
     //  "4 Instrument status", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @pesr - pointer to the variable to store the value of ESR (event status register) to.
     // Returns: none
     void ( * fGPIB_get_event_status_register)( xGPIBRegisters_t * _gpibr, uint8_t * pesr );

     // --------------------------------------------------------------------------------------------------------
     // @gpib_set_event_status_register_power_on_state
     // Sets GPIB event status register status: power on
     // Reference:
     //  "4 Instrument status", [2]
     //  "11.5.1.1 Standard Event Status Register Bit Definitions", [4]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @pon - value of Power On bit (PON) in ESR (event status register) to write to GPIB Register structure.
     // Returns: none
     void ( * fGPIB_set_event_status_register_power_on_state )( xGPIBRegisters_t * _gpibr, bool pon );
     
     // --------------------------------------------------------------------------------------------------------
     // @gpib_set_event_status_register_user_request_state
     // Sets GPIB event status register status: user request
     // Reference:
     //  "4 Instrument status", [2]
     //  "11.5.1.1 Standard Event Status Register Bit Definitions", [4]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @urq - value of User Request bit (URQ) in ESR (event status register) to write to GPIB Register structure.
     // Returns: none
     void ( * fGPIB_set_event_status_register_user_request_state )( xGPIBRegisters_t * _gpibr, bool urq );
     
     // --------------------------------------------------------------------------------------------------------
     // @gpib_set_event_status_register_command_error_state
     // Sets GPIB event status register status: command error
     // Reference:
     //  "4 Instrument status", [2]
     //  "11.5.1.1 Standard Event Status Register Bit Definitions", [4]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @cme - value of Command Error bit (CME) in ESR (event status register) to write to GPIB Register structure.
     // Returns: none
     void ( * fGPIB_set_event_status_register_command_error_state )( xGPIBRegisters_t * _gpibr, bool cme );
     
     // --------------------------------------------------------------------------------------------------------
     // @gpib_set_event_status_register_execution_error_state
     // Sets GPIB event status register status: execution error
     // Reference:
     //  "4 Instrument status", [2]
     //  "11.5.1.1 Standard Event Status Register Bit Definitions", [4]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @e - value of Execution Error bit (E) in ESR (event status register) to write to GPIB Register structure.
     // Returns: none
     void ( * fGPIB_set_event_status_register_execution_error_state )( xGPIBRegisters_t * _gpibr, bool e );
     
     // --------------------------------------------------------------------------------------------------------
     // @gpib_set_event_status_register_device_specific_error_state
     // Sets GPIB event status register status: device specific error
     // Reference:
     //  "4 Instrument status", [2]
     //  "11.5.1.1 Standard Event Status Register Bit Definitions", [4]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @dde - value of Device Specific Error bit (DDE) in ESR (event status register) to write to GPIB Register structure.
     // Returns: none
     void ( * fGPIB_set_event_status_register_device_specific_error_state )( xGPIBRegisters_t * _gpibr, bool dde );
     
     // --------------------------------------------------------------------------------------------------------
     // @gpib_set_event_status_register_query_error_state
     // Sets GPIB event status register status: query error
     // Reference:
     //  "4 Instrument status", [2]
     //  "11.5.1.1 Standard Event Status Register Bit Definitions", [4]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @qye - value of Device Specific Error bit (QYE) in ESR (event status register) to write to GPIB Register structure.
     // Returns: none
     void ( * fGPIB_set_event_status_register_query_error_state )( xGPIBRegisters_t * _gpibr, bool qye );
     
     // --------------------------------------------------------------------------------------------------------
     // @gpib_set_event_status_register_request_control_state
     // Sets GPIB event status register status: request control
     // Reference:
     //  "4 Instrument status", [2]
     //  "11.5.1.1 Standard Event Status Register Bit Definitions", [4]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @rqc - value of Request Control bit (RQC) in ESR (event status register) to write to GPIB Register structure.
     // Returns: none
     void ( * fGPIB_set_event_status_register_request_control_state )( xGPIBRegisters_t * _gpibr, bool rqc );
     
     // --------------------------------------------------------------------------------------------------------
     // @gpib_set_event_status_register_operation_complete_state
     // Sets GPIB event status register status: operation complete
     // Reference:
     //  "4 Instrument status", [2]
     //  "11.5.1.1 Standard Event Status Register Bit Definitions", [4]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @opc - value of Operation Complete bit (RQC) in ESR (event status register) to write to GPIB Register structure.
     // Returns: none
     void ( * fGPIB_set_event_status_register_operation_complete_state )( xGPIBRegisters_t * _gpibr, bool opc );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_get_event_status_enable_register
     // Returns GPIB event status enable register
     // Reference:
     //  "4 Instrument status", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @pesr - pointer to the variable to store the value of ESE (event status enable register) to.
     // Returns: none     
     void ( * fGPIB_get_event_status_enable_register)( xGPIBRegisters_t * _gpibr, uint8_t * pese );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_set_event_status_enable_register
     // Sets GPIB event status enable register
     // Reference:
     //  "4 Instrument status", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @ese - value of ESE (event status enable register) to write to GPIB Register structure.
     // Returns: none
     void ( * fGPIB_set_event_status_enable_register)( xGPIBRegisters_t * _gpibr, uint8_t ese );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_get_event_summary_bit
     // Return GPIB event summary bit
     // Reference:
     //   "4.1 Status Byte registers (STB and SRE)", "Event Summary Bit", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @pesb - pointer to the variable to store the value of ESB (event summary bit) to.
     // Note: the value of the bit will be set to the corresponding bit position, all the rest bits are reset to zero.
     // Returns: none
     void ( * fGPIB_get_event_summary_bit)( xGPIBRegisters_t * _gpibr, uint8_t * pesb );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_set_event_summary_enable_state
     // Set GPIB event summary enable bit in Service Request Enable Register (SRE) 
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @esb - the event summary indictor enable to set to GPIB Register structure.     
     // Returns: none
     void ( * fGPIB_set_event_summary_enable_state)( xGPIBRegisters_t * _gpibr, bool esb );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_set_message_available_bit
     // Set GPIB message available bit
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @pmav - pointer to the variable to store the value of MAV (message available bit) to.
     // Note: the value of the bit will be set to the corresponding bit position, all the rest bits are reset to zero.
     // Returns: none 
     void ( * fGPIB_set_message_available_bit)( xGPIBRegisters_t * _gpibr, bool mav ); 

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_set_message_available_enable_state
     // Set GPIB message available enable bit in Service Request Enable Register (SRE) 
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @mav - the message available indictor enable to set to GPIB Register structure.     
     // Returns: none
     void ( * fGPIB_set_message_available_enable_state)( xGPIBRegisters_t * _gpibr, bool mav );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_get_message_available_bit
     // Return GPIB message available bit
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @mav - the message available indictor to set to GPIB Register structure.
     // Returns: none
     void ( * fGPIB_get_message_available_bit)( xGPIBRegisters_t * _gpibr, uint8_t * pmav );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_set_error_available_bit
     // Set GPIB error available bit
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @eav - the error available indictor to set to GPIB Register structure.
     // Returns: none 
     void ( * fGPIB_set_error_available_bit)( xGPIBRegisters_t * _gpibr, bool eav );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_set_error_available_enable_state
     // Set GPIB error available enable bit in Service Request Enable Register (SRE)
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @eav - the error available indictor enable to set to GPIB Register structure.
     // Returns: none 
     void ( * fGPIB_set_error_available_enable_state)( xGPIBRegisters_t * _gpibr, bool eav );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_get_error_available_bit
     // Return GPIB error available bit
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @peav - pointer to the variable to store the value of EAV (error available bit) to.
     // Note: the value of the bit will be set to the corresponding bit position, all the rest bits are reset to zero.
     // Returns: none 
     void ( * fGPIB_get_error_available_bit)( xGPIBRegisters_t * _gpibr, uint8_t * peav );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_get_status_byte_serial_poll
     // Return GPIB Status Byte
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     //   "3.4.1 Interrupt-IN DATA sent due to an SRQ condition", [3]
     //   "3.4.2 Interrupt-IN DATA sent due to READ_STATUS_BYTE request", [3]
     //   "11.2.2 Reading the Status Byte Register", [4]
     //   "11.2.2.3 Master Summary Status", [4]
     //   "11.3.2.4 Clearing the Service Request Enable Register", [4]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @pstb - pointer to the variable to store the value of STB (status byte) to.
     // Returns: none 
     void ( * fGPIB_get_status_byte_serial_poll)( xGPIBRegisters_t * _gpibr, uint8_t * pstb );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_get_status_byte_normal_poll
     // Return GPIB Status Byte
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     //   "3.4.1 Interrupt-IN DATA sent due to an SRQ condition", [3]
     //   "3.4.2 Interrupt-IN DATA sent due to READ_STATUS_BYTE request", [3]
     //   "11.2.2 Reading the Status Byte Register", [4]
     //   "11.2.2.3 Master Summary Status", [4]
     //   "11.3.2.4 Clearing the Service Request Enable Register", [4]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @pstb - pointer to the variable to store the value of STB (status byte) to.
     // Returns: none 
     void ( * fGPIB_get_status_byte_normal_poll)( xGPIBRegisters_t * _gpibr, uint8_t * pstb );
     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_clr_status_byte
     // Clears GPIB Status Byte
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     //   "11.2.4 Clearing the Status Byte Register"
     // Parameters:
     // @_gpibr - GPIB Register structure;     
     // Returns: none 
     void ( * fGPIB_clr_status_byte)( xGPIBRegisters_t * _gpibr );
     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_get_service_request_enable_register
     // Return GPIB Service Request Enable Register
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @psre - pointer to the variable to store the value of SRE (Service Request Enable Register) to.
     // Returns: none 
     void ( * fGPIB_get_service_request_enable_register)( xGPIBRegisters_t * _gpibr, uint8_t * psre );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_set_service_request_enable_register
     // Set GPIB Service Request Enable Register
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @sre - value of SRE (Service Request Enable Register) to write to GPIB Register structure.
     // Returns: none 
     void ( * fGPIB_set_service_request_enable_register)( xGPIBRegisters_t * _gpibr, uint8_t sre );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_get_service_request_status
     // Return GPIB Service Request indicator (Service Request Generation, SRQ)
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @psrq - pointer to the variable to store the state of SRQ indicator (Service ReQuest) to.
     // Returns: none 
     void ( * fGPIB_get_service_request_status)( xGPIBRegisters_t * _gpibr, bool * psrq );

     // --------------------------------------------------------------------------------------------------------
     // @fGPIB_set_service_request_status
     // Writes GPIB Service Request indicator (Service Request Generation, SRQ)
     // Reference:
     //   "4 Instrument status", [2]
     //   "4.1 Status Byte registers (STB and SRE)", [2]
     //   "11.2.2.3 Master Summary Status", [4]
     //   "11.3.2.4 Clearing the Service Request Enable Register", [4]
     // Parameters:
     // @_gpibr - GPIB Register structure;
     // @srq - SRQ indicator value (Service ReQuest) to write
     // Returns: none 
     void ( * fGPIB_set_service_request_status)( xGPIBRegisters_t * _gpibr, bool srq );
  }
  sGPIBMachineRoutines_t;

  // Export GPIB Machine routines
  extern const sGPIBMachineRoutines_t GPIBMachine;
#endif