Refs #244. Added Microboot interface DLL framework for the Kvaser Leaf Light v2 CAN adapter.

git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@213 5dc33758-31d5-4daf-9ae8-b24bf3d40d73
This commit is contained in:
Frank Voorburg 2017-04-13 14:05:30 +00:00
parent 25fc389ad3
commit 6eb42533ce
8 changed files with 1598 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

View File

@ -0,0 +1,488 @@
unit XcpSettings;
//***************************************************************************************
// Description: XCP settings interface for CAN
// File Name: XcpSettings.pas
//
//---------------------------------------------------------------------------------------
// C O P Y R I G H T
//---------------------------------------------------------------------------------------
// Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved
//
// This software has been carefully tested, but is not guaranteed for any particular
// purpose. The author does not offer any warranties and does not guarantee the accuracy,
// adequacy, or completeness of the software and is not responsible for any errors or
// omissions or the results obtained from use of the software.
//
//---------------------------------------------------------------------------------------
// L I C E N S E
//---------------------------------------------------------------------------------------
// This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option) any later
// version.
//
// OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.
//
// You have received a copy of the GNU General Public License along with OpenBLT. It
// should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy.
//
//***************************************************************************************
interface
//***************************************************************************************
// Includes
//***************************************************************************************
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, ExtCtrls, IniFiles, Vcl.Imaging.pngimage;
//***************************************************************************************
// Type Definitions
//***************************************************************************************
type
TXcpSettingsForm = class(TForm)
pnlFooter: TPanel;
btnOK: TButton;
btnCancel: TButton;
pageControl: TPageControl;
tabXcp: TTabSheet;
tabCan: TTabSheet;
iconCan: TImage;
lblCan: TLabel;
lblXcp: TLabel;
iconXcp2: TImage;
lblHardware: TLabel;
cmbHardware: TComboBox;
lblChannel: TLabel;
cmbChannel: TComboBox;
lblBaudRate: TLabel;
chbExtendedId: TCheckBox;
lblT1: TLabel;
lblT3: TLabel;
lblT4: TLabel;
lblT5: TLabel;
lblT7: TLabel;
edtT1: TEdit;
edtT3: TEdit;
edtT4: TEdit;
edtT5: TEdit;
edtT7: TEdit;
tabProt: TTabSheet;
iconXcp1: TImage;
lblPort: TLabel;
edtSeedKey: TEdit;
btnBrowse: TButton;
lblTransmitId: TLabel;
Label1: TLabel;
edtTransmitId: TEdit;
edtReceiveId: TEdit;
openDialog: TOpenDialog;
edtTconnect: TEdit;
lblTconnect: TLabel;
cmbBaudrate: TComboBox;
procedure btnOKClick(Sender: TObject);
procedure btnCancelClick(Sender: TObject);
procedure btnBrowseClick(Sender: TObject);
procedure cmbHardwareChange(Sender: TObject);
procedure edtTransmitIdChange(Sender: TObject);
procedure edtTransmitIdKeyPress(Sender: TObject; var Key: Char);
procedure edtReceiveIdKeyPress(Sender: TObject; var Key: Char);
procedure edtReceiveIdChange(Sender: TObject);
private
{ Private declarations }
procedure ValidateHexCanIdInputChange(EdtID: TEdit);
procedure ValidateHexCanIdInputPress(Sender: TObject; var Key: char);
public
{ Public declarations }
procedure SetAvailableChannels;
end;
type
TXcpSettings = class(TObject)
private
FSettingsForm : TXcpSettingsForm;
FIniFile : string;
public
constructor Create(iniFile : string);
destructor Destroy; override;
function Configure : Boolean;
end;
implementation
{$R *.DFM}
//***************************************************************************************
// NAME: SetAvailableChannels
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Updates the items in the channels combobox based on the selected
// hardware.
//
//***************************************************************************************
procedure TXcpSettingsForm.SetAvailableChannels;
var
maxChannels: Integer;
channelCnt: Integer;
oldSelectedIdx: Integer;
begin
// init to safe value
maxChannels := 1;
case cmbHardware.ItemIndex of
0: { KVASER_LEAFLIGHT_V2 }
begin
maxChannels := 1;
end;
end;
// backup currently selected channel
oldSelectedIdx := cmbChannel.ItemIndex;
// update the combobox contents
cmbChannel.Items.Clear;
for channelCnt := 1 to maxChannels do
begin
cmbChannel.Items.Add('Channel' + IntToStr(channelCnt));
end;
cmbChannel.DropDownCount := maxChannels;
// restore the selected channel
if oldSelectedIdx >= (maxChannels) then
begin
cmbChannel.ItemIndex := 0;
end
else
begin
cmbChannel.ItemIndex := oldSelectedIdx;
end;
end; //*** end of SetAvailableChannels ***
//***************************************************************************************
// NAME: ValidateHexCanIdInputChange
// PARAMETER: EdtID Signal source.
// RETURN VALUE: none.
// DESCRIPTION: Checks to see if a valid hexadecimal CAN identifier was entered in
// the specified edit box. Should be called in the edit box's onChange
// event handler.
//
//***************************************************************************************
procedure TXcpSettingsForm.ValidateHexCanIdInputChange(EdtID: TEdit);
var
value: Int64;
begin
// prevent a message identifier > 0x1FFFFFFF from being entered
if EdtID.Text <> '' then
begin
try
value := StrToInt64('$' + EdtID.Text);
if value < 0 then
begin
EdtID.Text := '0';
end
else if value > $1FFFFFFF then
begin
EdtID.Text := '1FFFFFFF';
end;
// automatically set extended if flag
if value > $7ff then
chbExtendedId.Checked := True;
except
// use id 0 if a non hex value was entered, for example through copy-paste
EdtID.Text := '0';
end;
end;
end; //*** end of ValidateHexCanIdInputChange ***
//***************************************************************************************
// NAME: ValidateHexCanIdInputPress
// PARAMETER: Sender Signal source.
// Key The key's character code that was pressed.
// RETURN VALUE: none.
// DESCRIPTION: Checks to see if a valid hexadecimal CAN identifier was entered in
// the specified edit box. Should be called in the edit box's onPress
// event handler.
//
//***************************************************************************************
procedure TXcpSettingsForm.ValidateHexCanIdInputPress(Sender: TObject; var Key: char);
begin
if not (AnsiChar(Key) In ['0'..'9', 'a'..'f', 'A'..'F', #8, ^V, ^C]) then // #8 = backspace
begin
// ignore it
Key := #0;
end;
// convert a..f to upper case
if AnsiChar(Key) In ['a'..'f'] then
begin
Key := UpCase(Key);
end;
end; //*** end of ValidateHexCanIdInputPress ***
//***************************************************************************************
// NAME: cmbHardwareChange
// PARAMETER: none
// RETURN VALUE: modal result
// DESCRIPTION: Event handler for when the hardware combobox selection changed.
//
//***************************************************************************************
procedure TXcpSettingsForm.cmbHardwareChange(Sender: TObject);
begin
SetAvailableChannels;
end; //*** end of cmbHardwareChange ***
//***************************************************************************************
// NAME: edtTransmitIdChange
// PARAMETER: Sender Signal source.
// RETURN VALUE: None.
// DESCRIPTION: Called when the text in the edit box changed.
//
//***************************************************************************************
procedure TXcpSettingsForm.edtReceiveIdChange(Sender: TObject);
begin
ValidateHexCanIdInputChange(edtReceiveId);
end; //*** end of edtReceiveIdChange ***
//***************************************************************************************
// NAME: edtReceiveIdKeyPress
// PARAMETER: Sender Signal source.
// Key The key's character code that was pressed.
// RETURN VALUE: None.
// DESCRIPTION: Called when a key is pressed.
//
//***************************************************************************************
procedure TXcpSettingsForm.edtReceiveIdKeyPress(Sender: TObject; var Key: Char);
begin
ValidateHexCanIdInputPress(edtReceiveId, Key);
end; //*** end of edtReceiveIdKeyPress ***
//***************************************************************************************
// NAME: edtTransmitIdChange
// PARAMETER: Sender Signal source.
// RETURN VALUE: None.
// DESCRIPTION: Called when the text in the edit box changed.
//
//***************************************************************************************
procedure TXcpSettingsForm.edtTransmitIdChange(Sender: TObject);
begin
ValidateHexCanIdInputChange(edtTransmitId);
end; //*** end of edtTransmitIdChange ***
//***************************************************************************************
// NAME: edtTransmitIdKeyPress
// PARAMETER: Sender Signal source.
// Key The key's character code that was pressed.
// RETURN VALUE: None.
// DESCRIPTION: Called when a key is pressed.
//
//***************************************************************************************
procedure TXcpSettingsForm.edtTransmitIdKeyPress(Sender: TObject; var Key: Char);
begin
ValidateHexCanIdInputPress(edtTransmitId, Key);
end; //*** end of edtTransmitIdKeyPress ***
//***************************************************************************************
// NAME: btnOKClick
// PARAMETER: none
// RETURN VALUE: modal result
// DESCRIPTION: Sets the module result to okay.
//
//***************************************************************************************
procedure TXcpSettingsForm.btnOKClick(Sender: TObject);
begin
ModalResult := mrOK;
end; //*** end of btnOKClick ***
//***************************************************************************************
// NAME: btnCancelClick
// PARAMETER: none
// RETURN VALUE: modal result
// DESCRIPTION: Sets the module result to cancel.
//
//***************************************************************************************
procedure TXcpSettingsForm.btnCancelClick(Sender: TObject);
begin
ModalResult := mrCancel;
end; //*** end of btnCancelClick ***
//***************************************************************************************
// NAME: btnBrowseClick
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Prompts the user to select the seed/key dll file.
//
//***************************************************************************************
procedure TXcpSettingsForm.btnBrowseClick(Sender: TObject);
begin
openDialog.InitialDir := ExtractFilePath(ParamStr(0));
if openDialog.Execute then
begin
edtSeedKey.Text := openDialog.FileName;
end;
end; //*** end of btnBrowseClick ***
//***************************************************************************************
// NAME: Create
// PARAMETER: Name of the INI file where the settings are and will be stored
// RETURN VALUE: none
// DESCRIPTION: Class constructor
//
//***************************************************************************************
constructor TXcpSettings.Create(iniFile : string);
begin
// call inherited constructor
inherited Create;
// set the inifile
FIniFile := iniFile;
// create an instance of the settings form
FSettingsForm := TXcpSettingsForm.Create(nil);
end; //*** end of Create ***
//***************************************************************************************
// NAME: Destroy
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Class destructor
//
//***************************************************************************************
destructor TXcpSettings.Destroy;
begin
// releaase the settings form object
FSettingsForm.Free;
// call inherited destructor
inherited;
end; //*** end of Destroy ***
//***************************************************************************************
// NAME: Configure
// PARAMETER: none
// RETURN VALUE: True if configuration was successfully changed, False otherwise
// DESCRIPTION: Allows the user to configure the XCP interface using a GUI.
//
//***************************************************************************************
function TXcpSettings.Configure : Boolean;
var
settingsIni: TIniFile;
settingsInt: Integer;
begin
// initialize the return value
result := false;
// init the form elements using the configuration found in the INI
if FileExists(FIniFile) then
begin
// create ini file object
settingsIni := TIniFile.Create(FIniFile);
// CAN related elements
settingsInt := settingsIni.ReadInteger('can', 'hardware', 0);
if settingsInt > FSettingsForm.cmbHardware.Items.Count then
settingsInt := 0;
FSettingsForm.cmbHardware.ItemIndex := settingsInt;
FSettingsForm.SetAvailableChannels;
settingsInt := settingsIni.ReadInteger('can', 'channel', 0);
if settingsInt >= FSettingsForm.cmbChannel.Items.Count then
settingsInt := 0;
FSettingsForm.cmbChannel.ItemIndex := settingsInt;
settingsInt := settingsIni.ReadInteger('can', 'baudrate', 1);
if settingsInt >= FSettingsForm.cmbBaudrate.Items.Count then
settingsInt := 1;
FSettingsForm.cmbBaudrate.ItemIndex := settingsInt;
FSettingsForm.chbExtendedId.Checked := settingsIni.ReadBool('can', 'extended', false);
FSettingsForm.edtTransmitId.Text := Format('%x',[settingsIni.ReadInteger('can', 'txid', $667)]);
FSettingsForm.edtReceiveId.Text := Format('%x',[settingsIni.ReadInteger('can', 'rxid', $7e1)]);
// XCP related elements
FSettingsForm.edtSeedKey.Text := settingsIni.ReadString('xcp', 'seedkey', '');
FSettingsForm.edtT1.Text := IntToStr(settingsIni.ReadInteger('xcp', 't1', 1000));
FSettingsForm.edtT3.Text := IntToStr(settingsIni.ReadInteger('xcp', 't3', 2000));
FSettingsForm.edtT4.Text := IntToStr(settingsIni.ReadInteger('xcp', 't4', 10000));
FSettingsForm.edtT5.Text := IntToStr(settingsIni.ReadInteger('xcp', 't5', 1000));
FSettingsForm.edtT7.Text := IntToStr(settingsIni.ReadInteger('xcp', 't7', 2000));
FSettingsForm.edtTconnect.Text := IntToStr(settingsIni.ReadInteger('xcp', 'tconnect', 20));
// release ini file object
settingsIni.Free;
end
else
begin
// set defaults
// CAN related elements
FSettingsForm.cmbHardware.ItemIndex := 0;
FSettingsForm.SetAvailableChannels;
FSettingsForm.cmbChannel.ItemIndex := 0;
FSettingsForm.cmbBaudrate.ItemIndex := 1;
FSettingsForm.chbExtendedId.Checked := false;
FSettingsForm.edtTransmitId.Text := Format('%x',[$667]);
FSettingsForm.edtReceiveId.Text := Format('%x',[$7e1]);
// XCP related elements
FSettingsForm.edtSeedKey.Text := '';
FSettingsForm.edtT1.Text := IntToStr(1000);
FSettingsForm.edtT3.Text := IntToStr(2000);
FSettingsForm.edtT4.Text := IntToStr(10000);
FSettingsForm.edtT5.Text := IntToStr(1000);
FSettingsForm.edtT7.Text := IntToStr(2000);
FSettingsForm.edtTconnect.Text := IntToStr(20);
end;
// show the form as modal so we can get the result here
if FSettingsForm.ShowModal = mrOK then
begin
if FIniFile <> '' then
begin
// create ini file object
settingsIni := TIniFile.Create(FIniFile);
// CAN related elements
settingsIni.WriteInteger('can', 'hardware', FSettingsForm.cmbHardware.ItemIndex);
settingsIni.WriteInteger('can', 'channel', FSettingsForm.cmbChannel.ItemIndex);
settingsIni.WriteInteger('can', 'baudrate', FSettingsForm.cmbBaudrate.ItemIndex);
settingsIni.WriteBool('can', 'extended', FSettingsForm.chbExtendedId.Checked);
settingsIni.WriteInteger('can', 'txid', StrToInt('$'+FSettingsForm.edtTransmitId.Text));
settingsIni.WriteInteger('can', 'rxid', StrToInt('$'+FSettingsForm.edtReceiveId.Text));
// XCP related elements
settingsIni.WriteString('xcp', 'seedkey', FSettingsForm.edtSeedKey.Text);
settingsIni.WriteInteger('xcp', 't1', StrToInt(FSettingsForm.edtT1.Text));
settingsIni.WriteInteger('xcp', 't3', StrToInt(FSettingsForm.edtT3.Text));
settingsIni.WriteInteger('xcp', 't4', StrToInt(FSettingsForm.edtT4.Text));
settingsIni.WriteInteger('xcp', 't5', StrToInt(FSettingsForm.edtT5.Text));
settingsIni.WriteInteger('xcp', 't7', StrToInt(FSettingsForm.edtT7.Text));
settingsIni.WriteInteger('xcp', 'tconnect', StrToInt(FSettingsForm.edtTconnect.Text));
// release ini file object
settingsIni.Free;
// indicate that the settings where successfully updated
result := true;
end;
end;
end; //*** end of Configure ***
end.
//******************************** end of XcpSettings.pas *******************************

View File

@ -0,0 +1,281 @@
unit XcpTransport;
//***************************************************************************************
// Description: XCP transport layer for CAN.
// File Name: XcpTransport.pas
//
//---------------------------------------------------------------------------------------
// C O P Y R I G H T
//---------------------------------------------------------------------------------------
// Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved
//
// This software has been carefully tested, but is not guaranteed for any particular
// purpose. The author does not offer any warranties and does not guarantee the accuracy,
// adequacy, or completeness of the software and is not responsible for any errors or
// omissions or the results obtained from use of the software.
//
//---------------------------------------------------------------------------------------
// L I C E N S E
//---------------------------------------------------------------------------------------
// This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option) any later
// version.
//
// OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.
//
// You have received a copy of the GNU General Public License along with OpenBLT. It
// should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy.
//
//***************************************************************************************
interface
//***************************************************************************************
// Includes
//***************************************************************************************
uses
Windows, Messages, SysUtils, Classes, Forms, IniFiles;
//***************************************************************************************
// Global Constants
//***************************************************************************************
// a CAN message can only have up to 8 bytes
const kMaxPacketSize = 8;
//***************************************************************************************
// Type Definitions
//***************************************************************************************
type
TKvaserHardware = ( KVASER_LEAFLIGHT_V2 = $01 );
TXcpTransport = class(TObject)
private
packetTxId : LongWord;
packetRxId : LongWord;
extendedId : Boolean;
canHardware : TKvaserHardware; { KVASER_xxx }
canChannel : Word; { currently supported is 1..8 }
canBaudrate : LongWord; { in bits/sec }
connected : Boolean;
public
packetData : array[0..kMaxPacketSize-1] of Byte;
packetLen : Word;
constructor Create;
procedure Configure(iniFile : string);
function Connect: Boolean;
function SendPacket(timeOutms: LongWord): Boolean;
function IsComError: Boolean;
procedure Disconnect;
destructor Destroy; override;
end;
implementation
//***************************************************************************************
// NAME: Create
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Class constructore
//
//***************************************************************************************
constructor TXcpTransport.Create;
begin
// call inherited constructor
inherited Create;
// 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;
end; //*** end of Create ***
//***************************************************************************************
// NAME: Destroy
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Class destructor
//
//***************************************************************************************
destructor TXcpTransport.Destroy;
begin
// call inherited destructor
inherited;
end; //*** end of Destroy ***
//***************************************************************************************
// NAME: Configure
// PARAMETER: filename of the INI
// RETURN VALUE: none
// DESCRIPTION: Configures both this class from the settings in the INI.
//
//***************************************************************************************
procedure TXcpTransport.Configure(iniFile : string);
var
settingsIni : TIniFile;
baudrateIdx : Integer;
const
baudrateLookupTable : array[0..7] of LongWord =
(
// list baudrates in the same order as they appear in the combobox on the settings
// form. this way the combobox's ItemIndex property can be used as an indexer to this
// array.
1000000, 500000, 250000, 125000, 100000, 83333, 50000, 10000
);
begin
// read XCP configuration from INI
if FileExists(iniFile) then
begin
// create ini file object
settingsIni := TIniFile.Create(iniFile);
// set hardware configuration
case settingsIni.ReadInteger('can', 'hardware', 0) of
0: canHardware := KVASER_LEAFLIGHT_V2;
else
canHardware := KVASER_LEAFLIGHT_V2;
end;
// set channel configuration
canChannel := settingsIni.ReadInteger('can', 'channel', 0) + 1;
// set baudrate configuration
baudrateIdx := settingsIni.ReadInteger('can', 'baudrate', 1);
canBaudrate := 500000;
if (baudrateIdx >= 0) and (baudrateIdx < Length(baudrateLookupTable)) then
canBaudrate := baudrateLookupTable[baudrateIdx];
// set message configuration
packetTxId := settingsIni.ReadInteger('can', 'txid', $667);
packetRxId := settingsIni.ReadInteger('can', 'rxid', $7e1);
extendedId := settingsIni.ReadBool('can', 'extended', false);
// release ini file object
settingsIni.Free;
end;
end; //*** end of Configure ***
//***************************************************************************************
// NAME: Connect
// PARAMETER: none
// RETURN VALUE: True if successful, False otherwise.
// DESCRIPTION: Connects the transport layer device.
//
//***************************************************************************************
function TXcpTransport.Connect: Boolean;
begin
// init result value
result := false;
// disconnect first if still connected
if connected then
Disconnect;
//##Vg TODO connect to the CAN hardware interface and update the connected flag
connected := false;
end; //*** end of Connect ***
//***************************************************************************************
// NAME: IsComError
// PARAMETER: none
// RETURN VALUE: True if in error state, False otherwise.
// DESCRIPTION: Determines if the communication interface is in an error state.
//
//***************************************************************************************
function TXcpTransport.IsComError: Boolean;
begin
// init result to no error.
result := false;
// check for bus off error if connected
if connected then
begin
//##Vg TODO check for bus off and possible bus heavy if available
end;
end; //*** end of IsComError ***
//***************************************************************************************
// NAME: SendPacket
// PARAMETER: the time[ms] allowed for the reponse from the slave to come in.
// RETURN VALUE: True if response received from slave, False otherwise
// DESCRIPTION: Sends the XCP packet using the data in 'packetData' and length in
// 'packetLen' and waits for the response to come in.
//
//***************************************************************************************
function TXcpTransport.SendPacket(timeOutms: LongWord): Boolean;
var
responseReceived: Boolean;
timeoutTime: DWORD;
begin
// initialize the result value
result := false;
// do not send data when the packet length is invalid or when not connected
// to the CAN hardware
if (packetLen > kMaxPacketSize) or (not connected) then
begin
Exit;
end;
//##Vg TODO prepare the packet for transmission in a CAN message
//##Vg transmit the packet via CAN and Exit if not possible
// reset flag and set the reception timeout time
responseReceived := false;
timeoutTime := GetTickCount + timeOutms;
// 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
// give the application a chance to use the processor
Application.ProcessMessages;
until (GetTickCount > timeoutTime) or (responseReceived);
// check if the response was correctly received
if responseReceived then
begin
//##Vg copy the response for futher processing (packetLen and packetData)
// success
result := true;
end;
end; //*** end of SendPacket ***
//***************************************************************************************
// NAME: Disconnect
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Disconnects the transport layer device.
//
//***************************************************************************************
procedure TXcpTransport.Disconnect;
begin
// disconnect CAN interface if connected
if connected then
begin
//##Vg TODO disconnect from the CAN hardware interface
end;
connected := false;
end; //*** end of Disconnect ***
end.
//******************************** end of XcpTransport.pas ******************************

View File

@ -0,0 +1,694 @@
library openblt_can_kvaser;
//***************************************************************************************
// Project Name: MicroBoot Interface for Delphi
// Description: XCP - CAN interface for MicroBoot supporting Kvaser Leaf Light v2
// File Name: openblt_can_kvaser.dpr
//
//---------------------------------------------------------------------------------------
// C O P Y R I G H T
//---------------------------------------------------------------------------------------
// Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved
//
// This software has been carefully tested, but is not guaranteed for any particular
// purpose. The author does not offer any warranties and does not guarantee the accuracy,
// adequacy, or completeness of the software and is not responsible for any errors or
// omissions or the results obtained from use of the software.
//
//---------------------------------------------------------------------------------------
// L I C E N S E
//---------------------------------------------------------------------------------------
// This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option) any later
// version.
//
// OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.
//
// You have received a copy of the GNU General Public License along with OpenBLT. It
// should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy.
//
//***************************************************************************************
//***************************************************************************************
// Includes
//***************************************************************************************
uses
Windows,
Messages,
Graphics,
Controls,
Forms,
Dialogs,
SysUtils,
Classes,
Extctrls,
XcpProtection in '..\..\XcpProtection.pas',
XcpLoader in '..\..\XcpLoader.pas',
XcpTransport in 'XcpTransport.pas',
XcpSettings in 'XcpSettings.pas' {XcpSettingsForm},
FirmwareData in '..\..\..\..\Library\FirmwareData\pas\FirmwareData.pas';
//***************************************************************************************
// Global Constants
//***************************************************************************************
const kMaxProgLen = 256; // maximum number of bytes to progam at one time
//***************************************************************************************
// Type Definitions
//***************************************************************************************
// DLL Interface Callbacks - modifications requires potential update of all interfaces!
type
TStartedEvent = procedure(length: Longword) of object;
TProgressEvent = procedure(progress: Longword) of object;
TDoneEvent = procedure of object;
TErrorEvent = procedure(error: ShortString) of object;
TLogEvent = procedure(info: ShortString) of object;
TInfoEvent = procedure(info: ShortString) of object;
type
TEventHandlers = class // create a dummy class
procedure OnTimeout(Sender: TObject);
end;
//***************************************************************************************
// Global Variables
//***************************************************************************************
var
//--- begin of don't change ---
AppOnStarted : TStartedEvent;
AppOnProgress : TProgressEvent;
AppOnDone : TDoneEvent;
AppOnError : TErrorEvent;
AppOnLog : TLogEvent;
AppOnInfo : TInfoEvent;
//--- end of don't change ---
timer : TTimer;
events : TEventHandlers;
loader : TXcpLoader;
datafile : TFirmwareData;
progdata : array of Byte;
progfile : string;
stopRequest : boolean;
//***************************************************************************************
// NAME: MbiCallbackOnStarted
// PARAMETER: length of the file that is being downloaded.
// RETURN VALUE: none
// DESCRIPTION: Wrapper function for safely calling an application callback
//
//***************************************************************************************
procedure MbiCallbackOnStarted(length: Longword);
begin
if Assigned(AppOnStarted) then
begin
AppOnStarted(length);
end;
end; //** end of MbiCallbackOnStarted ***
//***************************************************************************************
// NAME: MbiCallbackOnProgress
// PARAMETER: progress of the file download.
// RETURN VALUE: none
// DESCRIPTION: Wrapper function for safely calling an application callback
//
//***************************************************************************************
procedure MbiCallbackOnProgress(progress: Longword);
begin
if Assigned(AppOnProgress) then
begin
AppOnProgress(progress);
end;
end; //** end of MbiCallbackOnProgress ***
//***************************************************************************************
// NAME: MbiCallbackOnDone
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Wrapper function for safely calling an application callback
//
//***************************************************************************************
procedure MbiCallbackOnDone;
begin
if Assigned(AppOnDone) then
begin
AppOnDone;
end;
end; //** end of MbiCallbackOnDone ***
//***************************************************************************************
// NAME: MbiCallbackOnError
// PARAMETER: info about the error that occured.
// RETURN VALUE: none
// DESCRIPTION: Wrapper function for safely calling an application callback
//
//***************************************************************************************
procedure MbiCallbackOnError(error: ShortString);
begin
if Assigned(AppOnError) then
begin
AppOnError(error);
end;
end; //** end of MbiCallbackOnError ***
//***************************************************************************************
// NAME: MbiCallbackOnLog
// PARAMETER: info on the log event.
// RETURN VALUE: none
// DESCRIPTION: Wrapper function for safely calling an application callback
//
//***************************************************************************************
procedure MbiCallbackOnLog(info: ShortString);
begin
if Assigned(AppOnLog) then
begin
AppOnLog(info);
end;
end; //** end of MbiCallbackOnLog ***
//***************************************************************************************
// NAME: MbiCallbackOnInfo
// PARAMETER: details on the info event.
// RETURN VALUE: none
// DESCRIPTION: Wrapper function for safely calling an application callback
//
//***************************************************************************************
procedure MbiCallbackOnInfo(info: ShortString);
begin
if Assigned(AppOnInfo) then
begin
AppOnInfo(info);
end;
end; //** end of MbiCallbackOnLog ***
//***************************************************************************************
// NAME: LogData
// PARAMETER: pointer to byte array and the data length
// RETURN VALUE: none
// DESCRIPTION: Writes the program data formatted to the logfile
//
//***************************************************************************************
procedure LogData(data : PByteArray; len : longword); stdcall;
var
currentWriteCnt : byte;
cnt : byte;
logStr : string;
bufferOffset : longword;
begin
bufferOffset := 0;
while len > 0 do
begin
// set the current write length optimized to log 32 bytes per line
currentWriteCnt := len mod 32;
if currentWriteCnt = 0 then currentWriteCnt := 32;
logStr := '';
// prepare the line to add to the log
for cnt := 0 to currentWriteCnt-1 do
begin
logStr := logStr + Format('%2.2x ', [data[bufferOffset+cnt]]);
end;
// update the log
MbiCallbackOnLog(ShortString(logStr));
// update loop variables
len := len - currentWriteCnt;
bufferOffset := bufferOffset + currentWriteCnt;
end;
end; //*** end of LogData ***
//***************************************************************************************
// NAME: OnTimeout
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Timer event handler. A timer is used in this example to simulate the
// progress of a file download. It also demonstrates how to use the
// application callbacks to keep the application informed.
//
//***************************************************************************************
procedure TEventHandlers.OnTimeout(Sender: TObject);
var
errorInfo : string;
progress : longword;
segmentCnt : longword;
byteCnt : longword;
currentWriteCnt : word;
sessionStartResult : byte;
bufferOffset : longword;
addr : longword;
len : longword;
dataSizeKB : real;
dataSizeBytes : integer;
begin
timer.Enabled := False;
// connect the transport layer
MbiCallbackOnInfo('Connecting to the CAN interface.');
MbiCallbackOnLog('Connecting to the CAN interface. t='+ShortString(TimeToStr(Time)));
Application.ProcessMessages;
if not loader.Connect then
begin
// update the user info
MbiCallbackOnError('Could not connect to CAN interface. Check your configuration.');
MbiCallbackOnLog('Could not connect to CAN interface. Check your configuration and try again. t='+ShortString(TimeToStr(Time)));
Exit;
end;
//---------------- start the programming session --------------------------------------
MbiCallbackOnLog('Starting the programming session. t='+ShortString(TimeToStr(Time)));
// try initial connect via XCP. if the user program is able to reactivate the bootloader
// it will do so now
sessionStartResult := loader.StartProgrammingSession;
if sessionStartResult = kProgSessionUnlockError then
begin
MbiCallbackOnLog('Security issue. Could not unprotect the programming resource. Check your configured XCP protection DLL. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Security issue. Could not unprotect the programming resource.');
loader.Disconnect;
Exit;
end;
// try initial connect via XCP
if sessionStartResult <> kProgSessionStarted then
begin
// update the user info
MbiCallbackOnInfo('Could not connect. Retrying. Reset your target if this takes a long time.');
MbiCallbackOnLog('Connect failed. Switching to backdoor entry mode. t='+ShortString(TimeToStr(Time)));
Application.ProcessMessages;
// possible that the bootloader is being activated, which means that the target's
// CAN controller is being reinitialized. We should not send any data on the CAN
// network for this to finish. 200ms should do it. note that the backdoor entry time
// should be at least 2.5x this.
Sleep(200);
// continuously try to connect via XCP true the backdoor
sessionStartResult := kProgSessionGenericError;
while sessionStartResult <> kProgSessionStarted do
begin
sessionStartResult := loader.StartProgrammingSession;
Application.ProcessMessages;
Sleep(5);
// if the hardware is in reset or otherwise does not have the CAN controller synchronized to
// the CAN bus, we will be generating error frames, possibly leading to a bus off.
// check for this
if loader.IsComError then
begin
// bus off state, so try to recover.
MbiCallbackOnLog('Communication error detected. Trying automatic recovery. t='+ShortString(TimeToStr(Time)));
loader.Disconnect;
if not loader.Connect then
begin
MbiCallbackOnLog('Could not connect to CAN interface. Check your configuration and try again. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Could not connect to CAN interface. Check your configuration.');
Exit;
end;
Sleep(200);
end;
// don't retry if the error was caused by not being able to unprotect the programming resource
if sessionStartResult = kProgSessionUnlockError then
begin
MbiCallbackOnLog('Security issue. Could not unprotect the programming resource. Check your configured XCP protection DLL. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Security issue. Could not unprotect the programming resource.');
Exit;
end;
// check if the user cancelled
if stopRequest then
begin
// disconnect the transport layer
MbiCallbackOnLog('Disconnecting the transport layer. t='+ShortString(TimeToStr(Time)));
loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.');
Exit;
end;
end;
end;
// still here so programming session was started
MbiCallbackOnLog('Programming session started. t='+ShortString(TimeToStr(Time)));
// read the firmware file
MbiCallbackOnInfo('Reading firmware file.');
MbiCallbackOnLog('Reading firmware file. t='+ShortString(TimeToStr(Time)));
// create the datafile object and load the file contents
datafile := TFirmwareData.Create;
if not datafile.LoadFromFile(progfile, False) then
begin
MbiCallbackOnLog('Could not read firmware file (' + ShortString(ExtractFilename(progfile)) +'). t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Could not read firmware file (' + ShortString(ExtractFilename(progfile)) +').');
datafile.Free;
Exit;
end;
// compute the size in kbytes
dataSizeBytes := 0;
// loop through all segment to get the total byte count
for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin
dataSizeBytes := dataSizeBytes + datafile.Segment[segmentCnt].Size;
end;
// convert bytes to kilobytes
dataSizeKB := dataSizeBytes / 1024;
// Call application callback when we start the actual download
MbiCallbackOnStarted(dataSizeBytes);
// Init progress to 0 progress
progress := 0;
MbiCallbackOnProgress(progress);
//---------------- next clear the memory regions --------------------------------------
// update the user info
MbiCallbackOnInfo('Erasing memory...');
for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin
// check if the user cancelled
if stopRequest then
begin
// disconnect the transport layer
MbiCallbackOnLog('Disconnecting the transport layer. t='+ShortString(TimeToStr(Time)));
loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.');
datafile.Free;
Exit;
end;
// obtain the region info
addr := datafile.Segment[segmentCnt].BaseAddress;
len := datafile.Segment[segmentCnt].Size;
// erase the memory
MbiCallbackOnLog('Clearing Memory '+ShortString(Format('addr:0x%x,len:0x%x',[addr,len]))+'. t='+ShortString(TimeToStr(Time)));
if not loader.ClearMemory(addr, len) then
begin
loader.GetLastError(errorInfo);
MbiCallbackOnLog('Could not clear memory ('+ShortString(errorInfo)+'). t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Could not clear memory ('+ShortString(errorInfo)+').');
datafile.Free;
Exit;
end;
MbiCallbackOnLog('Memory cleared. t='+ShortString(TimeToStr(Time)));
end;
//---------------- next program the memory regions ------------------------------------
for segmentCnt := 0 to (datafile.SegmentCount - 1) do
begin
// update the user info
MbiCallbackOnInfo('Reading file...');
// obtain the region info
addr := datafile.Segment[segmentCnt].BaseAddress;
len := datafile.Segment[segmentCnt].Size;
SetLength(progdata, len);
for byteCnt := 0 to (len - 1) do
begin
progdata[byteCnt] := datafile.Segment[segmentCnt].Data[byteCnt];
end;
bufferOffset := 0;
while len > 0 do
begin
// check if the user cancelled
if stopRequest then
begin
// disconnect the transport layer
MbiCallbackOnLog('Disconnecting the transport layer. t='+ShortString(TimeToStr(Time)));
loader.Disconnect;
MbiCallbackOnLog('Programming session cancelled by user. t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Programming session cancelled by user.');
datafile.Free;
Exit;
end;
// set the current write length taking into account kMaxProgLen
currentWriteCnt := len mod kMaxProgLen;
if currentWriteCnt = 0 then currentWriteCnt := kMaxProgLen;
// program the data
MbiCallbackOnLog('Programming Data '+ShortString(Format('addr:0x%x,len:0x%x',[addr,currentWriteCnt]))+'. t='+ShortString(TimeToStr(Time)));
LogData(@progdata[bufferOffset], currentWriteCnt);
if not loader.WriteData(addr, currentWriteCnt, @progdata[bufferOffset]) then
begin
loader.GetLastError(errorInfo);
MbiCallbackOnLog('Could not program data ('+ShortString(errorInfo)+'). t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Could not program data ('+ShortString(errorInfo)+').');
datafile.Free;
Exit;
end;
MbiCallbackOnLog('Data Programmed. t='+ShortString(TimeToStr(Time)));
// update progress
progress := progress + currentWriteCnt;
MbiCallbackOnProgress(progress);
// update loop variables
len := len - currentWriteCnt;
addr := addr + currentWriteCnt;
bufferOffset := bufferOffset + currentWriteCnt;
// update the user info
MbiCallbackOnInfo('Programming data... ' + ShortString(Format('(%.1n of %.1n Kbytes)',[(progress/1024), dataSizeKB])));
end;
end;
//---------------- stop the programming session ---------------------------------------
MbiCallbackOnLog('Stopping the programming session. t='+ShortString(TimeToStr(Time)));
if not loader.StopProgrammingSession then
begin
loader.GetLastError(errorInfo);
MbiCallbackOnLog('Could not stop the programming session ('+ShortString(errorInfo)+'). t='+ShortString(TimeToStr(Time)));
MbiCallbackOnError('Could not stop the programming session ('+ShortString(errorInfo)+').');
datafile.Free;
Exit;
end;
MbiCallbackOnLog('Programming session stopped. t='+ShortString(TimeToStr(Time)));
// all done so set progress to 100% and finish up
progress := dataSizeBytes;
datafile.Free;
MbiCallbackOnProgress(progress);
MbiCallbackOnLog('File successfully downloaded t='+ShortString(TimeToStr(Time)));
MbiCallbackOnDone;
end; //*** end of OnTimeout ***
//***************************************************************************************
// NAME: MbiInit
// PARAMETER: callback function pointers
// RETURN VALUE: none
// DESCRIPTION: Called by the application to initialize the interface library.
//
//***************************************************************************************
procedure MbiInit(cbStarted: TStartedEvent; cbProgress: TProgressEvent;
cbDone: TDoneEvent; cbError: TErrorEvent; cbLog: TLogEvent;
cbInfo: TInfoEvent); stdcall;
begin
//--- begin of don't change ---
AppOnStarted := cbStarted;
AppOnProgress := cbProgress;
AppOnDone := cbDone;
AppOnLog := cbLog;
AppOnInfo := cbInfo;
AppOnError := cbError;
//--- end of don't change ---
// create xcp loader object
loader := TXcpLoader.Create;
// update to the latest configuration
loader.Configure(ExtractFilePath(ParamStr(0))+'openblt_can_kvaser.ini');
// create and init a timer
events := TEventHandlers.Create;
timer := TTimer.Create(nil);
timer.Enabled := False;
timer.Interval := 100;
timer.OnTimer := events.OnTimeout;
end; //*** end of MbiInit ***
//***************************************************************************************
// NAME: MbiStart
// PARAMETER: filename of the file that is to be downloaded.
// RETURN VALUE: none
// DESCRIPTION: Called by the application to request the interface library to download
// the file that is passed as a parameter.
//
//***************************************************************************************
procedure MbiStart(fileName: ShortString); stdcall;
begin
// update the user info
MbiCallbackOnInfo('');
// start the log
MbiCallbackOnLog('--- Downloading "'+fileName+'" ---');
// reset stop request
stopRequest := false;
// start the startup timer which gives microBoot a chance to paint itself
timer.Enabled := True;
// store the program's filename
progfile := String(fileName);
end; //*** end of MbiStart ***
//***************************************************************************************
// NAME: MbiStop
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Called by the application to request the interface library to stop
// a download that could be in progress.
//
//***************************************************************************************
procedure MbiStop; stdcall;
begin
// set stop request
stopRequest := true;
end; //*** end of MbiStop ***
//***************************************************************************************
// NAME: MbiDeInit
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Called by the application to uninitialize the interface library.
//
//***************************************************************************************
procedure MbiDeInit; stdcall;
begin
// release xcp loader object
loader.Free;
// release the timer and events object
timer.Free;
events.Free;
//--- begin of don't change ---
AppOnStarted := nil;
AppOnProgress := nil;
AppOnDone := nil;
AppOnLog := nil;
AppOnInfo := nil;
AppOnError := nil;
//--- end of don't change ---
end; //*** end of MbiDeInit ***
//***************************************************************************************
// NAME: MbiName
// PARAMETER: none
// RETURN VALUE: name of the interface library
// DESCRIPTION: Called by the application to obtain the name of the interface library.
//
//***************************************************************************************
function MbiName : ShortString; stdcall;
begin
Result := 'OpenBLT CAN Kvaser';
end; //*** end of MbiName ***
//***************************************************************************************
// NAME: MbiDescription
// PARAMETER: none
// RETURN VALUE: description of the interface library
// DESCRIPTION: Called by the application to obtain the description of the interface
// library.
//
//***************************************************************************************
function MbiDescription : ShortString; stdcall;
begin
Result := 'OpenBLT using Kvaser CAN Interface';
end; //*** end of MbiDescription ***
//***************************************************************************************
// NAME: MbiVersion
// PARAMETER: none
// RETURN VALUE: version number
// DESCRIPTION: Called by the application to obtain the version number of the
// interface library.
//
//***************************************************************************************
function MbiVersion : Longword; stdcall;
begin
Result := 10100; // v1.01.00
end; //*** end of MbiVersion ***
//***************************************************************************************
// NAME: MbiVInterface
// PARAMETER: none
// RETURN VALUE: version number of the supported interface
// DESCRIPTION: Called by the application to obtain the version number of the
// Mbi interface uBootInterface.pas (not the interface library). This can
// be used by the application for backward compatibility.
//
//***************************************************************************************
function MbiVInterface : Longword; stdcall;
begin
Result := 10001; // v1.00.01
end; //*** end of MbiVInterface ***
//***************************************************************************************
// NAME: MbiConfigure
// PARAMETER: none
// RETURN VALUE: none
// DESCRIPTION: Called by the application to enable the user to configure the inter-
// face library through the application.
//
//***************************************************************************************
procedure MbiConfigure; stdcall;
var
settings : TXcpSettings;
begin
// create xcp settings object
settings := TXcpSettings.Create(ExtractFilePath(ParamStr(0))+'openblt_can_kvaser.ini');
// display the modal configuration dialog
settings.Configure;
// release the xcp settings object
settings.Free;
// update to the latest configuration
loader.Configure(ExtractFilePath(ParamStr(0))+'openblt_can_kvaser.ini');
end; //*** end of MbiConfigure ***
//***************************************************************************************
// External Declarations
//***************************************************************************************
exports
//--- begin of don't change ---
MbiInit,
MbiStart,
MbiStop,
MbiDeInit,
MbiName,
MbiDescription,
MbiVersion,
MbiConfigure,
MbiVInterface;
//--- end of don't change ---
end.
//********************************** end of openblt_can_kvaser.dpr **********************

View File

@ -0,0 +1,120 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{C587575B-3E1C-4EA4-BB4F-912B83127DCE}</ProjectGuid>
<MainSource>openblt_can_kvaser.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Library</AppType>
<FrameworkType>VCL</FrameworkType>
<ProjectVersion>18.2</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_N>true</DCC_N>
<DCC_ExeOutput>../../../../../</DCC_ExeOutput>
<SanitizedProjectName>openblt_can_kvaser</SanitizedProjectName>
<DCC_SymbolReferenceInfo>1</DCC_SymbolReferenceInfo>
<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_Alignment>1</DCC_Alignment>
<DCC_E>false</DCC_E>
<DCC_K>false</DCC_K>
<DCC_F>false</DCC_F>
<GenDll>true</GenDll>
<DCC_UsePackage>Vcl40;Vclx40;Vcldb40;vcldbx40;VclSmp40;Qrpt40;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_WriteableConstants>true</DCC_WriteableConstants>
<VerInfo_Locale>1031</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<DCC_DebugInformation>1</DCC_DebugInformation>
<DCC_S>false</DCC_S>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileVersion=1.1.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.1.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName)</VerInfo_Keys>
<VerInfo_MinorVer>1</VerInfo_MinorVer>
<Debugger_HostApplication>C:\Work\software\OpenBLT\Host\MicroBoot.exe</Debugger_HostApplication>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<Manifest_File>(None)</Manifest_File>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="..\..\XcpProtection.pas"/>
<DCCReference Include="..\..\XcpLoader.pas"/>
<DCCReference Include="XcpTransport.pas"/>
<DCCReference Include="XcpSettings.pas">
<Form>XcpSettingsForm</Form>
</DCCReference>
<DCCReference Include="..\..\..\..\Library\FirmwareData\pas\FirmwareData.pas"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">openblt_can_kvaser.dpr</Source>
</Source>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

BIN
Host/openblt_can_kvaser.dll Normal file

Binary file not shown.

View File

@ -0,0 +1,15 @@
[can]
hardware=0
channel=0
baudrate=1
extended=0
txid=1639
rxid=2017
[xcp]
seedkey=
t1=1000
t3=2000
t4=10000
t5=1000
t7=2000
tconnect=20