89 |
89 |
90 master->main_mac = main_mac; |
90 master->main_mac = main_mac; |
91 master->backup_mac = backup_mac; |
91 master->backup_mac = backup_mac; |
92 init_MUTEX(&master->device_sem); |
92 init_MUTEX(&master->device_sem); |
93 |
93 |
94 master->mode = EC_MASTER_MODE_ORPHANED; |
94 master->phase = EC_ORPHANED; |
95 master->injection_seq_fsm = 0; |
95 master->injection_seq_fsm = 0; |
96 master->injection_seq_rt = 0; |
96 master->injection_seq_rt = 0; |
97 |
97 |
98 master->slaves = NULL; |
98 master->slaves = NULL; |
99 master->slave_count = 0; |
99 master->slave_count = 0; |
336 |
336 |
337 /*****************************************************************************/ |
337 /*****************************************************************************/ |
338 |
338 |
339 /** Stops the master thread. |
339 /** Stops the master thread. |
340 */ |
340 */ |
341 void ec_master_thread_stop(ec_master_t *master /**< EtherCAT master */) |
341 void ec_master_thread_stop( |
|
342 ec_master_t *master /**< EtherCAT master */ |
|
343 ) |
342 { |
344 { |
343 if (!master->thread_id) { |
345 if (!master->thread_id) { |
344 EC_WARN("ec_master_thread_stop: Already finished!\n"); |
346 EC_WARN("ec_master_thread_stop: Already finished!\n"); |
345 return; |
347 return; |
346 } |
348 } |
360 schedule(); |
362 schedule(); |
361 } |
363 } |
362 |
364 |
363 /*****************************************************************************/ |
365 /*****************************************************************************/ |
364 |
366 |
365 /** Transition function from ORPHANED to IDLE mode. |
367 /** Transition function from ORPHANED to IDLE phase. |
366 */ |
368 */ |
367 int ec_master_enter_idle_mode(ec_master_t *master /**< EtherCAT master */) |
369 int ec_master_enter_idle_phase( |
|
370 ec_master_t *master /**< EtherCAT master */ |
|
371 ) |
368 { |
372 { |
369 master->request_cb = ec_master_request_cb; |
373 master->request_cb = ec_master_request_cb; |
370 master->release_cb = ec_master_release_cb; |
374 master->release_cb = ec_master_release_cb; |
371 master->cb_data = master; |
375 master->cb_data = master; |
372 |
376 |
373 if (master->debug_level) |
377 if (master->debug_level) |
374 EC_DBG("ORPHANED -> IDLE.\n"); |
378 EC_DBG("ORPHANED -> IDLE.\n"); |
375 |
379 |
376 master->mode = EC_MASTER_MODE_IDLE; |
380 master->phase = EC_IDLE; |
377 if (ec_master_thread_start(master, ec_master_idle_thread)) { |
381 if (ec_master_thread_start(master, ec_master_idle_thread)) { |
378 master->mode = EC_MASTER_MODE_ORPHANED; |
382 master->phase = EC_ORPHANED; |
379 return -1; |
383 return -1; |
380 } |
384 } |
381 |
385 |
382 return 0; |
386 return 0; |
383 } |
387 } |
384 |
388 |
385 /*****************************************************************************/ |
389 /*****************************************************************************/ |
386 |
390 |
387 /** Transition function from IDLE to ORPHANED mode. |
391 /** Transition function from IDLE to ORPHANED phase. |
388 */ |
392 */ |
389 void ec_master_leave_idle_mode(ec_master_t *master /**< EtherCAT master */) |
393 void ec_master_leave_idle_phase(ec_master_t *master /**< EtherCAT master */) |
390 { |
394 { |
391 if (master->debug_level) |
395 if (master->debug_level) |
392 EC_DBG("IDLE -> ORPHANED.\n"); |
396 EC_DBG("IDLE -> ORPHANED.\n"); |
393 |
397 |
394 master->mode = EC_MASTER_MODE_ORPHANED; |
398 master->phase = EC_ORPHANED; |
395 |
399 |
396 #ifdef EC_EOE |
400 #ifdef EC_EOE |
397 ec_master_eoe_stop(master); |
401 ec_master_eoe_stop(master); |
398 #endif |
402 #endif |
399 ec_master_thread_stop(master); |
403 ec_master_thread_stop(master); |
400 ec_master_clear_slaves(master); |
404 ec_master_clear_slaves(master); |
401 } |
405 } |
402 |
406 |
403 /*****************************************************************************/ |
407 /*****************************************************************************/ |
404 |
408 |
405 /** Transition function from IDLE to OPERATION mode. |
409 /** Transition function from IDLE to OPERATION phase. |
406 */ |
410 */ |
407 int ec_master_enter_operation_mode(ec_master_t *master /**< EtherCAT master */) |
411 int ec_master_enter_operation_phase(ec_master_t *master /**< EtherCAT master */) |
408 { |
412 { |
409 ec_slave_t *slave; |
413 ec_slave_t *slave; |
410 #ifdef EC_EOE |
414 #ifdef EC_EOE |
411 ec_eoe_t *eoe; |
415 ec_eoe_t *eoe; |
412 #endif |
416 #endif |
462 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP); |
466 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP); |
463 } |
467 } |
464 #endif |
468 #endif |
465 |
469 |
466 if (master->debug_level) |
470 if (master->debug_level) |
467 EC_DBG("Switching to operation mode.\n"); |
471 EC_DBG("Switching to operation phase.\n"); |
468 |
472 |
469 master->mode = EC_MASTER_MODE_OPERATION; |
473 master->phase = EC_OPERATION; |
470 master->ext_request_cb = NULL; |
474 master->ext_request_cb = NULL; |
471 master->ext_release_cb = NULL; |
475 master->ext_release_cb = NULL; |
472 master->ext_cb_data = NULL; |
476 master->ext_cb_data = NULL; |
473 return 0; |
477 return 0; |
474 |
478 |
478 return -1; |
482 return -1; |
479 } |
483 } |
480 |
484 |
481 /*****************************************************************************/ |
485 /*****************************************************************************/ |
482 |
486 |
483 /** Transition function from OPERATION to IDLE mode. |
487 /** Transition function from OPERATION to IDLE phase. |
484 */ |
488 */ |
485 void ec_master_leave_operation_mode(ec_master_t *master |
489 void ec_master_leave_operation_phase(ec_master_t *master |
486 /**< EtherCAT master */) |
490 /**< EtherCAT master */) |
487 { |
491 { |
488 ec_slave_t *slave; |
492 ec_slave_t *slave; |
489 #ifdef EC_EOE |
493 #ifdef EC_EOE |
490 ec_eoe_t *eoe; |
494 ec_eoe_t *eoe; |
491 #endif |
495 #endif |
492 |
496 |
493 if (master->debug_level) |
497 if (master->debug_level) |
494 EC_DBG("OPERATION -> IDLE.\n"); |
498 EC_DBG("OPERATION -> IDLE.\n"); |
495 |
499 |
496 master->mode = EC_MASTER_MODE_IDLE; |
500 master->phase = EC_IDLE; |
497 |
501 |
498 #ifdef EC_EOE |
502 #ifdef EC_EOE |
499 ec_master_eoe_stop(master); |
503 ec_master_eoe_stop(master); |
500 #endif |
504 #endif |
501 ec_master_thread_stop(master); |
505 ec_master_thread_stop(master); |
769 } |
773 } |
770 } |
774 } |
771 |
775 |
772 /*****************************************************************************/ |
776 /*****************************************************************************/ |
773 |
777 |
774 /** Output statistics in cyclic mode. |
778 /** Output master statistics. |
775 * |
779 * |
776 * This function outputs statistical data on demand, but not more often than |
780 * This function outputs statistical data on demand, but not more often than |
777 * necessary. The output happens at most once a second. |
781 * necessary. The output happens at most once a second. |
778 */ |
782 */ |
779 void ec_master_output_stats(ec_master_t *master /**< EtherCAT master */) |
783 void ec_master_output_stats(ec_master_t *master /**< EtherCAT master */) |
855 complete_and_exit(&master->thread_exit, 0); |
859 complete_and_exit(&master->thread_exit, 0); |
856 } |
860 } |
857 |
861 |
858 /*****************************************************************************/ |
862 /*****************************************************************************/ |
859 |
863 |
860 /** Master kernel thread function for IDLE mode. |
864 /** Master kernel thread function for IDLE phase. |
861 */ |
865 */ |
862 static int ec_master_operation_thread(ec_master_t *master) |
866 static int ec_master_operation_thread(ec_master_t *master) |
863 { |
867 { |
864 cycles_t cycles_start, cycles_end; |
868 cycles_t cycles_start, cycles_end; |
865 |
869 |