//  PCANTP.pas
//
//  ~~~~~~~~~~~~
//
//  PCAN-ISO-TP API
//
//  ~~~~~~~~~~~~
//
//  ------------------------------------------------------------------
//	Last changed by:	$Author: Fabrice $
//  Last changed date:	$Date: 2019-12-09 12:10:22 +0100 (lun., 09 déc. 2019) $
//
//  Language: Pascal Not OO
//  ------------------------------------------------------------------
//
//  Copyright (C) 2015  PEAK-System Technik GmbH, Darmstadt
//  more Info at http://www.peak-system.com
//
unit PCANTP_NotOO;

interface

const
    ////////////////////////////////////////////////////////////
    // Value definitions
    ////////////////////////////////////////////////////////////

    // Currently defined and supported PCANTP channels
    //
    PCANTP_NONEBUS              = $00;  // Undefined/default value for a PCAN bus

    PCANTP_ISABUS1              = $21;  // PCAN-ISA interface, channel 1
    PCANTP_ISABUS2              = $22;  // PCAN-ISA interface, channel 2
    PCANTP_ISABUS3              = $23;  // PCAN-ISA interface, channel 3
    PCANTP_ISABUS4              = $24;  // PCAN-ISA interface, channel 4
    PCANTP_ISABUS5              = $25;  // PCAN-ISA interface, channel 5
    PCANTP_ISABUS6              = $26;  // PCAN-ISA interface, channel 6
    PCANTP_ISABUS7              = $27;  // PCAN-ISA interface, channel 7
    PCANTP_ISABUS8              = $28;  // PCAN-ISA interface, channel 8

    PCANTP_DNGBUS1              = $31;  // PPCAN-Dongle/LPT interface, channel 1

    PCANTP_PCIBUS1              = $41;  // PCAN-PCI interface, channel 1
    PCANTP_PCIBUS2              = $42;  // PCAN-PCI interface, channel 2
    PCANTP_PCIBUS3              = $43;  // PCAN-PCI interface, channel 3
    PCANTP_PCIBUS4              = $44;  // PCAN-PCI interface, channel 4
    PCANTP_PCIBUS5              = $45;  // PCAN-PCI interface, channel 5
    PCANTP_PCIBUS6              = $46;  // PCAN-PCI interface, channel 6
    PCANTP_PCIBUS7              = $47;  // PCAN-PCI interface, channel 7
    PCANTP_PCIBUS8              = $48;  // PCAN-PCI interface, channel 8
    PCANTP_PCIBUS9              = $409;  // PCAN-PCI interface, channel 9
	PCANTP_PCIBUS10             = $40A;  // PCAN-PCI interface, channel 10
	PCANTP_PCIBUS11             = $40B;  // PCAN-PCI interface, channel 11
	PCANTP_PCIBUS12             = $40C;  // PCAN-PCI interface, channel 12
	PCANTP_PCIBUS13             = $40D;  // PCAN-PCI interface, channel 13
	PCANTP_PCIBUS14             = $40E;  // PCAN-PCI interface, channel 14
	PCANTP_PCIBUS15             = $40F;  // PCAN-PCI interface, channel 15
	PCANTP_PCIBUS16             = $410;  // PCAN-PCI interface, channel 16

    PCANTP_USBBUS1              = $51;  // PCAN-USB interface, channel 1
    PCANTP_USBBUS2              = $52;  // PCAN-USB interface, channel 2
    PCANTP_USBBUS3              = $53;  // PCAN-USB interface, channel 3
    PCANTP_USBBUS4              = $54;  // PCAN-USB interface, channel 4
    PCANTP_USBBUS5              = $55;  // PCAN-USB interface, channel 5
    PCANTP_USBBUS6              = $56;  // PCAN-USB interface, channel 6
    PCANTP_USBBUS7              = $57;  // PCAN-USB interface, channel 7
    PCANTP_USBBUS8              = $58;  // PCAN-USB interface, channel 8
	PCANTP_USBBUS9              = $509;  // PCAN-USB interface, channel 9
	PCANTP_USBBUS10             = $50A;  // PCAN-USB interface, channel 10
	PCANTP_USBBUS11             = $50B;  // PCAN-USB interface, channel 11
	PCANTP_USBBUS12             = $50C;  // PCAN-USB interface, channel 12
	PCANTP_USBBUS13             = $50D;  // PCAN-USB interface, channel 13
	PCANTP_USBBUS14             = $50E;  // PCAN-USB interface, channel 14
	PCANTP_USBBUS15             = $50F;  // PCAN-USB interface, channel 15
	PCANTP_USBBUS16             = $510;  // PCAN-USB interface, channel 16

    PCANTP_PCCBUS1              = $61;  // PCAN-PC Card interface, channel 1
    PCANTP_PCCBUS2              = $62;  // PCAN-PC Card interface, channel 2

    PCANTP_LANBUS1              = $801;  // PCAN-LAN interface, channel 1
    PCANTP_LANBUS2              = $802;  // PCAN-LAN interface, channel 2
    PCANTP_LANBUS3              = $803;  // PCAN-LAN interface, channel 3
    PCANTP_LANBUS4              = $804;  // PCAN-LAN interface, channel 4
    PCANTP_LANBUS5              = $805;  // PCAN-LAN interface, channel 5
    PCANTP_LANBUS6              = $806;  // PCAN-LAN interface, channel 6
    PCANTP_LANBUS7              = $807;  // PCAN-LAN interface, channel 7
    PCANTP_LANBUS8              = $808;  // PCAN-LAN interface, channel 8
	PCANTP_LANBUS9              = $809;  // PCAN-LAN interface, channel 9
	PCANTP_LANBUS10             = $80A;  // PCAN-LAN interface, channel 10
	PCANTP_LANBUS11             = $80B;  // PCAN-LAN interface, channel 11
	PCANTP_LANBUS12             = $80C;  // PCAN-LAN interface, channel 12
	PCANTP_LANBUS13             = $80D;  // PCAN-LAN interface, channel 13
	PCANTP_LANBUS14             = $80E;  // PCAN-LAN interface, channel 14
	PCANTP_LANBUS15             = $80F;  // PCAN-LAN interface, channel 15
	PCANTP_LANBUS16             = $810;  // PCAN-LAN interface, channel 16

    // PCANTP Baudrates for the CAN Hardware
    //
    PCANTP_BAUD_1M          = $0014;  // Channel Baudrate 1 MBit/s
    PCANTP_BAUD_800K        = $0016;  // Channel Baudrate 800 kBit/s
    PCANTP_BAUD_500K        = $001C;  // Channel Baudrate 500 kBit/s
    PCANTP_BAUD_250K        = $011C;  // Channel Baudrate 250 kBit/s
    PCANTP_BAUD_125K        = $031C;  // Channel Baudrate 125 kBit/s
    PCANTP_BAUD_100K        = $432F;  // Channel Baudrate 100 kBit/s
    PCANTP_BAUD_95K         = $C34E;  // Channel Baudrate 95,238 kBit/s
    PCANTP_BAUD_83K         = $852B;  // Channel Baudrate 83,333 kBit/s
    PCANTP_BAUD_50K         = $472F;  // Channel Baudrate 50 kBit/s
    PCANTP_BAUD_47K         = $1414;  // Channel Baudrate 47,619 kBit/s
    PCANTP_BAUD_33K         = $8B2F;  // Channel Baudrate 33,333 kBit/s
    PCANTP_BAUD_20K         = $532F;  // Channel Baudrate 20 kBit/s
    PCANTP_BAUD_10K         = $672F;  // Channel Baudrate 10 kBit/s
    PCANTP_BAUD_5K          = $7F7F;  // Channel Baudrate 5 kBit/s
    
    // Represents the configuration for a CAN bit rate
    // Note: 
    //    * Each parameter and its value must be separated with a '='.
    //    * Each pair of parameter/value must be separated using ','. 
    //
    // Example:
    //    f_clock=80000000,nom_brp=0,nom_tseg1=13,nom_tseg2=0,nom_sjw=0,data_brp=0,data_tseg1=13,data_tseg2=0,data_sjw=0
    //
    PCANTP_BR_CLOCK            = 'f_clock';
    PCANTP_BR_CLOCK_MHZ        = 'f_clock_mhz';
    PCANTP_BR_NOM_BRP          = 'nom_brp';
    PCANTP_BR_NOM_TSEG1        = 'nom_tseg1';
    PCANTP_BR_NOM_TSEG2        = 'nom_tseg2';
    PCANTP_BR_NOM_SJW          = 'nom_sjw';
    PCANTP_BR_NOM_SAMPLE       = 'nom_sam';
    PCANTP_BR_DATA_BRP         = 'data_brp';
    PCANTP_BR_DATA_TSEG1       = 'data_tseg1';
    PCANTP_BR_DATA_TSEG2       = 'data_tseg2';
    PCANTP_BR_DATA_SJW         = 'data_sjw';
    PCANTP_BR_DATA_SAMPLE      = 'data_ssp_offset';

    // Non Plug-And-Play PCANTP Hardware types
    //
    PCANTP_TYPE_ISA            = $01;  // PCAN-ISA 82C200
    PCANTP_TYPE_ISA_SJA        = $09;  // PCAN-ISA SJA1000
    PCANTP_TYPE_ISA_PHYTEC     = $04;  // PHYTEC ISA
    PCANTP_TYPE_DNG            = $02;  // PCAN-Dongle 82C200
    PCANTP_TYPE_DNG_EPP        = $03;  // PCAN-Dongle EPP 82C200
    PCANTP_TYPE_DNG_SJA        = $05;  // PCAN-Dongle SJA1000
    PCANTP_TYPE_DNG_SJA_EPP    = $06;  // PCAN-Dongle EPP SJA1000

    // Represent the PCAN-TP error and status codes
    //
    PCANTP_ERROR_OK							      = $00000;	// No error
    PCANTP_ERROR_NOT_INITIALIZED			= $00001; // Not Initialized
    PCANTP_ERROR_ALREADY_INITIALIZED	= $00002; // Already Initialized
    PCANTP_ERROR_NO_MEMORY					  = $00003; // Could not obtain memory
    PCANTP_ERROR_OVERFLOW					    = $00004; // Input buffer overflow
    PCANTP_ERROR_NO_MESSAGE					  = $00007; // No Message available
    PCANTP_ERROR_WRONG_PARAM				  = $00008; // Wrong message parameters
    PCANTP_ERROR_BUSLIGHT					    = $00009; // PCANTP Channel is in BUS-LIGHT error state
    PCANTP_ERROR_BUSHEAVY					    = $0000A; // PCANTP Channel is in BUS-HEAVY error state
    PCANTP_ERROR_BUSOFF						    = $0000B; // PCANTP Channel is in BUS-OFF error state
    PCANTP_ERROR_CAN_ERROR					  = Longint($80000000);	// Global CAN error, status code for composition of PCANBasic Errors.
                                                                    // Remove this value to get a PCAN-Basic TPCANStatus error code.

    // Represents message request confirmation values defined in ISO-15765-2 (see page 10-11)
    //
    PCANTP_N_OK                       = $00;	// No network error
    PCANTP_N_TIMEOUT_A                = $01;	// timeout occured between 2 frames transmission (sender and receiver side)
    PCANTP_N_TIMEOUT_Bs               = $02;	// sender side timeout while waiting for flow control frame
    PCANTP_N_TIMEOUT_Cr               = $03;	// receiver side timeout while waiting for consecutive frame
    PCANTP_N_WRONG_SN                 = $04;	// unexpected sequence number
    PCANTP_N_INVALID_FS               = $05;	// invalid or unknown FlowStatus
    PCANTP_N_UNEXP_PDU                = $06;	// unexpected protocol data unit
    PCANTP_N_WFT_OVRN                 = $07;	// reception of flow control WAIT frame that exceeds the maximum counter defined by PCANTP_PARAM_WFT_MAX
    PCANTP_N_BUFFER_OVFLW             = $08;	// buffer on the receiver side cannot store the data length (server side only)
    PCANTP_N_ERROR                    = $09;	// general error

    // PCANTP parameters
    //
    PCANTP_PARAM_BLOCK_SIZE	          = $E1;     // 1 BYTE data describing the block size parameter (BS)
    PCANTP_PARAM_SEPARATION_TIME	    = $E2;     // 1 BYTE data describing the seperation time parameter (STmin)
    PCANTP_PARAM_DEBUG       	        = $E3;     // 1 BYTE data describing the debug mode
    PCANTP_PARAM_CHANNEL_CONDITION		= $E4;     // 1 BYTE data describing the condition of a channel.
    PCANTP_PARAM_WFT_MAX						  = $E5;     // Integer data describing the Wait Frame Transmissions parameter.
    PCANTP_PARAM_MSG_PENDING					= $E6;     // 1 BYTE data stating if pending messages are displayed/hidden
    PCANTP_PARAM_API_VERSION					= $E7;     // PCAN-ISO-TP API version parameter
    PCANTP_PARAM_CAN_DATA_PADDING			= $E8;     // 1 BYTE data stating if CAN frame DLC uses padding or not
  	PCANTP_PARAM_CAN_UNSEGMENTED			= $E9;	   // 1 BYTE data stating if unsegmented (NON-ISO-TP) CAN frames can be received
    PCANTP_PARAM_RECEIVE_EVENT				= $EA;	   // PCAN-ISO-TP receive event handler parameter
    PCANTP_PARAM_PADDING_VALUE				= $ED;	   // 1 BYTE data stating the value used for CAN data padding
    PCANTP_PARAM_J1939_PRIORITY				= $EE;	   // 1 BYTE data stating the default priority value for normal fixed, mixed and enhanced addressing (default=6)
    PCANTP_PARAM_CAN_TX_DL    				= $EF;	   // 1 BYTE data stating the default DLC to use when transmitting messages with CAN FD
    PCANTP_PARAM_SEPARATION_TIME_OPTIMIZATION = $F0;   // 1 BYTE data stating how to optimize Minimum SeparationTime latency (enabled=1 by default)
                                                       //  -> set value to 0 to ensure STMin is always strictly respected (but consequently lose some speed in communication process)

    // PCANTP parameter values
    //
    PCANTP_DEBUG_NONE		       	      = $00;     // No debug messages
    PCANTP_DEBUG_CAN		       	      = $01;     // Puts CAN debug messages to stdout
    PCANTP_CHANNEL_UNAVAILABLE				= $00;     // The Channel is illegal or not available
    PCANTP_CHANNEL_AVAILABLE					= $01;     // The Channel is available
    PCANTP_CHANNEL_OCCUPIED						= $02;     // The Channel is valid, and is being used
    PCANTP_WFT_MAX_UNLIMITED					= $00;     // if set Flow Control frame shall not use the WT flow status value
    PCANTP_WFT_MAX_DEFAULT						= $10;     // an integer describing the Wait Frame Transmissions parameter.
    PCANTP_MSG_PENDING_HIDE   		    = $00;     // hide messages with type PCANTP_MESSAGE_INDICATION from CANTP_Read function
    PCANTP_MSG_PENDING_SHOW						= $01;     // show messages with type PCANTP_MESSAGE_INDICATION from CANTP_Read function
    PCANTP_CAN_DATA_PADDING_NONE   		= $00;     // uses CAN frame data optimization
    PCANTP_CAN_DATA_PADDING_ON				= $01;     // uses CAN frame data padding (default, i.e. CAN DLC = 8)
    PCANTP_CAN_DATA_PADDING_VALUE			=	$55;	   // default value used if CAN data padding is enabled
    PCANTP_CAN_UNSEGMENTED_OFF   		  = $00;     // disable reception of unformatted (NON-ISO-TP) CAN frames (default)
		                    											   //   only ISO 15765 messages will be received
  	PCANTP_CAN_UNSEGMENTED_ON				  = $01;     // enable reception of unformatted (NON-ISO-TP) CAN frames
                      												   //   received messages will be treated as either ISO 15765 or as an unformatted CAN frame
  	PCANTP_CAN_UNSEGMENTED_ALL_FRAMES	= $02;     // enable reception of unformatted (NON-ISO-TP) CAN frames
                    													   //   received messages will be treated as ISO 15765, unformatted CAN frame, or both (user will able to read fragmented CAN frames)
  	PCANTP_J1939_PRIORITY_DEFAULT = $06;	 // default priority for ISO-TP messages (only available fot normal fixed, mixed and enhanced addressing)

    // PCANTP message types
    //
    PCANTP_MESSAGE_UNKNOWN						    = $00;     // Unknown (non-ISO-TP) message
    PCANTP_MESSAGE_DIAGNOSTIC             = $01;     // Diagnostic Request/Confirmation
    PCANTP_MESSAGE_REMOTE_DIAGNOSTIC      = $02;     // Remote Dignostic Request/Confirmation (uses RA address)
    PCANTP_MESSAGE_REQUEST_CONFIRMATION   = $03;     // Confirms that a message has been sent successfully/ not successfully
    PCANTP_MESSAGE_INDICATION             = $04;     // Multi-Frame Message is being received
    PCANTP_MESSAGE_INDICATION_TX          = $05;     // Multi-Frame Message is being transmitted

    // PCANTP CAN ID types
    //
    PCANTP_ID_CAN_11BIT							= $01;		// 11 bits CAN ID (CAN Standard Frame)
    PCANTP_ID_CAN_29BIT							= $02;		// 29 bits CAN ID (CAN Extended Frame)
    PCANTP_ID_CAN_FD						  	= $04;		// CAN FD flag
    PCANTP_ID_CAN_BRS						  	= $08;		// Bitrate Switch flag (only if CAN FD)
    PCANTP_ID_CAN_MASK							= $0F;		// Mask to retrieve the CAN ID type
    PCANTP_ID_CAN_IS_PRIORITY_MASK	= $10;		// Mask to check if the priority field is set
    PCANTP_ID_CAN_PRIORITY_MASK			= $E0;		// Mask to retrieve the J1939 priority
    CAN_ID_NO_MAPPING	              = LongWord($FFFFFFFF);
    PCANTP_MESSAGE_MAX_LENGTH				=	$fff;		// max data length (prior ISO 15765-2:2016 update)

    // PCANTP format types
    //
    PCANTP_FORMAT_UNKNOWN			    = $FF;    // unknown adressing format
	  PCANTP_FORMAT_NONE					  = $00;		// unsegmented CAN frame
    PCANTP_FORMAT_NORMAL			    = $01;    // normal adressing format from ISO 15765-2
    PCANTP_FORMAT_FIXED_NORMAL		= $02;    // fixed normal adressing format from ISO 15765-2
    PCANTP_FORMAT_EXTENDED			  = $03;    // extended adressing format from ISO 15765-2
    PCANTP_FORMAT_MIXED				    = $04;		// mixed adressing format from ISO 15765-2
    PCANTP_FORMAT_ENHANCED			  = $05;		// enhanced adressing format from ISO 15765-3

    // PCANTP addressing types
    //
    PCANTP_ADDRESSING_UNKNOWN		    = $00;     // Unknown (non-ISO-TP) message
    PCANTP_ADDRESSING_PHYSICAL      = $01;     // Physical addressing
    PCANTP_ADDRESSING_FUNCTIONAL    = $02;     // Functional addressing

