drivers/can_anagate_linux/can_anagate_linux.c
changeset 494 aa36efce6e78
child 631 08b6b903f84a
equal deleted inserted replaced
493:a204a86a71f1 494:aa36efce6e78
       
     1 /*
       
     2 This file is part of CanFestival, a library implementing CanOpen Stack. 
       
     3 
       
     4 Copyright (C): Edouard TISSERANT and Francis DUPIN
       
     5 
       
     6 See COPYING file for copyrights details.
       
     7 
       
     8 This library is free software; you can redistribute it and/or
       
     9 modify it under the terms of the GNU Lesser General Public
       
    10 License as published by the Free Software Foundation; either
       
    11 version 2.1 of the License, or (at your option) any later version.
       
    12 
       
    13 This library is distributed in the hope that it will be useful,
       
    14 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    16 Lesser General Public License for more details.
       
    17 
       
    18 You should have received a copy of the GNU Lesser General Public
       
    19 License along with this library; if not, write to the Free Software
       
    20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    21 */
       
    22 
       
    23 
       
    24 #include <stdio.h>
       
    25 #include <string.h>
       
    26 #include <errno.h>
       
    27 #include <fcntl.h>
       
    28 
       
    29 
       
    30 #include "can_driver.h"
       
    31 
       
    32 struct SAnaGatePort
       
    33 {
       
    34    int      hHandle;
       
    35    Message  sMsgBuffer;
       
    36    struct   SAnaGatePort *pNext;
       
    37    struct   SAnaGatePort *pPrev;
       
    38    int      bBufferFull;
       
    39 };
       
    40 
       
    41 
       
    42 struct SAnaGatePort *pFistAnaGatePort = NULL;
       
    43 
       
    44 
       
    45 /********* AnaGate API CAN receive callback Funciton  ****************/
       
    46 void AnaGateReceiveCallBack (int nIdentifier, const char* pcBuffer, int nBufferLen, int nFlags, int hHandle)
       
    47 {
       
    48    int i;
       
    49    struct SAnaGatePort *pAnaGatePort = pFistAnaGatePort;
       
    50    
       
    51    while (pAnaGatePort->hHandle != hHandle )
       
    52    {
       
    53       pAnaGatePort = pAnaGatePort->pNext;
       
    54       if (pAnaGatePort == pFistAnaGatePort )
       
    55       {
       
    56          pAnaGatePort = NULL;
       
    57          printf("AnaGateReceiveCallBack (AnaGate_Linux): ERROR: Can't find AnaGatePort-Objekt to the Received Handle %d\n",hHandle);
       
    58          return;
       
    59       }
       
    60    }
       
    61    while (pAnaGatePort->bBufferFull)
       
    62    {
       
    63       usleep(5000);
       
    64    }
       
    65    pAnaGatePort->sMsgBuffer.cob_id =   nIdentifier;
       
    66    pAnaGatePort->sMsgBuffer.len= nBufferLen;
       
    67    if (nFlags == 2)
       
    68     pAnaGatePort->sMsgBuffer.rtr = 1;
       
    69    else
       
    70     pAnaGatePort->sMsgBuffer.rtr = 0;
       
    71 
       
    72    for (i = 0 ; i < nBufferLen; i++)
       
    73    {
       
    74       pAnaGatePort->sMsgBuffer.data[i] = pcBuffer[i];
       
    75    }
       
    76 
       
    77    pAnaGatePort->bBufferFull = 1;
       
    78  
       
    79 }
       
    80 
       
    81 
       
    82 /*********functions which permit to communicate with the board****************/
       
    83 UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m)
       
    84 {
       
    85    int i;
       
    86    struct SAnaGatePort*  pAnaGatePort = (struct SAnaGatePort*)fd0;
       
    87 
       
    88    while (pAnaGatePort->bBufferFull == 0)
       
    89    {
       
    90       usleep (5000); 
       
    91    }
       
    92    
       
    93    m->cob_id = pAnaGatePort->sMsgBuffer.cob_id;
       
    94    m->len     = pAnaGatePort->sMsgBuffer.len;
       
    95    m->rtr     = pAnaGatePort->sMsgBuffer.rtr;
       
    96    for (i = 0 ; i < pAnaGatePort->sMsgBuffer.len; i++)
       
    97    {
       
    98      m->data[i] = pAnaGatePort->sMsgBuffer.data[i];
       
    99    }
       
   100    
       
   101    pAnaGatePort->bBufferFull = 0;
       
   102  
       
   103    return 0;
       
   104 }
       
   105 
       
   106 /***************************************************************************/
       
   107 UNS8 canSend_driver(CAN_HANDLE fd0, Message *m)
       
   108 {
       
   109    struct SAnaGatePort*  pAnaCanPort = (struct SAnaGatePort*)fd0;
       
   110    char cErrorMsg[100];
       
   111    int nRetCode;
       
   112    int nMsgTyp;
       
   113 
       
   114    if (m->rtr == 0)
       
   115    {
       
   116      nMsgTyp = 0; //Normal;
       
   117    }
       
   118    else
       
   119    {
       
   120      nMsgTyp = 2; //Remote frame;
       
   121    }
       
   122 
       
   123    if ( (nRetCode = CANWrite(pAnaCanPort->hHandle , m->cob_id,(const char*) m->data, m->len, nMsgTyp) ) )
       
   124    {
       
   125      CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge
       
   126      fprintf(stderr,"canSend_driver (AnaGate_Linux) %s \n",nRetCode);
       
   127      //printf("canSend_driver (AnaGate_Linux) %s \n",nRetCode);
       
   128      return 1;
       
   129    }
       
   130 
       
   131    return 0;
       
   132 }
       
   133 
       
   134 
       
   135 /***************************************************************************/
       
   136 int TranslateBaudeRate(char* optarg){
       
   137    if(!strcmp( optarg, "1M"))   return 1000000;
       
   138    if(!strcmp( optarg, "800K")) return  800000;
       
   139    if(!strcmp( optarg, "500K")) return  500000;
       
   140    if(!strcmp( optarg, "250K")) return  250000;
       
   141    if(!strcmp( optarg, "125K")) return  125000;
       
   142    if(!strcmp( optarg, "100K")) return  100000;
       
   143    if(!strcmp( optarg, "50K"))  return   50000;
       
   144    if(!strcmp( optarg, "20K"))  return   20000;
       
   145    if(!strcmp( optarg, "10K"))  return   10000;
       
   146  
       
   147    return 0x0000;
       
   148 }
       
   149 
       
   150 /***************************************************************************/
       
   151 UNS8 canChangeBaudRate_driver( CAN_HANDLE fd0, char* baud)
       
   152 {
       
   153    int nRetCode;
       
   154    char cErrorMsg[100];
       
   155    struct SAnaGatePort*  pAnaGatePort = (struct SAnaGatePort*)fd0;
       
   156    
       
   157    if (nRetCode = CANSetGlobals (pAnaGatePort->hHandle, TranslateBaudeRate(baud), 0, 0, 1) ) 
       
   158    {
       
   159       CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge
       
   160       fprintf(stderr, "canChangeBaudRate_drive (AnaGate_Linux): %s\n", cErrorMsg);
       
   161       //printf("canChangeBaudRate_drive (AnaGate_Linux): %s\n", cErrorMsg);
       
   162       return 1;
       
   163    }
       
   164    return 0;
       
   165 }
       
   166 
       
   167 /***************************************************************************/
       
   168 /* To open a connection to AnaGate CAN the s_BOARD board->busname must be 
       
   169  the AnaGate IP-Adresse followed from the CAN-Port (A or B) you want to use 
       
   170  For example "192.168.1.254:A"
       
   171 */
       
   172 
       
   173 CAN_HANDLE canOpen_driver(s_BOARD *board)
       
   174 {
       
   175    int nPortNr;
       
   176    char cErrorMsg[100];
       
   177    int nRetCode;
       
   178    char sIPAddress[16];
       
   179    struct SAnaGatePort *pNewAnaGatePort;
       
   180    unsigned int nBusnameLen;   
       
   181    char bBusnameValid = 1;
       
   182 
       
   183 
       
   184    ///////////////////////////////////////////
       
   185    // Do some checkings concerning the busname
       
   186    // format should be IP-Adress:Port
       
   187    // e.g. 192.168.1.254:A
       
   188    ///////////////////////////////////////////
       
   189    nBusnameLen = strlen(board->busname);
       
   190    
       
   191    if ( nBusnameLen < strlen( "1.2.3.4:A" ) )         bBusnameValid = 0;  // check minimum length of busname
       
   192    if ( nBusnameLen > strlen( "123.234.345.456:A" ) ) bBusnameValid = 0;  // check maximum length of busname
       
   193    if ( bBusnameValid )
       
   194    {
       
   195       switch (board->busname[nBusnameLen-1])                                 // check Portname of busname
       
   196       {
       
   197          case ('A'): nPortNr = 0; break;
       
   198          case ('B'): nPortNr = 1; break;
       
   199          case ('C'): nPortNr = 2; break;
       
   200          case ('D'): nPortNr = 3; break;
       
   201          default :   bBusnameValid = 0; break;
       
   202       }
       
   203       if (board->busname[nBusnameLen-2] != ':' )    bBusnameValid = 0;   // check Colon before Portname
       
   204    }
       
   205 
       
   206    if ( ! bBusnameValid )
       
   207    {
       
   208       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);
       
   209       return (CAN_HANDLE) NULL;
       
   210    }
       
   211 
       
   212    board->busname[nBusnameLen-2] = 0; // NULL Terminator for IP Address string
       
   213    strcpy (sIPAddress, board->busname);
       
   214    
       
   215    pNewAnaGatePort = (struct SAnaGatePort*) malloc(sizeof (struct SAnaGatePort));
       
   216    if (pFistAnaGatePort == NULL)
       
   217    {
       
   218       pFistAnaGatePort = pNewAnaGatePort;
       
   219       pNewAnaGatePort->pNext =  pNewAnaGatePort;
       
   220       pNewAnaGatePort->pPrev =  pNewAnaGatePort;
       
   221    }
       
   222    else
       
   223    {   pNewAnaGatePort->pNext =  pFistAnaGatePort;
       
   224       pNewAnaGatePort->pPrev =  pFistAnaGatePort->pPrev;
       
   225       pFistAnaGatePort->pPrev->pNext = pNewAnaGatePort;
       
   226       pFistAnaGatePort->pPrev = pNewAnaGatePort;
       
   227 
       
   228    }
       
   229 
       
   230    // Connect to AnaGate
       
   231    if ( nRetCode = CANOpenDevice (&pNewAnaGatePort->hHandle, 
       
   232                         0,      /*confimation off*/ 
       
   233                         1,      /*Monitor on*/ 
       
   234                         nPortNr,
       
   235                         sIPAddress,
       
   236                         1000   /*TimeOut*/ )  )
       
   237    {
       
   238       CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge
       
   239       fprintf(stderr, "canOpen_driver (AnaGate_Linux): %s @ %s  Port:%d\n", cErrorMsg,sIPAddress,nPortNr);
       
   240       //printf( "canOpen_driver (AnaGate_Linux): %s @ %s Port:%d\n", cErrorMsg,sIPAddress,nPortNr);
       
   241       return (CAN_HANDLE) NULL;
       
   242    }
       
   243    
       
   244    // Inizial Baudrate
       
   245 
       
   246    if (nRetCode = CANSetGlobals (pNewAnaGatePort->hHandle, 
       
   247                         TranslateBaudeRate(board->baudrate), 
       
   248                         0,/*OperatingMode = normal*/ 
       
   249                         0,/*CAN-Termination = off*/ 
       
   250                         1 /*HighSpeedMode = on*/) ) 
       
   251    {
       
   252       CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge
       
   253       fprintf(stderr, "canOpen_driver (AnaGate_Linux): %s @ %s\n", cErrorMsg,sIPAddress);
       
   254       //printf("canOpen_driver (AnaGate_Linux): %s @ %s\n", cErrorMsg,sIPAddress);
       
   255       return (CAN_HANDLE) NULL;
       
   256    }
       
   257    
       
   258    // Creat receive and receive-acknoledge event 
       
   259    /*pNewAnaGatePort->hAnaRecEvent = CreateEvent(   
       
   260                                     NULL,  // default security attributes
       
   261                                     FALSE, // manual-reset event
       
   262                                     FALSE, // initial state is nonsignaled
       
   263                                     NULL  // object name
       
   264                                     ); 
       
   265 
       
   266    pNewAnaGatePort->hFesticalRecAcknowledge = CreateEvent( 
       
   267                                     NULL,  // default security attributes
       
   268                                     FALSE, // manual-reset event
       
   269                                     FALSE, // initial state is nonsignaled
       
   270                                     NULL   // object name
       
   271                                     ); 
       
   272          */
       
   273  
       
   274    pNewAnaGatePort->bBufferFull = 0;
       
   275  
       
   276    // Install receive callback funktion
       
   277 
       
   278    if (nRetCode = CANSetCallback(pNewAnaGatePort->hHandle,  AnaGateReceiveCallBack) ) 
       
   279    {
       
   280       canClose_driver (pNewAnaGatePort);
       
   281       CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge
       
   282       fprintf(stderr, "canOpen_driver (AnaGate_Linux): %s @ %s\n", cErrorMsg,sIPAddress);
       
   283       //printf("canOpen_driver (AnaGate_Linux): %s @ %s\n", cErrorMsg,sIPAddress);
       
   284       return (CAN_HANDLE) NULL;
       
   285    }
       
   286 
       
   287 
       
   288   return (CAN_HANDLE)pNewAnaGatePort;
       
   289 }
       
   290 
       
   291 /***************************************************************************/
       
   292 int canClose_driver(CAN_HANDLE fd0)
       
   293 {
       
   294    struct SAnaGatePort*  pAnaGatePort = (struct SAnaGatePort*)fd0;
       
   295    char cErrorMsg[100];
       
   296    int nRetCode;
       
   297 
       
   298    pAnaGatePort->bBufferFull = 1;  
       
   299    
       
   300    if ( nRetCode = CANCloseDevice(pAnaGatePort->hHandle) )
       
   301    {
       
   302      CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge
       
   303      fprintf(stderr, "canClose_driver (AnaGate_Linux): %s\n", cErrorMsg);
       
   304      printf("canClose_driver (AnaGate_Linux): %s\n", cErrorMsg);
       
   305    }
       
   306 
       
   307    if (pAnaGatePort->pNext == pAnaGatePort)
       
   308    {
       
   309        free (pAnaGatePort);
       
   310        pFistAnaGatePort=NULL;
       
   311    }
       
   312    else
       
   313    {  
       
   314       pAnaGatePort->pNext->pPrev = pAnaGatePort->pPrev;
       
   315       pAnaGatePort->pPrev->pNext = pAnaGatePort->pNext;
       
   316       free (pAnaGatePort);
       
   317    }
       
   318 
       
   319    return 0;
       
   320 }