changeset 1995 | 7d748d9cf9e8 |
parent 1989 | 6aa393418fb3 |
parent 1952 | 7d9fb723fc4b |
child 1998 | 0330fdcbdd1f |
1994:b369f3f92eb8 | 1995:7d748d9cf9e8 |
---|---|
441 } |
441 } |
442 } |
442 } |
443 |
443 |
444 /*****************************************************************************/ |
444 /*****************************************************************************/ |
445 |
445 |
446 /** Clear the configuration applied by the application. |
|
447 */ |
|
448 void ec_master_clear_config( |
|
449 ec_master_t *master /**< EtherCAT master. */ |
|
450 ) |
|
451 { |
|
452 down(&master->master_sem); |
|
453 ec_master_clear_domains(master); |
|
454 ec_master_clear_slave_configs(master); |
|
455 up(&master->master_sem); |
|
456 } |
|
457 |
|
458 /*****************************************************************************/ |
|
459 |
|
446 /** Internal sending callback. |
460 /** Internal sending callback. |
447 */ |
461 */ |
448 void ec_master_internal_send_cb( |
462 void ec_master_internal_send_cb( |
449 void *cb_data /**< Callback data. */ |
463 void *cb_data /**< Callback data. */ |
450 ) |
464 ) |
655 */ |
669 */ |
656 void ec_master_leave_operation_phase( |
670 void ec_master_leave_operation_phase( |
657 ec_master_t *master /**< EtherCAT master */ |
671 ec_master_t *master /**< EtherCAT master */ |
658 ) |
672 ) |
659 { |
673 { |
660 if (master->active) |
674 if (master->active) { |
661 ecrt_master_deactivate(master); |
675 ecrt_master_deactivate(master); // also clears config |
676 } else { |
|
677 ec_master_clear_config(master); |
|
678 } |
|
662 |
679 |
663 EC_MASTER_DBG(master, 1, "OPERATION -> IDLE.\n"); |
680 EC_MASTER_DBG(master, 1, "OPERATION -> IDLE.\n"); |
664 |
681 |
665 master->phase = EC_IDLE; |
682 master->phase = EC_IDLE; |
666 } |
683 } |
667 |
|
668 |
684 |
669 /*****************************************************************************/ |
685 /*****************************************************************************/ |
670 |
686 |
671 /** Injects external datagrams that fit into the datagram queue. |
687 /** Injects external datagrams that fit into the datagram queue. |
672 */ |
688 */ |
700 else { |
716 else { |
701 if (datagram->data_size > master->max_queue_size) { |
717 if (datagram->data_size > master->max_queue_size) { |
702 list_del_init(&datagram->queue); |
718 list_del_init(&datagram->queue); |
703 datagram->state = EC_DATAGRAM_ERROR; |
719 datagram->state = EC_DATAGRAM_ERROR; |
704 EC_MASTER_ERR(master, "External datagram %p is too large," |
720 EC_MASTER_ERR(master, "External datagram %p is too large," |
705 " size=%u, max_queue_size=%u\n", |
721 " size=%zu, max_queue_size=%zu\n", |
706 datagram, datagram->data_size, |
722 datagram, datagram->data_size, |
707 master->max_queue_size); |
723 master->max_queue_size); |
708 } else { |
724 } else { |
709 #ifdef EC_HAVE_CYCLES |
725 #ifdef EC_HAVE_CYCLES |
710 cycles_t cycles_now = get_cycles(); |
726 cycles_t cycles_now = get_cycles(); |
727 #else |
743 #else |
728 time_us = (unsigned int) |
744 time_us = (unsigned int) |
729 ((jiffies - datagram->jiffies_sent) * 1000000 / HZ); |
745 ((jiffies - datagram->jiffies_sent) * 1000000 / HZ); |
730 #endif |
746 #endif |
731 EC_MASTER_ERR(master, "Timeout %u us: Injecting" |
747 EC_MASTER_ERR(master, "Timeout %u us: Injecting" |
732 " external datagram %p size=%u," |
748 " external datagram %p size=%zu," |
733 " max_queue_size=%u\n", time_us, datagram, |
749 " max_queue_size=%zu\n", time_us, datagram, |
734 datagram->data_size, master->max_queue_size); |
750 datagram->data_size, master->max_queue_size); |
735 } |
751 } |
736 #if DEBUG_INJECT |
752 #if DEBUG_INJECT |
737 else { |
753 else { |
738 EC_MASTER_DBG(master, 0, "Deferred injecting" |
754 EC_MASTER_DBG(master, 0, "Deferred injecting" |
751 /** Sets the expected interval between calls to ecrt_master_send |
767 /** Sets the expected interval between calls to ecrt_master_send |
752 * and calculates the maximum amount of data to queue. |
768 * and calculates the maximum amount of data to queue. |
753 */ |
769 */ |
754 void ec_master_set_send_interval( |
770 void ec_master_set_send_interval( |
755 ec_master_t *master, /**< EtherCAT master */ |
771 ec_master_t *master, /**< EtherCAT master */ |
756 size_t send_interval /**< Send interval */ |
772 unsigned int send_interval /**< Send interval */ |
757 ) |
773 ) |
758 { |
774 { |
759 master->send_interval = send_interval; |
775 master->send_interval = send_interval; |
760 master->max_queue_size = |
776 master->max_queue_size = |
761 (send_interval * 1000) / EC_BYTE_TRANSMISSION_TIME_NS; |
777 (send_interval * 1000) / EC_BYTE_TRANSMISSION_TIME_NS; |
1243 size_t sent_bytes; |
1259 size_t sent_bytes; |
1244 |
1260 |
1245 // send interval in IDLE phase |
1261 // send interval in IDLE phase |
1246 ec_master_set_send_interval(master, 1000000 / HZ); |
1262 ec_master_set_send_interval(master, 1000000 / HZ); |
1247 |
1263 |
1248 EC_MASTER_DBG(master, 1, "Idle thread running with send interval = %d us," |
1264 EC_MASTER_DBG(master, 1, "Idle thread running with send interval = %u us," |
1249 " max data size=%d\n", master->send_interval, |
1265 " max data size=%zu\n", master->send_interval, |
1250 master->max_queue_size); |
1266 master->max_queue_size); |
1251 |
1267 |
1252 while (!kthread_should_stop()) { |
1268 while (!kthread_should_stop()) { |
1253 ec_datagram_output_stats(&master->fsm_datagram); |
1269 ec_datagram_output_stats(&master->fsm_datagram); |
1254 |
1270 |
1310 ec_master_t *master = (ec_master_t *) priv_data; |
1326 ec_master_t *master = (ec_master_t *) priv_data; |
1311 ec_slave_t *slave = NULL; |
1327 ec_slave_t *slave = NULL; |
1312 int fsm_exec; |
1328 int fsm_exec; |
1313 |
1329 |
1314 EC_MASTER_DBG(master, 1, "Operation thread running" |
1330 EC_MASTER_DBG(master, 1, "Operation thread running" |
1315 " with fsm interval = %d us, max data size=%d\n", |
1331 " with fsm interval = %u us, max data size=%zu\n", |
1316 master->send_interval, master->max_queue_size); |
1332 master->send_interval, master->max_queue_size); |
1317 |
1333 |
1318 while (!kthread_should_stop()) { |
1334 while (!kthread_should_stop()) { |
1319 ec_datagram_output_stats(&master->fsm_datagram); |
1335 ec_datagram_output_stats(&master->fsm_datagram); |
1320 |
1336 |
2034 #ifdef EC_EOE |
2050 #ifdef EC_EOE |
2035 ec_eoe_t *eoe; |
2051 ec_eoe_t *eoe; |
2036 int eoe_was_running; |
2052 int eoe_was_running; |
2037 #endif |
2053 #endif |
2038 |
2054 |
2039 EC_MASTER_DBG(master, 1, "ecrt_master_deactivate(master = 0x%x)\n", |
2055 EC_MASTER_DBG(master, 1, "%s(master = 0x%p)\n", __func__, master); |
2040 (u32) master); |
|
2041 |
2056 |
2042 if (!master->active) { |
2057 if (!master->active) { |
2043 EC_MASTER_WARN(master, "%s: Master not active.\n", __func__); |
2058 EC_MASTER_WARN(master, "%s: Master not active.\n", __func__); |
2044 return; |
2059 return; |
2045 } |
2060 } |
2052 |
2067 |
2053 master->send_cb = ec_master_internal_send_cb; |
2068 master->send_cb = ec_master_internal_send_cb; |
2054 master->receive_cb = ec_master_internal_receive_cb; |
2069 master->receive_cb = ec_master_internal_receive_cb; |
2055 master->cb_data = master; |
2070 master->cb_data = master; |
2056 |
2071 |
2057 down(&master->master_sem); |
2072 ec_master_clear_config(master); |
2058 ec_master_clear_domains(master); |
|
2059 ec_master_clear_slave_configs(master); |
|
2060 up(&master->master_sem); |
|
2061 |
2073 |
2062 for (slave = master->slaves; |
2074 for (slave = master->slaves; |
2063 slave < master->slaves + master->slave_count; |
2075 slave < master->slaves + master->slave_count; |
2064 slave++) { |
2076 slave++) { |
2065 |
2077 |
2396 { |
2408 { |
2397 if (master->sync_mon_datagram.state == EC_DATAGRAM_RECEIVED) { |
2409 if (master->sync_mon_datagram.state == EC_DATAGRAM_RECEIVED) { |
2398 return EC_READ_U32(master->sync_mon_datagram.data) & 0x7fffffff; |
2410 return EC_READ_U32(master->sync_mon_datagram.data) & 0x7fffffff; |
2399 } else { |
2411 } else { |
2400 return 0xffffffff; |
2412 return 0xffffffff; |
2413 } |
|
2414 } |
|
2415 |
|
2416 /*****************************************************************************/ |
|
2417 |
|
2418 int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, |
|
2419 uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size, |
|
2420 uint16_t *error_code) |
|
2421 { |
|
2422 ec_master_soe_request_t request; |
|
2423 int retval; |
|
2424 |
|
2425 if (drive_no > 7) { |
|
2426 EC_MASTER_ERR(master, "Invalid drive number!\n"); |
|
2427 return -EINVAL; |
|
2428 } |
|
2429 |
|
2430 INIT_LIST_HEAD(&request.list); |
|
2431 ec_soe_request_init(&request.req); |
|
2432 ec_soe_request_set_drive_no(&request.req, drive_no); |
|
2433 ec_soe_request_set_idn(&request.req, idn); |
|
2434 |
|
2435 if (ec_soe_request_alloc(&request.req, data_size)) { |
|
2436 ec_soe_request_clear(&request.req); |
|
2437 return -ENOMEM; |
|
2438 } |
|
2439 |
|
2440 memcpy(request.req.data, data, data_size); |
|
2441 request.req.data_size = data_size; |
|
2442 ec_soe_request_write(&request.req); |
|
2443 |
|
2444 if (down_interruptible(&master->master_sem)) |
|
2445 return -EINTR; |
|
2446 |
|
2447 if (!(request.slave = ec_master_find_slave( |
|
2448 master, 0, slave_position))) { |
|
2449 up(&master->master_sem); |
|
2450 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
|
2451 slave_position); |
|
2452 ec_soe_request_clear(&request.req); |
|
2453 return -EINVAL; |
|
2454 } |
|
2455 |
|
2456 EC_SLAVE_DBG(request.slave, 1, "Scheduling SoE write request.\n"); |
|
2457 |
|
2458 // schedule SoE write request. |
|
2459 list_add_tail(&request.list, &request.slave->soe_requests); |
|
2460 |
|
2461 up(&master->master_sem); |
|
2462 |
|
2463 // wait for processing through FSM |
|
2464 if (wait_event_interruptible(request.slave->soe_queue, |
|
2465 request.req.state != EC_INT_REQUEST_QUEUED)) { |
|
2466 // interrupted by signal |
|
2467 down(&master->master_sem); |
|
2468 if (request.req.state == EC_INT_REQUEST_QUEUED) { |
|
2469 // abort request |
|
2470 list_del(&request.list); |
|
2471 up(&master->master_sem); |
|
2472 ec_soe_request_clear(&request.req); |
|
2473 return -EINTR; |
|
2474 } |
|
2475 up(&master->master_sem); |
|
2476 } |
|
2477 |
|
2478 // wait until master FSM has finished processing |
|
2479 wait_event(request.slave->soe_queue, |
|
2480 request.req.state != EC_INT_REQUEST_BUSY); |
|
2481 |
|
2482 if (error_code) { |
|
2483 *error_code = request.req.error_code; |
|
2484 } |
|
2485 retval = request.req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; |
|
2486 ec_soe_request_clear(&request.req); |
|
2487 |
|
2488 return retval; |
|
2489 } |
|
2490 |
|
2491 /*****************************************************************************/ |
|
2492 |
|
2493 int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position, |
|
2494 uint8_t drive_no, uint16_t idn, uint8_t *target, size_t target_size, |
|
2495 size_t *result_size, uint16_t *error_code) |
|
2496 { |
|
2497 ec_master_soe_request_t request; |
|
2498 |
|
2499 if (drive_no > 7) { |
|
2500 EC_MASTER_ERR(master, "Invalid drive number!\n"); |
|
2501 return -EINVAL; |
|
2502 } |
|
2503 |
|
2504 INIT_LIST_HEAD(&request.list); |
|
2505 ec_soe_request_init(&request.req); |
|
2506 ec_soe_request_set_drive_no(&request.req, drive_no); |
|
2507 ec_soe_request_set_idn(&request.req, idn); |
|
2508 ec_soe_request_read(&request.req); |
|
2509 |
|
2510 if (down_interruptible(&master->master_sem)) |
|
2511 return -EINTR; |
|
2512 |
|
2513 if (!(request.slave = ec_master_find_slave(master, 0, slave_position))) { |
|
2514 up(&master->master_sem); |
|
2515 ec_soe_request_clear(&request.req); |
|
2516 EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position); |
|
2517 return -EINVAL; |
|
2518 } |
|
2519 |
|
2520 // schedule request. |
|
2521 list_add_tail(&request.list, &request.slave->soe_requests); |
|
2522 |
|
2523 up(&master->master_sem); |
|
2524 |
|
2525 EC_SLAVE_DBG(request.slave, 1, "Scheduled SoE read request.\n"); |
|
2526 |
|
2527 // wait for processing through FSM |
|
2528 if (wait_event_interruptible(request.slave->soe_queue, |
|
2529 request.req.state != EC_INT_REQUEST_QUEUED)) { |
|
2530 // interrupted by signal |
|
2531 down(&master->master_sem); |
|
2532 if (request.req.state == EC_INT_REQUEST_QUEUED) { |
|
2533 list_del(&request.list); |
|
2534 up(&master->master_sem); |
|
2535 ec_soe_request_clear(&request.req); |
|
2536 return -EINTR; |
|
2537 } |
|
2538 // request already processing: interrupt not possible. |
|
2539 up(&master->master_sem); |
|
2540 } |
|
2541 |
|
2542 // wait until master FSM has finished processing |
|
2543 wait_event(request.slave->soe_queue, |
|
2544 request.req.state != EC_INT_REQUEST_BUSY); |
|
2545 |
|
2546 if (error_code) { |
|
2547 *error_code = request.req.error_code; |
|
2548 } |
|
2549 |
|
2550 EC_SLAVE_DBG(request.slave, 1, "Read %zd bytes via SoE.\n", |
|
2551 request.req.data_size); |
|
2552 |
|
2553 if (request.req.state != EC_INT_REQUEST_SUCCESS) { |
|
2554 if (result_size) { |
|
2555 *result_size = 0; |
|
2556 } |
|
2557 ec_soe_request_clear(&request.req); |
|
2558 return -EIO; |
|
2559 } else { |
|
2560 if (request.req.data_size > target_size) { |
|
2561 EC_MASTER_ERR(master, "Buffer too small.\n"); |
|
2562 ec_soe_request_clear(&request.req); |
|
2563 return -EOVERFLOW; |
|
2564 } |
|
2565 if (result_size) { |
|
2566 *result_size = request.req.data_size; |
|
2567 } |
|
2568 memcpy(target, request.req.data, request.req.data_size); |
|
2569 return 0; |
|
2401 } |
2570 } |
2402 } |
2571 } |
2403 |
2572 |
2404 /*****************************************************************************/ |
2573 /*****************************************************************************/ |
2405 |
2574 |
2419 EXPORT_SYMBOL(ecrt_master_application_time); |
2588 EXPORT_SYMBOL(ecrt_master_application_time); |
2420 EXPORT_SYMBOL(ecrt_master_sync_reference_clock); |
2589 EXPORT_SYMBOL(ecrt_master_sync_reference_clock); |
2421 EXPORT_SYMBOL(ecrt_master_sync_slave_clocks); |
2590 EXPORT_SYMBOL(ecrt_master_sync_slave_clocks); |
2422 EXPORT_SYMBOL(ecrt_master_sync_monitor_queue); |
2591 EXPORT_SYMBOL(ecrt_master_sync_monitor_queue); |
2423 EXPORT_SYMBOL(ecrt_master_sync_monitor_process); |
2592 EXPORT_SYMBOL(ecrt_master_sync_monitor_process); |
2593 EXPORT_SYMBOL(ecrt_master_write_idn); |
|
2594 EXPORT_SYMBOL(ecrt_master_read_idn); |
|
2424 |
2595 |
2425 /** \endcond */ |
2596 /** \endcond */ |
2426 |
2597 |
2427 /*****************************************************************************/ |
2598 /*****************************************************************************/ |