40 |
40 |
41 #include "fsm_pdo.h" |
41 #include "fsm_pdo.h" |
42 |
42 |
43 /*****************************************************************************/ |
43 /*****************************************************************************/ |
44 |
44 |
45 void ec_fsm_pdo_read_state_start(ec_fsm_pdo_t *); |
45 void ec_fsm_pdo_read_state_start(ec_fsm_pdo_t *, ec_datagram_t *); |
46 void ec_fsm_pdo_read_state_pdo_count(ec_fsm_pdo_t *); |
46 void ec_fsm_pdo_read_state_pdo_count(ec_fsm_pdo_t *, ec_datagram_t *); |
47 void ec_fsm_pdo_read_state_pdo(ec_fsm_pdo_t *); |
47 void ec_fsm_pdo_read_state_pdo(ec_fsm_pdo_t *, ec_datagram_t *); |
48 void ec_fsm_pdo_read_state_pdo_entries(ec_fsm_pdo_t *); |
48 void ec_fsm_pdo_read_state_pdo_entries(ec_fsm_pdo_t *, ec_datagram_t *); |
49 |
49 |
50 void ec_fsm_pdo_read_action_next_sync(ec_fsm_pdo_t *); |
50 void ec_fsm_pdo_read_action_next_sync(ec_fsm_pdo_t *, ec_datagram_t *); |
51 void ec_fsm_pdo_read_action_next_pdo(ec_fsm_pdo_t *); |
51 void ec_fsm_pdo_read_action_next_pdo(ec_fsm_pdo_t *, ec_datagram_t *); |
52 |
52 |
53 void ec_fsm_pdo_conf_state_start(ec_fsm_pdo_t *); |
53 void ec_fsm_pdo_conf_state_start(ec_fsm_pdo_t *, ec_datagram_t *); |
54 void ec_fsm_pdo_conf_state_read_mapping(ec_fsm_pdo_t *); |
54 void ec_fsm_pdo_conf_state_read_mapping(ec_fsm_pdo_t *, ec_datagram_t *); |
55 void ec_fsm_pdo_conf_state_mapping(ec_fsm_pdo_t *); |
55 void ec_fsm_pdo_conf_state_mapping(ec_fsm_pdo_t *, ec_datagram_t *); |
56 void ec_fsm_pdo_conf_state_zero_pdo_count(ec_fsm_pdo_t *); |
56 void ec_fsm_pdo_conf_state_zero_pdo_count(ec_fsm_pdo_t *, ec_datagram_t *); |
57 void ec_fsm_pdo_conf_state_assign_pdo(ec_fsm_pdo_t *); |
57 void ec_fsm_pdo_conf_state_assign_pdo(ec_fsm_pdo_t *, ec_datagram_t *); |
58 void ec_fsm_pdo_conf_state_set_pdo_count(ec_fsm_pdo_t *); |
58 void ec_fsm_pdo_conf_state_set_pdo_count(ec_fsm_pdo_t *, ec_datagram_t *); |
59 |
59 |
60 void ec_fsm_pdo_conf_action_next_sync(ec_fsm_pdo_t *); |
60 void ec_fsm_pdo_conf_action_next_sync(ec_fsm_pdo_t *, ec_datagram_t *); |
61 void ec_fsm_pdo_conf_action_pdo_mapping(ec_fsm_pdo_t *); |
61 void ec_fsm_pdo_conf_action_pdo_mapping(ec_fsm_pdo_t *, ec_datagram_t *); |
62 void ec_fsm_pdo_conf_action_check_mapping(ec_fsm_pdo_t *); |
62 void ec_fsm_pdo_conf_action_check_mapping(ec_fsm_pdo_t *, ec_datagram_t *); |
63 void ec_fsm_pdo_conf_action_next_pdo_mapping(ec_fsm_pdo_t *); |
63 void ec_fsm_pdo_conf_action_next_pdo_mapping(ec_fsm_pdo_t *, ec_datagram_t *); |
64 void ec_fsm_pdo_conf_action_check_assignment(ec_fsm_pdo_t *); |
64 void ec_fsm_pdo_conf_action_check_assignment(ec_fsm_pdo_t *, ec_datagram_t *); |
65 void ec_fsm_pdo_conf_action_assign_pdo(ec_fsm_pdo_t *); |
65 void ec_fsm_pdo_conf_action_assign_pdo(ec_fsm_pdo_t *, ec_datagram_t *); |
66 |
66 |
67 void ec_fsm_pdo_state_end(ec_fsm_pdo_t *); |
67 void ec_fsm_pdo_state_end(ec_fsm_pdo_t *, ec_datagram_t *); |
68 void ec_fsm_pdo_state_error(ec_fsm_pdo_t *); |
68 void ec_fsm_pdo_state_error(ec_fsm_pdo_t *, ec_datagram_t *); |
69 |
69 |
70 /*****************************************************************************/ |
70 /*****************************************************************************/ |
71 |
71 |
72 /** Constructor. |
72 /** Constructor. |
73 */ |
73 */ |
187 *****************************************************************************/ |
189 *****************************************************************************/ |
188 |
190 |
189 /** Start reading PDO assignment. |
191 /** Start reading PDO assignment. |
190 */ |
192 */ |
191 void ec_fsm_pdo_read_state_start( |
193 void ec_fsm_pdo_read_state_start( |
192 ec_fsm_pdo_t *fsm /**< finite state machine */ |
194 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
|
195 ec_datagram_t *datagram /**< Datagram to use. */ |
193 ) |
196 ) |
194 { |
197 { |
195 // read PDO assignment for first sync manager not reserved for mailbox |
198 // read PDO assignment for first sync manager not reserved for mailbox |
196 fsm->sync_index = 1; // next is 2 |
199 fsm->sync_index = 1; // next is 2 |
197 ec_fsm_pdo_read_action_next_sync(fsm); |
200 ec_fsm_pdo_read_action_next_sync(fsm, datagram); |
198 } |
201 } |
199 |
202 |
200 /*****************************************************************************/ |
203 /*****************************************************************************/ |
201 |
204 |
202 /** Read PDO assignment of next sync manager. |
205 /** Read PDO assignment of next sync manager. |
203 */ |
206 */ |
204 void ec_fsm_pdo_read_action_next_sync( |
207 void ec_fsm_pdo_read_action_next_sync( |
205 ec_fsm_pdo_t *fsm /**< Finite state machine */ |
208 ec_fsm_pdo_t *fsm, /**< finite state machine. */ |
|
209 ec_datagram_t *datagram /**< Datagram to use. */ |
206 ) |
210 ) |
207 { |
211 { |
208 ec_slave_t *slave = fsm->slave; |
212 ec_slave_t *slave = fsm->slave; |
209 |
213 |
210 fsm->sync_index++; |
214 fsm->sync_index++; |
235 /*****************************************************************************/ |
239 /*****************************************************************************/ |
236 |
240 |
237 /** Count assigned PDOs. |
241 /** Count assigned PDOs. |
238 */ |
242 */ |
239 void ec_fsm_pdo_read_state_pdo_count( |
243 void ec_fsm_pdo_read_state_pdo_count( |
240 ec_fsm_pdo_t *fsm /**< finite state machine */ |
244 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
241 ) |
245 ec_datagram_t *datagram /**< Datagram to use. */ |
242 { |
246 ) |
243 if (ec_fsm_coe_exec(fsm->fsm_coe)) return; |
247 { |
|
248 if (ec_fsm_coe_exec(fsm->fsm_coe, datagram)) { |
|
249 return; |
|
250 } |
244 |
251 |
245 if (!ec_fsm_coe_success(fsm->fsm_coe)) { |
252 if (!ec_fsm_coe_success(fsm->fsm_coe)) { |
246 EC_SLAVE_ERR(fsm->slave, "Failed to read number of assigned PDOs" |
253 EC_SLAVE_ERR(fsm->slave, "Failed to read number of assigned PDOs" |
247 " for SM%u.\n", fsm->sync_index); |
254 " for SM%u.\n", fsm->sync_index); |
248 ec_fsm_pdo_read_action_next_sync(fsm); |
255 ec_fsm_pdo_read_action_next_sync(fsm, datagram); |
249 return; |
256 return; |
250 } |
257 } |
251 |
258 |
252 if (fsm->request.data_size != sizeof(uint8_t)) { |
259 if (fsm->request.data_size != sizeof(uint8_t)) { |
253 EC_SLAVE_ERR(fsm->slave, "Invalid data size %zu returned" |
260 EC_SLAVE_ERR(fsm->slave, "Invalid data size %zu returned" |
254 " when uploading SDO 0x%04X:%02X.\n", fsm->request.data_size, |
261 " when uploading SDO 0x%04X:%02X.\n", fsm->request.data_size, |
255 fsm->request.index, fsm->request.subindex); |
262 fsm->request.index, fsm->request.subindex); |
256 ec_fsm_pdo_read_action_next_sync(fsm); |
263 ec_fsm_pdo_read_action_next_sync(fsm, datagram); |
257 return; |
264 return; |
258 } |
265 } |
259 fsm->pdo_count = EC_READ_U8(fsm->request.data); |
266 fsm->pdo_count = EC_READ_U8(fsm->request.data); |
260 |
267 |
261 EC_SLAVE_DBG(fsm->slave, 1, "%u PDOs assigned.\n", fsm->pdo_count); |
268 EC_SLAVE_DBG(fsm->slave, 1, "%u PDOs assigned.\n", fsm->pdo_count); |
262 |
269 |
263 // read first PDO |
270 // read first PDO |
264 fsm->pdo_pos = 1; |
271 fsm->pdo_pos = 1; |
265 ec_fsm_pdo_read_action_next_pdo(fsm); |
272 ec_fsm_pdo_read_action_next_pdo(fsm, datagram); |
266 } |
273 } |
267 |
274 |
268 /*****************************************************************************/ |
275 /*****************************************************************************/ |
269 |
276 |
270 /** Read next PDO. |
277 /** Read next PDO. |
271 */ |
278 */ |
272 void ec_fsm_pdo_read_action_next_pdo( |
279 void ec_fsm_pdo_read_action_next_pdo( |
273 ec_fsm_pdo_t *fsm /**< finite state machine */ |
280 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
|
281 ec_datagram_t *datagram /**< Datagram to use. */ |
274 ) |
282 ) |
275 { |
283 { |
276 if (fsm->pdo_pos <= fsm->pdo_count) { |
284 if (fsm->pdo_pos <= fsm->pdo_count) { |
277 ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync_index, |
285 ecrt_sdo_request_index(&fsm->request, 0x1C10 + fsm->sync_index, |
278 fsm->pdo_pos); |
286 fsm->pdo_pos); |
279 ecrt_sdo_request_read(&fsm->request); |
287 ecrt_sdo_request_read(&fsm->request); |
280 fsm->state = ec_fsm_pdo_read_state_pdo; |
288 fsm->state = ec_fsm_pdo_read_state_pdo; |
281 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); |
289 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); |
282 ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately |
290 ec_fsm_coe_exec(fsm->fsm_coe, datagram); // execute immediately |
283 return; |
291 return; |
284 } |
292 } |
285 |
293 |
286 // finished reading PDO configuration |
294 // finished reading PDO configuration |
287 |
295 |
288 ec_pdo_list_copy(&fsm->sync->pdos, &fsm->pdos); |
296 ec_pdo_list_copy(&fsm->sync->pdos, &fsm->pdos); |
289 ec_pdo_list_clear_pdos(&fsm->pdos); |
297 ec_pdo_list_clear_pdos(&fsm->pdos); |
290 |
298 |
291 // next sync manager |
299 // next sync manager |
292 ec_fsm_pdo_read_action_next_sync(fsm); |
300 ec_fsm_pdo_read_action_next_sync(fsm, datagram); |
293 } |
301 } |
294 |
302 |
295 /*****************************************************************************/ |
303 /*****************************************************************************/ |
296 |
304 |
297 /** Fetch PDO information. |
305 /** Fetch PDO information. |
298 */ |
306 */ |
299 void ec_fsm_pdo_read_state_pdo( |
307 void ec_fsm_pdo_read_state_pdo( |
300 ec_fsm_pdo_t *fsm /**< finite state machine */ |
308 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
301 ) |
309 ec_datagram_t *datagram /**< Datagram to use. */ |
302 { |
310 ) |
303 if (ec_fsm_coe_exec(fsm->fsm_coe)) return; |
311 { |
|
312 if (ec_fsm_coe_exec(fsm->fsm_coe, datagram)) { |
|
313 return; |
|
314 } |
304 |
315 |
305 if (!ec_fsm_coe_success(fsm->fsm_coe)) { |
316 if (!ec_fsm_coe_success(fsm->fsm_coe)) { |
306 EC_SLAVE_ERR(fsm->slave, "Failed to read index of" |
317 EC_SLAVE_ERR(fsm->slave, "Failed to read index of" |
307 " assigned PDO %u from SM%u.\n", |
318 " assigned PDO %u from SM%u.\n", |
308 fsm->pdo_pos, fsm->sync_index); |
319 fsm->pdo_pos, fsm->sync_index); |
309 ec_fsm_pdo_read_action_next_sync(fsm); |
320 ec_fsm_pdo_read_action_next_sync(fsm, datagram); |
310 return; |
321 return; |
311 } |
322 } |
312 |
323 |
313 if (fsm->request.data_size != sizeof(uint16_t)) { |
324 if (fsm->request.data_size != sizeof(uint16_t)) { |
314 EC_SLAVE_ERR(fsm->slave, "Invalid data size %zu returned" |
325 EC_SLAVE_ERR(fsm->slave, "Invalid data size %zu returned" |
315 " when uploading SDO 0x%04X:%02X.\n", fsm->request.data_size, |
326 " when uploading SDO 0x%04X:%02X.\n", fsm->request.data_size, |
316 fsm->request.index, fsm->request.subindex); |
327 fsm->request.index, fsm->request.subindex); |
317 ec_fsm_pdo_read_action_next_sync(fsm); |
328 ec_fsm_pdo_read_action_next_sync(fsm, datagram); |
318 return; |
329 return; |
319 } |
330 } |
320 |
331 |
321 if (!(fsm->pdo = (ec_pdo_t *) |
332 if (!(fsm->pdo = (ec_pdo_t *) |
322 kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) { |
333 kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) { |
323 EC_SLAVE_ERR(fsm->slave, "Failed to allocate PDO.\n"); |
334 EC_SLAVE_ERR(fsm->slave, "Failed to allocate PDO.\n"); |
324 ec_fsm_pdo_read_action_next_sync(fsm); |
335 ec_fsm_pdo_read_action_next_sync(fsm, datagram); |
325 return; |
336 return; |
326 } |
337 } |
327 |
338 |
328 ec_pdo_init(fsm->pdo); |
339 ec_pdo_init(fsm->pdo); |
329 fsm->pdo->index = EC_READ_U16(fsm->request.data); |
340 fsm->pdo->index = EC_READ_U16(fsm->request.data); |
333 |
344 |
334 list_add_tail(&fsm->pdo->list, &fsm->pdos.list); |
345 list_add_tail(&fsm->pdo->list, &fsm->pdos.list); |
335 |
346 |
336 fsm->state = ec_fsm_pdo_read_state_pdo_entries; |
347 fsm->state = ec_fsm_pdo_read_state_pdo_entries; |
337 ec_fsm_pdo_entry_start_reading(&fsm->fsm_pdo_entry, fsm->slave, fsm->pdo); |
348 ec_fsm_pdo_entry_start_reading(&fsm->fsm_pdo_entry, fsm->slave, fsm->pdo); |
338 fsm->state(fsm); // execute immediately |
349 fsm->state(fsm, datagram); // execute immediately |
339 } |
350 } |
340 |
351 |
341 /*****************************************************************************/ |
352 /*****************************************************************************/ |
342 |
353 |
343 /** Fetch PDO information. |
354 /** Fetch PDO information. |
344 */ |
355 */ |
345 void ec_fsm_pdo_read_state_pdo_entries( |
356 void ec_fsm_pdo_read_state_pdo_entries( |
346 ec_fsm_pdo_t *fsm /**< finite state machine */ |
357 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
347 ) |
358 ec_datagram_t *datagram /**< Datagram to use. */ |
348 { |
359 ) |
349 if (ec_fsm_pdo_entry_exec(&fsm->fsm_pdo_entry)) |
360 { |
350 return; |
361 if (ec_fsm_pdo_entry_exec(&fsm->fsm_pdo_entry, datagram)) { |
|
362 return; |
|
363 } |
351 |
364 |
352 if (!ec_fsm_pdo_entry_success(&fsm->fsm_pdo_entry)) { |
365 if (!ec_fsm_pdo_entry_success(&fsm->fsm_pdo_entry)) { |
353 EC_SLAVE_ERR(fsm->slave, "Failed to read mapped PDO entries" |
366 EC_SLAVE_ERR(fsm->slave, "Failed to read mapped PDO entries" |
354 " for PDO 0x%04X.\n", fsm->pdo->index); |
367 " for PDO 0x%04X.\n", fsm->pdo->index); |
355 ec_fsm_pdo_read_action_next_sync(fsm); |
368 ec_fsm_pdo_read_action_next_sync(fsm, datagram); |
356 return; |
369 return; |
357 } |
370 } |
358 |
371 |
359 // next PDO |
372 // next PDO |
360 fsm->pdo_pos++; |
373 fsm->pdo_pos++; |
361 ec_fsm_pdo_read_action_next_pdo(fsm); |
374 ec_fsm_pdo_read_action_next_pdo(fsm, datagram); |
362 } |
375 } |
363 |
376 |
364 /****************************************************************************** |
377 /****************************************************************************** |
365 * Writing state functions. |
378 * Writing state functions. |
366 *****************************************************************************/ |
379 *****************************************************************************/ |
367 |
380 |
368 /** Start PDO configuration. |
381 /** Start PDO configuration. |
369 */ |
382 */ |
370 void ec_fsm_pdo_conf_state_start( |
383 void ec_fsm_pdo_conf_state_start( |
371 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
384 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
|
385 ec_datagram_t *datagram /**< Datagram to use. */ |
372 ) |
386 ) |
373 { |
387 { |
374 if (!fsm->slave->config) { |
388 if (!fsm->slave->config) { |
375 fsm->state = ec_fsm_pdo_state_end; |
389 fsm->state = ec_fsm_pdo_state_end; |
376 return; |
390 return; |
377 } |
391 } |
378 |
392 |
379 fsm->sync_index = 1; // next is 2 |
393 fsm->sync_index = 1; // next is 2 |
380 ec_fsm_pdo_conf_action_next_sync(fsm); |
394 ec_fsm_pdo_conf_action_next_sync(fsm, datagram); |
381 } |
395 } |
382 |
396 |
383 /*****************************************************************************/ |
397 /*****************************************************************************/ |
384 |
398 |
385 /** Assign next PDO. |
399 /** Assign next PDO. |
|
400 * |
|
401 * \return Next PDO, or NULL. |
386 */ |
402 */ |
387 ec_pdo_t *ec_fsm_pdo_conf_action_next_pdo( |
403 ec_pdo_t *ec_fsm_pdo_conf_action_next_pdo( |
388 const ec_fsm_pdo_t *fsm, /**< PDO configuration state machine. */ |
404 const ec_fsm_pdo_t *fsm, /**< PDO configuration state machine. */ |
389 const struct list_head *list /**< current PDO list item */ |
405 const struct list_head *list /**< current PDO list item */ |
390 ) |
406 ) |
391 { |
407 { |
392 list = list->next; |
408 list = list->next; |
393 if (list == &fsm->pdos.list) |
409 if (list == &fsm->pdos.list) |
394 return NULL; // no next PDO |
410 return NULL; // no next PDO |
395 return list_entry(list, ec_pdo_t, list); |
411 return list_entry(list, ec_pdo_t, list); |
396 } |
412 } |
397 |
413 |
398 /*****************************************************************************/ |
414 /*****************************************************************************/ |
399 |
415 |
400 /** Get the next sync manager for a pdo configuration. |
416 /** Get the next sync manager for a pdo configuration. |
401 */ |
417 */ |
402 void ec_fsm_pdo_conf_action_next_sync( |
418 void ec_fsm_pdo_conf_action_next_sync( |
403 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
419 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
|
420 ec_datagram_t *datagram /**< Datagram to use. */ |
404 ) |
421 ) |
405 { |
422 { |
406 fsm->sync_index++; |
423 fsm->sync_index++; |
407 |
424 |
408 for (; fsm->sync_index < EC_MAX_SYNC_MANAGERS; fsm->sync_index++) { |
425 for (; fsm->sync_index < EC_MAX_SYNC_MANAGERS; fsm->sync_index++) { |
409 if (!fsm->slave->config) { |
426 if (!fsm->slave->config) { |
410 // slave configuration removed in the meantime |
427 // slave configuration removed in the meantime |
411 fsm->state = ec_fsm_pdo_state_error; |
428 fsm->state = ec_fsm_pdo_state_error; |
412 return; |
429 return; |
413 } |
430 } |
414 |
431 |
462 } |
480 } |
463 |
481 |
464 if (list_empty(&fsm->slave_pdo.entries)) { |
482 if (list_empty(&fsm->slave_pdo.entries)) { |
465 EC_SLAVE_DBG(fsm->slave, 1, "Reading mapping of PDO 0x%04X.\n", |
483 EC_SLAVE_DBG(fsm->slave, 1, "Reading mapping of PDO 0x%04X.\n", |
466 fsm->pdo->index); |
484 fsm->pdo->index); |
467 |
485 |
468 // pdo mapping is unknown; start loading it |
486 // pdo mapping is unknown; start loading it |
469 ec_fsm_pdo_entry_start_reading(&fsm->fsm_pdo_entry, fsm->slave, |
487 ec_fsm_pdo_entry_start_reading(&fsm->fsm_pdo_entry, fsm->slave, |
470 &fsm->slave_pdo); |
488 &fsm->slave_pdo); |
471 fsm->state = ec_fsm_pdo_conf_state_read_mapping; |
489 fsm->state = ec_fsm_pdo_conf_state_read_mapping; |
472 fsm->state(fsm); // execute immediately |
490 fsm->state(fsm, datagram); // execute immediately |
473 return; |
491 return; |
474 } |
492 } |
475 |
493 |
476 // pdo mapping is known, check if it most be re-configured |
494 // pdo mapping is known, check if it most be re-configured |
477 ec_fsm_pdo_conf_action_check_mapping(fsm); |
495 ec_fsm_pdo_conf_action_check_mapping(fsm, datagram); |
478 } |
496 } |
479 |
497 |
480 /*****************************************************************************/ |
498 /*****************************************************************************/ |
481 |
499 |
482 /** Execute the PDO entry state machine to read the current PDO's mapping. |
500 /** Execute the PDO entry state machine to read the current PDO's mapping. |
483 */ |
501 */ |
484 void ec_fsm_pdo_conf_state_read_mapping( |
502 void ec_fsm_pdo_conf_state_read_mapping( |
485 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
503 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
486 ) |
504 ec_datagram_t *datagram /**< Datagram to use. */ |
487 { |
505 ) |
488 if (ec_fsm_pdo_entry_exec(&fsm->fsm_pdo_entry)) |
506 { |
489 return; |
507 if (ec_fsm_pdo_entry_exec(&fsm->fsm_pdo_entry, datagram)) { |
|
508 return; |
|
509 } |
490 |
510 |
491 if (!ec_fsm_pdo_entry_success(&fsm->fsm_pdo_entry)) |
511 if (!ec_fsm_pdo_entry_success(&fsm->fsm_pdo_entry)) |
492 EC_SLAVE_WARN(fsm->slave, |
512 EC_SLAVE_WARN(fsm->slave, |
493 "Failed to read PDO entries for PDO 0x%04X.\n", |
513 "Failed to read PDO entries for PDO 0x%04X.\n", |
494 fsm->pdo->index); |
514 fsm->pdo->index); |
495 |
515 |
496 // check if the mapping must be re-configured |
516 // check if the mapping must be re-configured |
497 ec_fsm_pdo_conf_action_check_mapping(fsm); |
517 ec_fsm_pdo_conf_action_check_mapping(fsm, datagram); |
498 } |
518 } |
499 |
519 |
500 /*****************************************************************************/ |
520 /*****************************************************************************/ |
501 |
521 |
502 /** Check if the mapping has to be re-configured. |
522 /** Check if the mapping has to be re-configured. |
503 * |
523 * |
504 * \todo Display mapping differences. |
524 * \todo Display mapping differences. |
505 */ |
525 */ |
506 void ec_fsm_pdo_conf_action_check_mapping( |
526 void ec_fsm_pdo_conf_action_check_mapping( |
507 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
527 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
|
528 ec_datagram_t *datagram /**< Datagram to use. */ |
508 ) |
529 ) |
509 { |
530 { |
510 // check, if slave supports PDO configuration |
531 // check, if slave supports PDO configuration |
511 if ((fsm->slave->sii.mailbox_protocols & EC_MBOX_COE) |
532 if ((fsm->slave->sii.mailbox_protocols & EC_MBOX_COE) |
512 && fsm->slave->sii.has_general |
533 && fsm->slave->sii.has_general |
528 printk(". Entries to map: "); |
549 printk(". Entries to map: "); |
529 ec_pdo_print_entries(fsm->pdo); |
550 ec_pdo_print_entries(fsm->pdo); |
530 printk("\n"); |
551 printk("\n"); |
531 } |
552 } |
532 |
553 |
533 ec_fsm_pdo_conf_action_next_pdo_mapping(fsm); |
554 ec_fsm_pdo_conf_action_next_pdo_mapping(fsm, datagram); |
534 } |
555 } |
535 |
556 |
536 /*****************************************************************************/ |
557 /*****************************************************************************/ |
537 |
558 |
538 /** Let the PDO entry state machine configure the current PDO's mapping. |
559 /** Let the PDO entry state machine configure the current PDO's mapping. |
539 */ |
560 */ |
540 void ec_fsm_pdo_conf_state_mapping( |
561 void ec_fsm_pdo_conf_state_mapping( |
541 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
562 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
542 ) |
563 ec_datagram_t *datagram /**< Datagram to use. */ |
543 { |
564 ) |
544 if (ec_fsm_pdo_entry_exec(&fsm->fsm_pdo_entry)) |
565 { |
545 return; |
566 if (ec_fsm_pdo_entry_exec(&fsm->fsm_pdo_entry, datagram)) { |
|
567 return; |
|
568 } |
546 |
569 |
547 if (!ec_fsm_pdo_entry_success(&fsm->fsm_pdo_entry)) |
570 if (!ec_fsm_pdo_entry_success(&fsm->fsm_pdo_entry)) |
548 EC_SLAVE_WARN(fsm->slave, |
571 EC_SLAVE_WARN(fsm->slave, |
549 "Failed to configure mapping of PDO 0x%04X.\n", |
572 "Failed to configure mapping of PDO 0x%04X.\n", |
550 fsm->pdo->index); |
573 fsm->pdo->index); |
551 |
574 |
552 ec_fsm_pdo_conf_action_next_pdo_mapping(fsm); |
575 ec_fsm_pdo_conf_action_next_pdo_mapping(fsm, datagram); |
553 } |
576 } |
554 |
577 |
555 /*****************************************************************************/ |
578 /*****************************************************************************/ |
556 |
579 |
557 /** Check mapping of next PDO, otherwise configure assignment. |
580 /** Check mapping of next PDO, otherwise configure assignment. |
558 */ |
581 */ |
559 void ec_fsm_pdo_conf_action_next_pdo_mapping( |
582 void ec_fsm_pdo_conf_action_next_pdo_mapping( |
560 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
583 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
|
584 ec_datagram_t *datagram /**< Datagram to use. */ |
561 ) |
585 ) |
562 { |
586 { |
563 // get next configured PDO |
587 // get next configured PDO |
564 if (!(fsm->pdo = ec_fsm_pdo_conf_action_next_pdo(fsm, &fsm->pdo->list))) { |
588 if (!(fsm->pdo = ec_fsm_pdo_conf_action_next_pdo(fsm, &fsm->pdo->list))) { |
565 // no more configured pdos |
589 // no more configured pdos |
566 ec_fsm_pdo_conf_action_check_assignment(fsm); |
590 ec_fsm_pdo_conf_action_check_assignment(fsm, datagram); |
567 return; |
591 return; |
568 } |
592 } |
569 |
593 |
570 ec_fsm_pdo_conf_action_pdo_mapping(fsm); |
594 ec_fsm_pdo_conf_action_pdo_mapping(fsm, datagram); |
571 } |
595 } |
572 |
596 |
573 /*****************************************************************************/ |
597 /*****************************************************************************/ |
574 |
598 |
575 /** Check if the PDO assignment of the current SM has to be re-configured. |
599 /** Check if the PDO assignment of the current SM has to be re-configured. |
576 */ |
600 */ |
577 void ec_fsm_pdo_conf_action_check_assignment( |
601 void ec_fsm_pdo_conf_action_check_assignment( |
578 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
602 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
|
603 ec_datagram_t *datagram /**< Datagram to use. */ |
579 ) |
604 ) |
580 { |
605 { |
581 if ((fsm->slave->sii.mailbox_protocols & EC_MBOX_COE) |
606 if ((fsm->slave->sii.mailbox_protocols & EC_MBOX_COE) |
582 && fsm->slave->sii.has_general |
607 && fsm->slave->sii.has_general |
583 && fsm->slave->sii.coe_details.enable_pdo_assign) { |
608 && fsm->slave->sii.coe_details.enable_pdo_assign) { |
595 } |
620 } |
596 |
621 |
597 // set mapped PDO count to zero |
622 // set mapped PDO count to zero |
598 EC_WRITE_U8(fsm->request.data, 0); // zero PDOs mapped |
623 EC_WRITE_U8(fsm->request.data, 0); // zero PDOs mapped |
599 fsm->request.data_size = 1; |
624 fsm->request.data_size = 1; |
600 ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync_index, 0); |
625 ecrt_sdo_request_index(&fsm->request, 0x1C10 + fsm->sync_index, 0); |
601 ecrt_sdo_request_write(&fsm->request); |
626 ecrt_sdo_request_write(&fsm->request); |
602 |
627 |
603 EC_SLAVE_DBG(fsm->slave, 1, "Setting number of assigned" |
628 EC_SLAVE_DBG(fsm->slave, 1, "Setting number of assigned" |
604 " PDOs to zero.\n"); |
629 " PDOs to zero.\n"); |
605 |
630 |
606 fsm->state = ec_fsm_pdo_conf_state_zero_pdo_count; |
631 fsm->state = ec_fsm_pdo_conf_state_zero_pdo_count; |
607 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); |
632 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); |
608 ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately |
633 ec_fsm_coe_exec(fsm->fsm_coe, datagram); // execute immediately |
609 return; |
634 return; |
610 } |
635 } |
611 else if (!ec_pdo_list_equal(&fsm->sync->pdos, &fsm->pdos)) { |
636 else if (!ec_pdo_list_equal(&fsm->sync->pdos, &fsm->pdos)) { |
612 EC_SLAVE_WARN(fsm->slave, "Slave does not support assigning PDOs!\n"); |
637 EC_SLAVE_WARN(fsm->slave, "Slave does not support assigning PDOs!\n"); |
613 EC_SLAVE_WARN(fsm->slave, ""); ec_fsm_pdo_print(fsm); |
638 EC_SLAVE_WARN(fsm->slave, ""); ec_fsm_pdo_print(fsm); |
614 } |
639 } |
615 |
640 |
616 ec_fsm_pdo_conf_action_next_sync(fsm); |
641 ec_fsm_pdo_conf_action_next_sync(fsm, datagram); |
617 } |
642 } |
618 |
643 |
619 /*****************************************************************************/ |
644 /*****************************************************************************/ |
620 |
645 |
621 /** Set the number of assigned PDOs to zero. |
646 /** Set the number of assigned PDOs to zero. |
622 */ |
647 */ |
623 void ec_fsm_pdo_conf_state_zero_pdo_count( |
648 void ec_fsm_pdo_conf_state_zero_pdo_count( |
624 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
649 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
625 ) |
650 ec_datagram_t *datagram /**< Datagram to use. */ |
626 { |
651 ) |
627 if (ec_fsm_coe_exec(fsm->fsm_coe)) |
652 { |
628 return; |
653 if (ec_fsm_coe_exec(fsm->fsm_coe, datagram)) { |
|
654 return; |
|
655 } |
629 |
656 |
630 if (!ec_fsm_coe_success(fsm->fsm_coe)) { |
657 if (!ec_fsm_coe_success(fsm->fsm_coe)) { |
631 EC_SLAVE_WARN(fsm->slave, "Failed to clear PDO assignment of SM%u.\n", |
658 EC_SLAVE_WARN(fsm->slave, "Failed to clear PDO assignment of SM%u.\n", |
632 fsm->sync_index); |
659 fsm->sync_index); |
633 EC_SLAVE_WARN(fsm->slave, ""); ec_fsm_pdo_print(fsm); |
660 EC_SLAVE_WARN(fsm->slave, ""); |
634 ec_fsm_pdo_conf_action_next_sync(fsm); |
661 ec_fsm_pdo_print(fsm); |
|
662 ec_fsm_pdo_conf_action_next_sync(fsm, datagram); |
635 return; |
663 return; |
636 } |
664 } |
637 |
665 |
638 // the sync manager's assigned PDOs have been cleared |
666 // the sync manager's assigned PDOs have been cleared |
639 ec_pdo_list_clear_pdos(&fsm->sync->pdos); |
667 ec_pdo_list_clear_pdos(&fsm->sync->pdos); |
640 |
668 |
641 // assign all PDOs belonging to the current sync manager |
669 // assign all PDOs belonging to the current sync manager |
642 |
670 |
643 // find first PDO |
671 // find first PDO |
644 if (!(fsm->pdo = ec_fsm_pdo_conf_action_next_pdo(fsm, &fsm->pdos.list))) { |
672 if (!(fsm->pdo = ec_fsm_pdo_conf_action_next_pdo(fsm, &fsm->pdos.list))) { |
645 |
|
646 // check for mapping to be altered |
673 // check for mapping to be altered |
647 ec_fsm_pdo_conf_action_next_sync(fsm); |
674 ec_fsm_pdo_conf_action_next_sync(fsm, datagram); |
648 return; |
675 return; |
649 } |
676 } |
650 |
677 |
651 // assign first PDO |
678 // assign first PDO |
652 fsm->pdo_pos = 1; |
679 fsm->pdo_pos = 1; |
653 ec_fsm_pdo_conf_action_assign_pdo(fsm); |
680 ec_fsm_pdo_conf_action_assign_pdo(fsm, datagram); |
654 } |
681 } |
655 |
682 |
656 /*****************************************************************************/ |
683 /*****************************************************************************/ |
657 |
684 |
658 /** Assign a PDO. |
685 /** Assign a PDO. |
659 */ |
686 */ |
660 void ec_fsm_pdo_conf_action_assign_pdo( |
687 void ec_fsm_pdo_conf_action_assign_pdo( |
661 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
688 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
|
689 ec_datagram_t *datagram /**< Datagram to use. */ |
662 ) |
690 ) |
663 { |
691 { |
664 EC_WRITE_U16(fsm->request.data, fsm->pdo->index); |
692 EC_WRITE_U16(fsm->request.data, fsm->pdo->index); |
665 fsm->request.data_size = 2; |
693 fsm->request.data_size = 2; |
666 ec_sdo_request_address(&fsm->request, |
694 ecrt_sdo_request_index(&fsm->request, |
667 0x1C10 + fsm->sync_index, fsm->pdo_pos); |
695 0x1C10 + fsm->sync_index, fsm->pdo_pos); |
668 ecrt_sdo_request_write(&fsm->request); |
696 ecrt_sdo_request_write(&fsm->request); |
669 |
697 |
670 EC_SLAVE_DBG(fsm->slave, 1, "Assigning PDO 0x%04X at position %u.\n", |
698 EC_SLAVE_DBG(fsm->slave, 1, "Assigning PDO 0x%04X at position %u.\n", |
671 fsm->pdo->index, fsm->pdo_pos); |
699 fsm->pdo->index, fsm->pdo_pos); |
672 |
700 |
673 fsm->state = ec_fsm_pdo_conf_state_assign_pdo; |
701 fsm->state = ec_fsm_pdo_conf_state_assign_pdo; |
674 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); |
702 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); |
675 ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately |
703 ec_fsm_coe_exec(fsm->fsm_coe, datagram); // execute immediately |
676 } |
704 } |
677 |
705 |
678 /*****************************************************************************/ |
706 /*****************************************************************************/ |
679 |
707 |
680 /** Add a PDO to the sync managers PDO assignment. |
708 /** Add a PDO to the sync managers PDO assignment. |
681 */ |
709 */ |
682 void ec_fsm_pdo_conf_state_assign_pdo( |
710 void ec_fsm_pdo_conf_state_assign_pdo( |
683 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
711 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
684 ) |
712 ec_datagram_t *datagram /**< Datagram to use. */ |
685 { |
713 ) |
686 if (ec_fsm_coe_exec(fsm->fsm_coe)) return; |
714 { |
|
715 if (ec_fsm_coe_exec(fsm->fsm_coe, datagram)) { |
|
716 return; |
|
717 } |
687 |
718 |
688 if (!ec_fsm_coe_success(fsm->fsm_coe)) { |
719 if (!ec_fsm_coe_success(fsm->fsm_coe)) { |
689 EC_SLAVE_WARN(fsm->slave, "Failed to assign PDO 0x%04X at position %u" |
720 EC_SLAVE_WARN(fsm->slave, "Failed to assign PDO 0x%04X at position %u" |
690 " of SM%u.\n", |
721 " of SM%u.\n", |
691 fsm->pdo->index, fsm->pdo_pos, fsm->sync_index); |
722 fsm->pdo->index, fsm->pdo_pos, fsm->sync_index); |
694 return; |
725 return; |
695 } |
726 } |
696 |
727 |
697 // find next PDO |
728 // find next PDO |
698 if (!(fsm->pdo = ec_fsm_pdo_conf_action_next_pdo(fsm, &fsm->pdo->list))) { |
729 if (!(fsm->pdo = ec_fsm_pdo_conf_action_next_pdo(fsm, &fsm->pdo->list))) { |
699 |
|
700 // no more PDOs to assign, set PDO count |
730 // no more PDOs to assign, set PDO count |
701 EC_WRITE_U8(fsm->request.data, fsm->pdo_pos); |
731 EC_WRITE_U8(fsm->request.data, fsm->pdo_pos); |
702 fsm->request.data_size = 1; |
732 fsm->request.data_size = 1; |
703 ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync_index, 0); |
733 ecrt_sdo_request_index(&fsm->request, 0x1C10 + fsm->sync_index, 0); |
704 ecrt_sdo_request_write(&fsm->request); |
734 ecrt_sdo_request_write(&fsm->request); |
705 |
735 |
706 EC_SLAVE_DBG(fsm->slave, 1, |
736 EC_SLAVE_DBG(fsm->slave, 1, |
707 "Setting number of assigned PDOs to %u.\n", |
737 "Setting number of assigned PDOs to %u.\n", |
708 fsm->pdo_pos); |
738 fsm->pdo_pos); |
709 |
739 |
710 fsm->state = ec_fsm_pdo_conf_state_set_pdo_count; |
740 fsm->state = ec_fsm_pdo_conf_state_set_pdo_count; |
711 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); |
741 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); |
712 ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately |
742 ec_fsm_coe_exec(fsm->fsm_coe, datagram); // execute immediately |
713 return; |
743 return; |
714 } |
744 } |
715 |
745 |
716 // add next PDO to assignment |
746 // add next PDO to assignment |
717 fsm->pdo_pos++; |
747 fsm->pdo_pos++; |
718 ec_fsm_pdo_conf_action_assign_pdo(fsm); |
748 ec_fsm_pdo_conf_action_assign_pdo(fsm, datagram); |
719 } |
749 } |
720 |
750 |
721 /*****************************************************************************/ |
751 /*****************************************************************************/ |
722 |
752 |
723 /** Set the number of assigned PDOs. |
753 /** Set the number of assigned PDOs. |
724 */ |
754 */ |
725 void ec_fsm_pdo_conf_state_set_pdo_count( |
755 void ec_fsm_pdo_conf_state_set_pdo_count( |
726 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
756 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
727 ) |
757 ec_datagram_t *datagram /**< Datagram to use. */ |
728 { |
758 ) |
729 if (ec_fsm_coe_exec(fsm->fsm_coe)) return; |
759 { |
|
760 if (ec_fsm_coe_exec(fsm->fsm_coe, datagram)) { |
|
761 return; |
|
762 } |
730 |
763 |
731 if (!ec_fsm_coe_success(fsm->fsm_coe)) { |
764 if (!ec_fsm_coe_success(fsm->fsm_coe)) { |
732 EC_SLAVE_WARN(fsm->slave, "Failed to set number of" |
765 EC_SLAVE_WARN(fsm->slave, "Failed to set number of" |
733 " assigned PDOs of SM%u.\n", fsm->sync_index); |
766 " assigned PDOs of SM%u.\n", fsm->sync_index); |
734 EC_SLAVE_WARN(fsm->slave, ""); ec_fsm_pdo_print(fsm); |
767 EC_SLAVE_WARN(fsm->slave, ""); ec_fsm_pdo_print(fsm); |
741 |
774 |
742 EC_SLAVE_DBG(fsm->slave, 1, "Successfully configured" |
775 EC_SLAVE_DBG(fsm->slave, 1, "Successfully configured" |
743 " PDO assignment of SM%u.\n", fsm->sync_index); |
776 " PDO assignment of SM%u.\n", fsm->sync_index); |
744 |
777 |
745 // check if PDO mapping has to be altered |
778 // check if PDO mapping has to be altered |
746 ec_fsm_pdo_conf_action_next_sync(fsm); |
779 ec_fsm_pdo_conf_action_next_sync(fsm, datagram); |
747 } |
780 } |
748 |
781 |
749 /****************************************************************************** |
782 /****************************************************************************** |
750 * Common state functions |
783 * Common state functions |
751 *****************************************************************************/ |
784 *****************************************************************************/ |
752 |
785 |
753 /** State: ERROR. |
786 /** State: ERROR. |
754 */ |
787 */ |
755 void ec_fsm_pdo_state_error( |
788 void ec_fsm_pdo_state_error( |
756 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
789 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
|
790 ec_datagram_t *datagram /**< Datagram to use. */ |
757 ) |
791 ) |
758 { |
792 { |
759 } |
793 } |
760 |
794 |
761 /*****************************************************************************/ |
795 /*****************************************************************************/ |
762 |
796 |
763 /** State: END. |
797 /** State: END. |
764 */ |
798 */ |
765 void ec_fsm_pdo_state_end( |
799 void ec_fsm_pdo_state_end( |
766 ec_fsm_pdo_t *fsm /**< PDO configuration state machine. */ |
800 ec_fsm_pdo_t *fsm, /**< Finite state machine. */ |
767 ) |
801 ec_datagram_t *datagram /**< Datagram to use. */ |
768 { |
802 ) |
769 } |
803 { |
770 |
804 } |
771 /*****************************************************************************/ |
805 |
|
806 /*****************************************************************************/ |