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