type
    ////////////////////////////////////////////////////////////
    // Type definitions
    ////////////////////////////////////////////////////////////

    TPCANTPHandle = Word;         // Represents a PCANTP hardware channel (based upon a TPCANHandle
    TPCANTPStatus = LongWord;     // Represents a PCANTP status/error code
    TPCANTPBaudrate = Word;       // Represents the baudrate register for the PCANTP channel
    TPCANTPBitrateFD = PAnsiChar; // Represents a PCAN-FD bit rate string
    TPCANTPHWType = Byte;         // Represents the type of PCAN hardware to be initialized
    TPCANTPMessageType = Byte;    // Represents the type of a PCANTP message
    TPCANTPIdType = Byte;         // Represents the type of CAN ID
    TPCANTPFormatType = Byte;     // Represents the type of format of a PCANTP message
    TPCANTPAddressingType = Byte; // Represents a PCANTP addressing type
    TPCANTPConfirmation = Byte;	  // Represents the network status of a communicated message
    TPCANTPParameter = Byte;      // Represents a PCANTP parameter to be read or set

    ////////////////////////////////////////////////////////////
    // Message definition
    ////////////////////////////////////////////////////////////

    TPCANTPMsg = record
        SA: Byte;                        // Source Address
        TA: Byte;                        // Target Address
        TA_TYPE: TPCANTPAddressingType;  // Target Address Type (see PCANTP_ADDRESSING_xxx)
        RA: Byte;                        // Remote address

        IDTYPE: TPCANTPIdType;           // CAN ID configuration (see PCANTP_ID_CAN_xxx)
        MSGTYPE: TPCANTPMessageType;     // Type of the message (see PCANTP_MESSAGE_xxx)
        FORMAT: TPCANTPFormatType;       // Addressing Format (see PCANTP_FORMAT_xxx)


        DATA: array[0..4094] of Byte;    // Raw data of the message
        LEN: Word;                       // Data Length Code of the message

        RESULT: TPCANTPConfirmation;     // Result status (see PCANTP_N_xxx)
    end;
	
    // Represents a timestamp of a received PCANTP message.
    // Total Microseconds = micros + 1000 * millis + 0x100000000 * 1000 * millis_overflow
    //
    TPCANTPTimestamp = record
        millis: Longword;          // Base-value: milliseconds: 0.. 2^32-1
        millis_overflow: Word;     // Roll-arounds of millis
        micros: Word;              // Microseconds: 0..999
    end;
    PTPCANTPTimestamp = ^TPCANTPTimestamp;

