77 |
74 |
78 Dies entspricht einem "ifconfig up". Vorher wird der Zeiger |
75 Dies entspricht einem "ifconfig up". Vorher wird der Zeiger |
79 auf das EtherCAT-Gerät auf Gültigkeit geprüft und der |
76 auf das EtherCAT-Gerät auf Gültigkeit geprüft und der |
80 Gerätezustand zurückgesetzt. |
77 Gerätezustand zurückgesetzt. |
81 |
78 |
82 @param ecd EtherCAT-Gerät |
79 \return 0 bei Erfolg, < 0: Ungültiger Zeiger, oder open() |
83 |
80 fehlgeschlagen |
84 @return 0 bei Erfolg, < 0: Ungültiger Zeiger, oder open() |
81 */ |
85 fehlgeschlagen |
82 |
86 */ |
83 int ec_device_open(ec_device_t *device /**< EtherCAT-Gerät */) |
87 |
|
88 int ec_device_open(ec_device_t *ecd) |
|
89 { |
84 { |
90 unsigned int i; |
85 unsigned int i; |
91 |
86 |
92 if (!ecd) { |
87 if (!device) { |
93 printk(KERN_ERR "EtherCAT: Trying to open a NULL device!\n"); |
88 printk(KERN_ERR "EtherCAT: Trying to open a NULL device!\n"); |
94 return -1; |
89 return -1; |
95 } |
90 } |
96 |
91 |
97 if (!ecd->dev) { |
92 if (!device->dev) { |
98 printk(KERN_ERR "EtherCAT: No net_device to open!\n"); |
93 printk(KERN_ERR "EtherCAT: No net_device to open!\n"); |
99 return -1; |
94 return -1; |
100 } |
95 } |
101 |
96 |
102 if (ecd->open) { |
97 if (device->open) { |
103 printk(KERN_WARNING "EtherCAT: Device already opened!\n"); |
98 printk(KERN_WARNING "EtherCAT: Device already opened!\n"); |
104 } |
99 } |
105 else { |
100 else { |
106 // Device could have received frames before |
101 // Device could have received frames before |
107 for (i = 0; i < 4; i++) ec_device_call_isr(ecd); |
102 for (i = 0; i < 4; i++) ec_device_call_isr(device); |
108 |
103 |
109 // Reset old device state |
104 // Reset old device state |
110 ecd->state = EC_DEVICE_STATE_READY; |
105 device->state = EC_DEVICE_STATE_READY; |
111 |
106 |
112 if (ecd->dev->open(ecd->dev) == 0) ecd->open = 1; |
107 if (device->dev->open(device->dev) == 0) device->open = 1; |
113 } |
108 } |
114 |
109 |
115 return ecd->open ? 0 : -1; |
110 return device->open ? 0 : -1; |
116 } |
111 } |
117 |
112 |
118 /*****************************************************************************/ |
113 /*****************************************************************************/ |
119 |
114 |
120 /** |
115 /** |
121 Führt die stop()-Funktion des net_devices aus. |
116 Führt die stop()-Funktion des net_devices aus. |
122 |
117 |
123 @param ecd EtherCAT-Gerät |
118 \return 0 bei Erfolg, < 0: Kein Gerät zum Schliessen oder |
124 |
|
125 @return 0 bei Erfolg, < 0: Kein Gerät zum Schliessen oder |
|
126 Schliessen fehlgeschlagen. |
119 Schliessen fehlgeschlagen. |
127 */ |
120 */ |
128 |
121 |
129 int ec_device_close(ec_device_t *ecd) |
122 int ec_device_close(ec_device_t *device /**< EtherCAT-Gerät */) |
130 { |
123 { |
131 if (!ecd->dev) { |
124 if (!device->dev) { |
132 printk(KERN_ERR "EtherCAT: No device to close!\n"); |
125 printk(KERN_ERR "EtherCAT: No device to close!\n"); |
133 return -1; |
126 return -1; |
134 } |
127 } |
135 |
128 |
136 if (!ecd->open) { |
129 if (!device->open) { |
137 printk(KERN_WARNING "EtherCAT: Device already closed!\n"); |
130 printk(KERN_WARNING "EtherCAT: Device already closed!\n"); |
138 } |
131 } |
139 else { |
132 else { |
140 if (ecd->dev->stop(ecd->dev) == 0) ecd->open = 0; |
133 if (device->dev->stop(device->dev) == 0) device->open = 0; |
141 } |
134 } |
142 |
135 |
143 return !ecd->open ? 0 : -1; |
136 return !device->open ? 0 : -1; |
144 } |
137 } |
145 |
138 |
146 /*****************************************************************************/ |
139 /*****************************************************************************/ |
147 |
140 |
148 /** |
141 /** |
149 Bereitet den geräteinternen Socket-Buffer auf den Versand vor. |
142 Bereitet den geräteinternen Socket-Buffer auf den Versand vor. |
150 |
143 |
151 \return Zeiger auf den Speicher, in den die Frame-Daten sollen. |
144 \return Zeiger auf den Speicher, in den die Frame-Daten sollen. |
152 */ |
145 */ |
153 |
146 |
154 uint8_t *ec_device_prepare(ec_device_t *ecd /**< EtherCAT-Gerät */) |
147 uint8_t *ec_device_prepare(ec_device_t *device /**< EtherCAT-Gerät */) |
155 { |
148 { |
156 // Clear transmit socket buffer and reserve space for Ethernet-II header |
149 // Clear transmit socket buffer and reserve space for Ethernet-II header |
157 skb_trim(ecd->tx_skb, 0); |
150 skb_trim(device->tx_skb, 0); |
158 skb_reserve(ecd->tx_skb, ETH_HLEN); |
151 skb_reserve(device->tx_skb, ETH_HLEN); |
159 |
152 |
160 // Erstmal Speicher für maximal langen Frame reservieren |
153 // Erstmal Speicher für maximal langen Frame reservieren |
161 return skb_put(ecd->tx_skb, EC_MAX_FRAME_SIZE); |
154 return skb_put(device->tx_skb, EC_MAX_FRAME_SIZE); |
162 } |
155 } |
163 |
156 |
164 /*****************************************************************************/ |
157 /*****************************************************************************/ |
165 |
158 |
166 /** |
159 /** |
172 |
165 |
173 \return 0 bei Erfolg, < 0: Vorheriger Rahmen noch |
166 \return 0 bei Erfolg, < 0: Vorheriger Rahmen noch |
174 nicht empfangen, oder kein Speicher mehr vorhanden |
167 nicht empfangen, oder kein Speicher mehr vorhanden |
175 */ |
168 */ |
176 |
169 |
177 void ec_device_send(ec_device_t *ecd, /**< EtherCAT-Gerät */ |
170 void ec_device_send(ec_device_t *device, /**< EtherCAT-Gerät */ |
178 unsigned int length /**< Länge der zu sendenden Daten */ |
171 unsigned int length /**< Länge der zu sendenden Daten */ |
179 ) |
172 ) |
180 { |
173 { |
181 struct ethhdr *eth; |
174 struct ethhdr *eth; |
182 |
175 |
183 // Framegroesse auf (jetzt bekannte) Laenge abschneiden |
176 // Framegroesse auf (jetzt bekannte) Laenge abschneiden |
184 skb_trim(ecd->tx_skb, length); |
177 skb_trim(device->tx_skb, length); |
185 |
178 |
186 // Ethernet-II-Header hinzufuegen |
179 // Ethernet-II-Header hinzufuegen |
187 eth = (struct ethhdr *) skb_push(ecd->tx_skb, ETH_HLEN); |
180 eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN); |
188 eth->h_proto = htons(0x88A4); |
181 eth->h_proto = htons(0x88A4); |
189 memcpy(eth->h_source, ecd->dev->dev_addr, ecd->dev->addr_len); |
182 memcpy(eth->h_source, device->dev->dev_addr, device->dev->addr_len); |
190 memset(eth->h_dest, 0xFF, ecd->dev->addr_len); |
183 memset(eth->h_dest, 0xFF, device->dev->addr_len); |
191 |
184 |
192 ecd->state = EC_DEVICE_STATE_SENT; |
185 device->state = EC_DEVICE_STATE_SENT; |
193 ecd->rx_data_length = 0; |
186 device->rx_data_size = 0; |
|
187 |
|
188 if (unlikely(device->master->debug_level > 1)) { |
|
189 printk(KERN_DEBUG "EtherCAT: Sending frame:\n"); |
|
190 ec_data_print(device->tx_skb->data + ETH_HLEN, device->tx_skb->len); |
|
191 } |
194 |
192 |
195 // Senden einleiten |
193 // Senden einleiten |
196 rdtscl(ecd->tx_time); // Get CPU cycles |
194 rdtscl(device->tx_time); // Get CPU cycles |
197 ecd->dev->hard_start_xmit(ecd->tx_skb, ecd->dev); |
195 device->dev->hard_start_xmit(device->tx_skb, device->dev); |
198 } |
196 } |
199 |
197 |
200 /*****************************************************************************/ |
198 /*****************************************************************************/ |
201 |
199 |
202 /** |
200 /** |
203 Gibt die Anzahl der empfangenen Bytes zurück. |
201 Gibt die Anzahl der empfangenen Bytes zurück. |
204 |
202 |
205 \return Empfangene Bytes, oder 0, wenn kein Frame empfangen wurde. |
203 \return Empfangene Bytes, oder 0, wenn kein Frame empfangen wurde. |
206 */ |
204 */ |
207 |
205 |
208 unsigned int ec_device_received(const ec_device_t *ecd) |
206 unsigned int ec_device_received(const ec_device_t *device) |
209 { |
207 { |
210 return ecd->rx_data_length; |
208 return device->rx_data_size; |
211 } |
209 } |
212 |
210 |
213 /*****************************************************************************/ |
211 /*****************************************************************************/ |
214 |
212 |
215 /** |
213 /** |
216 Gibt die empfangenen Daten zurück. |
214 Gibt die empfangenen Daten zurück. |
217 |
215 |
218 \return Adresse auf empfangene Daten. |
216 \return Adresse auf empfangene Daten. |
219 */ |
217 */ |
220 |
218 |
221 uint8_t *ec_device_data(ec_device_t *ecd) |
219 uint8_t *ec_device_data(ec_device_t *device) |
222 { |
220 { |
223 return ecd->rx_data; |
221 return device->rx_data; |
224 } |
222 } |
225 |
223 |
226 /*****************************************************************************/ |
224 /*****************************************************************************/ |
227 |
225 |
228 /** |
226 /** |
229 Ruft die Interrupt-Routine der Netzwerkkarte auf. |
227 Ruft die Interrupt-Routine der Netzwerkkarte auf. |
230 |
228 */ |
231 @param ecd EtherCAT-Gerät |
229 |
232 |
230 void ec_device_call_isr(ec_device_t *device /**< EtherCAT-Gerät */) |
233 @return Anzahl der kopierten Bytes bei Erfolg, sonst < 0 |
231 { |
234 */ |
232 if (likely(device->isr)) device->isr(0, device->dev, NULL); |
235 |
|
236 void ec_device_call_isr(ec_device_t *ecd) |
|
237 { |
|
238 if (likely(ecd->isr)) ecd->isr(0, ecd->dev, NULL); |
|
239 } |
233 } |
240 |
234 |
241 /*****************************************************************************/ |
235 /*****************************************************************************/ |
242 |
236 |
243 /** |
237 /** |
244 Gibt alle Informationen über das Device-Objekt aus. |
238 Gibt alle Informationen über das Device-Objekt aus. |
245 |
239 */ |
246 @param ecd EtherCAT-Gerät |
240 |
247 */ |
241 void ec_device_print(ec_device_t *device /**< EtherCAT-Gerät */) |
248 |
|
249 void ec_device_print(ec_device_t *ecd) |
|
250 { |
242 { |
251 printk(KERN_DEBUG "---EtherCAT device information begin---\n"); |
243 printk(KERN_DEBUG "---EtherCAT device information begin---\n"); |
252 |
244 |
253 if (ecd) |
245 if (device) |
254 { |
246 { |
255 printk(KERN_DEBUG "Assigned net_device: %X\n", |
247 printk(KERN_DEBUG "Assigned net_device: %X\n", |
256 (unsigned) ecd->dev); |
248 (unsigned) device->dev); |
257 printk(KERN_DEBUG "Transmit socket buffer: %X\n", |
249 printk(KERN_DEBUG "Transmit socket buffer: %X\n", |
258 (unsigned) ecd->tx_skb); |
250 (unsigned) device->tx_skb); |
259 printk(KERN_DEBUG "Time of last transmission: %u\n", |
251 printk(KERN_DEBUG "Time of last transmission: %u\n", |
260 (unsigned) ecd->tx_time); |
252 (unsigned) device->tx_time); |
261 printk(KERN_DEBUG "Time of last receive: %u\n", |
253 printk(KERN_DEBUG "Time of last receive: %u\n", |
262 (unsigned) ecd->rx_time); |
254 (unsigned) device->rx_time); |
263 printk(KERN_DEBUG "Actual device state: %i\n", |
255 printk(KERN_DEBUG "Actual device state: %i\n", |
264 (int) ecd->state); |
256 (int) device->state); |
265 printk(KERN_DEBUG "Receive buffer: %X\n", |
257 printk(KERN_DEBUG "Receive buffer: %X\n", |
266 (unsigned) ecd->rx_data); |
258 (unsigned) device->rx_data); |
267 printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n", |
259 printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n", |
268 (unsigned) ecd->rx_data_length, EC_MAX_FRAME_SIZE); |
260 (unsigned) device->rx_data_size, EC_MAX_FRAME_SIZE); |
269 } |
261 } |
270 else |
262 else |
271 { |
263 { |
272 printk(KERN_DEBUG "Device is NULL!\n"); |
264 printk(KERN_DEBUG "Device is NULL!\n"); |
273 } |
265 } |
274 |
266 |
275 printk(KERN_DEBUG "---EtherCAT device information end---\n"); |
267 printk(KERN_DEBUG "---EtherCAT device information end---\n"); |
276 } |
268 } |
277 |
269 |
|
270 /*****************************************************************************/ |
|
271 |
|
272 /** |
|
273 Gibt das letzte Rahmenpaar aus. |
|
274 */ |
|
275 |
|
276 void ec_device_debug(const ec_device_t *device /**< EtherCAT-Gerät */) |
|
277 { |
|
278 printk(KERN_DEBUG "EtherCAT: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); |
|
279 ec_data_print(device->tx_skb->data + ETH_HLEN, device->tx_skb->len); |
|
280 printk(KERN_DEBUG "------------------------------------------------\n"); |
|
281 ec_data_print_diff(device->tx_skb->data + ETH_HLEN, device->rx_data, |
|
282 device->rx_data_size); |
|
283 printk(KERN_DEBUG "EtherCAT: <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); |
|
284 } |
|
285 |
|
286 /*****************************************************************************/ |
|
287 |
|
288 /** |
|
289 Gibt Frame-Inhalte zwecks Debugging aus. |
|
290 */ |
|
291 |
|
292 void ec_data_print(const uint8_t *data /**< Daten */, |
|
293 size_t size /**< Anzahl Bytes */ |
|
294 ) |
|
295 { |
|
296 size_t i; |
|
297 |
|
298 printk(KERN_DEBUG); |
|
299 for (i = 0; i < size; i++) { |
|
300 printk("%02X ", data[i]); |
|
301 if ((i + 1) % 16 == 0) printk("\n" KERN_DEBUG); |
|
302 } |
|
303 printk("\n"); |
|
304 } |
|
305 |
|
306 /*****************************************************************************/ |
|
307 |
|
308 /** |
|
309 Gibt Frame-Inhalte zwecks Debugging aus, differentiell. |
|
310 */ |
|
311 |
|
312 void ec_data_print_diff(const uint8_t *d1, /**< Daten 1 */ |
|
313 const uint8_t *d2, /**< Daten 2 */ |
|
314 size_t size /** Anzahl Bytes */ |
|
315 ) |
|
316 { |
|
317 size_t i; |
|
318 |
|
319 printk(KERN_DEBUG); |
|
320 for (i = 0; i < size; i++) { |
|
321 if (d1[i] == d2[i]) printk(".. "); |
|
322 else printk("%02X ", d2[i]); |
|
323 if ((i + 1) % 16 == 0) printk("\n" KERN_DEBUG); |
|
324 } |
|
325 printk("\n"); |
|
326 } |
|
327 |
278 /****************************************************************************** |
328 /****************************************************************************** |
279 * |
329 * |
280 * Treiberschnittstelle |
330 * Treiberschnittstelle |
281 * |
331 * |
282 *****************************************************************************/ |
332 *****************************************************************************/ |
283 |
333 |
284 void EtherCAT_dev_state(ec_device_t *ecd, ec_device_state_t state) |
334 /** |
285 { |
335 Setzt den Zustand des EtherCAT-Gerätes. |
286 ecd->state = state; |
336 */ |
287 } |
337 |
288 |
338 void EtherCAT_dev_state(ec_device_t *device, /**< EtherCAT-Gerät */ |
289 /*****************************************************************************/ |
339 ec_device_state_t state /**< Neuer Zustand */ |
290 |
340 ) |
291 int EtherCAT_dev_is_ec(ec_device_t *ecd, struct net_device *dev) |
341 { |
292 { |
342 device->state = state; |
293 return ecd && ecd->dev == dev; |
343 } |
294 } |
344 |
295 |
345 /*****************************************************************************/ |
296 /*****************************************************************************/ |
346 |
297 |
347 /** |
298 void EtherCAT_dev_receive(ec_device_t *ecd, void *data, unsigned int size) |
348 Prüft, ob das Net-Device \a dev zum registrierten EtherCAT-Gerät gehört. |
|
349 */ |
|
350 |
|
351 int EtherCAT_dev_is_ec(const ec_device_t *device, /**< EtherCAT-Gerät */ |
|
352 const struct net_device *dev /**< Net-Device */ |
|
353 ) |
|
354 { |
|
355 return device && device->dev == dev; |
|
356 } |
|
357 |
|
358 /*****************************************************************************/ |
|
359 |
|
360 void EtherCAT_dev_receive(ec_device_t *device, const void *data, size_t size) |
299 { |
361 { |
300 // Copy received data to ethercat-device buffer |
362 // Copy received data to ethercat-device buffer |
301 memcpy(ecd->rx_data, data, size); |
363 memcpy(device->rx_data, data, size); |
302 ecd->rx_data_length = size; |
364 device->rx_data_size = size; |
303 ecd->state = EC_DEVICE_STATE_RECEIVED; |
365 device->state = EC_DEVICE_STATE_RECEIVED; |
|
366 |
|
367 if (unlikely(device->master->debug_level > 1)) { |
|
368 printk(KERN_DEBUG "EtherCAT: Received frame:\n"); |
|
369 ec_data_print_diff(device->tx_skb->data + ETH_HLEN, device->rx_data, |
|
370 device->rx_data_size); |
|
371 } |
304 } |
372 } |
305 |
373 |
306 /*****************************************************************************/ |
374 /*****************************************************************************/ |
307 |
375 |
308 EXPORT_SYMBOL(EtherCAT_dev_is_ec); |
376 EXPORT_SYMBOL(EtherCAT_dev_is_ec); |