equal
deleted
inserted
replaced
22 * --- |
22 * --- |
23 * |
23 * |
24 * The license mentioned above concerns the source code only. Using the |
24 * The license mentioned above concerns the source code only. Using the |
25 * EtherCAT technology and brand is only permitted in compliance with the |
25 * EtherCAT technology and brand is only permitted in compliance with the |
26 * industrial property and similar rights of Beckhoff Automation GmbH. |
26 * industrial property and similar rights of Beckhoff Automation GmbH. |
|
27 * |
|
28 * vim: expandtab |
27 * |
29 * |
28 *****************************************************************************/ |
30 *****************************************************************************/ |
29 |
31 |
30 /** |
32 /** |
31 \file |
33 \file |
61 #ifdef EC_HAVE_CYCLES |
63 #ifdef EC_HAVE_CYCLES |
62 |
64 |
63 /** Frame timeout in cycles. |
65 /** Frame timeout in cycles. |
64 */ |
66 */ |
65 static cycles_t timeout_cycles; |
67 static cycles_t timeout_cycles; |
66 static cycles_t sdo_injection_timeout_cycles; |
68 |
|
69 /** Timeout for external datagram injection [cycles]. |
|
70 */ |
|
71 static cycles_t ext_injection_timeout_cycles; |
|
72 |
67 #else |
73 #else |
68 |
74 |
69 /** Frame timeout in jiffies. |
75 /** Frame timeout in jiffies. |
70 */ |
76 */ |
71 static unsigned long timeout_jiffies; |
77 static unsigned long timeout_jiffies; |
72 static unsigned long sdo_injection_timeout_jiffies; |
78 |
|
79 /** Timeout for external datagram injection [jiffies]. |
|
80 */ |
|
81 static unsigned long ext_injection_timeout_jiffies; |
73 |
82 |
74 #endif |
83 #endif |
75 |
84 |
76 /*****************************************************************************/ |
85 /*****************************************************************************/ |
77 |
86 |
90 */ |
99 */ |
91 void ec_master_init_static(void) |
100 void ec_master_init_static(void) |
92 { |
101 { |
93 #ifdef EC_HAVE_CYCLES |
102 #ifdef EC_HAVE_CYCLES |
94 timeout_cycles = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000); |
103 timeout_cycles = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000); |
95 sdo_injection_timeout_cycles = (cycles_t) EC_SDO_INJECTION_TIMEOUT /* us */ * (cpu_khz / 1000); |
104 ext_injection_timeout_cycles = (cycles_t) EC_SDO_INJECTION_TIMEOUT /* us */ * (cpu_khz / 1000); |
96 #else |
105 #else |
97 // one jiffy may always elapse between time measurement |
106 // one jiffy may always elapse between time measurement |
98 timeout_jiffies = max(EC_IO_TIMEOUT * HZ / 1000000, 1); |
107 timeout_jiffies = max(EC_IO_TIMEOUT * HZ / 1000000, 1); |
99 sdo_injection_timeout_jiffies = max(EC_SDO_INJECTION_TIMEOUT * HZ / 1000000, 1); |
108 ext_injection_timeout_jiffies = max(EC_SDO_INJECTION_TIMEOUT * HZ / 1000000, 1); |
100 #endif |
109 #endif |
101 } |
110 } |
102 |
111 |
103 /*****************************************************************************/ |
112 /*****************************************************************************/ |
104 |
113 |
415 // get first request |
424 // get first request |
416 request = list_entry(slave->slave_sdo_requests.next, |
425 request = list_entry(slave->slave_sdo_requests.next, |
417 ec_master_sdo_request_t, list); |
426 ec_master_sdo_request_t, list); |
418 list_del_init(&request->list); // dequeue |
427 list_del_init(&request->list); // dequeue |
419 EC_INFO("Discarding SDO request," |
428 EC_INFO("Discarding SDO request," |
420 " slave %u does not exist anymore.\n", |
429 " slave %u does not exist anymore.\n", |
421 slave->ring_position); |
430 slave->ring_position); |
422 request->req.state = EC_INT_REQUEST_FAILURE; |
431 request->req.state = EC_INT_REQUEST_FAILURE; |
423 wake_up(&slave->sdo_queue); |
432 wake_up(&slave->sdo_queue); |
424 } |
433 } |
425 // FoE requests |
434 // FoE requests |
430 // get first request |
439 // get first request |
431 request = list_entry(slave->foe_requests.next, |
440 request = list_entry(slave->foe_requests.next, |
432 ec_master_foe_request_t, list); |
441 ec_master_foe_request_t, list); |
433 list_del_init(&request->list); // dequeue |
442 list_del_init(&request->list); // dequeue |
434 EC_INFO("Discarding FoE request," |
443 EC_INFO("Discarding FoE request," |
435 " slave %u does not exist anymore.\n", |
444 " slave %u does not exist anymore.\n", |
436 slave->ring_position); |
445 slave->ring_position); |
437 request->req.state = EC_INT_REQUEST_FAILURE; |
446 request->req.state = EC_INT_REQUEST_FAILURE; |
438 wake_up(&slave->foe_queue); |
447 wake_up(&slave->foe_queue); |
439 } |
448 } |
440 // SoE requests |
449 // SoE requests |
445 // get first request |
454 // get first request |
446 request = list_entry(slave->soe_requests.next, |
455 request = list_entry(slave->soe_requests.next, |
447 ec_master_soe_request_t, list); |
456 ec_master_soe_request_t, list); |
448 list_del_init(&request->list); // dequeue |
457 list_del_init(&request->list); // dequeue |
449 EC_INFO("Discarding SoE request," |
458 EC_INFO("Discarding SoE request," |
450 " slave %u does not exist anymore.\n", |
459 " slave %u does not exist anymore.\n", |
451 slave->ring_position); |
460 slave->ring_position); |
452 request->req.state = EC_INT_REQUEST_FAILURE; |
461 request->req.state = EC_INT_REQUEST_FAILURE; |
453 wake_up(&slave->soe_queue); |
462 wake_up(&slave->soe_queue); |
454 } |
463 } |
455 ec_slave_clear(slave); |
464 ec_slave_clear(slave); |
749 } else { |
758 } else { |
750 #ifdef EC_HAVE_CYCLES |
759 #ifdef EC_HAVE_CYCLES |
751 cycles_t cycles_now = get_cycles(); |
760 cycles_t cycles_now = get_cycles(); |
752 |
761 |
753 if (cycles_now - datagram->cycles_sent |
762 if (cycles_now - datagram->cycles_sent |
754 > sdo_injection_timeout_cycles) |
763 > ext_injection_timeout_cycles) |
755 #else |
764 #else |
756 if (jiffies - datagram->jiffies_sent |
765 if (jiffies - datagram->jiffies_sent |
757 > sdo_injection_timeout_jiffies) |
766 > ext_injection_timeout_jiffies) |
758 #endif |
767 #endif |
759 { |
768 { |
760 unsigned int time_us; |
769 unsigned int time_us; |
761 |
770 |
762 list_del_init(&datagram->queue); |
771 list_del_init(&datagram->queue); |
1515 #define EC_FIND_SLAVE \ |
1524 #define EC_FIND_SLAVE \ |
1516 do { \ |
1525 do { \ |
1517 if (alias) { \ |
1526 if (alias) { \ |
1518 for (; slave < master->slaves + master->slave_count; \ |
1527 for (; slave < master->slaves + master->slave_count; \ |
1519 slave++) { \ |
1528 slave++) { \ |
1520 if (slave->sii.alias == alias) \ |
1529 if (slave->effective_alias == alias) \ |
1521 break; \ |
1530 break; \ |
1522 } \ |
1531 } \ |
1523 if (slave == master->slaves + master->slave_count) \ |
1532 if (slave == master->slaves + master->slave_count) \ |
1524 return NULL; \ |
1533 return NULL; \ |
1525 } \ |
1534 } \ |
1930 int ecrt_master_activate(ec_master_t *master) |
1939 int ecrt_master_activate(ec_master_t *master) |
1931 { |
1940 { |
1932 uint32_t domain_offset; |
1941 uint32_t domain_offset; |
1933 ec_domain_t *domain; |
1942 ec_domain_t *domain; |
1934 int ret; |
1943 int ret; |
|
1944 #ifdef EC_EOE |
|
1945 int eoe_was_running; |
|
1946 #endif |
1935 |
1947 |
1936 if (master->debug_level) |
1948 if (master->debug_level) |
1937 EC_DBG("ecrt_master_activate(master = 0x%p)\n", master); |
1949 EC_DBG("ecrt_master_activate(master = 0x%p)\n", master); |
1938 |
1950 |
1939 if (master->active) { |
1951 if (master->active) { |
1961 } |
1973 } |
1962 |
1974 |
1963 up(&master->master_sem); |
1975 up(&master->master_sem); |
1964 |
1976 |
1965 // restart EoE process and master thread with new locking |
1977 // restart EoE process and master thread with new locking |
|
1978 |
|
1979 ec_master_thread_stop(master); |
1966 #ifdef EC_EOE |
1980 #ifdef EC_EOE |
|
1981 eoe_was_running = master->eoe_thread != NULL; |
1967 ec_master_eoe_stop(master); |
1982 ec_master_eoe_stop(master); |
1968 #endif |
1983 #endif |
1969 ec_master_thread_stop(master); |
|
1970 |
1984 |
1971 if (master->debug_level) |
1985 if (master->debug_level) |
1972 EC_DBG("FSM datagram is %p.\n", &master->fsm_datagram); |
1986 EC_DBG("FSM datagram is %p.\n", &master->fsm_datagram); |
1973 |
1987 |
1974 master->injection_seq_fsm = 0; |
1988 master->injection_seq_fsm = 0; |
1976 |
1990 |
1977 master->send_cb = master->app_send_cb; |
1991 master->send_cb = master->app_send_cb; |
1978 master->receive_cb = master->app_receive_cb; |
1992 master->receive_cb = master->app_receive_cb; |
1979 master->cb_data = master->app_cb_data; |
1993 master->cb_data = master->app_cb_data; |
1980 |
1994 |
|
1995 #ifdef EC_EOE |
|
1996 if (eoe_was_running) { |
|
1997 ec_master_eoe_start(master); |
|
1998 } |
|
1999 #endif |
1981 ret = ec_master_thread_start(master, ec_master_operation_thread, |
2000 ret = ec_master_thread_start(master, ec_master_operation_thread, |
1982 "EtherCAT-OP"); |
2001 "EtherCAT-OP"); |
1983 if (ret < 0) { |
2002 if (ret < 0) { |
1984 EC_ERR("Failed to start master thread!\n"); |
2003 EC_ERR("Failed to start master thread!\n"); |
1985 return ret; |
2004 return ret; |
1986 } |
2005 } |
1987 #ifdef EC_EOE |
|
1988 ec_master_eoe_start(master); |
|
1989 #endif |
|
1990 |
2006 |
1991 master->allow_config = 1; // request the current configuration |
2007 master->allow_config = 1; // request the current configuration |
1992 master->allow_scan = 1; // allow re-scanning on topology change |
2008 master->allow_scan = 1; // allow re-scanning on topology change |
1993 master->active = 1; |
2009 master->active = 1; |
1994 return 0; |
2010 return 0; |
1999 void ecrt_master_deactivate(ec_master_t *master) |
2015 void ecrt_master_deactivate(ec_master_t *master) |
2000 { |
2016 { |
2001 ec_slave_t *slave; |
2017 ec_slave_t *slave; |
2002 #ifdef EC_EOE |
2018 #ifdef EC_EOE |
2003 ec_eoe_t *eoe; |
2019 ec_eoe_t *eoe; |
|
2020 int eoe_was_running; |
2004 #endif |
2021 #endif |
2005 |
2022 |
2006 if (master->debug_level) |
2023 if (master->debug_level) |
2007 EC_DBG("ecrt_master_deactivate(master = 0x%x)\n", (u32) master); |
2024 EC_DBG("ecrt_master_deactivate(master = 0x%x)\n", (u32) master); |
2008 |
2025 |
2009 if (!master->active) { |
2026 if (!master->active) { |
2010 EC_WARN("%s: Master not active.\n", __func__); |
2027 EC_WARN("%s: Master not active.\n", __func__); |
2011 return; |
2028 return; |
2012 } |
2029 } |
2013 |
2030 |
|
2031 ec_master_thread_stop(master); |
2014 #ifdef EC_EOE |
2032 #ifdef EC_EOE |
|
2033 eoe_was_running = master->eoe_thread != NULL; |
2015 ec_master_eoe_stop(master); |
2034 ec_master_eoe_stop(master); |
2016 #endif |
2035 #endif |
2017 ec_master_thread_stop(master); |
|
2018 |
2036 |
2019 master->send_cb = ec_master_internal_send_cb; |
2037 master->send_cb = ec_master_internal_send_cb; |
2020 master->receive_cb = ec_master_internal_receive_cb; |
2038 master->receive_cb = ec_master_internal_receive_cb; |
2021 master->cb_data = master; |
2039 master->cb_data = master; |
2022 |
2040 |
2048 |
2066 |
2049 master->app_time = 0ULL; |
2067 master->app_time = 0ULL; |
2050 master->app_start_time = 0ULL; |
2068 master->app_start_time = 0ULL; |
2051 master->has_start_time = 0; |
2069 master->has_start_time = 0; |
2052 |
2070 |
|
2071 #ifdef EC_EOE |
|
2072 if (eoe_was_running) { |
|
2073 ec_master_eoe_start(master); |
|
2074 } |
|
2075 #endif |
2053 if (ec_master_thread_start(master, ec_master_idle_thread, |
2076 if (ec_master_thread_start(master, ec_master_idle_thread, |
2054 "EtherCAT-IDLE")) |
2077 "EtherCAT-IDLE")) |
2055 EC_WARN("Failed to restart master thread!\n"); |
2078 EC_WARN("Failed to restart master thread!\n"); |
2056 #ifdef EC_EOE |
|
2057 ec_master_eoe_start(master); |
|
2058 #endif |
|
2059 |
2079 |
2060 master->allow_scan = 1; |
2080 master->allow_scan = 1; |
2061 master->allow_config = 1; |
2081 master->allow_config = 1; |
2062 master->active = 0; |
2082 master->active = 0; |
2063 } |
2083 } |
2251 slave_info->position = slave->ring_position; |
2271 slave_info->position = slave->ring_position; |
2252 slave_info->vendor_id = slave->sii.vendor_id; |
2272 slave_info->vendor_id = slave->sii.vendor_id; |
2253 slave_info->product_code = slave->sii.product_code; |
2273 slave_info->product_code = slave->sii.product_code; |
2254 slave_info->revision_number = slave->sii.revision_number; |
2274 slave_info->revision_number = slave->sii.revision_number; |
2255 slave_info->serial_number = slave->sii.serial_number; |
2275 slave_info->serial_number = slave->sii.serial_number; |
2256 slave_info->alias = slave->sii.alias; |
2276 slave_info->alias = slave->effective_alias; |
2257 slave_info->current_on_ebus = slave->sii.current_on_ebus; |
2277 slave_info->current_on_ebus = slave->sii.current_on_ebus; |
2258 slave_info->al_state = slave->current_state; |
2278 slave_info->al_state = slave->current_state; |
2259 slave_info->error_flag = slave->error_flag; |
2279 slave_info->error_flag = slave->error_flag; |
2260 slave_info->sync_count = slave->sii.sync_count; |
2280 slave_info->sync_count = slave->sii.sync_count; |
2261 slave_info->sdo_count = ec_slave_sdo_count(slave); |
2281 slave_info->sdo_count = ec_slave_sdo_count(slave); |