////////////////////////////////////////////////////////////
// PCAN-Basic API function CANTP_declarations
////////////////////////////////////////////////////////////

/// <summary>
/// Initializes a PCANTP-Client based on a CANTP Channel
/// </summary>
/// <remarks>Only one PCANTP-Client can be initialized per CAN-Channel</remarks>
/// <param name="CanChannel">A PCANTP Channel Handle representing a PCANTP-Client</param>
/// <param name="Baudrate">The CAN Hardware speed</param>
/// <param name="HwType">NON PLUG&PLAY: The type of hardware and operation mode</param>
/// <param name="IOPort">NON PLUG&PLAY: The I/O address for the parallel port</param>
/// <param name="Interrupt">NON PLUG&PLAY: Interrupt number of the parallel port</param>
/// <returns>A TPCANTPStatus code. PCANTP_ERROR_OK is returned on success</returns>
function CANTP_Initialize(
    CanChannel: TPCANTPHandle;
    Baudrate: TPCANTPBaudrate;
    HwType: TPCANTPHWType;
    IOPort: LongWord;
    Interrupt: Word
    ): TPCANTPStatus; stdcall;

/// <summary>
/// Initializes a PCANTP-Client based on a CANTP Channel (including CAN-FD support)
/// </summary>
/// <param name="Channel">"The handle of a FD capable PCAN Channel"</param>
/// <param name="BitrateFD">"The speed for the communication (FD bit rate string)"</param>
/// <remarks>Only one PCANTP-Client can be initialized per CAN-Channel.
/// See PCAN_BR_* values
/// * Parameter and values must be separated by '='
/// * Couples of Parameter/value must be separated by ','
/// * Following Parameter must be filled out: f_clock, data_brp, data_sjw, data_tseg1, data_tseg2,
///   nom_brp, nom_sjw, nom_tseg1, nom_tseg2.
/// * Following Parameters are optional (not used yet): data_ssp_offset, nom_samp
///</remarks>
/// <example>f_clock_mhz=80,nom_brp=0,nom_tseg1=13,nom_tseg2=0,nom_sjw=0,data_brp=0,
/// data_tseg1=13,data_tseg2=0,data_sjw=0</example>
/// <returns>"A TPCANStatus error code"</returns>
function CANTP_InitializeFD(
    Channel: TPCANTPHandle;
    BitrateFD: TPCANTPBitrateFD
    ): TPCANTPStatus; stdcall;

