--- /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 <stdio.h>
+#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