drivers/can_peak/can_peak.c
changeset 0 4472ee7c6c3e
child 33 c767eabbaaac
equal deleted inserted replaced
-1:000000000000 0:4472ee7c6c3e
       
     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 #include <stdio.h>
       
    24 #include <string.h>
       
    25 #include <stdlib.h>
       
    26 #include <errno.h>
       
    27 #include <stddef.h> /* for NULL */
       
    28 #include <sys/ioctl.h>
       
    29 #include <fcntl.h>
       
    30 #include <signal.h>
       
    31 #include <sys/time.h>
       
    32 #include <unistd.h>
       
    33 
       
    34 /* driver pcan pci for Peak board */
       
    35 //#include "libpcan.h"
       
    36 //#include "pcan.h"
       
    37 
       
    38 #include "libpcan.h" // for CAN_HANDLE
       
    39 
       
    40 #include <applicfg.h>
       
    41 #include "timer.h"
       
    42 #include "can_driver.h"
       
    43 #include "timers_driver.h"
       
    44 
       
    45 #define MAX_NB_CAN_PORTS 16
       
    46 
       
    47 typedef struct {
       
    48   char used;
       
    49   HANDLE fd;
       
    50   TASK_HANDLE receiveTask;
       
    51   CO_Data* d;
       
    52 } CANPort;
       
    53 
       
    54 CANPort canports[MAX_NB_CAN_PORTS] = {{0,},};
       
    55 
       
    56 // Define for rtr CAN message
       
    57 #define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR 
       
    58 
       
    59 /*********functions which permit to communicate with the board****************/
       
    60 UNS8 canReceive(CAN_HANDLE fd0, Message *m)
       
    61 {
       
    62   UNS8 data; 
       
    63   TPCANMsg peakMsg;
       
    64   if ((errno = CAN_Read(((CANPort*)fd0)->fd, & peakMsg))) {		// Blocks until no new message or error.
       
    65     perror("!!! Peak board : error of reading. (from f_can_receive function) \n");
       
    66     return 1;
       
    67   }
       
    68   m->cob_id.w = peakMsg.ID;   
       
    69   if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST)         	/* bits of MSGTYPE_*/
       
    70     m->rtr = 0;
       
    71   else 
       
    72     m->rtr = 1;
       
    73   m->len = peakMsg.LEN;					/* count of data bytes (0..8) */
       
    74   for(data = 0  ; data < peakMsg.LEN ; data++)             			
       
    75     m->data[data] = peakMsg.DATA[data];         	/* data bytes, up to 8 */
       
    76   
       
    77   return 0;
       
    78 }
       
    79 
       
    80 void canReceiveLoop(CAN_HANDLE fd0)
       
    81 {
       
    82 	CO_Data* d = ((CANPort*)fd0)->d;
       
    83 	Message m;
       
    84 	while (1) {
       
    85 		if(!canReceive(fd0, &m))
       
    86 		{
       
    87 			EnterMutex();
       
    88 			canDispatch(d, &m);
       
    89 			LeaveMutex();
       
    90 		}else{
       
    91 //			printf("canReceive returned error\n");
       
    92 			break;
       
    93 		}
       
    94 	}
       
    95 }
       
    96 
       
    97 /***************************************************************************/
       
    98 UNS8 canSend(CAN_HANDLE fd0, Message *m)
       
    99 {
       
   100   UNS8 data;
       
   101   TPCANMsg peakMsg;
       
   102   peakMsg.ID=m -> cob_id.w;              			/* 11/29 bit code */
       
   103   if(m->rtr == 0)	
       
   104     peakMsg.MSGTYPE = CAN_INIT_TYPE_ST;       /* bits of MSGTYPE_*/
       
   105   else {
       
   106     peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR;       /* bits of MSGTYPE_*/
       
   107   }
       
   108   peakMsg.LEN = m->len;   
       
   109           			/* count of data bytes (0..8) */
       
   110   for(data = 0 ; data <  m->len; data ++)
       
   111   	peakMsg.DATA[data] = m->data[data];         	/* data bytes, up to 8 */
       
   112   
       
   113   if((errno = CAN_Write(((CANPort*)fd0)->fd, & peakMsg))) {
       
   114     perror("!!! Peak board : error of writing. (from canSend function) \n");
       
   115     return 1;
       
   116   }
       
   117   return 0;
       
   118 
       
   119 }
       
   120 
       
   121 /***************************************************************************/
       
   122 CAN_HANDLE canOpen(s_BOARD *board)
       
   123 {
       
   124   HANDLE fd0 = NULL;
       
   125   char busname[64];
       
   126   char* pEnd;
       
   127   int i;  
       
   128   
       
   129   for(i=0; i < MAX_NB_CAN_PORTS; i++)
       
   130   {
       
   131   	if(!canports[i].used)
       
   132 	  	break;
       
   133   }
       
   134 
       
   135   if(strtol(board->busname, &pEnd,0) >= 0)
       
   136   {
       
   137     sprintf(busname,"/dev/pcan%s",board->busname);
       
   138     fd0 = LINUX_CAN_Open(busname, O_RDWR);
       
   139   }
       
   140 
       
   141   if (i==MAX_NB_CAN_PORTS || fd0 == NULL)
       
   142     {
       
   143       fprintf (stderr, "Open failed.\n");
       
   144       return (CAN_HANDLE)NULL;
       
   145     }
       
   146 
       
   147    CAN_Init(fd0, board->baudrate, CAN_INIT_TYPE_ST);
       
   148 
       
   149    canports[i].used = 1;
       
   150    canports[i].fd = fd0;
       
   151 
       
   152    canports[i].d = board->d;
       
   153    CreateReceiveTask((CANPort*) &canports[i], &canports[i].receiveTask);
       
   154 
       
   155    return (CANPort*) &canports[i];
       
   156 }
       
   157 
       
   158 /***************************************************************************/
       
   159 int canClose(CAN_HANDLE fd0)
       
   160 {
       
   161   CAN_Close(((CANPort*)fd0)->fd);
       
   162   ((CANPort*)fd0)->used = 0;
       
   163   WaitReceiveTaskEnd(&((CANPort*)fd0)->receiveTask);
       
   164   return 0;
       
   165 }