/// <summary>
/// Uninitializes a PCANTP-Client initialized before
/// </summary>
/// <param name="CanChannel">A PCANTP Channel Handle representing a PCANTP-Client</param>
/// <returns>A TPCANTPStatus code. PCANTP_ERROR_OK is returned on success</returns>
function CANTP_Uninitialize(
    CanChannel: TPCANTPHandle
    ): TPCANTPStatus; stdcall;


/// <summary>
/// Resets the receive and transmit queues of a PCANTP-Client 
/// </summary>
/// <param name="CanChannel">A PCANTP Channel Handle representing a PCANTP-Client</param>
/// <returns>A TPCANTPStatus code. PCANTP_ERROR_OK is returned on success</returns>
function CANTP_Reset(
    CanChannel: TPCANTPHandle
    ): TPCANTPStatus; stdcall;

/// <summary>
/// Gets information about the internal BUS status of a PCANTP-Channel.
/// </summary>
/// <param name="CanChannel">A PCANTP Channel Handle representing a PCANTP-Client</param>
/// <returns>A TPCANTPStatus code. PCANTP_ERROR_OK is returned on success</returns>
function CANTP_GetStatus(
    CanChannel: TPCANTPHandle
    ): TPCANTPStatus; stdcall;

/// <summary>
/// Reads a PCANTP message from the receive queue of a PCANTP-Client
/// </summary>
/// <param name="CanChannel">A PCANTP Channel Handle representing a PCANTP-Client</param>
/// <param name="MessageBuffer">A TPCANTPMsg structure buffer to store the PUDS message</param>
/// <returns>A TPCANTPStatus code. PCANTP_ERROR_OK is returned on success</returns>
function CANTP_Read(
    CanChannel: TPCANTPHandle;
    var MessageBuffer: TPCANTPMsg;
	  TimestampBuffer: PTPCANTPTimestamp = nil
    ): TPCANTPStatus; stdcall;

