40 slave->sii_revision_number = 0; |
50 slave->sii_revision_number = 0; |
41 slave->sii_serial_number = 0; |
51 slave->sii_serial_number = 0; |
42 slave->type = NULL; |
52 slave->type = NULL; |
43 slave->registered = 0; |
53 slave->registered = 0; |
44 slave->fmmu_count = 0; |
54 slave->fmmu_count = 0; |
|
55 |
|
56 INIT_LIST_HEAD(&slave->cat_strings); |
45 } |
57 } |
46 |
58 |
47 /*****************************************************************************/ |
59 /*****************************************************************************/ |
48 |
60 |
49 /** |
61 /** |
50 EtherCAT-Slave-Destruktor. |
62 EtherCAT-Slave-Destruktor. |
51 */ |
63 */ |
52 |
64 |
53 void ec_slave_clear(ec_slave_t *slave /**< EtherCAT-Slave */) |
65 void ec_slave_clear(ec_slave_t *slave /**< EtherCAT-Slave */) |
54 { |
66 { |
55 // Nichts freizugeben |
67 ec_slave_string_t *string, *next; |
|
68 |
|
69 // Alle Strings freigeben |
|
70 list_for_each_entry_safe(string, next, &slave->cat_strings, list) { |
|
71 list_del(&string->list); |
|
72 kfree(string); |
|
73 } |
56 } |
74 } |
57 |
75 |
58 /*****************************************************************************/ |
76 /*****************************************************************************/ |
59 |
77 |
60 /** |
78 /** |
250 return 0; |
273 return 0; |
251 } |
274 } |
252 } |
275 } |
253 |
276 |
254 if (unlikely((end - start) >= timeout)) { |
277 if (unlikely((end - start) >= timeout)) { |
255 EC_ERR("SSI-write: Slave %i timed out!\n", slave->ring_position); |
278 EC_ERR("SII-write: Slave %i timed out!\n", slave->ring_position); |
256 return -1; |
279 return -1; |
257 } |
280 } |
258 } |
281 } |
|
282 } |
|
283 |
|
284 /*****************************************************************************/ |
|
285 |
|
286 /** |
|
287 Holt Daten aus dem EEPROM. |
|
288 |
|
289 \return 0, wenn alles ok, sonst < 0 |
|
290 */ |
|
291 |
|
292 int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT-Slave */) |
|
293 { |
|
294 uint16_t word_offset, header, word_count; |
|
295 uint32_t value; |
|
296 uint8_t *cat_data; |
|
297 unsigned int i; |
|
298 |
|
299 word_offset = 0x0040; |
|
300 |
|
301 //EC_DBG("Slave %i...\n", slave->ring_position); |
|
302 |
|
303 if (!(cat_data = (uint8_t *) kmalloc(0x10000, GFP_KERNEL))) { |
|
304 EC_ERR("Failed to allocate 64k bytes for category data.\n"); |
|
305 return -1; |
|
306 } |
|
307 |
|
308 while (1) { |
|
309 // read category header |
|
310 if (ec_slave_sii_read(slave, word_offset, &value)) { |
|
311 EC_ERR("Unable to read category header and size.\n"); |
|
312 kfree(cat_data); |
|
313 return -1; |
|
314 } |
|
315 |
|
316 // Last category? |
|
317 if ((value & 0xFFFF) == 0xFFFF) break; |
|
318 |
|
319 header = value & 0x7FFF; |
|
320 word_count = (value >> 16) & 0xFFFF; |
|
321 |
|
322 // Fetch category data |
|
323 for (i = 0; i < word_count; i++) { |
|
324 if (ec_slave_sii_read(slave, word_offset + 2 + i, &value)) { |
|
325 EC_ERR("Unable to read category data word %i.\n", i); |
|
326 kfree(cat_data); |
|
327 return -1; |
|
328 } |
|
329 |
|
330 cat_data[i * 2] = (value >> 0) & 0xFF; |
|
331 cat_data[i * 2 + 1] = (value >> 8) & 0xFF; |
|
332 |
|
333 // read second word "on the fly" |
|
334 if (i + 1 < word_count) { |
|
335 i++; |
|
336 cat_data[i * 2] = (value >> 16) & 0xFF; |
|
337 cat_data[i * 2 + 1] = (value >> 24) & 0xFF; |
|
338 } |
|
339 } |
|
340 |
|
341 switch (header) |
|
342 { |
|
343 case 0x000A: |
|
344 if (ec_slave_fetch_strings(slave, cat_data)) { |
|
345 kfree(cat_data); |
|
346 return -1; |
|
347 } |
|
348 break; |
|
349 case 0x001E: |
|
350 case 0x0001: |
|
351 ec_slave_fetch_general(slave, cat_data); |
|
352 break; |
|
353 case 0x0028: |
|
354 case 0x0002: |
|
355 ec_slave_fetch_fmmu(slave, cat_data); |
|
356 break; |
|
357 case 0x0029: |
|
358 case 0x0003: |
|
359 ec_slave_fetch_sync(slave, cat_data); |
|
360 break; |
|
361 case 0x0032: |
|
362 case 0x0004: |
|
363 ec_slave_fetch_txpdo(slave, cat_data); |
|
364 break; |
|
365 case 0x0033: |
|
366 case 0x0005: |
|
367 ec_slave_fetch_rxpdo(slave, cat_data); |
|
368 break; |
|
369 default: |
|
370 EC_WARN("Unknown category header 0x%04X in slave %i.\n", |
|
371 header, slave->ring_position); |
|
372 } |
|
373 |
|
374 word_offset += 2 + word_count; |
|
375 } |
|
376 |
|
377 kfree(cat_data); |
|
378 return 0; |
|
379 } |
|
380 |
|
381 /*****************************************************************************/ |
|
382 |
|
383 /** |
|
384 Holt die Daten einer String-Kategorie. |
|
385 |
|
386 \return 0 wenn alles ok, sonst < 0 |
|
387 */ |
|
388 |
|
389 int ec_slave_fetch_strings(ec_slave_t *slave, /**< EtherCAT-Slave */ |
|
390 const uint8_t *data /**< Kategoriedaten */ |
|
391 ) |
|
392 { |
|
393 unsigned int string_count, i; |
|
394 size_t size; |
|
395 off_t offset; |
|
396 ec_slave_string_t *string; |
|
397 |
|
398 string_count = data[0]; |
|
399 offset = 1; |
|
400 for (i = 0; i < string_count; i++) { |
|
401 size = data[offset]; |
|
402 // Speicher für String-Objekt und Daten in einem Rutsch allozieren |
|
403 if (!(string = (ec_slave_string_t *) kmalloc(sizeof(ec_slave_string_t) |
|
404 + size + 1, |
|
405 GFP_KERNEL))) { |
|
406 EC_ERR("Failed to allocate string memory.\n"); |
|
407 return -1; |
|
408 } |
|
409 string->data = (char *) (string + sizeof(ec_slave_string_t)); |
|
410 memcpy(string->data, data + offset + 1, size); |
|
411 string->data[size] = 0x00; |
|
412 list_add_tail(&string->list, &slave->cat_strings); |
|
413 offset += 1 + size; |
|
414 } |
|
415 |
|
416 return 0; |
|
417 } |
|
418 |
|
419 /*****************************************************************************/ |
|
420 |
|
421 /** |
|
422 Holt die Daten einer General-Kategorie. |
|
423 */ |
|
424 |
|
425 void ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT-Slave */ |
|
426 const uint8_t *data /**< Kategorie-Daten */ |
|
427 ) |
|
428 { |
|
429 } |
|
430 |
|
431 /*****************************************************************************/ |
|
432 |
|
433 /** |
|
434 Holt die Daten einer FMMU-Kategorie. |
|
435 */ |
|
436 |
|
437 void ec_slave_fetch_fmmu(ec_slave_t *slave, /**< EtherCAT-Slave */ |
|
438 const uint8_t *data /**< Kategorie-Daten */ |
|
439 ) |
|
440 { |
|
441 } |
|
442 |
|
443 /*****************************************************************************/ |
|
444 |
|
445 /** |
|
446 Holt die Daten einer Sync-Manager-Kategorie. |
|
447 */ |
|
448 |
|
449 void ec_slave_fetch_sync(ec_slave_t *slave, /**< EtherCAT-Slave */ |
|
450 const uint8_t *data /**< Kategorie-Daten */ |
|
451 ) |
|
452 { |
|
453 } |
|
454 |
|
455 /*****************************************************************************/ |
|
456 |
|
457 /** |
|
458 Holt die Daten einer TXPDO-Kategorie. |
|
459 */ |
|
460 |
|
461 void ec_slave_fetch_txpdo(ec_slave_t *slave, /**< EtherCAT-Slave */ |
|
462 const uint8_t *data /**< Kategorie-Daten */ |
|
463 ) |
|
464 { |
|
465 } |
|
466 |
|
467 /*****************************************************************************/ |
|
468 |
|
469 /** |
|
470 Holt die Daten einer RXPDO-Kategorie. |
|
471 */ |
|
472 |
|
473 void ec_slave_fetch_rxpdo(ec_slave_t *slave, /**< EtherCAT-Slave */ |
|
474 const uint8_t *data /**< Kategorie-Daten */ |
|
475 ) |
|
476 { |
259 } |
477 } |
260 |
478 |
261 /*****************************************************************************/ |
479 /*****************************************************************************/ |
262 |
480 |
263 /** |
481 /** |
462 slave->sii_alias); |
682 slave->sii_alias); |
463 EC_INFO(" Vendor-ID: 0x%08X, Product code: 0x%08X\n", |
683 EC_INFO(" Vendor-ID: 0x%08X, Product code: 0x%08X\n", |
464 slave->sii_vendor_id, slave->sii_product_code); |
684 slave->sii_vendor_id, slave->sii_product_code); |
465 EC_INFO(" Revision number: 0x%08X, Serial number: 0x%08X\n", |
685 EC_INFO(" Revision number: 0x%08X, Serial number: 0x%08X\n", |
466 slave->sii_revision_number, slave->sii_serial_number); |
686 slave->sii_revision_number, slave->sii_serial_number); |
|
687 |
|
688 EC_INFO(" EEPROM strings:\n"); |
|
689 list_for_each_entry(string, &slave->cat_strings, list) { |
|
690 EC_INFO(" * \"%s\"\n", string->data); |
|
691 } |
467 } |
692 } |
468 |
693 |
469 /*****************************************************************************/ |
694 /*****************************************************************************/ |
470 |
695 |
471 /** |
696 /** |