# HG changeset patch # User Florian Pose # Date 1207229653 0 # Node ID 9b395c5646ab44fe6df3d7f7aca3813905e138a4 # Parent 40c379697ebfb920fb986cd6671e0c9d0d5fbf90 Changed terms "Pdo mapping" -> "Pdo assignment" and "Pdo configuration" -> "Pdo mapping"; created ecrt_slave_config_pdo_assign_clear() and ecrt_slave_config_pdo_mapping_clear(). diff -r 40c379697ebf -r 9b395c5646ab documentation/graphs/Makefile --- a/documentation/graphs/Makefile Mon Mar 31 09:42:37 2008 +0000 +++ b/documentation/graphs/Makefile Thu Apr 03 13:34:13 2008 +0000 @@ -5,12 +5,12 @@ #----------------------------------------------------------------------------- GRAPHS := \ + fsm_coe_map \ + fsm_master \ + fsm_pdo_assign \ + fsm_pdo_mapping \ fsm_slave_conf \ - fsm_slave_scan \ - fsm_pdo_mapping \ - fsm_pdo_config \ - fsm_master \ - fsm_coe_map + fsm_slave_scan #----------------------------------------------------------------------------- diff -r 40c379697ebf -r 9b395c5646ab documentation/graphs/fsm_pdo_assign.dot --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/documentation/graphs/fsm_pdo_assign.dot Thu Apr 03 13:34:13 2008 +0000 @@ -0,0 +1,19 @@ + +/* $Id$ */ + +digraph pdomapping { + size="7,9" + center=1 + ratio=fill + + next_sync [shape=point,label=""] + + start -> next_sync [label="First SM"] + next_sync -> end [label="No more SMs"] + next_sync -> zero_count [label="Next SM"] + zero_count -> next_sync [label="No Pdos"] + zero_count -> add_pdo [label="Map first Pdo", weight=5] + add_pdo -> add_pdo [label="Map next Pdo"] + add_pdo -> pdo_count [label="No more Pdos", weight=5] + pdo_count -> next_sync +} diff -r 40c379697ebf -r 9b395c5646ab documentation/graphs/fsm_pdo_config.dot --- a/documentation/graphs/fsm_pdo_config.dot Mon Mar 31 09:42:37 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ - -/* $Id$ */ - -digraph pdoconfig { - size="7,9" - center=1 - ratio=fill - - next_pdo [shape=point,label=""] - - start -> next_pdo [label="First Pdo"] - next_pdo -> end [label="No more Pdos"] - next_pdo -> zero_count [label="Next Pdo"] - zero_count -> next_pdo [label="No Entries"] - zero_count -> add_entry [label="Add first entry", weight=5] - add_entry -> add_entry [label="Add next entry"] - add_entry -> entry_count [label="No more Entries", weight=5] - entry_count -> next_pdo -} diff -r 40c379697ebf -r 9b395c5646ab documentation/graphs/fsm_pdo_mapping.dot --- a/documentation/graphs/fsm_pdo_mapping.dot Mon Mar 31 09:42:37 2008 +0000 +++ b/documentation/graphs/fsm_pdo_mapping.dot Thu Apr 03 13:34:13 2008 +0000 @@ -1,19 +1,19 @@ /* $Id$ */ -digraph pdomapping { +digraph pdoconfig { size="7,9" center=1 ratio=fill - next_sync [shape=point,label=""] + next_pdo [shape=point,label=""] - start -> next_sync [label="First SM"] - next_sync -> end [label="No more SMs"] - next_sync -> zero_count [label="Next SM"] - zero_count -> next_sync [label="No Pdos"] - zero_count -> add_pdo [label="Map first Pdo", weight=5] - add_pdo -> add_pdo [label="Map next Pdo"] - add_pdo -> pdo_count [label="No more Pdos", weight=5] - pdo_count -> next_sync + start -> next_pdo [label="First Pdo"] + next_pdo -> end [label="No more Pdos"] + next_pdo -> zero_count [label="Next Pdo"] + zero_count -> next_pdo [label="No Entries"] + zero_count -> add_entry [label="Add first entry", weight=5] + add_entry -> add_entry [label="Add next entry"] + add_entry -> entry_count [label="No more Entries", weight=5] + entry_count -> next_pdo } diff -r 40c379697ebf -r 9b395c5646ab documentation/graphs/fsm_slave_conf.dot --- a/documentation/graphs/fsm_slave_conf.dot Mon Mar 31 09:42:37 2008 +0000 +++ b/documentation/graphs/fsm_slave_conf.dot Thu Apr 03 13:34:13 2008 +0000 @@ -9,7 +9,7 @@ enter_mbox_sync [shape=point,label=""] enter_fmmu [shape=point,label=""] enter_sdo_conf [shape=point,label=""] - enter_mapping [shape=point,label=""] + enter_pdo_assign [shape=point,label=""] enter_pdo_sync [shape=point,label=""] enter_safeop [shape=point,label=""] @@ -32,18 +32,18 @@ preop -> end [label="PREOP req."] preop -> enter_sdo_conf [weight=10] enter_sdo_conf -> enter_safeop [label="No configuration"] - enter_sdo_conf -> enter_mapping [label="No Sdo configs"] + enter_sdo_conf -> enter_pdo_assign [label="No Sdo configs"] enter_sdo_conf -> sdo_conf [label="Sdo configs", weight=10] sdo_conf -> sdo_conf sdo_conf -> error - sdo_conf -> enter_mapping [weight=10] - enter_mapping -> mapping [weight=10] - mapping -> mapping - mapping -> error - mapping -> pdo_conf [weight=10] - pdo_conf -> pdo_conf - pdo_conf -> error - pdo_conf -> enter_pdo_sync [weight=10] + sdo_conf -> enter_pdo_assign [weight=10] + enter_pdo_assign -> pdo_assign [weight=10] + pdo_assign -> pdo_assign + pdo_assign -> error + pdo_assign -> pdo_mapping [weight=10] + pdo_mapping -> pdo_mapping + pdo_mapping -> error + pdo_mapping -> enter_pdo_sync [weight=10] enter_pdo_sync -> pdo_sync [label="Pdo SMs", weight=10] enter_pdo_sync -> enter_fmmu pdo_sync -> pdo_sync diff -r 40c379697ebf -r 9b395c5646ab examples/mini/mini.c --- a/examples/mini/mini.c Mon Mar 31 09:42:37 2008 +0000 +++ b/examples/mini/mini.c Thu Apr 03 13:34:13 2008 +0000 @@ -45,7 +45,7 @@ #define FREQUENCY 100 // Optional features -#define CONFIGURE_MAPPING +#define CONFIGURE_PDOS #define EXTERNAL_MEMORY #define SDO_ACCESS @@ -82,7 +82,7 @@ /*****************************************************************************/ -#ifdef CONFIGURE_MAPPING +#ifdef CONFIGURE_PDOS static ec_pdo_entry_info_t el3162_channel1[] = { {0x3101, 1, 8}, // status {0x3101, 2, 16} // value @@ -93,10 +93,10 @@ {0x3102, 2, 16} // value }; -static ec_pdo_info_t el3162_mapping[] = { +static ec_pdo_info_t el3162_pdos[] = { {EC_DIR_INPUT, 0x1A00, 2, el3162_channel1}, {EC_DIR_INPUT, 0x1A01, 2, el3162_channel2}, - {EC_MAP_END} + {EC_END} }; static ec_pdo_entry_info_t el2004_channels[] = { @@ -106,7 +106,7 @@ {0x3001, 4, 1} // Value 4 }; -static ec_pdo_info_t el2004_mapping[] = { +static ec_pdo_info_t el2004_pdos[] = { {EC_DIR_OUTPUT, 0x1600, 1, &el2004_channels[0]}, {EC_DIR_OUTPUT, 0x1601, 1, &el2004_channels[1]}, {EC_DIR_OUTPUT, 0x1602, 1, &el2004_channels[2]}, @@ -251,7 +251,7 @@ int __init init_mini_module(void) { -#ifdef CONFIGURE_MAPPING +#ifdef CONFIGURE_PDOS ec_slave_config_t *sc; #endif #ifdef EXTERNAL_MEMORY @@ -273,15 +273,15 @@ goto out_release_master; } -#ifdef CONFIGURE_MAPPING - printk(KERN_INFO PFX "Configuring Pdo mapping...\n"); +#ifdef CONFIGURE_PDOS + printk(KERN_INFO PFX "Configuring Pdos...\n"); if (!(sc = ecrt_master_slave_config(master, 0, 1, Beckhoff_EL3162))) { printk(KERN_ERR PFX "Failed to get slave configuration.\n"); goto out_release_master; } - if (ecrt_slave_config_mapping(sc, EC_MAP_END, el3162_mapping)) { - printk(KERN_ERR PFX "Failed to configure Pdo mapping.\n"); + if (ecrt_slave_config_pdos(sc, EC_END, el3162_pdos)) { + printk(KERN_ERR PFX "Failed to configure Pdos.\n"); goto out_release_master; } @@ -290,8 +290,8 @@ goto out_release_master; } - if (ecrt_slave_config_mapping(sc, 4, el2004_mapping)) { - printk(KERN_ERR PFX "Failed to configure Pdo mapping.\n"); + if (ecrt_slave_config_pdos(sc, 4, el2004_pdos)) { + printk(KERN_ERR PFX "Failed to configure Pdos.\n"); goto out_release_master; } #endif diff -r 40c379697ebf -r 9b395c5646ab include/ecrt.h --- a/include/ecrt.h Mon Mar 31 09:42:37 2008 +0000 +++ b/include/ecrt.h Thu Apr 03 13:34:13 2008 +0000 @@ -37,10 +37,10 @@ * * \defgroup RealtimeInterface EtherCAT Realtime Interface * - * EtherCAT interface for realtime modules. This interface is designed for - * realtime modules that want to use EtherCAT. There are functions to request - * a master, to map process data, to communicate with slaves via CoE and to - * configure and activate the bus. + * EtherCAT interface for realtime applications. This interface is designed + * for realtime modules that want to use EtherCAT. There are functions to + * request a master, to map process data, to communicate with slaves via CoE + * and to configure and activate the bus. * * Changes in Version 1.4: * @@ -64,11 +64,12 @@ * is directly usable. If the domain's process data is allocated internally, * the start address can be retrieved with ecrt_domain_data(). * - Replaced ecrt_slave_pdo_mapping/add/clear() with - * ecrt_slave_config_pdo() to add a Pdo to the mapping and - * ecrt_slave_config_pdo_entry() to add a Pdo entry to a Pdo configuration. - * ecrt_slave_config_mapping() is a convenience function for - * both, that uses the new data types ec_pdo_info_t and ec_pdo_entry_info_t. - * Mapped Pdo entries can now immediately be registered. + * ecrt_slave_config_pdo_assign_add() to add a Pdo to a sync manager's Pdo + * assignment and ecrt_slave_config_pdo_mapping_add() to add a Pdo entry to a + * Pdo's mapping. ecrt_slave_config_pdos() is a convenience function + * for both, that uses the new data types ec_pdo_info_t and + * ec_pdo_entry_info_t. Pdo entries, that are mapped with these functions + * can now immediately be registered, even if the bus is offline. * - Renamed ec_bus_status_t, ec_master_status_t to ec_bus_state_t and * ec_master_state_t, respectively. Renamed ecrt_master_get_status() to * ecrt_master_state(), for consistency reasons. @@ -122,11 +123,11 @@ /*****************************************************************************/ -/** End of mapping. - * - * This is used in ecrt_slave_config_mapping(). - */ -#define EC_MAP_END ~0U +/** End of the Pdo list. + * + * This is used in ecrt_slave_config_pdos(). + */ +#define EC_END ~0U /****************************************************************************** * Data types @@ -149,6 +150,9 @@ /** Bus state. * * This is used in ec_master_state_t. + * + * \deprecated + * \todo remove */ typedef enum { EC_BUS_FAILURE = -1, /**< At least one configured slave is offline. */ @@ -214,9 +218,10 @@ /*****************************************************************************/ -/** Pdo entry mapping. - * - * \see ecrt_slave_config_mapping(). +/** Pdo entry information. + * + * This can be used to map multiple Pdo entries into a given Pdo using + * ecrt_slave_config_pdos(). */ typedef struct { uint16_t index; /**< Index of the Pdo entry to add to the Pdo @@ -230,17 +235,17 @@ /** Pdo information. * - * \see ecrt_slave_config_mapping(). + * This can be use to assign multiple Pdos to a sync manager using + * ecrt_slave_config_pdos(). */ typedef struct { ec_direction_t dir; /**< Pdo direction (input/output). */ uint16_t index; /**< Index of the Pdo to map. */ - unsigned int n_entries; /**< Number of Pdo entries for the Pdo - configuration. Zero means, that the default Pdo - configuration shall be used. */ - ec_pdo_entry_info_t *entries; /**< Pdo configuration array. This - array must contain at least \a - n_entries values. */ + unsigned int n_entries; /**< Number of Pdo entries in \a entries to map. + Zero means, that the default mapping shall be + used. */ + ec_pdo_entry_info_t *entries; /**< Array of Pdo entries to map. This must + contain at least \a n_entries values. */ } ec_pdo_info_t; /*****************************************************************************/ @@ -358,27 +363,38 @@ uint32_t product_code /**< Expected product code. */ ); -/** Applies the bus configuration and switches to realtime mode. - * - * Does the complete configuration and activation for all slaves. Sets sync - * managers and FMMUs, and does the appropriate transitions, until the slave - * is operational. +/** Finishes the configuration phase and prepares for realtime mode. + * + * This function has to be called after all Pdo entries are registered. It + * tells the master that the configuration phase is finished and the realtime + * operation will begin. The function allocates internal memory for the + * domains and calculates the logical FMMU addresses for domain members. It + * tells the master state machine that the bus configuration is now to be + * applied. + * + * \attention After this function has been called, the realtime application is + * in charge of cyclically calling ecrt_master_send() and + * ecrt_master_receive() to ensure bus communication. Before calling this + * function, the master thread is responsible for that, so these functions may + * not be called! * * \return 0 in case of success, else < 0 */ -int ecrt_master_activate( - ec_master_t *master /**< EtherCAT master. */ - ); +int ecrt_master_activate( ec_master_t *master /**< EtherCAT master. */); /** Sends all datagrams in the queue. * - * \todo doc + * This has to be called cyclically by the realtime application after + * ecrt_master_activate() has returned. */ void ecrt_master_send( ec_master_t *master /**< EtherCAT master. */ ); /** Fetches received frames from the hardware and processes the datagrams. + * + * This has to be called cyclically by the realtime application after + * ecrt_master_activate() has returned. */ void ecrt_master_receive( ec_master_t *master /**< EtherCAT master. */ @@ -397,48 +413,64 @@ * Slave configuration methods *****************************************************************************/ -/** Add a Pdo to the slave's Pdo mapping for the given direction. - * - * The first call of this function for a given \a dir will clear the default - * mapping. - * - * \see ecrt_slave_config_mapping() +/** Add a Pdo to a sync manager's Pdo assignment. + * + * \see ecrt_slave_config_pdos() * \return zero on success, else non-zero */ -int ecrt_slave_config_pdo( +int ecrt_slave_config_pdo_assign_add( ec_slave_config_t *sc, /**< Slave configuration. */ - ec_direction_t dir, /**< Pdo direction (input/output). */ - uint16_t index /**< Index of the Pdo to map. */ - ); - -/** Add a Pdo entry to the given Pdo's configuration. - * - * The first call of this function for a given \a pdo_index will clear the - * default Pdo configuration. - * - * \see ecrt_slave_config_mapping() + ec_direction_t dir, /**< Sync manager direction (input/output). */ + uint16_t index /**< Index of the Pdo to assign. */ + ); + +/** Clear a sync manager's Pdo assignment. + * + * This can be called before assigning Pdos via + * ecrt_slave_config_pdo_assign_add(), to clear the default assignment. + */ +void ecrt_slave_config_pdo_assign_clear( + ec_slave_config_t *sc, /**< Slave configuration. */ + ec_direction_t dir /**< Sync manager direction (input/output). */ + ); + +/** Add a Pdo entry to the given Pdo's mapping. + * + * \see ecrt_slave_config_pdos() * \return zero on success, else non-zero */ -int ecrt_slave_config_pdo_entry( +int ecrt_slave_config_pdo_mapping_add( ec_slave_config_t *sc, /**< Slave configuration. */ - uint16_t pdo_index, /**< Index of the Pdo to configure. */ + uint16_t pdo_index, /**< Index of the Pdo. */ uint16_t entry_index, /**< Index of the Pdo entry to add to the Pdo's - configuration. */ + mapping. */ uint8_t entry_subindex, /**< Subindex of the Pdo entry to add to the - Pdo's configuration. */ + Pdo's mapping. */ uint8_t entry_bit_length /**< Size of the Pdo entry in bit. */ ); -/** Specify the Pdo mapping and (optionally) the Pdo configuration. - * - * This function is a convenience function for the ecrt_slave_config_pdo() - * and ecrt_slave_config_pdo_entry() functions, that are better suitable - * for automatic code generation. - * - * The following example shows, how to specify a complete Pdo mapping - * including the Pdo configuration. With this information, the master is able - * to reserve the complete process data, even if the slave is not present - * at configuration time: +/** Clear the mapping of a given Pdo. + * + * This can be called before mapping Pdo entries via + * ecrt_slave_config_pdo_mapping_add(), to clear the default mapping. + */ +void ecrt_slave_config_pdo_mapping_clear( + ec_slave_config_t *sc, /**< Slave configuration. */ + uint16_t pdo_index /**< Index of the Pdo. */ + ); + +/** Specify the Pdo assignment and (optionally) the Pdo mappings. + * + * This function is a convenience wrapper for the functions + * ecrt_slave_config_pdo_assign_clear(), ecrt_slave_config_pdo_assign_add(), + * ecrt_slave_config_pdo_mapping_clear() and + * ecrt_slave_config_pdo_mapping_add(), that are better suitable for automatic + * code generation. + * + * The following example shows, how to specify a complete Pdo assignment + * including the Pdo mappings. With this information, the master is able to + * reserve the complete process data, even if the slave is not present at + * configuration time: * * \code * const ec_pdo_entry_info_t el3162_channel1[] = { @@ -451,52 +483,52 @@ * {0x3102, 2, 16} // value * }; * - * const ec_pdo_info_t el3162_mapping[] = { + * const ec_pdo_info_t el3162_pdos[] = { * {EC_DIR_INPUT, 0x1A00, 2, el3162_channel1}, * {EC_DIR_INPUT, 0x1A01, 2, el3162_channel2}, * }; * - * if (ecrt_slave_config_mapping(sc, 2, el3162_mapping)) + * if (ecrt_slave_config_pdos(sc, 2, el3162_pdos)) * return -1; // error * \endcode - * - * The next example shows, how to configure only the Pdo mapping. The entries - * for each mapped Pdo are taken from the default Pdo configuration. Please - * note, that Pdo entry registration will fail, if the Pdo configuration is - * left empty and the slave is offline. + * + * The next example shows, how to configure only the Pdo assignment. The + * entries for each assigned Pdo are taken from the Pdo's default mapping. + * Please note, that Pdo entry registration will fail, if the Pdo + * configuration is left empty and the slave is offline. * * \code - * const ec_pdo_info_t pdo_mapping[] = { + * const ec_pdo_info_t pdos[] = { * {EC_DIR_INPUT, 0x1600}, // Channel 1 * {EC_DIR_INPUT, 0x1601} // Channel 2 * }; * - * if (ecrt_slave_config_mapping(slave_config_ana_in, 2, pdo_mapping)) + * if (ecrt_slave_config_pdos(slave_config_ana_in, 2, pdos)) * return -1; // error * \endcode * * Processing of \a pdo_infos will stop, if * - the number of processed items reaches \a n_infos, or - * - the \a dir member of an ec_pdo_info_t item is EC_MAP_END. In this case, + * - the \a dir member of an ec_pdo_info_t item is EC_END. In this case, * \a n_infos should set to a number greater than the number of list items; - * using EC_MAP_END is recommended. + * using EC_END is recommended. * * \return zero on success, else non-zero */ -int ecrt_slave_config_mapping( +int ecrt_slave_config_pdos( ec_slave_config_t *sc, /**< Slave configuration. */ unsigned int n_infos, /**< Number of Pdo infos in \a pdo_infos. */ - const ec_pdo_info_t pdo_infos[] /**< List with Pdo mapping. */ + const ec_pdo_info_t pdo_infos[] /**< List with Pdos. */ ); /** Registers a Pdo entry for process data exchange in a domain. * - * Searches the current mapping and Pdo configurations for the given Pdo + * Searches the current Pdo assignment and Pdo mappings for the given Pdo * entry. An error is raised, if the given entry is not mapped. Otherwise, the * corresponding sync manager and FMMU configurations are provided for slave - * configuration and the respective sync manager's Pdos are appended to the - * given domain, if not already done. The offset of the requested Pdo entry's - * data inside the domain's process data is returned. + * configuration and the respective sync manager's assigned Pdos are appended + * to the given domain, if not already done. The offset of the requested Pdo + * entry's data inside the domain's process data is returned. * * \retval >=0 Success: Offset of the Pdo entry's process data. * \retval -1 Error: Pdo entry not found. diff -r 40c379697ebf -r 9b395c5646ab master/Kbuild.in --- a/master/Kbuild.in Mon Mar 31 09:42:37 2008 +0000 +++ b/master/Kbuild.in Thu Apr 03 13:34:13 2008 +0000 @@ -42,7 +42,7 @@ fsm_coe.o \ fsm_coe_map.o \ fsm_master.o \ - fsm_pdo_config.o \ + fsm_pdo_assign.o \ fsm_pdo_mapping.o \ fsm_sii.o \ fsm_slave_config.o \ @@ -51,7 +51,7 @@ master.o \ module.o \ pdo.o \ - pdo_mapping.o \ + pdo_list.o \ sdo.o \ sdo_entry.o \ sdo_request.o \ diff -r 40c379697ebf -r 9b395c5646ab master/Makefile.am --- a/master/Makefile.am Mon Mar 31 09:42:37 2008 +0000 +++ b/master/Makefile.am Thu Apr 03 13:34:13 2008 +0000 @@ -44,7 +44,7 @@ fsm_coe.c fsm_coe.h \ fsm_coe_map.c fsm_coe_map.h \ fsm_master.c fsm_master.h \ - fsm_pdo_config.c fsm_pdo_config.h \ + fsm_pdo_assign.c fsm_pdo_assign.h \ fsm_pdo_mapping.c fsm_pdo_mapping.h \ fsm_sii.c fsm_sii.h \ fsm_slave_config.c fsm_slave_config.h \ @@ -54,7 +54,7 @@ master.c master.h \ module.c \ pdo.c pdo.h \ - pdo_mapping.c pdo_mapping.h \ + pdo_list.c pdo_list.h \ sdo.c sdo.h \ sdo_entry.c sdo_entry.h \ sdo_request.c sdo_request.h \ diff -r 40c379697ebf -r 9b395c5646ab master/fmmu_config.c --- a/master/fmmu_config.c Mon Mar 31 09:42:37 2008 +0000 +++ b/master/fmmu_config.c Thu Apr 03 13:34:13 2008 +0000 @@ -62,7 +62,7 @@ fmmu->dir = dir; fmmu->logical_start_address = domain->data_size; - fmmu->data_size = ec_pdo_mapping_total_size(&sc->mapping[dir]); + fmmu->data_size = ec_pdo_list_total_size(&sc->pdos[dir]); ec_domain_add_fmmu_config(domain, fmmu); } diff -r 40c379697ebf -r 9b395c5646ab master/fsm_coe_map.c --- a/master/fsm_coe_map.c Mon Mar 31 09:42:37 2008 +0000 +++ b/master/fsm_coe_map.c Thu Apr 03 13:34:13 2008 +0000 @@ -33,7 +33,7 @@ /** \file - EtherCAT CoE mapping state machines. + EtherCAT Pdo information state machines. */ /*****************************************************************************/ @@ -73,7 +73,7 @@ fsm->fsm_coe = fsm_coe; fsm->state = NULL; ec_sdo_request_init(&fsm->request); - ec_pdo_mapping_init(&fsm->mapping); + ec_pdo_list_init(&fsm->pdos); } /*****************************************************************************/ @@ -85,7 +85,7 @@ void ec_fsm_coe_map_clear(ec_fsm_coe_map_t *fsm /**< finite state machine */) { ec_sdo_request_clear(&fsm->request); - ec_pdo_mapping_clear(&fsm->mapping); + ec_pdo_list_clear(&fsm->pdos); } /*****************************************************************************/ @@ -135,14 +135,14 @@ *****************************************************************************/ /** - * Start reading mapping. + * Start reading Pdo assignment. */ void ec_fsm_coe_map_state_start( ec_fsm_coe_map_t *fsm /**< finite state machine */ ) { - // read mapping for first direction + // read Pdo assignment for first direction fsm->dir = (ec_direction_t) -1; // next is EC_DIR_OUTPUT ec_fsm_coe_map_action_next_dir(fsm); } @@ -150,7 +150,7 @@ /*****************************************************************************/ /** - * Read mapping of next direction manager. + * Read Pdo assignment of next direction manager. */ void ec_fsm_coe_map_action_next_dir( @@ -176,10 +176,10 @@ fsm->sync_sdo_index = 0x1C10 + fsm->sync->index; if (slave->master->debug_level) - EC_DBG("Reading Pdo mapping of sync manager %u of slave %u.\n", + EC_DBG("Reading Pdo assignment of sync manager %u of slave %u.\n", fsm->sync->index, slave->ring_position); - ec_pdo_mapping_clear_pdos(&fsm->mapping); + ec_pdo_list_clear_pdos(&fsm->pdos); ec_sdo_request_address(&fsm->request, fsm->sync_sdo_index, 0); ecrt_sdo_request_read(&fsm->request); @@ -190,7 +190,7 @@ } if (slave->master->debug_level) - EC_DBG("Reading of Pdo mapping finished for slave %u.\n", + EC_DBG("Reading of Pdo assignment finished for slave %u.\n", slave->ring_position); fsm->state = ec_fsm_coe_map_state_end; @@ -199,7 +199,7 @@ /*****************************************************************************/ /** - * Count mapped Pdos. + * Count assigned Pdos. */ void ec_fsm_coe_map_state_pdo_count( @@ -218,7 +218,7 @@ fsm->sync_subindices = EC_READ_U8(fsm->request.data); if (fsm->slave->master->debug_level) - EC_DBG(" %u Pdos mapped.\n", fsm->sync_subindices); + EC_DBG(" %u Pdos assigned.\n", fsm->sync_subindices); // read first Pdo fsm->sync_subindex = 1; @@ -245,15 +245,15 @@ return; } - // finished reading Pdo mapping/configuration + // finished reading Pdo assignment/mapping - if (ec_pdo_mapping_copy(&fsm->sync->mapping, &fsm->mapping)) { - fsm->state = ec_fsm_coe_map_state_error; - return; - } - - fsm->sync->mapping_source = EC_SYNC_MAPPING_COE; - ec_pdo_mapping_clear_pdos(&fsm->mapping); + if (ec_pdo_list_copy(&fsm->sync->pdos, &fsm->pdos)) { + fsm->state = ec_fsm_coe_map_state_error; + return; + } + + fsm->sync->assign_source = EC_ASSIGN_COE; + ec_pdo_list_clear_pdos(&fsm->pdos); // next direction ec_fsm_coe_map_action_next_dir(fsm); @@ -272,7 +272,7 @@ if (ec_fsm_coe_exec(fsm->fsm_coe)) return; if (!ec_fsm_coe_success(fsm->fsm_coe)) { - EC_ERR("Failed to read mapped Pdo index from slave %u.\n", + EC_ERR("Failed to read assigned Pdo index from slave %u.\n", fsm->slave->ring_position); fsm->state = ec_fsm_coe_map_state_error; return; @@ -292,7 +292,7 @@ if (fsm->slave->master->debug_level) EC_DBG(" Pdo 0x%04X.\n", fsm->pdo->index); - list_add_tail(&fsm->pdo->list, &fsm->mapping.pdos); + list_add_tail(&fsm->pdo->list, &fsm->pdos.list); ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0); ecrt_sdo_request_read(&fsm->request); @@ -304,7 +304,7 @@ /*****************************************************************************/ /** - * Read number of Pdo entries. + * Read number of mapped Pdo entries. */ void ec_fsm_coe_map_state_pdo_entry_count( @@ -367,7 +367,7 @@ if (ec_fsm_coe_exec(fsm->fsm_coe)) return; if (!ec_fsm_coe_success(fsm->fsm_coe)) { - EC_ERR("Failed to read index of mapped Pdo entry from slave %u.\n", + EC_ERR("Failed to read mapped Pdo entry from slave %u.\n", fsm->slave->ring_position); fsm->state = ec_fsm_coe_map_state_error; return; diff -r 40c379697ebf -r 9b395c5646ab master/fsm_coe_map.h --- a/master/fsm_coe_map.h Mon Mar 31 09:42:37 2008 +0000 +++ b/master/fsm_coe_map.h Thu Apr 03 13:34:13 2008 +0000 @@ -67,11 +67,11 @@ uint8_t sync_subindices; /**< number of mapped Pdos */ uint16_t sync_subindex; /**< current subindex in mapping Sdo */ - ec_pdo_mapping_t mapping; /**< Mapping to apply. */ - ec_pdo_t *pdo; /**< current Pdo */ - ec_sdo_t *pdo_sdo; /**< current Pdo Sdo */ - uint8_t pdo_subindices; /**< number of Pdo entries */ - uint16_t pdo_subindex; /**< current subindex in Pdo Sdo */ + ec_pdo_list_t pdos; /**< List of read in Pdos. */ + ec_pdo_t *pdo; /**< Current Pdo. */ + ec_sdo_t *pdo_sdo; /**< Current Pdo Sdo. */ + uint8_t pdo_subindices; /**< Number of Pdo entries. */ + uint16_t pdo_subindex; /**< Current subindex in Pdo Sdo. */ }; /*****************************************************************************/ diff -r 40c379697ebf -r 9b395c5646ab master/fsm_pdo_assign.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/master/fsm_pdo_assign.c Thu Apr 03 13:34:13 2008 +0000 @@ -0,0 +1,380 @@ +/****************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The IgH EtherCAT Master is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * The right to use EtherCAT Technology is granted and comes free of + * charge under condition of compatibility of product made by + * Licensee. People intending to distribute/sell products based on the + * code, have to sign an agreement to guarantee that products using + * software based on IgH EtherCAT master stay compatible with the actual + * EtherCAT specification (which are released themselves as an open + * standard) as the (only) precondition to have the right to use EtherCAT + * Technology, IP and trade marks. + * + *****************************************************************************/ + +/** \file + * EtherCAT Pdo assignment state machine. + */ + +/*****************************************************************************/ + +#include "globals.h" +#include "master.h" +#include "mailbox.h" +#include "slave_config.h" + +#include "fsm_pdo_assign.h" + +/*****************************************************************************/ + +void ec_fsm_pdo_assign_state_start(ec_fsm_pdo_assign_t *); +void ec_fsm_pdo_assign_state_zero_count(ec_fsm_pdo_assign_t *); +void ec_fsm_pdo_assign_state_add_pdo(ec_fsm_pdo_assign_t *); +void ec_fsm_pdo_assign_state_pdo_count(ec_fsm_pdo_assign_t *); +void ec_fsm_pdo_assign_state_end(ec_fsm_pdo_assign_t *); +void ec_fsm_pdo_assign_state_error(ec_fsm_pdo_assign_t *); + +void ec_fsm_pdo_assign_next_dir(ec_fsm_pdo_assign_t *); + +/*****************************************************************************/ + +/** Constructor. + */ +void ec_fsm_pdo_assign_init( + ec_fsm_pdo_assign_t *fsm, /**< Pdo assignment state machine. */ + ec_fsm_coe_t *fsm_coe /**< CoE state machine to use */ + ) +{ + fsm->fsm_coe = fsm_coe; + ec_sdo_request_init(&fsm->request); +} + +/*****************************************************************************/ + +/** Destructor. + */ +void ec_fsm_pdo_assign_clear( + ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */ + ) +{ + ec_sdo_request_clear(&fsm->request); +} + +/*****************************************************************************/ + +/** Start Pdo assignment state machine. + */ +void ec_fsm_pdo_assign_start( + ec_fsm_pdo_assign_t *fsm, /**< Pdo assignment state machine. */ + ec_slave_t *slave /**< slave to configure */ + ) +{ + fsm->slave = slave; + fsm->state = ec_fsm_pdo_assign_state_start; +} + +/*****************************************************************************/ + +/** Get running state. + * + * \return false, if state machine has terminated + */ +int ec_fsm_pdo_assign_running( + const ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */ + ) +{ + return fsm->state != ec_fsm_pdo_assign_state_end + && fsm->state != ec_fsm_pdo_assign_state_error; +} + +/*****************************************************************************/ + +/** Executes the current state of the state machine. + * + * If the state machine's datagram is not sent or received yet, the execution + * of the state machine is delayed to the next cycle. + * + * \return false, if state machine has terminated + */ +int ec_fsm_pdo_assign_exec( + ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */ + ) +{ + fsm->state(fsm); + return ec_fsm_pdo_assign_running(fsm); +} + +/*****************************************************************************/ + +/** Get execution result. + * + * \return true, if the state machine terminated gracefully + */ +int ec_fsm_pdo_assign_success( + const ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */ + ) +{ + return fsm->state == ec_fsm_pdo_assign_state_end; +} + +/****************************************************************************** + * State functions. + *****************************************************************************/ + +/** Start Pdo assignment. + */ +void ec_fsm_pdo_assign_state_start( + ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */ + ) +{ + if (!fsm->slave->config) { + fsm->state = ec_fsm_pdo_assign_state_end; + return; + } + + fsm->dir = (ec_direction_t) -1; // next is EC_DIR_OUTPUT + ec_fsm_pdo_assign_next_dir(fsm); +} + +/*****************************************************************************/ + +/** Process Pdo assignment of next direction. + */ +void ec_fsm_pdo_assign_next_dir( + ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */ + ) +{ + fsm->dir++; + + for (; fsm->dir <= EC_DIR_INPUT; fsm->dir++) { + fsm->pdos = &fsm->slave->config->pdos[fsm->dir]; + + if (!(fsm->sync = ec_slave_get_pdo_sync(fsm->slave, fsm->dir))) { + if (!list_empty(&fsm->pdos->list)) { + EC_ERR("No sync manager for direction %u!\n", fsm->dir); + fsm->state = ec_fsm_pdo_assign_state_end; + return; + } + continue; + } + + // check if assignment has to be altered + if (ec_pdo_list_equal(&fsm->sync->pdos, fsm->pdos)) + continue; + + // Pdo assignment has to be changed. Does the slave support this? + if (!(fsm->slave->sii.mailbox_protocols & EC_MBOX_COE) + || (fsm->slave->sii.has_general + && !fsm->slave->sii.coe_details.enable_pdo_assign)) { + EC_ERR("Slave %u does not support assigning Pdos!\n", + fsm->slave->ring_position); + fsm->state = ec_fsm_pdo_assign_state_error; + return; + } + + if (fsm->slave->master->debug_level) { + EC_DBG("Changing Pdo assignment for SM%u of slave %u.\n", + fsm->sync->index, fsm->slave->ring_position); + } + + if (ec_sdo_request_alloc(&fsm->request, 2)) { + fsm->state = ec_fsm_pdo_assign_state_error; + return; + } + + // set mapped Pdo count to zero + EC_WRITE_U8(fsm->request.data, 0); // zero Pdos mapped + fsm->request.data_size = 1; + ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0); + ecrt_sdo_request_write(&fsm->request); + if (fsm->slave->master->debug_level) + EC_DBG("Setting Pdo count to zero for SM%u.\n", fsm->sync->index); + + fsm->state = ec_fsm_pdo_assign_state_zero_count; + ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); + ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately + return; + } + + if (fsm->slave->master->debug_level) + EC_DBG("Pdo assignment finished for slave %u.\n", + fsm->slave->ring_position); + fsm->state = ec_fsm_pdo_assign_state_end; +} + +/*****************************************************************************/ + +/** Assign next Pdo. + */ +ec_pdo_t *ec_fsm_pdo_assign_next_pdo( + const ec_fsm_pdo_assign_t *fsm, /**< Pdo assignment state machine. */ + const struct list_head *list /**< current Pdo list item */ + ) +{ + list = list->next; + if (list == &fsm->pdos->list) + return NULL; // no next Pdo + return list_entry(list, ec_pdo_t, list); +} + +/*****************************************************************************/ + +/** Assign a Pdo. + */ +void ec_fsm_pdo_assign_add_pdo( + ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */ + ) +{ + EC_WRITE_U16(fsm->request.data, fsm->pdo->index); + fsm->request.data_size = 2; + ec_sdo_request_address(&fsm->request, + 0x1C10 + fsm->sync->index, fsm->pdo_count); + ecrt_sdo_request_write(&fsm->request); + if (fsm->slave->master->debug_level) + EC_DBG("Assigning Pdo 0x%04X at position %u.\n", + fsm->pdo->index, fsm->pdo_count); + + fsm->state = ec_fsm_pdo_assign_state_add_pdo; + ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); + ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately +} + +/*****************************************************************************/ + +/** Set the number of assigned Pdos to zero. + */ +void ec_fsm_pdo_assign_state_zero_count( + ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */ + ) +{ + if (ec_fsm_coe_exec(fsm->fsm_coe)) return; + + if (!ec_fsm_coe_success(fsm->fsm_coe)) { + EC_ERR("Failed to clear Pdo assignment of slave %u.\n", + fsm->slave->ring_position); + fsm->state = ec_fsm_pdo_assign_state_error; + return; + } + + // assign all Pdos belonging to the current sync manager + + // find first Pdo + if (!(fsm->pdo = ec_fsm_pdo_assign_next_pdo(fsm, &fsm->pdos->list))) { + if (fsm->slave->master->debug_level) + EC_DBG("No Pdos to assign for SM%u of slave %u.\n", + fsm->sync->index, fsm->slave->ring_position); + ec_fsm_pdo_assign_next_dir(fsm); + return; + } + + // assign first Pdo + fsm->pdo_count = 1; + ec_fsm_pdo_assign_add_pdo(fsm); +} + +/*****************************************************************************/ + +/** Add a Pdo to the sync managers Pdo assignment. + */ +void ec_fsm_pdo_assign_state_add_pdo( + ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */ + ) +{ + if (ec_fsm_coe_exec(fsm->fsm_coe)) return; + + if (!ec_fsm_coe_success(fsm->fsm_coe)) { + EC_ERR("Failed to map Pdo 0x%04X for SM%u of slave %u.\n", + fsm->pdo->index, fsm->sync->index, fsm->slave->ring_position); + fsm->state = ec_fsm_pdo_assign_state_error; + return; + } + + // find next Pdo + if (!(fsm->pdo = ec_fsm_pdo_assign_next_pdo(fsm, &fsm->pdo->list))) { + // no more Pdos to map. write Pdo count + EC_WRITE_U8(fsm->request.data, fsm->pdo_count); + fsm->request.data_size = 1; + ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0); + ecrt_sdo_request_write(&fsm->request); + if (fsm->slave->master->debug_level) + EC_DBG("Setting number of assigned Pdos to %u.\n", + fsm->pdo_count); + + fsm->state = ec_fsm_pdo_assign_state_pdo_count; + ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); + ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately + return; + } + + // add next Pdo to assignment + fsm->pdo_count++; + ec_fsm_pdo_assign_add_pdo(fsm); +} + +/*****************************************************************************/ + +/** Set the number of assigned Pdos. + */ +void ec_fsm_pdo_assign_state_pdo_count( + ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */ + ) +{ + if (ec_fsm_coe_exec(fsm->fsm_coe)) return; + + if (!ec_fsm_coe_success(fsm->fsm_coe)) { + EC_ERR("Failed to set number of assigned Pdos for slave %u.\n", + fsm->slave->ring_position); + fsm->state = ec_fsm_pdo_assign_state_error; + return; + } + + if (fsm->slave->master->debug_level) + EC_DBG("Successfully set Pdo assignment for SM%u of slave %u.\n", + fsm->sync->index, fsm->slave->ring_position); + + // assignment for this direction finished + ec_fsm_pdo_assign_next_dir(fsm); +} + +/****************************************************************************** + * Common state functions + *****************************************************************************/ + +/** State: ERROR. + */ +void ec_fsm_pdo_assign_state_error( + ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */ + ) +{ +} + +/*****************************************************************************/ + +/** State: END. + */ +void ec_fsm_pdo_assign_state_end( + ec_fsm_pdo_assign_t *fsm /**< Pdo assignment state machine. */ + ) +{ +} + +/*****************************************************************************/ diff -r 40c379697ebf -r 9b395c5646ab master/fsm_pdo_assign.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/master/fsm_pdo_assign.h Thu Apr 03 13:34:13 2008 +0000 @@ -0,0 +1,85 @@ +/****************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The IgH EtherCAT Master is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * The right to use EtherCAT Technology is granted and comes free of + * charge under condition of compatibility of product made by + * Licensee. People intending to distribute/sell products based on the + * code, have to sign an agreement to guarantee that products using + * software based on IgH EtherCAT master stay compatible with the actual + * EtherCAT specification (which are released themselves as an open + * standard) as the (only) precondition to have the right to use EtherCAT + * Technology, IP and trade marks. + * + *****************************************************************************/ + +/** + \file + EtherCAT Pdo assignment state machine structures. +*/ + +/*****************************************************************************/ + +#ifndef _EC_FSM_PDO_ASSIGN_H_ +#define _EC_FSM_PDO_ASSIGN_H_ + +#include "../include/ecrt.h" + +#include "globals.h" +#include "datagram.h" +#include "fsm_coe.h" + +/*****************************************************************************/ + +/** + * \see ec_fsm_pdo_assign + */ +typedef struct ec_fsm_pdo_assign ec_fsm_pdo_assign_t; + +/** Pdo assignment state machine. + */ +struct ec_fsm_pdo_assign +{ + void (*state)(ec_fsm_pdo_assign_t *); /**< State function. */ + ec_fsm_coe_t *fsm_coe; /**< CoE state machine to use. */ + ec_slave_t *slave; /**< Slave the FSM runs on. */ + + ec_direction_t dir; /**< Current direction. */ + const ec_sync_t *sync; /**< Current sync manager. */ + const ec_pdo_list_t *pdos; /**< Target Pdo assignment. */ + const ec_pdo_t *pdo; /**< Current Pdo. */ + + ec_sdo_request_t request; /**< Sdo request. */ + unsigned int pdo_count; /**< Number of assigned Pdos. */ +}; + +/*****************************************************************************/ + +void ec_fsm_pdo_assign_init(ec_fsm_pdo_assign_t *, ec_fsm_coe_t *); +void ec_fsm_pdo_assign_clear(ec_fsm_pdo_assign_t *); + +void ec_fsm_pdo_assign_start(ec_fsm_pdo_assign_t *, ec_slave_t *); +int ec_fsm_pdo_assign_exec(ec_fsm_pdo_assign_t *); +int ec_fsm_pdo_assign_success(const ec_fsm_pdo_assign_t *); + +/*****************************************************************************/ + +#endif diff -r 40c379697ebf -r 9b395c5646ab master/fsm_pdo_config.c --- a/master/fsm_pdo_config.c Mon Mar 31 09:42:37 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,385 +0,0 @@ -/****************************************************************************** - * - * $Id$ - * - * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH - * - * This file is part of the IgH EtherCAT Master. - * - * The IgH EtherCAT Master is free software; you can redistribute it - * and/or modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The IgH EtherCAT Master is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the IgH EtherCAT Master; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * The right to use EtherCAT Technology is granted and comes free of - * charge under condition of compatibility of product made by - * Licensee. People intending to distribute/sell products based on the - * code, have to sign an agreement to guarantee that products using - * software based on IgH EtherCAT master stay compatible with the actual - * EtherCAT specification (which are released themselves as an open - * standard) as the (only) precondition to have the right to use EtherCAT - * Technology, IP and trade marks. - * - *****************************************************************************/ - -/** \file - * EtherCAT Pdo configuration state machine. - */ - -/*****************************************************************************/ - -#include "globals.h" -#include "master.h" -#include "mailbox.h" -#include "slave_config.h" - -#include "fsm_pdo_config.h" - -/*****************************************************************************/ - -void ec_fsm_pdo_config_state_start(ec_fsm_pdo_config_t *); -void ec_fsm_pdo_config_state_zero_count(ec_fsm_pdo_config_t *); -void ec_fsm_pdo_config_state_add_entry(ec_fsm_pdo_config_t *); -void ec_fsm_pdo_config_state_entry_count(ec_fsm_pdo_config_t *); -void ec_fsm_pdo_config_state_end(ec_fsm_pdo_config_t *); -void ec_fsm_pdo_config_state_error(ec_fsm_pdo_config_t *); - -void ec_fsm_pdo_config_next_pdo(ec_fsm_pdo_config_t *); - -/*****************************************************************************/ - -/** Constructor. - */ -void ec_fsm_pdo_config_init( - ec_fsm_pdo_config_t *fsm, /**< pdo_config state machine */ - ec_fsm_coe_t *fsm_coe /**< CoE state machine to use */ - ) -{ - fsm->fsm_coe = fsm_coe; - ec_sdo_request_init(&fsm->request); -} - -/*****************************************************************************/ - -/** Destructor. - */ -void ec_fsm_pdo_config_clear( - ec_fsm_pdo_config_t *fsm /**< pdo_config state machine */ - ) -{ - ec_sdo_request_clear(&fsm->request); -} - -/*****************************************************************************/ - -/** Start Pdo configuration state machine. - */ -void ec_fsm_pdo_config_start( - ec_fsm_pdo_config_t *fsm, /**< Pdo configuration state machine */ - ec_slave_t *slave /**< slave to configure */ - ) -{ - fsm->slave = slave; - fsm->state = ec_fsm_pdo_config_state_start; -} - -/*****************************************************************************/ - -/** Get running state. - * - * \return false, if state machine has terminated - */ -int ec_fsm_pdo_config_running( - const ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */ - ) -{ - return fsm->state != ec_fsm_pdo_config_state_end - && fsm->state != ec_fsm_pdo_config_state_error; -} - -/*****************************************************************************/ - -/** Executes the current state. - * - * \return false, if state machine has terminated - */ -int ec_fsm_pdo_config_exec( - ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */ - ) -{ - fsm->state(fsm); - return ec_fsm_pdo_config_running(fsm); -} - -/*****************************************************************************/ - -/** Get execution result. - * - * \return true, if the state machine terminated gracefully - */ -int ec_fsm_pdo_config_success( - const ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */ - ) -{ - return fsm->state == ec_fsm_pdo_config_state_end; -} - -/****************************************************************************** - * State functions. - *****************************************************************************/ - -/** Start Pdo configuration. - */ -void ec_fsm_pdo_config_state_start( - ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */ - ) -{ - if (!fsm->slave->config) { - fsm->state = ec_fsm_pdo_config_state_end; - return; - } - - fsm->pdo = NULL; - ec_fsm_pdo_config_next_pdo(fsm); -} - -/*****************************************************************************/ - -/** Process configuration of next Pdo. - */ -void ec_fsm_pdo_config_next_pdo( - ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */ - ) -{ - ec_direction_t dir; - const ec_pdo_mapping_t *map; - const ec_pdo_t *pdo, *mapped_pdo; - - for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) { - map = &fsm->slave->config->mapping[dir]; - - list_for_each_entry(pdo, &map->pdos, list) { - if (fsm->pdo) { // there was a Pdo configured in the last run - if (pdo == fsm->pdo) // this is the last Pdo - fsm->pdo = NULL; // take the next one - } else { - if ((mapped_pdo = ec_slave_find_pdo(fsm->slave, pdo->index))) - if (ec_pdo_equal_entries(pdo, mapped_pdo)) - continue; // Pdo configured correctly - - fsm->pdo = pdo; - break; - } - } - } - - if (!fsm->pdo) { - if (fsm->slave->master->debug_level) - EC_DBG("Pdo configuration finished for slave %u.\n", - fsm->slave->ring_position); - fsm->state = ec_fsm_pdo_config_state_end; - return; - } - - // Pdo configuration has to be changed. Does the slave support this? - if (!(fsm->slave->sii.mailbox_protocols & EC_MBOX_COE) - || (fsm->slave->sii.has_general - && !fsm->slave->sii.coe_details.enable_pdo_configuration)) { - EC_ERR("Slave %u does not support changing the Pdo configuration!\n", - fsm->slave->ring_position); - fsm->state = ec_fsm_pdo_config_state_error; - return; - } - - if (fsm->slave->master->debug_level) { - EC_DBG("Changing configuration of Pdo 0x%04X of slave %u.\n", - fsm->pdo->index, fsm->slave->ring_position); - } - - if (ec_sdo_request_alloc(&fsm->request, 4)) { - fsm->state = ec_fsm_pdo_config_state_error; - return; - } - - // set mapped Pdo count to zero - EC_WRITE_U8(fsm->request.data, 0); - fsm->request.data_size = 1; - ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0); - ecrt_sdo_request_write(&fsm->request); - if (fsm->slave->master->debug_level) - EC_DBG("Setting entry count to zero for Pdo 0x%04X.\n", - fsm->pdo->index); - - fsm->state = ec_fsm_pdo_config_state_zero_count; - ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); - ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately -} - -/*****************************************************************************/ - -/** Process next Pdo entry. - */ -ec_pdo_entry_t *ec_fsm_pdo_config_next_entry( - const ec_fsm_pdo_config_t *fsm, /**< Pdo configuration state machine */ - const struct list_head *list /**< current entry list item */ - ) -{ - list = list->next; - if (list == &fsm->pdo->entries) - return NULL; // no next entry - return list_entry(list, ec_pdo_entry_t, list); -} - -/*****************************************************************************/ - -/** Starts to add a Pdo entry. - */ -void ec_fsm_pdo_config_add_entry( - ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine. */ - ) -{ - uint32_t value; - - value = fsm->entry->index << 16 - | fsm->entry->subindex << 8 | fsm->entry->bit_length; - EC_WRITE_U32(fsm->request.data, value); - fsm->request.data_size = 4; - ec_sdo_request_address(&fsm->request, fsm->pdo->index, fsm->entry_count); - ecrt_sdo_request_write(&fsm->request); - if (fsm->slave->master->debug_level) - EC_DBG("Configuring Pdo entry %08X at position %u.\n", - value, fsm->entry_count); - - fsm->state = ec_fsm_pdo_config_state_add_entry; - ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); - ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately -} - -/*****************************************************************************/ - -/** Set the number of configured entries to zero. - */ -void ec_fsm_pdo_config_state_zero_count( - ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */ - ) -{ - if (ec_fsm_coe_exec(fsm->fsm_coe)) return; - - if (!ec_fsm_coe_success(fsm->fsm_coe)) { - EC_ERR("Failed to clear Pdo configuration for slave %u.\n", - fsm->slave->ring_position); - fsm->state = ec_fsm_pdo_config_state_error; - return; - } - - // find first entry - if (!(fsm->entry = - ec_fsm_pdo_config_next_entry(fsm, &fsm->pdo->entries))) { - if (fsm->slave->master->debug_level) - EC_DBG("No entries to configure for Pdo 0x%04X of slave %u.\n", - fsm->pdo->index, fsm->slave->ring_position); - ec_fsm_pdo_config_next_pdo(fsm); - return; - } - - // add first entry - fsm->entry_count = 1; - ec_fsm_pdo_config_add_entry(fsm); -} - -/*****************************************************************************/ - -/** Add a Pdo entry. - */ -void ec_fsm_pdo_config_state_add_entry( - ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */ - ) -{ - if (ec_fsm_coe_exec(fsm->fsm_coe)) return; - - if (!ec_fsm_coe_success(fsm->fsm_coe)) { - EC_ERR("Failed to add entry 0x%04X:%u for slave %u.\n", - fsm->entry->index, fsm->entry->subindex, - fsm->slave->ring_position); - fsm->state = ec_fsm_pdo_config_state_error; - return; - } - - // find next entry - if (!(fsm->entry = ec_fsm_pdo_config_next_entry(fsm, &fsm->entry->list))) { - // No more entries to add. Write entry count. - EC_WRITE_U8(fsm->request.data, fsm->entry_count); - fsm->request.data_size = 1; - ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0); - ecrt_sdo_request_write(&fsm->request); - if (fsm->slave->master->debug_level) - EC_DBG("Setting number of Pdo entries to %u.\n", - fsm->entry_count); - - fsm->state = ec_fsm_pdo_config_state_entry_count; - ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); - ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately - return; - } - - // add next entry - fsm->entry_count++; - ec_fsm_pdo_config_add_entry(fsm); -} - -/*****************************************************************************/ - -/** Set the number of entries. - */ -void ec_fsm_pdo_config_state_entry_count( - ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */ - ) -{ - if (ec_fsm_coe_exec(fsm->fsm_coe)) return; - - if (!ec_fsm_coe_success(fsm->fsm_coe)) { - EC_ERR("Failed to set number of entries for slave %u.\n", - fsm->slave->ring_position); - fsm->state = ec_fsm_pdo_config_state_error; - return; - } - - if (fsm->slave->master->debug_level) - EC_DBG("Successfully configured Pdo 0x%04X on slave %u.\n", - fsm->pdo->index, fsm->slave->ring_position); - - ec_fsm_pdo_config_next_pdo(fsm); -} - -/****************************************************************************** - * Common state functions - *****************************************************************************/ - -/** State: ERROR. - */ -void ec_fsm_pdo_config_state_error( - ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */ - ) -{ -} - -/*****************************************************************************/ - -/** State: END. - */ -void ec_fsm_pdo_config_state_end( - ec_fsm_pdo_config_t *fsm /**< Pdo configuration state machine */ - ) -{ -} - -/*****************************************************************************/ diff -r 40c379697ebf -r 9b395c5646ab master/fsm_pdo_config.h --- a/master/fsm_pdo_config.h Mon Mar 31 09:42:37 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/****************************************************************************** - * - * $Id$ - * - * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH - * - * This file is part of the IgH EtherCAT Master. - * - * The IgH EtherCAT Master is free software; you can redistribute it - * and/or modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The IgH EtherCAT Master is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the IgH EtherCAT Master; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * The right to use EtherCAT Technology is granted and comes free of - * charge under condition of compatibility of product made by - * Licensee. People intending to distribute/sell products based on the - * code, have to sign an agreement to guarantee that products using - * software based on IgH EtherCAT master stay compatible with the actual - * EtherCAT specification (which are released themselves as an open - * standard) as the (only) precondition to have the right to use EtherCAT - * Technology, IP and trade marks. - * - *****************************************************************************/ - -/** \file - * EtherCAT Pdo configuration state machine structures. - */ - -/*****************************************************************************/ - -#ifndef __EC_FSM_PDO_CONFIG__ -#define __EC_FSM_PDO_CONFIG__ - -#include "globals.h" -#include "../include/ecrt.h" -#include "datagram.h" -#include "fsm_coe.h" - -/*****************************************************************************/ - -/** - * \see ec_fsm_pdo_config - */ -typedef struct ec_fsm_pdo_config ec_fsm_pdo_config_t; - -/** Pdo configuration state machine. - */ -struct ec_fsm_pdo_config -{ - void (*state)(ec_fsm_pdo_config_t *); /**< state function */ - ec_fsm_coe_t *fsm_coe; /**< CoE state machine to use */ - ec_slave_t *slave; /**< Slave the FSM runs on. */ - - const ec_pdo_t *pdo; /**< Current Pdo to configure. */ - const ec_pdo_entry_t *entry; /**< Current entry. */ - - ec_sdo_request_t request; /**< Sdo request. */ - unsigned int entry_count; /**< Number of configured entries. */ -}; - -/*****************************************************************************/ - -void ec_fsm_pdo_config_init(ec_fsm_pdo_config_t *, ec_fsm_coe_t *); -void ec_fsm_pdo_config_clear(ec_fsm_pdo_config_t *); - -void ec_fsm_pdo_config_start(ec_fsm_pdo_config_t *, ec_slave_t *); -int ec_fsm_pdo_config_exec(ec_fsm_pdo_config_t *); -int ec_fsm_pdo_config_success(const ec_fsm_pdo_config_t *); - -/*****************************************************************************/ - -#endif diff -r 40c379697ebf -r 9b395c5646ab master/fsm_pdo_mapping.c --- a/master/fsm_pdo_mapping.c Mon Mar 31 09:42:37 2008 +0000 +++ b/master/fsm_pdo_mapping.c Thu Apr 03 13:34:13 2008 +0000 @@ -48,20 +48,20 @@ void ec_fsm_pdo_mapping_state_start(ec_fsm_pdo_mapping_t *); void ec_fsm_pdo_mapping_state_zero_count(ec_fsm_pdo_mapping_t *); -void ec_fsm_pdo_mapping_state_add_pdo(ec_fsm_pdo_mapping_t *); -void ec_fsm_pdo_mapping_state_pdo_count(ec_fsm_pdo_mapping_t *); +void ec_fsm_pdo_mapping_state_add_entry(ec_fsm_pdo_mapping_t *); +void ec_fsm_pdo_mapping_state_entry_count(ec_fsm_pdo_mapping_t *); void ec_fsm_pdo_mapping_state_end(ec_fsm_pdo_mapping_t *); void ec_fsm_pdo_mapping_state_error(ec_fsm_pdo_mapping_t *); -void ec_fsm_pdo_mapping_next_dir(ec_fsm_pdo_mapping_t *); +void ec_fsm_pdo_mapping_next_pdo(ec_fsm_pdo_mapping_t *); /*****************************************************************************/ /** Constructor. */ void ec_fsm_pdo_mapping_init( - ec_fsm_pdo_mapping_t *fsm, /**< mapping state machine */ - ec_fsm_coe_t *fsm_coe /**< CoE state machine to use */ + ec_fsm_pdo_mapping_t *fsm, /**< Pdo mapping state machine. */ + ec_fsm_coe_t *fsm_coe /**< CoE state machine to use. */ ) { fsm->fsm_coe = fsm_coe; @@ -73,7 +73,7 @@ /** Destructor. */ void ec_fsm_pdo_mapping_clear( - ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ + ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */ ) { ec_sdo_request_clear(&fsm->request); @@ -81,10 +81,10 @@ /*****************************************************************************/ -/** Start Pdo mapping configuration state machine. +/** Start Pdo mapping state machine. */ void ec_fsm_pdo_mapping_start( - ec_fsm_pdo_mapping_t *fsm, /**< mapping state machine */ + ec_fsm_pdo_mapping_t *fsm, /**< Pdo mapping state machine. */ ec_slave_t *slave /**< slave to configure */ ) { @@ -99,7 +99,7 @@ * \return false, if state machine has terminated */ int ec_fsm_pdo_mapping_running( - const ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ + const ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */ ) { return fsm->state != ec_fsm_pdo_mapping_state_end @@ -108,15 +108,12 @@ /*****************************************************************************/ -/** Executes the current state of the state machine. - * - * If the state machine's datagram is not sent or received yet, the execution - * of the state machine is delayed to the next cycle. +/** Executes the current state. * * \return false, if state machine has terminated */ int ec_fsm_pdo_mapping_exec( - ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ + ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */ ) { fsm->state(fsm); @@ -130,7 +127,7 @@ * \return true, if the state machine terminated gracefully */ int ec_fsm_pdo_mapping_success( - const ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ + const ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */ ) { return fsm->state == ec_fsm_pdo_mapping_state_end; @@ -140,10 +137,10 @@ * State functions. *****************************************************************************/ -/** Start mapping configuration. +/** Start Pdo mapping. */ void ec_fsm_pdo_mapping_state_start( - ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ + ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */ ) { if (!fsm->slave->config) { @@ -151,119 +148,128 @@ return; } - fsm->dir = (ec_direction_t) -1; // next is EC_DIR_OUTPUT - ec_fsm_pdo_mapping_next_dir(fsm); -} - -/*****************************************************************************/ - -/** Process mapping of next direction. - */ -void ec_fsm_pdo_mapping_next_dir( - ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ - ) -{ - fsm->dir++; - - for (; fsm->dir <= EC_DIR_INPUT; fsm->dir++) { - fsm->mapping = &fsm->slave->config->mapping[fsm->dir]; - - if (!(fsm->sync = ec_slave_get_pdo_sync(fsm->slave, fsm->dir))) { - if (!list_empty(&fsm->mapping->pdos)) { - EC_ERR("No sync manager for direction %u!\n", fsm->dir); - fsm->state = ec_fsm_pdo_mapping_state_end; - return; + fsm->pdo = NULL; + ec_fsm_pdo_mapping_next_pdo(fsm); +} + +/*****************************************************************************/ + +/** Process mapping of next Pdo. + */ +void ec_fsm_pdo_mapping_next_pdo( + ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */ + ) +{ + ec_direction_t dir; + const ec_pdo_list_t *pdos; + const ec_pdo_t *pdo, *assigned_pdo; + + for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) { + pdos = &fsm->slave->config->pdos[dir]; + + list_for_each_entry(pdo, &pdos->list, list) { + if (fsm->pdo) { // there was a Pdo mapping changed in the last run + if (pdo == fsm->pdo) // this is the last Pdo + fsm->pdo = NULL; // take the next one + } else { + if ((assigned_pdo = ec_slave_find_pdo(fsm->slave, pdo->index))) + if (ec_pdo_equal_entries(pdo, assigned_pdo)) + continue; // Pdo entries mapped correctly + + fsm->pdo = pdo; + break; } - continue; } - - // check if mapping has to be altered - if (ec_pdo_mapping_equal(&fsm->sync->mapping, fsm->mapping)) - continue; - - // Pdo mapping has to be changed. Does the slave support this? - if (!fsm->slave->sii.mailbox_protocols & EC_MBOX_COE - || (fsm->slave->sii.has_general - && !fsm->slave->sii.coe_details.enable_pdo_assign)) { - EC_ERR("Slave %u does not support changing the Pdo mapping!\n", + } + + if (!fsm->pdo) { + if (fsm->slave->master->debug_level) + EC_DBG("Pdo mapping finished for slave %u.\n", fsm->slave->ring_position); - fsm->state = ec_fsm_pdo_mapping_state_error; - return; - } - - if (fsm->slave->master->debug_level) { - EC_DBG("Changing Pdo mapping for SM%u of slave %u.\n", - fsm->sync->index, fsm->slave->ring_position); - } - - if (ec_sdo_request_alloc(&fsm->request, 2)) { - fsm->state = ec_fsm_pdo_mapping_state_error; - return; - } - - // set mapped Pdo count to zero - EC_WRITE_U8(fsm->request.data, 0); // zero Pdos mapped - fsm->request.data_size = 1; - ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0); - ecrt_sdo_request_write(&fsm->request); - if (fsm->slave->master->debug_level) - EC_DBG("Setting Pdo count to zero for SM%u.\n", fsm->sync->index); - - fsm->state = ec_fsm_pdo_mapping_state_zero_count; - ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); - ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately - return; - } - - if (fsm->slave->master->debug_level) - EC_DBG("Pdo mapping finished for slave %u.\n", + fsm->state = ec_fsm_pdo_mapping_state_end; + return; + } + + // Pdo mapping has to be changed. Does the slave support this? + if (!(fsm->slave->sii.mailbox_protocols & EC_MBOX_COE) + || (fsm->slave->sii.has_general + && !fsm->slave->sii.coe_details.enable_pdo_configuration)) { + EC_ERR("Slave %u does not support changing the Pdo mapping!\n", fsm->slave->ring_position); - fsm->state = ec_fsm_pdo_mapping_state_end; -} - -/*****************************************************************************/ - -/** Process mapping of next Pdo. - */ -ec_pdo_t *ec_fsm_pdo_mapping_next_pdo( - const ec_fsm_pdo_mapping_t *fsm, /**< mapping state machine */ - const struct list_head *list /**< current Pdo list item */ - ) -{ - list = list->next; - if (list == &fsm->mapping->pdos) - return NULL; // no next Pdo - return list_entry(list, ec_pdo_t, list); -} - -/*****************************************************************************/ - -/** Add a Pdo to the mapping. - */ -void ec_fsm_pdo_mapping_add_pdo( - ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ - ) -{ - EC_WRITE_U16(fsm->request.data, fsm->pdo->index); - fsm->request.data_size = 2; - ec_sdo_request_address(&fsm->request, - 0x1C10 + fsm->sync->index, fsm->pdo_count); + fsm->state = ec_fsm_pdo_mapping_state_error; + return; + } + + if (fsm->slave->master->debug_level) { + EC_DBG("Changing mapping of Pdo 0x%04X of slave %u.\n", + fsm->pdo->index, fsm->slave->ring_position); + } + + if (ec_sdo_request_alloc(&fsm->request, 4)) { + fsm->state = ec_fsm_pdo_mapping_state_error; + return; + } + + // set mapped Pdo count to zero + EC_WRITE_U8(fsm->request.data, 0); + fsm->request.data_size = 1; + ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0); ecrt_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) - EC_DBG("Mapping Pdo 0x%04X at position %u.\n", - fsm->pdo->index, fsm->pdo_count); - - fsm->state = ec_fsm_pdo_mapping_state_add_pdo; + EC_DBG("Setting entry count to zero for Pdo 0x%04X.\n", + fsm->pdo->index); + + fsm->state = ec_fsm_pdo_mapping_state_zero_count; ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately } /*****************************************************************************/ -/** Set the number of mapped Pdos to zero. +/** Process next Pdo entry. + */ +ec_pdo_entry_t *ec_fsm_pdo_mapping_next_entry( + const ec_fsm_pdo_mapping_t *fsm, /**< Pdo mapping state machine. */ + const struct list_head *list /**< current entry list item */ + ) +{ + list = list->next; + if (list == &fsm->pdo->entries) + return NULL; // no next entry + return list_entry(list, ec_pdo_entry_t, list); +} + +/*****************************************************************************/ + +/** Starts to add a Pdo entry. + */ +void ec_fsm_pdo_mapping_add_entry( + ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */ + ) +{ + uint32_t value; + + value = fsm->entry->index << 16 + | fsm->entry->subindex << 8 | fsm->entry->bit_length; + EC_WRITE_U32(fsm->request.data, value); + fsm->request.data_size = 4; + ec_sdo_request_address(&fsm->request, fsm->pdo->index, fsm->entry_count); + ecrt_sdo_request_write(&fsm->request); + if (fsm->slave->master->debug_level) + EC_DBG("Configuring Pdo entry %08X at position %u.\n", + value, fsm->entry_count); + + fsm->state = ec_fsm_pdo_mapping_state_add_entry; + ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); + ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately +} + +/*****************************************************************************/ + +/** Set the number of mapped entries to zero. */ void ec_fsm_pdo_mapping_state_zero_count( - ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ + ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */ ) { if (ec_fsm_coe_exec(fsm->fsm_coe)) return; @@ -275,84 +281,83 @@ return; } - // map all Pdos belonging to the current sync manager - - // find first Pdo - if (!(fsm->pdo = ec_fsm_pdo_mapping_next_pdo(fsm, &fsm->mapping->pdos))) { + // find first entry + if (!(fsm->entry = + ec_fsm_pdo_mapping_next_entry(fsm, &fsm->pdo->entries))) { if (fsm->slave->master->debug_level) - EC_DBG("No Pdos to map for SM%u of slave %u.\n", - fsm->sync->index, fsm->slave->ring_position); - ec_fsm_pdo_mapping_next_dir(fsm); - return; - } - - // add first Pdo to mapping - fsm->pdo_count = 1; - ec_fsm_pdo_mapping_add_pdo(fsm); -} - -/*****************************************************************************/ - -/** Add a Pdo to the sync managers mapping. - */ -void ec_fsm_pdo_mapping_state_add_pdo( - ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ + EC_DBG("No entries to map for Pdo 0x%04X of slave %u.\n", + fsm->pdo->index, fsm->slave->ring_position); + ec_fsm_pdo_mapping_next_pdo(fsm); + return; + } + + // add first entry + fsm->entry_count = 1; + ec_fsm_pdo_mapping_add_entry(fsm); +} + +/*****************************************************************************/ + +/** Add a Pdo entry. + */ +void ec_fsm_pdo_mapping_state_add_entry( + ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */ ) { if (ec_fsm_coe_exec(fsm->fsm_coe)) return; if (!ec_fsm_coe_success(fsm->fsm_coe)) { - EC_ERR("Failed to map Pdo 0x%04X for SM%u of slave %u.\n", - fsm->pdo->index, fsm->sync->index, fsm->slave->ring_position); - fsm->state = ec_fsm_pdo_mapping_state_error; - return; - } - - // find next Pdo - if (!(fsm->pdo = ec_fsm_pdo_mapping_next_pdo(fsm, &fsm->pdo->list))) { - // no more Pdos to map. write Pdo count - EC_WRITE_U8(fsm->request.data, fsm->pdo_count); + EC_ERR("Failed to add entry 0x%04X:%u for slave %u.\n", + fsm->entry->index, fsm->entry->subindex, + fsm->slave->ring_position); + fsm->state = ec_fsm_pdo_mapping_state_error; + return; + } + + // find next entry + if (!(fsm->entry = ec_fsm_pdo_mapping_next_entry(fsm, &fsm->entry->list))) { + // No more entries to add. Write entry count. + EC_WRITE_U8(fsm->request.data, fsm->entry_count); fsm->request.data_size = 1; - ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0); + ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0); ecrt_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) - EC_DBG("Setting number of mapped Pdos to %u.\n", - fsm->pdo_count); + EC_DBG("Setting number of Pdo entries to %u.\n", + fsm->entry_count); - fsm->state = ec_fsm_pdo_mapping_state_pdo_count; + fsm->state = ec_fsm_pdo_mapping_state_entry_count; ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately return; } - // add next Pdo to mapping - fsm->pdo_count++; - ec_fsm_pdo_mapping_add_pdo(fsm); -} - -/*****************************************************************************/ - -/** Set the number of mapped Pdos. - */ -void ec_fsm_pdo_mapping_state_pdo_count( - ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ + // add next entry + fsm->entry_count++; + ec_fsm_pdo_mapping_add_entry(fsm); +} + +/*****************************************************************************/ + +/** Set the number of entries. + */ +void ec_fsm_pdo_mapping_state_entry_count( + ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */ ) { if (ec_fsm_coe_exec(fsm->fsm_coe)) return; if (!ec_fsm_coe_success(fsm->fsm_coe)) { - EC_ERR("Failed to set number of mapped Pdos for slave %u.\n", + EC_ERR("Failed to set number of entries for slave %u.\n", fsm->slave->ring_position); fsm->state = ec_fsm_pdo_mapping_state_error; return; } if (fsm->slave->master->debug_level) - EC_DBG("Successfully set Pdo mapping for SM%u of slave %u.\n", - fsm->sync->index, fsm->slave->ring_position); - - // mapping configuration for this direction finished - ec_fsm_pdo_mapping_next_dir(fsm); + EC_DBG("Successfully configured mapping for Pdo 0x%04X on slave %u.\n", + fsm->pdo->index, fsm->slave->ring_position); + + ec_fsm_pdo_mapping_next_pdo(fsm); } /****************************************************************************** @@ -362,7 +367,7 @@ /** State: ERROR. */ void ec_fsm_pdo_mapping_state_error( - ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ + ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */ ) { } @@ -372,9 +377,9 @@ /** State: END. */ void ec_fsm_pdo_mapping_state_end( - ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ - ) -{ -} - -/*****************************************************************************/ + ec_fsm_pdo_mapping_t *fsm /**< Pdo mapping state machine. */ + ) +{ +} + +/*****************************************************************************/ diff -r 40c379697ebf -r 9b395c5646ab master/fsm_pdo_mapping.h --- a/master/fsm_pdo_mapping.h Mon Mar 31 09:42:37 2008 +0000 +++ b/master/fsm_pdo_mapping.h Thu Apr 03 13:34:13 2008 +0000 @@ -31,19 +31,17 @@ * *****************************************************************************/ -/** - \file - EtherCAT Pdo mapping state machine structures. -*/ +/** \file + * EtherCAT Pdo configuration state machine structures. + */ /*****************************************************************************/ #ifndef __EC_FSM_PDO_MAPPING__ #define __EC_FSM_PDO_MAPPING__ +#include "globals.h" #include "../include/ecrt.h" - -#include "globals.h" #include "datagram.h" #include "fsm_coe.h" @@ -54,21 +52,19 @@ */ typedef struct ec_fsm_pdo_mapping ec_fsm_pdo_mapping_t; -/** Pdo mapping state machine. +/** Pdo configuration state machine. */ struct ec_fsm_pdo_mapping { - void (*state)(ec_fsm_pdo_mapping_t *); /**< State function. */ - ec_fsm_coe_t *fsm_coe; /**< CoE state machine to use. */ + void (*state)(ec_fsm_pdo_mapping_t *); /**< state function */ + ec_fsm_coe_t *fsm_coe; /**< CoE state machine to use */ ec_slave_t *slave; /**< Slave the FSM runs on. */ - ec_direction_t dir; /**< Current direction. */ - const ec_sync_t *sync; /**< Current sync manager. */ - const ec_pdo_mapping_t *mapping; /**< Target Pdo mapping. */ - const ec_pdo_t *pdo; /**< Current Pdo. */ + const ec_pdo_t *pdo; /**< Current Pdo to configure. */ + const ec_pdo_entry_t *entry; /**< Current entry. */ ec_sdo_request_t request; /**< Sdo request. */ - unsigned int pdo_count; /**< Number of mapped Pdos. */ + unsigned int entry_count; /**< Number of configured entries. */ }; /*****************************************************************************/ diff -r 40c379697ebf -r 9b395c5646ab master/fsm_slave_config.c --- a/master/fsm_slave_config.c Mon Mar 31 09:42:37 2008 +0000 +++ b/master/fsm_slave_config.c Thu Apr 03 13:34:13 2008 +0000 @@ -52,8 +52,8 @@ void ec_fsm_slave_config_state_mbox_sync(ec_fsm_slave_config_t *); void ec_fsm_slave_config_state_preop(ec_fsm_slave_config_t *); void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *); -void ec_fsm_slave_config_state_mapping(ec_fsm_slave_config_t *); -void ec_fsm_slave_config_state_pdo_conf(ec_fsm_slave_config_t *); +void ec_fsm_slave_config_state_pdo_assign(ec_fsm_slave_config_t *); +void ec_fsm_slave_config_state_pdo_mapping(ec_fsm_slave_config_t *); void ec_fsm_slave_config_state_pdo_sync(ec_fsm_slave_config_t *); void ec_fsm_slave_config_state_fmmu(ec_fsm_slave_config_t *); void ec_fsm_slave_config_state_safeop(ec_fsm_slave_config_t *); @@ -62,7 +62,7 @@ void ec_fsm_slave_config_enter_mbox_sync(ec_fsm_slave_config_t *); void ec_fsm_slave_config_enter_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_mapping(ec_fsm_slave_config_t *); +void ec_fsm_slave_config_enter_pdo_assign(ec_fsm_slave_config_t *); void ec_fsm_slave_config_enter_pdo_sync(ec_fsm_slave_config_t *); void ec_fsm_slave_config_enter_fmmu(ec_fsm_slave_config_t *); void ec_fsm_slave_config_enter_safeop(ec_fsm_slave_config_t *); @@ -83,8 +83,8 @@ // init sub state machines ec_fsm_change_init(&fsm->fsm_change, fsm->datagram); ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram); - ec_fsm_pdo_mapping_init(&fsm->fsm_pdo_map, &fsm->fsm_coe); - ec_fsm_pdo_config_init(&fsm->fsm_pdo_conf, &fsm->fsm_coe); + ec_fsm_pdo_assign_init(&fsm->fsm_pdo_assign, &fsm->fsm_coe); + ec_fsm_pdo_mapping_init(&fsm->fsm_pdo_mapping, &fsm->fsm_coe); } /*****************************************************************************/ @@ -96,8 +96,8 @@ // clear sub state machines ec_fsm_change_clear(&fsm->fsm_change); ec_fsm_coe_clear(&fsm->fsm_coe); - ec_fsm_pdo_mapping_clear(&fsm->fsm_pdo_map); - ec_fsm_pdo_config_clear(&fsm->fsm_pdo_conf); + ec_fsm_pdo_assign_clear(&fsm->fsm_pdo_assign); + ec_fsm_pdo_mapping_clear(&fsm->fsm_pdo_mapping); } /*****************************************************************************/ @@ -442,7 +442,7 @@ // No CoE configuration to be applied? if (list_empty(&slave->config->sdo_configs)) { // skip Sdo configuration - ec_fsm_slave_config_enter_mapping(fsm); + ec_fsm_slave_config_enter_pdo_assign(fsm); return; } @@ -486,65 +486,65 @@ } // All Sdos are now configured. - ec_fsm_slave_config_enter_mapping(fsm); -} - -/*****************************************************************************/ - -/** - * Check for Pdo mappings to be applied. - */ - -void ec_fsm_slave_config_enter_mapping( + ec_fsm_slave_config_enter_pdo_assign(fsm); +} + +/*****************************************************************************/ + +/** + * Check for alternate Pdo assignments to be applied. + */ + +void ec_fsm_slave_config_enter_pdo_assign( ec_fsm_slave_config_t *fsm /**< slave state machine */ ) { - // start configuring Pdo mapping - fsm->state = ec_fsm_slave_config_state_mapping; - ec_fsm_pdo_mapping_start(&fsm->fsm_pdo_map, fsm->slave); - ec_fsm_pdo_mapping_exec(&fsm->fsm_pdo_map); // execute immediately -} - -/*****************************************************************************/ - -/** - Slave configuration state: MAPPING. -*/ - -void ec_fsm_slave_config_state_mapping( + // start applying alternate Pdo assignments + fsm->state = ec_fsm_slave_config_state_pdo_assign; + ec_fsm_pdo_assign_start(&fsm->fsm_pdo_assign, fsm->slave); + ec_fsm_pdo_assign_exec(&fsm->fsm_pdo_assign); // execute immediately +} + +/*****************************************************************************/ + +/** + Slave configuration state: PDO_ASSIGN. +*/ + +void ec_fsm_slave_config_state_pdo_assign( ec_fsm_slave_config_t *fsm /**< slave state machine */ ) { - if (ec_fsm_pdo_mapping_exec(&fsm->fsm_pdo_map)) return; - - if (!ec_fsm_pdo_mapping_success(&fsm->fsm_pdo_map)) { - EC_ERR("Pdo mapping configuration failed for slave %u.\n", + if (ec_fsm_pdo_assign_exec(&fsm->fsm_pdo_assign)) return; + + if (!ec_fsm_pdo_assign_success(&fsm->fsm_pdo_assign)) { + EC_ERR("Pdo assignment failed for slave %u.\n", fsm->slave->ring_position); fsm->slave->error_flag = 1; fsm->state = ec_fsm_slave_config_state_error; return; } - // Start Pdo configuration - fsm->state = ec_fsm_slave_config_state_pdo_conf; - ec_fsm_pdo_config_start(&fsm->fsm_pdo_conf, fsm->slave); - ec_fsm_pdo_config_exec(&fsm->fsm_pdo_conf); // execute immediately -} - -/*****************************************************************************/ - -/** - Slave configuration state: PDO_CONF. -*/ - -void ec_fsm_slave_config_state_pdo_conf( + // Start configuring Pdo mapping + fsm->state = ec_fsm_slave_config_state_pdo_mapping; + ec_fsm_pdo_mapping_start(&fsm->fsm_pdo_mapping, fsm->slave); + ec_fsm_pdo_mapping_exec(&fsm->fsm_pdo_mapping); // execute immediately +} + +/*****************************************************************************/ + +/** + Slave configuration state: PDO_MAPPING. +*/ + +void ec_fsm_slave_config_state_pdo_mapping( ec_fsm_slave_config_t *fsm /**< slave state machine */ ) { - if (ec_fsm_pdo_config_exec(&fsm->fsm_pdo_conf)) return; - - if (!ec_fsm_pdo_config_success(&fsm->fsm_pdo_conf)) { - EC_ERR("Pdo configuration failed for slave %u.\n", + if (ec_fsm_pdo_mapping_exec(&fsm->fsm_pdo_mapping)) return; + + if (!ec_fsm_pdo_mapping_success(&fsm->fsm_pdo_mapping)) { + EC_ERR("Configuration of Pdo mapping failed for slave %u.\n", fsm->slave->ring_position); fsm->slave->error_flag = 1; fsm->state = ec_fsm_slave_config_state_error; @@ -592,7 +592,7 @@ for (i = 0; i < num_syncs; i++) { sync = &slave->sii.syncs[i + offset]; dir = ec_sync_direction(sync); - size = ec_pdo_mapping_total_size(&slave->config->mapping[dir]); + size = ec_pdo_list_total_size(&slave->config->pdos[dir]); ec_sync_config(sync, size, datagram->data + EC_SYNC_PAGE_SIZE * i); } diff -r 40c379697ebf -r 9b395c5646ab master/fsm_slave_config.h --- a/master/fsm_slave_config.h Mon Mar 31 09:42:37 2008 +0000 +++ b/master/fsm_slave_config.h Thu Apr 03 13:34:13 2008 +0000 @@ -48,8 +48,8 @@ #include "datagram.h" #include "fsm_change.h" #include "fsm_coe.h" +#include "fsm_pdo_assign.h" #include "fsm_pdo_mapping.h" -#include "fsm_pdo_config.h" /*****************************************************************************/ @@ -68,8 +68,8 @@ ec_sdo_request_t *request; /**< Sdo request for Sdo configuration. */ ec_fsm_change_t fsm_change; /**< State change state machine. */ ec_fsm_coe_t fsm_coe; /**< CoE state machine. */ - ec_fsm_pdo_mapping_t fsm_pdo_map; /**< Pdo mapping state machine. */ - ec_fsm_pdo_config_t fsm_pdo_conf; /**< Pdo configuration state machine. */ + ec_fsm_pdo_assign_t fsm_pdo_assign; /**< Pdo assignment state machine. */ + ec_fsm_pdo_mapping_t fsm_pdo_mapping; /**< Pdo mapping state machine. */ }; /*****************************************************************************/ diff -r 40c379697ebf -r 9b395c5646ab master/fsm_slave_scan.h --- a/master/fsm_slave_scan.h Mon Mar 31 09:42:37 2008 +0000 +++ b/master/fsm_slave_scan.h Thu Apr 03 13:34:13 2008 +0000 @@ -50,8 +50,6 @@ #include "fsm_change.h" #include "fsm_coe.h" #include "fsm_coe_map.h" -#include "fsm_pdo_mapping.h" -#include "fsm_pdo_config.h" /*****************************************************************************/ diff -r 40c379697ebf -r 9b395c5646ab master/master.c --- a/master/master.c Mon Mar 31 09:42:37 2008 +0000 +++ b/master/master.c Thu Apr 03 13:34:13 2008 +0000 @@ -1510,7 +1510,7 @@ // try to find the addressed slave ec_slave_config_attach(sc); - ec_slave_config_load_default_mapping(sc); + ec_slave_config_load_default_assignment(sc); list_add_tail(&sc->list, &master->configs); } diff -r 40c379697ebf -r 9b395c5646ab master/pdo_list.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/master/pdo_list.c Thu Apr 03 13:34:13 2008 +0000 @@ -0,0 +1,280 @@ +/****************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The IgH EtherCAT Master is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * The right to use EtherCAT Technology is granted and comes free of + * charge under condition of compatibility of product made by + * Licensee. People intending to distribute/sell products based on the + * code, have to sign an agreement to guarantee that products using + * software based on IgH EtherCAT master stay compatible with the actual + * EtherCAT specification (which are released themselves as an open + * standard) as the (only) precondition to have the right to use EtherCAT + * Technology, IP and trade marks. + * + *****************************************************************************/ + +/** + \file + EtherCAT Pdo list methods. +*/ + +/*****************************************************************************/ + +#include + +#include "globals.h" +#include "pdo.h" +#include "slave_config.h" +#include "master.h" + +#include "pdo_list.h" + +/*****************************************************************************/ + +/** Pdo list constructor. + */ +void ec_pdo_list_init( + ec_pdo_list_t *pl /**< Pdo list. */ + ) +{ + INIT_LIST_HEAD(&pl->list); +} + +/*****************************************************************************/ + +/** Pdo list destructor. + */ +void ec_pdo_list_clear(ec_pdo_list_t *pl /**< Pdo list. */) +{ + ec_pdo_list_clear_pdos(pl); +} + +/*****************************************************************************/ + +/** Clears the list of mapped Pdos. + */ +void ec_pdo_list_clear_pdos(ec_pdo_list_t *pl /**< Pdo list. */) +{ + ec_pdo_t *pdo, *next; + + list_for_each_entry_safe(pdo, next, &pl->list, list) { + list_del_init(&pdo->list); + ec_pdo_clear(pdo); + kfree(pdo); + } +} + +/*****************************************************************************/ + +/** Calculates the total size of the mapped Pdo entries. + * + * \retval Data size in byte. + */ +uint16_t ec_pdo_list_total_size( + const ec_pdo_list_t *pl /**< Pdo list. */ + ) +{ + unsigned int bit_size; + const ec_pdo_t *pdo; + const ec_pdo_entry_t *pdo_entry; + uint16_t byte_size; + + bit_size = 0; + list_for_each_entry(pdo, &pl->list, list) { + list_for_each_entry(pdo_entry, &pdo->entries, list) { + bit_size += pdo_entry->bit_length; + } + } + + if (bit_size % 8) // round up to full bytes + byte_size = bit_size / 8 + 1; + else + byte_size = bit_size / 8; + + return byte_size; +} + +/*****************************************************************************/ + +/** Add a new Pdo to the list. + * + * \retval >0 Pointer to new Pdo. + * \retval NULL No memory. + */ +ec_pdo_t *ec_pdo_list_add_pdo( + ec_pdo_list_t *pl, /**< Pdo list. */ + ec_direction_t dir, /**< Direction. */ + uint16_t index /**< Pdo index. */ + ) +{ + ec_pdo_t *pdo; + + if (!(pdo = (ec_pdo_t *) kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) { + EC_ERR("Failed to allocate memory for Pdo.\n"); + return NULL; + } + + ec_pdo_init(pdo); + pdo->dir = dir; + pdo->index = index; + list_add_tail(&pdo->list, &pl->list); + return pdo; +} + +/*****************************************************************************/ + +/** Add the copy of an existing Pdo to the list. + * + * \return 0 on success, else < 0 + */ +int ec_pdo_list_add_pdo_copy( + ec_pdo_list_t *pl, /**< Pdo list. */ + const ec_pdo_t *pdo /**< Pdo to add. */ + ) +{ + ec_pdo_t *mapped_pdo; + + // Pdo already mapped? + list_for_each_entry(mapped_pdo, &pl->list, list) { + if (mapped_pdo->index != pdo->index) continue; + EC_ERR("Pdo 0x%04X is already mapped!\n", pdo->index); + return -1; + } + + if (!(mapped_pdo = kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) { + EC_ERR("Failed to allocate Pdo memory.\n"); + return -1; + } + + if (ec_pdo_init_copy(mapped_pdo, pdo)) { + kfree(mapped_pdo); + return -1; + } + + list_add_tail(&mapped_pdo->list, &pl->list); + return 0; +} + +/*****************************************************************************/ + +/** Makes a deep copy of another Pdo list. + * + * \return 0 on success, else < 0 + */ +int ec_pdo_list_copy( + ec_pdo_list_t *pl, /**< Pdo list. */ + const ec_pdo_list_t *other /**< Pdo list to copy from. */ + ) +{ + ec_pdo_t *other_pdo; + + ec_pdo_list_clear_pdos(pl); + + // Pdo already mapped? + list_for_each_entry(other_pdo, &other->list, list) { + if (ec_pdo_list_add_pdo_copy(pl, other_pdo)) + return -1; + } + + return 0; +} + +/*****************************************************************************/ + +/** Compares two Pdo lists. + * + * Only the list is compared, not the Pdo entries (i. e. the Pdo + * configuration). + * + * \retval 1 The given Pdo lists are equal. + * \retval 0 The given Pdo lists differ. + */ +int ec_pdo_list_equal( + const ec_pdo_list_t *pl1, /**< First list. */ + const ec_pdo_list_t *pl2 /**< Second list. */ + ) +{ + const struct list_head *h1, *h2, *l1, *l2; + const ec_pdo_t *p1, *p2; + + h1 = l1 = &pl1->list; + h2 = l2 = &pl2->list; + + while (1) { + l1 = l1->next; + l2 = l2->next; + + if ((l1 == h1) ^ (l2 == h2)) // unequal lengths + return 0; + if (l1 == h1) // both finished + break; + + p1 = list_entry(l1, ec_pdo_t, list); + p2 = list_entry(l2, ec_pdo_t, list); + + if (p1->index != p2->index) + return 0; + } + + return 1; +} + +/*****************************************************************************/ + +/** Finds a Pdo with the given index. + */ +ec_pdo_t *ec_pdo_list_find_pdo( + const ec_pdo_list_t *pl, /**< Pdo list. */ + uint16_t index /**< Pdo index. */ + ) +{ + ec_pdo_t *pdo; + + list_for_each_entry(pdo, &pl->list, list) { + if (pdo->index != index) + continue; + return pdo; + } + + return NULL; +} + +/*****************************************************************************/ + +/** Finds a Pdo with the given index and returns a const pointer. + */ +const ec_pdo_t *ec_pdo_list_find_pdo_const( + const ec_pdo_list_t *pl, /**< Pdo list. */ + uint16_t index /**< Pdo index. */ + ) +{ + const ec_pdo_t *pdo; + + list_for_each_entry(pdo, &pl->list, list) { + if (pdo->index != index) + continue; + return pdo; + } + + return NULL; +} + +/*****************************************************************************/ diff -r 40c379697ebf -r 9b395c5646ab master/pdo_list.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/master/pdo_list.h Thu Apr 03 13:34:13 2008 +0000 @@ -0,0 +1,81 @@ +/****************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The IgH EtherCAT Master is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * The right to use EtherCAT Technology is granted and comes free of + * charge under condition of compatibility of product made by + * Licensee. People intending to distribute/sell products based on the + * code, have to sign an agreement to guarantee that products using + * software based on IgH EtherCAT master stay compatible with the actual + * EtherCAT specification (which are released themselves as an open + * standard) as the (only) precondition to have the right to use EtherCAT + * Technology, IP and trade marks. + * + *****************************************************************************/ + +/** + \file + EtherCAT Pdo list structure. +*/ + +/*****************************************************************************/ + +#ifndef _EC_PDO_LIST_H_ +#define _EC_PDO_LIST_H_ + +#include + +#include "../include/ecrt.h" + +#include "globals.h" +#include "pdo.h" + +/*****************************************************************************/ + +/** EtherCAT Pdo list. + */ +typedef struct { + struct list_head list; /**< List of Pdos. */ +} ec_pdo_list_t; + +/*****************************************************************************/ + +void ec_pdo_list_init(ec_pdo_list_t *); +void ec_pdo_list_clear(ec_pdo_list_t *); + +void ec_pdo_list_clear_pdos(ec_pdo_list_t *); + +ec_pdo_t *ec_pdo_list_add_pdo(ec_pdo_list_t *, ec_direction_t, + uint16_t); +int ec_pdo_list_add_pdo_copy(ec_pdo_list_t *, const ec_pdo_t *); + +int ec_pdo_list_copy(ec_pdo_list_t *, const ec_pdo_list_t *); + +uint16_t ec_pdo_list_total_size(const ec_pdo_list_t *); +int ec_pdo_list_equal(const ec_pdo_list_t *, const ec_pdo_list_t *); + +ec_pdo_t *ec_pdo_list_find_pdo(const ec_pdo_list_t *, uint16_t); +const ec_pdo_t *ec_pdo_list_find_pdo_const(const ec_pdo_list_t *, + uint16_t); + +/*****************************************************************************/ + +#endif diff -r 40c379697ebf -r 9b395c5646ab master/pdo_mapping.c --- a/master/pdo_mapping.c Mon Mar 31 09:42:37 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,281 +0,0 @@ -/****************************************************************************** - * - * $Id$ - * - * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH - * - * This file is part of the IgH EtherCAT Master. - * - * The IgH EtherCAT Master is free software; you can redistribute it - * and/or modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The IgH EtherCAT Master is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the IgH EtherCAT Master; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * The right to use EtherCAT Technology is granted and comes free of - * charge under condition of compatibility of product made by - * Licensee. People intending to distribute/sell products based on the - * code, have to sign an agreement to guarantee that products using - * software based on IgH EtherCAT master stay compatible with the actual - * EtherCAT specification (which are released themselves as an open - * standard) as the (only) precondition to have the right to use EtherCAT - * Technology, IP and trade marks. - * - *****************************************************************************/ - -/** - \file - EtherCAT Pdo mapping methods. -*/ - -/*****************************************************************************/ - -#include - -#include "globals.h" -#include "pdo.h" -#include "slave_config.h" -#include "master.h" - -#include "pdo_mapping.h" - -/*****************************************************************************/ - -/** Pdo mapping constructor. - */ -void ec_pdo_mapping_init( - ec_pdo_mapping_t *pm /**< Pdo mapping. */ - ) -{ - INIT_LIST_HEAD(&pm->pdos); - pm->default_mapping = 1; -} - -/*****************************************************************************/ - -/** Pdo mapping destructor. - */ -void ec_pdo_mapping_clear(ec_pdo_mapping_t *pm /**< Pdo mapping. */) -{ - ec_pdo_mapping_clear_pdos(pm); -} - -/*****************************************************************************/ - -/** Clears the list of mapped Pdos. - */ -void ec_pdo_mapping_clear_pdos(ec_pdo_mapping_t *pm /**< Pdo mapping. */) -{ - ec_pdo_t *pdo, *next; - - list_for_each_entry_safe(pdo, next, &pm->pdos, list) { - list_del_init(&pdo->list); - ec_pdo_clear(pdo); - kfree(pdo); - } -} - -/*****************************************************************************/ - -/** Calculates the total size of the mapped Pdo entries. - * - * \retval Data size in byte. - */ -uint16_t ec_pdo_mapping_total_size( - const ec_pdo_mapping_t *pm /**< Pdo mapping. */ - ) -{ - unsigned int bit_size; - const ec_pdo_t *pdo; - const ec_pdo_entry_t *pdo_entry; - uint16_t byte_size; - - bit_size = 0; - list_for_each_entry(pdo, &pm->pdos, list) { - list_for_each_entry(pdo_entry, &pdo->entries, list) { - bit_size += pdo_entry->bit_length; - } - } - - if (bit_size % 8) // round up to full bytes - byte_size = bit_size / 8 + 1; - else - byte_size = bit_size / 8; - - return byte_size; -} - -/*****************************************************************************/ - -/** Add a new Pdo to the mapping. - * - * \retval >0 Pointer to new Pdo. - * \retval NULL No memory. - */ -ec_pdo_t *ec_pdo_mapping_add_pdo( - ec_pdo_mapping_t *pm, /**< Pdo mapping. */ - ec_direction_t dir, /**< Direction. */ - uint16_t index /**< Pdo index. */ - ) -{ - ec_pdo_t *pdo; - - if (!(pdo = (ec_pdo_t *) kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) { - EC_ERR("Failed to allocate memory for Pdo.\n"); - return NULL; - } - - ec_pdo_init(pdo); - pdo->dir = dir; - pdo->index = index; - list_add_tail(&pdo->list, &pm->pdos); - return pdo; -} - -/*****************************************************************************/ - -/** Add the copy of an existing Pdo to the mapping. - * - * \return 0 on success, else < 0 - */ -int ec_pdo_mapping_add_pdo_copy( - ec_pdo_mapping_t *pm, /**< Pdo mapping. */ - const ec_pdo_t *pdo /**< Pdo to add. */ - ) -{ - ec_pdo_t *mapped_pdo; - - // Pdo already mapped? - list_for_each_entry(mapped_pdo, &pm->pdos, list) { - if (mapped_pdo->index != pdo->index) continue; - EC_ERR("Pdo 0x%04X is already mapped!\n", pdo->index); - return -1; - } - - if (!(mapped_pdo = kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) { - EC_ERR("Failed to allocate Pdo memory.\n"); - return -1; - } - - if (ec_pdo_init_copy(mapped_pdo, pdo)) { - kfree(mapped_pdo); - return -1; - } - - list_add_tail(&mapped_pdo->list, &pm->pdos); - return 0; -} - -/*****************************************************************************/ - -/** Makes a deep copy of another Pdo mapping. - * - * \return 0 on success, else < 0 - */ -int ec_pdo_mapping_copy( - ec_pdo_mapping_t *pm, /**< Pdo mapping. */ - const ec_pdo_mapping_t *other /**< Pdo mapping to copy from. */ - ) -{ - ec_pdo_t *other_pdo; - - ec_pdo_mapping_clear_pdos(pm); - - // Pdo already mapped? - list_for_each_entry(other_pdo, &other->pdos, list) { - if (ec_pdo_mapping_add_pdo_copy(pm, other_pdo)) - return -1; - } - - return 0; -} - -/*****************************************************************************/ - -/** Compares two Pdo mappings. - * - * Only the mapping is compared, not the Pdo entries (i. e. the Pdo - * configuration). - * - * \retval 1 The given Pdo mappings are equal. - * \retval 0 The given Pdo mappings differ. - */ -int ec_pdo_mapping_equal( - const ec_pdo_mapping_t *pm1, /**< First mapping. */ - const ec_pdo_mapping_t *pm2 /**< Second mapping. */ - ) -{ - const struct list_head *h1, *h2, *l1, *l2; - const ec_pdo_t *p1, *p2; - - h1 = l1 = &pm1->pdos; - h2 = l2 = &pm2->pdos; - - while (1) { - l1 = l1->next; - l2 = l2->next; - - if ((l1 == h1) ^ (l2 == h2)) // unequal lengths - return 0; - if (l1 == h1) // both finished - break; - - p1 = list_entry(l1, ec_pdo_t, list); - p2 = list_entry(l2, ec_pdo_t, list); - - if (p1->index != p2->index) - return 0; - } - - return 1; -} - -/*****************************************************************************/ - -/** Finds a Pdo with the given index. - */ -ec_pdo_t *ec_pdo_mapping_find_pdo( - const ec_pdo_mapping_t *pm, /**< Pdo mapping. */ - uint16_t index /**< Pdo index. */ - ) -{ - ec_pdo_t *pdo; - - list_for_each_entry(pdo, &pm->pdos, list) { - if (pdo->index != index) - continue; - return pdo; - } - - return NULL; -} - -/*****************************************************************************/ - -/** Finds a Pdo with the given index and returns a const pointer. - */ -const ec_pdo_t *ec_pdo_mapping_find_pdo_const( - const ec_pdo_mapping_t *pm, /**< Pdo mapping. */ - uint16_t index /**< Pdo index. */ - ) -{ - const ec_pdo_t *pdo; - - list_for_each_entry(pdo, &pm->pdos, list) { - if (pdo->index != index) - continue; - return pdo; - } - - return NULL; -} - -/*****************************************************************************/ diff -r 40c379697ebf -r 9b395c5646ab master/pdo_mapping.h --- a/master/pdo_mapping.h Mon Mar 31 09:42:37 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/****************************************************************************** - * - * $Id$ - * - * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH - * - * This file is part of the IgH EtherCAT Master. - * - * The IgH EtherCAT Master is free software; you can redistribute it - * and/or modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The IgH EtherCAT Master is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the IgH EtherCAT Master; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * The right to use EtherCAT Technology is granted and comes free of - * charge under condition of compatibility of product made by - * Licensee. People intending to distribute/sell products based on the - * code, have to sign an agreement to guarantee that products using - * software based on IgH EtherCAT master stay compatible with the actual - * EtherCAT specification (which are released themselves as an open - * standard) as the (only) precondition to have the right to use EtherCAT - * Technology, IP and trade marks. - * - *****************************************************************************/ - -/** - \file - EtherCAT Pdo mapping structure. -*/ - -/*****************************************************************************/ - -#ifndef _EC_PDO_MAPPING_H_ -#define _EC_PDO_MAPPING_H_ - -#include - -#include "../include/ecrt.h" - -#include "globals.h" -#include "pdo.h" - -/*****************************************************************************/ - -/** EtherCAT Pdo mapping. - */ -typedef struct { - struct list_head pdos; /**< List of Pdos. */ - unsigned int default_mapping; /**< This is the default mapping. */ -} ec_pdo_mapping_t; - -/*****************************************************************************/ - -void ec_pdo_mapping_init(ec_pdo_mapping_t *); -void ec_pdo_mapping_clear(ec_pdo_mapping_t *); - -void ec_pdo_mapping_clear_pdos(ec_pdo_mapping_t *); - -ec_pdo_t *ec_pdo_mapping_add_pdo(ec_pdo_mapping_t *, ec_direction_t, - uint16_t); -int ec_pdo_mapping_add_pdo_copy(ec_pdo_mapping_t *, const ec_pdo_t *); - -int ec_pdo_mapping_copy(ec_pdo_mapping_t *, const ec_pdo_mapping_t *); - -uint16_t ec_pdo_mapping_total_size(const ec_pdo_mapping_t *); -int ec_pdo_mapping_equal(const ec_pdo_mapping_t *, const ec_pdo_mapping_t *); - -ec_pdo_t *ec_pdo_mapping_find_pdo(const ec_pdo_mapping_t *, uint16_t); -const ec_pdo_t *ec_pdo_mapping_find_pdo_const(const ec_pdo_mapping_t *, - uint16_t); - -/*****************************************************************************/ - -#endif diff -r 40c379697ebf -r 9b395c5646ab master/slave.c --- a/master/slave.c Mon Mar 31 09:42:37 2008 +0000 +++ b/master/slave.c Thu Apr 03 13:34:13 2008 +0000 @@ -615,10 +615,10 @@ } sync = &slave->sii.syncs[pdo->sync_index]; - if (ec_pdo_mapping_add_pdo_copy(&sync->mapping, pdo)) + if (ec_pdo_list_add_pdo_copy(&sync->pdos, pdo)) return -1; - sync->mapping_source = EC_SYNC_MAPPING_SII; + sync->assign_source = EC_ASSIGN_SII; } } @@ -798,7 +798,7 @@ } if (slave->sii.sync_count) { - buf += sprintf(buf, "Sync managers / Pdo mapping:\n"); + buf += sprintf(buf, "Sync managers / assigned Pdos:\n"); for (i = 0; i < slave->sii.sync_count; i++) { sync = &slave->sii.syncs[i]; @@ -808,16 +808,28 @@ sync->length, sync->control_register, sync->enable ? "enable" : "disable"); - if (list_empty(&sync->mapping.pdos)) { - buf += sprintf(buf, " No Pdos mapped.\n"); - } else if (sync->mapping_source != EC_SYNC_MAPPING_NONE) { - buf += sprintf(buf, - " Pdo mapping information from %s.\n", - sync->mapping_source == EC_SYNC_MAPPING_SII - ? "SII" : "CoE"); + if (list_empty(&sync->pdos.list)) { + buf += sprintf(buf, " No Pdos assigned.\n"); + } else if (sync->assign_source != EC_ASSIGN_NONE) { + buf += sprintf(buf, " Pdo assignment from "); + switch (sync->assign_source) { + case EC_ASSIGN_SII: + buf += sprintf(buf, "SII"); + break; + case EC_ASSIGN_COE: + buf += sprintf(buf, "CoE"); + break; + case EC_ASSIGN_CUSTOM: + buf += sprintf(buf, "application"); + break; + default: + buf += sprintf(buf, "?"); + break; + } + buf += sprintf(buf, ".\n"); } - list_for_each_entry(pdo, &sync->mapping.pdos, list) { + list_for_each_entry(pdo, &sync->pdos.list, list) { buf += sprintf(buf, " %s 0x%04X \"%s\"\n", pdo->dir == EC_DIR_OUTPUT ? "RxPdo" : "TxPdo", pdo->index, pdo->name ? pdo->name : "???"); @@ -843,10 +855,10 @@ pdo->dir == EC_DIR_OUTPUT ? "RxPdo" : "TxPdo", pdo->index, pdo->name ? pdo->name : "???"); if (pdo->sync_index >= 0) - buf += sprintf(buf, ", default mapping: SM%u.\n", + buf += sprintf(buf, ", default assignment: SM%u.\n", pdo->sync_index); else - buf += sprintf(buf, ", no default mapping.\n"); + buf += sprintf(buf, ", no default assignment.\n"); list_for_each_entry(pdo_entry, &pdo->entries, list) { buf += sprintf(buf, " 0x%04X:%X \"%s\", %u bit\n", @@ -1302,7 +1314,7 @@ for (i = 0; i < slave->sii.sync_count; i++) { sync = &slave->sii.syncs[i]; - if (!(pdo = ec_pdo_mapping_find_pdo_const(&sync->mapping, index))) + if (!(pdo = ec_pdo_list_find_pdo_const(&sync->pdos, index))) continue; return pdo; diff -r 40c379697ebf -r 9b395c5646ab master/slave_config.c --- a/master/slave_config.c Mon Mar 31 09:42:37 2008 +0000 +++ b/master/slave_config.c Thu Apr 03 13:34:13 2008 +0000 @@ -102,7 +102,7 @@ sc->slave = NULL; for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) - ec_pdo_mapping_init(&sc->mapping[dir]); + ec_pdo_list_init(&sc->pdos[dir]); INIT_LIST_HEAD(&sc->sdo_configs); INIT_LIST_HEAD(&sc->sdo_requests); @@ -166,7 +166,7 @@ // Free Pdo mappings for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) - ec_pdo_mapping_clear(&sc->mapping[dir]); + ec_pdo_list_clear(&sc->pdos[dir]); // free all Sdo configurations list_for_each_entry_safe(req, next_req, &sc->sdo_configs, list) { @@ -236,7 +236,7 @@ { char *buf = buffer; ec_direction_t dir; - const ec_pdo_mapping_t *map; + const ec_pdo_list_t *pdos; const ec_pdo_t *pdo; const ec_pdo_entry_t *entry; char str[20]; @@ -246,13 +246,13 @@ buf += sprintf(buf, "Position: %u\n", sc->position); for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) { - map = &sc->mapping[dir]; + pdos = &sc->pdos[dir]; - if (!list_empty(&map->pdos)) { - buf += sprintf(buf, "%s mapping:\n", + if (!list_empty(&pdos->list)) { + buf += sprintf(buf, "%s Pdo assignment / mapping:\n", dir == EC_DIR_OUTPUT ? "Output" : "Input"); - list_for_each_entry(pdo, &map->pdos, list) { + list_for_each_entry(pdo, &pdos->list, list) { buf += sprintf(buf, " %s 0x%04X \"%s\"\n", pdo->dir == EC_DIR_OUTPUT ? "RxPdo" : "TxPdo", pdo->index, pdo->name ? pdo->name : "???"); @@ -429,31 +429,29 @@ /*****************************************************************************/ -/** Loads the default mapping from the slave object. - */ -void ec_slave_config_load_default_mapping(ec_slave_config_t *sc) +/** Loads the default Pdo assignment from the slave object. + */ +void ec_slave_config_load_default_assignment(ec_slave_config_t *sc) { ec_direction_t dir; - ec_pdo_mapping_t *map; + ec_pdo_list_t *pdos; ec_sync_t *sync; if (!sc->slave) return; for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) { - map = &sc->mapping[dir]; - if (!(sync = ec_slave_get_pdo_sync(sc->slave, dir))) - continue; - ec_pdo_mapping_copy(map, &sync->mapping); - map->default_mapping = 1; - } -} - -/*****************************************************************************/ - -/** Loads the default configuration for a Pdo from the slave object. - */ -void ec_slave_config_load_default_pdo_config( + pdos = &sc->pdos[dir]; + if ((sync = ec_slave_get_pdo_sync(sc->slave, dir))) + ec_pdo_list_copy(pdos, &sync->pdos); + } +} + +/*****************************************************************************/ + +/** Loads the default mapping for a Pdo from the slave object. + */ +void ec_slave_config_load_default_mapping( const ec_slave_config_t *sc, ec_pdo_t *pdo ) @@ -479,7 +477,7 @@ return; } - list_for_each_entry(default_pdo, &sync->mapping.pdos, list) { + list_for_each_entry(default_pdo, &sync->pdos.list, list) { if (default_pdo->index != pdo->index) continue; @@ -508,113 +506,128 @@ * Realtime interface *****************************************************************************/ -int ecrt_slave_config_pdo(ec_slave_config_t *sc, ec_direction_t dir, - uint16_t index) -{ - ec_pdo_mapping_t *pm = &sc->mapping[dir]; +int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc, + ec_direction_t dir, uint16_t index) +{ + ec_pdo_list_t *pl = &sc->pdos[dir]; ec_pdo_t *pdo; - if (pm->default_mapping) { - if (sc->master->debug_level) - EC_DBG("Clearing default mapping for dir %u, config %u:%u.\n", - dir, sc->alias, sc->position); - pm->default_mapping = 0; - ec_pdo_mapping_clear_pdos(pm); - } - if (sc->master->debug_level) - EC_DBG("Adding Pdo 0x%04X to mapping for dir %u, config %u:%u.\n", + EC_DBG("Adding Pdo 0x%04X to assignment for dir %u, config %u:%u.\n", index, dir, sc->alias, sc->position); - if (!(pdo = ec_pdo_mapping_add_pdo(pm, dir, index))) + if (!(pdo = ec_pdo_list_add_pdo(pl, dir, index))) return -1; - ec_slave_config_load_default_pdo_config(sc, pdo); + ec_slave_config_load_default_mapping(sc, pdo); return 0; } /*****************************************************************************/ -int ecrt_slave_config_pdo_entry(ec_slave_config_t *sc, uint16_t pdo_index, - uint16_t entry_index, uint8_t entry_subindex, +void ecrt_slave_config_pdo_assign_clear(ec_slave_config_t *sc, + ec_direction_t dir) +{ + if (sc->master->debug_level) + EC_DBG("Clearing Pdo assignment for dir %u, config %u:%u.\n", + dir, sc->alias, sc->position); + + ec_pdo_list_clear_pdos(&sc->pdos[dir]); +} + +/*****************************************************************************/ + +int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc, + uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex, uint8_t entry_bit_length) { ec_direction_t dir; ec_pdo_t *pdo; if (sc->master->debug_level) - EC_DBG("Adding Pdo entry 0x%04X:%u (%u bit) to configuration of Pdo" + EC_DBG("Adding Pdo entry 0x%04X:%u (%u bit) to mapping of Pdo" " 0x%04X, config %u:%u.\n", entry_index, entry_subindex, entry_bit_length, pdo_index, sc->alias, sc->position); for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) - if ((pdo = ec_pdo_mapping_find_pdo(&sc->mapping[dir], pdo_index))) + if ((pdo = ec_pdo_list_find_pdo(&sc->pdos[dir], pdo_index))) break; if (!pdo) { - EC_ERR("Pdo 0x%04X was not found in the mapping of config %u:%u.\n", + EC_ERR("Pdo 0x%04X is not assigned in config %u:%u.\n", pdo_index, sc->alias, sc->position); return -1; } - if (pdo->default_config) { - if (sc->master->debug_level) - EC_DBG("Clearing default configuration of Pdo 0x%04X," - " config %u:%u.\n", pdo->index, sc->alias, sc->position); - pdo->default_config = 0; - ec_pdo_clear_entries(pdo); - } - return ec_pdo_add_entry(pdo, entry_index, entry_subindex, entry_bit_length) ? 0 : -1; } /*****************************************************************************/ -int ecrt_slave_config_mapping(ec_slave_config_t *sc, unsigned int n_infos, +void ecrt_slave_config_pdo_mapping_clear(ec_slave_config_t *sc, + uint16_t pdo_index) +{ + ec_direction_t dir; + ec_pdo_t *pdo; + + if (sc->master->debug_level) + EC_DBG("Clearing mapping of Pdo 0x%04X, config %u:%u.\n", + pdo_index, sc->alias, sc->position); + + for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) + if ((pdo = ec_pdo_list_find_pdo(&sc->pdos[dir], pdo_index))) + break; + + if (!pdo) { + EC_WARN("Pdo 0x%04X is not assigned in config %u:%u.\n", + pdo_index, sc->alias, sc->position); + return; + } + + ec_pdo_clear_entries(pdo); +} + +/*****************************************************************************/ + +int ecrt_slave_config_pdos(ec_slave_config_t *sc, unsigned int n_infos, const ec_pdo_info_t pdo_infos[]) { unsigned int i, j; const ec_pdo_info_t *pi; - ec_pdo_mapping_t *pm; - ec_pdo_t *pdo; + ec_pdo_list_t *pl; + unsigned int cleared[] = {0, 0}; const ec_pdo_entry_info_t *ei; for (i = 0; i < n_infos; i++) { pi = &pdo_infos[i]; - if (pi->dir == EC_MAP_END) + if (pi->dir == EC_END) break; - pm = &sc->mapping[pi->dir]; - - if (pm->default_mapping) { + pl = &sc->pdos[pi->dir]; + + if (!cleared[pi->dir]) { + ecrt_slave_config_pdo_assign_clear(sc, pi->dir); + cleared[pi->dir] = 1; + } + + if (ecrt_slave_config_pdo_assign_add(sc, pi->dir, pi->index)) + return -1; + + if (pi->n_entries && pi->entries) { // mapping provided if (sc->master->debug_level) - EC_DBG("Clearing default mapping for dir %u, config %u:%u.\n", - pi->dir, sc->alias, sc->position); - pm->default_mapping = 0; - ec_pdo_mapping_clear_pdos(pm); - } - - if (sc->master->debug_level) - EC_DBG("Adding Pdo 0x%04X to mapping for dir %u, config %u:%u.\n", - pi->index, pi->dir, sc->alias, sc->position); - - if (!(pdo = ec_pdo_mapping_add_pdo(pm, pi->dir, pi->index))) - return -1; - - if (pi->n_entries && pi->entries) { // configuration provided - if (sc->master->debug_level) - EC_DBG(" Pdo configuration information provided.\n"); + EC_DBG(" Pdo mapping information provided.\n"); + + ecrt_slave_config_pdo_mapping_clear(sc, pi->index); for (j = 0; j < pi->n_entries; j++) { ei = &pi->entries[j]; - if (!ec_pdo_add_entry(pdo, ei->index, ei->subindex, - ei->bit_length)) + + if (ecrt_slave_config_pdo_mapping_add(sc, pi->index, + ei->index, ei->subindex, ei->bit_length)) return -1; } - } else { // use default Pdo configuration - ec_slave_config_load_default_pdo_config(sc, pdo); } } @@ -631,16 +644,16 @@ ) { ec_direction_t dir; - ec_pdo_mapping_t *map; + ec_pdo_list_t *pdos; unsigned int bit_offset, byte_offset; ec_pdo_t *pdo; ec_pdo_entry_t *entry; int ret; for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) { - map = &sc->mapping[dir]; + pdos = &sc->pdos[dir]; bit_offset = 0; - list_for_each_entry(pdo, &map->pdos, list) { + list_for_each_entry(pdo, &pdos->list, list) { list_for_each_entry(entry, &pdo->entries, list) { if (entry->index != index || entry->subindex != subindex) { bit_offset += entry->bit_length; @@ -726,9 +739,11 @@ /** \cond */ -EXPORT_SYMBOL(ecrt_slave_config_pdo); -EXPORT_SYMBOL(ecrt_slave_config_pdo_entry); -EXPORT_SYMBOL(ecrt_slave_config_mapping); +EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_add); +EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_clear); +EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_add); +EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_clear); +EXPORT_SYMBOL(ecrt_slave_config_pdos); EXPORT_SYMBOL(ecrt_slave_config_reg_pdo_entry); EXPORT_SYMBOL(ecrt_slave_config_sdo8); EXPORT_SYMBOL(ecrt_slave_config_sdo16); diff -r 40c379697ebf -r 9b395c5646ab master/slave_config.h --- a/master/slave_config.h Mon Mar 31 09:42:37 2008 +0000 +++ b/master/slave_config.h Thu Apr 03 13:34:13 2008 +0000 @@ -49,7 +49,7 @@ #include "globals.h" #include "slave.h" #include "fmmu_config.h" -#include "pdo_mapping.h" +#include "pdo_list.h" /*****************************************************************************/ @@ -69,7 +69,7 @@ ec_slave_t *slave; /**< Slave pointer. This is \a NULL, if the slave is offline. */ - ec_pdo_mapping_t mapping[2]; /**< Output and input Pdo mapping. */ + ec_pdo_list_t pdos[2]; /**< Output and input Pdo assignment / mapping. */ struct list_head sdo_configs; /**< List of Sdo configurations. */ struct list_head sdo_requests; /**< List of Sdo requests. */ @@ -87,8 +87,8 @@ int ec_slave_config_attach(ec_slave_config_t *); void ec_slave_config_detach(ec_slave_config_t *); -void ec_slave_config_load_default_mapping(ec_slave_config_t *); -void ec_slave_config_load_default_pdo_config(const ec_slave_config_t *, +void ec_slave_config_load_default_assignment(ec_slave_config_t *); +void ec_slave_config_load_default_mapping(const ec_slave_config_t *, ec_pdo_t *); /*****************************************************************************/ diff -r 40c379697ebf -r 9b395c5646ab master/sync.c --- a/master/sync.c Mon Mar 31 09:42:37 2008 +0000 +++ b/master/sync.c Thu Apr 03 13:34:13 2008 +0000 @@ -56,8 +56,8 @@ sync->slave = slave; sync->index = index; - ec_pdo_mapping_init(&sync->mapping); - sync->mapping_source = EC_SYNC_MAPPING_NONE; + ec_pdo_list_init(&sync->pdos); + sync->assign_source = EC_ASSIGN_NONE; } /*****************************************************************************/ @@ -76,10 +76,10 @@ sync->control_register = other->control_register; sync->enable = other->enable; - ec_pdo_mapping_init(&sync->mapping); - ec_pdo_mapping_copy(&sync->mapping, &other->mapping); + ec_pdo_list_init(&sync->pdos); + ec_pdo_list_copy(&sync->pdos, &other->pdos); - sync->mapping_source = other->mapping_source; + sync->assign_source = other->assign_source; } /*****************************************************************************/ @@ -90,7 +90,7 @@ ec_sync_t *sync /**< EtherCAT sync manager. */ ) { - ec_pdo_mapping_clear(&sync->mapping); + ec_pdo_list_clear(&sync->pdos); } /*****************************************************************************/ @@ -129,7 +129,7 @@ const ec_pdo_t *pdo /**< Pdo to map. */ ) { - return ec_pdo_mapping_add_pdo_copy(&sync->mapping, pdo); + return ec_pdo_list_add_pdo_copy(&sync->pdos, pdo); } /*****************************************************************************/ diff -r 40c379697ebf -r 9b395c5646ab master/sync.h --- a/master/sync.h Mon Mar 31 09:42:37 2008 +0000 +++ b/master/sync.h Thu Apr 03 13:34:13 2008 +0000 @@ -45,18 +45,18 @@ #include "../include/ecrt.h" #include "globals.h" -#include "pdo_mapping.h" +#include "pdo_list.h" /*****************************************************************************/ -/** EtherCAT sync manager Pdo mapping information source. +/** EtherCAT Pdo assignment source. */ typedef enum { - EC_SYNC_MAPPING_NONE, /**< No Pdo mapping information. */ - EC_SYNC_MAPPING_SII, /**< Pdo mapping information from SII. */ - EC_SYNC_MAPPING_COE, /**< Pdo mapping information from CoE dictionary. */ - EC_SYNC_MAPPING_CUSTOM, /**< Pdo mapping configured externally. */ -} ec_sync_mapping_source_t; + EC_ASSIGN_NONE, /**< No Pdos assigned. */ + EC_ASSIGN_SII, /**< Pdo assignment read from SII. */ + EC_ASSIGN_COE, /**< Pdo assignment read via CoE. */ + EC_ASSIGN_CUSTOM, /**< Pdos assignment set by application. */ +} ec_assign_source_t; /*****************************************************************************/ @@ -69,8 +69,8 @@ uint16_t length; /**< Data length in bytes. */ uint8_t control_register; /**< Control register value. */ uint8_t enable; /**< Enable bit. */ - ec_pdo_mapping_t mapping; /**< Current Pdo mapping. */ - ec_sync_mapping_source_t mapping_source; /**< Pdo mapping source. */ + ec_pdo_list_t pdos; /**< Current Pdo assignment. */ + ec_assign_source_t assign_source; /**< Pdo assignment source. */ } ec_sync_t; /*****************************************************************************/