/// <summary>
/// Transmits a PCANTP message
/// </summary>
/// <param name="CanChannel">A PCANTP Channel Handle representing a PCANTP-Client</param>
/// <param name="MessageBuffer">A TPCANTPMsg buffer with the message to be sent</param>
/// <returns>A TPCANTPStatus code. PCANTP_ERROR_OK is returned on success</returns>
function CANTP_Write(
    CanChannel: TPCANTPHandle;
    var MessageBuffer: TPCANTPMsg
    ): TPCANTPStatus; stdcall;

/// <summary>
/// Retrieves a PCANTP-Client value
/// </summary>
/// <param name="CanChannel">A PCANTP Channel Handle representing a PCANTP-Client</param>
/// <param name="Parameter">The TPCANTPParameter parameter to get</param>
/// <param name="StringBuffer">Buffer for the parameter value</param>
/// <param name="BufferLength">Size in bytes of the buffer</param>
/// <returns>A TPCANTPStatus code. PCANTP_ERROR_OK is returned on success</returns>
function CANTP_GetValue(
    CanChannel: TPCANTPHandle;
    Parameter: TPCANTPParameter;
    Buffer: Pointer;
    BufferLength: LongWord
    ): TPCANTPStatus; stdcall;

/// <summary>
/// Configures or sets a PCANTP-Client value
/// </summary>
/// <param name="CanChannel">A PCANTP Channel Handle representing a PCANTP-Client</param>
/// <param name="Parameter">The TPCANTPParameter parameter to set</param>
/// <param name="NumericBuffer">Buffer with the value to be set</param>
/// <param name="BufferLength">Size in bytes of the buffer</param>
/// <returns>A TPCANTPStatus code. PCANTP_ERROR_OK is returned on success</returns>
function CANTP_SetValue(
    CanChannel: TPCANTPHandle;
    Parameter: TPCANTPParameter;
    Buffer: Pointer;
    BufferLength: LongWord
    ): TPCANTPStatus; stdcall;

