232 |
232 |
233 // init reference sync datagram |
233 // init reference sync datagram |
234 ec_datagram_init(&master->ref_sync_datagram); |
234 ec_datagram_init(&master->ref_sync_datagram); |
235 snprintf(master->ref_sync_datagram.name, EC_DATAGRAM_NAME_SIZE, |
235 snprintf(master->ref_sync_datagram.name, EC_DATAGRAM_NAME_SIZE, |
236 "refsync"); |
236 "refsync"); |
237 ret = ec_datagram_apwr(&master->ref_sync_datagram, 0, 0x0910, 8); |
237 ret = ec_datagram_prealloc(&master->ref_sync_datagram, 4); |
238 if (ret < 0) { |
238 if (ret < 0) { |
239 ec_datagram_clear(&master->ref_sync_datagram); |
239 ec_datagram_clear(&master->ref_sync_datagram); |
240 EC_MASTER_ERR(master, "Failed to allocate reference" |
240 EC_MASTER_ERR(master, "Failed to allocate reference" |
241 " synchronisation datagram.\n"); |
241 " synchronisation datagram.\n"); |
242 goto out_clear_fsm; |
242 goto out_clear_fsm; |
263 EC_MASTER_ERR(master, "Failed to allocate sync" |
263 EC_MASTER_ERR(master, "Failed to allocate sync" |
264 " monitoring datagram.\n"); |
264 " monitoring datagram.\n"); |
265 goto out_clear_sync; |
265 goto out_clear_sync; |
266 } |
266 } |
267 |
267 |
268 ec_master_find_dc_ref_clock(master); |
268 master->dc_ref_config = NULL; |
|
269 master->dc_ref_clock = NULL; |
269 |
270 |
270 // init character device |
271 // init character device |
271 ret = ec_cdev_init(&master->cdev, master, device_number); |
272 ret = ec_cdev_init(&master->cdev, master, device_number); |
272 if (ret) |
273 if (ret) |
273 goto out_clear_sync_mon; |
274 goto out_clear_sync_mon; |
392 /** Clear all slave configurations. |
393 /** Clear all slave configurations. |
393 */ |
394 */ |
394 void ec_master_clear_slave_configs(ec_master_t *master) |
395 void ec_master_clear_slave_configs(ec_master_t *master) |
395 { |
396 { |
396 ec_slave_config_t *sc, *next; |
397 ec_slave_config_t *sc, *next; |
|
398 |
|
399 master->dc_ref_config = NULL; |
397 |
400 |
398 list_for_each_entry_safe(sc, next, &master->configs, list) { |
401 list_for_each_entry_safe(sc, next, &master->configs, list) { |
399 list_del(&sc->list); |
402 list_del(&sc->list); |
400 ec_slave_config_clear(sc); |
403 ec_slave_config_clear(sc); |
401 kfree(sc); |
404 kfree(sc); |
1870 ec_master_t *master /**< EtherCAT master. */ |
1873 ec_master_t *master /**< EtherCAT master. */ |
1871 ) |
1874 ) |
1872 { |
1875 { |
1873 ec_slave_t *slave, *ref = NULL; |
1876 ec_slave_t *slave, *ref = NULL; |
1874 |
1877 |
1875 for (slave = master->slaves; |
1878 if (master->dc_ref_config) { |
1876 slave < master->slaves + master->slave_count; |
1879 // Use application-selected reference clock |
1877 slave++) { |
1880 slave = master->dc_ref_config->slave; |
1878 if (slave->base_dc_supported && slave->has_dc_system_time) { |
1881 |
1879 ref = slave; |
1882 if (slave) { |
1880 break; |
1883 if (slave->base_dc_supported && slave->has_dc_system_time) { |
1881 } |
1884 ref = slave; |
|
1885 } |
|
1886 else { |
|
1887 EC_MASTER_WARN(master, "Slave %u can not act as a" |
|
1888 " DC reference clock!", slave->ring_position); |
|
1889 } |
|
1890 } |
|
1891 else { |
|
1892 EC_MASTER_WARN(master, "DC reference clock config (%u-%u)" |
|
1893 " has no slave attached!\n", master->dc_ref_config->alias, |
|
1894 master->dc_ref_config->position); |
|
1895 } |
|
1896 } |
|
1897 else { |
|
1898 // Use first slave with DC support as reference clock |
|
1899 for (slave = master->slaves; |
|
1900 slave < master->slaves + master->slave_count; |
|
1901 slave++) { |
|
1902 if (slave->base_dc_supported && slave->has_dc_system_time) { |
|
1903 ref = slave; |
|
1904 break; |
|
1905 } |
|
1906 } |
|
1907 |
1882 } |
1908 } |
1883 |
1909 |
1884 master->dc_ref_clock = ref; |
1910 master->dc_ref_clock = ref; |
1885 |
1911 |
1886 // This call always succeeds, because the datagram has been pre-allocated. |
1912 if (ref) { |
|
1913 EC_MASTER_INFO(master, "Using slave %u as DC reference clock.\n", |
|
1914 ref->ring_position); |
|
1915 } |
|
1916 else { |
|
1917 EC_MASTER_INFO(master, "No DC reference clock found.\n"); |
|
1918 } |
|
1919 |
|
1920 // These calls always succeed, because the |
|
1921 // datagrams have been pre-allocated. |
|
1922 ec_datagram_fpwr(&master->ref_sync_datagram, |
|
1923 ref ? ref->station_address : 0xffff, 0x0910, 4); |
1887 ec_datagram_frmw(&master->sync_datagram, |
1924 ec_datagram_frmw(&master->sync_datagram, |
1888 ref ? ref->station_address : 0xffff, 0x0910, 4); |
1925 ref ? ref->station_address : 0xffff, 0x0910, 4); |
1889 } |
1926 } |
1890 |
1927 |
1891 /*****************************************************************************/ |
1928 /*****************************************************************************/ |
2390 return IS_ERR(sc) ? NULL : sc; |
2427 return IS_ERR(sc) ? NULL : sc; |
2391 } |
2428 } |
2392 |
2429 |
2393 /*****************************************************************************/ |
2430 /*****************************************************************************/ |
2394 |
2431 |
|
2432 int ecrt_master_select_reference_clock(ec_master_t *master, |
|
2433 ec_slave_config_t *sc) |
|
2434 { |
|
2435 if (sc) { |
|
2436 ec_slave_t *slave = sc->slave; |
|
2437 |
|
2438 // output an early warning |
|
2439 if (slave && |
|
2440 (!slave->base_dc_supported || !slave->has_dc_system_time)) { |
|
2441 EC_MASTER_WARN(master, "Slave %u can not act as" |
|
2442 " a reference clock!", slave->ring_position); |
|
2443 } |
|
2444 } |
|
2445 |
|
2446 master->dc_ref_config = sc; |
|
2447 return 0; |
|
2448 } |
|
2449 |
|
2450 /*****************************************************************************/ |
|
2451 |
2395 int ecrt_master(ec_master_t *master, ec_master_info_t *master_info) |
2452 int ecrt_master(ec_master_t *master, ec_master_info_t *master_info) |
2396 { |
2453 { |
2397 EC_MASTER_DBG(master, 1, "ecrt_master(master = 0x%p," |
2454 EC_MASTER_DBG(master, 1, "ecrt_master(master = 0x%p," |
2398 " master_info = 0x%p)\n", master, master_info); |
2455 " master_info = 0x%p)\n", master, master_info); |
2399 |
2456 |
2523 } |
2580 } |
2524 } |
2581 } |
2525 |
2582 |
2526 /*****************************************************************************/ |
2583 /*****************************************************************************/ |
2527 |
2584 |
|
2585 int ecrt_master_reference_clock_time(ec_master_t *master, uint32_t *time) |
|
2586 { |
|
2587 if (!master->dc_ref_clock) { |
|
2588 return -ENXIO; |
|
2589 } |
|
2590 |
|
2591 if (master->sync_datagram.state != EC_DATAGRAM_RECEIVED) { |
|
2592 return -EIO; |
|
2593 } |
|
2594 |
|
2595 // Get returned datagram time, transmission delay removed. |
|
2596 *time = EC_READ_U32(master->sync_datagram.data) - |
|
2597 master->dc_ref_clock->transmission_delay; |
|
2598 |
|
2599 return 0; |
|
2600 } |
|
2601 |
|
2602 /*****************************************************************************/ |
|
2603 |
2528 void ecrt_master_sync_reference_clock(ec_master_t *master) |
2604 void ecrt_master_sync_reference_clock(ec_master_t *master) |
2529 { |
2605 { |
2530 EC_WRITE_U32(master->ref_sync_datagram.data, master->app_time); |
2606 EC_WRITE_U32(master->ref_sync_datagram.data, master->app_time); |
2531 ec_master_queue_datagram(master, &master->ref_sync_datagram); |
2607 ec_master_queue_datagram(master, &master->ref_sync_datagram); |
2532 } |
2608 } |
2983 EXPORT_SYMBOL(ecrt_master_receive); |
3059 EXPORT_SYMBOL(ecrt_master_receive); |
2984 EXPORT_SYMBOL(ecrt_master_callbacks); |
3060 EXPORT_SYMBOL(ecrt_master_callbacks); |
2985 EXPORT_SYMBOL(ecrt_master); |
3061 EXPORT_SYMBOL(ecrt_master); |
2986 EXPORT_SYMBOL(ecrt_master_get_slave); |
3062 EXPORT_SYMBOL(ecrt_master_get_slave); |
2987 EXPORT_SYMBOL(ecrt_master_slave_config); |
3063 EXPORT_SYMBOL(ecrt_master_slave_config); |
|
3064 EXPORT_SYMBOL(ecrt_master_select_reference_clock); |
2988 EXPORT_SYMBOL(ecrt_master_state); |
3065 EXPORT_SYMBOL(ecrt_master_state); |
2989 EXPORT_SYMBOL(ecrt_master_link_state); |
3066 EXPORT_SYMBOL(ecrt_master_link_state); |
2990 EXPORT_SYMBOL(ecrt_master_application_time); |
3067 EXPORT_SYMBOL(ecrt_master_application_time); |
2991 EXPORT_SYMBOL(ecrt_master_sync_reference_clock); |
3068 EXPORT_SYMBOL(ecrt_master_sync_reference_clock); |
2992 EXPORT_SYMBOL(ecrt_master_sync_slave_clocks); |
3069 EXPORT_SYMBOL(ecrt_master_sync_slave_clocks); |
|
3070 EXPORT_SYMBOL(ecrt_master_reference_clock_time); |
2993 EXPORT_SYMBOL(ecrt_master_sync_monitor_queue); |
3071 EXPORT_SYMBOL(ecrt_master_sync_monitor_queue); |
2994 EXPORT_SYMBOL(ecrt_master_sync_monitor_process); |
3072 EXPORT_SYMBOL(ecrt_master_sync_monitor_process); |
2995 EXPORT_SYMBOL(ecrt_master_sdo_download); |
3073 EXPORT_SYMBOL(ecrt_master_sdo_download); |
2996 EXPORT_SYMBOL(ecrt_master_sdo_download_complete); |
3074 EXPORT_SYMBOL(ecrt_master_sdo_download_complete); |
2997 EXPORT_SYMBOL(ecrt_master_sdo_upload); |
3075 EXPORT_SYMBOL(ecrt_master_sdo_upload); |