]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - drivers/can_peak_win32/can_peak_win32.c
Changes to compile for win32
[CanFestival-3.git] / drivers / can_peak_win32 / can_peak_win32.c
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 #if defined(WIN32) && !defined(__CYGWIN__)
24 #define usleep(micro) Sleep(micro%1000 ? (micro/1000) + 1 : (micro/1000))
25 #else
26 #include <stdio.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #endif
31
32 #include "cancfg.h"
33 #include "can_driver.h"
34 #include "def.h"
35 #ifndef extra_PCAN_init_params
36         #define extra_PCAN_init_params /**/
37 #else
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
42 #endif
43
44 static s_BOARD *first_board = NULL;
45 #ifdef PCAN2_HEADER_
46 static s_BOARD *second_board = NULL;
47 #endif
48
49 //pthread_mutex_t PeakCan_mutex = PTHREAD_MUTEX_INITIALIZER;
50
51 // Define for rtr CAN message
52 #define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR
53
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;
66         return 0x0000;
67 }
68
69 void
70 canInit (s_BOARD *board)
71 {
72         int baudrate;
73         
74 #ifdef PCAN2_HEADER_
75         // if not the first handler
76         if(second_board == (s_BOARD *)board)
77                 if(baudrate = TranslateBaudeRate(board->baudrate))
78                         CAN2_Init (baudrate,
79                           CAN_INIT_TYPE_ST extra_PCAN_init_params);
80 #endif
81         if(first_board == (s_BOARD *)board)
82                 if(baudrate = TranslateBaudeRate(board->baudrate))
83                         CAN_Init (baudrate,
84                           CAN_INIT_TYPE_ST extra_PCAN_init_params);
85 }
86
87 /*********functions which permit to communicate with the board****************/
88 UNS8
89 canReceive_driver (CAN_HANDLE fd0, Message * m)
90 {
91         UNS8 data;
92         TPCANMsg peakMsg;
93         DWORD Res;
94         do{
95                 // We read the queue looking for messages.
96                 // 
97                 //pthread_mutex_lock (&PeakCan_mutex);
98 #ifdef PCAN2_HEADER_
99                 // if not the first handler
100                 if(second_board == (s_BOARD *)fd0)
101                         Res = CAN2_Read (&peakMsg);
102                 else
103 #endif
104                 if(first_board == (s_BOARD *)fd0)
105                         Res = CAN_Read (&peakMsg);
106                 else
107                         Res = CAN_ERR_BUSOFF;
108                 // A message was received
109                 // We process the message(s)
110                 // 
111                 if (Res == CAN_ERR_OK)
112                 {
113                         // if something different that 11bit or rtr... problem
114                         if (peakMsg.MSGTYPE & ~(MSGTYPE_STANDARD | MSGTYPE_RTR))
115                         {
116                                 if (peakMsg.MSGTYPE == CAN_ERR_BUSOFF)
117                                 {
118                                         printf ("!!! Peak board read : re-init\n");
119                                         canInit((s_BOARD*) fd0);
120                                         usleep (10000);
121                                 }
122         
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;
127                         }
128                         m->cob_id.w = peakMsg.ID;
129                         
130                         if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST)        /* bits of MSGTYPE_ */
131                                 m->rtr = 0;
132                         else
133                                 m->rtr = 1;
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                 
138                 }else{
139                 //pthread_mutex_unlock (&PeakCan_mutex);
140                 //if (Res != CAN_ERR_OK)
141                 //{
142                         if (!
143                                 (Res & CAN_ERR_QRCVEMPTY || Res & CAN_ERR_BUSLIGHT
144                                  || Res & CAN_ERR_BUSHEAVY))
145                         {
146                                 printf ("canReceive returned error (%d)\n", Res);
147                                 return 1;
148                         }
149                         usleep (1000);          
150                 }
151         }while(Res != CAN_ERR_OK);
152         return 0;
153 }
154
155 /***************************************************************************/
156 UNS8
157 canSend_driver (CAN_HANDLE fd0, Message * m)
158 {
159         UNS8 data;
160         TPCANMsg peakMsg;
161         peakMsg.ID = m->cob_id.w;       /* 11/29 bit code */
162         if (m->rtr == 0)
163                 peakMsg.MSGTYPE = CAN_INIT_TYPE_ST;     /* bits of MSGTYPE_ */
164         else
165         {
166                 peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR; /* bits of MSGTYPE_ */
167         }
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 */
172         
173         do
174         {
175 #ifdef PCAN2_HEADER_
176                 // if not the first handler
177                 if(second_board == (s_BOARD *)fd0)
178                 {
179                         errno = CAN2_Write (&peakMsg);
180                 }
181                 else 
182 #endif
183                 if(first_board == (s_BOARD *)fd0)
184                         {
185                                 errno = CAN_Write (&peakMsg);
186                         }
187                 else 
188                         goto fail;
189                 if (errno)
190                 {
191                         if (errno == CAN_ERR_BUSOFF)
192                         {
193                                 printf ("!!! Peak board write : re-init\n");
194                                 canInit((s_BOARD*)fd0);
195                                 usleep (10000);
196                         }
197                         usleep (1000);
198                 }
199         }
200         while (errno != CAN_ERR_OK);
201         return 0;
202 fail:
203         return 1;
204 }
205
206 /***************************************************************************/
207 CAN_HANDLE
208 canOpen_driver (s_BOARD * board)
209 {
210   char busname[64];
211   char* pEnd;
212         
213   //printf ("Board Busname=%d.\n",strtol(board->busname, &pEnd,0));
214   if (strtol(board->busname, &pEnd,0) == 0)
215   {
216       first_board = board;
217       printf ("First Board selected\n");
218       canInit(board);   
219       return (CAN_HANDLE)board;
220   }
221   #ifdef PCAN2_HEADER_
222   if (strtol(board->busname, &pEnd,0) == 1)
223   {
224       second_board = board;
225       printf ("Second Board selected\n");
226       canInit(board);   
227       return (CAN_HANDLE)board;
228   }
229   #endif
230   return NULL;
231 }
232
233 /***************************************************************************/
234 int
235 canClose_driver (CAN_HANDLE fd0)
236 {
237 #ifdef PCAN2_HEADER_
238         // if not the first handler
239         if(second_board == (s_BOARD *)fd0)
240         {
241                 CAN2_Close ();
242                 second_board = (s_BOARD *)NULL;
243         }else   
244 #endif
245         if(first_board == (s_BOARD *)fd0)
246         {
247                 CAN_Close ();
248                 first_board = (s_BOARD *)NULL;
249         }
250         return 0;
251 }