greg@494: /* greg@494: This file is part of CanFestival, a library implementing CanOpen Stack. greg@494: greg@494: Copyright (C): Edouard TISSERANT and Francis DUPIN greg@494: greg@494: See COPYING file for copyrights details. greg@494: greg@494: This library is free software; you can redistribute it and/or greg@494: modify it under the terms of the GNU Lesser General Public greg@494: License as published by the Free Software Foundation; either greg@494: version 2.1 of the License, or (at your option) any later version. greg@494: greg@494: This library is distributed in the hope that it will be useful, greg@494: but WITHOUT ANY WARRANTY; without even the implied warranty of greg@494: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU greg@494: Lesser General Public License for more details. greg@494: greg@494: You should have received a copy of the GNU Lesser General Public greg@494: License along with this library; if not, write to the Free Software greg@494: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA greg@494: */ greg@494: greg@494: #if defined(WIN32) && !defined(__CYGWIN__) greg@494: #define usleep(micro) Sleep(micro%1000 ? (micro/1000) + 1 : (micro/1000)) greg@494: #define _CRT_SECURE_NO_DEPRECATE greg@494: #else greg@494: #include greg@494: #include greg@494: #include greg@494: #include greg@494: #endif greg@494: greg@494: #include "can_driver.h" greg@494: #include "AnaGateDllCan.h" greg@494: greg@494: greg@494: typedef struct SAnaGatePort greg@494: { greg@494: int hHandle; greg@494: HANDLE hAnaRecEvent; greg@494: HANDLE hFesticalRecAcknowledge; greg@494: Message sMsgBuffer; greg@494: struct SAnaGatePort *pNext; greg@494: struct SAnaGatePort *pPrev; greg@494: } SAnaGatePort; greg@494: greg@494: greg@494: SAnaGatePort *pFirstAnaGatePort=NULL; greg@494: greg@494: greg@494: /********* AnaGate API CAN receive callback Funciton ****************/ greg@494: void WINAPI AnaGateReceiveCallBack (int nIdentifier, const char* pcBuffer, int nBufferLen, int nFlags, int hHandle) greg@494: { greg@494: SAnaGatePort *pAnaGatePort = pFirstAnaGatePort; greg@494: int i; greg@494: greg@494: while (pAnaGatePort->hHandle != hHandle ) greg@494: { greg@494: pAnaGatePort = pAnaGatePort->pNext; greg@494: if (pAnaGatePort == pFirstAnaGatePort ) greg@494: { greg@494: pAnaGatePort = NULL; greg@494: printf("AnaGateReceiveCallBack (AnaGate_Win32): ERROR: Can't find AnaGatePort-Objekt to the Received Handle %d\n",hHandle); greg@494: return; greg@494: } greg@494: } greg@494: greg@494: pAnaGatePort->sMsgBuffer.cob_id = nIdentifier; greg@494: pAnaGatePort->sMsgBuffer.len= nBufferLen; greg@494: if (nFlags == 2) greg@494: pAnaGatePort->sMsgBuffer.rtr = 1; greg@494: else greg@494: pAnaGatePort->sMsgBuffer.rtr = 0; greg@494: greg@494: for (i = 0 ; i < nBufferLen; i++) greg@494: { greg@494: pAnaGatePort->sMsgBuffer.data[i] = pcBuffer[i]; greg@494: } greg@494: greg@494: SetEvent(pAnaGatePort->hAnaRecEvent); greg@494: greg@494: WaitForSingleObject(pAnaGatePort->hFesticalRecAcknowledge,INFINITE); greg@494: } greg@494: greg@494: greg@494: /*********functions which permit to communicate with the board****************/ greg@494: UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m) greg@494: { greg@494: SAnaGatePort* pAnaGatePort = (SAnaGatePort*)fd0; greg@494: int i; greg@494: greg@494: WaitForSingleObject( // Wait for receive event greg@494: pAnaGatePort->hAnaRecEvent, // event handle greg@494: INFINITE); // indefinite wait greg@494: greg@494: greg@494: m->cob_id = pAnaGatePort->sMsgBuffer.cob_id; greg@494: m->len = pAnaGatePort->sMsgBuffer.len; greg@494: m->rtr = pAnaGatePort->sMsgBuffer.rtr; greg@494: for (i = 0 ; i < pAnaGatePort->sMsgBuffer.len; i++) greg@494: { greg@494: m->data[i] = pAnaGatePort->sMsgBuffer.data[i]; greg@494: } greg@494: greg@494: SetEvent(pAnaGatePort->hFesticalRecAcknowledge); //Set Acknollede event greg@494: greg@494: return 0; greg@494: } greg@494: greg@494: /***************************************************************************/ greg@494: UNS8 canSend_driver(CAN_HANDLE fd0, Message *m) greg@494: { greg@494: SAnaGatePort* pAnaCanPort = (SAnaGatePort*)fd0; greg@494: char cErrorMsg[100]; greg@494: int nRetCode; greg@494: int nMsgTyp; greg@494: greg@494: if (m->rtr == 0) greg@494: { greg@494: nMsgTyp = 0; //Normal; greg@494: } greg@494: else greg@494: { greg@494: nMsgTyp = 2; //Remote frame; greg@494: } greg@494: greg@494: if ( (nRetCode = CANWrite(pAnaCanPort->hHandle , m->cob_id,(const char*) m->data, m->len, nMsgTyp) ) ) greg@494: { greg@494: CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge greg@494: fprintf(stderr,"canSend_driver (AnaGate_Win32) %s \n",nRetCode); greg@494: //printf("canSend_driver (AnaGate_Win32) %s \n",nRetCode); greg@494: return 1; greg@494: } greg@494: greg@494: return 0; greg@494: } greg@494: greg@494: greg@494: /***************************************************************************/ greg@494: int TranslateBaudeRate(char* optarg){ greg@494: if(!strcmp( optarg, "1M")) return 1000000; greg@494: if(!strcmp( optarg, "800K")) return 800000; greg@494: if(!strcmp( optarg, "500K")) return 500000; greg@494: if(!strcmp( optarg, "250K")) return 250000; greg@494: if(!strcmp( optarg, "125K")) return 125000; greg@494: if(!strcmp( optarg, "100K")) return 100000; greg@494: if(!strcmp( optarg, "50K")) return 50000; greg@494: if(!strcmp( optarg, "20K")) return 20000; greg@494: if(!strcmp( optarg, "10K")) return 10000; greg@494: greg@494: return 0x0000; greg@494: } greg@494: /****************************************************************************/ greg@494: greg@494: UNS8 canChangeBaudRate_driver( CAN_HANDLE fd0, char* baud) greg@494: { greg@494: int nRetCode; greg@494: char cErrorMsg[100]; greg@494: struct SAnaGatePort* pAnaGatePort = (struct SAnaGatePort*)fd0; greg@494: greg@494: if (nRetCode = CANSetGlobals (pAnaGatePort->hHandle, TranslateBaudeRate(baud), 0, 0, 1) ) greg@494: { greg@494: CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge greg@494: fprintf(stderr, "canChangeBaudRate_drive (AnaGate_Win32): %s\n", cErrorMsg); greg@494: printf("canChangeBaudRate_drive (AnaGate_Win32): %s\n", cErrorMsg); greg@494: return 1; greg@494: } greg@494: return 0; greg@494: } greg@494: greg@494: /***************************************************************************/ greg@494: /* To open a connection to AnaGate CAN the s_BOARD board->busname must be greg@494: the AnaGate IP-Adresse followed from the CAN-Port (A or B) you want to use greg@494: For example "192.168.1.254:A" greg@494: */ greg@494: greg@494: CAN_HANDLE canOpen_driver(s_BOARD *board) greg@494: { greg@494: int PortNr; greg@494: char cErrorMsg[100]; greg@494: int nRetCode; greg@494: char sIPAddress[16]; greg@494: struct SAnaGatePort *pNewAnaGatePort; greg@494: char bBusnameValid = TRUE; greg@494: unsigned int nBusnameLen; greg@494: greg@494: /////////////////////////////////////////// greg@494: // Do some checkings concerning the busname greg@494: // format should be IP-Adress:Port greg@494: // e.g. 192.168.1.254:A greg@494: /////////////////////////////////////////// greg@494: nBusnameLen = strlen(board->busname); greg@494: greg@494: if ( nBusnameLen < strlen( "1.2.3.4:A" ) ) bBusnameValid = FALSE; // check minimum length of busname greg@494: if ( nBusnameLen > strlen( "123.234.345.456:A" ) ) bBusnameValid = FALSE; // check maximum length of busname greg@494: if ( bBusnameValid ) greg@494: { greg@494: switch (board->busname[nBusnameLen-1]) // check Portname of busname greg@494: { greg@494: case ('A'): PortNr = 0; break; greg@494: case ('B'): PortNr = 1; break; greg@494: case ('C'): PortNr = 2; break; greg@494: case ('D'): PortNr = 3; break; greg@494: default : bBusnameValid = FALSE; break; greg@494: } greg@494: if (board->busname[nBusnameLen-2] != ':' ) bBusnameValid = FALSE; // check Colon before Portname greg@494: } greg@494: greg@494: if ( ! bBusnameValid ) greg@494: { greg@494: fprintf(stderr, "canOpen_driver (AnaGate_Win32): busname (\"%s\") has a wrong format. Use IPAddr:CANPort for example \"192.168.1.254:A\"\n",board->busname); greg@494: return (CAN_HANDLE) NULL; greg@494: } greg@494: greg@494: board->busname[nBusnameLen-2] = 0; // NULL Terminator for IP Address string greg@494: strcpy (sIPAddress, board->busname); greg@494: greg@494: pNewAnaGatePort = (SAnaGatePort*) malloc(sizeof (struct SAnaGatePort)); greg@494: if (pFirstAnaGatePort == NULL) greg@494: { greg@494: pFirstAnaGatePort = pNewAnaGatePort; greg@494: pNewAnaGatePort->pNext = pNewAnaGatePort; greg@494: pNewAnaGatePort->pPrev = pNewAnaGatePort; greg@494: } greg@494: else greg@494: { pNewAnaGatePort->pNext = pFirstAnaGatePort; greg@494: pNewAnaGatePort->pPrev = pFirstAnaGatePort->pPrev; greg@494: pFirstAnaGatePort->pPrev->pNext = pNewAnaGatePort; greg@494: pFirstAnaGatePort->pPrev = pNewAnaGatePort; greg@494: greg@494: } greg@494: // Connect to AnaGate greg@494: if ( nRetCode = CANOpenDevice (&pNewAnaGatePort->hHandle, greg@494: 0, /*confirmation*/ greg@494: 1, /*Monitor*/ greg@494: PortNr, greg@494: sIPAddress, greg@494: 1000 /*TimeOut*/ ) ) greg@494: { greg@494: CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge greg@494: fprintf(stderr, "canOpen_driver (AnaGate_Win32): %s @ %s\n", cErrorMsg,sIPAddress); greg@494: //printf( "canOpen_driver (AnaGate_Win32): %s @ %s\n", cErrorMsg,sIPAddress); greg@494: return (CAN_HANDLE) NULL; greg@494: } greg@494: greg@494: // Inizial Baudrate greg@494: if (nRetCode = CANSetGlobals (pNewAnaGatePort->hHandle, greg@494: TranslateBaudeRate(board->baudrate), greg@494: 0,/*OperatingMode = normal*/ greg@494: 0,/*CAN-Termination = off*/ greg@494: 1 /*HighSpeedMode = on*/) ) greg@494: { greg@494: CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge greg@494: fprintf(stderr, "canOpen_driver (AnaGate_Win32): %s @ %s\n", cErrorMsg,sIPAddress); greg@494: //printf("canOpen_driver (AnaGate_Win32): %s @ %s\n", cErrorMsg,sIPAddress); greg@494: return (CAN_HANDLE) NULL; greg@494: } greg@494: greg@494: // Creat receive and receive-acknoledge event greg@494: pNewAnaGatePort->hAnaRecEvent = CreateEvent( greg@494: NULL, // default security attributes greg@494: FALSE, // manual-reset event greg@494: FALSE, // initial state is nonsignaled greg@494: NULL // object name greg@494: ); greg@494: greg@494: pNewAnaGatePort->hFesticalRecAcknowledge = CreateEvent( greg@494: NULL, // default security attributes greg@494: FALSE, // manual-reset event greg@494: FALSE, // initial state is nonsignaled greg@494: NULL // object name greg@494: ); greg@494: greg@494: // Install receive callback funktion greg@494: if (nRetCode = CANSetCallback(pNewAnaGatePort->hHandle, AnaGateReceiveCallBack) ) greg@494: { greg@494: canClose_driver (pNewAnaGatePort); greg@494: CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge greg@494: fprintf(stderr, "canOpen_driver (AnaGate_Win32): %s @ %s\n", cErrorMsg,sIPAddress); greg@494: //printf("canOpen_driver (AnaGate_Win32): %s @ %s\n", cErrorMsg,sIPAddress); greg@494: return (CAN_HANDLE) NULL; greg@494: } greg@494: greg@494: return (CAN_HANDLE)pNewAnaGatePort; greg@494: } greg@494: greg@494: /***************************************************************************/ greg@494: int canClose_driver(CAN_HANDLE fd0) greg@494: { greg@494: SAnaGatePort* pAnaCanPort = (SAnaGatePort*)fd0; greg@494: char cErrorMsg[100]; greg@494: int nRetCode; greg@494: greg@494: greg@494: SetEvent (pAnaCanPort->hAnaRecEvent); greg@494: CloseHandle (pAnaCanPort->hAnaRecEvent); greg@494: CloseHandle (pAnaCanPort->hFesticalRecAcknowledge); greg@494: greg@494: if ( nRetCode = CANCloseDevice(pAnaCanPort->hHandle) ) greg@494: { greg@494: CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge greg@494: fprintf(stderr, "canClose_driver (AnaGate_Linux): %s\n", cErrorMsg); greg@494: //printf("canClose_driver (AnaGate_Linux): %s\n", cErrorMsg); greg@494: } greg@494: greg@494: if (pAnaCanPort->pNext == pAnaCanPort) greg@494: { greg@494: free (pAnaCanPort); greg@494: pFirstAnaGatePort=NULL; greg@494: } greg@494: else greg@494: { pAnaCanPort->pNext->pPrev = pAnaCanPort->pPrev; greg@494: pAnaCanPort->pPrev->pNext = pAnaCanPort->pNext; greg@494: free (pAnaCanPort); greg@494: } greg@494: greg@494: return 0; greg@494: } greg@494: greg@494: greg@494: greg@494: greg@494: