equal
deleted
inserted
replaced
55 |
55 |
56 static int ec_master_count = 1; /**< parameter value, number of masters */ |
56 static int ec_master_count = 1; /**< parameter value, number of masters */ |
57 static int ec_eoeif_count = 0; /**< parameter value, number of EoE interf. */ |
57 static int ec_eoeif_count = 0; /**< parameter value, number of EoE interf. */ |
58 static struct list_head ec_masters; /**< list of masters */ |
58 static struct list_head ec_masters; /**< list of masters */ |
59 |
59 |
|
60 char *ec_master_version_str = EC_MASTER_VERSION; |
|
61 |
60 /*****************************************************************************/ |
62 /*****************************************************************************/ |
61 |
63 |
62 /** \cond */ |
64 /** \cond */ |
63 |
65 |
64 module_param(ec_master_count, int, S_IRUGO); |
66 module_param(ec_master_count, int, S_IRUGO); |
105 } |
107 } |
106 |
108 |
107 if (ec_master_init(master, i, ec_eoeif_count)) |
109 if (ec_master_init(master, i, ec_eoeif_count)) |
108 goto out_free; |
110 goto out_free; |
109 |
111 |
110 if (kobject_add(&master->kobj)) { |
|
111 EC_ERR("Failed to add kobj.\n"); |
|
112 kobject_put(&master->kobj); // free master |
|
113 goto out_free; |
|
114 } |
|
115 |
|
116 list_add_tail(&master->list, &ec_masters); |
112 list_add_tail(&master->list, &ec_masters); |
117 } |
113 } |
118 |
114 |
119 EC_INFO("Master driver initialized.\n"); |
115 EC_INFO("Master driver initialized.\n"); |
120 return 0; |
116 return 0; |
142 |
138 |
143 EC_INFO("Cleaning up master driver...\n"); |
139 EC_INFO("Cleaning up master driver...\n"); |
144 |
140 |
145 list_for_each_entry_safe(master, next, &ec_masters, list) { |
141 list_for_each_entry_safe(master, next, &ec_masters, list) { |
146 list_del(&master->list); |
142 list_del(&master->list); |
147 kobject_del(&master->kobj); |
143 ec_master_destroy(master); |
148 kobject_put(&master->kobj); // free master |
|
149 } |
144 } |
150 |
145 |
151 EC_INFO("Master driver cleaned up.\n"); |
146 EC_INFO("Master driver cleaned up.\n"); |
152 } |
147 } |
153 |
148 |
223 /** |
218 /** |
224 Prints slave states in clear text. |
219 Prints slave states in clear text. |
225 */ |
220 */ |
226 |
221 |
227 size_t ec_state_string(uint8_t states, /**< slave states */ |
222 size_t ec_state_string(uint8_t states, /**< slave states */ |
228 char *buffer /**< target buffer (min. 25 bytes) */ |
223 char *buffer /**< target buffer |
|
224 (min. EC_STATE_STRING_SIZE bytes) */ |
229 ) |
225 ) |
230 { |
226 { |
231 off_t off = 0; |
227 off_t off = 0; |
232 unsigned int first = 1; |
228 unsigned int first = 1; |
233 |
229 |
251 first = 0; |
247 first = 0; |
252 } |
248 } |
253 if (states & EC_SLAVE_STATE_OP) { |
249 if (states & EC_SLAVE_STATE_OP) { |
254 if (!first) off += sprintf(buffer + off, ", "); |
250 if (!first) off += sprintf(buffer + off, ", "); |
255 off += sprintf(buffer + off, "OP"); |
251 off += sprintf(buffer + off, "OP"); |
|
252 } |
|
253 if (states & EC_SLAVE_STATE_ACK_ERR) { |
|
254 if (!first) off += sprintf(buffer + off, " + "); |
|
255 off += sprintf(buffer + off, "ERROR"); |
256 } |
256 } |
257 |
257 |
258 return off; |
258 return off; |
259 } |
259 } |
260 |
260 |
367 if (ec_device_open(master->device)) { |
367 if (ec_device_open(master->device)) { |
368 EC_ERR("Failed to open device!\n"); |
368 EC_ERR("Failed to open device!\n"); |
369 return -1; |
369 return -1; |
370 } |
370 } |
371 |
371 |
372 ec_master_idle_start(master); |
372 ec_master_enter_idle_mode(master); |
|
373 |
373 return 0; |
374 return 0; |
374 } |
375 } |
375 |
376 |
376 /*****************************************************************************/ |
377 /*****************************************************************************/ |
377 |
378 |
385 void ecdev_stop(unsigned int master_index /**< master index */) |
386 void ecdev_stop(unsigned int master_index /**< master index */) |
386 { |
387 { |
387 ec_master_t *master; |
388 ec_master_t *master; |
388 if (!(master = ec_find_master(master_index))) return; |
389 if (!(master = ec_find_master(master_index))) return; |
389 |
390 |
390 ec_master_idle_stop(master); |
391 ec_master_leave_idle_mode(master); |
391 |
392 |
392 if (ec_device_close(master->device)) |
393 if (ec_device_close(master->device)) |
393 EC_WARN("Failed to close device!\n"); |
394 EC_WARN("Failed to close device!\n"); |
394 } |
395 } |
395 |
396 |
441 if (!master->device->link_state) { |
442 if (!master->device->link_state) { |
442 EC_ERR("Link is DOWN.\n"); |
443 EC_ERR("Link is DOWN.\n"); |
443 goto out_module_put; |
444 goto out_module_put; |
444 } |
445 } |
445 |
446 |
446 ec_master_reset(master); // also stops idle mode |
447 if (ec_master_enter_operation_mode(master)) { |
447 master->mode = EC_MASTER_MODE_OPERATION; |
448 EC_ERR("Failed to enter OPERATION mode!\n"); |
448 |
449 goto out_module_put; |
449 if (ec_master_measure_bus_time(master)) { |
|
450 EC_ERR("Bus time measuring failed!\n"); |
|
451 goto out_reset; |
|
452 } |
|
453 |
|
454 if (ec_master_bus_scan(master)) { |
|
455 EC_ERR("Bus scan failed!\n"); |
|
456 goto out_reset; |
|
457 } |
450 } |
458 |
451 |
459 EC_INFO("Successfully requested master %i.\n", master_index); |
452 EC_INFO("Successfully requested master %i.\n", master_index); |
460 return master; |
453 return master; |
461 |
454 |
462 out_reset: |
|
463 ec_master_reset(master); |
|
464 ec_master_idle_start(master); |
|
465 out_module_put: |
455 out_module_put: |
466 module_put(master->device->module); |
456 module_put(master->device->module); |
467 out_release: |
457 out_release: |
468 atomic_inc(&master->available); |
458 atomic_inc(&master->available); |
469 out_return: |
459 out_return: |
470 EC_ERR("Failed to request master %i.\n", master_index); |
|
471 return NULL; |
460 return NULL; |
472 } |
461 } |
473 |
462 |
474 /*****************************************************************************/ |
463 /*****************************************************************************/ |
475 |
464 |
478 \ingroup RealtimeInterface |
467 \ingroup RealtimeInterface |
479 */ |
468 */ |
480 |
469 |
481 void ecrt_release_master(ec_master_t *master /**< EtherCAT master */) |
470 void ecrt_release_master(ec_master_t *master /**< EtherCAT master */) |
482 { |
471 { |
483 EC_INFO("Releasing master %i...\n", master->index); |
472 ec_master_leave_operation_mode(master); |
484 |
|
485 if (atomic_read(&master->available)) { |
|
486 EC_ERR("Master %i was never requested!\n", master->index); |
|
487 return; |
|
488 } |
|
489 |
|
490 ec_master_reset(master); |
|
491 ec_master_idle_start(master); |
|
492 |
473 |
493 module_put(master->device->module); |
474 module_put(master->device->module); |
494 atomic_inc(&master->available); |
475 atomic_inc(&master->available); |
495 |
476 |
496 EC_INFO("Successfully released master %i.\n", master->index); |
477 EC_INFO("Released master %i.\n", master->index); |
497 return; |
478 return; |
498 } |
479 } |
499 |
480 |
500 /*****************************************************************************/ |
481 /*****************************************************************************/ |
501 |
482 |