|
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 #define _CRT_SECURE_NO_DEPRECATE |
|
26 #else |
|
27 #include <stdio.h> |
|
28 #include <string.h> |
|
29 #include <errno.h> |
|
30 #include <fcntl.h> |
|
31 #endif |
|
32 |
|
33 #include "can_driver.h" |
|
34 #include "AnaGateDllCan.h" |
|
35 |
|
36 |
|
37 typedef struct SAnaGatePort |
|
38 { |
|
39 int hHandle; |
|
40 HANDLE hAnaRecEvent; |
|
41 HANDLE hFesticalRecAcknowledge; |
|
42 Message sMsgBuffer; |
|
43 struct SAnaGatePort *pNext; |
|
44 struct SAnaGatePort *pPrev; |
|
45 } SAnaGatePort; |
|
46 |
|
47 |
|
48 SAnaGatePort *pFirstAnaGatePort=NULL; |
|
49 |
|
50 |
|
51 /********* AnaGate API CAN receive callback Funciton ****************/ |
|
52 void WINAPI AnaGateReceiveCallBack (int nIdentifier, const char* pcBuffer, int nBufferLen, int nFlags, int hHandle) |
|
53 { |
|
54 SAnaGatePort *pAnaGatePort = pFirstAnaGatePort; |
|
55 int i; |
|
56 |
|
57 while (pAnaGatePort->hHandle != hHandle ) |
|
58 { |
|
59 pAnaGatePort = pAnaGatePort->pNext; |
|
60 if (pAnaGatePort == pFirstAnaGatePort ) |
|
61 { |
|
62 pAnaGatePort = NULL; |
|
63 printf("AnaGateReceiveCallBack (AnaGate_Win32): ERROR: Can't find AnaGatePort-Objekt to the Received Handle %d\n",hHandle); |
|
64 return; |
|
65 } |
|
66 } |
|
67 |
|
68 pAnaGatePort->sMsgBuffer.cob_id = nIdentifier; |
|
69 pAnaGatePort->sMsgBuffer.len= nBufferLen; |
|
70 if (nFlags == 2) |
|
71 pAnaGatePort->sMsgBuffer.rtr = 1; |
|
72 else |
|
73 pAnaGatePort->sMsgBuffer.rtr = 0; |
|
74 |
|
75 for (i = 0 ; i < nBufferLen; i++) |
|
76 { |
|
77 pAnaGatePort->sMsgBuffer.data[i] = pcBuffer[i]; |
|
78 } |
|
79 |
|
80 SetEvent(pAnaGatePort->hAnaRecEvent); |
|
81 |
|
82 WaitForSingleObject(pAnaGatePort->hFesticalRecAcknowledge,INFINITE); |
|
83 } |
|
84 |
|
85 |
|
86 /*********functions which permit to communicate with the board****************/ |
|
87 UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m) |
|
88 { |
|
89 SAnaGatePort* pAnaGatePort = (SAnaGatePort*)fd0; |
|
90 int i; |
|
91 |
|
92 WaitForSingleObject( // Wait for receive event |
|
93 pAnaGatePort->hAnaRecEvent, // event handle |
|
94 INFINITE); // indefinite wait |
|
95 |
|
96 |
|
97 m->cob_id = pAnaGatePort->sMsgBuffer.cob_id; |
|
98 m->len = pAnaGatePort->sMsgBuffer.len; |
|
99 m->rtr = pAnaGatePort->sMsgBuffer.rtr; |
|
100 for (i = 0 ; i < pAnaGatePort->sMsgBuffer.len; i++) |
|
101 { |
|
102 m->data[i] = pAnaGatePort->sMsgBuffer.data[i]; |
|
103 } |
|
104 |
|
105 SetEvent(pAnaGatePort->hFesticalRecAcknowledge); //Set Acknollede event |
|
106 |
|
107 return 0; |
|
108 } |
|
109 |
|
110 /***************************************************************************/ |
|
111 UNS8 canSend_driver(CAN_HANDLE fd0, Message *m) |
|
112 { |
|
113 SAnaGatePort* pAnaCanPort = (SAnaGatePort*)fd0; |
|
114 char cErrorMsg[100]; |
|
115 int nRetCode; |
|
116 int nMsgTyp; |
|
117 |
|
118 if (m->rtr == 0) |
|
119 { |
|
120 nMsgTyp = 0; //Normal; |
|
121 } |
|
122 else |
|
123 { |
|
124 nMsgTyp = 2; //Remote frame; |
|
125 } |
|
126 |
|
127 if ( (nRetCode = CANWrite(pAnaCanPort->hHandle , m->cob_id,(const char*) m->data, m->len, nMsgTyp) ) ) |
|
128 { |
|
129 CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge |
|
130 fprintf(stderr,"canSend_driver (AnaGate_Win32) %s \n",nRetCode); |
|
131 //printf("canSend_driver (AnaGate_Win32) %s \n",nRetCode); |
|
132 return 1; |
|
133 } |
|
134 |
|
135 return 0; |
|
136 } |
|
137 |
|
138 |
|
139 /***************************************************************************/ |
|
140 int TranslateBaudeRate(char* optarg){ |
|
141 if(!strcmp( optarg, "1M")) return 1000000; |
|
142 if(!strcmp( optarg, "800K")) return 800000; |
|
143 if(!strcmp( optarg, "500K")) return 500000; |
|
144 if(!strcmp( optarg, "250K")) return 250000; |
|
145 if(!strcmp( optarg, "125K")) return 125000; |
|
146 if(!strcmp( optarg, "100K")) return 100000; |
|
147 if(!strcmp( optarg, "50K")) return 50000; |
|
148 if(!strcmp( optarg, "20K")) return 20000; |
|
149 if(!strcmp( optarg, "10K")) return 10000; |
|
150 |
|
151 return 0x0000; |
|
152 } |
|
153 /****************************************************************************/ |
|
154 |
|
155 UNS8 canChangeBaudRate_driver( CAN_HANDLE fd0, char* baud) |
|
156 { |
|
157 int nRetCode; |
|
158 char cErrorMsg[100]; |
|
159 struct SAnaGatePort* pAnaGatePort = (struct SAnaGatePort*)fd0; |
|
160 |
|
161 if (nRetCode = CANSetGlobals (pAnaGatePort->hHandle, TranslateBaudeRate(baud), 0, 0, 1) ) |
|
162 { |
|
163 CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge |
|
164 fprintf(stderr, "canChangeBaudRate_drive (AnaGate_Win32): %s\n", cErrorMsg); |
|
165 printf("canChangeBaudRate_drive (AnaGate_Win32): %s\n", cErrorMsg); |
|
166 return 1; |
|
167 } |
|
168 return 0; |
|
169 } |
|
170 |
|
171 /***************************************************************************/ |
|
172 /* To open a connection to AnaGate CAN the s_BOARD board->busname must be |
|
173 the AnaGate IP-Adresse followed from the CAN-Port (A or B) you want to use |
|
174 For example "192.168.1.254:A" |
|
175 */ |
|
176 |
|
177 CAN_HANDLE canOpen_driver(s_BOARD *board) |
|
178 { |
|
179 int PortNr; |
|
180 char cErrorMsg[100]; |
|
181 int nRetCode; |
|
182 char sIPAddress[16]; |
|
183 struct SAnaGatePort *pNewAnaGatePort; |
|
184 char bBusnameValid = TRUE; |
|
185 unsigned int nBusnameLen; |
|
186 |
|
187 /////////////////////////////////////////// |
|
188 // Do some checkings concerning the busname |
|
189 // format should be IP-Adress:Port |
|
190 // e.g. 192.168.1.254:A |
|
191 /////////////////////////////////////////// |
|
192 nBusnameLen = strlen(board->busname); |
|
193 |
|
194 if ( nBusnameLen < strlen( "1.2.3.4:A" ) ) bBusnameValid = FALSE; // check minimum length of busname |
|
195 if ( nBusnameLen > strlen( "123.234.345.456:A" ) ) bBusnameValid = FALSE; // check maximum length of busname |
|
196 if ( bBusnameValid ) |
|
197 { |
|
198 switch (board->busname[nBusnameLen-1]) // check Portname of busname |
|
199 { |
|
200 case ('A'): PortNr = 0; break; |
|
201 case ('B'): PortNr = 1; break; |
|
202 case ('C'): PortNr = 2; break; |
|
203 case ('D'): PortNr = 3; break; |
|
204 default : bBusnameValid = FALSE; break; |
|
205 } |
|
206 if (board->busname[nBusnameLen-2] != ':' ) bBusnameValid = FALSE; // check Colon before Portname |
|
207 } |
|
208 |
|
209 if ( ! bBusnameValid ) |
|
210 { |
|
211 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); |
|
212 return (CAN_HANDLE) NULL; |
|
213 } |
|
214 |
|
215 board->busname[nBusnameLen-2] = 0; // NULL Terminator for IP Address string |
|
216 strcpy (sIPAddress, board->busname); |
|
217 |
|
218 pNewAnaGatePort = (SAnaGatePort*) malloc(sizeof (struct SAnaGatePort)); |
|
219 if (pFirstAnaGatePort == NULL) |
|
220 { |
|
221 pFirstAnaGatePort = pNewAnaGatePort; |
|
222 pNewAnaGatePort->pNext = pNewAnaGatePort; |
|
223 pNewAnaGatePort->pPrev = pNewAnaGatePort; |
|
224 } |
|
225 else |
|
226 { pNewAnaGatePort->pNext = pFirstAnaGatePort; |
|
227 pNewAnaGatePort->pPrev = pFirstAnaGatePort->pPrev; |
|
228 pFirstAnaGatePort->pPrev->pNext = pNewAnaGatePort; |
|
229 pFirstAnaGatePort->pPrev = pNewAnaGatePort; |
|
230 |
|
231 } |
|
232 // Connect to AnaGate |
|
233 if ( nRetCode = CANOpenDevice (&pNewAnaGatePort->hHandle, |
|
234 0, /*confirmation*/ |
|
235 1, /*Monitor*/ |
|
236 PortNr, |
|
237 sIPAddress, |
|
238 1000 /*TimeOut*/ ) ) |
|
239 { |
|
240 CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge |
|
241 fprintf(stderr, "canOpen_driver (AnaGate_Win32): %s @ %s\n", cErrorMsg,sIPAddress); |
|
242 //printf( "canOpen_driver (AnaGate_Win32): %s @ %s\n", cErrorMsg,sIPAddress); |
|
243 return (CAN_HANDLE) NULL; |
|
244 } |
|
245 |
|
246 // Inizial Baudrate |
|
247 if (nRetCode = CANSetGlobals (pNewAnaGatePort->hHandle, |
|
248 TranslateBaudeRate(board->baudrate), |
|
249 0,/*OperatingMode = normal*/ |
|
250 0,/*CAN-Termination = off*/ |
|
251 1 /*HighSpeedMode = on*/) ) |
|
252 { |
|
253 CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge |
|
254 fprintf(stderr, "canOpen_driver (AnaGate_Win32): %s @ %s\n", cErrorMsg,sIPAddress); |
|
255 //printf("canOpen_driver (AnaGate_Win32): %s @ %s\n", cErrorMsg,sIPAddress); |
|
256 return (CAN_HANDLE) NULL; |
|
257 } |
|
258 |
|
259 // Creat receive and receive-acknoledge event |
|
260 pNewAnaGatePort->hAnaRecEvent = CreateEvent( |
|
261 NULL, // default security attributes |
|
262 FALSE, // manual-reset event |
|
263 FALSE, // initial state is nonsignaled |
|
264 NULL // object name |
|
265 ); |
|
266 |
|
267 pNewAnaGatePort->hFesticalRecAcknowledge = CreateEvent( |
|
268 NULL, // default security attributes |
|
269 FALSE, // manual-reset event |
|
270 FALSE, // initial state is nonsignaled |
|
271 NULL // object name |
|
272 ); |
|
273 |
|
274 // Install receive callback funktion |
|
275 if (nRetCode = CANSetCallback(pNewAnaGatePort->hHandle, AnaGateReceiveCallBack) ) |
|
276 { |
|
277 canClose_driver (pNewAnaGatePort); |
|
278 CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge |
|
279 fprintf(stderr, "canOpen_driver (AnaGate_Win32): %s @ %s\n", cErrorMsg,sIPAddress); |
|
280 //printf("canOpen_driver (AnaGate_Win32): %s @ %s\n", cErrorMsg,sIPAddress); |
|
281 return (CAN_HANDLE) NULL; |
|
282 } |
|
283 |
|
284 return (CAN_HANDLE)pNewAnaGatePort; |
|
285 } |
|
286 |
|
287 /***************************************************************************/ |
|
288 int canClose_driver(CAN_HANDLE fd0) |
|
289 { |
|
290 SAnaGatePort* pAnaCanPort = (SAnaGatePort*)fd0; |
|
291 char cErrorMsg[100]; |
|
292 int nRetCode; |
|
293 |
|
294 |
|
295 SetEvent (pAnaCanPort->hAnaRecEvent); |
|
296 CloseHandle (pAnaCanPort->hAnaRecEvent); |
|
297 CloseHandle (pAnaCanPort->hFesticalRecAcknowledge); |
|
298 |
|
299 if ( nRetCode = CANCloseDevice(pAnaCanPort->hHandle) ) |
|
300 { |
|
301 CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge |
|
302 fprintf(stderr, "canClose_driver (AnaGate_Linux): %s\n", cErrorMsg); |
|
303 //printf("canClose_driver (AnaGate_Linux): %s\n", cErrorMsg); |
|
304 } |
|
305 |
|
306 if (pAnaCanPort->pNext == pAnaCanPort) |
|
307 { |
|
308 free (pAnaCanPort); |
|
309 pFirstAnaGatePort=NULL; |
|
310 } |
|
311 else |
|
312 { pAnaCanPort->pNext->pPrev = pAnaCanPort->pPrev; |
|
313 pAnaCanPort->pPrev->pNext = pAnaCanPort->pNext; |
|
314 free (pAnaCanPort); |
|
315 } |
|
316 |
|
317 return 0; |
|
318 } |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 |