2342 void ecrt_master_application_time(ec_master_t *master, uint64_t app_time) |
2350 void ecrt_master_application_time(ec_master_t *master, uint64_t app_time) |
2343 { |
2351 { |
2344 master->app_time = app_time; |
2352 master->app_time = app_time; |
2345 |
2353 |
2346 if (unlikely(!master->has_app_time)) { |
2354 if (unlikely(!master->has_app_time)) { |
2347 EC_MASTER_DBG(master, 1, "set application start time = %llu\n",app_time); |
2355 EC_MASTER_DBG(master, 1, "Set application start time = %llu\n", |
2348 master->app_start_time = app_time; |
2356 app_time); |
|
2357 master->app_start_time = app_time; |
2349 #ifdef EC_HAVE_CYCLES |
2358 #ifdef EC_HAVE_CYCLES |
2350 master->dc_cycles_app_start_time = get_cycles(); |
2359 master->dc_cycles_app_start_time = get_cycles(); |
2351 #endif |
2360 #endif |
2352 master->dc_jiffies_app_start_time = jiffies; |
2361 master->dc_jiffies_app_start_time = jiffies; |
2353 master->has_app_time = 1; |
2362 master->has_app_time = 1; |
2354 } |
2363 } |
2355 } |
2364 } |
2356 |
2365 |
2357 /*****************************************************************************/ |
2366 /*****************************************************************************/ |
2385 if (master->sync_mon_datagram.state == EC_DATAGRAM_RECEIVED) { |
2394 if (master->sync_mon_datagram.state == EC_DATAGRAM_RECEIVED) { |
2386 return EC_READ_U32(master->sync_mon_datagram.data) & 0x7fffffff; |
2395 return EC_READ_U32(master->sync_mon_datagram.data) & 0x7fffffff; |
2387 } else { |
2396 } else { |
2388 return 0xffffffff; |
2397 return 0xffffffff; |
2389 } |
2398 } |
|
2399 } |
|
2400 |
|
2401 /*****************************************************************************/ |
|
2402 |
|
2403 int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position, |
|
2404 uint16_t index, uint8_t subindex, uint8_t *data, |
|
2405 size_t data_size, uint32_t *abort_code) |
|
2406 { |
|
2407 ec_master_sdo_request_t* request; |
|
2408 int retval; |
|
2409 |
|
2410 if (!data_size) { |
|
2411 EC_MASTER_ERR(master, "Zero data size!\n"); |
|
2412 return -EINVAL; |
|
2413 } |
|
2414 |
|
2415 request = kmalloc(sizeof(*request), GFP_KERNEL); |
|
2416 if (!request) { |
|
2417 return -ENOMEM; |
|
2418 } |
|
2419 kref_init(&request->refcount); |
|
2420 |
|
2421 ec_sdo_request_init(&request->req); |
|
2422 ec_sdo_request_address(&request->req, index, subindex); |
|
2423 if (ec_sdo_request_alloc(&request->req, data_size)) { |
|
2424 kref_put(&request->refcount, ec_master_sdo_request_release); |
|
2425 return -ENOMEM; |
|
2426 } |
|
2427 memcpy(request->req.data, data, data_size); |
|
2428 request->req.data_size = data_size; |
|
2429 ecrt_sdo_request_write(&request->req); |
|
2430 |
|
2431 if (ec_mutex_lock_interruptible(&master->master_mutex)) { |
|
2432 kref_put(&request->refcount, ec_master_sdo_request_release); |
|
2433 return -EINTR; |
|
2434 } |
|
2435 |
|
2436 if (!(request->slave = ec_master_find_slave( |
|
2437 master, 0, slave_position))) { |
|
2438 ec_mutex_unlock(&master->master_mutex); |
|
2439 EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position); |
|
2440 kref_put(&request->refcount, ec_master_sdo_request_release); |
|
2441 return -EINVAL; |
|
2442 } |
|
2443 |
|
2444 EC_SLAVE_DBG(request->slave, 1, "Schedule SDO download request %p.\n", |
|
2445 request); |
|
2446 |
|
2447 // schedule request |
|
2448 kref_get(&request->refcount); |
|
2449 list_add_tail(&request->list, &request->slave->slave_sdo_requests); |
|
2450 |
|
2451 ec_mutex_unlock(&master->master_mutex); |
|
2452 |
|
2453 // wait for processing through FSM |
|
2454 if (wait_event_interruptible(request->slave->sdo_queue, |
|
2455 ((request->req.state == EC_INT_REQUEST_SUCCESS) || |
|
2456 (request->req.state == EC_INT_REQUEST_FAILURE)))) { |
|
2457 // interrupted by signal |
|
2458 kref_put(&request->refcount, ec_master_sdo_request_release); |
|
2459 return -EINTR; |
|
2460 } |
|
2461 |
|
2462 EC_SLAVE_DBG(request->slave, 1, "Finished SDO download request %p.\n", |
|
2463 request); |
|
2464 |
|
2465 *abort_code = request->req.abort_code; |
|
2466 |
|
2467 if (request->req.state == EC_INT_REQUEST_SUCCESS) { |
|
2468 retval = 0; |
|
2469 } else if (request->req.errno) { |
|
2470 retval = -request->req.errno; |
|
2471 } else { |
|
2472 retval = -EIO; |
|
2473 } |
|
2474 |
|
2475 kref_put(&request->refcount, ec_master_sdo_request_release); |
|
2476 return retval; |
|
2477 } |
|
2478 |
|
2479 /*****************************************************************************/ |
|
2480 |
|
2481 int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position, |
|
2482 uint16_t index, uint8_t subindex, uint8_t *target, |
|
2483 size_t target_size, size_t *result_size, uint32_t *abort_code) |
|
2484 { |
|
2485 ec_master_sdo_request_t* request; |
|
2486 int retval; |
|
2487 |
|
2488 request = kmalloc(sizeof(*request), GFP_KERNEL); |
|
2489 if (!request) |
|
2490 return -ENOMEM; |
|
2491 kref_init(&request->refcount); |
|
2492 |
|
2493 ec_sdo_request_init(&request->req); |
|
2494 ec_sdo_request_address(&request->req, index, subindex); |
|
2495 ecrt_sdo_request_read(&request->req); |
|
2496 |
|
2497 if (ec_mutex_lock_interruptible(&master->master_mutex)) { |
|
2498 kref_put(&request->refcount, ec_master_sdo_request_release); |
|
2499 return -EINTR; |
|
2500 } |
|
2501 |
|
2502 if (!(request->slave = ec_master_find_slave( |
|
2503 master, 0, slave_position))) { |
|
2504 ec_mutex_unlock(&master->master_mutex); |
|
2505 EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position); |
|
2506 kref_put(&request->refcount, ec_master_sdo_request_release); |
|
2507 return -EINVAL; |
|
2508 } |
|
2509 |
|
2510 EC_SLAVE_DBG(request->slave, 1, "Schedule SDO upload request %p.\n", |
|
2511 request); |
|
2512 |
|
2513 // schedule request |
|
2514 kref_get(&request->refcount); |
|
2515 list_add_tail(&request->list, &request->slave->slave_sdo_requests); |
|
2516 |
|
2517 ec_mutex_unlock(&master->master_mutex); |
|
2518 |
|
2519 // wait for processing through FSM |
|
2520 if (wait_event_interruptible(request->slave->sdo_queue, |
|
2521 ((request->req.state == EC_INT_REQUEST_SUCCESS) || |
|
2522 (request->req.state == EC_INT_REQUEST_FAILURE)))) { |
|
2523 // interrupted by signal |
|
2524 kref_put(&request->refcount, ec_master_sdo_request_release); |
|
2525 return -EINTR; |
|
2526 } |
|
2527 |
|
2528 EC_SLAVE_DBG(request->slave, 1, "Finished SDO upload request %p.\n", |
|
2529 request); |
|
2530 |
|
2531 *abort_code = request->req.abort_code; |
|
2532 |
|
2533 if (request->req.state != EC_INT_REQUEST_SUCCESS) { |
|
2534 *result_size = 0; |
|
2535 if (request->req.errno) { |
|
2536 retval = -request->req.errno; |
|
2537 } else { |
|
2538 retval = -EIO; |
|
2539 } |
|
2540 } else { |
|
2541 if (request->req.data_size > target_size) { |
|
2542 EC_MASTER_ERR(master, "Buffer too small.\n"); |
|
2543 kref_put(&request->refcount, ec_master_sdo_request_release); |
|
2544 return -EOVERFLOW; |
|
2545 } |
|
2546 memcpy(target, request->req.data, request->req.data_size); |
|
2547 *result_size = request->req.data_size; |
|
2548 retval = 0; |
|
2549 } |
|
2550 |
|
2551 kref_put(&request->refcount, ec_master_sdo_request_release); |
|
2552 return retval; |
2390 } |
2553 } |
2391 |
2554 |
2392 /*****************************************************************************/ |
2555 /*****************************************************************************/ |
2393 |
2556 |
2394 int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, |
2557 int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, |
2435 slave_position); |
2598 slave_position); |
2436 kref_put(&request->refcount,ec_master_soe_request_release); |
2599 kref_put(&request->refcount,ec_master_soe_request_release); |
2437 return -EINVAL; |
2600 return -EINVAL; |
2438 } |
2601 } |
2439 |
2602 |
2440 EC_SLAVE_DBG(request->slave, 1, "Scheduled SoE write request %p.\n",request); |
2603 EC_SLAVE_DBG(request->slave, 1, "Scheduled SoE write request %p.\n", |
|
2604 request); |
2441 |
2605 |
2442 // schedule SoE write request. |
2606 // schedule SoE write request. |
2443 list_add_tail(&request->list, &request->slave->soe_requests); |
2607 list_add_tail(&request->list, &request->slave->soe_requests); |
2444 kref_get(&request->refcount); |
2608 kref_get(&request->refcount); |
2445 |
2609 |
2446 ec_mutex_unlock(&master->master_mutex); |
2610 ec_mutex_unlock(&master->master_mutex); |
2447 |
2611 |
2448 // wait for processing through FSM |
2612 // wait for processing through FSM |
2449 if (wait_event_interruptible(request->slave->soe_queue, |
2613 if (wait_event_interruptible(request->slave->soe_queue, |
2450 ((request->req.state == EC_INT_REQUEST_SUCCESS) || (request->req.state == EC_INT_REQUEST_FAILURE)))) { |
2614 ((request->req.state == EC_INT_REQUEST_SUCCESS) || |
|
2615 (request->req.state == EC_INT_REQUEST_FAILURE)))) { |
2451 // interrupted by signal |
2616 // interrupted by signal |
2452 kref_put(&request->refcount,ec_master_soe_request_release); |
2617 kref_put(&request->refcount,ec_master_soe_request_release); |
2453 return -EINTR; |
2618 return -EINTR; |
2454 } |
2619 } |
2455 |
2620 |
2502 list_add_tail(&request->list, &request->slave->soe_requests); |
2667 list_add_tail(&request->list, &request->slave->soe_requests); |
2503 kref_get(&request->refcount); |
2668 kref_get(&request->refcount); |
2504 |
2669 |
2505 ec_mutex_unlock(&master->master_mutex); |
2670 ec_mutex_unlock(&master->master_mutex); |
2506 |
2671 |
2507 EC_SLAVE_DBG(request->slave, 1, "Scheduled SoE read request %p.\n",request); |
2672 EC_SLAVE_DBG(request->slave, 1, "Scheduled SoE read request %p.\n", |
|
2673 request); |
2508 |
2674 |
2509 // wait for processing through FSM |
2675 // wait for processing through FSM |
2510 if (wait_event_interruptible(request->slave->soe_queue, |
2676 if (wait_event_interruptible(request->slave->soe_queue, |
2511 ((request->req.state == EC_INT_REQUEST_SUCCESS) || (request->req.state == EC_INT_REQUEST_FAILURE)))) { |
2677 ((request->req.state == EC_INT_REQUEST_SUCCESS) || |
|
2678 (request->req.state == EC_INT_REQUEST_FAILURE)))) { |
2512 // interrupted by signal |
2679 // interrupted by signal |
2513 kref_put(&request->refcount,ec_master_soe_request_release); |
2680 kref_put(&request->refcount,ec_master_soe_request_release); |
2514 return -EINTR; |
2681 return -EINTR; |
2515 } |
2682 } |
2516 |
2683 |
2517 if (error_code) { |
2684 if (error_code) { |
2518 *error_code = request->req.error_code; |
2685 *error_code = request->req.error_code; |
2519 } |
2686 } |
2520 |
2687 |
2521 EC_SLAVE_DBG(request->slave, 1, "SoE request %p read %zd bytes via SoE.\n", |
2688 EC_SLAVE_DBG(request->slave, 1, "SoE request %p read %zd bytes" |
2522 request,request->req.data_size); |
2689 " via SoE.\n", request, request->req.data_size); |
2523 |
2690 |
2524 if (request->req.state != EC_INT_REQUEST_SUCCESS) { |
2691 if (request->req.state != EC_INT_REQUEST_SUCCESS) { |
2525 if (result_size) { |
2692 if (result_size) { |
2526 *result_size = 0; |
2693 *result_size = 0; |
2527 } |
2694 } |