fp@39: /****************************************************************************** fp@0: * fp@39: * $Id$ fp@0: * fp@1618: * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH fp@1618: * fp@1618: * This file is part of the IgH EtherCAT Master. fp@1618: * fp@1618: * The IgH EtherCAT Master is free software; you can redistribute it fp@1618: * and/or modify it under the terms of the GNU General Public License fp@1619: * as published by the Free Software Foundation; either version 2 of the fp@1619: * License, or (at your option) any later version. fp@1618: * fp@1618: * The IgH EtherCAT Master is distributed in the hope that it will be fp@1618: * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of fp@1618: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the fp@1618: * GNU General Public License for more details. fp@1618: * fp@1618: * You should have received a copy of the GNU General Public License fp@1618: * along with the IgH EtherCAT Master; if not, write to the Free Software fp@1618: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA fp@1618: * fp@1619: * The right to use EtherCAT Technology is granted and comes free of fp@1619: * charge under condition of compatibility of product made by fp@1619: * Licensee. People intending to distribute/sell products based on the fp@1619: * code, have to sign an agreement to guarantee that products using fp@1619: * software based on IgH EtherCAT master stay compatible with the actual fp@1619: * EtherCAT specification (which are released themselves as an open fp@1619: * standard) as the (only) precondition to have the right to use EtherCAT fp@1619: * Technology, IP and trade marks. fp@1619: * fp@39: *****************************************************************************/ fp@0: fp@1618: /** fp@1618: \file fp@1618: EtherCAT stave structure. fp@1618: */ fp@1618: fp@1618: /*****************************************************************************/ fp@1618: fp@0: #ifndef _EC_SLAVE_H_ fp@0: #define _EC_SLAVE_H_ fp@0: fp@145: #include fp@182: #include fp@145: fp@145: #include "globals.h" fp@1624: #include "datagram.h" fp@54: #include "types.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@126: EC_ACK = 0x10 fp@195: /**< Acknoledge bit (no 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: FMMU configuration. fp@195: */ fp@195: fp@195: typedef struct fp@195: { fp@195: const ec_domain_t *domain; /**< domain */ fp@195: const ec_sync_t *sync; /**< sync manager */ fp@195: uint32_t logical_start_address; /**< logical start address */ fp@73: } fp@73: ec_fmmu_t; fp@0: fp@39: /*****************************************************************************/ fp@0: fp@73: /** 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@126: ec_eeprom_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@126: } fp@126: ec_eeprom_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@126: ec_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@195: ec_pdo_type_t type; /**< PDO type */ fp@195: uint16_t index; /**< PDO index */ fp@195: uint8_t sync_manager; /**< assigned sync manager */ fp@195: char *name; /**< PDO name */ fp@195: struct list_head entries; /**< entry list */ fp@126: } fp@126: ec_eeprom_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@126: ec_eeprom_pdo_entry_t; fp@118: fp@118: /*****************************************************************************/ fp@118: fp@118: /** fp@195: CANopen SDO. fp@195: */ fp@195: fp@195: typedef struct fp@195: { fp@195: struct list_head list; /**< list item */ fp@195: uint16_t index; /**< SDO index */ fp@175: //uint16_t type; fp@195: uint8_t object_code; /**< object code */ fp@195: char *name; /**< SDO name */ fp@195: struct list_head entries; /**< entry list */ fp@135: } fp@135: ec_sdo_t; fp@135: fp@135: /*****************************************************************************/ fp@135: fp@135: /** fp@195: CANopen SDO entry. fp@195: */ fp@195: fp@195: typedef struct fp@195: { fp@195: struct list_head list; /**< list item */ fp@195: uint8_t subindex; /**< entry subindex */ fp@195: uint16_t data_type; /**< entry data type */ fp@195: uint16_t bit_length; /**< entry length in bit */ fp@195: char *name; /**< entry name */ fp@139: } fp@139: ec_sdo_entry_t; fp@139: fp@139: /*****************************************************************************/ fp@139: fp@139: /** fp@1621: Variable-sized field information. fp@1621: */ fp@1621: fp@1621: typedef struct fp@1621: { fp@1621: struct list_head list; /**< list item */ fp@1621: const ec_field_t *field; /**< data field */ fp@1621: size_t size; /**< field size */ fp@1621: } fp@1621: ec_varsize_t; fp@1621: fp@1621: /*****************************************************************************/ fp@1621: fp@1621: /** fp@1618: 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@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@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@195: fp@195: const ec_slave_type_t *type; /**< pointer to slave type object */ fp@195: fp@195: uint8_t registered; /**< true, if slave has been registered */ 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@1621: uint8_t *eeprom_data; /**< Complete EEPROM image */ fp@1621: uint16_t eeprom_size; /**< size of the EEPROM contents in byte */ fp@195: struct list_head eeprom_strings; /**< EEPROM STRING categories */ fp@195: struct list_head eeprom_syncs; /**< EEPROM SYNC MANAGER categories */ fp@195: struct list_head eeprom_pdos; /**< EEPROM [RT]XPDO categories */ fp@1619: char *eeprom_group; /**< slave group acc. to EEPROM */ fp@1619: char *eeprom_image; /**< slave image name acc. to EEPROM */ fp@1619: char *eeprom_order; /**< slave order number acc. to EEPROM */ fp@195: char *eeprom_name; /**< slave name acc. to EEPROM */ fp@195: fp@1621: uint16_t *new_eeprom_data; /**< new EEPROM data to write */ fp@1621: size_t new_eeprom_size; /**< size of new EEPROM data in words */ fp@1621: fp@195: struct list_head sdo_dictionary; /**< SDO directory list */ fp@195: fp@1619: ec_slave_state_t requested_state; /**< requested slave state */ fp@1619: ec_slave_state_t current_state; /**< current slave state */ fp@1624: unsigned int error_flag; /**< stop processing after an error */ fp@1619: unsigned int online; /**< non-zero, if the slave responds. */ fp@1621: fp@1621: struct list_head varsize_fields; /**< size information for variable-sized fp@1621: data fields. */ 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@182: void ec_slave_clear(struct kobject *); fp@73: fp@195: // slave control fp@73: int ec_slave_fetch(ec_slave_t *); fp@136: int ec_slave_sii_read16(ec_slave_t *, uint16_t, uint16_t *); fp@136: int ec_slave_sii_read32(ec_slave_t *, uint16_t, uint32_t *); fp@136: int ec_slave_sii_write16(ec_slave_t *, uint16_t, uint16_t); fp@73: int ec_slave_state_change(ec_slave_t *, uint8_t); fp@160: int ec_slave_prepare_fmmu(ec_slave_t *, const ec_domain_t *, fp@160: const ec_sync_t *); fp@73: fp@195: // CoE fp@133: int ec_slave_fetch_sdo_list(ec_slave_t *); fp@133: fp@1619: // state machine fp@1619: int ec_slave_fetch_strings(ec_slave_t *, const uint8_t *); fp@1619: int ec_slave_fetch_general(ec_slave_t *, const uint8_t *); fp@1619: int ec_slave_fetch_sync(ec_slave_t *, const uint8_t *, size_t); fp@1619: int ec_slave_fetch_pdo(ec_slave_t *, const uint8_t *, size_t, ec_pdo_type_t); fp@1619: int ec_slave_locate_string(ec_slave_t *, unsigned int, char **); fp@1619: fp@195: // misc. fp@1621: size_t ec_slave_calc_sync_size(const ec_slave_t *, const ec_sync_t *); fp@1624: uint16_t ec_slave_calc_eeprom_sync_size(const ec_slave_t *, fp@1624: const ec_eeprom_sync_t *); fp@1624: fp@140: void ec_slave_print(const ec_slave_t *, unsigned int); fp@74: int ec_slave_check_crc(ec_slave_t *); fp@0: fp@39: /*****************************************************************************/ fp@0: fp@0: #endif