master/fsm_master.c
changeset 2600 1a969896d52e
parent 2589 2b9c78543663
child 2620 0e4d098db815
equal deleted inserted replaced
2598:19ff84bbbcb3 2600:1a969896d52e
    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 *);
   413             ec_datagram_fprd(fsm->datagram, fsm->slave->station_address,
   420             ec_datagram_fprd(fsm->datagram, fsm->slave->station_address,
   414                     0x0130, 2);
   421                     0x0130, 2);
   415             ec_datagram_zero(datagram);
   422             ec_datagram_zero(datagram);
   416             fsm->datagram->device_index = fsm->slave->device_index;
   423             fsm->datagram->device_index = fsm->slave->device_index;
   417             fsm->retries = EC_FSM_RETRIES;
   424             fsm->retries = EC_FSM_RETRIES;
   418             fsm->state = ec_fsm_master_state_read_state;
   425             fsm->state = ec_fsm_master_state_read_al_status;
   419         }
   426         }
   420     } else {
   427     } else {
   421         ec_fsm_master_restart(fsm);
   428         ec_fsm_master_restart(fsm);
   422     }
   429     }
   423 }
   430 }
   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;
   692         ec_fsm_master_restart(fsm);
   849         ec_fsm_master_restart(fsm);
   693         return;
   850         return;
   694     }
   851     }
   695 
   852 
   696     // A single slave responded
   853     // A single slave responded
   697     ec_slave_set_state(slave, EC_READ_U8(datagram->data));
   854     ec_slave_set_al_status(slave, EC_READ_U8(datagram->data));
   698 
   855 
   699     if (!slave->error_flag) {
   856     if (!slave->error_flag) {
   700         // Check, if new slave state has to be acknowledged
   857         // Check, if new slave state has to be acknowledged
   701         if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
   858         if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
   702             fsm->idle = 0;
   859             fsm->idle = 0;
   709         // No acknowlegde necessary; check for configuration
   866         // No acknowlegde necessary; check for configuration
   710         ec_fsm_master_action_configure(fsm);
   867         ec_fsm_master_action_configure(fsm);
   711         return;
   868         return;
   712     }
   869     }
   713 
   870 
   714     // slave has error flag set; process next one
   871 #ifdef EC_LOOP_CONTROL
       
   872     // read DL status
       
   873     ec_fsm_master_action_read_dl_status(fsm);
       
   874 #else
       
   875     // process next slave
   715     ec_fsm_master_action_next_slave_state(fsm);
   876     ec_fsm_master_action_next_slave_state(fsm);
       
   877 #endif
   716 }
   878 }
   717 
   879 
   718 /*****************************************************************************/
   880 /*****************************************************************************/
   719 
   881 
   720 /** Master state: ACKNOWLEDGE.
   882 /** Master state: ACKNOWLEDGE.
   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.
   945     if (!ec_fsm_slave_config_success(&fsm->fsm_slave_config)) {
  1170     if (!ec_fsm_slave_config_success(&fsm->fsm_slave_config)) {
   946         // TODO: mark slave_config as failed.
  1171         // TODO: mark slave_config as failed.
   947     }
  1172     }
   948 
  1173 
   949     fsm->idle = 1;
  1174     fsm->idle = 1;
       
  1175 
       
  1176 #ifdef EC_LOOP_CONTROL
       
  1177     // read DL status
       
  1178     ec_fsm_master_action_read_dl_status(fsm);
       
  1179 #else
       
  1180     // process next slave
   950     ec_fsm_master_action_next_slave_state(fsm);
  1181     ec_fsm_master_action_next_slave_state(fsm);
       
  1182 #endif
   951 }
  1183 }
   952 
  1184 
   953 /*****************************************************************************/
  1185 /*****************************************************************************/
   954 
  1186 
   955 /** Start writing DC system times.
  1187 /** Start writing DC system times.