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); |