- Added automatic bus off recovery to the Peak CAN communication interface for Microboot.

git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@99 5dc33758-31d5-4daf-9ae8-b24bf3d40d73
This commit is contained in:
Frank Voorburg 2014-07-23 08:27:06 +00:00
parent 3f4bc7dd69
commit 706e582e63
5 changed files with 126 additions and 37 deletions

Binary file not shown.

View File

@ -357,6 +357,7 @@ begin
if CAN_Init(Baudcode, MsgType) <> CAN_ERR_OK then Exit;
//-------------------------- open the acceptance filter --------------------------------
if CAN_ResetFilter <> CAN_ERR_OK then
begin
@ -470,8 +471,19 @@ begin
// submit the transmit request
if CAN_Write(msg) <> CAN_ERR_OK then
begin
Result := False;
exit;
// the Peak CAN interface has a bug because if it is the only node on the bus
// transmitting a message, it will actually go in bus off, which is not allowed
// according to the CAN protocol. this scenario can be resolved by re-initializing
// the CAN interface.
if (CAN_Status and CAN_ERR_BUSOFF) = CAN_ERR_BUSOFF then
begin
Disconnect;
if not Connect then
begin
Result := False;
exit;
end;
end;
end;
//---------------- process transmission confirmation --------------------------

View File

