# HG changeset patch # User Ian Tracy # Date 1379946007 14400 # Node ID e13fa74d169cbd3c34885afa3a94761ec067a79e # Parent b72a88dbc7c328a7b37eee410f0d1c735be7dde9 VCI3 driver added diff -r b72a88dbc7c3 -r e13fa74d169c drivers/can_ixxat_win32/can_ixxat_win.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_ixxat_win32/can_ixxat_win.c Mon Sep 23 10:20:07 2013 -0400 @@ -0,0 +1,428 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +/* + Wrapper Layer for CANFestival to interact with IXXAT VCI V3.X.X Drivers (vcisdk.lib) + Provides external references for win32 library see win32.c (CanFestival-3) + + http://www.ixxat.com/download_vci_v3_en.html + + Currently the VCI CAN driver for Windows supports the following IXXAT interfaces: + + PC-I 04/PCI + iPC-I 320/PCI II + iPC-I 165/PCI + iPC-I XC16/PCI + iPC-I XC16/PMC + iPC-I XC16/PCIe + USB-to-CAN compact + USB-to-CAN II + CAN-IB100/PCIe + CAN-IB200/PCIe + CAN-IB120/PCIe Mini + CAN-IB130/PCIe 104 + CAN-IB230/PCIe 104 + CAN@net II/VCI + CANblue II + FR-IB100/PCIe (only in combination with VCI V2.20) + tinCAN 161 + +*/ + + +/************************************************************************* +** +************************************************************************** +** +** File: can_ixxat_win32.c +** Summary: Wrapper to encapsulate handling of VCI3 +** Include vcisdk.lib +** +************************************************************************** +************************************************************************** +** +** Functions: canOpen_driver +** canReceive_driver +** TimerProc1 +** canClose_driver +** canSend_drive +** +**/ + +#include +#include "can_driver.h" +#include "def.h" +#include "winuser.h" + +// Include a path to the following header files provided with VCI V3.X.X +// ...sdk/Microsoft_VisualC/inc +#include "vcinpl.h" +#include "VCI3.h" +#include "vcitype.h" +#include "vciguid.h" +#include "vcierr.h" + + + +/************************************************************************ +** bus status polling cycle milliseconds +*************************************************************************/ +#define STATUS_POLLING_CYCLE 1000 + +/************************************************************************* +** function prototypes +*************************************************************************/ +void CALLBACK TimerProc1(void* lpParametar, BOOL TimerOrWaitFired ); +void Display_Error(HRESULT hResult); + + +/************************************************************************* +** static variables +*************************************************************************/ +static HANDLE hDevice; // device handle +static LONG lCtrlNo; // controller number +static HANDLE hCanCtl; // controller handle +static HANDLE hCanChn; // channel handle +static LONG lMustQuit = 0; // quit flag for the receive thread +static HANDLE hTimerHandle; // timer handle + +/************************************************************************* +** datatypes +*************************************************************************/ + +struct sLook_up_table +{ + char baud_rate[20]; + UINT8 bt0; + UINT8 bt1; +}; + +struct sInterface_lookup_table +{ + char board_num[10]; + UINT8 num; +}; + +/************************************************************************* +** +** Function : canOpen_driver +** +** Description : Initializes the Control and Message Channels +** Parameters : s_BOARD *board - pointer to board information +** Returnvalue : (CAN_HANDLE)board - handle for CAN controller +** +*************************************************************************/ +CAN_HANDLE __stdcall canOpen_driver(s_BOARD *board) +{ + HANDLE hEnumerator; // enumerator handle + VCIDEVICEINFO VCIDeviceInfo; // device info + HRESULT hResult; + int index, boardNum; + BOOL bResult; + + struct sLook_up_table sBitRate_lookup[9] = { + {"10K",0x31,0x1C}, + {"20K",0x18,0x1C}, + {"50K",0x09,0x1C}, + {"100K",0x04,0x1C}, + {"125K",0x03,0x1C}, + {"250K",0x01,0x1C}, + {"500K",0x00,0x1C}, + {"800K",0x00,0x16}, + {"1M",0x00,0x14}}; + + struct sInterface_lookup_table sInterfaceList[4]={ + {"vcan0",0}, + {"vcan1",1}, + {"vcan2",2}, + {"vcan3",3}}; + + for (boardNum =0 ; boardNum<4;boardNum++) // determine canline selected + { + if (strcmp(sInterfaceList[boardNum].board_num,board->busname )==0) + break; + } + + for (index = 0; index < 10; ++index) // determine baudrate + { + if (strcmp(sBitRate_lookup[index].baud_rate,board->baudrate)==0) + break; + } + + if (index == 9) + { + MSG_ERR_DRV("IXXAT::open: The given baudrate %S is invalid.", baud_rate); + return NULL ; + } + + + /* + ** The following can be used when the client has multiple CAN interfaces to slect from, and does not wish to use the + ** selection dialog box + /* + + /* + hResult= vciEnumDeviceOpen(&hEnumerator); + // This loop will increment the index of the device list and returns the decription of the CAN line chose by user + if (hResult== VCI_OK) + { + for (index1=0; index1 <= sInterfaceList[boardNum].num; index1++){ + hResult=vciEnumDeviceNext(hEnumerator, &VCIDeviceInfo); + } + } + printf("Device Selected: %s %s\n",VCIDeviceInfo.Manufacturer, VCIDeviceInfo.Description); + if (hResult== VCI_OK) + hResult=vciEnumDeviceClose(hEnumerator); + + if (hResult== VCI_OK) + hResult= vciDeviceOpen(&VCIDeviceInfo.VciObjectId, &hDevice); + */ + + + + /* + ** Display Interface Selection Dialog Box + */ + hResult= vciDeviceOpenDlg(0, &hDevice); + + /* + ** Establish and activate the message Channel + */ + if (hResult== VCI_OK) + hResult= canChannelOpen(hDevice, 0, TRUE, &hCanChn); + // Select Rx fifo size, Rx threshold, Tx fifo size, Tx threshold + if (hResult== VCI_OK) + hResult=canChannelInitialize( hCanChn, 1024, 1,128,1); + + if (hResult== VCI_OK) + hResult=canChannelActivate(hCanChn, TRUE); + + + /* + ** Establish and Activate the Contol Channel + */ + if (hResult== VCI_OK) + hResult=canControlOpen(hDevice, 0, &hCanCtl); + + // Select 11 or 29 bit IDs, Select operating mode + if (hResult== VCI_OK) + hResult=canControlInitialize( hCanCtl, CAN_OPMODE_STANDARD | CAN_OPMODE_ERRFRAME, sBitRate_lookup[index].bt0, sBitRate_lookup[index].bt1 ); + + + // With VCI it is possible to filter IDs, See VCI V3 manual. The following will accept all IDs + if (hResult== VCI_OK) + hResult= canControlSetAccFilter( hCanCtl, FALSE, CAN_ACC_CODE_ALL, CAN_ACC_MASK_ALL); + + if (hResult== VCI_OK) + hResult=canControlStart(hCanCtl, TRUE); + + if (hResult!=VCI_OK) + { + Display_Error(hResult); + return NULL; + } + + + /* + ** Create timer to poll bus status + */ + bResult= CreateTimerQueueTimer( + & hTimerHandle, + NULL, + TimerProc1, // Callback function + NULL, + 0, + STATUS_POLLING_CYCLE, + WT_EXECUTEINIOTHREAD + ); + + return (CAN_HANDLE)board; +} + + +/************************************************************************* +** +** Function : canReceive_driver +** +** Description : Transfers RX messages to Festival application +** Parameters : CAN_HANDLE inst - handle for CAN controller + Message *m - pointer to Message struct +** Returnvalue : hResult - VCI_OK if success +** +*************************************************************************/ +UNS8 __stdcall canReceive_driver(CAN_HANDLE inst, Message *m) +{ + HRESULT hResult; + CANMSG rCanMsg; + //Read message from the receive buffer + hResult=canChannelReadMessage( hCanChn, INFINITE, &rCanMsg ); + if (hResult !=VCI_OK ) + return 1; + + m->cob_id = rCanMsg.dwMsgId; + m->len = rCanMsg.uMsgInfo.Bits.dlc; + m->rtr = rCanMsg.uMsgInfo.Bits.rtr; + if (m->rtr == NOT_A_REQUEST) + memcpy(m->data, rCanMsg.abData , m->len); + return (UNS8)hResult; +} + +/************************************************************************* +** +** Function : canSend_driver +** +** Description : Transfers RX messages to Interface +** Parameters : CAN_HANDLE inst - handle for CAN controller +** Message *m - pointer to Message struct +** Returnvalue : hResult - VCI_OK if success +** +*************************************************************************/ +UNS8 __stdcall canSend_driver(CAN_HANDLE inst, Message const *m) +{ + HRESULT hResult; + CANMSG sCanMsg; + + sCanMsg.uMsgInfo.Bytes.bType = CAN_MSGTYPE_DATA; + sCanMsg.uMsgInfo.Bytes.bFlags = CAN_MAKE_MSGFLAGS(8,0,0,0,0); + sCanMsg.uMsgInfo.Bits.srr = 0; + sCanMsg.dwTime = 0; + sCanMsg.dwMsgId = m->cob_id ; + memcpy(sCanMsg.abData,m->data, m->len); + sCanMsg.uMsgInfo.Bits.dlc = m->len; + sCanMsg.uMsgInfo.Bits.rtr=m->rtr; + + // write the CAN message into the transmit FIFO without waiting for transmission + hResult = canChannelPostMessage(hCanChn, &sCanMsg); + + return (UNS8)hResult; +} + + + + +/************************************************************************* +** +** Function : canClose_driver +** +** Description : Close the message and control channel +** Parameters : CAN_HANDLE inst - handle for CAN controller +** Returnvalue : +** +*************************************************************************/ + int __stdcall canClose_driver(CAN_HANDLE inst) + { + printf("CAN close \n"); + canControlReset(hCanCtl); + canChannelClose(hCanChn); + canControlClose(hCanCtl); + vciDeviceClose(hDevice); + DeleteTimerQueueTimer(NULL,hTimerHandle,NULL); + return 1; + } + + +/************************************************************************* +** +** Function : canChangeBaudRate_driver +** +** Description : Changes the Baudrate of the interface (not supported) +** Parameters : +** Returnvalue : +** +*************************************************************************/ + UNS8 __stdcall canChangeBaudRate_driver( CAN_HANDLE fd, char* baud) + { + //printf("canChangeBaudRate not yet supported by this driver\n"); + return 0; + } + + + /************************************************************************* +** +** Function : TimerProc1 +** +** Description : Basic Polling of the the canline status, +** print debug message for buffer overflow, and BUSOFF condition +** Parameters : void* lpParametar, BOOL TimerOrWaitFired +** Returnvalue : none +** +*************************************************************************/ + void CALLBACK TimerProc1(void* lpParametar, BOOL TimerOrWaitFired ) + { + HRESULT hResult; + CANLINESTATUS canStatus; + + + /* Establish CAN controller status */ + hResult = canControlGetStatus ( hCanCtl, &canStatus); + if (hResult!=VCI_OK) + printf("Error did not read CAN STATUS\n"); + switch ( canStatus.dwStatus) + { + case CAN_STATUS_OVRRUN: + printf("Overrun of the recieve buffer\n"); + break; + case CAN_STATUS_ERRLIM: + printf("Overrun of the CAN controller error counter \n"); + break; + case CAN_STATUS_BUSOFF: + printf("CAN status: BUSOFF"); + break; + case CAN_STATUS_ININIT: + break; + case (CAN_STATUS_BUSOFF)+(CAN_STATUS_ININIT): + printf("CAN status: BUSOFF\n"); + + /* + ** Bus off recovery should come after a software reset, and 128*11 recessive bits. + ** This can only happen when an Error-Active node sends an active error flag, + ** and other nodes respond with Error Echo Flag + */ + break; + default: + break; + } + }; + + + /************************************************************************* +** +** Function : Display_Error +** +** Description : Display the CANline Error +** Parameters : HANDLE hResult +** Returnvalue : none +** +*************************************************************************/ + void Display_Error(HRESULT hResult ) + { + char szError[VCI_MAX_ERRSTRLEN]; + if (hResult != NO_ERROR) + { + if (hResult == -1) + hResult = GetLastError(); + szError[0] = 0; + vciFormatError(hResult, szError, sizeof(szError)); + printf("Error Establishing CAN channel, Error Code: %s\n",szError); + } + } \ No newline at end of file diff -r b72a88dbc7c3 -r e13fa74d169c drivers/can_ixxat_win32/can_ixxat_win32.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_ixxat_win32/can_ixxat_win32.def Mon Sep 23 10:20:07 2013 -0400 @@ -0,0 +1,30 @@ +; This file is part of CanFestival, a library implementing CanOpen Stack. +; +; CanFestival Copyright (C): Edouard TISSERANT and Francis DUPIN +; CanFestival Win32 port Copyright (C) 2007 Leonid Tochinski, ChattenAssociates, Inc. +; +; See COPYING file for copyrights details. +; +; This library is free software; you can redistribute it and/or +; modify it under the terms of the GNU Lesser General Public +; License as published by the Free Software Foundation; either +; version 2.1 of the License, or (at your option) any later version. +; +; This library 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 +; Lesser General Public License for more details. +; +; You should have received a copy of the GNU Lesser General Public +; License along with this library; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +LIBRARY can_ixxat_win32 + +EXPORTS + canReceive_driver + canSend_driver + canOpen_driver + canClose_driver + canChangeBaudRate_driver + diff -r b72a88dbc7c3 -r e13fa74d169c drivers/can_ixxat_win32/can_ixxat_win32.vc10.vcxproj --- a/drivers/can_ixxat_win32/can_ixxat_win32.vc10.vcxproj Tue May 14 20:22:06 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - can_ixxat_win32 - {8F57E7FF-1B73-4134-A2B2-9C0EADB2AEFB} - can_ixxat_win32 - Win32Proj - - - - DynamicLibrary - MultiByte - - - DynamicLibrary - MultiByte - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ../../Debug\ - Debug\ - true - ../../Release\ - Release\ - false - - - - Disabled - ../../include;../../include/win32;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - $(OutDir)$(ProjectName).pdb - - - vci11un6.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - IXXAT.def - true - $(OutDir)$(ProjectName).pdb - Windows - false - - - $(OutDir)$(ProjectName).lib - MachineX86 - - - - - ../../include;../../include/win32;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreadedDLL - - - Level3 - ProgramDatabase - - - vci11un6.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - IXXAT.def - true - Windows - true - true - false - - - $(OutDir)$(ProjectName).lib - MachineX86 - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff -r b72a88dbc7c3 -r e13fa74d169c drivers/can_ixxat_win32/can_ixxat_win32.vc10.vcxproj.filters --- a/drivers/can_ixxat_win32/can_ixxat_win32.vc10.vcxproj.filters Tue May 14 20:22:06 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - - - - \ No newline at end of file diff -r b72a88dbc7c3 -r e13fa74d169c drivers/can_ixxat_win32/can_ixxat_win32.vc12.v11.suo Binary file drivers/can_ixxat_win32/can_ixxat_win32.vc12.v11.suo has changed diff -r b72a88dbc7c3 -r e13fa74d169c drivers/can_ixxat_win32/can_ixxat_win32.vc12.vcxproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_ixxat_win32/can_ixxat_win32.vc12.vcxproj Mon Sep 23 10:20:07 2013 -0400 @@ -0,0 +1,124 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + can_ixxat_win32 + {8F57E7FF-1B73-4134-A2B2-9C0EADB2AEFB} + can_ixxat_win32 + Win32Proj + + + + DynamicLibrary + v110 + MultiByte + + + DynamicLibrary + v110 + MultiByte + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.51106.1 + + + ../../Debug\ + Debug\ + true + + + ../../Release\ + Release\ + false + + + + Disabled + ../../include;../../include/win32;C:\Program Files\IXXAT\VCI 3.5\sdk\Microsoft_VisualC\inc;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + + + vcisdk.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + can_ixxat_win32.def + true + $(OutDir)$(ProjectName).pdb + Windows + false + + $(OutDir)$(ProjectName).lib + MachineX86 + C:\Program Files\IXXAT\VCI 3.5\sdk\Microsoft_VisualC\lib\ia32;%(AdditionalLibraryDirectories) + + + + + C:\Program Files\IXXAT\VCI 3.5\sdk\Microsoft_VisualC\inc;../../include;../../include/win32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;CASA;%(PreprocessorDefinitions) + MultiThreadedDLL + + Level3 + ProgramDatabase + + + vcisdk.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + can_ixxat_win32.def + true + Windows + true + true + false + + $(OutDir)$(ProjectName).lib + MachineX86 + C:\Program Files\IXXAT\VCI 3.5\sdk\Microsoft_VisualC\lib\ia32;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r b72a88dbc7c3 -r e13fa74d169c drivers/can_ixxat_win32/can_ixxat_win32.vc9.vcproj --- a/drivers/can_ixxat_win32/can_ixxat_win32.vc9.vcproj Tue May 14 20:22:06 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,229 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r b72a88dbc7c3 -r e13fa74d169c drivers/can_ixxat_win32/ixxat.cpp --- a/drivers/can_ixxat_win32/ixxat.cpp Tue May 14 20:22:06 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,417 +0,0 @@ -/* -This file is part of CanFestival, a library implementing CanOpen Stack. - -CanFestival Copyright (C): Edouard TISSERANT and Francis DUPIN -CanFestival Win32 port Copyright (C) 2007 Leonid Tochinski, ChattenAssociates, Inc. - -See COPYING file for copyrights details. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -// pragma based message -// http://www.codeproject.com/macro/location_pragma.asp -#define __STR2__(x) #x -#define __STR1__(x) __STR2__(x) -#define __LOC2__ __FILE__ "("__STR1__(__LINE__)") : " - - -#pragma message("*********************************************************************************") -#pragma message(" NOTE: IXXAT Win32 drivers and API should be installed in order to build this project!") -#pragma message(__LOC2__ "See IXXAT.Cpp header for details.") -#pragma message("*********************************************************************************") - - -// IXXAT adapter driver for CanFestival-3 Win32 port -// -// Notes -//-------------------------------------------- -// For building of this project you will need -// the following IXXAT API files -// Vci2.h -// Vci11un6.lib -// -// IXXAT Win32 drivers and API can be downloaded from -// http://www.ixxat.com/download_vci_en,7547,5873.html -// -// Copy Vci2.h & Vci11un6.lib files to can_ixxat_win32 folder of add path to them in Project settings. - - -#include -extern "C" { -#include "applicfg.h" -#include "can_driver.h" -#include "def.h" -} -#include "VCI2.h" -#include "async_access_que.h" - -#define CAN_NUM 0 - -class IXXAT - { - public: - class error - { - }; - IXXAT(s_BOARD *board); - ~IXXAT(); - bool send(const Message *m); - bool receive(Message *m); - - static bool isDriverClosed() {return m_driverClosed;} - private: - bool open(int board_number, const char* baud_rate); - bool close(); - void receive_queuedata(UINT16 que_hdl, UINT16 count, VCI_CAN_OBJ* p_obj); - // VCI2 handler - static void VCI_CALLBACKATTR message_handler(char *msg_str); - static void VCI_CALLBACKATTR receive_queuedata_handler(UINT16 que_hdl, UINT16 count, VCI_CAN_OBJ* p_obj); - static void VCI_CALLBACKATTR exception_handler(VCI_FUNC_NUM func_num, INT32 err_code, UINT16 ext_err, char* err_str); - - static void CALLBACK canBusWatchdog(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime); - void watchdog(); - private: - UINT16 m_BoardHdl; - UINT16 m_TxQueHdl; - UINT16 m_RxQueHdl; - async_access_que m_RX_Que; - static IXXAT* m_callbackPtr; - - static bool m_driverClosed; - static UINT_PTR m_watchdogTimerId; - static const unsigned int CAN_BUS_WATCHDOG_INTERVAL_MSEC = 10000; - - /** Bitmask inside sts from VCI_ReadCanStatus() that defines the can bus off state.*/ - static const unsigned char STS_CAN_BUS_OFF = 0x80; - - /** Bitmask inside sts from VCI_ReadCanStatus() that defines the can data overrun state.*/ - static const unsigned char STS_CAN_DATA_OVERRUN = 0x20; - - /** Bitmask inside sts from VCI_ReadCanStatus() that defines the remote queue overrun state.*/ - static const unsigned char STS_REMOTE_QUEUE_OVERRUN = 0x04; - }; - -IXXAT *IXXAT::m_callbackPtr = NULL; - -UINT_PTR IXXAT::m_watchdogTimerId = 0; - -bool IXXAT::m_driverClosed = false; - -IXXAT::IXXAT(s_BOARD *board) : m_BoardHdl(0xFFFF), - m_TxQueHdl(0xFFFF), - m_RxQueHdl(0xFFFF) - - { - if (!board) - { - close(); - throw error(); - } - - long board_number = 0; - - if (board->busname) - { - board_number = atol(board->busname); - } - - if (!open(board_number, board->baudrate)) - { - close(); - throw error(); - } - m_callbackPtr = this; - } - -IXXAT::~IXXAT() - { - close(); - m_callbackPtr = 0; - } - -bool IXXAT::send(const Message *m) - { - if (m_BoardHdl == 0xFFFF) - return true; // true -> NOT OK - long res = VCI_ERR; - if (m->rtr == NOT_A_REQUEST) - res = VCI_TransmitObj(m_BoardHdl, m_TxQueHdl, m->cob_id, m->len, const_cast(m->data)); - else - res = VCI_RequestObj(m_BoardHdl, m_TxQueHdl, m->cob_id, m->len); - - return (res == VCI_OK); - } - - -bool IXXAT::receive(Message *m) - { - if (m_BoardHdl == 0xFFFF) - return false; - VCI_CAN_OBJ obj; - if (m_RX_Que.extract_top(obj)) - { - m->cob_id = static_cast(obj.id); //valid for 11Bit ids - m->len = obj.len; - m->rtr = (obj.rtr == VCI_RX_BUF) ? NOT_A_REQUEST : REQUEST; - if (m->rtr == NOT_A_REQUEST) - ::memcpy(m->data, obj.a_data, m->len); - return true; - } - return false; - } - -bool IXXAT::open(int board_number, const char* baud_rate) - { - // check, if baudrate is supported - struct IXXAT_baud_rate_param - { - UINT8 bt0; - UINT8 bt1; - }; - struct IXXAT_look_up_table - { - char baud_rate[20]; - IXXAT_baud_rate_param bt; - }; - static const IXXAT_look_up_table br_lut[] = { - {"10K",{VCI_10KB}}, - {"20K",{VCI_20KB}}, - {"50K",{VCI_50KB}}, - {"100K",{VCI_100KB}}, - {"125K",{VCI_125KB}}, - {"250K",{VCI_250KB}}, - {"500K",{VCI_500KB}}, - {"800K",{VCI_800KB}}, - {"1M",{VCI_1000KB}} - }; - static const long br_lut_size = sizeof (br_lut)/sizeof(IXXAT_look_up_table); - int index; - for (index = 0; index < br_lut_size; ++index) - { - if (::strcmp(br_lut[index].baud_rate,baud_rate)==0) - break; - } - if (index == br_lut_size) - { - MSG_ERR_DRV("IXXAT::open: The given baudrate %S is invalid.", baud_rate); - return false; - } - // close existing board - close(); - // init IXXAT board - long res = VCI2_PrepareBoard( 0, // board type, unused in VCI2 - board_number, // unique board index, see XAT_EnumHwEntry() and XAT_GetConfig() - NULL, // pointer to buffer for additional info - 0, // length of additional info buffer - message_handler, // pointer to msg-callbackhandler - receive_queuedata_handler, // pointer to receive-callbackhandler - exception_handler); // pointer to exception-callbackhandler - if (res < 0) - { - MSG_ERR_DRV("IXXAT::open: VCI2_PrepareBoard failed with code '%d'.", res); - return false; - } - m_BoardHdl = (UINT16)res; - - VCI_ResetBoard(m_BoardHdl); - - // init CAN parameters - - // initialize CAN-Controller - res = VCI_InitCan(m_BoardHdl, CAN_NUM, br_lut[index].bt.bt0,br_lut[index].bt.bt1, VCI_11B); - - // definition of Acceptance-Mask (define to receive all IDs) - res = VCI_SetAccMask(m_BoardHdl, CAN_NUM, 0x0UL, 0x0UL); - - // definition of Transmit Queue - res = VCI_ConfigQueue(m_BoardHdl, CAN_NUM, VCI_TX_QUE, 100 , 0, 0, 0, &m_TxQueHdl); - - // definition of Receive Queue (interrupt mode) - res = VCI_ConfigQueue(m_BoardHdl, CAN_NUM, VCI_RX_QUE, 500, 1, 0, 100, &m_RxQueHdl); - - // assign the all IDs to the Receive Queue - res = VCI_AssignRxQueObj(m_BoardHdl, m_RxQueHdl ,VCI_ACCEPT, 0, 0); - - // And now start the CAN - res = VCI_StartCan(m_BoardHdl, CAN_NUM); - - //Start CAN Bus-Off watchdog - m_watchdogTimerId = SetTimer(NULL, NULL, IXXAT::CAN_BUS_WATCHDOG_INTERVAL_MSEC, IXXAT::canBusWatchdog); - - m_driverClosed = false; - - return true; - } - -bool IXXAT::close() - { - m_driverClosed = true; - if (m_BoardHdl == 0xFFFF) - return true; - VCI_ResetBoard(m_BoardHdl); - VCI_CancelBoard(m_BoardHdl); - m_BoardHdl = - m_TxQueHdl = - m_RxQueHdl = 0xFFFF; - return true; - } - -void IXXAT::receive_queuedata(UINT16 que_hdl, UINT16 count, VCI_CAN_OBJ *p_obj) - { - for (int i = 0; i < count; ++i) - m_RX_Que.append(p_obj[i]); // can packet - } - -void VCI_CALLBACKATTR IXXAT::receive_queuedata_handler(UINT16 que_hdl, UINT16 count, VCI_CAN_OBJ *p_obj) - { - if (m_callbackPtr != NULL) - m_callbackPtr->receive_queuedata(que_hdl, count, p_obj); - } - -void VCI_CALLBACKATTR IXXAT::message_handler(char *msg_str) - { - MSG_ERR_DRV("IXXAT Message: [%S]", msg_str); - } - -void VCI_CALLBACKATTR IXXAT::exception_handler(VCI_FUNC_NUM func_num, INT32 err_code, UINT16 ext_err, char* err_str) - { - static const char* Num2Function[] = - { - "VCI_Init", - "VCI_Searchboard", - "VCI_Prepareboard", - "VCI_Cancel_board", - "VCI_Testboard", - "VCI_ReadBoardInfo", - "VCI_ReadBoardStatus", - "VCI_Resetboard", - "VCI_ReadCANInfo", - "VCI_ReadCANStatus", - "VCI_InitCAN", - "VCI_SetAccMask", - "VCI_ResetCAN", - "VCI_StartCAN", - "VCI_ResetTimeStamps", - "VCI_ConfigQueue", - "VCI_AssignRxQueObj", - "VCI_ConfigBuffer", - "VCI_ReconfigBuffer", - "VCI_ConfigTimer", - "VCI_ReadQueStatus", - "VCI_ReadQueObj", - "VCI_ReadBufStatus", - "VCI_ReadBufData", - "VCI_TransmitObj", - "VCI_RequestObj", - "VCI_UpdateBufObj", - "VCI_CciReqData" - }; - - MSG_ERR_DRV("IXXAT Exception: %S (%i / %u) [%S]", Num2Function[func_num], err_code, ext_err, err_str); - } - - void IXXAT::watchdog() - { - VCI_CAN_STS sts; - long res = VCI_ReadCanStatus(m_BoardHdl, CAN_NUM, &sts); - - if (res < 0) - { - MSG_ERR_DRV("IXXAT canBusWatchdog: ERROR: Reading the can state failed!"); - } - else - { - if (sts.sts & (STS_CAN_BUS_OFF | STS_CAN_DATA_OVERRUN | STS_REMOTE_QUEUE_OVERRUN)) - { - if (sts.sts & STS_CAN_BUS_OFF) - { - MSG_ERR_DRV("IXXAT canBusWatchdog: CAN bus off detected!"); - } - if (sts.sts & STS_CAN_DATA_OVERRUN) - { - MSG_ERR_DRV("IXXAT canBusWatchdog: CAN data overrun detected!"); - } - if (sts.sts & STS_REMOTE_QUEUE_OVERRUN) - { - MSG_ERR_DRV("IXXAT canBusWatchdog: Remote queue overrun detected!"); - } - - res = VCI_ResetCan(m_BoardHdl, CAN_NUM); - if (res <= 0) - { - MSG_ERR_DRV("IXXAT canBusWatchdog: ERROR: Resetting the can module failed with code '%d'!", res); - } - - res = VCI_StartCan(m_BoardHdl, CAN_NUM); - if (res <= 0) - { - MSG_ERR_DRV("IXXAT canBusWatchdog: ERROR: Restaring the can module failed with code '%d'!", res); - } - } - } - - if (SetTimer(NULL, m_watchdogTimerId, IXXAT::CAN_BUS_WATCHDOG_INTERVAL_MSEC, IXXAT::canBusWatchdog) == 0) - { - MSG_ERR_DRV("IXXAT canBusWatchdog: ERROR: Creation of the watchdog timer failed!"); - } - } - -void CALLBACK IXXAT::canBusWatchdog(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime) -{ - if (m_callbackPtr != NULL) - m_callbackPtr->watchdog(); -} - -//------------------------------------------------------------------------ -extern "C" - UNS8 __stdcall canReceive_driver(CAN_HANDLE inst, Message *m) - { - if (IXXAT::isDriverClosed()) return 0; - return reinterpret_cast(inst)->receive(m) ? 0 : 1; - } - -extern "C" - UNS8 __stdcall canSend_driver(CAN_HANDLE inst, Message const *m) - { - if (IXXAT::isDriverClosed()) return 0; - return reinterpret_cast(inst)->send(m) ? 0 : 1; - } - -extern "C" - CAN_HANDLE __stdcall canOpen_driver(s_BOARD *board) - { - try - { - return new IXXAT(board); - } - catch (IXXAT::error&) - { - return 0; - } - } - -extern "C" - int __stdcall canClose_driver(CAN_HANDLE inst) - { - delete reinterpret_cast(inst); - return 1; - } - -extern "C" - UNS8 __stdcall canChangeBaudRate_driver( CAN_HANDLE fd, char* baud) - { - //printf("canChangeBaudRate not yet supported by this driver\n"); - return 0; - }