diff --git a/Host/Source/MicroBoot/interfaces/can/kvaser/XcpTransport.pas b/Host/Source/MicroBoot/interfaces/can/kvaser/XcpTransport.pas index ada57c16..ecfb479d 100644 --- a/Host/Source/MicroBoot/interfaces/can/kvaser/XcpTransport.pas +++ b/Host/Source/MicroBoot/interfaces/can/kvaser/XcpTransport.pas @@ -36,7 +36,7 @@ interface // Includes //*************************************************************************************** uses - Windows, Messages, SysUtils, Classes, Forms, IniFiles; + Windows, Messages, SysUtils, Classes, Forms, IniFiles, canlib; //*************************************************************************************** @@ -57,8 +57,9 @@ type packetTxId : LongWord; packetRxId : LongWord; extendedId : Boolean; + kvaserHandle : canHandle; canHardware : TKvaserHardware; { KVASER_xxx } - canChannel : Word; { currently supported is 1..8 } + canChannel : Word; { currently supported is 1..1 } canBaudrate : LongWord; { in bits/sec } connected : Boolean; public @@ -91,15 +92,16 @@ begin // reset the packet ids packetTxId := 0; packetRxId := 0; - // use standard id's by default extendedId := false; - // reset packet length packetLen := 0; - // disconnected by default connected := false; + // invalidate the handle + kvaserHandle := canINVALID_HANDLE; + // initialize the library + canInitializeLibrary; end; //*** end of Create *** @@ -112,6 +114,8 @@ end; //*** end of Create *** //*************************************************************************************** destructor TXcpTransport.Destroy; begin + // unload the library + canUnloadLibrary; // call inherited destructor inherited; end; //*** end of Destroy *** @@ -175,6 +179,9 @@ end; //*** end of Configure *** // //*************************************************************************************** function TXcpTransport.Connect: Boolean; +var + openFlags: Integer; + frequency: Integer; begin // init result value result := false; @@ -183,8 +190,52 @@ begin if connected then Disconnect; - //##Vg TODO connect to the CAN hardware interface and update the connected flag - connected := false; + // the current version only supports the leaf light v2 + if canHardware = KVASER_LEAFLIGHT_V2 then + begin + // open the CAN channel if valid + if canChannel > 0 then + begin + // set the open flags + openFlags := canOPEN_REQUIRE_INIT_ACCESS; + if extendedId then + begin + openFlags := openFlags or canOPEN_REQUIRE_EXTENDED; + end; + kvaserHandle := canOpenChannel(canChannel - 1, openFlags); + // only continue if the channel was opened and the handle is not valid + if kvaserHandle >= 0 then + begin + case canBaudrate of + 1000000: frequency := canBITRATE_1M; + 500000: frequency := canBITRATE_500K; + 250000: frequency := canBITRATE_250K; + 125000: frequency := canBITRATE_125K; + 100000: frequency := canBITRATE_100K; + 83333: frequency := canBITRATE_83K; + 50000: frequency := canBITRATE_50K; + 10000: frequency := canBITRATE_10K; + else + frequency := canBITRATE_500K; + end; + // configure the baudrate + if canSetBusParams(kvaserHandle, frequency, 0, 0, 0, 0, 0) = canOK then + begin + // configure output control to the default normal mode + if canSetBusOutputControl(kvaserHandle, canDRIVER_NORMAL) = canOK then + begin + // go on the bus + if canBusOn(kvaserHandle) = canOK then + begin + // connection was established + connected := true; + result := true; + end; + end; + end; + end; + end; + end; end; //*** end of Connect *** @@ -196,14 +247,34 @@ end; //*** end of Connect *** // //*************************************************************************************** function TXcpTransport.IsComError: Boolean; +var + statusFlags: Cardinal; begin // init result to no error. result := false; - // check for bus off error if connected + // do not check if the handle is invalid + if kvaserHandle <= canINVALID_HANDLE then + begin + Exit; + end; + + // check for bus off error or error passive if connected if connected then begin - //##Vg TODO check for bus off and possible bus heavy if available + if canReadStatus(kvaserHandle, statusFlags) = canOK then + begin + // check for bus off or error passive bits + if (statusFlags and (canSTAT_BUS_OFF or canSTAT_ERROR_PASSIVE)) > 0 then + begin + result := true; + end; + end + else + begin + // could not read the status which is also an indicator that something is wrong + result := true + end; end; end; //*** end of IsComError *** @@ -220,6 +291,17 @@ function TXcpTransport.SendPacket(timeOutms: LongWord): Boolean; var responseReceived: Boolean; timeoutTime: DWORD; + txId: LongInt; + txData: array[0..kMaxPacketSize-1] of Byte; + txFlags: Cardinal; + rxId: LongInt; + rxData: array[0..kMaxPacketSize-1] of Byte; + rxFlags: Cardinal; + rxLen: Cardinal; + rxTime: Cardinal; + byteIdx: Byte; + status: canStatus; + idTypeOk: Boolean; begin // initialize the result value result := false; @@ -231,9 +313,28 @@ begin Exit; end; - //##Vg TODO prepare the packet for transmission in a CAN message + // do not send if the handle is invalid + if kvaserHandle <= canINVALID_HANDLE then + begin + Exit; + end; - //##Vg transmit the packet via CAN and Exit if not possible + // prepare the packet for transmission in a CAN message + txId := packetTxId; + for byteIdx := 0 to (packetLen - 1) do + begin + txData[byteIdx] := packetData[byteIdx]; + end; + if extendedId then + txFlags := canMSG_EXT + else + txFlags := canMSG_STD; + + // submit the packet for transmission via the CAN bus + if canWrite(kvaserHandle, txId, @txData[0], packetLen, txFlags) <> canOK then + begin + Exit; + end; // reset flag and set the reception timeout time responseReceived := false; @@ -241,10 +342,38 @@ begin // attempt to receive the packet response within the timeout time repeat - //##Vg attempt to read a message from the reception buffer, break loop on error - //##Vg check if it has the correct identifier (packetRxId) and set the - // responseReceived flag if so - + // prepare message reception + rxId := packetRxId; + // attempt to read the packet response from the reception queue + status := canReadSpecificSkip(kvaserHandle, rxId, @rxData[0], rxLen, rxFlags, rxTime); + // check if an error was detected + if (status <> canOK) and (status <> canERR_NOMSG) then + begin + // error detected. stop loop. + Break; + end; + // no error, now check if a message was actually received + if status = canOK then + begin + // a message with the identifier of the response packet was received. now check + // that the identifier type also matches + idTypeOk := false; + if extendedId then + begin + if (rxFlags and canMSG_EXT) > 0 then + idTypeOk := true; + end + else + begin + if (rxFlags and canMSG_STD) > 0 then + idTypeOk := true; + end; + if idTypeOk then + begin + // response received. set flag + responseReceived := true; + end; + end; // give the application a chance to use the processor Application.ProcessMessages; until (GetTickCount > timeoutTime) or (responseReceived); @@ -252,7 +381,12 @@ begin // check if the response was correctly received if responseReceived then begin - //##Vg copy the response for futher processing (packetLen and packetData) + // copy the received response packet + packetLen := rxLen; + for byteIdx := 0 to (packetLen - 1) do + begin + packetData[byteIdx] := rxData[byteIdx]; + end; // success result := true; end; @@ -271,8 +405,16 @@ begin // disconnect CAN interface if connected if connected then begin - //##Vg TODO disconnect from the CAN hardware interface + // only disconnect if the handle is valid + if kvaserHandle > canINVALID_HANDLE then + begin + // take the channel from the bus + canBusOff(kvaserHandle); + // close the channel + canClose(kvaserHandle); + end; end; + kvaserHandle := canINVALID_HANDLE; connected := false; end; //*** end of Disconnect *** diff --git a/Host/Source/MicroBoot/interfaces/can/kvaser/canlib.pas b/Host/Source/MicroBoot/interfaces/can/kvaser/canlib.pas new file mode 100644 index 00000000..bdfbab99 --- /dev/null +++ b/Host/Source/MicroBoot/interfaces/can/kvaser/canlib.pas @@ -0,0 +1,943 @@ +unit CANLIB; +(* +** Copyright 1995-2013 by KVASER AB +** WWW: http://www.kvaser.com +** +** This software is furnished under a license and may be used and copied +** only in accordance with the terms of such license. +** +*) +(* +** This unit defines an interface for Delphi to CANLIB32.DLL. +** It has been tested with Delphi 2007. +*) + +interface + +uses + Messages, Windows; + +const + + canINVALID_HANDLE = -1; + + canOK = 0; + canERR_PARAM = -1; {// Error in parameter} + canERR_NOMSG = -2; {// No messages available} + canERR_NOTFOUND = -3; {// Specified hw not found} + canERR_NOMEM = -4; {// Out of memory} + canERR_NOCHANNELS = -5; {// No channels avaliable} + canERR_RESERVED_3 = -6; + canERR_TIMEOUT = -7; {// Timeout occurred} + canERR_NOTINITIALIZED = -8; {// Lib not initialized} + canERR_NOHANDLES = -9; {// Can't get handle} + canERR_INVHANDLE = -10; {// Handle is invalid} + canERR_INIFILE = -11; {// Error in the ini-file (16-bit only)} + canERR_DRIVER = -12; {// CAN driver type not supported} + canERR_TXBUFOFL = -13; {// Transmit buffer overflow} + canERR_RESERVED_1 = -14; + canERR_HARDWARE = -15; {// Some hardware error has occurred} + canERR_DYNALOAD = -16; {// Can't find requested DLL} + canERR_DYNALIB = -17; {// DLL seems to be wrong version} + canERR_DYNAINIT = -18; {// Error when initializing DLL} + canERR_NOT_SUPPORTED = -19; + canERR_RESERVED_5 = -20; + canERR_RESERVED_6 = -21; + canERR_RESERVED_2 = -22; + canERR_DRIVERLOAD = -23; {// Can't find/load driver} + canERR_DRIVERFAILED = -24; {// DeviceIOControl failed; use Win32 GetLastError()} + canERR_NOCONFIGMGR = -25; {// Can't find req'd config s/w (e.g. CS/SS)} + canERR_NOCARD = -26; {// The card was removed or not inserted} + canERR_RESERVED_7 = -27; + canERR_REGISTRY = -28; // Error in the Registry + canERR_LICENSE = -29; // The license is not valid. + canERR_INTERNAL = -30; // Internal error in the driver. + canERR_NO_ACCESS = -31; // Access denied + canERR_NOT_IMPLEMENTED = -32; // Requested function is not implemented + canERR_DEVICE_FILE = -33; + canERR_HOST_FILE = -34; + canERR_DISK = -35; + canERR_CRC = -36; + canERR_CONFIG = -37; + canERR_MEMO_FAIL = -38; + canERR_SCRIPT_FAIL = -39; + canERR_SCRIPT_WRONG_VERSION = -40; + canERR__RESERVED = -41; // RESERVED + + + + WM__CANLIB = (WM_USER + 16354); {Windows message from Can unit.} + + canEVENT_RX = 32000; {Receive event} + canEVENT_TX = 32001; {Transmit event} + canEVENT_ERROR = 32002; {Error event} + canEVENT_STATUS = 32003; {Change-of-status event} + canEVENT_ENVVAR = 32004; {An envvar changed} + canEVENT_BUSONOFF = 32005; {Bus on/off status changed} + canEVENT_REMOVED = 32006; {Device removed} + + {Used in canSetNotify} + canNOTIFY_RX = $0001; { Notify on receive } + canNOTIFY_TX = $0002; { Notify on transmit } + canNOTIFY_ERROR = $0004; { Notify on error } + canNOTIFY_STATUS = $0008; { Notify on (some) status change events } + canNOTIFY_ENVVAR = $0010; { An environment variable was changed by a script } + canNOTIFY_BUSONOFF = $0020; { Notify on bus on/off status changed } + canNOTIFY_REMOVED = $0040; { Notify on device removed } + + +{Circuit status flags} + canSTAT_ERROR_PASSIVE = $00000001; {The circuit is error passive} + canSTAT_BUS_OFF = $00000002; {The circuit is Off Bus} + canSTAT_ERROR_WARNING = $00000004; {At least one error counter > 96} + canSTAT_ERROR_ACTIVE = $00000008; {The circuit is error active.} + canSTAT_TX_PENDING = $00000010; {There are messages pending transmission} + canSTAT_RX_PENDING = $00000020; {There are messages in the receive buffer} + canSTAT_RESERVED_1 = $00000040; + canSTAT_TXERR = $00000080; {There has been at least one TX error} + canSTAT_RXERR = $00000100; {There has been at least one RX error of some sort} + canSTAT_HW_OVERRUN = $00000200; {The has been at least one HW buffer overflow} + canSTAT_SW_OVERRUN = $00000400; {The has been at least one SW buffer overflow} + + + {Message information flags} + canMSG_MASK = $00FF; { Used to mask the non-info bits } + canMSG_RTR = $0001; { Message is a remote request } + canMSG_STD = $0002; { Message has a standard ID } + canMSG_EXT = $0004; { Message has an extended id } + canMSG_WAKEUP = $0008; { Message is a SWC wakeup frame} + canMSG_STATUS = $0008; { Obsolete - retained for compatibility } + canMSG_NERR = $0010; { Message sent/received with TJA1054 (etc.) NERR active } + canMSG_ERROR_FRAME = $0020; { Message is an error frame } + canMSG_TXACK = $0040; { Message is a TX ACK (msg is really sent) } + canMSG_TXRQ = $0080; { Message is a TX REQUEST (msg is transfered to the chip)} + canMSG_DELAY_MSG = $0100; { Message is NOT sent on the bus. The transmission of messages are delayed. + The dlc specifies the delay in milliseconds } + + {Message error flags, >= $0100} + canFDMSG_MASK = $ff0000; { Used to mask the non-info bits } + canFDMSG_EDL = $010000; { Obsolete, use canFDMSG_FDF instead} + canFDMSG_FDF = $010000; { Indicate if message is an FD message } + canFDMSG_BRS = $020000; { Indicate if message should be sent with bit rate switch } + canFDMSG_ESI = $040000; { Indicate if the sender of this message is in error passive mode } + + // single shot flags: + canMSG_SINGLE_SHOT = $1000000; // Message is Single Shot, try to send once, no retransmission (only tx) + canMSG_TXNACK = $2000000; // Message is a failed Single Shot, message was not sent (only rx) + canMSG_ABL = $4000000; // Only together with canMSG_TXNACK, Single shot message was not sent because arbitration was lost (only rx) + + {Message error flags, >= $0100} + canMSGERR_MASK = $FF00; { Used to mask the non-error bits } + { $0100 reserved } + canMSGERR_HW_OVERRUN = $0200; { HW buffer overrun } + canMSGERR_SW_OVERRUN = $0400; { SW buffer overrun } + canMSGERR_STUFF = $0800; { Stuff error } + canMSGERR_FORM = $1000; { Form error } + canMSGERR_CRC = $2000; { CRC error } + canMSGERR_BIT0 = $4000; { Sent dom, read rec} + canMSGERR_BIT1 = $8000; { Sent rec, read dom} + + {Convenience values} + canMSGERR_OVERRUN = $0600; { Any overrun condition.} + canMSGERR_BIT = $C000; { Any bit error (note: TWO bits)} + canMSGERR_BUSERR = $F800; { Any RX error} + + canCIRCUIT_ANY = -1; { Any circuit will do } + canCARD_ANY = -1; { Any card will do} + canCHANNEL_ANY = -1; { Any channel will do} + + + + {Flags for canAccept} + canFILTER_ACCEPT = 1; + canFILTER_REJECT = 2; + canFILTER_SET_CODE_STD = 3; + canFILTER_SET_MASK_STD = 4; + canFILTER_SET_CODE_EXT = 5; + canFILTER_SET_MASK_EXT = 6; + + canFILTER_NULL_MASK = 0; + + canDRIVER_NORMAL = 4; + canDRIVER_SILENT = 1; + canDRIVER_SELFRECEPTION = 8; + canDRIVER_OFF = 0; + + + { "shortcut" baud rates; use with canBusParams or canTranslateBaud } + { canBAUD_xxx is obsolete; use canBITRATE_xxx instead } + canBAUD_1M = -1; + canBAUD_500K = -2; + canBAUD_250K = -3; + canBAUD_125K = -4; + canBAUD_100K = -5; + canBAUD_62K = -6; + canBAUD_50K = -7; + canBAUD_83K = -8; + + canBITRATE_1M = -1; + canBITRATE_500K = -2; + canBITRATE_250K = -3; + canBITRATE_125K = -4; + canBITRATE_100K = -5; + canBITRATE_62K = -6; + canBITRATE_50K = -7; + canBITRATE_83K = -8; + canBITRATE_10K = -9; + + canFD_BITRATE_500K_80P = -1000; + canFD_BITRATE_1M_80P = -1001; + canFD_BITRATE_2M_80P = -1002; + canFD_BITRATE_4M_80P = -1003; + canFD_BITRATE_8M_60P = -1004; + + canIOCTL_PREFER_EXT = 1; + canIOCTL_PREFER_STD = 2; + { 3,4 reserved } + canIOCTL_CLEAR_ERROR_COUNTERS = 5; + canIOCTL_SET_TIMER_SCALE = 6; + canIOCTL_SET_TXACK = 7; + + canIOCTL_GET_RX_BUFFER_LEVEL = 8; + canIOCTL_GET_TX_BUFFER_LEVEL = 9; + canIOCTL_FLUSH_RX_BUFFER = 10; + canIOCTL_FLUSH_TX_BUFFER = 11; + + canIOCTL_GET_TIMER_SCALE = 12; + canIOCTL_SET_TX_REQUESTS = 13; + + canIOCTL_GET_EVENTHANDLE = 14; + canIOCTL_SET_BYPASS_MODE = 15; + canIOCTL_SET_WAKEUP = 16; + + canIOCTL_GET_DRIVERHANDLE = 17; + canIOCTL_MAP_RXQUEUE = 18; + canIOCTL_GET_WAKEUP = 19; + canIOCTL_SET_REPORT_ACCESS_ERRORS = 20; + canIOCTL_GET_REPORT_ACCESS_ERRORS = 21; + canIOCTL_CONNECT_TO_VIRTUAL_BUS = 22; + canIOCTL_DISCONNECT_FROM_VIRTUAL_BUS = 23; + canIOCTL_SET_USER_IOPORT = 24; + canIOCTL_GET_USER_IOPORT = 25; + canIOCTL_SET_BUFFER_WRAPAROUND_MODE = 26; + canIOCTL_SET_RX_QUEUE_SIZE = 27; + canIOCTL_SET_USB_THROTTLE = 28; + canIOCTL_GET_USB_THROTTLE = 29; + canIOCTL_SET_BUSON_TIME_AUTO_RESET = 30; + canIOCTL_GET_TXACK = 31; + canIOCTL_SET_LOCAL_TXECHO = 32; + canIOCTL_SET_ERROR_FRAMES_REPORTING = 33; + canIOCTL_GET_CHANNEL_QUALITY = 34; + canIOCTL_GET_ROUNDTRIP_TIME = 35; + canIOCTL_GET_BUS_TYPE = 36; + canIOCTL_GET_DEVNAME_ASCII = 37; + canIOCTL_GET_TIME_SINCE_LAST_SEEN = 38; + canIOCTL_GET_TREF_LIST = 39; + canIOCTL_TX_INTERVAL = 40; + canIOCTL_SET_THROTTLE_SCALED = 41; + canIOCTL_GET_THROTTLE_SCALED = 42; + canIOCTL_SET_BRLIMIT = 43; + canIOCTL_RESET_OVERRUN_COUNT = 44; + + //Type of buffer + canOBJBUF_TYPE_AUTO_RESPONSE = $01; + canOBJBUF_TYPE_PERIODIC_TX = $02; + + // The buffer responds to RTRs only, not regular messages. + canOBJBUF_AUTO_RESPONSE_RTR_ONLY = $01; + + // Check for specific version(s) of CANLIB. + canVERSION_DONT_ACCEPT_LATER = $01; + canVERSION_DONT_ACCEPT_BETAS = $02; + + CANID_METAMSG = (-1); + CANID_WILDCARD = (-2); + + kvENVVAR_TYPE_INT = 1; + kvENVVAR_TYPE_FLOAT = 2; + kvENVVAR_TYPE_STRING = 3; + + kvEVENT_TYPE_KEY = 1; + + kvSCRIPT_STOP_NORMAL = 0; + kvSCRIPT_STOP_FORCED = -9; + + kvDEVICE_MODE_INTERFACE = $00; + kvDEVICE_MODE_LOGGER = $01; + + canVERSION_CANLIB32_VERSION = 0; + canVERSION_CANLIB32_PRODVER = 1; + canVERSION_CANLIB32_PRODVER32 = 2; + canVERSION_CANLIB32_BETA = 3; + + kvBUSTYPE_NONE = 0; + kvBUSTYPE_PCI = 1; + kvBUSTYPE_PCMCIA = 2; + kvBUSTYPE_USB = 3; + kvBUSTYPE_WLAN = 4; + kvBUSTYPE_PCI_EXPRESS = 5; + kvBUSTYPE_ISA = 6; + kvBUSTYPE_VIRTUAL = 7; + kvBUSTYPE_PC104_PLUS = 8; + kvBUSTYPE_LAN = 9; + + kvBUSTYPE_GROUP_VIRTUAL = 1; ///< ::kvBUSTYPE_VIRTUAL + kvBUSTYPE_GROUP_LOCAL = 2; ///< ::kvBUSTYPE_USB + kvBUSTYPE_GROUP_REMOTE = 3; ///< ::kvBUSTYPE_WLAN + kvBUSTYPE_GROUP_INTERNAL = 4; ///< ::kvBUSTYPE_PCI, ::kvBUSTYPE_PCMCIA, ... + /// + /// + kvSCRIPT_REQUEST_TEXT_UNSUBSCRIBE = 1; + kvSCRIPT_REQUEST_TEXT_SUBSCRIBE = 2; + kvSCRIPT_REQUEST_TEXT_ALL_SLOTS = 255; + +type + + + { This one is primarily used by WCANKING } + TMsgRec = record + {This record holds information about a CAN message.} + envelope: Longint; {The CAN envelope.} + dlc: Integer; {The data length code.} + flag: Integer; {The flag have information about remote request and + #X Return flags} + case indexType: Integer of + 0: (data: array[0..7] of AnsiChar); {CAN data as char.} + 1: (shData: array[0..7] of ShortInt); {CAN data as shortint.} + 2: (bData: array[0..7] of Byte); {CAN data as byte.} + 3: (iData: array[0..3] of SmallInt); {CAN data as smallint.} + 4: (lData: array[0..1] of LongInt); {CAN data as Longint.} + 6: (wData: array[0..3] of Word); {CAN data as word.} + 7: (tData: string[7]); {CAN data as string[7].} + 8: (fData: array[0..1] of Single); {CAN data as float.} + 9: (rData: Real); {CAN data as real.} + 10: (dData: Double); {CAN data as double.} + 11: (cData: Comp); {CAN data as comp.} + end; + + + { This one is primarily used by WCANKING } + TMsgObj = class(TObject) + { A TMsgObj holds a TMsgRec, so it can be used as an object in TStringList.} + public + {Public declarations} + txm: Boolean; {True if CAN message sent, false if received.} + time: LongInt; {Receive time in milliseconds.} + count: Integer; {Message number.} + MsgRec: TMsgRec; {The CAN message.} + end; + + + canMemoryAllocator = TFarProc; {Memory allocator, if nil malloc is used.} + canMemoryDeallocator = TFarProc; {Memory deallocator, if nil free is used.} + canAction = TFarProc; {Currently unsupported.} + BYTEPTR = PAnsiChar; {Byte pointer.} + + {Can hardware descriptor, holds information about CAN card + and CAN circuit used.} + canHWDescr = record + circuitType: integer; { The CAN circuit.} + cardType: integer; + channel: integer; + end; + + { Used in canOpen. Obsolete. } + canSWDescr = record + rxBufSize: integer; {Requested receive buffer size [1, 32767].} + txBufSize: integer; {Requested transmit buffer size [0, 32767].} + alloc: canMemoryAllocator; {Memory allocator.} + deAlloc: canMemoryDeallocator; {Memory deallocator.} + end; + + canSWDescrPointer = ^canSWDescr; + + TWMCan = record {Type declaration for windows or dos message} + Msg: Cardinal; + case Integer of + 0: (WParam: Cardinal; + LParam: Longint; + Result: Longint); + + 1: (handle: Cardinal; {CAN handle issuing message.} + minorMsg: Word; {Message types.} + status: Word; ); {Status.} + end; + + canStatus = integer; + canHandle = integer; + kvEnvHandle = Int64; + + canBusStatistics = record + stdData: Cardinal; + stdRemote: Cardinal; + extData: Cardinal; + extRemote: Cardinal; + errFrame: Cardinal; // Error frames + busLoad: Cardinal; // 0 .. 10000 meaning 0.00-100.00% + overruns: Cardinal; + end; + + canUserIoPortData = record + portNo: Cardinal; + portValue: Cardinal; + end; + + TCanInterface = class(TObject) + public + channel : Integer; + eanhi, eanlo : Cardinal; + serial : Cardinal; + hnd : canHandle; + name: String; + Constructor create(canChannel: Integer);overload; + + private + end; + +{------------------------------------------------------------+ +| End of type definitions. | ++------------------------------------------------------------} + +function canLocateHardware: canStatus; stdcall; +procedure canInitializeLibrary; stdcall; +function canUnloadLibrary: Integer; stdcall; +procedure SetDllName(s: string); + + + + +type + kvCallback_t = procedure(handle: canHandle; context: Pointer; notifyEvent: Cardinal); stdcall; + + kvStatus = canStatus; + + kvTimeDomain = Cardinal; { Really a pointer to something } + + kvTimeDomainData = packed record + nMagiSyncGroups: Integer; + nMagiSyncedMembers: Integer; + nNonMagiSyncCards: Integer; + nNonMagiSyncedMembers: Integer; + end; + +var + canOpen: function(const hwdescr: canHWDescr; swdescr: Pointer; flags: Cardinal): canHandle; stdcall; + canClose: function(handle: canHandle): canStatus; stdcall; + canBusOn: function(handle: canHandle): canStatus; stdcall; + canBusOff: function(handle: canHandle): canStatus; stdcall; + canSetBusParams: function(handle: canHandle; freq: Longint; tseg1, tseg2, sjw, noSamp, syncmode: Cardinal): canStatus; stdcall; + canGetBusParams: function(handle: canHandle; var freq: Longint; var tseg1, tseg2, sjw, noSamp, syncmode: Cardinal): canStatus; stdcall; + canSetBusParamsFd: function(handle: canHandle; freq: Longint; tseg1, tseg2, sjw: Cardinal): canStatus; stdcall; + canGetBusParamsFd: function(handle: canHandle; var freq: Longint; var tseg1, tseg2, sjw: Cardinal): canStatus; stdcall; + canSetBusOutputControl: function(handle: canHandle; drivertype: Cardinal): canStatus; stdcall; + canGetBusOutputControl: function(handle: canHandle; var drivertype: Cardinal): canStatus; stdcall; + canAccept: function(handle: canHandle; envelope: Longint; flag: Cardinal): canStatus; stdcall; + canReadStatus: function(handle: canHandle; var flags: Cardinal): canStatus; stdcall; + canReadErrorCounters: function(handle: canHandle; var txErr, rxErr, ovErr: Cardinal): canStatus; stdcall; + canWrite: function(handle: canHandle; id: Longint; msg: Pointer; dlc: Cardinal; flag: Cardinal): canStatus; stdcall; + canWriteSync: function(handle: canHandle; timeout: Cardinal): canStatus; stdcall; + canRead: function(handle: canHandle; var id: Longint; msg: Pointer; var dlc: Cardinal; var flag: Cardinal; var time: Cardinal): canStatus; stdcall; + canReadWait: function(handle: canHandle; var id: Longint; msg: Pointer; var dlc: Cardinal; var flag: Cardinal; var time: Cardinal; timeout: Cardinal): canStatus; stdcall; + canReadSpecific: function(handle: canHandle; id: Longint; msg: Pointer; var dlc: Cardinal; var flag: Cardinal; var time: Cardinal): canStatus; stdcall; + canReadSync: function(handle: canHandle; timeout: Cardinal): canStatus; stdcall; + canReadSyncSpecific: function(handle: canHandle; id, timeout: Cardinal): canStatus; stdcall; + canReadSpecificSkip: function(handle: canHandle; id: Longint; msg: Pointer; var dlc: Cardinal; var flag: Cardinal; var time: Cardinal): canStatus; stdcall; + canInstallAction: function(handle: canHandle; id: Longint; fn: Pointer): canStatus; stdcall; + canUninstallAction: function(handle: canHandle; id: Longint): canStatus; stdcall; + canInstallOwnBuffer: function(handle: canHandle; id: Longint; len: Cardinal; buf: Pointer): canStatus; stdcall; + canUninstallOwnBuffer: function(handle: canHandle; id: Longint): canStatus; stdcall; + canSetNotify: function(handle: canHandle; aHWnd: HWND; aNotifyFlags: Cardinal): canStatus; stdcall; + canTranslateBaud: function(var freq: longint; var tseg1, tseg2, sjw, noSamp, syncMode: Cardinal): canStatus; stdcall; + canGetErrorText: function(err: canStatus; buf: PAnsiChar; bufsiz: Cardinal): canStatus; stdcall; + canGetVersion: function: Word; stdcall; + canIoCtl: function(handle: canHandle; func: Cardinal; buf: Pointer; buflen: Cardinal): canStatus; stdcall; + canReadTimer: function(handle: canHandle): Cardinal; stdcall; + kvReadTimer: function(handle: canHandle; var time: Cardinal): kvStatus; stdcall; + kvReadTimer64: function(handle: canHandle; var time: Int64): kvStatus; stdcall; + canGetNumberOfChannels: function(var channelCount: Integer): canStatus; stdcall; + canGetChannelData: function(channel, item: Integer; var buffer; bufsize: Cardinal): canStatus; stdcall; + canOpenChannel: function(channel: Integer; flags: Integer): canHandle; stdcall; + canWaitForEvent: function(hnd: canHandle; timeout: Cardinal): canStatus; stdcall; + canSetBusParamsC200: function(hnd: canHandle; btr0, btr1: byte): canStatus; stdcall; + canGetVersionEx: function(itemCode: Cardinal): Cardinal; stdcall; + canSetDriverMode: function(hnd: canHandle; lineMode, resNet: Integer): canStatus; stdcall; + canGetDriverMode: function(hnd: canHandle; var lineMode: Integer; var resNet: Integer): canStatus; stdcall; + canParamGetCount: function(): canStatus; stdcall; + canParamCommitChanges: function(): canStatus; stdcall; + canParamDeleteEntry: function(index: Integer): canStatus; stdcall; + canParamCreateNewEntry: function(): canStatus; stdcall; + canParamSwapEntries: function(index1, index2: Integer): canStatus; stdcall; + canParamGetName: function(index: Integer; buffer: PAnsiChar; maxlen: Integer): canStatus; stdcall; + canParamGetChannelNumber: function(index: Integer): canStatus; stdcall; + canParamGetBusParams: function(index: Integer; var bitrate: LongInt; var tseg1: Cardinal; var tseg2: Cardinal; var sjw: Cardinal; var nosamp: Cardinal): canStatus; stdcall; + canParamSetName: function(index: Integer; buffer: PAnsiChar): canStatus; stdcall; + canParamSetChannelNumber: function(index, channel: Integer): canStatus; stdcall; + canParamSetBusParams: function(index: Integer; bitrate: longint; tseq1, tseq2, sjw, noSamp: Cardinal): canStatus; stdcall; + canParamFindByName: function(const Name: PAnsiChar):canStatus; stdcall; + canObjBufFreeAll: function(handle: canHandle): canStatus; stdcall; + canObjBufAllocate: function(handle: canHandle; tp: Integer): canStatus; stdcall; + canObjBufFree: function(handle: canHandle; idx: Integer): canStatus; stdcall; + canObjBufWrite: function(handle: canHandle; idx, id: Integer; var msg; dlc, flags: cardinal): canstatus; stdcall; + canObjBufSetFilter: function(handle: canHandle; idx: Integer; code, mask: Cardinal): canStatus; stdcall; + canObjBufSetFlags: function(handle: canHandle; idx: Integer; flags: Cardinal): canStatus; stdcall; + canObjBufEnable: function(handle: canHandle; idx: Integer): canStatus; stdcall; + canObjBufDisable: function(handle: canHandle; idx: Integer): canStatus; stdcall; + canObjBufSetPeriod: function(handle: canHandle; idx: Integer; period: Cardinal): canStatus; stdcall; + canObjBufSetMsgCount: function(handle: canHandle; idx: Integer; count: Cardinal): canStatus; stdcall; + canObjBufSendBurst: function(handle: canHandle; idx: Integer; burstLen: Cardinal): canStatus; stdcall; + canProbeVersion: function(handle: canHandle; major, minor, oem_id: Integer; flags: Cardinal): Boolean; stdcall; + canResetBus: function(handle: canHandle): canStatus; stdcall; + canWriteWait: function(handle: canHandle; id: longint; var msg; dlc, flag, timeout : Cardinal): canStatus; stdcall; + canSetAcceptanceFilter: function(handle: canHandle; code, mask: Cardinal; is_extended: Integer): canStatus; stdcall; + canFlushReceiveQueue: function(handle: canHandle): canStatus; stdcall; + canFlushTransmitQueue: function(handle: canHandle): canStatus; stdcall; + canRequestChipStatus:function(handle: canHandle): canStatus; stdcall; + canRequestBusStatistics: function(handle: canHandle): canStatus; stdcall; + canGetBusStatistics: function(handle: canHandle; var stat: canBusStatistics; bufsiz: Cardinal): canStatus; stdcall; + kvAnnounceIdentity: function(handle: canHandle; var buf; bufsiz: Cardinal): canStatus; stdcall; + kvAnnounceIdentityEx: function(handle: canHandle; typ: Integer; var buf; bufsiz: Cardinal): canStatus; stdcall; + kvSetNotifyCallback: function(handle: canHandle; callback: kvCallback_t; context: Pointer; notifyFlags: Cardinal): canStatus; stdcall; + kvBeep: function(handle: canHandle; freq: Integer; duration: Cardinal): canStatus; stdcall; + kvSelfTest: function(handle: canHandle; var presults: Cardinal): canStatus; stdcall; + kvFlashLeds: function(handle: canHandle; action: Integer; timeout: Integer): canStatus; stdcall; + canSetBitrate: function(handle: canHandle; bitrate: Integer): canStatus; stdcall; + canGetHandleData: function(handle: canHandle; item: Integer; var Buffer; bufsize: Cardinal): canStatus; stdcall; + kvGetApplicationMapping: function(busType: Integer; appName: PAnsiChar; appChannel: Integer; var resultingChannel: Integer): canStatus; stdcall; + kvTimeDomainCreate: function(var domain: kvTimeDomain): kvStatus; stdcall; + kvTimeDomainDelete: function(domain: kvTimeDomain): kvStatus; stdcall; + kvTimeDomainResetTime: function(domain: kvTimeDomain): kvStatus; stdcall; + kvTimeDomainGetData: function(domain: kvTimeDomain; var data: kvTimeDomainData; bufsiz: Cardinal): kvStatus; stdcall; + kvTimeDomainAddHandle: function(domain: kvTimeDomain; handle: canHandle): kvStatus; stdcall; + kvTimeDomainRemoveHandle: function(domain: kvTimeDomain; handle: canHandle): kvStatus; stdcall; + kvReadDeviceCustomerData: function(hnd: canHandle;userNumber, itemNumber: Integer; var data; bufsize: Cardinal): kvStatus; stdcall; + kvGetSupportedInterfaceInfo: function(index: Integer; hwName: PAnsiChar; nameLen: Cardinal; var hwType: Integer; var hwBusType: Integer): kvStatus; stdcall; + kvScriptStart: function(const hnd: canHandle; slotNo: integer): kvStatus; stdcall; + kvScriptStatus: function(const hnd: canHandle; slotNo: integer; var status: integer): kvStatus; stdcall; + kvScriptStop: function(const hnd: canHandle; slotNo: integer; mode: integer): kvStatus; stdcall; + kvScriptUnload: function(const hnd: canHandle; slotNo: integer): kvStatus; stdcall; + kvScriptSendEvent: function(const hnd: canHandle; + slotNo: integer; + eventType: integer; + eventNo: integer; + data: Cardinal): kvStatus; stdcall; + kvScriptEnvvarOpen: function(const hnd: canHandle; envvarName: PAnsiChar; var envvarType: Integer; var envvarSize: Integer): kvEnvHandle; stdcall; + + kvScriptEnvvarClose: function(const eHnd: kvEnvHandle): kvStatus; stdcall; + kvScriptEnvvarSetInt: function(const eHnd: kvEnvHandle; val: Integer): kvStatus; stdcall; + kvScriptEnvvarGetInt: function(const eHnd: kvEnvHandle; var val: Integer): kvStatus; stdcall; + kvScriptEnvvarSetFloat: function(const eHnd: kvEnvHandle; val: Single): kvStatus; stdcall; + kvScriptEnvvarGetFloat: function(const eHnd: kvEnvHandle; var val: Single): kvStatus; stdcall; + kvScriptEnvvarSetData: function(const eHnd: kvEnvHandle; var buf; start_index: Integer; data_len: Integer): kvStatus; stdcall; + kvScriptEnvvarGetData: function(const eHnd: kvEnvHandle; var buf; start_index: Integer; data_len: Integer): kvStatus; stdcall; + kvScriptGetMaxEnvvarSize: function(hnd: canHandle; var envvarSize: Integer): kvStatus; stdcall; + kvScriptLoadFileOnDevice: function(hnd: canHandle; slotNo: Integer; localFile: PAnsiChar): kvStatus; stdcall; + kvScriptLoadFile: function(hnd: canHandle; slotNo: Integer; filePathOnPC: PAnsiChar): kvStatus; stdcall; + kvScriptRequestText: function(hnd: canHandle; slotNo: cardinal; request: cardinal): kvStatus; stdcall; + kvScriptGetText: function(hnd: canHandle; var slot: integer; var time: Cardinal; var flags: Cardinal; buf: PAnsiChar; bufsize: Cardinal): kvStatus; stdcall; + kvFileCopyToDevice: function(hnd: canHandle; hostFileName: PAnsiChar; deviceFileName: PAnsiChar): kvStatus; stdcall; + kvFileCopyFromDevice: function(hnd: canHandle; deviceFileName: PAnsiChar; hostFileName: PAnsiChar): kvStatus; stdcall; + kvFileDelete: function(hnd: canHandle; deviceFileName: PAnsiChar): kvStatus; stdcall; + kvFileGetName: function(hnd: canHandle; fileNo: Integer; name: PAnsiChar; namelen: Integer): kvStatus; stdcall; + kvFileGetCount: function(hnd: canHandle; var count: Integer): kvStatus; stdcall; + kvFileGetSystemData: function(hnd: canHandle; itemCode: Integer; var result: Integer): kvStatus; stdcall; + kvDeviceSetMode: function(hnd: canHandle; mode: Integer): kvStatus; stdcall; + kvDeviceGetMode: function(hnd: canHandle; var mode: Integer): kvStatus; stdcall; + kvPingRequest: function(hnd: canHandle; var requestTime: Cardinal): kvStatus; stdcall; + kvPingGetLatest: function(hnd: canHandle; var requestTime: Cardinal; var pingTime: Cardinal): kvStatus; stdcall; + +const + + kvLED_ACTION_ALL_LEDS_ON = 0; + kvLED_ACTION_ALL_LEDS_OFF = 1; + kvLED_ACTION_LED_0_ON = 2; + kvLED_ACTION_LED_0_OFF = 3; + kvLED_ACTION_LED_1_ON = 4; + kvLED_ACTION_LED_1_OFF = 5; + kvLED_ACTION_LED_2_ON = 6; + kvLED_ACTION_LED_2_OFF = 7; + kvLED_ACTION_LED_3_ON = 8; + kvLED_ACTION_LED_3_OFF = 9; + + canCHANNELDATA_CHANNEL_CAP = 1; + canCHANNELDATA_TRANS_CAP = 2; + canCHANNELDATA_CHANNEL_FLAGS = 3; // available, etc + canCHANNELDATA_CARD_TYPE = 4; // canHWTYPE_xxx + canCHANNELDATA_CARD_NUMBER = 5; // Number in machine, 0,1,... + canCHANNELDATA_CHAN_NO_ON_CARD = 6; + canCHANNELDATA_CARD_SERIAL_NO = 7; + canCHANNELDATA_TRANS_SERIAL_NO = 8; + canCHANNELDATA_CARD_FIRMWARE_REV = 9; + canCHANNELDATA_CARD_HARDWARE_REV = 10; + canCHANNELDATA_CARD_UPC_NO = 11; + canCHANNELDATA_TRANS_UPC_NO = 12; + canCHANNELDATA_CHANNEL_NAME = 13; + canCHANNELDATA_DLL_FILE_VERSION = 14; + canCHANNELDATA_DLL_PRODUCT_VERSION = 15; + canCHANNELDATA_DLL_FILETYPE = 16; + canCHANNELDATA_TRANS_TYPE = 17; + canCHANNELDATA_DEVICE_PHYSICAL_POSITION = 18; + canCHANNELDATA_UI_NUMBER = 19; + canCHANNELDATA_TIMESYNC_ENABLED = 20; + canCHANNELDATA_DRIVER_FILE_VERSION = 21; + canCHANNELDATA_DRIVER_PRODUCT_VERSION = 22; + canCHANNELDATA_MFGNAME_UNICODE = 23; + canCHANNELDATA_MFGNAME_ASCII = 24; + canCHANNELDATA_DEVDESCR_UNICODE = 25; + canCHANNELDATA_DEVDESCR_ASCII = 26; + canCHANNELDATA_DRIVER_NAME = 27; + canCHANNELDATA_CHANNEL_QUALITY = 28; + canCHANNELDATA_ROUNDTRIP_TIME = 29; + canCHANNELDATA_BUS_TYPE = 30; + canCHANNELDATA_DEVNAME_ASCII = 31; + canCHANNELDATA_TIME_SINCE_LAST_SEEN = 32; + canCHANNELDATA_REMOTE_OPERATIONAL_MODE = 33; + canCHANNELDATA_REMOTE_PROFILE_NAME = 34; + canCHANNELDATA_REMOTE_HOST_NAME = 35; + canCHANNELDATA_REMOTE_MAC = 36; + canCHANNELDATA_MAX_BITRATE = 37; + canCHANNELDATA_CHANNEL_CAP_MASK = 38; + canCHANNELDATA_CUST_CHANNEL_NAME = 39; + canCHANNELDATA_IS_REMOTE = 40; + canCHANNELDATA_REMOTE_TYPE = 41; + canCHANNELDATA_LOGGER_TYPE = 42; + + + +// channelFlags in canChannelData + canCHANNEL_IS_EXCLUSIVE = $0001; + canCHANNEL_IS_OPEN = $0002; + canCHANNEL_IS_CANFD = $0004; + +// For canOpen(), canOpenChannel() + canWANT_EXCLUSIVE = $08; { Don't allow sharing } + canWANT_EXTENDED = $10; { Extended CAN is required } + canWANT_VIRTUAL = $0020; + canOPEN_EXCLUSIVE = canWANT_EXCLUSIVE; + canOPEN_REQUIRE_EXTENDED = canWANT_EXTENDED; + canOPEN_ACCEPT_VIRTUAL = canWANT_VIRTUAL; + canOPEN_OVERRIDE_EXCLUSIVE = $0040; + canOPEN_REQUIRE_INIT_ACCESS = $0080; + canOPEN_NO_INIT_ACCESS = $0100; + canOPEN_ACCEPT_LARGE_DLC = $0200; + canOPEN_CAN_FD = $0400; + canOPEN_CAN_FD_NONISO = $0800; + + +// Hardware types. + canHWTYPE_NONE = 0; // Unknown + canHWTYPE_VIRTUAL = 1; // Virtual channel. + canHWTYPE_LAPCAN = 2; // LAPcan family + canHWTYPE_CANPARI = 3; // CANpari (not supported.) + canHWTYPE_PCCAN = 8; // PCcan family + canHWTYPE_PCICAN = 9; // PCIcan family + canHWTYPE_USBCAN = 11; // USBcan family + canHWTYPE_PCICAN_II = 40; + canHWTYPE_USBCAN_II = 42; + canHWTYPE_SIMULATED = 44; + canHWTYPE_ACQUISITOR = 46; + canHWTYPE_LEAF = 48; + canHWTYPE_PC104_PLUS = 50; // PC104+ + canHWTYPE_PCICANX_II = 52; // PCIcanx II + canHWTYPE_MEMORATOR_II = 54; // Memorator Professional + canHWTYPE_MEMORATOR_PRO = 54; // Memorator Professional + canHWTYPE_USBCAN_PRO = 56; // USBcan Professional + canHWTYPE_IRIS = 58; // Obsolete name, use canHWTYPE_BLACKBIRD instead + canHWTYPE_BLACKBIRD = 58; + canHWTYPE_MEMORATOR_LIGHT = 60; ///< Kvaser Memorator Light + canHWTYPE_MINIHYDRA = 62; ///< Obsolete name, use canHWTYPE_EAGLE instead + canHWTYPE_EAGLE = 62; ///< Kvaser Eagle family + canHWTYPE_BAGEL = 64; ///< Obsolete name, use canHWTYPE_BLACKBIRD_V2 instead + canHWTYPE_BLACKBIRD_V2 = 64; ///< Kvaser BlackBird v2 + canHWTYPE_MINIPCIE = 66; ///< "Mini PCI Express" for now, subject to change. + canHWTYPE_USBCAN_KLINE = 68; ///< USBcan Pro HS/K-Line + canHWTYPE_ETHERCAN = 70; ///< Kvaser Ethercan + canHWTYPE_USBCAN_LIGHT = 72; ///< Kvaser USBcan Light + canHWTYPE_USBCAN_PRO2 = 74; ///< Kvaser USBcan Pro 5xHS + canHWTYPE_PCIE_V2 = 76; ///< PCIe for now + canHWTYPE_MEMORATOR_PRO2 = 78; ///< Kvaser Memorator Pro 5xHS + canHWTYPE_LEAF2 = 80; ///< Kvaser Leaf Pro HS v2 and variants + canHWTYPE_MEMORATOR_V2 = 82; ///< Kvaser Memorator (2nd generation) + + + canTRANSCEIVER_TYPE_UNKNOWN = 0; + canTRANSCEIVER_TYPE_251 = 1; + canTRANSCEIVER_TYPE_252 = 2; + canTRANSCEIVER_TYPE_DNOPTO = 3; + canTRANSCEIVER_TYPE_W210 = 4; + canTRANSCEIVER_TYPE_SWC_PROTO = 5; + canTRANSCEIVER_TYPE_SWC = 6; + canTRANSCEIVER_TYPE_EVA = 7; + canTRANSCEIVER_TYPE_FIBER = 8; + canTRANSCEIVER_TYPE_K251 = 9; + canTRANSCEIVER_TYPE_K = 10; + canTRANSCEIVER_TYPE_1054_OPTO = 11; + canTRANSCEIVER_TYPE_SWC_OPTO = 12; + canTRANSCEIVER_TYPE_TT = 13; + canTRANSCEIVER_TYPE_1050 = 14; + canTRANSCEIVER_TYPE_1050_OPTO = 15; + canTRANSCEIVER_TYPE_1041 = 16; + canTRANSCEIVER_TYPE_1041_OPTO = 17; + canTRANSCEIVER_TYPE_RS485 = 18; + canTRANSCEIVER_TYPE_LIN = 19; + canTRANSCEIVER_TYPE_KONE = 20; + canTRANSCEIVER_TYPE_CANFD = 22; + canTRANSCEIVER_TYPE_LINX_LIN = 64; + canTRANSCEIVER_TYPE_LINX_J1708 = 66; + canTRANSCEIVER_TYPE_LINX_K = 68; + canTRANSCEIVER_TYPE_LINX_SWC = 70; + canTRANSCEIVER_TYPE_LINX_LS = 72; + + +// Channel capabilities. + canCHANNEL_CAP_EXTENDED_CAN = $00000001; ///< Can use extended identifiers + canCHANNEL_CAP_BUS_STATISTICS = $00000002; ///< Can report busload etc + canCHANNEL_CAP_ERROR_COUNTERS = $00000004; ///< Can return error counters + canCHANNEL_CAP_CAN_DIAGNOSTICS = $00000008; ///< Can report CAN diagnostics + canCHANNEL_CAP_GENERATE_ERROR = $00000010; ///< Can send error frames + canCHANNEL_CAP_GENERATE_OVERLOAD = $00000020; ///< Can send CAN overload frame + canCHANNEL_CAP_TXREQUEST = $00000040; ///< Can report when a CAN messsage transmission is initiated + canCHANNEL_CAP_TXACKNOWLEDGE = $00000080; ///< Can report when a CAN messages has been transmitted + canCHANNEL_CAP_VIRTUAL = $00010000; ///< Virtual CAN channel + canCHANNEL_CAP_SIMULATED = $00020000; ///< Simulated CAN channel + canCHANNEL_CAP_REMOTE = $00040000; ///< Remote CAN channel (e.g. BlackBird). + canCHANNEL_CAP_CAN_FD = $00080000; ///< CAN-FD ISO compliant channel + canCHANNEL_CAP_CAN_FD_NONISO = $00100000; ///< CAN-FD NON-ISO compliant channel + canCHANNEL_CAP_SILENT_MODE = $00200000; ///< Channel supports Silent mode + canCHANNEL_CAP_SINGLE_SHOT = $00400000; ///< Channel supports Single Shot messages + canCHANNEL_CAP_LOGGER = $00800000; ///< Channel has logger capabilities. + canCHANNEL_CAP_REMOTE_ACCESS = $01000000; ///< Channel has remote capabilities + canCHANNEL_CAP_SCRIPT = $02000000; ///< Channel has script capabilities. + +// Driver (transceiver) capabilities + canDRIVER_CAP_HIGHSPEED = $00000001; + + +implementation + +uses + SysUtils; + +var + hDLL: THandle; + realCanLocateHardware: function: canStatus; + realCanInitializeLibrary: procedure; + realCanUnloadLibrary: function: Integer; + DLLName: array[0..50] of char = 'CANLIB32.DLL'; + + +Constructor TCanInterface.create(canChannel: Integer) overload; +Var + cname: packed array[0..256] of AnsiChar; +begin + channel := canChannel; + + canGetChannelData(channel, canCHANNELDATA_CHANNEL_NAME, cname, 256); + //OutputDebugString(PCHAR(inttostr(status))); + name := Format('%s', [cname]); + //Inherited Create; +end; + + + +procedure LoadDLL; forward; +procedure UnloadDLL; forward; + +procedure canInitializeLibrary; +begin + if hDLL <> 0 then Exit; + LoadDLL; + if hDLL <> 0 then begin + realCanInitializeLibrary; + end; +end; + +function canLocateHardware: canStatus; +begin + if hDLL <> 0 then begin + Result := canOK; + Exit; + end; + LoadDLL; + if hDLL = 0 then begin + Result := canERR_DYNALOAD; + end else begin + Result := realCanLocateHardware; + end; +end; + +function canUnloadLibrary: Integer; +begin + if hDLL = 0 then begin + Result := canOK; + Exit; + end; + if Assigned(realCanUnloadLibrary) then realCanUnloadLibrary; + UnloadDLL; + Result := canOK; +end; + + +function GPA(const proc: string): Pointer; +var s: array[0..300] of char; +begin + StrPCopy(s, proc); + Result := GetProcAddress(hDLL, s); + if Result = nil then begin + raise Exception.CreateFmt('CANLIB: function %s not found.', [proc]); + end; +end; + +procedure SetDllName(s: string); +begin + StrPCopy(DLLName, s); +end; + +procedure LoadDLL; +var + err: integer; +begin + hDLL := LoadLibrary(DLLName); + err := GetLastError; + if hDLL = 0 then begin + raise Exception.Create(Format('Can not load the CAN driver - is it correctly installed? ' + + '(Error 0x%8.8x)', [err])); + Exit; + end; + + @realCanLocateHardware := GPA('canLocateHardware'); + @realCanInitializeLibrary := GPA('canInitializeLibrary'); + + @canOpen := GPA('canOpen'); + + @canClose := GPA('canClose'); + @canBusOn := GPA('canBusOn'); + @canBusOff := GPA('canBusOff'); + @canSetBusParams := GPA('canSetBusParams'); + @canGetBusParams := GPA('canGetBusParams'); + @canSetBusParamsFd := GPA('canSetBusParamsFd'); + @canGetBusParamsFd := GPA('canGetBusParamsFd'); + @canSetBusOutputControl := GPA('canSetBusOutputControl'); + @canGetBusOutputControl := GPA('canGetBusOutputControl'); + @canAccept := GPA('canAccept'); + @canReadStatus := GPA('canReadStatus'); + @canReadErrorCounters := GPA('canReadErrorCounters'); + @canWrite := GPA('canWrite'); + @canWriteSync := GPA('canWriteSync'); + @canRead := GPA('canRead'); + @canReadWait := GPA('canReadWait'); + @canReadSpecific := GPA('canReadSpecific'); + @canReadSync := GPA('canReadSync'); + @canReadSyncSpecific := GPA('canReadSyncSpecific'); + @canReadSpecificSkip := GPA('canReadSpecificSkip'); + @canInstallAction := nil; + @canUninstallAction := nil; + @canInstallOwnBuffer := nil; + @canUninstallOwnBuffer := nil; + @canSetNotify := GPA('canSetNotify'); + @canTranslateBaud := GPA('canTranslateBaud'); + @canGetErrorText := GPA('canGetErrorText'); + @canGetVersion := GPA('canGetVersion'); + @canIoCtl := GPA('canIoCtl'); + @canReadTimer := GPA('canReadTimer'); + @canGetNumberOfChannels := GPA('canGetNumberOfChannels'); + @canGetChannelData := GPA('canGetChannelData'); + @canOpenChannel := GPA('canOpenChannel'); + @canWaitForEvent := GPA('canWaitForEvent'); + @canSetBusParamsC200 := GPA('canSetBusParamsC200'); + @canGetVersionEx := GPA('canGetVersionEx'); + @canSetDriverMode := GPA('canSetDriverMode'); + @canGetDriverMode := GPA('canGetDriverMode'); + @canParamGetCount := GPA('canParamGetCount'); + @canParamCommitChanges := GPA('canParamCommitChanges'); + @canParamDeleteEntry := GPA('canParamDeleteEntry'); + @canParamCreateNewEntry := GPA('canParamCreateNewEntry'); + @canParamSwapEntries := GPA('canParamSwapEntries'); + @canParamGetName := GPA('canParamGetName'); + @canParamGetChannelNumber := GPA('canParamGetChannelNumber'); + @canParamGetBusParams := GPA('canGetBusParams'); + @canParamSetName := GPA('canParamSetName'); + @canParamSetChannelNumber := GPA('canParamSetChannelNumber'); + @canParamSetBusParams := GPA('canParamSetBusParams'); + @canParamFindByName := GPA('canParamFindByName'); + @canObjBufFreeAll := GPA('canObjBufFreeAll'); + @canObjBufAllocate := GPA('canObjBufAllocate'); + @canObjBufFree := GPA('canObjBufFree'); + @canObjBufWrite := GPA('canObjBufWrite'); + @canObjBufSetFilter := GPA('canObjBufSetFilter'); + @canObjBufSetFlags := GPA('canObjBufSetFilter'); + @canObjBufEnable := GPA('canObjBufEnable'); + @canObjBufDisable := GPA('canObjBufDisable'); + @canProbeVersion := GPA('canProbeVersion'); + @canResetBus := GPA('canResetBus'); + @canWriteWait := GPA('canWriteWait'); + @canSetAcceptanceFilter :=GPA('canSetAcceptanceFilter'); + @canRequestChipStatus := GPA('canRequestChipStatus'); + @canRequestBusStatistics := GPA('canRequestBusStatistics'); + @canGetBusStatistics := GPA('canGetBusStatistics'); + @kvAnnounceIdentity := GPA('kvAnnounceIdentity'); + @kvSetNotifyCallback := GPA('kvSetNotifyCallback'); + @kvBeep := GPA('kvBeep'); + @kvSelfTest := GPA('kvSelfTest'); + @kvFlashLeds := GPA('kvFlashLeds'); + @canSetBitrate := GPA('canSetBitrate'); + @canGetHandleData := GPA('canGetHandleData'); + @kvTimeDomainCreate := GPA('kvTimeDomainCreate'); + @kvTimeDomainDelete := GPA('kvTimeDomainDelete'); + @kvTimeDomainResetTime := GPA('kvTimeDomainResetTime'); + @kvTimeDomainGetData := GPA('kvTimeDomainGetData'); + @kvTimeDomainAddHandle := GPA('kvTimeDomainAddHandle'); + @kvTimeDomainRemoveHandle := GPA('kvTimeDomainRemoveHandle'); + @kvReadDeviceCustomerData := GPA('kvReadDeviceCustomerData'); + @kvReadTimer := GPA('kvReadTimer'); + @kvReadTimer64 := GPA('kvReadTimer64'); + @canObjBufSetPeriod := GPA('canObjBufSetPeriod'); + @canObjBufSetMsgCount := GPA('canObjBufSetMsgCount'); + @canObjBufSendBurst := GPA('canObjBufSendBurst'); + @canFlushReceiveQueue := GPA('canFlushReceiveQueue'); + @canFlushTransmitQueue := GPA('canFlushTransmitQueue'); + @kvAnnounceIdentityEx := GPA('kvAnnounceIdentityEx'); + @kvGetApplicationMapping := GPA('kvGetApplicationMapping'); + @kvGetSupportedInterfaceInfo := GPA('kvGetSupportedInterfaceInfo'); + @kvScriptStart := GPA('kvScriptStart'); + @kvScriptStatus := GPA('kvScriptStatus'); + @kvScriptStop := GPA('kvScriptStop'); + @kvScriptUnload := GPA('kvScriptUnload'); + @kvScriptSendEvent := GPA('kvScriptSendEvent'); + @kvScriptEnvvarOpen := GPA('kvScriptEnvvarOpen'); + @kvScriptEnvvarClose := GPA('kvScriptEnvvarClose'); + @kvScriptEnvvarSetInt := GPA('kvScriptEnvvarSetInt'); + @kvScriptEnvvarGetInt := GPA('kvScriptEnvvarGetInt'); + @kvScriptEnvvarSetFloat := GPA('kvScriptEnvvarSetFloat'); + @kvScriptEnvvarGetFloat := GPA('kvScriptEnvvarGetFloat'); + @kvScriptEnvvarSetData := GPA('kvScriptEnvvarSetData'); + @kvScriptEnvvarGetData := GPA('kvScriptEnvvarGetData'); + @kvScriptGetMaxEnvvarSize := GPA('kvScriptGetMaxEnvvarSize'); + @kvScriptLoadFileOnDevice := GPA('kvScriptLoadFileOnDevice'); + @kvScriptLoadFile := GPA('kvScriptLoadFile'); + @kvScriptRequestText := GPA('kvScriptRequestText'); + @kvScriptGetText := GPA('kvScriptGetText'); + @kvFileCopyToDevice := GPA('kvFileCopyToDevice'); + @kvFileCopyFromDevice := GPA('kvFileCopyFromDevice'); + @kvFileDelete := GPA('kvFileDelete'); + @kvFileGetName := GPA('kvFileGetName'); + @kvFileGetCount := GPA('kvFileGetCount'); + @kvFileGetSystemData := GPA('kvFileGetSystemData'); + @kvDeviceSetMode := GPA('kvDeviceSetMode'); + @kvDeviceGetMode := GPA('kvDeviceGetMode'); + @kvPingRequest := GPA('kvPingRequest'); + @kvPingGetLatest := GPA('kvPingGetLatest'); + {--} + @realCanUnloadLibrary := GPA('canUnloadLibrary'); + +end; + +procedure UnloadDLL; +begin + if not Assigned(realCanUnloadLibrary) then Exit; + realCanUnloadLibrary; + FreeLibrary(hDLL); + hDLL := 0; +end; + + +end. diff --git a/Host/Source/MicroBoot/interfaces/can/kvaser/openblt_can_kvaser.dpr b/Host/Source/MicroBoot/interfaces/can/kvaser/openblt_can_kvaser.dpr index 15de82d5..bca41c61 100644 --- a/Host/Source/MicroBoot/interfaces/can/kvaser/openblt_can_kvaser.dpr +++ b/Host/Source/MicroBoot/interfaces/can/kvaser/openblt_can_kvaser.dpr @@ -51,6 +51,7 @@ uses XcpSettings in 'XcpSettings.pas' {XcpSettingsForm}, FirmwareData in '..\..\..\..\Library\FirmwareData\pas\FirmwareData.pas'; + //*************************************************************************************** // Global Constants //*************************************************************************************** diff --git a/Host/canlib32.dll b/Host/canlib32.dll new file mode 100644 index 00000000..a9f9628f Binary files /dev/null and b/Host/canlib32.dll differ diff --git a/Host/openblt_can_kvaser.dll b/Host/openblt_can_kvaser.dll index 25ae9435..94538dce 100644 Binary files a/Host/openblt_can_kvaser.dll and b/Host/openblt_can_kvaser.dll differ