master/fsm_slave_config.c
changeset 2589 2b9c78543663
parent 2414 f35c7c8e6591
child 2608 ec0b5d9a2ff1
child 2633 3b61ec73acd2
equal deleted inserted replaced
2415:af21f0bdc7c9 2589:2b9c78543663
    47 /** Maximum clock difference (in ns) before going to SAFEOP.
    47 /** Maximum clock difference (in ns) before going to SAFEOP.
    48  *
    48  *
    49  * Wait for DC time difference to drop under this absolute value before
    49  * Wait for DC time difference to drop under this absolute value before
    50  * requesting SAFEOP.
    50  * requesting SAFEOP.
    51  */
    51  */
    52 #define EC_DC_MAX_SYNC_DIFF_NS 5000
    52 #define EC_DC_MAX_SYNC_DIFF_NS 10000
    53 
    53 
    54 /** Maximum time (in ms) to wait for clock discipline.
    54 /** Maximum time (in ms) to wait for clock discipline.
    55  */
    55  */
    56 #define EC_DC_SYNC_WAIT_MS 5000
    56 #define EC_DC_SYNC_WAIT_MS 5000
    57 
    57 
    65 void ec_fsm_slave_config_state_init(ec_fsm_slave_config_t *);
    65 void ec_fsm_slave_config_state_init(ec_fsm_slave_config_t *);
    66 void ec_fsm_slave_config_state_clear_fmmus(ec_fsm_slave_config_t *);
    66 void ec_fsm_slave_config_state_clear_fmmus(ec_fsm_slave_config_t *);
    67 void ec_fsm_slave_config_state_clear_sync(ec_fsm_slave_config_t *);
    67 void ec_fsm_slave_config_state_clear_sync(ec_fsm_slave_config_t *);
    68 void ec_fsm_slave_config_state_dc_clear_assign(ec_fsm_slave_config_t *);
    68 void ec_fsm_slave_config_state_dc_clear_assign(ec_fsm_slave_config_t *);
    69 void ec_fsm_slave_config_state_mbox_sync(ec_fsm_slave_config_t *);
    69 void ec_fsm_slave_config_state_mbox_sync(ec_fsm_slave_config_t *);
       
    70 #ifdef EC_SII_ASSIGN
       
    71 void ec_fsm_slave_config_state_assign_pdi(ec_fsm_slave_config_t *);
       
    72 #endif
    70 void ec_fsm_slave_config_state_boot_preop(ec_fsm_slave_config_t *);
    73 void ec_fsm_slave_config_state_boot_preop(ec_fsm_slave_config_t *);
       
    74 #ifdef EC_SII_ASSIGN
       
    75 void ec_fsm_slave_config_state_assign_ethercat(ec_fsm_slave_config_t *);
       
    76 #endif
    71 void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *);
    77 void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *);
    72 void ec_fsm_slave_config_state_soe_conf_preop(ec_fsm_slave_config_t *);
    78 void ec_fsm_slave_config_state_soe_conf_preop(ec_fsm_slave_config_t *);
    73 void ec_fsm_slave_config_state_watchdog_divider(ec_fsm_slave_config_t *);
    79 void ec_fsm_slave_config_state_watchdog_divider(ec_fsm_slave_config_t *);
    74 void ec_fsm_slave_config_state_watchdog(ec_fsm_slave_config_t *);
    80 void ec_fsm_slave_config_state_watchdog(ec_fsm_slave_config_t *);
    75 void ec_fsm_slave_config_state_pdo_sync(ec_fsm_slave_config_t *);
    81 void ec_fsm_slave_config_state_pdo_sync(ec_fsm_slave_config_t *);
    85 
    91 
    86 void ec_fsm_slave_config_enter_init(ec_fsm_slave_config_t *);
    92 void ec_fsm_slave_config_enter_init(ec_fsm_slave_config_t *);
    87 void ec_fsm_slave_config_enter_clear_sync(ec_fsm_slave_config_t *);
    93 void ec_fsm_slave_config_enter_clear_sync(ec_fsm_slave_config_t *);
    88 void ec_fsm_slave_config_enter_dc_clear_assign(ec_fsm_slave_config_t *);
    94 void ec_fsm_slave_config_enter_dc_clear_assign(ec_fsm_slave_config_t *);
    89 void ec_fsm_slave_config_enter_mbox_sync(ec_fsm_slave_config_t *);
    95 void ec_fsm_slave_config_enter_mbox_sync(ec_fsm_slave_config_t *);
       
    96 #ifdef EC_SII_ASSIGN
       
    97 void ec_fsm_slave_config_enter_assign_pdi(ec_fsm_slave_config_t *);
       
    98 #endif
    90 void ec_fsm_slave_config_enter_boot_preop(ec_fsm_slave_config_t *);
    99 void ec_fsm_slave_config_enter_boot_preop(ec_fsm_slave_config_t *);
    91 void ec_fsm_slave_config_enter_sdo_conf(ec_fsm_slave_config_t *);
   100 void ec_fsm_slave_config_enter_sdo_conf(ec_fsm_slave_config_t *);
    92 void ec_fsm_slave_config_enter_soe_conf_preop(ec_fsm_slave_config_t *);
   101 void ec_fsm_slave_config_enter_soe_conf_preop(ec_fsm_slave_config_t *);
    93 void ec_fsm_slave_config_enter_pdo_conf(ec_fsm_slave_config_t *);
   102 void ec_fsm_slave_config_enter_pdo_conf(ec_fsm_slave_config_t *);
    94 void ec_fsm_slave_config_enter_watchdog_divider(ec_fsm_slave_config_t *);
   103 void ec_fsm_slave_config_enter_watchdog_divider(ec_fsm_slave_config_t *);
   112 void ec_fsm_slave_config_init(
   121 void ec_fsm_slave_config_init(
   113         ec_fsm_slave_config_t *fsm, /**< slave state machine */
   122         ec_fsm_slave_config_t *fsm, /**< slave state machine */
   114         ec_datagram_t *datagram, /**< datagram structure to use */
   123         ec_datagram_t *datagram, /**< datagram structure to use */
   115         ec_fsm_change_t *fsm_change, /**< State change state machine to use. */
   124         ec_fsm_change_t *fsm_change, /**< State change state machine to use. */
   116         ec_fsm_coe_t *fsm_coe, /**< CoE state machine to use. */
   125         ec_fsm_coe_t *fsm_coe, /**< CoE state machine to use. */
       
   126         ec_fsm_soe_t *fsm_soe, /**< SoE state machine to use. */
   117         ec_fsm_pdo_t *fsm_pdo /**< PDO configuration state machine to use. */
   127         ec_fsm_pdo_t *fsm_pdo /**< PDO configuration state machine to use. */
   118         )
   128         )
   119 {
   129 {
   120     ec_sdo_request_init(&fsm->request_copy);
   130     ec_sdo_request_init(&fsm->request_copy);
   121     ec_soe_request_init(&fsm->soe_request_copy);
   131     ec_soe_request_init(&fsm->soe_request_copy);
   122 
   132 
   123     fsm->datagram = datagram;
   133     fsm->datagram = datagram;
   124     fsm->fsm_change = fsm_change;
   134     fsm->fsm_change = fsm_change;
   125     fsm->fsm_coe = fsm_coe;
   135     fsm->fsm_coe = fsm_coe;
       
   136     fsm->fsm_soe = fsm_soe;
   126     fsm->fsm_pdo = fsm_pdo;
   137     fsm->fsm_pdo = fsm_pdo;
   127 }
   138 }
   128 
   139 
   129 /*****************************************************************************/
   140 /*****************************************************************************/
   130 
   141 
   175  */
   186  */
   176 int ec_fsm_slave_config_exec(
   187 int ec_fsm_slave_config_exec(
   177         ec_fsm_slave_config_t *fsm /**< slave state machine */
   188         ec_fsm_slave_config_t *fsm /**< slave state machine */
   178         )
   189         )
   179 {
   190 {
   180     if (fsm->datagram->state == EC_DATAGRAM_QUEUED
   191     if (fsm->datagram->state == EC_DATAGRAM_SENT
   181         || fsm->datagram->state == EC_DATAGRAM_SENT) {
   192         || fsm->datagram->state == EC_DATAGRAM_QUEUED) {
   182         // datagram was not sent or received yet.
   193         // datagram was not sent or received yet.
   183         return ec_fsm_slave_config_running(fsm);
   194         return ec_fsm_slave_config_running(fsm);
   184     }
   195     }
   185 
   196 
   186     fsm->state(fsm);
   197     fsm->state(fsm);
   428 
   439 
   429     if (!slave->sii.mailbox_protocols) {
   440     if (!slave->sii.mailbox_protocols) {
   430         // no mailbox protocols supported
   441         // no mailbox protocols supported
   431         EC_SLAVE_DBG(slave, 1, "Slave does not support"
   442         EC_SLAVE_DBG(slave, 1, "Slave does not support"
   432                 " mailbox communication.\n");
   443                 " mailbox communication.\n");
       
   444 #ifdef EC_SII_ASSIGN
       
   445         ec_fsm_slave_config_enter_assign_pdi(fsm);
       
   446 #else
   433         ec_fsm_slave_config_enter_boot_preop(fsm);
   447         ec_fsm_slave_config_enter_boot_preop(fsm);
       
   448 #endif
   434         return;
   449         return;
   435     }
   450     }
   436 
   451 
   437     EC_SLAVE_DBG(slave, 1, "Configuring mailbox sync managers...\n");
   452     EC_SLAVE_DBG(slave, 1, "Configuring mailbox sync managers...\n");
   438 
   453 
   591         EC_SLAVE_ERR(slave, "Failed to set sync managers: ");
   606         EC_SLAVE_ERR(slave, "Failed to set sync managers: ");
   592         ec_datagram_print_wc_error(datagram);
   607         ec_datagram_print_wc_error(datagram);
   593         return;
   608         return;
   594     }
   609     }
   595 
   610 
       
   611 #ifdef EC_SII_ASSIGN
       
   612     ec_fsm_slave_config_enter_assign_pdi(fsm);
       
   613 #else
   596     ec_fsm_slave_config_enter_boot_preop(fsm);
   614     ec_fsm_slave_config_enter_boot_preop(fsm);
   597 }
   615 #endif
       
   616 }
       
   617 
       
   618 /*****************************************************************************/
       
   619 
       
   620 #ifdef EC_SII_ASSIGN
       
   621 
       
   622 /** Assign SII to PDI.
       
   623  */
       
   624 void ec_fsm_slave_config_enter_assign_pdi(
       
   625         ec_fsm_slave_config_t *fsm /**< slave state machine */
       
   626         )
       
   627 {
       
   628     ec_datagram_t *datagram = fsm->datagram;
       
   629     ec_slave_t *slave = fsm->slave;
       
   630 
       
   631     if (fsm->slave->requested_state != EC_SLAVE_STATE_BOOT) {
       
   632         EC_SLAVE_DBG(slave, 1, "Assigning SII access to PDI.\n");
       
   633 
       
   634         ec_datagram_fpwr(datagram, slave->station_address, 0x0500, 0x01);
       
   635         EC_WRITE_U8(datagram->data, 0x01); // PDI
       
   636         fsm->retries = EC_FSM_RETRIES;
       
   637         fsm->state = ec_fsm_slave_config_state_assign_pdi;
       
   638     }
       
   639     else {
       
   640         ec_fsm_slave_config_enter_boot_preop(fsm);
       
   641     }
       
   642 }
       
   643 
       
   644 /*****************************************************************************/
       
   645 
       
   646 /** Slave configuration state: ASSIGN_PDI.
       
   647  */
       
   648 void ec_fsm_slave_config_state_assign_pdi(
       
   649         ec_fsm_slave_config_t *fsm /**< slave state machine */
       
   650         )
       
   651 {
       
   652     ec_datagram_t *datagram = fsm->datagram;
       
   653     ec_slave_t *slave = fsm->slave;
       
   654 
       
   655     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
       
   656         return;
       
   657     }
       
   658 
       
   659     if (datagram->state != EC_DATAGRAM_RECEIVED) {
       
   660         EC_SLAVE_WARN(slave, "Failed receive SII assignment datagram: ");
       
   661         ec_datagram_print_state(datagram);
       
   662         goto cont_preop;
       
   663     }
       
   664 
       
   665     if (datagram->working_counter != 1) {
       
   666         EC_SLAVE_WARN(slave, "Failed to assign SII to PDI: ");
       
   667         ec_datagram_print_wc_error(datagram);
       
   668     }
       
   669 
       
   670 cont_preop:
       
   671     ec_fsm_slave_config_enter_boot_preop(fsm);
       
   672 }
       
   673 
       
   674 #endif
   598 
   675 
   599 /*****************************************************************************/
   676 /*****************************************************************************/
   600 
   677 
   601 /** Request PREOP state.
   678 /** Request PREOP state.
   602  */
   679  */
   605         )
   682         )
   606 {
   683 {
   607     fsm->state = ec_fsm_slave_config_state_boot_preop;
   684     fsm->state = ec_fsm_slave_config_state_boot_preop;
   608 
   685 
   609     if (fsm->slave->requested_state != EC_SLAVE_STATE_BOOT) {
   686     if (fsm->slave->requested_state != EC_SLAVE_STATE_BOOT) {
   610         ec_fsm_change_start(fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_PREOP);
   687         ec_fsm_change_start(fsm->fsm_change,
       
   688                 fsm->slave, EC_SLAVE_STATE_PREOP);
   611     } else { // BOOT
   689     } else { // BOOT
   612         ec_fsm_change_start(fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_BOOT);
   690         ec_fsm_change_start(fsm->fsm_change,
       
   691                 fsm->slave, EC_SLAVE_STATE_BOOT);
   613     }
   692     }
   614 
   693 
   615     ec_fsm_change_exec(fsm->fsm_change); // execute immediately
   694     ec_fsm_change_exec(fsm->fsm_change); // execute immediately
   616 }
   695 }
   617 
   696 
   623         ec_fsm_slave_config_t *fsm /**< slave state machine */
   702         ec_fsm_slave_config_t *fsm /**< slave state machine */
   624         )
   703         )
   625 {
   704 {
   626     ec_slave_t *slave = fsm->slave;
   705     ec_slave_t *slave = fsm->slave;
   627 
   706 
   628     if (ec_fsm_change_exec(fsm->fsm_change)) return;
   707     if (ec_fsm_change_exec(fsm->fsm_change)) {
       
   708         return;
       
   709     }
   629 
   710 
   630     if (!ec_fsm_change_success(fsm->fsm_change)) {
   711     if (!ec_fsm_change_success(fsm->fsm_change)) {
   631         if (!fsm->fsm_change->spontaneous_change)
   712         if (!fsm->fsm_change->spontaneous_change)
   632             slave->error_flag = 1;
   713             slave->error_flag = 1;
   633         fsm->state = ec_fsm_slave_config_state_error;
   714         fsm->state = ec_fsm_slave_config_state_error;
   638     slave->jiffies_preop = fsm->datagram->jiffies_received;
   719     slave->jiffies_preop = fsm->datagram->jiffies_received;
   639 
   720 
   640     EC_SLAVE_DBG(slave, 1, "Now in %s.\n",
   721     EC_SLAVE_DBG(slave, 1, "Now in %s.\n",
   641             slave->requested_state != EC_SLAVE_STATE_BOOT ? "PREOP" : "BOOT");
   722             slave->requested_state != EC_SLAVE_STATE_BOOT ? "PREOP" : "BOOT");
   642 
   723 
       
   724 #ifdef EC_SII_ASSIGN
       
   725     EC_SLAVE_DBG(slave, 1, "Assigning SII access back to EtherCAT.\n");
       
   726 
       
   727     ec_datagram_fpwr(fsm->datagram, slave->station_address, 0x0500, 0x01);
       
   728     EC_WRITE_U8(fsm->datagram->data, 0x00); // EtherCAT
       
   729     fsm->retries = EC_FSM_RETRIES;
       
   730     fsm->state = ec_fsm_slave_config_state_assign_ethercat;
       
   731 #else
   643     if (slave->current_state == slave->requested_state) {
   732     if (slave->current_state == slave->requested_state) {
   644         fsm->state = ec_fsm_slave_config_state_end; // successful
   733         fsm->state = ec_fsm_slave_config_state_end; // successful
   645         EC_SLAVE_DBG(slave, 1, "Finished configuration.\n");
   734         EC_SLAVE_DBG(slave, 1, "Finished configuration.\n");
   646         return;
   735         return;
   647     }
   736     }
   648 
   737 
   649     ec_fsm_slave_config_enter_sdo_conf(fsm);
   738     ec_fsm_slave_config_enter_sdo_conf(fsm);
   650 }
   739 #endif
       
   740 }
       
   741 
       
   742 /*****************************************************************************/
       
   743 
       
   744 #ifdef EC_SII_ASSIGN
       
   745 
       
   746 /** Slave configuration state: ASSIGN_ETHERCAT.
       
   747  */
       
   748 void ec_fsm_slave_config_state_assign_ethercat(
       
   749         ec_fsm_slave_config_t *fsm /**< slave state machine */
       
   750         )
       
   751 {
       
   752     ec_datagram_t *datagram = fsm->datagram;
       
   753     ec_slave_t *slave = fsm->slave;
       
   754 
       
   755     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
       
   756         return;
       
   757     }
       
   758 
       
   759     if (datagram->state != EC_DATAGRAM_RECEIVED) {
       
   760         EC_SLAVE_WARN(slave, "Failed receive SII assignment datagram: ");
       
   761         ec_datagram_print_state(datagram);
       
   762         goto cont_sdo_conf;
       
   763     }
       
   764 
       
   765     if (datagram->working_counter != 1) {
       
   766         EC_SLAVE_WARN(slave, "Failed to assign SII back to EtherCAT: ");
       
   767         ec_datagram_print_wc_error(datagram);
       
   768     }
       
   769 
       
   770 cont_sdo_conf:
       
   771     if (slave->current_state == slave->requested_state) {
       
   772         fsm->state = ec_fsm_slave_config_state_end; // successful
       
   773         EC_SLAVE_DBG(slave, 1, "Finished configuration.\n");
       
   774         return;
       
   775     }
       
   776 
       
   777     ec_fsm_slave_config_enter_sdo_conf(fsm);
       
   778 }
       
   779 
       
   780 #endif
   651 
   781 
   652 /*****************************************************************************/
   782 /*****************************************************************************/
   653 
   783 
   654 /** Check for SDO configurations to be applied.
   784 /** Check for SDO configurations to be applied.
   655  */
   785  */
   675     fsm->request = list_entry(fsm->slave->config->sdo_configs.next,
   805     fsm->request = list_entry(fsm->slave->config->sdo_configs.next,
   676             ec_sdo_request_t, list);
   806             ec_sdo_request_t, list);
   677     ec_sdo_request_copy(&fsm->request_copy, fsm->request);
   807     ec_sdo_request_copy(&fsm->request_copy, fsm->request);
   678     ecrt_sdo_request_write(&fsm->request_copy);
   808     ecrt_sdo_request_write(&fsm->request_copy);
   679     ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request_copy);
   809     ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request_copy);
   680     ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
   810     ec_fsm_coe_exec(fsm->fsm_coe, fsm->datagram); // execute immediately
   681 }
   811 }
   682 
   812 
   683 /*****************************************************************************/
   813 /*****************************************************************************/
   684 
   814 
   685 /** Slave configuration state: SDO_CONF.
   815 /** Slave configuration state: SDO_CONF.
   686  */
   816  */
   687 void ec_fsm_slave_config_state_sdo_conf(
   817 void ec_fsm_slave_config_state_sdo_conf(
   688         ec_fsm_slave_config_t *fsm /**< slave state machine */
   818         ec_fsm_slave_config_t *fsm /**< slave state machine */
   689         )
   819         )
   690 {
   820 {
   691     if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
   821     if (ec_fsm_coe_exec(fsm->fsm_coe, fsm->datagram)) {
       
   822         return;
       
   823     }
   692 
   824 
   693     if (!ec_fsm_coe_success(fsm->fsm_coe)) {
   825     if (!ec_fsm_coe_success(fsm->fsm_coe)) {
   694         EC_SLAVE_ERR(fsm->slave, "SDO configuration failed.\n");
   826         EC_SLAVE_ERR(fsm->slave, "SDO configuration failed.\n");
   695         fsm->slave->error_flag = 1;
   827         fsm->slave->error_flag = 1;
   696         fsm->state = ec_fsm_slave_config_state_error;
   828         fsm->state = ec_fsm_slave_config_state_error;
   707         fsm->request = list_entry(fsm->request->list.next,
   839         fsm->request = list_entry(fsm->request->list.next,
   708                 ec_sdo_request_t, list);
   840                 ec_sdo_request_t, list);
   709         ec_sdo_request_copy(&fsm->request_copy, fsm->request);
   841         ec_sdo_request_copy(&fsm->request_copy, fsm->request);
   710         ecrt_sdo_request_write(&fsm->request_copy);
   842         ecrt_sdo_request_write(&fsm->request_copy);
   711         ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request_copy);
   843         ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request_copy);
   712         ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
   844         ec_fsm_coe_exec(fsm->fsm_coe, fsm->datagram); // execute immediately
   713         return;
   845         return;
   714     }
   846     }
   715 
   847 
   716     // All SDOs are now configured.
   848     // All SDOs are now configured.
   717     ec_fsm_slave_config_enter_soe_conf_preop(fsm);
   849     ec_fsm_slave_config_enter_soe_conf_preop(fsm);
   724 void ec_fsm_slave_config_enter_soe_conf_preop(
   856 void ec_fsm_slave_config_enter_soe_conf_preop(
   725         ec_fsm_slave_config_t *fsm /**< slave state machine */
   857         ec_fsm_slave_config_t *fsm /**< slave state machine */
   726         )
   858         )
   727 {
   859 {
   728     ec_slave_t *slave = fsm->slave;
   860     ec_slave_t *slave = fsm->slave;
   729     ec_fsm_soe_t *fsm_soe = &slave->fsm.fsm_soe;
       
   730     ec_soe_request_t *req;
   861     ec_soe_request_t *req;
   731 
   862 
   732     if (!slave->config) {
   863     if (!slave->config) {
   733         ec_fsm_slave_config_enter_pdo_sync(fsm);
   864         ec_fsm_slave_config_enter_pdo_sync(fsm);
   734         return;
   865         return;
   739             // start SoE configuration
   870             // start SoE configuration
   740             fsm->state = ec_fsm_slave_config_state_soe_conf_preop;
   871             fsm->state = ec_fsm_slave_config_state_soe_conf_preop;
   741             fsm->soe_request = req;
   872             fsm->soe_request = req;
   742             ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request);
   873             ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request);
   743             ec_soe_request_write(&fsm->soe_request_copy);
   874             ec_soe_request_write(&fsm->soe_request_copy);
   744             ec_fsm_soe_transfer(fsm_soe, fsm->slave, &fsm->soe_request_copy);
   875             ec_fsm_soe_transfer(fsm->fsm_soe, fsm->slave,
   745             ec_fsm_soe_exec(fsm_soe); // execute immediately
   876                     &fsm->soe_request_copy);
   746             ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox);
   877             ec_fsm_soe_exec(fsm->fsm_soe, fsm->datagram);
   747             return;
   878             return;
   748         }
   879         }
   749     }
   880     }
   750 
   881 
   751     // No SoE configuration to be applied in PREOP
   882     // No SoE configuration to be applied in PREOP
   759 void ec_fsm_slave_config_state_soe_conf_preop(
   890 void ec_fsm_slave_config_state_soe_conf_preop(
   760         ec_fsm_slave_config_t *fsm /**< slave state machine */
   891         ec_fsm_slave_config_t *fsm /**< slave state machine */
   761         )
   892         )
   762 {
   893 {
   763     ec_slave_t *slave = fsm->slave;
   894     ec_slave_t *slave = fsm->slave;
   764     ec_fsm_soe_t *fsm_soe = &slave->fsm.fsm_soe;
   895 
   765 
   896     if (ec_fsm_soe_exec(fsm->fsm_soe, fsm->datagram)) {
   766     if (ec_fsm_soe_exec(fsm_soe)) {
   897         return;
   767         ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox);
   898     }
   768         return;
   899 
   769     }
   900     if (!ec_fsm_soe_success(fsm->fsm_soe)) {
   770 
       
   771     if (!ec_fsm_soe_success(fsm_soe)) {
       
   772         EC_SLAVE_ERR(slave, "SoE configuration failed.\n");
   901         EC_SLAVE_ERR(slave, "SoE configuration failed.\n");
   773         fsm->slave->error_flag = 1;
   902         fsm->slave->error_flag = 1;
   774         fsm->state = ec_fsm_slave_config_state_error;
   903         fsm->state = ec_fsm_slave_config_state_error;
   775         return;
   904         return;
   776     }
   905     }
   785         fsm->soe_request = list_entry(fsm->soe_request->list.next,
   914         fsm->soe_request = list_entry(fsm->soe_request->list.next,
   786                 ec_soe_request_t, list);
   915                 ec_soe_request_t, list);
   787         if (fsm->soe_request->al_state == EC_AL_STATE_PREOP) {
   916         if (fsm->soe_request->al_state == EC_AL_STATE_PREOP) {
   788             ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request);
   917             ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request);
   789             ec_soe_request_write(&fsm->soe_request_copy);
   918             ec_soe_request_write(&fsm->soe_request_copy);
   790             ec_fsm_soe_transfer(fsm_soe, fsm->slave, &fsm->soe_request_copy);
   919             ec_fsm_soe_transfer(fsm->fsm_soe, fsm->slave,
   791             ec_fsm_soe_exec(fsm_soe); // execute immediately
   920                     &fsm->soe_request_copy);
   792             ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox);
   921             ec_fsm_soe_exec(fsm->fsm_soe, fsm->datagram);
   793             return;
   922             return;
   794         }
   923         }
   795     }
   924     }
   796 
   925 
   797     // All PREOP IDNs are now configured.
   926     // All PREOP IDNs are now configured.
   820         ec_fsm_slave_config_t *fsm /**< slave state machine */
   949         ec_fsm_slave_config_t *fsm /**< slave state machine */
   821         )
   950         )
   822 {
   951 {
   823     // TODO check for config here
   952     // TODO check for config here
   824 
   953 
   825     if (ec_fsm_pdo_exec(fsm->fsm_pdo))
   954     if (ec_fsm_pdo_exec(fsm->fsm_pdo, fsm->datagram)) {
   826         return;
   955         return;
       
   956     }
   827 
   957 
   828     if (!fsm->slave->config) { // config removed in the meantime
   958     if (!fsm->slave->config) { // config removed in the meantime
   829         ec_fsm_slave_config_reconfigure(fsm);
   959         ec_fsm_slave_config_reconfigure(fsm);
   830         return;
   960         return;
   831     }
   961     }
  1261     }
  1391     }
  1262 
  1392 
  1263     abs_sync_diff = EC_READ_U32(datagram->data) & 0x7fffffff;
  1393     abs_sync_diff = EC_READ_U32(datagram->data) & 0x7fffffff;
  1264     diff_ms = (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
  1394     diff_ms = (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
  1265 
  1395 
  1266 	if (abs_sync_diff > EC_DC_MAX_SYNC_DIFF_NS) {
  1396     if (abs_sync_diff > EC_DC_MAX_SYNC_DIFF_NS) {
  1267 
  1397 
  1268         if (diff_ms >= EC_DC_SYNC_WAIT_MS) {
  1398         if (diff_ms >= EC_DC_SYNC_WAIT_MS) {
  1269             EC_SLAVE_WARN(slave, "Slave did not sync after %lu ms.\n",
  1399             EC_SLAVE_WARN(slave, "Slave did not sync after %lu ms.\n",
  1270                     diff_ms);
  1400                     diff_ms);
  1271         } else {
  1401         } else {
  1298             start = start_time +
  1428             start = start_time +
  1299                 sync0->cycle_time - remainder + sync0->shift_time;
  1429                 sync0->cycle_time - remainder + sync0->shift_time;
  1300 
  1430 
  1301             EC_SLAVE_DBG(slave, 1, "app_start_time=%llu\n",
  1431             EC_SLAVE_DBG(slave, 1, "app_start_time=%llu\n",
  1302                     master->app_start_time);
  1432                     master->app_start_time);
       
  1433             EC_SLAVE_DBG(slave, 1, "      app_time=%llu\n", master->app_time);
  1303             EC_SLAVE_DBG(slave, 1, "    start_time=%llu\n", start_time);
  1434             EC_SLAVE_DBG(slave, 1, "    start_time=%llu\n", start_time);
  1304             EC_SLAVE_DBG(slave, 1, "    cycle_time=%u\n", sync0->cycle_time);
  1435             EC_SLAVE_DBG(slave, 1, "    cycle_time=%u\n", sync0->cycle_time);
  1305             EC_SLAVE_DBG(slave, 1, "    shift_time=%u\n", sync0->shift_time);
  1436             EC_SLAVE_DBG(slave, 1, "    shift_time=%i\n", sync0->shift_time);
  1306             EC_SLAVE_DBG(slave, 1, "     remainder=%u\n", remainder);
  1437             EC_SLAVE_DBG(slave, 1, "     remainder=%u\n", remainder);
  1307             EC_SLAVE_DBG(slave, 1, "         start=%llu\n", start);
  1438             EC_SLAVE_DBG(slave, 1, "         start=%llu\n", start);
  1308             start_time = start;
  1439             start_time = start;
  1309         } else {
  1440         } else {
  1310             EC_SLAVE_WARN(slave, "No application time supplied."
  1441             EC_SLAVE_WARN(slave, "No application time supplied."
  1450 void ec_fsm_slave_config_enter_soe_conf_safeop(
  1581 void ec_fsm_slave_config_enter_soe_conf_safeop(
  1451         ec_fsm_slave_config_t *fsm /**< slave state machine */
  1582         ec_fsm_slave_config_t *fsm /**< slave state machine */
  1452         )
  1583         )
  1453 {
  1584 {
  1454     ec_slave_t *slave = fsm->slave;
  1585     ec_slave_t *slave = fsm->slave;
  1455     ec_fsm_soe_t *fsm_soe = &slave->fsm.fsm_soe;
       
  1456     ec_soe_request_t *req;
  1586     ec_soe_request_t *req;
  1457 
  1587 
  1458     if (!slave->config) {
  1588     if (!slave->config) {
  1459         ec_fsm_slave_config_enter_op(fsm);
  1589         ec_fsm_slave_config_enter_op(fsm);
  1460         return;
  1590         return;
  1465             // start SoE configuration
  1595             // start SoE configuration
  1466             fsm->state = ec_fsm_slave_config_state_soe_conf_safeop;
  1596             fsm->state = ec_fsm_slave_config_state_soe_conf_safeop;
  1467             fsm->soe_request = req;
  1597             fsm->soe_request = req;
  1468             ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request);
  1598             ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request);
  1469             ec_soe_request_write(&fsm->soe_request_copy);
  1599             ec_soe_request_write(&fsm->soe_request_copy);
  1470             ec_fsm_soe_transfer(fsm_soe, fsm->slave, &fsm->soe_request_copy);
  1600             ec_fsm_soe_transfer(fsm->fsm_soe, fsm->slave,
  1471             ec_fsm_soe_exec(fsm_soe); // execute immediately
  1601                     &fsm->soe_request_copy);
  1472             ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox);
  1602             ec_fsm_soe_exec(fsm->fsm_soe, fsm->datagram);
  1473             return;
  1603             return;
  1474         }
  1604         }
  1475     }
  1605     }
  1476 
  1606 
  1477     // No SoE configuration to be applied in SAFEOP
  1607     // No SoE configuration to be applied in SAFEOP
  1485 void ec_fsm_slave_config_state_soe_conf_safeop(
  1615 void ec_fsm_slave_config_state_soe_conf_safeop(
  1486         ec_fsm_slave_config_t *fsm /**< slave state machine */
  1616         ec_fsm_slave_config_t *fsm /**< slave state machine */
  1487         )
  1617         )
  1488 {
  1618 {
  1489     ec_slave_t *slave = fsm->slave;
  1619     ec_slave_t *slave = fsm->slave;
  1490     ec_fsm_soe_t *fsm_soe = &slave->fsm.fsm_soe;
  1620 
  1491 
  1621     if (ec_fsm_soe_exec(fsm->fsm_soe, fsm->datagram)) {
  1492     if (ec_fsm_soe_exec(fsm_soe)) {
  1622         return;
  1493         ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox);
  1623     }
  1494         return;
  1624 
  1495     }
  1625     if (!ec_fsm_soe_success(fsm->fsm_soe)) {
  1496 
       
  1497     if (!ec_fsm_soe_success(fsm_soe)) {
       
  1498         EC_SLAVE_ERR(slave, "SoE configuration failed.\n");
  1626         EC_SLAVE_ERR(slave, "SoE configuration failed.\n");
  1499         fsm->slave->error_flag = 1;
  1627         fsm->slave->error_flag = 1;
  1500         fsm->state = ec_fsm_slave_config_state_error;
  1628         fsm->state = ec_fsm_slave_config_state_error;
  1501         return;
  1629         return;
  1502     }
  1630     }
  1511         fsm->soe_request = list_entry(fsm->soe_request->list.next,
  1639         fsm->soe_request = list_entry(fsm->soe_request->list.next,
  1512                 ec_soe_request_t, list);
  1640                 ec_soe_request_t, list);
  1513         if (fsm->soe_request->al_state == EC_AL_STATE_SAFEOP) {
  1641         if (fsm->soe_request->al_state == EC_AL_STATE_SAFEOP) {
  1514             ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request);
  1642             ec_soe_request_copy(&fsm->soe_request_copy, fsm->soe_request);
  1515             ec_soe_request_write(&fsm->soe_request_copy);
  1643             ec_soe_request_write(&fsm->soe_request_copy);
  1516             ec_fsm_soe_transfer(fsm_soe, fsm->slave, &fsm->soe_request_copy);
  1644             ec_fsm_soe_transfer(fsm->fsm_soe, fsm->slave,
  1517             ec_fsm_soe_exec(fsm_soe); // execute immediately
  1645                     &fsm->soe_request_copy);
  1518             ec_slave_mbox_queue_datagrams(slave, fsm_soe->mbox);
  1646             ec_fsm_soe_exec(fsm->fsm_soe, fsm->datagram);
  1519             return;
  1647             return;
  1520         }
  1648         }
  1521     }
  1649     }
  1522 
  1650 
  1523     // All SAFEOP IDNs are now configured.
  1651     // All SAFEOP IDNs are now configured.