fp@39: /****************************************************************************** fp@0: * fp@39: * $Id$ fp@0: * fp@197: * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH fp@197: * fp@197: * This file is part of the IgH EtherCAT Master. fp@197: * fp@197: * The IgH EtherCAT Master is free software; you can redistribute it fp@197: * and/or modify it under the terms of the GNU General Public License fp@246: * as published by the Free Software Foundation; either version 2 of the fp@246: * License, or (at your option) any later version. fp@197: * fp@197: * The IgH EtherCAT Master is distributed in the hope that it will be fp@197: * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of fp@197: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the fp@197: * GNU General Public License for more details. fp@197: * fp@197: * You should have received a copy of the GNU General Public License fp@197: * along with the IgH EtherCAT Master; if not, write to the Free Software fp@197: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA fp@197: * fp@246: * The right to use EtherCAT Technology is granted and comes free of fp@246: * charge under condition of compatibility of product made by fp@246: * Licensee. People intending to distribute/sell products based on the fp@246: * code, have to sign an agreement to guarantee that products using fp@246: * software based on IgH EtherCAT master stay compatible with the actual fp@246: * EtherCAT specification (which are released themselves as an open fp@246: * standard) as the (only) precondition to have the right to use EtherCAT fp@246: * Technology, IP and trade marks. fp@246: * fp@39: *****************************************************************************/ fp@0: fp@199: /** fp@199: \file fp@199: EtherCAT stave structure. fp@199: */ fp@199: fp@199: /*****************************************************************************/ fp@199: fp@0: #ifndef _EC_SLAVE_H_ fp@0: #define _EC_SLAVE_H_ fp@0: fp@145: #include fp@182: #include fp@145: fp@325: #include "../include/ecrt.h" fp@325: fp@145: #include "globals.h" fp@293: #include "datagram.h" fp@0: fp@39: /*****************************************************************************/ fp@0: fp@73: /** fp@195: State of an EtherCAT slave. fp@98: */ fp@98: fp@98: typedef enum fp@98: { fp@126: EC_SLAVE_STATE_UNKNOWN = 0x00, fp@195: /**< unknown state */ fp@126: EC_SLAVE_STATE_INIT = 0x01, fp@195: /**< INIT state (no mailbox communication, no IO) */ fp@126: EC_SLAVE_STATE_PREOP = 0x02, fp@195: /**< PREOP state (mailbox communication, no IO) */ fp@126: EC_SLAVE_STATE_SAVEOP = 0x04, fp@195: /**< SAVEOP (mailbox communication and input update) */ fp@126: EC_SLAVE_STATE_OP = 0x08, fp@195: /**< OP (mailbox communication and input/output update) */ fp@402: EC_SLAVE_STATE_ACK_ERR = 0x10 fp@406: /**< Acknowledge/Error bit (no actual state) */ fp@98: } fp@98: ec_slave_state_t; fp@98: fp@98: /*****************************************************************************/ fp@98: fp@98: /** fp@195: Supported mailbox protocols. fp@133: */ fp@133: fp@133: enum fp@133: { fp@145: EC_MBOX_AOE = 0x01, /**< ADS-over-EtherCAT */ fp@145: EC_MBOX_EOE = 0x02, /**< Ethernet-over-EtherCAT */ fp@145: EC_MBOX_COE = 0x04, /**< CANopen-over-EtherCAT */ fp@145: EC_MBOX_FOE = 0x08, /**< File-Access-over-EtherCAT */ fp@145: EC_MBOX_SOE = 0x10, /**< Servo-Profile-over-EtherCAT */ fp@133: EC_MBOX_VOE = 0x20 /**< Vendor specific */ fp@133: }; fp@133: fp@133: /*****************************************************************************/ fp@133: fp@133: /** fp@195: String object (EEPROM). fp@195: */ fp@195: fp@195: typedef struct fp@195: { fp@195: struct list_head list; /**< list item */ fp@195: size_t size; /**< size in bytes */ fp@195: char *data; /**< string data */ fp@118: } fp@325: ec_sii_string_t; fp@126: fp@126: /*****************************************************************************/ fp@126: fp@126: /** fp@195: Sync manager configuration (EEPROM). fp@195: */ fp@195: fp@195: typedef struct fp@195: { fp@195: struct list_head list; /**< list item */ fp@195: unsigned int index; /**< sync manager index */ fp@195: uint16_t physical_start_address; /**< physical start address */ fp@195: uint16_t length; /**< data length in bytes */ fp@195: uint8_t control_register; /**< control register value */ fp@195: uint8_t enable; /**< enable bit */ fp@416: uint16_t est_length; /**< Estimated length. This is no field of the SII, fp@416: but it is used to calculate the length via fp@416: PDO ranges */ fp@126: } fp@325: ec_sii_sync_t; fp@126: fp@126: /*****************************************************************************/ fp@126: fp@126: /** fp@195: PDO type. fp@126: */ fp@126: fp@126: typedef enum fp@126: { fp@195: EC_RX_PDO, /**< Reveive PDO */ fp@195: EC_TX_PDO /**< Transmit PDO */ fp@126: } fp@325: ec_sii_pdo_type_t; fp@126: fp@126: /*****************************************************************************/ fp@126: fp@126: /** fp@195: PDO description (EEPROM). fp@195: */ fp@195: fp@195: typedef struct fp@195: { fp@195: struct list_head list; /**< list item */ fp@325: ec_sii_pdo_type_t type; /**< PDO type */ fp@195: uint16_t index; /**< PDO index */ fp@325: uint8_t sync_index; /**< assigned sync manager */ fp@195: char *name; /**< PDO name */ fp@195: struct list_head entries; /**< entry list */ fp@126: } fp@325: ec_sii_pdo_t; fp@126: fp@126: /*****************************************************************************/ fp@126: fp@126: /** fp@195: PDO entry description (EEPROM). fp@195: */ fp@195: fp@195: typedef struct fp@195: { fp@195: struct list_head list; /**< list item */ fp@195: uint16_t index; /**< PDO index */ fp@195: uint8_t subindex; /**< entry subindex */ fp@195: char *name; /**< entry name */ fp@195: uint8_t bit_length; /**< entry length in bit */ fp@126: } fp@325: ec_sii_pdo_entry_t; fp@118: fp@118: /*****************************************************************************/ fp@118: fp@118: /** fp@325: FMMU configuration. fp@325: */ fp@325: fp@325: typedef struct fp@325: { fp@412: unsigned int index; /**< FMMU index */ fp@325: const ec_domain_t *domain; /**< domain */ fp@325: const ec_sii_sync_t *sync; /**< sync manager */ fp@325: uint32_t logical_start_address; /**< logical start address */ fp@325: } fp@325: ec_fmmu_t; fp@325: fp@325: /*****************************************************************************/ fp@325: fp@325: /** fp@199: EtherCAT slave. fp@73: */ fp@73: fp@73: struct ec_slave fp@73: { fp@195: struct list_head list; /**< list item */ fp@195: struct kobject kobj; /**< kobject */ fp@195: ec_master_t *master; /**< master owning the slave */ fp@195: fp@325: ec_slave_state_t requested_state; /**< requested slave state */ fp@325: ec_slave_state_t current_state; /**< current slave state */ fp@325: unsigned int error_flag; /**< stop processing after an error */ fp@325: unsigned int online; /**< non-zero, if the slave responds. */ fp@325: fp@195: // addresses fp@195: uint16_t ring_position; /**< ring position */ fp@195: uint16_t station_address; /**< configured station address */ fp@195: uint16_t coupler_index; /**< index of the last bus coupler */ fp@195: uint16_t coupler_subindex; /**< index of this slave after last coupler */ fp@195: fp@195: // base data fp@195: uint8_t base_type; /**< slave type */ fp@195: uint8_t base_revision; /**< revision */ fp@195: uint16_t base_build; /**< build number */ fp@195: uint16_t base_fmmu_count; /**< number of supported FMMUs */ fp@195: uint16_t base_sync_count; /**< number of supported sync managers */ fp@195: fp@195: // data link status fp@195: uint8_t dl_link[4]; /**< link detected */ fp@195: uint8_t dl_loop[4]; /**< loop closed */ fp@195: uint8_t dl_signal[4]; /**< detected signal on RX port */ fp@195: fp@325: // EEPROM fp@325: uint8_t *eeprom_data; /**< Complete EEPROM image */ fp@325: uint16_t eeprom_size; /**< size of the EEPROM contents in byte */ fp@325: uint16_t *new_eeprom_data; /**< new EEPROM data to write */ fp@325: uint16_t new_eeprom_size; /**< size of new EEPROM data in words */ fp@325: fp@195: // slave information interface fp@195: uint16_t sii_alias; /**< configured station alias */ fp@195: uint32_t sii_vendor_id; /**< vendor id */ fp@195: uint32_t sii_product_code; /**< vendor's product code */ fp@195: uint32_t sii_revision_number; /**< revision number */ fp@195: uint32_t sii_serial_number; /**< serial number */ fp@195: uint16_t sii_rx_mailbox_offset; /**< mailbox address (master to slave) */ fp@195: uint16_t sii_rx_mailbox_size; /**< mailbox size (master to slave) */ fp@195: uint16_t sii_tx_mailbox_offset; /**< mailbox address (slave to master) */ fp@195: uint16_t sii_tx_mailbox_size; /**< mailbox size (slave to master) */ fp@195: uint16_t sii_mailbox_protocols; /**< supported mailbox protocols */ fp@195: uint8_t sii_physical_layer[4]; /**< port media */ fp@325: struct list_head sii_strings; /**< EEPROM STRING categories */ fp@325: struct list_head sii_syncs; /**< EEPROM SYNC MANAGER categories */ fp@325: struct list_head sii_pdos; /**< EEPROM [RT]XPDO categories */ fp@325: char *sii_group; /**< slave group acc. to EEPROM */ fp@325: char *sii_image; /**< slave image name acc. to EEPROM */ fp@325: char *sii_order; /**< slave order number acc. to EEPROM */ fp@325: char *sii_name; /**< slave name acc. to EEPROM */ fp@499: int16_t sii_current_on_ebus; /**< power consumption */ fp@195: fp@195: ec_fmmu_t fmmus[EC_MAX_FMMUS]; /**< FMMU configurations */ fp@195: uint8_t fmmu_count; /**< number of FMMUs used */ fp@195: fp@419: struct kobject sdo_kobj; /**< kobject for SDOs */ fp@399: struct list_head sdo_dictionary; /**< SDO dictionary list */ fp@329: struct list_head sdo_confs; /**< list of SDO configurations */ fp@419: uint8_t sdo_dictionary_fetched; /**< dictionary has been fetched */ fp@419: unsigned long jiffies_preop; /**< time, the slave went to PREOP */ fp@73: }; fp@73: fp@73: /*****************************************************************************/ fp@73: fp@195: // slave construction/destruction fp@182: int ec_slave_init(ec_slave_t *, ec_master_t *, uint16_t, uint16_t); fp@448: void ec_slave_destroy(ec_slave_t *); fp@73: fp@446: void ec_slave_reset(ec_slave_t *); fp@446: fp@160: int ec_slave_prepare_fmmu(ec_slave_t *, const ec_domain_t *, fp@325: const ec_sii_sync_t *); fp@73: fp@446: void ec_slave_request_state(ec_slave_t *, ec_slave_state_t); fp@446: fp@325: // SII categories fp@238: int ec_slave_fetch_strings(ec_slave_t *, const uint8_t *); fp@325: void ec_slave_fetch_general(ec_slave_t *, const uint8_t *); fp@238: int ec_slave_fetch_sync(ec_slave_t *, const uint8_t *, size_t); fp@325: int ec_slave_fetch_pdo(ec_slave_t *, const uint8_t *, size_t, fp@325: ec_sii_pdo_type_t); fp@238: int ec_slave_locate_string(ec_slave_t *, unsigned int, char **); fp@238: fp@195: // misc. fp@325: uint16_t ec_slave_calc_sync_size(const ec_slave_t *, fp@325: const ec_sii_sync_t *); fp@298: fp@325: int ec_slave_is_coupler(const ec_slave_t *); fp@394: int ec_slave_has_subbus(const ec_slave_t *); fp@0: fp@410: int ec_slave_validate(const ec_slave_t *, uint32_t, uint32_t); fp@410: fp@423: void ec_slave_sdo_dict_info(const ec_slave_t *, fp@423: unsigned int *, unsigned int *); fp@423: fp@39: /*****************************************************************************/ fp@0: fp@0: #endif