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