master/slave.h
changeset 2589 2b9c78543663
parent 2045 ff2a13a4603c
child 2597 0e145bb05859
equal deleted inserted replaced
2415:af21f0bdc7c9 2589:2b9c78543663
     1 /******************************************************************************
     1 /******************************************************************************
     2  *
     2  *
     3  *  $Id$
     3  *  $Id$
     4  *
     4  *
     5  *  Copyright (C) 2006-2008  Florian Pose, Ingenieurgemeinschaft IgH
     5  *  Copyright (C) 2006-2012  Florian Pose, Ingenieurgemeinschaft IgH
     6  *
     6  *
     7  *  This file is part of the IgH EtherCAT Master.
     7  *  This file is part of the IgH EtherCAT Master.
     8  *
     8  *
     9  *  The IgH EtherCAT Master is free software; you can redistribute it and/or
     9  *  The IgH EtherCAT Master is free software; you can redistribute it and/or
    10  *  modify it under the terms of the GNU General Public License version 2, as
    10  *  modify it under the terms of the GNU General Public License version 2, as
    44 #include "datagram.h"
    44 #include "datagram.h"
    45 #include "pdo.h"
    45 #include "pdo.h"
    46 #include "sync.h"
    46 #include "sync.h"
    47 #include "sdo.h"
    47 #include "sdo.h"
    48 #include "fsm_slave.h"
    48 #include "fsm_slave.h"
    49 #include "mailbox.h"
       
    50 
    49 
    51 /*****************************************************************************/
    50 /*****************************************************************************/
    52 
    51 
    53 /** Convenience macro for printing slave-specific information to syslog.
    52 /** Convenience macro for printing slave-specific information to syslog.
    54  *
    53  *
    58  *
    57  *
    59  * \param slave EtherCAT slave
    58  * \param slave EtherCAT slave
    60  * \param fmt format string (like in printf())
    59  * \param fmt format string (like in printf())
    61  * \param args arguments (optional)
    60  * \param args arguments (optional)
    62  */
    61  */
    63 #ifdef USE_TRACE_PRINTK
       
    64 #define EC_SLAVE_INFO(slave, fmt, args...) \
       
    65     do { \
       
    66         __trace_printk(_THIS_IP_,"EtherCAT %u-%u: " fmt, slave->master->index, \
       
    67                 slave->ring_position, ##args); \
       
    68         printk(KERN_INFO "EtherCAT %u-%u: " fmt, slave->master->index, \
       
    69                 slave->ring_position, ##args);  \
       
    70     } while (0)
       
    71 #else
       
    72 #define EC_SLAVE_INFO(slave, fmt, args...) \
    62 #define EC_SLAVE_INFO(slave, fmt, args...) \
    73     printk(KERN_INFO "EtherCAT %u-%u: " fmt, slave->master->index, \
    63     printk(KERN_INFO "EtherCAT %u-%u: " fmt, slave->master->index, \
    74             slave->ring_position, ##args)
    64             slave->ring_position, ##args)
    75 #endif
       
    76 
    65 
    77 /** Convenience macro for printing slave-specific errors to syslog.
    66 /** Convenience macro for printing slave-specific errors to syslog.
    78  *
    67  *
    79  * This will print the message in \a fmt with a prefixed
    68  * This will print the message in \a fmt with a prefixed
    80  * "EtherCAT <INDEX>-<POSITION>: ", where INDEX is the master index and
    69  * "EtherCAT <INDEX>-<POSITION>: ", where INDEX is the master index and
    82  *
    71  *
    83  * \param slave EtherCAT slave
    72  * \param slave EtherCAT slave
    84  * \param fmt format string (like in printf())
    73  * \param fmt format string (like in printf())
    85  * \param args arguments (optional)
    74  * \param args arguments (optional)
    86  */
    75  */
    87 #ifdef USE_TRACE_PRINTK
       
    88 #define EC_SLAVE_ERR(slave, fmt, args...) \
       
    89     do { \
       
    90         __trace_printk(_THIS_IP_,"EtherCAT ERROR %u-%u: " fmt, slave->master->index, \
       
    91                 slave->ring_position, ##args); \
       
    92         printk(KERN_ERR "EtherCAT ERROR %u-%u: " fmt, slave->master->index, \
       
    93                 slave->ring_position, ##args);  \
       
    94     } while (0)
       
    95 #else
       
    96 #define EC_SLAVE_ERR(slave, fmt, args...) \
    76 #define EC_SLAVE_ERR(slave, fmt, args...) \
    97     printk(KERN_ERR "EtherCAT ERROR %u-%u: " fmt, slave->master->index, \
    77     printk(KERN_ERR "EtherCAT ERROR %u-%u: " fmt, slave->master->index, \
    98             slave->ring_position, ##args)
    78             slave->ring_position, ##args)
    99 #endif
       
   100 
    79 
   101 /** Convenience macro for printing slave-specific warnings to syslog.
    80 /** Convenience macro for printing slave-specific warnings to syslog.
   102  *
    81  *
   103  * This will print the message in \a fmt with a prefixed
    82  * This will print the message in \a fmt with a prefixed
   104  * "EtherCAT <INDEX>-<POSITION>: ", where INDEX is the master index and
    83  * "EtherCAT <INDEX>-<POSITION>: ", where INDEX is the master index and
   106  *
    85  *
   107  * \param slave EtherCAT slave
    86  * \param slave EtherCAT slave
   108  * \param fmt format string (like in printf())
    87  * \param fmt format string (like in printf())
   109  * \param args arguments (optional)
    88  * \param args arguments (optional)
   110  */
    89  */
   111 #ifdef USE_TRACE_PRINTK
       
   112 #define EC_SLAVE_WARN(slave, fmt, args...) \
       
   113     do { \
       
   114         __trace_printk(_THIS_IP_,"EtherCAT WARNING %u-%u: " fmt, \
       
   115                 slave->master->index, slave->ring_position, ##args); \
       
   116         printk(KERN_WARNING "EtherCAT WARNING %u-%u: " fmt, \
       
   117                 slave->master->index, slave->ring_position, ##args);    \
       
   118     } while (0)
       
   119 #else
       
   120 #define EC_SLAVE_WARN(slave, fmt, args...) \
    90 #define EC_SLAVE_WARN(slave, fmt, args...) \
   121     printk(KERN_WARNING "EtherCAT WARNING %u-%u: " fmt, \
    91     printk(KERN_WARNING "EtherCAT WARNING %u-%u: " fmt, \
   122             slave->master->index, slave->ring_position, ##args)
    92             slave->master->index, slave->ring_position, ##args)
   123 #endif
       
   124 
    93 
   125 /** Convenience macro for printing slave-specific debug messages to syslog.
    94 /** Convenience macro for printing slave-specific debug messages to syslog.
   126  *
    95  *
   127  * This will print the message in \a fmt with a prefixed
    96  * This will print the message in \a fmt with a prefixed
   128  * "EtherCAT <INDEX>-<POSITION>: ", where INDEX is the master index and
    97  * "EtherCAT <INDEX>-<POSITION>: ", where INDEX is the master index and
   129  * POSITION is the slave's ring position.
    98  * POSITION is the slave's ring position.
   130  *
    99  *
   131  * \param slave EtherCAT slave
   100  * \param slave EtherCAT slave
   132  * \param fmt format string (like in printf())
   101  * \param level Debug level. Master's debug level must be >= \a level for
   133  * \param args arguments (optional)
   102  * output.
   134  */
   103  * \param fmt format string (like in printf())
   135 #ifdef USE_TRACE_PRINTK
   104  * \param args arguments (optional)
   136 #define EC_SLAVE_DBG(slave, level, fmt, args...) \
   105  */
   137     do { \
       
   138         __trace_printk(_THIS_IP_,"EtherCAT DEBUG%u %u-%u: " fmt, \
       
   139             level,slave->master->index, slave->ring_position, ##args); \
       
   140         if (slave->master->debug_level >= level) { \
       
   141             printk(KERN_DEBUG "EtherCAT DEBUG %u-%u: " fmt, \
       
   142                     slave->master->index, slave->ring_position, ##args); \
       
   143         } \
       
   144     } while (0)
       
   145 #else
       
   146 #define EC_SLAVE_DBG(slave, level, fmt, args...) \
   106 #define EC_SLAVE_DBG(slave, level, fmt, args...) \
   147     do { \
   107     do { \
   148         if (slave->master->debug_level >= level) { \
   108         if (slave->master->debug_level >= level) { \
   149             printk(KERN_DEBUG "EtherCAT DEBUG %u-%u: " fmt, \
   109             printk(KERN_DEBUG "EtherCAT DEBUG %u-%u: " fmt, \
   150                     slave->master->index, slave->ring_position, ##args); \
   110                     slave->master->index, slave->ring_position, ##args); \
   151         } \
   111         } \
   152     } while (0)
   112     } while (0)
   153 #endif
       
   154 
   113 
   155 /*****************************************************************************/
   114 /*****************************************************************************/
   156 
   115 
   157 /** Slave port.
   116 /** Slave port.
   158  */
   117  */
   169 /*****************************************************************************/
   128 /*****************************************************************************/
   170 
   129 
   171 /** Slave information interface data.
   130 /** Slave information interface data.
   172  */
   131  */
   173 typedef struct {
   132 typedef struct {
   174     // Non-category data 
   133     // Non-category data
   175     uint16_t alias; /**< Configured station alias. */
   134     uint16_t alias; /**< Configured station alias. */
   176     uint32_t vendor_id; /**< Vendor ID. */
   135     uint32_t vendor_id; /**< Vendor ID. */
   177     uint32_t product_code; /**< Vendor-specific product code. */
   136     uint32_t product_code; /**< Vendor-specific product code. */
   178     uint32_t revision_number; /**< Revision number. */
   137     uint32_t revision_number; /**< Revision number. */
   179     uint32_t serial_number; /**< Serial number. */
   138     uint32_t serial_number; /**< Serial number. */
   215 /** EtherCAT slave.
   174 /** EtherCAT slave.
   216  */
   175  */
   217 struct ec_slave
   176 struct ec_slave
   218 {
   177 {
   219     ec_master_t *master; /**< Master owning the slave. */
   178     ec_master_t *master; /**< Master owning the slave. */
       
   179     ec_device_index_t device_index; /**< Index of device the slave responds
       
   180                                       on. */
   220 
   181 
   221     // addresses
   182     // addresses
   222     uint16_t ring_position; /**< Ring position. */
   183     uint16_t ring_position; /**< Ring position. */
   223     uint16_t station_address; /**< Configured station address. */
   184     uint16_t station_address; /**< Configured station address. */
   224     uint16_t effective_alias; /**< Effective alias address. */
   185     uint16_t effective_alias; /**< Effective alias address. */
   263 
   224 
   264     struct list_head sdo_dictionary; /**< SDO dictionary list */
   225     struct list_head sdo_dictionary; /**< SDO dictionary list */
   265     uint8_t sdo_dictionary_fetched; /**< Dictionary has been fetched. */
   226     uint8_t sdo_dictionary_fetched; /**< Dictionary has been fetched. */
   266     unsigned long jiffies_preop; /**< Time, the slave went to PREOP. */
   227     unsigned long jiffies_preop; /**< Time, the slave went to PREOP. */
   267 
   228 
   268     struct list_head slave_sdo_requests; /**< SDO access requests. */
   229     struct list_head sdo_requests; /**< SDO access requests. */
   269     wait_queue_head_t sdo_queue; /**< Wait queue for SDO access requests
   230     struct list_head reg_requests; /**< Register access requests. */
   270                                    from user space. */
       
   271     struct list_head foe_requests; /**< FoE write requests. */
   231     struct list_head foe_requests; /**< FoE write requests. */
   272     wait_queue_head_t foe_queue; /**< Wait queue for FoE requests from user
   232     struct list_head soe_requests; /**< SoE write requests. */
   273                                    space. */
   233 
   274     struct list_head soe_requests; /**< FoE write requests. */
       
   275     wait_queue_head_t soe_queue; /**< Wait queue for SoE requests from user
       
   276                                    space. */
       
   277     ec_fsm_slave_t fsm; /**< Slave state machine. */
   234     ec_fsm_slave_t fsm; /**< Slave state machine. */
   278     ec_datagram_t datagram; /** Datagram used for data transfers */
       
   279     ec_mailbox_t mbox; /**< Mailbox used for data transfers. */
       
   280 };
   235 };
   281 
   236 
   282 /*****************************************************************************/
   237 /*****************************************************************************/
   283 
   238 
   284 // slave construction/destruction
   239 // slave construction/destruction
   285 void ec_slave_init(ec_slave_t *, ec_master_t *, uint16_t, uint16_t);
   240 void ec_slave_init(ec_slave_t *, ec_master_t *, ec_device_index_t,
       
   241         uint16_t, uint16_t);
   286 void ec_slave_clear(ec_slave_t *);
   242 void ec_slave_clear(ec_slave_t *);
   287 
   243 
   288 void ec_slave_clear_sync_managers(ec_slave_t *);
   244 void ec_slave_clear_sync_managers(ec_slave_t *);
   289 
   245 
   290 void ec_slave_request_state(ec_slave_t *, ec_slave_state_t);
   246 void ec_slave_request_state(ec_slave_t *, ec_slave_state_t);
   296 int ec_slave_fetch_sii_syncs(ec_slave_t *, const uint8_t *, size_t);
   252 int ec_slave_fetch_sii_syncs(ec_slave_t *, const uint8_t *, size_t);
   297 int ec_slave_fetch_sii_pdos(ec_slave_t *, const uint8_t *, size_t,
   253 int ec_slave_fetch_sii_pdos(ec_slave_t *, const uint8_t *, size_t,
   298         ec_direction_t);
   254         ec_direction_t);
   299 
   255 
   300 // misc.
   256 // misc.
   301 ec_sync_t *ec_slave_get_sync(ec_slave_t *, uint8_t); 
   257 ec_sync_t *ec_slave_get_sync(ec_slave_t *, uint8_t);
   302 
   258 
   303 void ec_slave_sdo_dict_info(const ec_slave_t *,
   259 void ec_slave_sdo_dict_info(const ec_slave_t *,
   304         unsigned int *, unsigned int *);
   260         unsigned int *, unsigned int *);
   305 ec_sdo_t *ec_slave_get_sdo(ec_slave_t *, uint16_t);
   261 ec_sdo_t *ec_slave_get_sdo(ec_slave_t *, uint16_t);
   306 const ec_sdo_t *ec_slave_get_sdo_const(const ec_slave_t *, uint16_t);
   262 const ec_sdo_t *ec_slave_get_sdo_const(const ec_slave_t *, uint16_t);