From 205891e4120dfbf3b3762b21e0828c15e3750131 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 7 Apr 2009 09:00:20 +0000 Subject: [PATCH] Reading more base information (incl. whether DC supported). --- master/cdev.c | 7 +++++++ master/fsm_slave_scan.c | 24 ++++++++++++++++++++-- master/globals.h | 17 ++++++++++++++++ master/ioctl.h | 4 ++++ master/slave.c | 7 +++++++ master/slave.h | 7 ++++++- tool/CommandSlaves.cpp | 45 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 108 insertions(+), 3 deletions(-) diff --git a/master/cdev.c b/master/cdev.c index 47d16605..6e92f26b 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -209,6 +209,7 @@ int ec_cdev_ioctl_slave( { ec_ioctl_slave_t data; const ec_slave_t *slave; + int i; if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { return -EFAULT; @@ -242,6 +243,12 @@ int ec_cdev_ioctl_slave( data.coe_details = slave->sii.coe_details; data.general_flags = slave->sii.general_flags; data.current_on_ebus = slave->sii.current_on_ebus; + for (i = 0; i < EC_MAX_PORTS; i++) { + data.ports[i] = slave->base_ports[i]; + } + data.fmmu_bit = slave->base_fmmu_bit_operation; + data.dc_supported = slave->base_dc_supported; + data.dc_range = slave->base_dc_range; data.al_state = slave->current_state; data.error_flag = slave->error_flag; diff --git a/master/fsm_slave_scan.c b/master/fsm_slave_scan.c index aeb3a5cc..00becefd 100644 --- a/master/fsm_slave_scan.c +++ b/master/fsm_slave_scan.c @@ -247,7 +247,7 @@ void ec_fsm_slave_scan_state_state( } // read base data - ec_datagram_fprd(datagram, fsm->slave->station_address, 0x0000, 6); + ec_datagram_fprd(datagram, fsm->slave->station_address, 0x0000, 12); ec_datagram_zero(datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_slave_scan_state_base; @@ -263,6 +263,8 @@ void ec_fsm_slave_scan_state_base(ec_fsm_slave_scan_t *fsm /**< slave state mach { ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; + u8 octet; + int i; if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) return; @@ -287,8 +289,8 @@ void ec_fsm_slave_scan_state_base(ec_fsm_slave_scan_t *fsm /**< slave state mach slave->base_type = EC_READ_U8 (datagram->data); slave->base_revision = EC_READ_U8 (datagram->data + 1); slave->base_build = EC_READ_U16(datagram->data + 2); - slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4); + slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4); if (slave->base_fmmu_count > EC_MAX_FMMUS) { EC_WARN("Slave %u has more FMMUs (%u) than the master can" " handle (%u).\n", slave->ring_position, @@ -296,6 +298,24 @@ void ec_fsm_slave_scan_state_base(ec_fsm_slave_scan_t *fsm /**< slave state mach slave->base_fmmu_count = EC_MAX_FMMUS; } + slave->base_sync_count = EC_READ_U8 (datagram->data + 5); + if (slave->base_sync_count > EC_MAX_SYNC_MANAGERS) { + EC_WARN("Slave %u provides more sync managers (%u) than the master can" + " handle (%u).\n", slave->ring_position, + slave->base_sync_count, EC_MAX_SYNC_MANAGERS); + slave->base_sync_count = EC_MAX_SYNC_MANAGERS; + } + + octet = EC_READ_U8(datagram->data + 7); + for (i = 0; i < EC_MAX_PORTS; i++) { + slave->base_ports[i] = (octet >> (2 * i)) & 0x03; + } + + octet = EC_READ_U8(datagram->data + 8); + slave->base_fmmu_bit_operation = octet & 0x01; + slave->base_dc_supported = (octet >> 2) & 0x01; + slave->base_dc_range = ((octet >> 3) & 0x01) ? EC_DC_64 : EC_DC_32; + // read data link status ec_datagram_fprd(datagram, slave->station_address, 0x0110, 2); ec_datagram_zero(datagram); diff --git a/master/globals.h b/master/globals.h index d7e700ea..0afe2cfe 100644 --- a/master/globals.h +++ b/master/globals.h @@ -157,6 +157,23 @@ typedef struct { uint8_t enable_not_lrw : 1; /**< Slave does not support LRW. */ } ec_sii_general_flags_t; +/** EtherCAT slave port descriptor. + */ +typedef enum { + EC_PORT_NOT_IMPLEMENTED, + EC_PORT_NOT_CONFIGURED, + EC_PORT_EBUS, + EC_PORT_MII +} ec_slave_port_desc_t; + +/** EtherCAT slave distributed clocks range. + */ +typedef enum { + EC_DC_32, /**< 32 bit. */ + EC_DC_64 /*< 64 bit for system time, system time offset and + port 0 receive time. */ +} ec_slave_dc_range_t; + /*****************************************************************************/ /** Convenience macro for printing EtherCAT-specific information to syslog. diff --git a/master/ioctl.h b/master/ioctl.h index b4fcf7ef..c8001eb6 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -157,6 +157,10 @@ typedef struct { ec_sii_coe_details_t coe_details; ec_sii_general_flags_t general_flags; int16_t current_on_ebus; + ec_slave_port_desc_t ports[EC_MAX_PORTS]; + uint8_t fmmu_bit; + uint8_t dc_supported; + ec_slave_dc_range_t dc_range; uint8_t al_state; uint8_t error_flag; uint8_t sync_count; diff --git a/master/slave.c b/master/slave.c index dcee9847..222b12e1 100644 --- a/master/slave.c +++ b/master/slave.c @@ -86,14 +86,21 @@ void ec_slave_init( slave->base_revision = 0; slave->base_build = 0; slave->base_fmmu_count = 0; + slave->base_sync_count = 0; for (i = 0; i < EC_MAX_PORTS; i++) { + slave->base_ports[i] = EC_PORT_NOT_IMPLEMENTED; + slave->ports[i].dl_link = 0; slave->ports[i].dl_loop = 0; slave->ports[i].dl_signal = 0; slave->sii.physical_layer[i] = 0xFF; } + slave->base_fmmu_bit_operation = 0; + slave->base_dc_supported = 0; + slave->base_dc_range = EC_DC_32; + slave->sii_words = NULL; slave->sii_nwords = 0; diff --git a/master/slave.h b/master/slave.h index dfb24523..ea522718 100644 --- a/master/slave.h +++ b/master/slave.h @@ -127,7 +127,12 @@ struct ec_slave uint8_t base_type; /**< Slave type. */ uint8_t base_revision; /**< Revision. */ uint16_t base_build; /**< Build number. */ - uint16_t base_fmmu_count; /**< Number of supported FMMUs. */ + uint8_t base_fmmu_count; /**< Number of supported FMMUs. */ + uint8_t base_sync_count; /**< Number of supported sync managers. */ + ec_slave_port_desc_t base_ports[EC_MAX_PORTS]; /**< Port descriptors. */ + uint8_t base_fmmu_bit_operation; /**< FMMU bit operation is supported. */ + uint8_t base_dc_supported; /**< Distributed clocks are supported. */ + ec_slave_dc_range_t base_dc_range; /**< DC range. */ // data link status ec_slave_port_t ports[EC_MAX_PORTS]; /**< Port link status. */ diff --git a/tool/CommandSlaves.cpp b/tool/CommandSlaves.cpp index 4a473aee..43ffd9db 100644 --- a/tool/CommandSlaves.cpp +++ b/tool/CommandSlaves.cpp @@ -219,6 +219,7 @@ void CommandSlaves::showSlaves( ) { SlaveList::const_iterator si; + int i; for (si = slaves.begin(); si != slaves.end(); si++) { cout << "=== Slave " << dec << si->position << " ===" << endl; @@ -240,6 +241,50 @@ void CommandSlaves::showSlaves( << " Serial number: 0x" << setw(8) << si->serial_number << endl; + cout << "Ports:" << endl; + for (i = 0; i < EC_MAX_PORTS; i++) { + cout << " " << i << ": "; + switch (si->ports[i]) { + case EC_PORT_NOT_IMPLEMENTED: + cout << "Not implemented."; + break; + case EC_PORT_NOT_CONFIGURED: + cout << "Not configured."; + break; + case EC_PORT_EBUS: + cout << "EBUS."; + break; + case EC_PORT_MII: + cout << "MII."; + break; + default: + cout << "???"; + } + cout << endl; + } + + cout << "DL information:" << endl + << " FMMU bit operation: " + << (si->fmmu_bit ? "yes" : "no") << endl + << " Distributed clocks: "; + if (si->dc_supported) { + cout << "yes ("; + switch (si->dc_range) { + case EC_DC_32: + cout << "32 bit"; + break; + case EC_DC_64: + cout << "64 bit"; + break; + default: + cout << "???"; + } + cout << ")"; + } else { + cout << "no"; + } + cout << endl; + if (si->mailbox_protocols) { list protoList; list::const_iterator protoIter;