master/slave_config.c
changeset 879 9b395c5646ab
parent 878 40c379697ebf
child 893 d921fff3d6e2
equal deleted inserted replaced
878:40c379697ebf 879:9b395c5646ab
   100     sc->vendor_id = vendor_id;
   100     sc->vendor_id = vendor_id;
   101     sc->product_code = product_code;
   101     sc->product_code = product_code;
   102     sc->slave = NULL;
   102     sc->slave = NULL;
   103 
   103 
   104     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
   104     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
   105         ec_pdo_mapping_init(&sc->mapping[dir]);
   105         ec_pdo_list_init(&sc->pdos[dir]);
   106 
   106 
   107     INIT_LIST_HEAD(&sc->sdo_configs);
   107     INIT_LIST_HEAD(&sc->sdo_configs);
   108     INIT_LIST_HEAD(&sc->sdo_requests);
   108     INIT_LIST_HEAD(&sc->sdo_requests);
   109 
   109 
   110     sc->used_fmmus = 0;
   110     sc->used_fmmus = 0;
   164 
   164 
   165     sc = container_of(kobj, ec_slave_config_t, kobj);
   165     sc = container_of(kobj, ec_slave_config_t, kobj);
   166 
   166 
   167     // Free Pdo mappings
   167     // Free Pdo mappings
   168     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
   168     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
   169         ec_pdo_mapping_clear(&sc->mapping[dir]);
   169         ec_pdo_list_clear(&sc->pdos[dir]);
   170 
   170 
   171     // free all Sdo configurations
   171     // free all Sdo configurations
   172     list_for_each_entry_safe(req, next_req, &sc->sdo_configs, list) {
   172     list_for_each_entry_safe(req, next_req, &sc->sdo_configs, list) {
   173         list_del(&req->list);
   173         list_del(&req->list);
   174         ec_sdo_request_clear(req);
   174         ec_sdo_request_clear(req);
   234         char *buffer /**< Output buffer */
   234         char *buffer /**< Output buffer */
   235         )
   235         )
   236 {
   236 {
   237     char *buf = buffer;
   237     char *buf = buffer;
   238     ec_direction_t dir;
   238     ec_direction_t dir;
   239     const ec_pdo_mapping_t *map;
   239     const ec_pdo_list_t *pdos;
   240     const ec_pdo_t *pdo;
   240     const ec_pdo_t *pdo;
   241     const ec_pdo_entry_t *entry;
   241     const ec_pdo_entry_t *entry;
   242     char str[20];
   242     char str[20];
   243     const ec_sdo_request_t *req;
   243     const ec_sdo_request_t *req;
   244 
   244 
   245     buf += sprintf(buf, "Alias: 0x%04X (%u)\n", sc->alias, sc->alias);
   245     buf += sprintf(buf, "Alias: 0x%04X (%u)\n", sc->alias, sc->alias);
   246     buf += sprintf(buf, "Position: %u\n", sc->position);
   246     buf += sprintf(buf, "Position: %u\n", sc->position);
   247 
   247 
   248     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
   248     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
   249         map = &sc->mapping[dir];
   249         pdos = &sc->pdos[dir];
   250         
   250         
   251         if (!list_empty(&map->pdos)) {
   251         if (!list_empty(&pdos->list)) {
   252             buf += sprintf(buf, "%s mapping:\n",
   252             buf += sprintf(buf, "%s Pdo assignment / mapping:\n",
   253                     dir == EC_DIR_OUTPUT ? "Output" : "Input");
   253                     dir == EC_DIR_OUTPUT ? "Output" : "Input");
   254 
   254 
   255             list_for_each_entry(pdo, &map->pdos, list) {
   255             list_for_each_entry(pdo, &pdos->list, list) {
   256                 buf += sprintf(buf, "  %s 0x%04X \"%s\"\n",
   256                 buf += sprintf(buf, "  %s 0x%04X \"%s\"\n",
   257                         pdo->dir == EC_DIR_OUTPUT ? "RxPdo" : "TxPdo",
   257                         pdo->dir == EC_DIR_OUTPUT ? "RxPdo" : "TxPdo",
   258                         pdo->index, pdo->name ? pdo->name : "???");
   258                         pdo->index, pdo->name ? pdo->name : "???");
   259 
   259 
   260                 list_for_each_entry(entry, &pdo->entries, list) {
   260                 list_for_each_entry(entry, &pdo->entries, list) {
   427     }
   427     }
   428 }
   428 }
   429 
   429 
   430 /*****************************************************************************/
   430 /*****************************************************************************/
   431 
   431 
   432 /** Loads the default mapping from the slave object.
   432 /** Loads the default Pdo assignment from the slave object.
   433  */
   433  */
   434 void ec_slave_config_load_default_mapping(ec_slave_config_t *sc)
   434 void ec_slave_config_load_default_assignment(ec_slave_config_t *sc)
   435 {
   435 {
   436     ec_direction_t dir;
   436     ec_direction_t dir;
   437     ec_pdo_mapping_t *map;
   437     ec_pdo_list_t *pdos;
   438     ec_sync_t *sync;
   438     ec_sync_t *sync;
   439 
   439 
   440     if (!sc->slave)
   440     if (!sc->slave)
   441         return;
   441         return;
   442     
   442     
   443     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
   443     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
   444         map = &sc->mapping[dir];
   444         pdos = &sc->pdos[dir];
   445         if (!(sync = ec_slave_get_pdo_sync(sc->slave, dir)))
   445         if ((sync = ec_slave_get_pdo_sync(sc->slave, dir)))
   446             continue;
   446             ec_pdo_list_copy(pdos, &sync->pdos);
   447         ec_pdo_mapping_copy(map, &sync->mapping);
   447     }
   448         map->default_mapping = 1;
   448 }
   449     }
   449 
   450 }
   450 /*****************************************************************************/
   451 
   451 
   452 /*****************************************************************************/
   452 /** Loads the default mapping for a Pdo from the slave object.
   453 
   453  */
   454 /** Loads the default configuration for a Pdo from the slave object.
   454 void ec_slave_config_load_default_mapping(
   455  */
       
   456 void ec_slave_config_load_default_pdo_config(
       
   457         const ec_slave_config_t *sc,
   455         const ec_slave_config_t *sc,
   458         ec_pdo_t *pdo
   456         ec_pdo_t *pdo
   459         )
   457         )
   460 {
   458 {
   461     const ec_sync_t *sync;
   459     const ec_sync_t *sync;
   477         EC_WARN("Slave %u does not provide a default Pdo"
   475         EC_WARN("Slave %u does not provide a default Pdo"
   478                 " configuration!\n", sc->slave->ring_position);
   476                 " configuration!\n", sc->slave->ring_position);
   479         return;
   477         return;
   480     }
   478     }
   481 
   479 
   482     list_for_each_entry(default_pdo, &sync->mapping.pdos, list) {
   480     list_for_each_entry(default_pdo, &sync->pdos.list, list) {
   483         if (default_pdo->index != pdo->index)
   481         if (default_pdo->index != pdo->index)
   484             continue;
   482             continue;
   485 
   483 
   486         if (sc->master->debug_level)
   484         if (sc->master->debug_level)
   487             EC_DBG("  Found Pdo name \"%s\".\n",
   485             EC_DBG("  Found Pdo name \"%s\".\n",
   506 
   504 
   507 /******************************************************************************
   505 /******************************************************************************
   508  *  Realtime interface
   506  *  Realtime interface
   509  *****************************************************************************/
   507  *****************************************************************************/
   510 
   508 
   511 int ecrt_slave_config_pdo(ec_slave_config_t *sc, ec_direction_t dir,
   509 int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc,
   512         uint16_t index)
   510         ec_direction_t dir, uint16_t index)
   513 {
   511 {
   514     ec_pdo_mapping_t *pm = &sc->mapping[dir];
   512     ec_pdo_list_t *pl = &sc->pdos[dir];
   515     ec_pdo_t *pdo;
   513     ec_pdo_t *pdo;
   516     
   514     
   517     if (pm->default_mapping) {
       
   518         if (sc->master->debug_level)
       
   519             EC_DBG("Clearing default mapping for dir %u, config %u:%u.\n",
       
   520                     dir, sc->alias, sc->position);
       
   521         pm->default_mapping = 0;
       
   522         ec_pdo_mapping_clear_pdos(pm);
       
   523     }
       
   524 
       
   525     if (sc->master->debug_level)
   515     if (sc->master->debug_level)
   526         EC_DBG("Adding Pdo 0x%04X to mapping for dir %u, config %u:%u.\n",
   516         EC_DBG("Adding Pdo 0x%04X to assignment for dir %u, config %u:%u.\n",
   527                 index, dir, sc->alias, sc->position);
   517                 index, dir, sc->alias, sc->position);
   528 
   518 
   529     if (!(pdo = ec_pdo_mapping_add_pdo(pm, dir, index)))
   519     if (!(pdo = ec_pdo_list_add_pdo(pl, dir, index)))
   530         return -1;
   520         return -1;
   531 
   521 
   532     ec_slave_config_load_default_pdo_config(sc, pdo);
   522     ec_slave_config_load_default_mapping(sc, pdo);
   533     return 0;
   523     return 0;
   534 }
   524 }
   535 
   525 
   536 /*****************************************************************************/
   526 /*****************************************************************************/
   537 
   527 
   538 int ecrt_slave_config_pdo_entry(ec_slave_config_t *sc, uint16_t pdo_index,
   528 void ecrt_slave_config_pdo_assign_clear(ec_slave_config_t *sc,
   539         uint16_t entry_index, uint8_t entry_subindex,
   529         ec_direction_t dir)
       
   530 {
       
   531     if (sc->master->debug_level)
       
   532         EC_DBG("Clearing Pdo assignment for dir %u, config %u:%u.\n",
       
   533                 dir, sc->alias, sc->position);
       
   534 
       
   535     ec_pdo_list_clear_pdos(&sc->pdos[dir]);
       
   536 }
       
   537 
       
   538 /*****************************************************************************/
       
   539 
       
   540 int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc,
       
   541         uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex,
   540         uint8_t entry_bit_length)
   542         uint8_t entry_bit_length)
   541 {
   543 {
   542     ec_direction_t dir;
   544     ec_direction_t dir;
   543     ec_pdo_t *pdo;
   545     ec_pdo_t *pdo;
   544     
   546     
   545     if (sc->master->debug_level)
   547     if (sc->master->debug_level)
   546         EC_DBG("Adding Pdo entry 0x%04X:%u (%u bit) to configuration of Pdo"
   548         EC_DBG("Adding Pdo entry 0x%04X:%u (%u bit) to mapping of Pdo"
   547                 " 0x%04X, config %u:%u.\n", entry_index, entry_subindex,
   549                 " 0x%04X, config %u:%u.\n", entry_index, entry_subindex,
   548                 entry_bit_length, pdo_index, sc->alias, sc->position);
   550                 entry_bit_length, pdo_index, sc->alias, sc->position);
   549 
   551 
   550     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
   552     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
   551         if ((pdo = ec_pdo_mapping_find_pdo(&sc->mapping[dir], pdo_index)))
   553         if ((pdo = ec_pdo_list_find_pdo(&sc->pdos[dir], pdo_index)))
   552             break;
   554             break;
   553 
   555 
   554     if (!pdo) {
   556     if (!pdo) {
   555         EC_ERR("Pdo 0x%04X was not found in the mapping of config %u:%u.\n",
   557         EC_ERR("Pdo 0x%04X is not assigned in config %u:%u.\n",
   556                 pdo_index, sc->alias, sc->position);
   558                 pdo_index, sc->alias, sc->position);
   557         return -1;
   559         return -1;
   558     }
   560     }
   559 
   561 
   560     if (pdo->default_config) {
       
   561         if (sc->master->debug_level)
       
   562             EC_DBG("Clearing default configuration of Pdo 0x%04X,"
       
   563                     " config %u:%u.\n", pdo->index, sc->alias, sc->position);
       
   564         pdo->default_config = 0;
       
   565         ec_pdo_clear_entries(pdo);
       
   566     }
       
   567 
       
   568     return ec_pdo_add_entry(pdo, entry_index, entry_subindex,
   562     return ec_pdo_add_entry(pdo, entry_index, entry_subindex,
   569             entry_bit_length) ? 0 : -1;
   563             entry_bit_length) ? 0 : -1;
   570 }
   564 }
   571 
   565 
   572 /*****************************************************************************/
   566 /*****************************************************************************/
   573 
   567 
   574 int ecrt_slave_config_mapping(ec_slave_config_t *sc, unsigned int n_infos,
   568 void ecrt_slave_config_pdo_mapping_clear(ec_slave_config_t *sc,
       
   569         uint16_t pdo_index)
       
   570 {
       
   571     ec_direction_t dir;
       
   572     ec_pdo_t *pdo;
       
   573     
       
   574     if (sc->master->debug_level)
       
   575         EC_DBG("Clearing mapping of Pdo 0x%04X, config %u:%u.\n",
       
   576                 pdo_index, sc->alias, sc->position);
       
   577 
       
   578     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++)
       
   579         if ((pdo = ec_pdo_list_find_pdo(&sc->pdos[dir], pdo_index)))
       
   580             break;
       
   581 
       
   582     if (!pdo) {
       
   583         EC_WARN("Pdo 0x%04X is not assigned in config %u:%u.\n",
       
   584                 pdo_index, sc->alias, sc->position);
       
   585         return;
       
   586     }
       
   587 
       
   588     ec_pdo_clear_entries(pdo);
       
   589 }
       
   590 
       
   591 /*****************************************************************************/
       
   592 
       
   593 int ecrt_slave_config_pdos(ec_slave_config_t *sc, unsigned int n_infos,
   575         const ec_pdo_info_t pdo_infos[])
   594         const ec_pdo_info_t pdo_infos[])
   576 {
   595 {
   577     unsigned int i, j;
   596     unsigned int i, j;
   578     const ec_pdo_info_t *pi;
   597     const ec_pdo_info_t *pi;
   579     ec_pdo_mapping_t *pm;
   598     ec_pdo_list_t *pl;
   580     ec_pdo_t *pdo;
   599     unsigned int cleared[] = {0, 0};
   581     const ec_pdo_entry_info_t *ei;
   600     const ec_pdo_entry_info_t *ei;
   582 
   601 
   583     for (i = 0; i < n_infos; i++) {
   602     for (i = 0; i < n_infos; i++) {
   584         pi = &pdo_infos[i];
   603         pi = &pdo_infos[i];
   585 
   604 
   586         if (pi->dir == EC_MAP_END)
   605         if (pi->dir == EC_END)
   587             break;
   606             break;
   588 
   607 
   589         pm = &sc->mapping[pi->dir];
   608         pl = &sc->pdos[pi->dir];
   590 
   609 
   591         if (pm->default_mapping) {
   610         if (!cleared[pi->dir]) {
       
   611             ecrt_slave_config_pdo_assign_clear(sc, pi->dir);
       
   612             cleared[pi->dir] = 1;
       
   613         }
       
   614 
       
   615         if (ecrt_slave_config_pdo_assign_add(sc, pi->dir, pi->index))
       
   616             return -1;
       
   617 
       
   618         if (pi->n_entries && pi->entries) { // mapping provided
   592             if (sc->master->debug_level)
   619             if (sc->master->debug_level)
   593                 EC_DBG("Clearing default mapping for dir %u, config %u:%u.\n",
   620                 EC_DBG("  Pdo mapping information provided.\n");
   594                         pi->dir, sc->alias, sc->position);
   621 
   595             pm->default_mapping = 0;
   622             ecrt_slave_config_pdo_mapping_clear(sc, pi->index);
   596             ec_pdo_mapping_clear_pdos(pm);
       
   597         }
       
   598 
       
   599         if (sc->master->debug_level)
       
   600             EC_DBG("Adding Pdo 0x%04X to mapping for dir %u, config %u:%u.\n",
       
   601                     pi->index, pi->dir, sc->alias, sc->position);
       
   602 
       
   603         if (!(pdo = ec_pdo_mapping_add_pdo(pm, pi->dir, pi->index)))
       
   604             return -1;
       
   605 
       
   606         if (pi->n_entries && pi->entries) { // configuration provided
       
   607             if (sc->master->debug_level)
       
   608                 EC_DBG("  Pdo configuration information provided.\n");
       
   609 
   623 
   610             for (j = 0; j < pi->n_entries; j++) {
   624             for (j = 0; j < pi->n_entries; j++) {
   611                 ei = &pi->entries[j];
   625                 ei = &pi->entries[j];
   612                 if (!ec_pdo_add_entry(pdo, ei->index, ei->subindex,
   626 
   613                             ei->bit_length))
   627                 if (ecrt_slave_config_pdo_mapping_add(sc, pi->index,
       
   628                         ei->index, ei->subindex, ei->bit_length))
   614                     return -1;
   629                     return -1;
   615             }
   630             }
   616         } else { // use default Pdo configuration
       
   617             ec_slave_config_load_default_pdo_config(sc, pdo);
       
   618         }
   631         }
   619     }
   632     }
   620 
   633 
   621     return 0;
   634     return 0;
   622 }
   635 }
   629         uint8_t subindex, /**< Subindex of Pdo entry to register. */
   642         uint8_t subindex, /**< Subindex of Pdo entry to register. */
   630         ec_domain_t *domain /**< Domain. */
   643         ec_domain_t *domain /**< Domain. */
   631         )
   644         )
   632 {
   645 {
   633     ec_direction_t dir;
   646     ec_direction_t dir;
   634     ec_pdo_mapping_t *map;
   647     ec_pdo_list_t *pdos;
   635     unsigned int bit_offset, byte_offset;
   648     unsigned int bit_offset, byte_offset;
   636     ec_pdo_t *pdo;
   649     ec_pdo_t *pdo;
   637     ec_pdo_entry_t *entry;
   650     ec_pdo_entry_t *entry;
   638     int ret;
   651     int ret;
   639 
   652 
   640     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
   653     for (dir = EC_DIR_OUTPUT; dir <= EC_DIR_INPUT; dir++) {
   641         map = &sc->mapping[dir];
   654         pdos = &sc->pdos[dir];
   642         bit_offset = 0;
   655         bit_offset = 0;
   643         list_for_each_entry(pdo, &map->pdos, list) {
   656         list_for_each_entry(pdo, &pdos->list, list) {
   644             list_for_each_entry(entry, &pdo->entries, list) {
   657             list_for_each_entry(entry, &pdo->entries, list) {
   645                 if (entry->index != index || entry->subindex != subindex) {
   658                 if (entry->index != index || entry->subindex != subindex) {
   646                     bit_offset += entry->bit_length;
   659                     bit_offset += entry->bit_length;
   647                 } else {
   660                 } else {
   648                     goto found;
   661                     goto found;
   724 
   737 
   725 /*****************************************************************************/
   738 /*****************************************************************************/
   726 
   739 
   727 /** \cond */
   740 /** \cond */
   728 
   741 
   729 EXPORT_SYMBOL(ecrt_slave_config_pdo);
   742 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_add);
   730 EXPORT_SYMBOL(ecrt_slave_config_pdo_entry);
   743 EXPORT_SYMBOL(ecrt_slave_config_pdo_assign_clear);
   731 EXPORT_SYMBOL(ecrt_slave_config_mapping);
   744 EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_add);
       
   745 EXPORT_SYMBOL(ecrt_slave_config_pdo_mapping_clear);
       
   746 EXPORT_SYMBOL(ecrt_slave_config_pdos);
   732 EXPORT_SYMBOL(ecrt_slave_config_reg_pdo_entry);
   747 EXPORT_SYMBOL(ecrt_slave_config_reg_pdo_entry);
   733 EXPORT_SYMBOL(ecrt_slave_config_sdo8);
   748 EXPORT_SYMBOL(ecrt_slave_config_sdo8);
   734 EXPORT_SYMBOL(ecrt_slave_config_sdo16);
   749 EXPORT_SYMBOL(ecrt_slave_config_sdo16);
   735 EXPORT_SYMBOL(ecrt_slave_config_sdo32);
   750 EXPORT_SYMBOL(ecrt_slave_config_sdo32);
   736 EXPORT_SYMBOL(ecrt_slave_config_create_sdo_request);
   751 EXPORT_SYMBOL(ecrt_slave_config_create_sdo_request);