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; - }