2 This file is part of CanFestival, a library implementing CanOpen Stack.
4 Copyright (C): Edouard TISSERANT and Francis DUPIN
6 See COPYING file for copyrights details.
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.
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.
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
23 #if defined(WIN32) && !defined(__CYGWIN__)
24 #define usleep(micro) Sleep(micro%1000 ? (micro/1000) + 1 : (micro/1000))
33 #include "can_driver.h"
35 #ifndef extra_PCAN_init_params
36 #define extra_PCAN_init_params /**/
38 #define extra_PCAN_init_params\
39 ,getenv("PCANHwType") ? strtol(getenv("PCANHwType"),NULL,0):0\
40 ,getenv("PCANIO_Port") ? strtol(getenv("PCANIO_Port"),NULL,0):0\
41 ,getenv("PCANInterupt") ? strtol(getenv("PCANInterupt"),NULL,0):0
44 static s_BOARD *first_board = NULL;
46 static s_BOARD *second_board = NULL;
49 //pthread_mutex_t PeakCan_mutex = PTHREAD_MUTEX_INITIALIZER;
51 // Define for rtr CAN message
52 #define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR
54 /***************************************************************************/
55 int TranslateBaudeRate(char* optarg){
56 if(!strcmp( optarg, "1M")) return CAN_BAUD_1M;
57 if(!strcmp( optarg, "500K")) return CAN_BAUD_500K;
58 if(!strcmp( optarg, "250K")) return CAN_BAUD_250K;
59 if(!strcmp( optarg, "125K")) return CAN_BAUD_125K;
60 if(!strcmp( optarg, "100K")) return CAN_BAUD_100K;
61 if(!strcmp( optarg, "50K")) return CAN_BAUD_50K;
62 if(!strcmp( optarg, "20K")) return CAN_BAUD_20K;
63 if(!strcmp( optarg, "10K")) return CAN_BAUD_10K;
64 if(!strcmp( optarg, "5K")) return CAN_BAUD_5K;
65 if(!strcmp( optarg, "none")) return 0;
70 canInit (s_BOARD *board)
75 // if not the first handler
76 if(second_board == (s_BOARD *)board)
77 if(baudrate = TranslateBaudeRate(board->baudrate))
79 CAN_INIT_TYPE_ST extra_PCAN_init_params);
81 if(first_board == (s_BOARD *)board)
82 if(baudrate = TranslateBaudeRate(board->baudrate))
84 CAN_INIT_TYPE_ST extra_PCAN_init_params);
87 /*********functions which permit to communicate with the board****************/
89 canReceive_driver (CAN_HANDLE fd0, Message * m)
95 // We read the queue looking for messages.
97 //pthread_mutex_lock (&PeakCan_mutex);
99 // if not the first handler
100 if(second_board == (s_BOARD *)fd0)
101 Res = CAN2_Read (&peakMsg);
104 if(first_board == (s_BOARD *)fd0)
105 Res = CAN_Read (&peakMsg);
107 Res = CAN_ERR_BUSOFF;
108 // A message was received
109 // We process the message(s)
111 if (Res == CAN_ERR_OK)
113 // if something different that 11bit or rtr... problem
114 if (peakMsg.MSGTYPE & ~(MSGTYPE_STANDARD | MSGTYPE_RTR))
116 if (peakMsg.MSGTYPE == CAN_ERR_BUSOFF)
118 printf ("!!! Peak board read : re-init\n");
119 canInit((s_BOARD*) fd0);
123 // If status, return status if 29bit, return overrun
124 //pthread_mutex_unlock (&PeakCan_mutex);
125 return peakMsg.MSGTYPE ==
126 MSGTYPE_STATUS ? peakMsg.DATA[2] : CAN_ERR_OVERRUN;
128 m->cob_id.w = peakMsg.ID;
130 if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST) /* bits of MSGTYPE_ */
134 m->len = peakMsg.LEN; /* count of data bytes (0..8) */
135 for (data = 0; data < peakMsg.LEN; data++)
136 m->data[data] = peakMsg.DATA[data]; /* data bytes, up to 8 */
139 //pthread_mutex_unlock (&PeakCan_mutex);
140 //if (Res != CAN_ERR_OK)
143 (Res & CAN_ERR_QRCVEMPTY || Res & CAN_ERR_BUSLIGHT
144 || Res & CAN_ERR_BUSHEAVY))
146 printf ("canReceive returned error (%d)\n", Res);
151 }while(Res != CAN_ERR_OK);
155 /***************************************************************************/
157 canSend_driver (CAN_HANDLE fd0, Message * m)
161 peakMsg.ID = m->cob_id.w; /* 11/29 bit code */
163 peakMsg.MSGTYPE = CAN_INIT_TYPE_ST; /* bits of MSGTYPE_ */
166 peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR; /* bits of MSGTYPE_ */
168 peakMsg.LEN = m->len;
169 /* count of data bytes (0..8) */
170 for (data = 0; data < m->len; data++)
171 peakMsg.DATA[data] = m->data[data]; /* data bytes, up to 8 */
176 // if not the first handler
177 if(second_board == (s_BOARD *)fd0)
179 errno = CAN2_Write (&peakMsg);
183 if(first_board == (s_BOARD *)fd0)
185 errno = CAN_Write (&peakMsg);
191 if (errno == CAN_ERR_BUSOFF)
193 printf ("!!! Peak board write : re-init\n");
194 canInit((s_BOARD*)fd0);
200 while (errno != CAN_ERR_OK);
206 /***************************************************************************/
208 canOpen_driver (s_BOARD * board)
213 //printf ("Board Busname=%d.\n",strtol(board->busname, &pEnd,0));
214 if (strtol(board->busname, &pEnd,0) == 0)
217 printf ("First Board selected\n");
219 return (CAN_HANDLE)board;
222 if (strtol(board->busname, &pEnd,0) == 1)
224 second_board = board;
225 printf ("Second Board selected\n");
227 return (CAN_HANDLE)board;
233 /***************************************************************************/
235 canClose_driver (CAN_HANDLE fd0)
238 // if not the first handler
239 if(second_board == (s_BOARD *)fd0)
242 second_board = (s_BOARD *)NULL;
245 if(first_board == (s_BOARD *)fd0)
248 first_board = (s_BOARD *)NULL;