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 = 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 */
137 #if defined DEBUG_MSG_CONSOLE_ON
142 //pthread_mutex_unlock (&PeakCan_mutex);
143 //if (Res != CAN_ERR_OK)
146 (Res & CAN_ERR_QRCVEMPTY || Res & CAN_ERR_BUSLIGHT
147 || Res & CAN_ERR_BUSHEAVY))
149 printf ("canReceive returned error (%d)\n", Res);
154 }while(Res != CAN_ERR_OK);
158 /***************************************************************************/
160 canSend_driver (CAN_HANDLE fd0, Message * m)
164 peakMsg.ID = m->cob_id; /* 11/29 bit code */
166 peakMsg.MSGTYPE = CAN_INIT_TYPE_ST; /* bits of MSGTYPE_ */
169 peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR; /* bits of MSGTYPE_ */
171 peakMsg.LEN = m->len;
172 /* count of data bytes (0..8) */
173 for (data = 0; data < m->len; data++)
174 peakMsg.DATA[data] = m->data[data]; /* data bytes, up to 8 */
179 // if not the first handler
180 if(second_board == (s_BOARD *)fd0)
182 errno = CAN2_Write (&peakMsg);
186 if(first_board == (s_BOARD *)fd0)
188 errno = CAN_Write (&peakMsg);
194 if (errno == CAN_ERR_BUSOFF)
196 printf ("!!! Peak board write : re-init\n");
197 canInit((s_BOARD*)fd0);
203 while (errno != CAN_ERR_OK);
204 #if defined DEBUG_MSG_CONSOLE_ON
213 /***************************************************************************/
214 UNS8 canChangeBaudRate_driver( CAN_HANDLE fd, char* baud)
216 printf("canChangeBaudRate not yet supported by this driver\n");
220 /***************************************************************************/
222 canOpen_driver (s_BOARD * board)
227 //printf ("Board Busname=%d.\n",strtol(board->busname, &pEnd,0));
228 if (strtol(board->busname, &pEnd,0) == 0)
231 printf ("First Board selected\n");
233 return (CAN_HANDLE)board;
236 if (strtol(board->busname, &pEnd,0) == 1)
238 second_board = board;
239 printf ("Second Board selected\n");
241 return (CAN_HANDLE)board;
247 /***************************************************************************/
249 canClose_driver (CAN_HANDLE fd0)
252 // if not the first handler
253 if(second_board == (s_BOARD *)fd0)
256 second_board = (s_BOARD *)NULL;
259 if(first_board == (s_BOARD *)fd0)
262 first_board = (s_BOARD *)NULL;