60 /*****************************************************************************/ |
60 /*****************************************************************************/ |
61 |
61 |
62 /** \cond */ |
62 /** \cond */ |
63 |
63 |
64 EC_SYSFS_READ_ATTR(ring_position); |
64 EC_SYSFS_READ_ATTR(ring_position); |
65 EC_SYSFS_READ_ATTR(coupler_address); |
65 EC_SYSFS_READ_ATTR(advanced_position); |
66 EC_SYSFS_READ_ATTR(vendor_name); |
66 EC_SYSFS_READ_ATTR(vendor_name); // deprecated |
67 EC_SYSFS_READ_ATTR(product_name); |
67 EC_SYSFS_READ_ATTR(product_name); // deprecated |
68 EC_SYSFS_READ_ATTR(product_desc); |
68 EC_SYSFS_READ_ATTR(product_desc); // deprecated |
69 EC_SYSFS_READ_ATTR(sii_name); |
69 EC_SYSFS_READ_ATTR(name); |
70 EC_SYSFS_READ_ATTR(type); |
70 EC_SYSFS_READ_ATTR(type); // deprecated |
71 EC_SYSFS_READ_WRITE_ATTR(state); |
71 EC_SYSFS_READ_WRITE_ATTR(state); |
72 EC_SYSFS_READ_WRITE_ATTR(eeprom); |
72 EC_SYSFS_READ_WRITE_ATTR(eeprom); |
73 |
73 |
74 static struct attribute *def_attrs[] = { |
74 static struct attribute *def_attrs[] = { |
75 &attr_ring_position, |
75 &attr_ring_position, |
76 &attr_coupler_address, |
76 &attr_advanced_position, |
77 &attr_vendor_name, |
77 &attr_vendor_name, |
78 &attr_product_name, |
78 &attr_product_name, |
79 &attr_product_desc, |
79 &attr_product_desc, |
80 &attr_sii_name, |
80 &attr_name, |
81 &attr_type, |
81 &attr_type, |
82 &attr_state, |
82 &attr_state, |
83 &attr_eeprom, |
83 &attr_eeprom, |
84 NULL, |
84 NULL, |
85 }; |
85 }; |
257 \return 0 in case of success, else < 0 |
257 \return 0 in case of success, else < 0 |
258 */ |
258 */ |
259 |
259 |
260 int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT slave */) |
260 int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT slave */) |
261 { |
261 { |
262 ec_command_t *command; |
262 ec_datagram_t *datagram; |
263 unsigned int i; |
263 unsigned int i; |
264 uint16_t dl_status; |
264 uint16_t dl_status; |
265 |
265 |
266 command = &slave->master->simple_command; |
266 datagram = &slave->master->simple_datagram; |
267 |
267 |
268 // read base data |
268 // read base data |
269 if (ec_command_nprd(command, slave->station_address, 0x0000, 6)) return -1; |
269 if (ec_datagram_nprd(datagram, slave->station_address, 0x0000, 6)) |
270 if (unlikely(ec_master_simple_io(slave->master, command))) { |
270 return -1; |
|
271 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
271 EC_ERR("Reading base data from slave %i failed!\n", |
272 EC_ERR("Reading base data from slave %i failed!\n", |
272 slave->ring_position); |
273 slave->ring_position); |
273 return -1; |
274 return -1; |
274 } |
275 } |
275 |
276 |
276 slave->base_type = EC_READ_U8 (command->data); |
277 slave->base_type = EC_READ_U8 (datagram->data); |
277 slave->base_revision = EC_READ_U8 (command->data + 1); |
278 slave->base_revision = EC_READ_U8 (datagram->data + 1); |
278 slave->base_build = EC_READ_U16(command->data + 2); |
279 slave->base_build = EC_READ_U16(datagram->data + 2); |
279 slave->base_fmmu_count = EC_READ_U8 (command->data + 4); |
280 slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4); |
280 slave->base_sync_count = EC_READ_U8 (command->data + 5); |
281 slave->base_sync_count = EC_READ_U8 (datagram->data + 5); |
281 |
282 |
282 if (slave->base_fmmu_count > EC_MAX_FMMUS) |
283 if (slave->base_fmmu_count > EC_MAX_FMMUS) |
283 slave->base_fmmu_count = EC_MAX_FMMUS; |
284 slave->base_fmmu_count = EC_MAX_FMMUS; |
284 |
285 |
285 // read data link status |
286 // read data link status |
286 if (ec_command_nprd(command, slave->station_address, 0x0110, 2)) return -1; |
287 if (ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2)) |
287 if (unlikely(ec_master_simple_io(slave->master, command))) { |
288 return -1; |
|
289 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
288 EC_ERR("Reading DL status from slave %i failed!\n", |
290 EC_ERR("Reading DL status from slave %i failed!\n", |
289 slave->ring_position); |
291 slave->ring_position); |
290 return -1; |
292 return -1; |
291 } |
293 } |
292 |
294 |
293 dl_status = EC_READ_U16(command->data); |
295 dl_status = EC_READ_U16(datagram->data); |
294 for (i = 0; i < 4; i++) { |
296 for (i = 0; i < 4; i++) { |
295 slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0; |
297 slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0; |
296 slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0; |
298 slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0; |
297 slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0; |
299 slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0; |
298 } |
300 } |
340 /**< address of the SII register to read */ |
342 /**< address of the SII register to read */ |
341 uint16_t *target |
343 uint16_t *target |
342 /**< target memory */ |
344 /**< target memory */ |
343 ) |
345 ) |
344 { |
346 { |
345 ec_command_t *command; |
347 ec_datagram_t *datagram; |
346 cycles_t start, end, timeout; |
348 cycles_t start, end, timeout; |
347 |
349 |
348 command = &slave->master->simple_command; |
350 datagram = &slave->master->simple_datagram; |
349 |
351 |
350 // initiate read operation |
352 // initiate read operation |
351 if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1; |
353 if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 6)) |
352 EC_WRITE_U8 (command->data, 0x00); // read-only access |
354 return -1; |
353 EC_WRITE_U8 (command->data + 1, 0x01); // request read operation |
355 EC_WRITE_U8 (datagram->data, 0x00); // read-only access |
354 EC_WRITE_U32(command->data + 2, offset); |
356 EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation |
355 if (unlikely(ec_master_simple_io(slave->master, command))) { |
357 EC_WRITE_U32(datagram->data + 2, offset); |
|
358 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
356 EC_ERR("SII-read failed on slave %i!\n", slave->ring_position); |
359 EC_ERR("SII-read failed on slave %i!\n", slave->ring_position); |
357 return -1; |
360 return -1; |
358 } |
361 } |
359 |
362 |
360 start = get_cycles(); |
363 start = get_cycles(); |
362 |
365 |
363 while (1) |
366 while (1) |
364 { |
367 { |
365 udelay(10); |
368 udelay(10); |
366 |
369 |
367 if (ec_command_nprd(command, slave->station_address, 0x502, 10)) |
370 if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 10)) |
368 return -1; |
371 return -1; |
369 if (unlikely(ec_master_simple_io(slave->master, command))) { |
372 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
370 EC_ERR("Getting SII-read status failed on slave %i!\n", |
373 EC_ERR("Getting SII-read status failed on slave %i!\n", |
371 slave->ring_position); |
374 slave->ring_position); |
372 return -1; |
375 return -1; |
373 } |
376 } |
374 |
377 |
375 end = get_cycles(); |
378 end = get_cycles(); |
376 |
379 |
377 // check for "busy bit" |
380 // check for "busy bit" |
378 if (likely((EC_READ_U8(command->data + 1) & 0x81) == 0)) { |
381 if (likely((EC_READ_U8(datagram->data + 1) & 0x81) == 0)) { |
379 *target = EC_READ_U16(command->data + 6); |
382 *target = EC_READ_U16(datagram->data + 6); |
380 return 0; |
383 return 0; |
381 } |
384 } |
382 |
385 |
383 if (unlikely((end - start) >= timeout)) { |
386 if (unlikely((end - start) >= timeout)) { |
384 EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position); |
387 EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position); |
400 /**< address of the SII register to read */ |
403 /**< address of the SII register to read */ |
401 uint32_t *target |
404 uint32_t *target |
402 /**< target memory */ |
405 /**< target memory */ |
403 ) |
406 ) |
404 { |
407 { |
405 ec_command_t *command; |
408 ec_datagram_t *datagram; |
406 cycles_t start, end, timeout; |
409 cycles_t start, end, timeout; |
407 |
410 |
408 command = &slave->master->simple_command; |
411 datagram = &slave->master->simple_datagram; |
409 |
412 |
410 // initiate read operation |
413 // initiate read operation |
411 if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1; |
414 if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 6)) |
412 EC_WRITE_U8 (command->data, 0x00); // read-only access |
415 return -1; |
413 EC_WRITE_U8 (command->data + 1, 0x01); // request read operation |
416 EC_WRITE_U8 (datagram->data, 0x00); // read-only access |
414 EC_WRITE_U32(command->data + 2, offset); |
417 EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation |
415 if (unlikely(ec_master_simple_io(slave->master, command))) { |
418 EC_WRITE_U32(datagram->data + 2, offset); |
|
419 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
416 EC_ERR("SII-read failed on slave %i!\n", slave->ring_position); |
420 EC_ERR("SII-read failed on slave %i!\n", slave->ring_position); |
417 return -1; |
421 return -1; |
418 } |
422 } |
419 |
423 |
420 start = get_cycles(); |
424 start = get_cycles(); |
422 |
426 |
423 while (1) |
427 while (1) |
424 { |
428 { |
425 udelay(10); |
429 udelay(10); |
426 |
430 |
427 if (ec_command_nprd(command, slave->station_address, 0x502, 10)) |
431 if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 10)) |
428 return -1; |
432 return -1; |
429 if (unlikely(ec_master_simple_io(slave->master, command))) { |
433 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
430 EC_ERR("Getting SII-read status failed on slave %i!\n", |
434 EC_ERR("Getting SII-read status failed on slave %i!\n", |
431 slave->ring_position); |
435 slave->ring_position); |
432 return -1; |
436 return -1; |
433 } |
437 } |
434 |
438 |
435 end = get_cycles(); |
439 end = get_cycles(); |
436 |
440 |
437 // check "busy bit" |
441 // check "busy bit" |
438 if (likely((EC_READ_U8(command->data + 1) & 0x81) == 0)) { |
442 if (likely((EC_READ_U8(datagram->data + 1) & 0x81) == 0)) { |
439 *target = EC_READ_U32(command->data + 6); |
443 *target = EC_READ_U32(datagram->data + 6); |
440 return 0; |
444 return 0; |
441 } |
445 } |
442 |
446 |
443 if (unlikely((end - start) >= timeout)) { |
447 if (unlikely((end - start) >= timeout)) { |
444 EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position); |
448 EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position); |
460 /**< address of the SII register to write */ |
464 /**< address of the SII register to write */ |
461 uint16_t value |
465 uint16_t value |
462 /**< new value */ |
466 /**< new value */ |
463 ) |
467 ) |
464 { |
468 { |
465 ec_command_t *command; |
469 ec_datagram_t *datagram; |
466 cycles_t start, end, timeout; |
470 cycles_t start, end, timeout; |
467 |
471 |
468 command = &slave->master->simple_command; |
472 datagram = &slave->master->simple_datagram; |
469 |
473 |
470 EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n", |
474 EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n", |
471 slave->ring_position, offset, value); |
475 slave->ring_position, offset, value); |
472 |
476 |
473 // initiate write operation |
477 // initiate write operation |
474 if (ec_command_npwr(command, slave->station_address, 0x502, 8)) return -1; |
478 if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 8)) |
475 EC_WRITE_U8 (command->data, 0x01); // enable write access |
479 return -1; |
476 EC_WRITE_U8 (command->data + 1, 0x02); // request write operation |
480 EC_WRITE_U8 (datagram->data, 0x01); // enable write access |
477 EC_WRITE_U32(command->data + 2, offset); |
481 EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation |
478 EC_WRITE_U16(command->data + 6, value); |
482 EC_WRITE_U32(datagram->data + 2, offset); |
479 if (unlikely(ec_master_simple_io(slave->master, command))) { |
483 EC_WRITE_U16(datagram->data + 6, value); |
|
484 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
480 EC_ERR("SII-write failed on slave %i!\n", slave->ring_position); |
485 EC_ERR("SII-write failed on slave %i!\n", slave->ring_position); |
481 return -1; |
486 return -1; |
482 } |
487 } |
483 |
488 |
484 start = get_cycles(); |
489 start = get_cycles(); |
486 |
491 |
487 while (1) |
492 while (1) |
488 { |
493 { |
489 udelay(10); |
494 udelay(10); |
490 |
495 |
491 if (ec_command_nprd(command, slave->station_address, 0x502, 2)) |
496 if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 2)) |
492 return -1; |
497 return -1; |
493 if (unlikely(ec_master_simple_io(slave->master, command))) { |
498 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
494 EC_ERR("Getting SII-write status failed on slave %i!\n", |
499 EC_ERR("Getting SII-write status failed on slave %i!\n", |
495 slave->ring_position); |
500 slave->ring_position); |
496 return -1; |
501 return -1; |
497 } |
502 } |
498 |
503 |
499 end = get_cycles(); |
504 end = get_cycles(); |
500 |
505 |
501 // check "busy bit" |
506 // check "busy bit" |
502 if (likely((EC_READ_U8(command->data + 1) & 0x82) == 0)) { |
507 if (likely((EC_READ_U8(datagram->data + 1) & 0x82) == 0)) { |
503 if (EC_READ_U8(command->data + 1) & 0x40) { |
508 if (EC_READ_U8(datagram->data + 1) & 0x40) { |
504 EC_ERR("SII-write failed!\n"); |
509 EC_ERR("SII-write failed!\n"); |
505 return -1; |
510 return -1; |
506 } |
511 } |
507 else { |
512 else { |
508 EC_INFO("SII-write succeeded!\n"); |
513 EC_INFO("SII-write succeeded!\n"); |
832 |
837 |
833 void ec_slave_state_ack(ec_slave_t *slave, /**< EtherCAT slave */ |
838 void ec_slave_state_ack(ec_slave_t *slave, /**< EtherCAT slave */ |
834 uint8_t state /**< previous state */ |
839 uint8_t state /**< previous state */ |
835 ) |
840 ) |
836 { |
841 { |
837 ec_command_t *command; |
842 ec_datagram_t *datagram; |
838 cycles_t start, end, timeout; |
843 cycles_t start, end, timeout; |
839 |
844 |
840 command = &slave->master->simple_command; |
845 datagram = &slave->master->simple_datagram; |
841 |
846 |
842 if (ec_command_npwr(command, slave->station_address, 0x0120, 2)) return; |
847 if (ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2)) return; |
843 EC_WRITE_U16(command->data, state | EC_ACK); |
848 EC_WRITE_U16(datagram->data, state | EC_ACK); |
844 if (unlikely(ec_master_simple_io(slave->master, command))) { |
849 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
845 EC_WARN("Acknowledge sending failed on slave %i!\n", |
850 EC_WARN("Acknowledge sending failed on slave %i!\n", |
846 slave->ring_position); |
851 slave->ring_position); |
847 return; |
852 return; |
848 } |
853 } |
849 |
854 |
850 start = get_cycles(); |
855 start = get_cycles(); |
851 timeout = (cycles_t) 10 * cpu_khz; // 10ms |
856 timeout = (cycles_t) 100 * cpu_khz; // 100ms |
852 |
857 |
853 while (1) |
858 while (1) { |
854 { |
|
855 udelay(100); // wait a little bit... |
859 udelay(100); // wait a little bit... |
856 |
860 |
857 if (ec_command_nprd(command, slave->station_address, 0x0130, 2)) |
861 if (ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2)) |
858 return; |
862 return; |
859 if (unlikely(ec_master_simple_io(slave->master, command))) { |
863 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
860 slave->current_state = EC_SLAVE_STATE_UNKNOWN; |
864 slave->current_state = EC_SLAVE_STATE_UNKNOWN; |
861 EC_WARN("Acknowledge checking failed on slave %i!\n", |
865 EC_WARN("Acknowledge checking failed on slave %i!\n", |
862 slave->ring_position); |
866 slave->ring_position); |
863 return; |
867 return; |
864 } |
868 } |
865 |
869 |
866 end = get_cycles(); |
870 end = get_cycles(); |
867 |
871 |
868 if (likely(EC_READ_U8(command->data) == state)) { |
872 if (EC_READ_U8(datagram->data) == state) { |
869 slave->current_state = state; |
873 slave->current_state = state; |
870 EC_INFO("Acknowleged state 0x%02X on slave %i.\n", state, |
874 EC_INFO("Acknowleged state 0x%02X on slave %i.\n", state, |
871 slave->ring_position); |
875 slave->ring_position); |
872 return; |
876 return; |
873 } |
877 } |
874 |
878 |
875 if (unlikely((end - start) >= timeout)) { |
879 if (end - start >= timeout) { |
876 slave->current_state = EC_SLAVE_STATE_UNKNOWN; |
880 slave->current_state = EC_SLAVE_STATE_UNKNOWN; |
877 EC_WARN("Failed to acknowledge state 0x%02X on slave %i" |
881 EC_WARN("Failed to acknowledge state 0x%02X on slave %i" |
878 " - Timeout!\n", state, slave->ring_position); |
882 " - Timeout!\n", state, slave->ring_position); |
879 return; |
883 return; |
880 } |
884 } |
889 resulting in code = 0), nothing is displayed. |
893 resulting in code = 0), nothing is displayed. |
890 */ |
894 */ |
891 |
895 |
892 void ec_slave_read_al_status_code(ec_slave_t *slave /**< EtherCAT slave */) |
896 void ec_slave_read_al_status_code(ec_slave_t *slave /**< EtherCAT slave */) |
893 { |
897 { |
894 ec_command_t *command; |
898 ec_datagram_t *datagram; |
895 uint16_t code; |
899 uint16_t code; |
896 const ec_code_msg_t *al_msg; |
900 const ec_code_msg_t *al_msg; |
897 |
901 |
898 command = &slave->master->simple_command; |
902 datagram = &slave->master->simple_datagram; |
899 |
903 |
900 if (ec_command_nprd(command, slave->station_address, 0x0134, 2)) return; |
904 if (ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2)) return; |
901 if (unlikely(ec_master_simple_io(slave->master, command))) { |
905 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
902 EC_WARN("Failed to read AL status code on slave %i!\n", |
906 EC_WARN("Failed to read AL status code on slave %i!\n", |
903 slave->ring_position); |
907 slave->ring_position); |
904 return; |
908 return; |
905 } |
909 } |
906 |
910 |
907 if (!(code = EC_READ_U16(command->data))) return; |
911 if (!(code = EC_READ_U16(datagram->data))) return; |
908 |
912 |
909 for (al_msg = al_status_messages; al_msg->code; al_msg++) { |
913 for (al_msg = al_status_messages; al_msg->code; al_msg++) { |
910 if (al_msg->code == code) { |
914 if (al_msg->code == code) { |
911 EC_ERR("AL status message 0x%04X: \"%s\".\n", |
915 EC_ERR("AL status message 0x%04X: \"%s\".\n", |
912 al_msg->code, al_msg->message); |
916 al_msg->code, al_msg->message); |
926 |
930 |
927 int ec_slave_state_change(ec_slave_t *slave, /**< EtherCAT slave */ |
931 int ec_slave_state_change(ec_slave_t *slave, /**< EtherCAT slave */ |
928 uint8_t state /**< new state */ |
932 uint8_t state /**< new state */ |
929 ) |
933 ) |
930 { |
934 { |
931 ec_command_t *command; |
935 ec_datagram_t *datagram; |
932 cycles_t start, end, timeout; |
936 cycles_t start, end, timeout; |
933 |
937 |
934 command = &slave->master->simple_command; |
938 datagram = &slave->master->simple_datagram; |
935 |
939 |
936 slave->requested_state = state; |
940 slave->requested_state = state; |
937 |
941 |
938 if (ec_command_npwr(command, slave->station_address, 0x0120, 2)) return -1; |
942 if (ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2)) |
939 EC_WRITE_U16(command->data, state); |
943 return -1; |
940 if (unlikely(ec_master_simple_io(slave->master, command))) { |
944 EC_WRITE_U16(datagram->data, state); |
|
945 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
941 EC_ERR("Failed to set state 0x%02X on slave %i!\n", |
946 EC_ERR("Failed to set state 0x%02X on slave %i!\n", |
942 state, slave->ring_position); |
947 state, slave->ring_position); |
943 return -1; |
948 return -1; |
944 } |
949 } |
945 |
950 |
948 |
953 |
949 while (1) |
954 while (1) |
950 { |
955 { |
951 udelay(100); // wait a little bit |
956 udelay(100); // wait a little bit |
952 |
957 |
953 if (ec_command_nprd(command, slave->station_address, 0x0130, 2)) |
958 if (ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2)) |
954 return -1; |
959 return -1; |
955 if (unlikely(ec_master_simple_io(slave->master, command))) { |
960 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
956 slave->current_state = EC_SLAVE_STATE_UNKNOWN; |
961 slave->current_state = EC_SLAVE_STATE_UNKNOWN; |
957 EC_ERR("Failed to check state 0x%02X on slave %i!\n", |
962 EC_ERR("Failed to check state 0x%02X on slave %i!\n", |
958 state, slave->ring_position); |
963 state, slave->ring_position); |
959 return -1; |
964 return -1; |
960 } |
965 } |
961 |
966 |
962 end = get_cycles(); |
967 end = get_cycles(); |
963 |
968 |
964 if (unlikely(EC_READ_U8(command->data) & 0x10)) { // state change error |
969 if (unlikely(EC_READ_U8(datagram->data) & 0x10)) { |
|
970 // state change error |
965 EC_ERR("Failed to set state 0x%02X - Slave %i refused state change" |
971 EC_ERR("Failed to set state 0x%02X - Slave %i refused state change" |
966 " (code 0x%02X)!\n", state, slave->ring_position, |
972 " (code 0x%02X)!\n", state, slave->ring_position, |
967 EC_READ_U8(command->data)); |
973 EC_READ_U8(datagram->data)); |
968 slave->current_state = EC_READ_U8(command->data); |
974 slave->current_state = EC_READ_U8(datagram->data); |
969 state = slave->current_state & 0x0F; |
975 state = slave->current_state & 0x0F; |
970 ec_slave_read_al_status_code(slave); |
976 ec_slave_read_al_status_code(slave); |
971 ec_slave_state_ack(slave, state); |
977 ec_slave_state_ack(slave, state); |
972 return -1; |
978 return -1; |
973 } |
979 } |
974 |
980 |
975 if (likely(EC_READ_U8(command->data) == (state & 0x0F))) { |
981 if (likely(EC_READ_U8(datagram->data) == (state & 0x0F))) { |
976 slave->current_state = state; |
982 slave->current_state = state; |
977 return 0; // state change successful |
983 return 0; // state change successful |
978 } |
984 } |
979 |
985 |
980 if (unlikely((end - start) >= timeout)) { |
986 if (unlikely((end - start) >= timeout)) { |
1203 \return 0 in case of success, else < 0 |
1209 \return 0 in case of success, else < 0 |
1204 */ |
1210 */ |
1205 |
1211 |
1206 int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT slave */) |
1212 int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT slave */) |
1207 { |
1213 { |
1208 ec_command_t *command; |
1214 ec_datagram_t *datagram; |
1209 |
1215 |
1210 command = &slave->master->simple_command; |
1216 datagram = &slave->master->simple_datagram; |
1211 |
1217 |
1212 if (ec_command_nprd(command, slave->station_address, 0x0300, 4)) return -1; |
1218 if (ec_datagram_nprd(datagram, slave->station_address, 0x0300, 4)) |
1213 if (unlikely(ec_master_simple_io(slave->master, command))) { |
1219 return -1; |
|
1220 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
1214 EC_WARN("Reading CRC fault counters failed on slave %i!\n", |
1221 EC_WARN("Reading CRC fault counters failed on slave %i!\n", |
1215 slave->ring_position); |
1222 slave->ring_position); |
1216 return -1; |
1223 return -1; |
1217 } |
1224 } |
1218 |
1225 |
1219 if (!EC_READ_U32(command->data)) return 0; // no CRC faults |
1226 if (!EC_READ_U32(datagram->data)) return 0; // no CRC faults |
1220 |
1227 |
1221 if (EC_READ_U8(command->data)) |
1228 if (EC_READ_U8(datagram->data)) |
1222 EC_WARN("%3i RX-error%s on slave %i, channel A.\n", |
1229 EC_WARN("%3i RX-error%s on slave %i, channel A.\n", |
1223 EC_READ_U8(command->data), |
1230 EC_READ_U8(datagram->data), |
1224 EC_READ_U8(command->data) == 1 ? "" : "s", |
1231 EC_READ_U8(datagram->data) == 1 ? "" : "s", |
1225 slave->ring_position); |
1232 slave->ring_position); |
1226 if (EC_READ_U8(command->data + 1)) |
1233 if (EC_READ_U8(datagram->data + 1)) |
1227 EC_WARN("%3i invalid frame%s on slave %i, channel A.\n", |
1234 EC_WARN("%3i invalid frame%s on slave %i, channel A.\n", |
1228 EC_READ_U8(command->data + 1), |
1235 EC_READ_U8(datagram->data + 1), |
1229 EC_READ_U8(command->data + 1) == 1 ? "" : "s", |
1236 EC_READ_U8(datagram->data + 1) == 1 ? "" : "s", |
1230 slave->ring_position); |
1237 slave->ring_position); |
1231 if (EC_READ_U8(command->data + 2)) |
1238 if (EC_READ_U8(datagram->data + 2)) |
1232 EC_WARN("%3i RX-error%s on slave %i, channel B.\n", |
1239 EC_WARN("%3i RX-error%s on slave %i, channel B.\n", |
1233 EC_READ_U8(command->data + 2), |
1240 EC_READ_U8(datagram->data + 2), |
1234 EC_READ_U8(command->data + 2) == 1 ? "" : "s", |
1241 EC_READ_U8(datagram->data + 2) == 1 ? "" : "s", |
1235 slave->ring_position); |
1242 slave->ring_position); |
1236 if (EC_READ_U8(command->data + 3)) |
1243 if (EC_READ_U8(datagram->data + 3)) |
1237 EC_WARN("%3i invalid frame%s on slave %i, channel B.\n", |
1244 EC_WARN("%3i invalid frame%s on slave %i, channel B.\n", |
1238 EC_READ_U8(command->data + 3), |
1245 EC_READ_U8(datagram->data + 3), |
1239 EC_READ_U8(command->data + 3) == 1 ? "" : "s", |
1246 EC_READ_U8(datagram->data + 3) == 1 ? "" : "s", |
1240 slave->ring_position); |
1247 slave->ring_position); |
1241 |
1248 |
1242 // reset CRC counters |
1249 // reset CRC counters |
1243 if (ec_command_npwr(command, slave->station_address, 0x0300, 4)) return -1; |
1250 if (ec_datagram_npwr(datagram, slave->station_address, 0x0300, 4)) |
1244 EC_WRITE_U32(command->data, 0x00000000); |
1251 return -1; |
1245 if (unlikely(ec_master_simple_io(slave->master, command))) { |
1252 EC_WRITE_U32(datagram->data, 0x00000000); |
|
1253 if (unlikely(ec_master_simple_io(slave->master, datagram))) { |
1246 EC_WARN("Resetting CRC fault counters failed on slave %i!\n", |
1254 EC_WARN("Resetting CRC fault counters failed on slave %i!\n", |
1247 slave->ring_position); |
1255 slave->ring_position); |
1248 return -1; |
1256 return -1; |
1249 } |
1257 } |
1250 |
1258 |
1343 ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj); |
1351 ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj); |
1344 |
1352 |
1345 if (attr == &attr_ring_position) { |
1353 if (attr == &attr_ring_position) { |
1346 return sprintf(buffer, "%i\n", slave->ring_position); |
1354 return sprintf(buffer, "%i\n", slave->ring_position); |
1347 } |
1355 } |
1348 else if (attr == &attr_coupler_address) { |
1356 else if (attr == &attr_advanced_position) { |
1349 return sprintf(buffer, "%i:%i\n", slave->coupler_index, |
1357 return sprintf(buffer, "%i:%i\n", slave->coupler_index, |
1350 slave->coupler_subindex); |
1358 slave->coupler_subindex); |
1351 } |
1359 } |
1352 else if (attr == &attr_vendor_name) { |
1360 else if (attr == &attr_vendor_name) { |
1353 if (slave->type) |
1361 if (slave->type) |
1359 } |
1367 } |
1360 else if (attr == &attr_product_desc) { |
1368 else if (attr == &attr_product_desc) { |
1361 if (slave->type) |
1369 if (slave->type) |
1362 return sprintf(buffer, "%s\n", slave->type->description); |
1370 return sprintf(buffer, "%s\n", slave->type->description); |
1363 } |
1371 } |
1364 else if (attr == &attr_sii_name) { |
1372 else if (attr == &attr_name) { |
1365 if (slave->eeprom_name) |
1373 if (slave->eeprom_name) |
1366 return sprintf(buffer, "%s\n", slave->eeprom_name); |
1374 return sprintf(buffer, "%s\n", slave->eeprom_name); |
1367 } |
1375 } |
1368 else if (attr == &attr_type) { |
1376 else if (attr == &attr_type) { |
1369 if (slave->type) { |
1377 if (slave->type) { |
1370 if (slave->type->special == EC_TYPE_BUS_COUPLER) |
1378 if (slave->type->special == EC_TYPE_BUS_COUPLER) |
1371 return sprintf(buffer, "coupler\n"); |
1379 return sprintf(buffer, "coupler\n"); |
|
1380 else if (slave->type->special == EC_TYPE_INFRA) |
|
1381 return sprintf(buffer, "infrastructure\n"); |
1372 else |
1382 else |
1373 return sprintf(buffer, "normal\n"); |
1383 return sprintf(buffer, "normal\n"); |
1374 } |
1384 } |
1375 } |
1385 } |
1376 else if (attr == &attr_state) { |
1386 else if (attr == &attr_state) { |
1418 ) |
1428 ) |
1419 { |
1429 { |
1420 ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj); |
1430 ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj); |
1421 |
1431 |
1422 if (attr == &attr_state) { |
1432 if (attr == &attr_state) { |
1423 if (!strcmp(buffer, "INIT\n")) { |
1433 if (!strcmp(buffer, "INIT\n")) |
1424 slave->requested_state = EC_SLAVE_STATE_INIT; |
1434 slave->requested_state = EC_SLAVE_STATE_INIT; |
1425 slave->state_error = 0; |
1435 else if (!strcmp(buffer, "PREOP\n")) |
1426 return size; |
|
1427 } |
|
1428 else if (!strcmp(buffer, "PREOP\n")) { |
|
1429 slave->requested_state = EC_SLAVE_STATE_PREOP; |
1436 slave->requested_state = EC_SLAVE_STATE_PREOP; |
1430 slave->state_error = 0; |
1437 else if (!strcmp(buffer, "SAVEOP\n")) |
1431 return size; |
|
1432 } |
|
1433 else if (!strcmp(buffer, "SAVEOP\n")) { |
|
1434 slave->requested_state = EC_SLAVE_STATE_SAVEOP; |
1438 slave->requested_state = EC_SLAVE_STATE_SAVEOP; |
1435 slave->state_error = 0; |
1439 else if (!strcmp(buffer, "OP\n")) |
1436 return size; |
|
1437 } |
|
1438 else if (!strcmp(buffer, "OP\n")) { |
|
1439 slave->requested_state = EC_SLAVE_STATE_OP; |
1440 slave->requested_state = EC_SLAVE_STATE_OP; |
1440 slave->state_error = 0; |
1441 else { |
1441 return size; |
1442 EC_ERR("Invalid slave state \"%s\"!\n", buffer); |
1442 } |
1443 return -EINVAL; |
1443 |
1444 } |
1444 EC_ERR("Failed to set slave state!\n"); |
1445 |
|
1446 EC_INFO("Accepted new state %s for slave %i.\n", |
|
1447 buffer, slave->ring_position); |
|
1448 slave->error_flag = 0; |
|
1449 return size; |
1445 } |
1450 } |
1446 else if (attr == &attr_eeprom) { |
1451 else if (attr == &attr_eeprom) { |
1447 if (!ec_slave_write_eeprom(slave, buffer, size)) |
1452 if (!ec_slave_write_eeprom(slave, buffer, size)) |
1448 return size; |
1453 return size; |
1449 } |
1454 } |
1484 EC_WARN("Variable data field \"%s\" of slave %i has no size" |
1489 EC_WARN("Variable data field \"%s\" of slave %i has no size" |
1485 " information!\n", field->name, slave->ring_position); |
1490 " information!\n", field->name, slave->ring_position); |
1486 } |
1491 } |
1487 } |
1492 } |
1488 return size; |
1493 return size; |
|
1494 } |
|
1495 |
|
1496 /*****************************************************************************/ |
|
1497 |
|
1498 /** |
|
1499 Calculates the size of a sync manager by evaluating PDO sizes. |
|
1500 \return sync manager size |
|
1501 */ |
|
1502 |
|
1503 uint16_t ec_slave_calc_eeprom_sync_size(const ec_slave_t *slave, |
|
1504 /**< EtherCAT slave */ |
|
1505 const ec_eeprom_sync_t *sync |
|
1506 /**< sync manager */ |
|
1507 ) |
|
1508 { |
|
1509 ec_eeprom_pdo_t *pdo; |
|
1510 ec_eeprom_pdo_entry_t *pdo_entry; |
|
1511 unsigned int bit_size; |
|
1512 |
|
1513 if (sync->length) return sync->length; |
|
1514 |
|
1515 bit_size = 0; |
|
1516 list_for_each_entry(pdo, &slave->eeprom_pdos, list) { |
|
1517 if (pdo->sync_manager != sync->index) continue; |
|
1518 |
|
1519 list_for_each_entry(pdo_entry, &pdo->entries, list) { |
|
1520 bit_size += pdo_entry->bit_length; |
|
1521 } |
|
1522 } |
|
1523 |
|
1524 if (bit_size % 8) // round up to full bytes |
|
1525 return bit_size / 8 + 1; |
|
1526 else |
|
1527 return bit_size / 8; |
1489 } |
1528 } |
1490 |
1529 |
1491 /****************************************************************************** |
1530 /****************************************************************************** |
1492 * Realtime interface |
1531 * Realtime interface |
1493 *****************************************************************************/ |
1532 *****************************************************************************/ |