@ -2,20 +2,16 @@
// PCAN-Light
// PCAN_USB.pas
//
// Version 1.5
// Version 2.x
//
// ~~~~~~~~~~
//
// Basic Idea:
//
// ~~~~~~~~~~
//
// Definition of the PCAN-Light API.
// The Driver support a Hardware and a Software who want to communicate with CAN-busses
// Definition of the PCAN-Light API.
// The Driver support a Hardware and a Software who want to communicate with CAN-busses
//
// ~~~~~~~~~~~~
//
// PCAN-Light -API
// PCAN-Light-API
//
// ~~~~~~~~~~~~
//
@ -24,21 +20,25 @@
// - CAN_Status()
// - CAN_Write(var MsgBuff: TPCANMsg)
// - CAN_Read(var MsgBuff: TPCANMsg)
// - CAN_ReadEx(var MsgBuff: TPCANMsg; var RcvTime: TPCANTimestamp)
// - CAN_VersionInfo(lpszTextBuff: PChar)
// - CAN_DLLVersionInfo(lpszTextBuff: PChar)
// - CAN_SpecialFunktion(distributorcode: LongWord; codenumber: Integer)
// - CAN_ResetClient()
// - CAN_MsgFilter(FromID, ToID: LongWord; _Type: Integer)
// - CAN_ResetFilter()
// - SetUSBDeviceNr(DevNum: Longint)
// - GetUSBDeviceNr(var DevNum: Longint)
// - SetUSBDeviceNr(DevNum: Integer)
// - GetUSBDeviceNr(var DevNum: Integer)
// - CAN_SetRcvFunc(hEvent: THandle)
//
// ------------------------------------------------------------------
// Author : Hoppe, Wilhelm
// Modified By: Wagner (13.08.2008)
// Modified By: Wagner (29.09.2009)
//
// Sprache: PASCAL OO
// Language: PASCAL OO
// ------------------------------------------------------------------
//
// Copyright (C) 1999-2006 PEAK-System Technik GmbH, Darmstadt
// Copyright (C) 1999-2009 PEAK-System Technik GmbH, Darmstadt
//
unit pcan_usb;
@ -79,23 +79,30 @@ const
// Error codes (bit code)
//
CAN_ERR_OK = $0000; // No error
CAN_ERR_XMTFULL = $0001; // Transmit buffer in CAN controller is full
CAN_ERR_OVERRUN = $0002; // CAN controller was read too late
CAN_ERR_BUSLIGHT = $0004; // Bus error: an error counter reached the 'light' limit
CAN_ERR_BUSHEAVY = $0008; // Bus error: an error counter reached the 'heavy' limit
CAN_ERR_BUSOFF = $0010; // Bus error: the CAN controller is in bus-off state
CAN_ERR_QRCVEMPTY = $0020; // Receive queue is empty
CAN_ERR_QOVERRUN = $0040; // Receive queue was read too late
CAN_ERR_QXMTFULL = $0080; // Transmit queue is full
CAN_ERR_REGTEST = $0100; // Test of the CAN controller hardware registers failed (no hardware found)
CAN_ERR_NOVXD = $0200; // Driver not loaded
CAN_ERR_RESOURCE = $2000; // Resource (FIFO, Client, timeout) cannot be created
CAN_ERR_ILLPARAMTYPE = $4000; // Invalid parameter
CAN_ERR_ILLPARAMVAL = $8000; // Invalid parameter value
CAN_ERRMASK_ILLHANDLE = $1C00; // Mask for all handle errors
CAN_ERR_ANYBUSERR = (CAN_ERR_BUSLIGHT or CAN_ERR_BUSHEAVY or CAN_ERR_BUSOFF);
// All further error conditions <> 0 please ask PEAK when required.......internal driver failure ........
CAN_ERR_OK = $0000; // No error
CAN_ERR_XMTFULL = $0001; // Transmit buffer in CAN controller is full
CAN_ERR_OVERRUN = $0002; // CAN controller was read too late
CAN_ERR_BUSLIGHT = $0004; // Bus error: an error counter reached the 'light' limit
CAN_ERR_BUSHEAVY = $0008; // Bus error: an error counter reached the 'heavy' limit
CAN_ERR_BUSOFF = $0010; // Bus error: the CAN controller is in bus-off state
CAN_ERR_QRCVEMPTY = $0020; // Receive queue is empty
CAN_ERR_QOVERRUN = $0040; // Receive queue was read too late
CAN_ERR_QXMTFULL = $0080; // Transmit queue ist full
CAN_ERR_REGTEST = $0100; // Test of the CAN controller hardware registers failed (no hardware found)
CAN_ERR_NOVXD = $0200; // Driver not loaded
CAN_ERR_NODRIVER = $0200; // Driver not loaded
CAN_ERRMASK_ILLHANDLE=$1C00; // Mask for all handle errors
CAN_ERR_HWINUSE = $0400; // Hardware already in use by a Net
CAN_ERR_NETINUSE = $0800; // a Client is already connected to the Net
CAN_ERR_ILLHW = $1400; // Hardware handle is invalid
CAN_ERR_ILLNET = $1800; // Net handle is invalid
CAN_ERR_ILLCLIENT = $1C00; // Client handle is invalid
CAN_ERR_RESOURCE = $2000; // Resource (FIFO, Client, timeout) cannot be created
CAN_ERR_ILLPARAMTYPE = $4000; // Invalid parameter
CAN_ERR_ILLPARAMVAL = $8000; // Invalid parameter value
CAN_ERR_UNKNOWN = $10000; // Unknown error
CAN_ERR_ANYBUSERR = (CAN_ERR_BUSLIGHT or CAN_ERR_BUSHEAVY or CAN_ERR_BUSOFF);
type
// CAN Message
@ -107,6 +114,15 @@ type
DATA: array[0..7] of Byte; // Data 0 .. 7
end;
// Timestamp of a receive/transmit event
// Total microseconds = micros + 1000 * millis + 0xFFFFFFFF * 1000 * millis_overflow
//
TPCANTimestamp = record
millis: LongWord; // Base-value: milliseconds: 0.. 2^32-1
millis_overflow: Word; // Roll-arounds of millis
micros: Word; // Microseconds: 0..999
end;
///////////////////////////////////////////////////////////////////////////////
// CAN_Init()
// This function make the following:
@ -123,7 +139,7 @@ type
// Possible Errors: NOVXD ILLHW REGTEST RESOURCE
//
function CAN_Init(wBTR0BTR1: Word;
CANMsgType: Integer): LongWord; stdcall;
CANMsgType: Integer): LongWord; stdcall;
///////////////////////////////////////////////////////////////////////////////
// CAN_Close()
@ -176,6 +192,37 @@ function CAN_Write(var MsgBuff: TPCANMsg): LongWord; stdcall;
//
function CAN_Read(var MsgBuff: TPCANMsg): LongWord; stdcall;
///////////////////////////////////////////////////////////////////////////////
// CAN_ReadEx()
// This function get the next message or the next error from the Receive Queue of
// the CAN Hardware and the time when the message arrived.
// REMARK:
// - Check always the type of the received Message (MSGTYPE_STANDARD,MSGTYPE_RTR,
// MSGTYPE_EXTENDED,MSGTYPE_STATUS)
// - The function will return ERR_OK always that you receive a CAN message successfully
// although if the messages is a MSGTYPE_STATUS message.
// - When a MSGTYPE_STATUS mesasge is got, the ID and Length information of the message
// will be treated as indefined values. Actually information of the received message
// should be interpreted using the first 4 data bytes as follow:
// * Data0 Data1 Data2 Data3 Kind of Error
// 0x00 0x00 0x00 0x02 CAN_ERR_OVERRUN 0x0002 CAN Controller was read to late
// 0x00 0x00 0x00 0x04 CAN_ERR_BUSLIGHT 0x0004 Bus Error: An error counter limit reached (96)
// 0x00 0x00 0x00 0x08 CAN_ERR_BUSHEAVY 0x0008 Bus Error: An error counter limit reached (128)
// 0x00 0x00 0x00 0x10 CAN_ERR_BUSOFF 0x0010 Bus Error: Can Controller went "Bus-Off"
// - If a CAN_ERR_BUSOFF status message is received, the CAN Controller must to be
// initialized again using the Init() function. Otherwise, will be not possible
// to send/receive more messages.
// - The message will be written to 'msgbuff'.
// Since Version 2.x the Ext. Version is available - new Parameter:
// - Receive timestamp
//
// Possible Errors: NOVXD QRCVEMPTY
//
function CAN_ReadEx(
var MsgBuff: TPCANMsg;
var RcvTime: TPCANTimestamp
): LongWord; stdcall;
///////////////////////////////////////////////////////////////////////////////
// CAN_VersionInfo()
// This function get the Version and copyright of the hardware as text
@ -187,6 +234,17 @@ function CAN_VersionInfo(
lpszTextBuff: PChar
): LongWord; stdcall;
///////////////////////////////////////////////////////////////////////////////
// CAN_DLLVersionInfo()
// This function is used to get the Version and copyright of the DLL as
// text (max. 255 characters)
//
// Possible Errors: -1 for NULL-Pointer parameters :-)
//
function CAN_DLLVersionInfo(
lpszTextBuff: PChar
): LongWord; stdcall;
///////////////////////////////////////////////////////////////////////////////
// CAN_SpecialFunktion()
// This function is an special function to be used "ONLY" for distributors
@ -241,7 +299,7 @@ function CAN_ResetFilter: LongWord; stdcall;
//
// Possible Errors: NOVXD ILLHW ILLPARAMTYPE ILLPARAMVAL REGTEST
//
function SetUSBDeviceNr(DevNum: Longint): LongWord; stdcall;
function SetUSBDeviceNr(DevNum: LongWord): LongWord; stdcall;
//////////////////////////////////////////////////////////////////////////////
// GetUSBDeviceNr()
@ -249,7 +307,16 @@ function SetUSBDeviceNr(DevNum: Longint): LongWord; stdcall;
//
// Possible Errors: NOVXD ILLHW ILLPARAMTYPE
//
function GetUSBDeviceNr(var DevNum: Longint): LongWord; stdcall;
function GetUSBDeviceNr(var DevNum: LongWord): LongWord; stdcall;
///////////////////////////////////////////////////////////////////////////////
// CAN_SetRcvEvent()
// This function is used to set the Event for the Event Handler
//
// Possible Errors: ILLCLIENT ILLPARAMTYPE ILLPARAMVAL NOVXD
//
function CAN_SetRcvEvent(hEvent: LongInt): LongWord; stdcall;
implementation
@ -272,9 +339,15 @@ external DLL_Name;
function CAN_Read(var MsgBuff: TPCANMsg): LongWord; stdcall;
external DLL_Name;
function CAN_ReadEx(var MsgBuff: TPCANMsg; var RcvTime: TPCANTimestamp): LongWord; stdcall;
external DLL_NAME;
function CAN_VersionInfo(lpszTextBuff: PChar): LongWord; stdcall;
external DLL_Name;
function CAN_DLLVersionInfo(lpszTextBuff: PChar): LongWord; stdcall;
external DLL_Name;
function CAN_SpecialFunktion(distributorcode: LongWord; codenumber: Integer): LongWord; stdcall;
external DLL_Name;
@ -287,10 +360,13 @@ external DLL_Name;
function CAN_ResetFilter: LongWord; stdcall;
external DLL_Name;
function SetUSBDeviceNr(DevNum: Longint): LongWord; stdcall;
function SetUSBDeviceNr(DevNum: LongWord): LongWord; stdcall;
external DLL_Name;
function GetUSBDeviceNr(var DevNum: Longint): LongWord; stdcall;
function GetUSBDeviceNr(var DevNum: LongWord): LongWord; stdcall;
external DLL_Name;
function CAN_SetRcvEvent(hEvent: LongInt):LongWord; stdcall;
external DLL_Name;
end.

View File

@ -313,6 +313,7 @@ begin
MbiCallbackOnProgress(progress);
//---------------- next clear the memory regions --------------------------------------
// update the user info
MbiCallbackOnInfo('Erasing memory...');

Binary file not shown.