17 #include "device.h" |
17 #include "device.h" |
18 #include "master.h" |
18 #include "master.h" |
19 |
19 |
20 /*****************************************************************************/ |
20 /*****************************************************************************/ |
21 |
21 |
|
22 void ec_data_print(const uint8_t *, size_t); |
|
23 void ec_data_print_diff(const uint8_t *, const uint8_t *, size_t); |
|
24 |
|
25 /*****************************************************************************/ |
|
26 |
22 /** |
27 /** |
23 EtherCAT-Geräte-Konstuktor. |
28 EtherCAT-Geräte-Konstuktor. |
24 |
29 |
25 \return 0 wenn alles ok, < 0 bei Fehler (zu wenig Speicher) |
30 \return 0 wenn alles ok, < 0 bei Fehler (zu wenig Speicher) |
26 */ |
31 */ |
27 |
32 |
28 int ec_device_init(ec_device_t *device, /**< EtherCAT-Gerät */ |
33 int ec_device_init(ec_device_t *device, /**< EtherCAT-Gerät */ |
29 ec_master_t *master /**< Zugehöriger Master */ |
34 ec_master_t *master, /**< Zugehöriger Master */ |
|
35 struct net_device *net_dev, /**< Net-Device */ |
|
36 ec_isr_t isr, /**< Adresse der ISR */ |
|
37 struct module *module /**< Modul-Adresse */ |
30 ) |
38 ) |
31 { |
39 { |
|
40 struct ethhdr *eth; |
|
41 |
32 device->master = master; |
42 device->master = master; |
33 device->dev = NULL; |
43 device->dev = net_dev; |
|
44 device->isr = isr; |
|
45 device->module = module; |
|
46 |
34 device->open = 0; |
47 device->open = 0; |
35 device->tx_time = 0; |
|
36 device->rx_time = 0; |
|
37 device->state = EC_DEVICE_STATE_READY; |
|
38 device->rx_data_size = 0; |
|
39 device->isr = NULL; |
|
40 device->module = NULL; |
|
41 device->error_reported = 0; |
|
42 device->link_state = 0; // down |
48 device->link_state = 0; // down |
43 |
49 |
44 if ((device->tx_skb = dev_alloc_skb(ETH_HLEN + EC_MAX_FRAME_SIZE)) == NULL) { |
50 if (!(device->tx_skb = dev_alloc_skb(ETH_HLEN + EC_MAX_FRAME_SIZE))) { |
45 EC_ERR("Error allocating device socket buffer!\n"); |
51 EC_ERR("Error allocating device socket buffer!\n"); |
46 return -1; |
52 return -1; |
47 } |
53 } |
48 |
54 |
|
55 device->tx_skb->dev = net_dev; |
|
56 |
|
57 // Ethernet-II-Header hinzufuegen |
|
58 skb_reserve(device->tx_skb, ETH_HLEN); |
|
59 eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN); |
|
60 eth->h_proto = htons(0x88A4); |
|
61 memcpy(eth->h_source, net_dev->dev_addr, net_dev->addr_len); |
|
62 memset(eth->h_dest, 0xFF, net_dev->addr_len); |
|
63 |
49 return 0; |
64 return 0; |
50 } |
65 } |
51 |
66 |
52 /*****************************************************************************/ |
67 /*****************************************************************************/ |
53 |
68 |
125 return -1; |
132 return -1; |
126 } |
133 } |
127 |
134 |
128 if (!device->open) { |
135 if (!device->open) { |
129 EC_WARN("Device already closed!\n"); |
136 EC_WARN("Device already closed!\n"); |
130 } |
137 return 0; |
131 else { |
138 } |
132 if (device->dev->stop(device->dev) == 0) device->open = 0; |
139 |
133 } |
140 if (device->dev->stop(device->dev) == 0) device->open = 0; |
134 |
141 |
135 return !device->open ? 0 : -1; |
142 return !device->open ? 0 : -1; |
136 } |
143 } |
137 |
144 |
138 /*****************************************************************************/ |
145 /*****************************************************************************/ |
139 |
146 |
140 /** |
147 /** |
141 Bereitet den geräteinternen Socket-Buffer auf den Versand vor. |
148 Liefert einen Zeiger auf den Sende-Speicher. |
142 |
149 |
143 \return Zeiger auf den Speicher, in den die Frame-Daten sollen. |
150 \return Zeiger auf den Speicher, in den die Frame-Daten sollen. |
144 */ |
151 */ |
145 |
152 |
146 uint8_t *ec_device_prepare(ec_device_t *device /**< EtherCAT-Gerät */) |
153 uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT-Gerät */) |
147 { |
154 { |
148 skb_trim(device->tx_skb, 0); // Auf Länge 0 abschneiden |
155 return device->tx_skb->data + ETH_HLEN; |
149 skb_reserve(device->tx_skb, ETH_HLEN); // Reserve für Ethernet-II-Header |
|
150 |
|
151 // Vorerst Speicher für maximal langen Frame reservieren |
|
152 return skb_put(device->tx_skb, EC_MAX_FRAME_SIZE); |
|
153 } |
156 } |
154 |
157 |
155 /*****************************************************************************/ |
158 /*****************************************************************************/ |
156 |
159 |
157 /** |
160 /** |
161 fügt den Ethernet-II-Header an und ruft die start_xmit()-Funktion der |
164 fügt den Ethernet-II-Header an und ruft die start_xmit()-Funktion der |
162 Netzwerkkarte auf. |
165 Netzwerkkarte auf. |
163 */ |
166 */ |
164 |
167 |
165 void ec_device_send(ec_device_t *device, /**< EtherCAT-Gerät */ |
168 void ec_device_send(ec_device_t *device, /**< EtherCAT-Gerät */ |
166 unsigned int length /**< Länge der zu sendenden Daten */ |
169 size_t size /**< Größe der zu sendenden Daten */ |
167 ) |
170 ) |
168 { |
171 { |
169 struct ethhdr *eth; |
|
170 |
|
171 if (unlikely(!device->link_state)) // Link down |
172 if (unlikely(!device->link_state)) // Link down |
172 return; |
173 return; |
173 |
174 |
174 // Framegröße auf (jetzt bekannte) Länge abschneiden |
175 // Framegröße auf (jetzt bekannte) Länge abschneiden |
175 skb_trim(device->tx_skb, length); |
176 device->tx_skb->len = ETH_HLEN + size; |
176 |
|
177 // Ethernet-II-Header hinzufuegen |
|
178 eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN); |
|
179 eth->h_proto = htons(0x88A4); |
|
180 memcpy(eth->h_source, device->dev->dev_addr, device->dev->addr_len); |
|
181 memset(eth->h_dest, 0xFF, device->dev->addr_len); |
|
182 |
|
183 device->state = EC_DEVICE_STATE_SENT; |
|
184 device->rx_data_size = 0; |
|
185 |
177 |
186 if (unlikely(device->master->debug_level > 1)) { |
178 if (unlikely(device->master->debug_level > 1)) { |
187 EC_DBG("Sending frame:\n"); |
179 EC_DBG("sending frame:\n"); |
188 ec_data_print(device->tx_skb->data + ETH_HLEN, device->tx_skb->len); |
180 ec_data_print(device->tx_skb->data + ETH_HLEN, size); |
189 } |
181 } |
190 |
182 |
191 // Senden einleiten |
183 // Senden einleiten |
192 rdtscl(device->tx_time); // Get CPU cycles |
|
193 device->dev->hard_start_xmit(device->tx_skb, device->dev); |
184 device->dev->hard_start_xmit(device->tx_skb, device->dev); |
194 } |
185 } |
195 |
186 |
196 /*****************************************************************************/ |
187 /*****************************************************************************/ |
197 |
188 |
198 /** |
189 /** |
199 Gibt die Anzahl der empfangenen Bytes zurück. |
|
200 |
|
201 \return Empfangene Bytes, oder 0, wenn kein Frame empfangen wurde. |
|
202 */ |
|
203 |
|
204 unsigned int ec_device_received(const ec_device_t *device) |
|
205 { |
|
206 return device->rx_data_size; |
|
207 } |
|
208 |
|
209 /*****************************************************************************/ |
|
210 |
|
211 /** |
|
212 Gibt die empfangenen Daten zurück. |
|
213 |
|
214 \return Zeiger auf empfangene Daten. |
|
215 */ |
|
216 |
|
217 uint8_t *ec_device_data(ec_device_t *device) |
|
218 { |
|
219 return device->rx_data; |
|
220 } |
|
221 |
|
222 /*****************************************************************************/ |
|
223 |
|
224 /** |
|
225 Ruft die Interrupt-Routine der Netzwerkkarte auf. |
190 Ruft die Interrupt-Routine der Netzwerkkarte auf. |
226 */ |
191 */ |
227 |
192 |
228 void ec_device_call_isr(ec_device_t *device /**< EtherCAT-Gerät */) |
193 void ec_device_call_isr(ec_device_t *device /**< EtherCAT-Gerät */) |
229 { |
194 { |
230 if (likely(device->isr)) device->isr(0, device->dev, NULL); |
195 if (likely(device->isr)) device->isr(0, device->dev, NULL); |
231 } |
|
232 |
|
233 /*****************************************************************************/ |
|
234 |
|
235 /** |
|
236 Gibt alle Informationen über das Device-Objekt aus. |
|
237 */ |
|
238 |
|
239 void ec_device_print(ec_device_t *device /**< EtherCAT-Gerät */) |
|
240 { |
|
241 EC_DBG("---EtherCAT device information begin---\n"); |
|
242 |
|
243 if (device) { |
|
244 EC_DBG("Assigned net_device: %X\n", (u32) device->dev); |
|
245 EC_DBG("Transmit socket buffer: %X\n", (u32) device->tx_skb); |
|
246 EC_DBG("Time of last transmission: %u\n", (u32) device->tx_time); |
|
247 EC_DBG("Time of last receive: %u\n", (u32) device->rx_time); |
|
248 EC_DBG("Actual device state: %i\n", (u8) device->state); |
|
249 EC_DBG("Receive buffer: %X\n", (u32) device->rx_data); |
|
250 EC_DBG("Receive buffer fill state: %u/%u\n", |
|
251 (u32) device->rx_data_size, EC_MAX_FRAME_SIZE); |
|
252 } |
|
253 else { |
|
254 EC_DBG("Device is NULL!\n"); |
|
255 } |
|
256 |
|
257 EC_DBG("---EtherCAT device information end---\n"); |
|
258 } |
|
259 |
|
260 /*****************************************************************************/ |
|
261 |
|
262 /** |
|
263 Gibt das letzte Rahmenpaar aus. |
|
264 */ |
|
265 |
|
266 void ec_device_debug(const ec_device_t *device /**< EtherCAT-Gerät */) |
|
267 { |
|
268 EC_DBG(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); |
|
269 ec_data_print(device->tx_skb->data + ETH_HLEN, device->tx_skb->len); |
|
270 EC_DBG("--------------------------------------\n"); |
|
271 ec_data_print_diff(device->tx_skb->data + ETH_HLEN, device->rx_data, |
|
272 device->rx_data_size); |
|
273 EC_DBG("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); |
|
274 } |
196 } |
275 |
197 |
276 /*****************************************************************************/ |
198 /*****************************************************************************/ |
277 |
199 |
278 /** |
200 /** |
364 void EtherCAT_dev_receive(ec_device_t *device, /**< EtherCAT-Gerät */ |
273 void EtherCAT_dev_receive(ec_device_t *device, /**< EtherCAT-Gerät */ |
365 const void *data, /**< Zeiger auf empfangene Daten */ |
274 const void *data, /**< Zeiger auf empfangene Daten */ |
366 size_t size /**< Größe der empfangenen Daten */ |
275 size_t size /**< Größe der empfangenen Daten */ |
367 ) |
276 ) |
368 { |
277 { |
369 // Copy received data to ethercat-device buffer |
|
370 memcpy(device->rx_data, data, size); |
|
371 device->rx_data_size = size; |
|
372 device->state = EC_DEVICE_STATE_RECEIVED; |
|
373 |
|
374 if (unlikely(device->master->debug_level > 1)) { |
278 if (unlikely(device->master->debug_level > 1)) { |
375 EC_DBG("Received frame:\n"); |
279 EC_DBG("Received frame:\n"); |
376 ec_data_print_diff(device->tx_skb->data + ETH_HLEN, device->rx_data, |
280 ec_data_print_diff(device->tx_skb->data + ETH_HLEN, data, size); |
377 device->rx_data_size); |
281 } |
378 } |
282 |
|
283 ec_master_receive(device->master, data, size); |
379 } |
284 } |
380 |
285 |
381 /*****************************************************************************/ |
286 /*****************************************************************************/ |
382 |
287 |
383 /** |
288 /** |