50 |
49 |
51 /*****************************************************************************/ |
50 /*****************************************************************************/ |
52 |
51 |
53 void ec_fsm_master_state_start(ec_fsm_master_t *); |
52 void ec_fsm_master_state_start(ec_fsm_master_t *); |
54 void ec_fsm_master_state_broadcast(ec_fsm_master_t *); |
53 void ec_fsm_master_state_broadcast(ec_fsm_master_t *); |
55 void ec_fsm_master_state_read_states(ec_fsm_master_t *); |
54 void ec_fsm_master_state_read_state(ec_fsm_master_t *); |
56 void ec_fsm_master_state_acknowledge(ec_fsm_master_t *); |
55 void ec_fsm_master_state_acknowledge(ec_fsm_master_t *); |
57 void ec_fsm_master_state_configure_slave(ec_fsm_master_t *); |
56 void ec_fsm_master_state_configure_slave(ec_fsm_master_t *); |
58 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *); |
57 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *); |
59 void ec_fsm_master_state_scan_slaves(ec_fsm_master_t *); |
58 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
60 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
59 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
61 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
60 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
62 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
61 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
63 void ec_fsm_master_state_end(ec_fsm_master_t *); |
62 void ec_fsm_master_state_end(ec_fsm_master_t *); |
64 void ec_fsm_master_state_error(ec_fsm_master_t *); |
63 void ec_fsm_master_state_error(ec_fsm_master_t *); |
65 |
64 |
66 /*****************************************************************************/ |
65 /*****************************************************************************/ |
67 |
66 |
68 /** |
67 /** Constructor. |
69 Constructor. |
68 */ |
70 */ |
69 void ec_fsm_master_init( |
71 |
70 ec_fsm_master_t *fsm, /**< Master state machine. */ |
72 void ec_fsm_master_init(ec_fsm_master_t *fsm, /**< master state machine */ |
71 ec_master_t *master, /**< EtherCAT master. */ |
73 ec_master_t *master, /**< EtherCAT master */ |
72 ec_datagram_t *datagram /**< Datagram object to use. */ |
74 ec_datagram_t *datagram /**< datagram object to use */ |
|
75 ) |
73 ) |
76 { |
74 { |
77 fsm->master = master; |
75 fsm->master = master; |
78 fsm->datagram = datagram; |
76 fsm->datagram = datagram; |
79 fsm->state = ec_fsm_master_state_start; |
77 fsm->state = ec_fsm_master_state_start; |
109 ec_fsm_coe_map_clear(&fsm->fsm_coe_map); |
107 ec_fsm_coe_map_clear(&fsm->fsm_coe_map); |
110 } |
108 } |
111 |
109 |
112 /*****************************************************************************/ |
110 /*****************************************************************************/ |
113 |
111 |
114 /** |
112 /** Executes the current state of the state machine. |
115 Executes the current state of the state machine. |
113 * |
116 If the state machine's datagram is not sent or received yet, the execution |
114 * If the state machine's datagram is not sent or received yet, the execution |
117 of the state machine is delayed to the next cycle. |
115 * of the state machine is delayed to the next cycle. |
118 \return false, if state machine has terminated |
116 * |
119 */ |
117 * \return false, if state machine has terminated |
120 |
118 */ |
121 int ec_fsm_master_exec(ec_fsm_master_t *fsm /**< master state machine */) |
119 int ec_fsm_master_exec( |
|
120 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
121 ) |
122 { |
122 { |
123 if (fsm->datagram->state == EC_DATAGRAM_SENT |
123 if (fsm->datagram->state == EC_DATAGRAM_SENT |
124 || fsm->datagram->state == EC_DATAGRAM_QUEUED) { |
124 || fsm->datagram->state == EC_DATAGRAM_QUEUED) { |
125 // datagram was not sent or received yet. |
125 // datagram was not sent or received yet. |
126 return ec_fsm_master_running(fsm); |
126 return ec_fsm_master_running(fsm); |
147 /*****************************************************************************/ |
146 /*****************************************************************************/ |
148 |
147 |
149 /** |
148 /** |
150 * \return true, if the state machine is in an idle phase |
149 * \return true, if the state machine is in an idle phase |
151 */ |
150 */ |
152 |
|
153 int ec_fsm_master_idle( |
151 int ec_fsm_master_idle( |
154 const ec_fsm_master_t *fsm /**< master state machine */ |
152 const ec_fsm_master_t *fsm /**< Master state machine. */ |
155 ) |
153 ) |
156 { |
154 { |
157 return fsm->idle; |
155 return fsm->idle; |
158 } |
156 } |
159 |
157 |
160 /****************************************************************************** |
158 /****************************************************************************** |
161 * master state machine |
159 * Master state machine |
162 *****************************************************************************/ |
160 *****************************************************************************/ |
163 |
161 |
164 /** |
162 /** Master state: START. |
165 Master state: START. |
163 * |
166 Starts with getting slave count and slave states. |
164 * Starts with getting slave count and slave states. |
167 */ |
165 */ |
168 |
166 void ec_fsm_master_state_start( |
169 void ec_fsm_master_state_start(ec_fsm_master_t *fsm) |
167 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
168 ) |
170 { |
169 { |
171 fsm->idle = 1; |
170 fsm->idle = 1; |
172 ec_datagram_brd(fsm->datagram, 0x0130, 2); |
171 ec_datagram_brd(fsm->datagram, 0x0130, 2); |
173 fsm->state = ec_fsm_master_state_broadcast; |
172 fsm->state = ec_fsm_master_state_broadcast; |
174 } |
173 } |
175 |
174 |
176 /*****************************************************************************/ |
175 /*****************************************************************************/ |
177 |
176 |
178 /** |
177 /** Master state: BROADCAST. |
179 Master state: BROADCAST. |
178 * |
180 Processes the broadcast read slave count and slaves states. |
179 * Processes the broadcast read slave count and slaves states. |
181 */ |
180 */ |
182 |
181 void ec_fsm_master_state_broadcast( |
183 void ec_fsm_master_state_broadcast(ec_fsm_master_t *fsm /**< master state machine */) |
182 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
183 ) |
184 { |
184 { |
185 ec_datagram_t *datagram = fsm->datagram; |
185 ec_datagram_t *datagram = fsm->datagram; |
186 unsigned int i; |
186 unsigned int i; |
187 ec_slave_t *slave; |
187 ec_slave_t *slave; |
188 ec_master_t *master = fsm->master; |
188 ec_master_t *master = fsm->master; |
274 } |
274 } |
275 |
275 |
276 if (list_empty(&master->slaves)) { |
276 if (list_empty(&master->slaves)) { |
277 fsm->state = ec_fsm_master_state_end; |
277 fsm->state = ec_fsm_master_state_end; |
278 } else { |
278 } else { |
279 // fetch state from each slave |
279 // fetch state from first slave |
280 fsm->slave = list_entry(master->slaves.next, ec_slave_t, list); |
280 fsm->slave = list_entry(master->slaves.next, ec_slave_t, list); |
281 ec_datagram_fprd(fsm->datagram, fsm->slave->station_address, 0x0130, 2); |
281 ec_datagram_fprd(fsm->datagram, fsm->slave->station_address, |
|
282 0x0130, 2); |
282 fsm->retries = EC_FSM_RETRIES; |
283 fsm->retries = EC_FSM_RETRIES; |
283 fsm->state = ec_fsm_master_state_read_states; |
284 fsm->state = ec_fsm_master_state_read_state; |
284 } |
285 } |
285 } |
286 } |
286 |
287 |
287 /*****************************************************************************/ |
288 /*****************************************************************************/ |
288 |
289 |
289 /** |
290 /** Check for pending SII write requests and process one. |
290 * Check for pending SII write requests and process one. |
291 * |
291 * \return non-zero, if an SII write request is processed. |
292 * \return non-zero, if an SII write request is processed. |
292 */ |
293 */ |
293 |
|
294 int ec_fsm_master_action_process_sii( |
294 int ec_fsm_master_action_process_sii( |
295 ec_fsm_master_t *fsm /**< master state machine */ |
295 ec_fsm_master_t *fsm /**< Master state machine. */ |
296 ) |
296 ) |
297 { |
297 { |
298 ec_master_t *master = fsm->master; |
298 ec_master_t *master = fsm->master; |
299 ec_sii_write_request_t *request; |
299 ec_sii_write_request_t *request; |
300 |
300 |
423 return 0; |
422 return 0; |
424 } |
423 } |
425 |
424 |
426 /*****************************************************************************/ |
425 /*****************************************************************************/ |
427 |
426 |
428 /** |
427 /** Master action: IDLE. |
429 * Check for slaves that are not configured and configure them. |
428 * |
430 */ |
429 * Does secondary work. |
431 |
430 */ |
432 int ec_fsm_master_action_configure( |
431 void ec_fsm_master_action_idle( |
433 ec_fsm_master_t *fsm /**< master state machine */ |
432 ec_fsm_master_t *fsm /**< Master state machine. */ |
434 ) |
433 ) |
435 { |
434 { |
|
435 ec_master_t *master = fsm->master; |
436 ec_slave_t *slave; |
436 ec_slave_t *slave; |
437 ec_master_t *master = fsm->master; |
|
438 char old_state[EC_STATE_STRING_SIZE], new_state[EC_STATE_STRING_SIZE]; |
|
439 |
|
440 // check if any slaves are not in the state, they're supposed to be |
|
441 // FIXME do not check all slaves in every cycle... |
|
442 list_for_each_entry(slave, &master->slaves, list) { |
|
443 if (slave->error_flag |
|
444 || slave->requested_state == EC_SLAVE_STATE_UNKNOWN |
|
445 || (slave->current_state == slave->requested_state |
|
446 && slave->self_configured)) continue; |
|
447 |
|
448 if (master->debug_level) { |
|
449 ec_state_string(slave->current_state, old_state); |
|
450 if (slave->current_state != slave->requested_state) { |
|
451 ec_state_string(slave->requested_state, new_state); |
|
452 EC_DBG("Changing state of slave %i (%s -> %s).\n", |
|
453 slave->ring_position, old_state, new_state); |
|
454 } |
|
455 else if (!slave->self_configured) { |
|
456 EC_DBG("Reconfiguring slave %i (%s).\n", |
|
457 slave->ring_position, old_state); |
|
458 } |
|
459 } |
|
460 |
|
461 fsm->idle = 0; |
|
462 fsm->slave = slave; |
|
463 fsm->state = ec_fsm_master_state_configure_slave; |
|
464 ec_fsm_slave_config_start(&fsm->fsm_slave_config, slave); |
|
465 ec_fsm_slave_config_exec(&fsm->fsm_slave_config); // execute immediately |
|
466 return 1; |
|
467 } |
|
468 |
|
469 master->config_busy = 0; |
|
470 wake_up_interruptible(&master->config_queue); |
|
471 return 0; |
|
472 } |
|
473 |
|
474 /*****************************************************************************/ |
|
475 |
|
476 /** |
|
477 Master action: PROC_STATES. |
|
478 Processes the slave states. |
|
479 */ |
|
480 |
|
481 void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm |
|
482 /**< master state machine */ |
|
483 ) |
|
484 { |
|
485 ec_master_t *master = fsm->master; |
|
486 ec_slave_t *slave; |
|
487 |
|
488 // Start slave configuration, if it is allowed. |
|
489 down(&master->config_sem); |
|
490 if (!master->allow_config) { |
|
491 up(&master->config_sem); |
|
492 } else { |
|
493 master->config_busy = 1; |
|
494 up(&master->config_sem); |
|
495 |
|
496 // check for pending slave configurations |
|
497 if (ec_fsm_master_action_configure(fsm)) |
|
498 return; |
|
499 } |
|
500 |
437 |
501 // Check for pending Sdo requests |
438 // Check for pending Sdo requests |
502 if (ec_fsm_master_action_process_sdo(fsm)) |
439 if (ec_fsm_master_action_process_sdo(fsm)) |
503 return; |
440 return; |
504 |
441 |
536 fsm->state = ec_fsm_master_state_end; |
473 fsm->state = ec_fsm_master_state_end; |
537 } |
474 } |
538 |
475 |
539 /*****************************************************************************/ |
476 /*****************************************************************************/ |
540 |
477 |
541 /** |
478 /** Master action: Get state of next slave. |
542 Master action: Get state of next slave. |
479 */ |
543 */ |
480 void ec_fsm_master_action_next_slave_state( |
544 |
481 ec_fsm_master_t *fsm /**< Master state machine. */ |
545 void ec_fsm_master_action_next_slave_state(ec_fsm_master_t *fsm |
482 ) |
546 /**< master state machine */) |
|
547 { |
483 { |
548 ec_master_t *master = fsm->master; |
484 ec_master_t *master = fsm->master; |
549 ec_slave_t *slave = fsm->slave; |
485 ec_slave_t *slave = fsm->slave; |
550 |
486 |
551 // is there another slave to query? |
487 // is there another slave to query? |
552 if (slave->list.next != &master->slaves) { |
488 if (slave->list.next != &master->slaves) { |
553 // process next slave |
489 // fetch state from next slave |
554 fsm->idle = 1; |
490 fsm->idle = 1; |
555 fsm->slave = list_entry(slave->list.next, ec_slave_t, list); |
491 fsm->slave = list_entry(slave->list.next, ec_slave_t, list); |
556 ec_datagram_fprd(fsm->datagram, fsm->slave->station_address, |
492 ec_datagram_fprd(fsm->datagram, fsm->slave->station_address, |
557 0x0130, 2); |
493 0x0130, 2); |
558 fsm->retries = EC_FSM_RETRIES; |
494 fsm->retries = EC_FSM_RETRIES; |
559 fsm->state = ec_fsm_master_state_read_states; |
495 fsm->state = ec_fsm_master_state_read_state; |
560 return; |
496 return; |
561 } |
497 } |
562 |
498 |
563 // all slave states read |
499 // all slaves processed |
564 ec_fsm_master_action_process_states(fsm); |
500 ec_fsm_master_action_idle(fsm); |
565 } |
501 } |
566 |
502 |
567 /*****************************************************************************/ |
503 /*****************************************************************************/ |
568 |
504 |
569 /** |
505 /** Master action: Configure. |
570 Master state: READ STATES. |
506 */ |
571 Fetches the AL- and online state of a slave. |
507 void ec_fsm_master_action_configure( |
572 */ |
508 ec_fsm_master_t *fsm /**< Master state machine. */ |
573 |
509 ) |
574 void ec_fsm_master_state_read_states(ec_fsm_master_t *fsm /**< master state machine */) |
510 { |
|
511 ec_master_t *master = fsm->master; |
|
512 ec_slave_t *slave = fsm->slave; |
|
513 |
|
514 // Does the slave have to be configured? |
|
515 if (!slave->error_flag |
|
516 && (slave->current_state != slave->requested_state |
|
517 || !slave->self_configured)) { |
|
518 // Start slave configuration, if it is allowed. |
|
519 down(&master->config_sem); |
|
520 if (!master->allow_config) { |
|
521 up(&master->config_sem); |
|
522 } else { |
|
523 master->config_busy = 1; |
|
524 up(&master->config_sem); |
|
525 |
|
526 if (master->debug_level) { |
|
527 char old_state[EC_STATE_STRING_SIZE]; |
|
528 ec_state_string(slave->current_state, old_state); |
|
529 if (slave->current_state != slave->requested_state) { |
|
530 char new_state[EC_STATE_STRING_SIZE]; |
|
531 ec_state_string(slave->requested_state, new_state); |
|
532 EC_DBG("Changing state of slave %u (%s -> %s).\n", |
|
533 slave->ring_position, old_state, new_state); |
|
534 } else if (!slave->self_configured) { |
|
535 EC_DBG("Reconfiguring slave %u (%s).\n", |
|
536 slave->ring_position, old_state); |
|
537 } |
|
538 } |
|
539 |
|
540 fsm->idle = 0; |
|
541 fsm->state = ec_fsm_master_state_configure_slave; |
|
542 ec_fsm_slave_config_start(&fsm->fsm_slave_config, slave); |
|
543 fsm->state(fsm); // execute immediately |
|
544 return; |
|
545 } |
|
546 } |
|
547 |
|
548 // slave has error flag set; process next one |
|
549 ec_fsm_master_action_next_slave_state(fsm); |
|
550 } |
|
551 |
|
552 /*****************************************************************************/ |
|
553 |
|
554 /** Master action: Acknowledge. |
|
555 */ |
|
556 void ec_fsm_master_action_acknowledge( |
|
557 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
558 ) |
|
559 { |
|
560 ec_slave_t *slave = fsm->slave; |
|
561 |
|
562 if (!slave->error_flag) { |
|
563 // Check, if new slave state has to be acknowledged |
|
564 if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) { |
|
565 fsm->idle = 0; |
|
566 fsm->state = ec_fsm_master_state_acknowledge; |
|
567 ec_fsm_change_ack(&fsm->fsm_change, slave); |
|
568 fsm->state(fsm); // execute immediately |
|
569 return; |
|
570 } |
|
571 |
|
572 // No acknowlegde necessary; check for configuration |
|
573 ec_fsm_master_action_configure(fsm); |
|
574 return; |
|
575 } |
|
576 |
|
577 // slave has error flag set; process next one |
|
578 ec_fsm_master_action_next_slave_state(fsm); |
|
579 } |
|
580 |
|
581 /*****************************************************************************/ |
|
582 |
|
583 /** Master state: READ STATE. |
|
584 * |
|
585 * Fetches the AL state of a slave. |
|
586 */ |
|
587 void ec_fsm_master_state_read_state( |
|
588 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
589 ) |
575 { |
590 { |
576 ec_slave_t *slave = fsm->slave; |
591 ec_slave_t *slave = fsm->slave; |
577 ec_datagram_t *datagram = fsm->datagram; |
592 ec_datagram_t *datagram = fsm->datagram; |
578 |
593 |
579 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
594 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
580 return; |
595 return; |
581 |
596 |
582 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
597 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
583 EC_ERR("Failed to receive AL state datagram for slave %i" |
598 EC_ERR("Failed to receive AL state datagram for slave %u" |
584 " (datagram state %i)\n", |
599 " (datagram state %i)\n", |
585 slave->ring_position, datagram->state); |
600 slave->ring_position, datagram->state); |
586 fsm->state = ec_fsm_master_state_error; |
601 fsm->state = ec_fsm_master_state_error; |
587 return; |
602 return; |
588 } |
603 } |
598 fsm->topology_change_pending = 1; |
613 fsm->topology_change_pending = 1; |
599 fsm->state = ec_fsm_master_state_error; |
614 fsm->state = ec_fsm_master_state_error; |
600 return; |
615 return; |
601 } |
616 } |
602 |
617 |
603 // a single slave responded |
618 // A single slave responded |
604 ec_slave_set_state(slave, EC_READ_U8(datagram->data)); // set app state first |
619 ec_slave_set_state(slave, EC_READ_U8(datagram->data)); |
605 |
620 ec_fsm_master_action_acknowledge(fsm); |
606 // check, if new slave state has to be acknowledged |
621 } |
607 if (slave->current_state & EC_SLAVE_STATE_ACK_ERR && !slave->error_flag) { |
622 |
608 fsm->idle = 0; |
623 /*****************************************************************************/ |
609 fsm->state = ec_fsm_master_state_acknowledge; |
624 |
610 ec_fsm_change_ack(&fsm->fsm_change, slave); |
625 /** Master state: ACKNOWLEDGE. |
611 ec_fsm_change_exec(&fsm->fsm_change); |
626 */ |
612 return; |
627 void ec_fsm_master_state_acknowledge( |
613 } |
628 ec_fsm_master_t *fsm /**< Master state machine. */ |
614 |
629 ) |
615 ec_fsm_master_action_next_slave_state(fsm); |
|
616 } |
|
617 |
|
618 /*****************************************************************************/ |
|
619 |
|
620 /** |
|
621 Master state: ACKNOWLEDGE |
|
622 */ |
|
623 |
|
624 void ec_fsm_master_state_acknowledge(ec_fsm_master_t *fsm /**< master state machine */) |
|
625 { |
630 { |
626 ec_slave_t *slave = fsm->slave; |
631 ec_slave_t *slave = fsm->slave; |
627 |
632 |
628 if (ec_fsm_change_exec(&fsm->fsm_change)) return; |
633 if (ec_fsm_change_exec(&fsm->fsm_change)) |
|
634 return; |
629 |
635 |
630 if (!ec_fsm_change_success(&fsm->fsm_change)) { |
636 if (!ec_fsm_change_success(&fsm->fsm_change)) { |
631 fsm->slave->error_flag = 1; |
637 fsm->slave->error_flag = 1; |
632 EC_ERR("Failed to acknowledge state change on slave %i.\n", |
638 EC_ERR("Failed to acknowledge state change on slave %u.\n", |
633 slave->ring_position); |
639 slave->ring_position); |
634 fsm->state = ec_fsm_master_state_error; |
640 } |
635 return; |
641 |
636 } |
642 ec_fsm_master_action_configure(fsm); |
637 |
643 } |
638 ec_fsm_master_action_next_slave_state(fsm); |
644 |
639 } |
645 /*****************************************************************************/ |
640 |
646 |
641 /*****************************************************************************/ |
647 /** Master state: CLEAR ADDRESSES. |
642 |
648 */ |
643 /** |
|
644 * Master state: CLEAR ADDRESSES. |
|
645 */ |
|
646 |
|
647 void ec_fsm_master_state_clear_addresses( |
649 void ec_fsm_master_state_clear_addresses( |
648 ec_fsm_master_t *fsm /**< master state machine */ |
650 ec_fsm_master_t *fsm /**< Master state machine. */ |
649 ) |
651 ) |
650 { |
652 { |
651 ec_master_t *master = fsm->master; |
653 ec_master_t *master = fsm->master; |
652 ec_datagram_t *datagram = fsm->datagram; |
654 ec_datagram_t *datagram = fsm->datagram; |
653 |
655 |
670 |
672 |
671 EC_INFO("Scanning bus.\n"); |
673 EC_INFO("Scanning bus.\n"); |
672 |
674 |
673 // begin scanning of slaves |
675 // begin scanning of slaves |
674 fsm->slave = list_entry(master->slaves.next, ec_slave_t, list); |
676 fsm->slave = list_entry(master->slaves.next, ec_slave_t, list); |
675 fsm->state = ec_fsm_master_state_scan_slaves; |
677 fsm->state = ec_fsm_master_state_scan_slave; |
676 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
678 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
677 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately |
679 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately |
678 } |
680 } |
679 |
681 |
680 /*****************************************************************************/ |
682 /*****************************************************************************/ |
681 |
683 |
682 /** |
684 /** Master state: SCAN SLAVE. |
683 * Master state: SCAN SLAVES. |
685 * |
684 * Executes the sub-statemachine for the scanning of a slave. |
686 * Executes the sub-statemachine for the scanning of a slave. |
685 */ |
687 */ |
686 |
688 void ec_fsm_master_state_scan_slave( |
687 void ec_fsm_master_state_scan_slaves( |
689 ec_fsm_master_t *fsm /**< Master state machine. */ |
688 ec_fsm_master_t *fsm /**< master state machine */ |
|
689 ) |
690 ) |
690 { |
691 { |
691 ec_master_t *master = fsm->master; |
692 ec_master_t *master = fsm->master; |
692 ec_slave_t *slave = fsm->slave; |
693 ec_slave_t *slave = fsm->slave; |
693 |
694 |
694 if (ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan)) // execute slave state machine |
695 if (ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan)) |
695 return; |
696 return; |
696 |
697 |
697 #ifdef EC_EOE |
698 #ifdef EC_EOE |
698 if (slave->sii.mailbox_protocols & EC_MBOX_EOE) { |
699 if (slave->sii.mailbox_protocols & EC_MBOX_EOE) { |
699 // create EoE handler for this slave |
700 // create EoE handler for this slave |
736 fsm->state = ec_fsm_master_state_end; |
737 fsm->state = ec_fsm_master_state_end; |
737 } |
738 } |
738 |
739 |
739 /*****************************************************************************/ |
740 /*****************************************************************************/ |
740 |
741 |
741 /** |
742 /** Master state: CONFIGURE SLAVE. |
742 Master state: CONFIGURE SLAVES. |
743 * |
743 Starts configuring a slave. |
744 * Starts configuring a slave. |
744 */ |
745 */ |
745 |
746 void ec_fsm_master_state_configure_slave( |
746 void ec_fsm_master_state_configure_slave(ec_fsm_master_t *fsm |
747 ec_fsm_master_t *fsm /**< Master state machine. */ |
747 /**< master state machine */ |
748 ) |
748 ) |
749 { |
749 { |
750 ec_master_t *master = fsm->master; |
750 if (ec_fsm_slave_config_exec(&fsm->fsm_slave_config)) // execute slave's state machine |
751 |
751 return; |
752 if (ec_fsm_slave_config_exec(&fsm->fsm_slave_config)) |
|
753 return; |
|
754 |
|
755 // configuration finished |
|
756 master->config_busy = 0; |
|
757 wake_up_interruptible(&master->config_queue); |
752 |
758 |
753 if (!ec_fsm_slave_config_success(&fsm->fsm_slave_config)) { |
759 if (!ec_fsm_slave_config_success(&fsm->fsm_slave_config)) { |
754 // TODO: mark slave_config as failed. |
760 // TODO: mark slave_config as failed. |
755 } |
761 } |
756 |
762 |
757 // configure next slave, if necessary |
763 fsm->idle = 1; |
758 if (ec_fsm_master_action_configure(fsm)) |
764 ec_fsm_master_action_next_slave_state(fsm); |
759 return; |
765 } |
760 |
766 |
761 fsm->state = ec_fsm_master_state_end; |
767 /*****************************************************************************/ |
762 } |
768 |
763 |
769 /** Master state: WRITE SII. |
764 /*****************************************************************************/ |
770 */ |
765 |
|
766 /** |
|
767 Master state: WRITE SII. |
|
768 */ |
|
769 |
|
770 void ec_fsm_master_state_write_sii( |
771 void ec_fsm_master_state_write_sii( |
771 ec_fsm_master_t *fsm /**< master state machine */) |
772 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
773 ) |
772 { |
774 { |
773 ec_master_t *master = fsm->master; |
775 ec_master_t *master = fsm->master; |
774 ec_sii_write_request_t *request = fsm->sii_request; |
776 ec_sii_write_request_t *request = fsm->sii_request; |
775 ec_slave_t *slave = request->slave; |
777 ec_slave_t *slave = request->slave; |
776 |
778 |