52 |
52 |
53 /*****************************************************************************/ |
53 /*****************************************************************************/ |
54 |
54 |
55 void ec_fsm_master_state_start(ec_fsm_master_t *); |
55 void ec_fsm_master_state_start(ec_fsm_master_t *); |
56 void ec_fsm_master_state_broadcast(ec_fsm_master_t *); |
56 void ec_fsm_master_state_broadcast(ec_fsm_master_t *); |
57 void ec_fsm_master_state_read_state(ec_fsm_master_t *); |
57 void ec_fsm_master_state_read_al_status(ec_fsm_master_t *); |
|
58 #ifdef EC_LOOP_CONTROL |
|
59 void ec_fsm_master_state_read_dl_status(ec_fsm_master_t *); |
|
60 void ec_fsm_master_state_open_port(ec_fsm_master_t *); |
|
61 #endif |
58 void ec_fsm_master_state_acknowledge(ec_fsm_master_t *); |
62 void ec_fsm_master_state_acknowledge(ec_fsm_master_t *); |
59 void ec_fsm_master_state_configure_slave(ec_fsm_master_t *); |
63 void ec_fsm_master_state_configure_slave(ec_fsm_master_t *); |
60 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *); |
64 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *); |
|
65 #ifdef EC_LOOP_CONTROL |
|
66 void ec_fsm_master_state_loop_control(ec_fsm_master_t *); |
|
67 #endif |
61 void ec_fsm_master_state_dc_measure_delays(ec_fsm_master_t *); |
68 void ec_fsm_master_state_dc_measure_delays(ec_fsm_master_t *); |
62 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
69 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
63 void ec_fsm_master_state_dc_read_offset(ec_fsm_master_t *); |
70 void ec_fsm_master_state_dc_read_offset(ec_fsm_master_t *); |
64 void ec_fsm_master_state_dc_write_offset(ec_fsm_master_t *); |
71 void ec_fsm_master_state_dc_write_offset(ec_fsm_master_t *); |
65 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
72 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
592 ec_datagram_fprd(fsm->datagram, |
599 ec_datagram_fprd(fsm->datagram, |
593 fsm->slave->station_address, 0x0130, 2); |
600 fsm->slave->station_address, 0x0130, 2); |
594 ec_datagram_zero(fsm->datagram); |
601 ec_datagram_zero(fsm->datagram); |
595 fsm->datagram->device_index = fsm->slave->device_index; |
602 fsm->datagram->device_index = fsm->slave->device_index; |
596 fsm->retries = EC_FSM_RETRIES; |
603 fsm->retries = EC_FSM_RETRIES; |
597 fsm->state = ec_fsm_master_state_read_state; |
604 fsm->state = ec_fsm_master_state_read_al_status; |
598 return; |
605 return; |
599 } |
606 } |
600 |
607 |
601 // all slaves processed |
608 // all slaves processed |
602 ec_fsm_master_action_idle(fsm); |
609 ec_fsm_master_action_idle(fsm); |
603 } |
610 } |
|
611 |
|
612 /*****************************************************************************/ |
|
613 |
|
614 #ifdef EC_LOOP_CONTROL |
|
615 |
|
616 /** Master action: Read DL status of current slave. |
|
617 */ |
|
618 void ec_fsm_master_action_read_dl_status( |
|
619 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
620 ) |
|
621 { |
|
622 ec_datagram_fprd(fsm->datagram, fsm->slave->station_address, 0x0110, 2); |
|
623 ec_datagram_zero(fsm->datagram); |
|
624 fsm->datagram->device_index = fsm->slave->device_index; |
|
625 fsm->retries = EC_FSM_RETRIES; |
|
626 fsm->state = ec_fsm_master_state_read_dl_status; |
|
627 } |
|
628 |
|
629 /*****************************************************************************/ |
|
630 |
|
631 /** Master action: Open slave port. |
|
632 */ |
|
633 void ec_fsm_master_action_open_port( |
|
634 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
635 ) |
|
636 { |
|
637 EC_SLAVE_INFO(fsm->slave, "Opening ports.\n"); |
|
638 |
|
639 ec_datagram_fpwr(fsm->datagram, fsm->slave->station_address, 0x0101, 1); |
|
640 EC_WRITE_U8(fsm->datagram->data, 0x54); // port 0 auto, 1-3 auto-close |
|
641 fsm->datagram->device_index = fsm->slave->device_index; |
|
642 fsm->retries = EC_FSM_RETRIES; |
|
643 fsm->state = ec_fsm_master_state_open_port; |
|
644 } |
|
645 |
|
646 /*****************************************************************************/ |
|
647 |
|
648 /** Master state: READ DL STATUS. |
|
649 * |
|
650 * Fetches the DL state of a slave. |
|
651 */ |
|
652 void ec_fsm_master_state_read_dl_status( |
|
653 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
654 ) |
|
655 { |
|
656 ec_slave_t *slave = fsm->slave; |
|
657 ec_datagram_t *datagram = fsm->datagram; |
|
658 unsigned int i; |
|
659 |
|
660 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { |
|
661 return; |
|
662 } |
|
663 |
|
664 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
665 EC_SLAVE_ERR(slave, "Failed to receive AL state datagram: "); |
|
666 ec_datagram_print_state(datagram); |
|
667 ec_fsm_master_restart(fsm); |
|
668 return; |
|
669 } |
|
670 |
|
671 // did the slave not respond to its station address? |
|
672 if (datagram->working_counter != 1) { |
|
673 // try again next time |
|
674 ec_fsm_master_action_next_slave_state(fsm); |
|
675 return; |
|
676 } |
|
677 |
|
678 ec_slave_set_dl_status(slave, EC_READ_U16(datagram->data)); |
|
679 |
|
680 // process port state machines |
|
681 for (i = 0; i < EC_MAX_PORTS; i++) { |
|
682 ec_slave_port_t *port = &slave->ports[i]; |
|
683 |
|
684 switch (port->state) { |
|
685 case EC_SLAVE_PORT_DOWN: |
|
686 if (port->link.loop_closed) { |
|
687 if (port->link.link_up) { |
|
688 port->link_detection_jiffies = jiffies; |
|
689 port->state = EC_SLAVE_PORT_WAIT; |
|
690 } |
|
691 } |
|
692 else { // loop open |
|
693 port->state = EC_SLAVE_PORT_UP; |
|
694 } |
|
695 break; |
|
696 case EC_SLAVE_PORT_WAIT: |
|
697 if (port->link.link_up) { |
|
698 if (jiffies - port->link_detection_jiffies > |
|
699 HZ * EC_PORT_WAIT_MS / 1000) { |
|
700 port->state = EC_SLAVE_PORT_UP; |
|
701 ec_fsm_master_action_open_port(fsm); |
|
702 return; |
|
703 } |
|
704 } |
|
705 else { // link down |
|
706 port->state = EC_SLAVE_PORT_DOWN; |
|
707 } |
|
708 break; |
|
709 default: // EC_SLAVE_PORT_UP |
|
710 if (!port->link.link_up) { |
|
711 port->state = EC_SLAVE_PORT_DOWN; |
|
712 } |
|
713 break; |
|
714 } |
|
715 } |
|
716 |
|
717 // process next slave |
|
718 ec_fsm_master_action_next_slave_state(fsm); |
|
719 } |
|
720 |
|
721 /*****************************************************************************/ |
|
722 |
|
723 /** Master state: OPEN_PORT. |
|
724 * |
|
725 * Opens slave ports. |
|
726 */ |
|
727 void ec_fsm_master_state_open_port( |
|
728 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
729 ) |
|
730 { |
|
731 ec_slave_t *slave = fsm->slave; |
|
732 ec_datagram_t *datagram = fsm->datagram; |
|
733 |
|
734 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { |
|
735 return; |
|
736 } |
|
737 |
|
738 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
739 EC_SLAVE_ERR(slave, "Failed to receive port open datagram: "); |
|
740 ec_datagram_print_state(datagram); |
|
741 ec_fsm_master_restart(fsm); |
|
742 return; |
|
743 } |
|
744 |
|
745 // did the slave not respond to its station address? |
|
746 if (datagram->working_counter != 1) { |
|
747 EC_SLAVE_ERR(slave, "Did not respond to port open command!\n"); |
|
748 return; |
|
749 } |
|
750 |
|
751 // process next slave |
|
752 ec_fsm_master_action_next_slave_state(fsm); |
|
753 } |
|
754 |
|
755 #endif |
604 |
756 |
605 /*****************************************************************************/ |
757 /*****************************************************************************/ |
606 |
758 |
607 /** Master action: Configure. |
759 /** Master action: Configure. |
608 */ |
760 */ |
652 fsm->state(fsm); // execute immediately |
804 fsm->state(fsm); // execute immediately |
653 fsm->datagram->device_index = fsm->slave->device_index; |
805 fsm->datagram->device_index = fsm->slave->device_index; |
654 return; |
806 return; |
655 } |
807 } |
656 |
808 |
|
809 #ifdef EC_LOOP_CONTROL |
|
810 // read DL status |
|
811 ec_fsm_master_action_read_dl_status(fsm); |
|
812 #else |
657 // process next slave |
813 // process next slave |
658 ec_fsm_master_action_next_slave_state(fsm); |
814 ec_fsm_master_action_next_slave_state(fsm); |
659 } |
815 #endif |
660 |
816 } |
661 /*****************************************************************************/ |
817 |
662 |
818 /*****************************************************************************/ |
663 /** Master state: READ STATE. |
819 |
|
820 /** Master state: READ AL STATUS. |
664 * |
821 * |
665 * Fetches the AL state of a slave. |
822 * Fetches the AL state of a slave. |
666 */ |
823 */ |
667 void ec_fsm_master_state_read_state( |
824 void ec_fsm_master_state_read_al_status( |
668 ec_fsm_master_t *fsm /**< Master state machine. */ |
825 ec_fsm_master_t *fsm /**< Master state machine. */ |
669 ) |
826 ) |
670 { |
827 { |
671 ec_slave_t *slave = fsm->slave; |
828 ec_slave_t *slave = fsm->slave; |
672 ec_datagram_t *datagram = fsm->datagram; |
829 ec_datagram_t *datagram = fsm->datagram; |
750 EC_WRITE_U16(fsm->datagram->data, 0x0000); |
912 EC_WRITE_U16(fsm->datagram->data, 0x0000); |
751 fsm->datagram->device_index = fsm->dev_idx; |
913 fsm->datagram->device_index = fsm->dev_idx; |
752 fsm->retries = EC_FSM_RETRIES; |
914 fsm->retries = EC_FSM_RETRIES; |
753 fsm->state = ec_fsm_master_state_clear_addresses; |
915 fsm->state = ec_fsm_master_state_clear_addresses; |
754 } |
916 } |
|
917 |
|
918 /*****************************************************************************/ |
|
919 |
|
920 /** Start measuring DC delays. |
|
921 */ |
|
922 void ec_fsm_master_enter_dc_measure_delays( |
|
923 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
924 ) |
|
925 { |
|
926 EC_MASTER_DBG(fsm->master, 1, "Sending broadcast-write" |
|
927 " to measure transmission delays on %s link.\n", |
|
928 ec_device_names[fsm->dev_idx != 0]); |
|
929 |
|
930 ec_datagram_bwr(fsm->datagram, 0x0900, 1); |
|
931 ec_datagram_zero(fsm->datagram); |
|
932 fsm->datagram->device_index = fsm->dev_idx; |
|
933 fsm->retries = EC_FSM_RETRIES; |
|
934 fsm->state = ec_fsm_master_state_dc_measure_delays; |
|
935 } |
|
936 |
|
937 /*****************************************************************************/ |
|
938 |
|
939 #ifdef EC_LOOP_CONTROL |
|
940 |
|
941 /** Start writing loop control registers. |
|
942 */ |
|
943 void ec_fsm_master_enter_loop_control( |
|
944 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
945 ) |
|
946 { |
|
947 EC_MASTER_DBG(fsm->master, 1, "Broadcast-writing" |
|
948 " loop control registers on %s link.\n", |
|
949 ec_device_names[fsm->dev_idx != 0]); |
|
950 |
|
951 ec_datagram_bwr(fsm->datagram, 0x0101, 1); |
|
952 EC_WRITE_U8(fsm->datagram->data, 0x54); // port 0 auto, 1-3 auto-close |
|
953 fsm->datagram->device_index = fsm->dev_idx; |
|
954 fsm->retries = EC_FSM_RETRIES; |
|
955 fsm->state = ec_fsm_master_state_loop_control; |
|
956 } |
|
957 |
|
958 /*****************************************************************************/ |
|
959 |
|
960 /** Master state: LOOP CONTROL. |
|
961 */ |
|
962 void ec_fsm_master_state_loop_control( |
|
963 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
964 ) |
|
965 { |
|
966 ec_master_t *master = fsm->master; |
|
967 ec_datagram_t *datagram = fsm->datagram; |
|
968 |
|
969 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { |
|
970 return; |
|
971 } |
|
972 |
|
973 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
974 EC_MASTER_ERR(master, "Failed to receive loop control" |
|
975 " datagram on %s link: ", |
|
976 ec_device_names[fsm->dev_idx != 0]); |
|
977 ec_datagram_print_state(datagram); |
|
978 } |
|
979 |
|
980 ec_fsm_master_enter_dc_measure_delays(fsm); |
|
981 } |
|
982 |
|
983 #endif |
755 |
984 |
756 /*****************************************************************************/ |
985 /*****************************************************************************/ |
757 |
986 |
758 /** Master state: CLEAR ADDRESSES. |
987 /** Master state: CLEAR ADDRESSES. |
759 */ |
988 */ |
784 " Cleared %u of %u", |
1013 " Cleared %u of %u", |
785 ec_device_names[fsm->dev_idx != 0], datagram->working_counter, |
1014 ec_device_names[fsm->dev_idx != 0], datagram->working_counter, |
786 fsm->slaves_responding[fsm->dev_idx]); |
1015 fsm->slaves_responding[fsm->dev_idx]); |
787 } |
1016 } |
788 |
1017 |
789 EC_MASTER_DBG(master, 1, "Sending broadcast-write" |
1018 #ifdef EC_LOOP_CONTROL |
790 " to measure transmission delays on %s link.\n", |
1019 ec_fsm_master_enter_loop_control(fsm); |
791 ec_device_names[fsm->dev_idx != 0]); |
1020 #else |
792 |
1021 ec_fsm_master_enter_dc_measure_delays(fsm); |
793 ec_datagram_bwr(datagram, 0x0900, 1); |
1022 #endif |
794 ec_datagram_zero(datagram); |
|
795 fsm->datagram->device_index = fsm->dev_idx; |
|
796 fsm->retries = EC_FSM_RETRIES; |
|
797 fsm->state = ec_fsm_master_state_dc_measure_delays; |
|
798 } |
1023 } |
799 |
1024 |
800 /*****************************************************************************/ |
1025 /*****************************************************************************/ |
801 |
1026 |
802 /** Master state: DC MEASURE DELAYS. |
1027 /** Master state: DC MEASURE DELAYS. |