/// <summary>
/// Adds a user-defined PCAN-TP mapping between CAN ID and Network Address Information
/// </summary>
/// <remark>
/// Defining a mapping enables ISO-TP communication with 11BITS CAN ID or 
/// with opened Addressing Formats (like PCANTP_FORMAT_NORMAL or PCANTP_FORMAT_EXTENDED).
/// </remark>
/// <param name="CanChannel">A PCANTP Channel Handle representing a PCANTP-Client</param>
/// <param name="canID">The CAN ID to map</param>
/// <param name="canIDResponse">The CAN ID mapped response</param>
/// <param name="canIdType">CAN ID Type (11 or 29 bits, see PCANTP_ID_CAN_XXX)</param>
/// <param name="formatType">Addressing format (see PCANTP_FORMAT_XXX)</param>
/// <param name="msgType">Message type (remote or diagnostic, see PCANTP_MESSAGE_XXX)</param>
/// <param name="sourceAddr">Source Address</param>
/// <param name="targetAddr">Target Address</param>
/// <param name="targetType">Target Addressing Type (physical or functional, see PCANTP_ADDRESSING_XXX)</param>
/// <param name="remoteAddr">Address extension or Remote address</param>
/// <returns>A TPCANTPStatus code : PCANTP_ERROR_OK is returned on success, 
/// PCANTP_ERROR_WRONG_PARAM states invalid Network Address Information parameters.</returns>
function CANTP_AddMapping(
    CanChannel: TPCANTPHandle;
    canID: LongWord;
    canIDResponse: LongWord;
    canIdType: TPCANTPIdType;
    formatType: TPCANTPFormatType;
    msgType: TPCANTPMessageType ;
    sourceAddr: Byte;
    targetAddr: Byte;
    targetType: TPCANTPAddressingType;
    remoteAddr: Byte
    ): TPCANTPStatus; stdcall;

