diff -r 8dbe0aec4f36 -r 6121ebff4da6 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 Sat Oct 12 09:09:04 2013 +0900 @@ -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