master/slave_config.c
changeset 1055 2be8918682fa
parent 1054 4c16fe64b403
child 1059 38b1630463aa
equal deleted inserted replaced
1054:4c16fe64b403 1055:2be8918682fa
    59         uint16_t position, /**< Slave position. */
    59         uint16_t position, /**< Slave position. */
    60         uint32_t vendor_id, /**< Expected vendor ID. */
    60         uint32_t vendor_id, /**< Expected vendor ID. */
    61         uint32_t product_code /**< Expected product code. */
    61         uint32_t product_code /**< Expected product code. */
    62         )
    62         )
    63 {
    63 {
    64     ec_direction_t dir;
    64     unsigned int i;
    65 
    65 
    66     sc->master = master;
    66     sc->master = master;
    67     sc->alias = alias;
    67     sc->alias = alias;
    68     sc->position = position;
    68     sc->position = position;
    69     sc->vendor_id = vendor_id;
    69     sc->vendor_id = vendor_id;
    70     sc->product_code = product_code;
    70     sc->product_code = product_code;
    71     sc->slave = NULL;
    71     sc->slave = NULL;
    72 
    72 
    73     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
    73     for (i = 0; i < EC_MAX_SYNCS; i++)
    74         ec_pdo_list_init(&sc->pdos[dir]);
    74         ec_sync_config_init(&sc->sync_configs[i]);
    75 
    75 
    76     INIT_LIST_HEAD(&sc->sdo_configs);
    76     INIT_LIST_HEAD(&sc->sdo_configs);
    77     INIT_LIST_HEAD(&sc->sdo_requests);
    77     INIT_LIST_HEAD(&sc->sdo_requests);
    78 
    78 
    79     sc->used_fmmus = 0;
    79     sc->used_fmmus = 0;
    87  */
    87  */
    88 void ec_slave_config_clear(
    88 void ec_slave_config_clear(
    89         ec_slave_config_t *sc /**< Slave configuration. */
    89         ec_slave_config_t *sc /**< Slave configuration. */
    90         )
    90         )
    91 {
    91 {
    92     ec_direction_t dir;
    92     unsigned int i;
    93     ec_sdo_request_t *req, *next_req;
    93     ec_sdo_request_t *req, *next_req;
    94 
    94 
    95     ec_slave_config_detach(sc);
    95     ec_slave_config_detach(sc);
    96 
    96 
    97     // Free Pdo mappings
    97     // Free sync managers
    98     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
    98     for (i = 0; i < EC_MAX_SYNCS; i++)
    99         ec_pdo_list_clear(&sc->pdos[dir]);
    99         ec_sync_config_clear(&sc->sync_configs[i]);
   100 
   100 
   101     // free all Sdo configurations
   101     // free all Sdo configurations
   102     list_for_each_entry_safe(req, next_req, &sc->sdo_configs, list) {
   102     list_for_each_entry_safe(req, next_req, &sc->sdo_configs, list) {
   103         list_del(&req->list);
   103         list_del(&req->list);
   104         ec_sdo_request_clear(req);
   104         ec_sdo_request_clear(req);
   128  * \retval -1  Error, FMMU limit reached.
   128  * \retval -1  Error, FMMU limit reached.
   129  */
   129  */
   130 int ec_slave_config_prepare_fmmu(
   130 int ec_slave_config_prepare_fmmu(
   131         ec_slave_config_t *sc, /**< Slave configuration. */
   131         ec_slave_config_t *sc, /**< Slave configuration. */
   132         ec_domain_t *domain, /**< Domain. */
   132         ec_domain_t *domain, /**< Domain. */
       
   133         uint8_t sync_index, /**< Sync manager index. */
   133         ec_direction_t dir /**< Pdo direction. */
   134         ec_direction_t dir /**< Pdo direction. */
   134         )
   135         )
   135 {
   136 {
   136     unsigned int i;
   137     unsigned int i;
   137     ec_fmmu_config_t *fmmu;
   138     ec_fmmu_config_t *fmmu;
   138 
   139 
   139     // FMMU configuration already prepared?
   140     // FMMU configuration already prepared?
   140     for (i = 0; i < sc->used_fmmus; i++) {
   141     for (i = 0; i < sc->used_fmmus; i++) {
   141         fmmu = &sc->fmmu_configs[i];
   142         fmmu = &sc->fmmu_configs[i];
   142         if (fmmu->domain == domain && fmmu->dir == dir)
   143         if (fmmu->domain == domain && fmmu->sync_index == sync_index)
   143             return fmmu->logical_start_address;
   144             return fmmu->logical_start_address;
   144     }
   145     }
   145 
   146 
   146     if (sc->used_fmmus == EC_MAX_FMMUS) {
   147     if (sc->used_fmmus == EC_MAX_FMMUS) {
   147         EC_ERR("FMMU limit reached for slave configuration %u:%u!\n",
   148         EC_ERR("FMMU limit reached for slave configuration %u:%u!\n",
   148                 sc->alias, sc->position);
   149                 sc->alias, sc->position);
   149         return -1;
   150         return -1;
   150     }
   151     }
   151 
   152 
   152     fmmu = &sc->fmmu_configs[sc->used_fmmus++];
   153     fmmu = &sc->fmmu_configs[sc->used_fmmus++];
   153     ec_fmmu_config_init(fmmu, sc, domain, dir);
   154     ec_fmmu_config_init(fmmu, sc, domain, sync_index, dir);
   154     return fmmu->logical_start_address;
   155     return fmmu->logical_start_address;
   155 }
   156 }
   156 
   157 
   157 /*****************************************************************************/
   158 /*****************************************************************************/
   158 
   159 
   226 
   227 
   227 /*****************************************************************************/
   228 /*****************************************************************************/
   228 
   229 
   229 /** Loads the default Pdo assignment from the slave object.
   230 /** Loads the default Pdo assignment from the slave object.
   230  */
   231  */
   231 void ec_slave_config_load_default_assignment(ec_slave_config_t *sc)
   232 void ec_slave_config_load_default_sync_config(ec_slave_config_t *sc)
   232 {
   233 {
   233     ec_direction_t dir;
   234     uint8_t sync_index;
   234     ec_pdo_list_t *pdos;
   235     ec_sync_config_t *sync_config;
   235     ec_sync_t *sync;
   236     const ec_sync_t *sync;
   236 
   237 
   237     if (!sc->slave)
   238     if (!sc->slave)
   238         return;
   239         return;
   239     
   240     
   240     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
   241     
   241         pdos = &sc->pdos[dir];
   242     for (sync_index = 0; sync_index < EC_MAX_SYNCS; sync_index++) {
   242         if ((sync = ec_slave_get_pdo_sync(sc->slave, dir)))
   243         sync_config = &sc->sync_configs[sync_index];
   243             ec_pdo_list_copy(pdos, &sync->pdos);
   244         if ((sync = ec_slave_get_sync(sc->slave, sync_index))) {
       
   245             sync_config->dir = ec_sync_default_direction(sync);
       
   246             if (sync_config->dir == EC_DIR_INVALID)
       
   247                 EC_WARN("SM%u of slave %u has an invalid direction field!\n",
       
   248                         sync_index, sc->slave->ring_position);
       
   249             ec_pdo_list_copy(&sync_config->pdos, &sync->pdos);
       
   250         }
   244     }
   251     }
   245 }
   252 }
   246 
   253 
   247 /*****************************************************************************/
   254 /*****************************************************************************/
   248 
   255 
   251 void ec_slave_config_load_default_mapping(
   258 void ec_slave_config_load_default_mapping(
   252         const ec_slave_config_t *sc,
   259         const ec_slave_config_t *sc,
   253         ec_pdo_t *pdo
   260         ec_pdo_t *pdo
   254         )
   261         )
   255 {
   262 {
       
   263     unsigned int i;
   256     const ec_sync_t *sync;
   264     const ec_sync_t *sync;
   257     const ec_pdo_t *default_pdo;
   265     const ec_pdo_t *default_pdo;
   258 
   266 
   259     if (sc->master->debug_level)
   267     if (!sc->slave)
   260         EC_DBG("Loading default configuration for Pdo 0x%04X in"
       
   261                 " config %u:%u.\n", pdo->index, sc->alias, sc->position);
       
   262 
       
   263     if (!sc->slave) {
       
   264         if (sc->master->debug_level)
       
   265             EC_DBG("Failed to load default Pdo configuration for %u:%u:"
       
   266                     " Slave not found.\n", sc->alias, sc->position);
       
   267         return;
   268         return;
   268     }
   269 
   269 
   270     if (sc->master->debug_level)
   270     if (!(sync = ec_slave_get_pdo_sync(sc->slave, pdo->dir))) {
   271         EC_DBG("Loading default mapping for Pdo 0x%04X in config %u:%u.\n",
   271         if (sc->master->debug_level)
   272                 pdo->index, sc->alias, sc->position);
   272             EC_DBG("Slave %u does not provide a default Pdo"
   273 
   273                     " configuration!\n", sc->slave->ring_position);
   274     // find Pdo in any sync manager (it could be reassigned later)
   274         return;
   275     for (i = 0; i < sc->slave->sii.sync_count; i++) {
   275     }
   276         sync = &sc->slave->sii.syncs[i];
   276 
   277 
   277     list_for_each_entry(default_pdo, &sync->pdos.list, list) {
   278         list_for_each_entry(default_pdo, &sync->pdos.list, list) {
   278         if (default_pdo->index != pdo->index)
   279             if (default_pdo->index != pdo->index)
   279             continue;
   280                 continue;
   280 
   281 
   281         if (sc->master->debug_level)
   282             if (default_pdo->name) {
   282             EC_DBG("  Found Pdo name \"%s\".\n",
   283                 if (sc->master->debug_level)
   283                     default_pdo->name);
   284                     EC_DBG("Found Pdo name \"%s\".\n", default_pdo->name);
   284 
   285 
   285         // try to take Pdo name from mapped one
   286                 // take Pdo name from assigned one
   286         ec_pdo_set_name(pdo, default_pdo->name);
   287                 ec_pdo_set_name(pdo, default_pdo->name);
   287 
   288             }
   288         // copy entries (= default Pdo configuration)
   289 
   289         if (ec_pdo_copy_entries(pdo, default_pdo))
   290             // copy entries (= default Pdo mapping)
       
   291             if (ec_pdo_copy_entries(pdo, default_pdo))
       
   292                 return;
       
   293 
       
   294             if (sc->master->debug_level) {
       
   295                 const ec_pdo_entry_t *entry;
       
   296                 list_for_each_entry(entry, &pdo->entries, list) {
       
   297                     EC_DBG("Entry 0x%04X:%02X.\n",
       
   298                             entry->index, entry->subindex);
       
   299                 }
       
   300             }
       
   301 
   290             return;
   302             return;
   291 
       
   292         if (sc->master->debug_level) {
       
   293             const ec_pdo_entry_t *entry;
       
   294             list_for_each_entry(entry, &pdo->entries, list) {
       
   295                 EC_DBG("    Entry 0x%04X:%02X.\n",
       
   296                         entry->index, entry->subindex);
       
   297             }
       
   298         }
   303         }
   299     }
   304     }
       
   305 
       
   306     if (sc->master->debug_level)
       
   307         EC_DBG("No default mapping found.\n");
   300 }
   308 }
   301 
   309 
   302 /*****************************************************************************/
   310 /*****************************************************************************/
   303 
   311 
   304 unsigned int ec_slave_config_sdo_count(
   312 unsigned int ec_slave_config_sdo_count(
   339 
   347 
   340 /******************************************************************************
   348 /******************************************************************************
   341  *  Realtime interface
   349  *  Realtime interface
   342  *****************************************************************************/
   350  *****************************************************************************/
   343 
   351 
       
   352 int ecrt_slave_config_sync_manager(ec_slave_config_t *sc, uint8_t sync_index,
       
   353         ec_direction_t dir)
       
   354 {
       
   355     ec_sync_config_t *sync_config;
       
   356     
       
   357     if (sc->master->debug_level)
       
   358         EC_DBG("ecrt_slave_config_sync_manager(sc = 0x%x, sync_index = %u, "
       
   359                 "dir = %u)\n", (u32) sc, sync_index, dir);
       
   360 
       
   361     if (sync_index >= EC_MAX_SYNCS) {
       
   362         EC_ERR("Invalid sync manager index %u!\n", sync_index);
       
   363         return -1;
       
   364     }
       
   365 
       
   366     if (dir != EC_DIR_OUTPUT && dir != EC_DIR_INPUT) {
       
   367         EC_ERR("Invalid direction %u!\n", (u32) dir);
       
   368         return -1;
       
   369     }
       
   370 
       
   371     sync_config = &sc->sync_configs[sync_index];
       
   372     sync_config->dir = dir;
       
   373     return 0;
       
   374 }
       
   375 
       
   376 /*****************************************************************************/
       
   377 
   344 int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc,
   378 int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc,
   345         ec_direction_t dir, uint16_t index)
   379         uint8_t sync_index, uint16_t pdo_index)
   346 {
   380 {
   347     ec_pdo_list_t *pl = &sc->pdos[dir];
       
   348     ec_pdo_t *pdo;
   381     ec_pdo_t *pdo;
   349     
   382 
   350     if (sc->master->debug_level)
   383     if (sc->master->debug_level)
   351         EC_DBG("Adding Pdo 0x%04X to assignment for dir %u, config %u:%u.\n",
   384         EC_DBG("ecrt_slave_config_pdo_assign_add(sc = 0x%x, sync_index = %u, "
   352                 index, dir, sc->alias, sc->position);
   385                 "pdo_index = 0x%04X)\n", (u32) sc, sync_index, pdo_index);
   353 
   386 
   354     if (!(pdo = ec_pdo_list_add_pdo(pl, dir, index)))
   387     if (sync_index >= EC_MAX_SYNCS) {
   355         return -1;
   388         EC_ERR("Invalid sync manager index %u!\n", sync_index);
       
   389         return -1;
       
   390     }
       
   391 
       
   392     if (!(pdo = ec_pdo_list_add_pdo(&sc->sync_configs[sync_index].pdos, pdo_index)))
       
   393         return -1;
       
   394     pdo->sync_index = sync_index;
   356 
   395 
   357     ec_slave_config_load_default_mapping(sc, pdo);
   396     ec_slave_config_load_default_mapping(sc, pdo);
   358     return 0;
   397     return 0;
   359 }
   398 }
   360 
   399 
   361 /*****************************************************************************/
   400 /*****************************************************************************/
   362 
   401 
   363 void ecrt_slave_config_pdo_assign_clear(ec_slave_config_t *sc,
   402 void ecrt_slave_config_pdo_assign_clear(ec_slave_config_t *sc,
   364         ec_direction_t dir)
   403         uint8_t sync_index)
   365 {
   404 {
   366     if (sc->master->debug_level)
   405     if (sc->master->debug_level)
   367         EC_DBG("Clearing Pdo assignment for dir %u, config %u:%u.\n",
   406         EC_DBG("ecrt_slave_config_pdo_assign_clear(sc = 0x%x, "
   368                 dir, sc->alias, sc->position);
   407                 "sync_index = %u)\n", (u32) sc, sync_index);
   369 
   408 
   370     ec_pdo_list_clear_pdos(&sc->pdos[dir]);
   409     if (sync_index >= EC_MAX_SYNCS) {
       
   410         EC_ERR("Invalid sync manager index %u!\n", sync_index);
       
   411         return;
       
   412     }
       
   413 
       
   414     ec_pdo_list_clear_pdos(&sc->sync_configs[sync_index].pdos);
   371 }
   415 }
   372 
   416 
   373 /*****************************************************************************/
   417 /*****************************************************************************/
   374 
   418 
   375 int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc,
   419 int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc,
   376         uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex,
   420         uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex,
   377         uint8_t entry_bit_length)
   421         uint8_t entry_bit_length)
   378 {
   422 {
   379     ec_direction_t dir;
   423     uint8_t sync_index;
   380     ec_pdo_t *pdo;
   424     ec_pdo_t *pdo = NULL;
   381     
   425     
   382     if (sc->master->debug_level)
   426     if (sc->master->debug_level)
   383         EC_DBG("Adding Pdo entry 0x%04X:%02X (%u bit) to mapping of Pdo"
   427         EC_DBG("ecrt_slave_config_pdo_mapping_add(sc = 0x%x, "
   384                 " 0x%04X, config %u:%u.\n", entry_index, entry_subindex,
   428                 "pdo_index = 0x%04X, entry_index = 0x%04X, "
   385                 entry_bit_length, pdo_index, sc->alias, sc->position);
   429                 "entry_subindex = 0x%02X, entry_bit_length = %u)\n",
   386 
   430                 (u32) sc, pdo_index, entry_index, entry_subindex,
   387     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
   431                 entry_bit_length);
   388         if ((pdo = ec_pdo_list_find_pdo(&sc->pdos[dir], pdo_index)))
   432 
       
   433     for (sync_index = 0; sync_index < EC_MAX_SYNCS; sync_index++)
       
   434         if ((pdo = ec_pdo_list_find_pdo(
       
   435                         &sc->sync_configs[sync_index].pdos, pdo_index)))
   389             break;
   436             break;
   390 
   437 
   391     if (!pdo) {
   438     if (!pdo) {
   392         EC_ERR("Pdo 0x%04X is not assigned in config %u:%u.\n",
   439         EC_ERR("Pdo 0x%04X is not assigned in config %u:%u.\n",
   393                 pdo_index, sc->alias, sc->position);
   440                 pdo_index, sc->alias, sc->position);
   401 /*****************************************************************************/
   448 /*****************************************************************************/
   402 
   449 
   403 void ecrt_slave_config_pdo_mapping_clear(ec_slave_config_t *sc,
   450 void ecrt_slave_config_pdo_mapping_clear(ec_slave_config_t *sc,
   404         uint16_t pdo_index)
   451         uint16_t pdo_index)
   405 {
   452 {
   406     ec_direction_t dir;
   453     uint8_t sync_index;
   407     ec_pdo_t *pdo;
   454     ec_pdo_t *pdo = NULL;
   408     
   455     
   409     if (sc->master->debug_level)
   456     if (sc->master->debug_level)
   410         EC_DBG("Clearing mapping of Pdo 0x%04X, config %u:%u.\n",
   457         EC_DBG("ecrt_slave_config_pdo_mapping_clear(sc = 0x%x, "
   411                 pdo_index, sc->alias, sc->position);
   458                 "pdo_index = 0x%04X)\n", (u32) sc, pdo_index);
   412 
   459 
   413     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
   460     for (sync_index = 0; sync_index < EC_MAX_SYNCS; sync_index++)
   414         if ((pdo = ec_pdo_list_find_pdo(&sc->pdos[dir], pdo_index)))
   461         if ((pdo = ec_pdo_list_find_pdo(
       
   462                         &sc->sync_configs[sync_index].pdos, pdo_index)))
   415             break;
   463             break;
   416 
   464 
   417     if (!pdo) {
   465     if (!pdo) {
   418         EC_WARN("Pdo 0x%04X is not assigned in config %u:%u.\n",
   466         EC_WARN("Pdo 0x%04X is not assigned in config %u:%u.\n",
   419                 pdo_index, sc->alias, sc->position);
   467                 pdo_index, sc->alias, sc->position);
   423     ec_pdo_clear_entries(pdo);
   471     ec_pdo_clear_entries(pdo);
   424 }
   472 }
   425 
   473 
   426 /*****************************************************************************/
   474 /*****************************************************************************/
   427 
   475 
   428 int ecrt_slave_config_pdos(ec_slave_config_t *sc, unsigned int n_infos,
   476 int ecrt_slave_config_sync_managers(ec_slave_config_t *sc,
   429         const ec_pdo_info_t pdo_infos[])
   477         unsigned int n_syncs, const ec_sync_info_t syncs[])
   430 {
   478 {
   431     unsigned int i, j;
   479     unsigned int i, j, k;
   432     const ec_pdo_info_t *pi;
   480     const ec_sync_info_t *sync_info;
   433     ec_pdo_list_t *pl;
   481     const ec_pdo_info_t *pdo_info;
   434     unsigned int cleared[] = {0, 0};
   482     const ec_pdo_entry_info_t *entry_info;
   435     const ec_pdo_entry_info_t *ei;
   483 
   436 
   484     if (sc->master->debug_level)
   437     if (!pdo_infos)
   485         EC_DBG("ecrt_slave_config_sync_managers(sc = 0x%x, n_syncs = %u, "
       
   486                 "syncs = 0x%x)\n", (u32) sc, n_syncs, (u32) syncs);
       
   487 
       
   488     if (!syncs)
   438         return 0;
   489         return 0;
   439 
   490 
   440     for (i = 0; i < n_infos; i++) {
   491     for (i = 0; i < n_syncs; i++) {
   441         pi = &pdo_infos[i];
   492         sync_info = &syncs[i];
   442 
   493 
   443         if (pi->dir == EC_END)
   494         if (sync_info->index == 0xff)
   444             break;
   495             break;
   445 
   496 
   446         pl = &sc->pdos[pi->dir];
   497         if (sync_info->index >= EC_MAX_SYNCS) {
   447 
   498             EC_ERR("Invalid sync manager index %u!\n", sync_info->index);
   448         if (!cleared[pi->dir]) {
   499             return -1;
   449             ecrt_slave_config_pdo_assign_clear(sc, pi->dir);
       
   450             cleared[pi->dir] = 1;
       
   451         }
   500         }
   452 
   501 
   453         if (ecrt_slave_config_pdo_assign_add(sc, pi->dir, pi->index))
   502         if (ecrt_slave_config_sync_manager(
       
   503                     sc, sync_info->index, sync_info->dir))
   454             return -1;
   504             return -1;
   455 
   505 
   456         if (pi->n_entries && pi->entries) { // mapping provided
   506         if (sync_info->n_pdos && sync_info->pdos) {
   457             if (sc->master->debug_level)
   507             ecrt_slave_config_pdo_assign_clear(sc, sync_info->index);
   458                 EC_DBG("  Pdo mapping information provided.\n");
   508 
   459 
   509             for (j = 0; j < sync_info->n_pdos; j++) {
   460             ecrt_slave_config_pdo_mapping_clear(sc, pi->index);
   510                 pdo_info = &sync_info->pdos[j];
   461 
   511 
   462             for (j = 0; j < pi->n_entries; j++) {
   512                 if (ecrt_slave_config_pdo_assign_add(
   463                 ei = &pi->entries[j];
   513                             sc, sync_info->index, pdo_info->index))
   464 
       
   465                 if (ecrt_slave_config_pdo_mapping_add(sc, pi->index,
       
   466                         ei->index, ei->subindex, ei->bit_length))
       
   467                     return -1;
   514                     return -1;
       
   515 
       
   516                 if (pdo_info->n_entries && pdo_info->entries) {
       
   517                     ecrt_slave_config_pdo_mapping_clear(sc, pdo_info->index);
       
   518 
       
   519                     for (k = 0; k < pdo_info->n_entries; k++) {
       
   520                         entry_info = &pdo_info->entries[k];
       
   521 
       
   522                         if (ecrt_slave_config_pdo_mapping_add(sc,
       
   523                                     pdo_info->index, entry_info->index,
       
   524                                     entry_info->subindex,
       
   525                                     entry_info->bit_length))
       
   526                             return -1;
       
   527                     }
       
   528                 }
   468             }
   529             }
   469         }
   530         }
   470     }
   531     }
   471 
   532 
   472     return 0;
   533     return 0;
   480         uint8_t subindex,
   541         uint8_t subindex,
   481         ec_domain_t *domain,
   542         ec_domain_t *domain,
   482         unsigned int *bit_position
   543         unsigned int *bit_position
   483         )
   544         )
   484 {
   545 {
   485     ec_direction_t dir;
   546     uint8_t sync_index;
   486     ec_pdo_list_t *pdos;
   547     const ec_sync_config_t *sync_config;
   487     unsigned int bit_offset, bit_pos;
   548     unsigned int bit_offset, bit_pos;
   488     ec_pdo_t *pdo;
   549     ec_pdo_t *pdo;
   489     ec_pdo_entry_t *entry;
   550     ec_pdo_entry_t *entry;
   490     int sync_offset;
   551     int sync_offset;
   491 
   552 
   492     if (sc->master->debug_level)
   553     if (sc->master->debug_level)
   493         EC_DBG("ecrt_slave_config_reg_pdo_entry(sc = 0x%x, index = 0x%04X, "
   554         EC_DBG("ecrt_slave_config_reg_pdo_entry(sc = 0x%x, index = 0x%04X, "
   494                 "subindex = 0x%02X, domain = 0x%x, bit_position = 0x%x)\n",
   555                 "subindex = 0x%02X, domain = 0x%x, bit_position = 0x%x)\n",
   495                 (unsigned int) sc, index, subindex, (unsigned int) domain,
   556                 (u32) sc, index, subindex, (u32) domain, (u32) bit_position);
   496                 (unsigned int) bit_position);
   557 
   497 
   558     for (sync_index = 0; sync_index < EC_MAX_SYNCS; sync_index++) {
   498     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
   559         sync_config = &sc->sync_configs[sync_index];
   499         pdos = &sc->pdos[dir];
       
   500         bit_offset = 0;
   560         bit_offset = 0;
   501         list_for_each_entry(pdo, &pdos->list, list) {
   561 
       
   562         list_for_each_entry(pdo, &sync_config->pdos.list, list) {
   502             list_for_each_entry(entry, &pdo->entries, list) {
   563             list_for_each_entry(entry, &pdo->entries, list) {
   503                 if (entry->index != index || entry->subindex != subindex) {
   564                 if (entry->index != index || entry->subindex != subindex) {
   504                     bit_offset += entry->bit_length;
   565                     bit_offset += entry->bit_length;
   505                 } else {
   566                 } else {
   506                     goto found;
   567                     sync_offset = ec_slave_config_prepare_fmmu(
       
   568                             sc, domain, sync_index, sync_config->dir);
       
   569                     if (sync_offset < 0)
       
   570                         return -2;
       
   571 
       
   572                     bit_pos = bit_offset % 8;
       
   573                     if (bit_position) {
       
   574                         *bit_position = bit_pos;
       
   575                     } else if (bit_pos) {
       
   576                         EC_ERR("Pdo entry 0x%04X:%02X does not byte-align "
       
   577                                 "in config %u:%u.\n", index, subindex,
       
   578                                 sc->alias, sc->position);
       
   579                         return -3;
       
   580                     }
       
   581 
       
   582                     return sync_offset + bit_offset / 8;
   507                 }
   583                 }
   508             }
   584             }
   509         }
   585         }
   510     }
   586     }
   511 
   587 
   512     EC_ERR("Pdo entry 0x%04X:%02X is not mapped in slave config %u:%u.\n",
   588     EC_ERR("Pdo entry 0x%04X:%02X is not mapped in slave config %u:%u.\n",
   513            index, subindex, sc->alias, sc->position);
   589            index, subindex, sc->alias, sc->position);
   514     return -1;
   590     return -1;
   515 
       
   516 found:
       
   517     sync_offset = ec_slave_config_prepare_fmmu(sc, domain, dir);
       
   518     if (sync_offset < 0)
       
   519         return -2;
       
   520 
       
   521     bit_pos = bit_offset % 8;
       
   522     if (bit_position) {
       
   523         *bit_position = bit_pos;
       
   524     } else if (bit_pos) {
       
   525         EC_ERR("Pdo entry 0x%04X:%02X does not byte-align in config %u:%u.\n",
       
   526                 index, subindex, sc->alias, sc->position);
       
   527         return -3;
       
   528     }
       
   529 
       
   530     return sync_offset + bit_offset / 8;
       
   531 }
   591 }
   532 
   592 
   533 
   593 
   534 /*****************************************************************************/
   594 /*****************************************************************************/
   535 
   595 
   641 
   701 
   642 /*****************************************************************************/
   702 /*****************************************************************************/
   643 
   703 
   644 /** \cond */
   704 /** \cond */
   645 
   705 
       
   706 EXPORT_SYMBOL(ecrt_slave_config_sync_manager);
   646 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_add);
   707 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_add);
   647 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_clear);
   708 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_clear);
   648 EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_add);
   709 EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_add);
   649 EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_clear);
   710 EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_clear);
   650 EXPORT_SYMBOL(ecrt_slave_config_pdos);
   711 EXPORT_SYMBOL(ecrt_slave_config_sync_managers);
   651 EXPORT_SYMBOL(ecrt_slave_config_reg_pdo_entry);
   712 EXPORT_SYMBOL(ecrt_slave_config_reg_pdo_entry);
   652 EXPORT_SYMBOL(ecrt_slave_config_sdo);
   713 EXPORT_SYMBOL(ecrt_slave_config_sdo);
   653 EXPORT_SYMBOL(ecrt_slave_config_sdo8);
   714 EXPORT_SYMBOL(ecrt_slave_config_sdo8);
   654 EXPORT_SYMBOL(ecrt_slave_config_sdo16);
   715 EXPORT_SYMBOL(ecrt_slave_config_sdo16);
   655 EXPORT_SYMBOL(ecrt_slave_config_sdo32);
   716 EXPORT_SYMBOL(ecrt_slave_config_sdo32);