/// <summary>
/// Removes a user-defined PCAN-TP mapping between CAN ID and Network Address Information
/// </summary>
/// <param name="CanChannel">A PCANTP Channel Handle representing a PCANTP-Client</param>
/// <param name="canID">The mapped CAN ID to remove</param>
/// <returns>A TPCANTPStatus code. PCANTP_ERROR_OK is returned on success</returns>
function CANTP_RemoveMapping(
    CanChannel: TPCANTPHandle;
    canID: LongWord
    ): TPCANTPStatus; stdcall;
	
/// <summary>
/// Returns a descriptive text of a given TPCANTPStatus error
/// code, in any desired language
/// </summary>
/// <remarks>The current languages available for translation are:
/// Neutral (0x00), German (0x07), English (0x09), Spanish (0x0A),
/// Italian (0x10) and French (0x0C)</remarks>
/// <param name="Error">A TPCANTPStatus error code</param>
/// <param name="Language">Indicates a 'Primary language ID'</param>
/// <param name="StringBuffer">Buffer for the text (must be at least 256 in length)</param>
/// <returns>A TPCANTPStatus error code</returns>
function CANTP_GetErrorText(
    Error: TPCANTPStatus;
    Language: Word; 
    StringBuffer: PAnsiChar
    ): TPCANTPStatus; stdcall;

