Introduced --enable-sii-assign.
--- a/NEWS Wed Feb 06 15:58:00 2013 +0100
+++ b/NEWS Wed Feb 06 17:25:08 2013 +0100
@@ -6,6 +6,11 @@
-------------------------------------------------------------------------------
+Changes since 1.5.1:
+
+* Introduced --enable-sii-assign to switch on assigning the SII to PDI and
+ back to EtherCAT during configuration.
+
Changes in 1.5.1:
* Fixed reset of allow_scanning flag if ecrt_master_activate() was not called.
--- a/TODO Wed Feb 06 15:58:00 2013 +0100
+++ b/TODO Wed Feb 06 17:25:08 2013 +0100
@@ -12,7 +12,6 @@
• Document --with-devices.
• Document RTDM interface.
-• Allow PDI access to EEPROM during INIT->PREOP transition.
Future issues:
--- a/configure.ac Wed Feb 06 15:58:00 2013 +0100
+++ b/configure.ac Wed Feb 06 17:25:08 2013 +0100
@@ -831,6 +831,30 @@
[Max. number of Ethernet devices per master])
#------------------------------------------------------------------------------
+# SII assignment
+#------------------------------------------------------------------------------
+
+AC_ARG_ENABLE([sii-assign],
+ AS_HELP_STRING([--enable-sii-assign],
+ [Enable SII assignment to PDI (default: no)]),
+ [
+ case "${enableval}" in
+ yes) siiassign=1
+ ;;
+ no) siiassign=0
+ ;;
+ *) AC_MSG_ERROR([Invalid value for --enable-sii-assign])
+ ;;
+ esac
+ ],
+ [siiassign=0]
+)
+
+if test "x${siiassign}" = "x1"; then
+ AC_DEFINE([EC_SII_ASSIGN], [1], [Assign SII to PDI])
+fi
+
+#------------------------------------------------------------------------------
AC_CONFIG_FILES([
Doxyfile
--- a/master/fsm_slave_config.c Wed Feb 06 15:58:00 2013 +0100
+++ b/master/fsm_slave_config.c Wed Feb 06 17:25:08 2013 +0100
@@ -67,7 +67,13 @@
void ec_fsm_slave_config_state_clear_sync(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_state_dc_clear_assign(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_state_mbox_sync(ec_fsm_slave_config_t *);
+#ifdef EC_SII_ASSIGN
+void ec_fsm_slave_config_state_assign_pdi(ec_fsm_slave_config_t *);
+#endif
void ec_fsm_slave_config_state_boot_preop(ec_fsm_slave_config_t *);
+#ifdef EC_SII_ASSIGN
+void ec_fsm_slave_config_state_assign_ethercat(ec_fsm_slave_config_t *);
+#endif
void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_state_soe_conf_preop(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_state_watchdog_divider(ec_fsm_slave_config_t *);
@@ -87,6 +93,9 @@
void ec_fsm_slave_config_enter_clear_sync(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_enter_dc_clear_assign(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_enter_mbox_sync(ec_fsm_slave_config_t *);
+#ifdef EC_SII_ASSIGN
+void ec_fsm_slave_config_enter_assign_pdi(ec_fsm_slave_config_t *);
+#endif
void ec_fsm_slave_config_enter_boot_preop(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_enter_sdo_conf(ec_fsm_slave_config_t *);
void ec_fsm_slave_config_enter_soe_conf_preop(ec_fsm_slave_config_t *);
@@ -432,7 +441,11 @@
// no mailbox protocols supported
EC_SLAVE_DBG(slave, 1, "Slave does not support"
" mailbox communication.\n");
+#ifdef EC_SII_ASSIGN
+ ec_fsm_slave_config_enter_assign_pdi(fsm);
+#else
ec_fsm_slave_config_enter_boot_preop(fsm);
+#endif
return;
}
@@ -595,8 +608,70 @@
return;
}
+#ifdef EC_SII_ASSIGN
+ ec_fsm_slave_config_enter_assign_pdi(fsm);
+#else
ec_fsm_slave_config_enter_boot_preop(fsm);
-}
+#endif
+}
+
+/*****************************************************************************/
+
+#ifdef EC_SII_ASSIGN
+
+/** Assign SII to PDI.
+ */
+void ec_fsm_slave_config_enter_assign_pdi(
+ ec_fsm_slave_config_t *fsm /**< slave state machine */
+ )
+{
+ ec_datagram_t *datagram = fsm->datagram;
+ ec_slave_t *slave = fsm->slave;
+
+ if (fsm->slave->requested_state != EC_SLAVE_STATE_BOOT) {
+ EC_SLAVE_DBG(slave, 1, "Assigning SII access to PDI.\n");
+
+ ec_datagram_fpwr(datagram, slave->station_address, 0x0500, 0x01);
+ EC_WRITE_U8(datagram->data, 0x01); // PDI
+ fsm->retries = EC_FSM_RETRIES;
+ fsm->state = ec_fsm_slave_config_state_assign_pdi;
+ }
+ else {
+ ec_fsm_slave_config_enter_boot_preop(fsm);
+ }
+}
+
+/*****************************************************************************/
+
+/** Slave configuration state: ASSIGN_PDI.
+ */
+void ec_fsm_slave_config_state_assign_pdi(
+ ec_fsm_slave_config_t *fsm /**< slave state machine */
+ )
+{
+ ec_datagram_t *datagram = fsm->datagram;
+ ec_slave_t *slave = fsm->slave;
+
+ if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
+ return;
+ }
+
+ if (datagram->state != EC_DATAGRAM_RECEIVED) {
+ EC_SLAVE_WARN(slave, "Failed receive SII assignment datagram: ");
+ ec_datagram_print_state(datagram);
+ goto cont_preop;
+ }
+
+ if (datagram->working_counter != 1) {
+ EC_SLAVE_WARN(slave, "Failed to assign SII to PDI: ");
+ ec_datagram_print_wc_error(datagram);
+ }
+
+cont_preop:
+ ec_fsm_slave_config_enter_boot_preop(fsm);
+}
+
+#endif
/*****************************************************************************/
@@ -609,9 +684,11 @@
fsm->state = ec_fsm_slave_config_state_boot_preop;
if (fsm->slave->requested_state != EC_SLAVE_STATE_BOOT) {
- ec_fsm_change_start(fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_PREOP);
+ ec_fsm_change_start(fsm->fsm_change,
+ fsm->slave, EC_SLAVE_STATE_PREOP);
} else { // BOOT
- ec_fsm_change_start(fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_BOOT);
+ ec_fsm_change_start(fsm->fsm_change,
+ fsm->slave, EC_SLAVE_STATE_BOOT);
}
ec_fsm_change_exec(fsm->fsm_change); // execute immediately
@@ -627,7 +704,9 @@
{
ec_slave_t *slave = fsm->slave;
- if (ec_fsm_change_exec(fsm->fsm_change)) return;
+ if (ec_fsm_change_exec(fsm->fsm_change)) {
+ return;
+ }
if (!ec_fsm_change_success(fsm->fsm_change)) {
if (!fsm->fsm_change->spontaneous_change)
@@ -642,6 +721,14 @@
EC_SLAVE_DBG(slave, 1, "Now in %s.\n",
slave->requested_state != EC_SLAVE_STATE_BOOT ? "PREOP" : "BOOT");
+#ifdef EC_SII_ASSIGN
+ EC_SLAVE_DBG(slave, 1, "Assigning SII access back to EtherCAT.\n");
+
+ ec_datagram_fpwr(fsm->datagram, slave->station_address, 0x0500, 0x01);
+ EC_WRITE_U8(fsm->datagram->data, 0x00); // EtherCAT
+ fsm->retries = EC_FSM_RETRIES;
+ fsm->state = ec_fsm_slave_config_state_assign_ethercat;
+#else
if (slave->current_state == slave->requested_state) {
fsm->state = ec_fsm_slave_config_state_end; // successful
EC_SLAVE_DBG(slave, 1, "Finished configuration.\n");
@@ -649,7 +736,48 @@
}
ec_fsm_slave_config_enter_sdo_conf(fsm);
-}
+#endif
+}
+
+/*****************************************************************************/
+
+#ifdef EC_SII_ASSIGN
+
+/** Slave configuration state: ASSIGN_ETHERCAT.
+ */
+void ec_fsm_slave_config_state_assign_ethercat(
+ ec_fsm_slave_config_t *fsm /**< slave state machine */
+ )
+{
+ ec_datagram_t *datagram = fsm->datagram;
+ ec_slave_t *slave = fsm->slave;
+
+ if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
+ return;
+ }
+
+ if (datagram->state != EC_DATAGRAM_RECEIVED) {
+ EC_SLAVE_WARN(slave, "Failed receive SII assignment datagram: ");
+ ec_datagram_print_state(datagram);
+ goto cont_sdo_conf;
+ }
+
+ if (datagram->working_counter != 1) {
+ EC_SLAVE_WARN(slave, "Failed to assign SII back to EtherCAT: ");
+ ec_datagram_print_wc_error(datagram);
+ }
+
+cont_sdo_conf:
+ if (slave->current_state == slave->requested_state) {
+ fsm->state = ec_fsm_slave_config_state_end; // successful
+ EC_SLAVE_DBG(slave, 1, "Finished configuration.\n");
+ return;
+ }
+
+ ec_fsm_slave_config_enter_sdo_conf(fsm);
+}
+
+#endif
/*****************************************************************************/
--- a/master/fsm_slave_scan.c Wed Feb 06 15:58:00 2013 +0100
+++ b/master/fsm_slave_scan.c Wed Feb 06 17:25:08 2013 +0100
@@ -50,6 +50,9 @@
void ec_fsm_slave_scan_state_dc_cap(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_dc_times(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_datalink(ec_fsm_slave_scan_t *);
+#ifdef EC_SII_ASSIGN
+void ec_fsm_slave_scan_state_assign_sii(ec_fsm_slave_scan_t *);
+#endif
void ec_fsm_slave_scan_state_sii_size(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *);
#ifdef EC_REGALIAS
@@ -439,11 +442,52 @@
/*****************************************************************************/
+/** Enter slave scan state SII_SIZE.
+ */
+void ec_fsm_slave_scan_enter_sii_size(
+ ec_fsm_slave_scan_t *fsm /**< slave state machine */
+ )
+{
+ // Start fetching SII size
+
+ fsm->sii_offset = EC_FIRST_SII_CATEGORY_OFFSET; // first category header
+ ec_fsm_sii_read(&fsm->fsm_sii, fsm->slave, fsm->sii_offset,
+ EC_FSM_SII_USE_CONFIGURED_ADDRESS);
+ fsm->state = ec_fsm_slave_scan_state_sii_size;
+ fsm->state(fsm); // execute state immediately
+}
+
+/*****************************************************************************/
+
+#ifdef EC_SII_ASSIGN
+
+/** Enter slave scan state ASSIGN_SII.
+ */
+void ec_fsm_slave_scan_enter_assign_sii(
+ ec_fsm_slave_scan_t *fsm /**< slave state machine */
+ )
+{
+ ec_datagram_t *datagram = fsm->datagram;
+ ec_slave_t *slave = fsm->slave;
+
+ // assign SII to ECAT
+ ec_datagram_fpwr(datagram, slave->station_address, 0x0500, 1);
+ EC_WRITE_U8(datagram->data, 0x00); // EtherCAT
+ fsm->retries = EC_FSM_RETRIES;
+ fsm->state = ec_fsm_slave_scan_state_assign_sii;
+}
+
+#endif
+
+/*****************************************************************************/
+
/**
Slave scan state: DATALINK.
*/
-void ec_fsm_slave_scan_state_datalink(ec_fsm_slave_scan_t *fsm /**< slave state machine */)
+void ec_fsm_slave_scan_state_datalink(
+ ec_fsm_slave_scan_t *fsm /**< slave state machine */
+ )
{
ec_datagram_t *datagram = fsm->datagram;
ec_slave_t *slave = fsm->slave;
@@ -478,14 +522,50 @@
dl_status & (1 << (9 + i * 2)) ? 1 : 0;
}
- // Start fetching SII size
-
- fsm->sii_offset = EC_FIRST_SII_CATEGORY_OFFSET; // first category header
- ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
- EC_FSM_SII_USE_CONFIGURED_ADDRESS);
- fsm->state = ec_fsm_slave_scan_state_sii_size;
- fsm->state(fsm); // execute state immediately
-}
+#ifdef EC_SII_ASSIGN
+ ec_fsm_slave_scan_enter_assign_sii(fsm);
+#else
+ ec_fsm_slave_scan_enter_sii_size(fsm);
+#endif
+}
+
+/*****************************************************************************/
+
+#ifdef EC_SII_ASSIGN
+
+/**
+ Slave scan state: ASSIGN_SII.
+*/
+
+void ec_fsm_slave_scan_state_assign_sii(
+ ec_fsm_slave_scan_t *fsm /**< slave state machine */
+ )
+{
+ ec_datagram_t *datagram = fsm->datagram;
+ ec_slave_t *slave = fsm->slave;
+
+ if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
+ return;
+ }
+
+ if (datagram->state != EC_DATAGRAM_RECEIVED) {
+ EC_SLAVE_WARN(slave, "Failed to receive SII assignment datagram: ");
+ ec_datagram_print_state(datagram);
+ // Try to go on, probably assignment is correct
+ goto continue_with_sii_size;
+ }
+
+ if (datagram->working_counter != 1) {
+ EC_SLAVE_WARN(slave, "Failed to assign SII to EtherCAT: ");
+ ec_datagram_print_wc_error(datagram);
+ // Try to go on, probably assignment is correct
+ }
+
+continue_with_sii_size:
+ ec_fsm_slave_scan_enter_sii_size(fsm);
+}
+
+#endif
/*****************************************************************************/
@@ -493,7 +573,9 @@
Slave scan state: SII SIZE.
*/
-void ec_fsm_slave_scan_state_sii_size(ec_fsm_slave_scan_t *fsm /**< slave state machine */)
+void ec_fsm_slave_scan_state_sii_size(
+ ec_fsm_slave_scan_t *fsm /**< slave state machine */
+ )
{
ec_slave_t *slave = fsm->slave;
uint16_t cat_type, cat_size;