// Get the 29bits CAN ID type with a specific J1939 priority
function PCANTP_ID_CAN_GET_29B(j1939_priority: Byte): TPCANTPIdType;
// Retrieves the priority field from a CAN ID type
function PCANTP_ID_CAN_GET_PRIORIY(id_type: Byte): Byte;
// States if the CAN ID TYpe is 29bits
function PCANTP_ID_CAN_IS_EXTENDED(id_type: Byte): Boolean;
// States if the id_type contains a J1939 priority field
function PCANTP_ID_CAN_HAS_PRIORITY(id_type: Byte): Boolean;

implementation
uses SysUtils;
const DLL_Name = 'PCAN-ISO-TP.DLL';

function CANTP_Initialize(CanChannel: TPCANTPHandle; Baudrate: TPCANTPBaudrate; HwType: TPCANTPHWType; IOPort: LongWord; Interrupt: Word): TPCANTPStatus; stdcall;
external DLL_Name;
function CANTP_InitializeFD(Channel: TPCANTPHandle; BitrateFD: TPCANTPBitrateFD): TPCANTPStatus; stdcall;
external DLL_Name;
function CANTP_Uninitialize(CanChannel: TPCANTPHandle): TPCANTPStatus; stdcall;
external DLL_Name;
function CANTP_Reset(CanChannel: TPCANTPHandle): TPCANTPStatus; stdcall;
external DLL_Name;
function CANTP_GetStatus(CanChannel: TPCANTPHandle): TPCANTPStatus; stdcall;
external DLL_Name;
function CANTP_Read(CanChannel: TPCANTPHandle; var MessageBuffer: TPCANTPMsg; TimestampBuffer: PTPCANTPTimestamp = nil):TPCANTPStatus; stdcall;
external DLL_Name;
function CANTP_Write(CanChannel: TPCANTPHandle; var MessageBuffer: TPCANTPMsg): TPCANTPStatus; stdcall;
external DLL_Name;
function CANTP_GetValue(CanChannel: TPCANTPHandle; Parameter: TPCANTPParameter; Buffer: Pointer; BufferLength: LongWord): TPCANTPStatus; stdcall;
external DLL_Name;
function CANTP_SetValue(CanChannel: TPCANTPHandle; Parameter: TPCANTPParameter; Buffer: Pointer; BufferLength: LongWord): TPCANTPStatus; stdcall;
external DLL_Name;
function CANTP_AddMapping(CanChannel: TPCANTPHandle; canID: LongWord; canIDResponse: LongWord; canIdType: TPCANTPIdType; formatType: TPCANTPFormatType; msgType: TPCANTPMessageType ; sourceAddr: Byte; targetAddr: Byte; targetType: TPCANTPAddressingType; remoteAddr: Byte): TPCANTPStatus; stdcall;
external DLL_Name;
function CANTP_RemoveMapping(CanChannel: TPCANTPHandle; canID: LongWord): TPCANTPStatus; stdcall;
external DLL_Name;
function CANTP_GetErrorText(Error: TPCANTPStatus; Language: Word; StringBuffer: PAnsiChar): TPCANTPStatus; stdcall;
external DLL_Name;
    
function PCANTP_ID_CAN_GET_29B(j1939_priority: Byte): Byte;
begin
  Result := Byte((j1939_priority shl 5) or PCANTP_ID_CAN_IS_PRIORITY_MASK or (PCANTP_ID_CAN_29BIT and PCANTP_ID_CAN_MASK));
end;

function PCANTP_ID_CAN_GET_PRIORIY(id_type: Byte): Byte;
begin
  Result :=	Byte((id_type and PCANTP_ID_CAN_PRIORITY_MASK) shr 5);
end;

function PCANTP_ID_CAN_IS_EXTENDED(id_type: Byte): Boolean;
begin
  Result :=	((id_type and PCANTP_ID_CAN_MASK) = PCANTP_ID_CAN_29BIT);
end;

function PCANTP_ID_CAN_HAS_PRIORITY(id_type: Byte): Boolean;
begin
  Result :=	(PCANTP_ID_CAN_IS_EXTENDED(id_type) and ((id_type and PCANTP_ID_CAN_IS_PRIORITY_MASK) = PCANTP_ID_CAN_IS_PRIORITY_MASK));
end;

end.
