master/master.c
branchstable-1.5
changeset 2109 755e6ce823f0
parent 2085 23ffec5c9c5b
child 2114 b91bb9b96823
equal deleted inserted replaced
2108:6d3620f2328f 2109:755e6ce823f0
  2364     }
  2364     }
  2365 }
  2365 }
  2366 
  2366 
  2367 /*****************************************************************************/
  2367 /*****************************************************************************/
  2368 
  2368 
       
  2369 int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
       
  2370         uint16_t index, uint8_t subindex, uint8_t *data,
       
  2371         size_t data_size, uint32_t *abort_code)
       
  2372 {
       
  2373     ec_master_sdo_request_t request;
       
  2374 
       
  2375     EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
       
  2376             " slave_position = %u, index = 0x%04X, subindex = 0x%02X,"
       
  2377             " data = 0x%p, data_size = %zu, abort_code = 0x%p)\n",
       
  2378             __func__, master, slave_position, index, subindex,
       
  2379             data, data_size, abort_code);
       
  2380 
       
  2381     if (!data_size) {
       
  2382         EC_MASTER_ERR(master, "Zero data size!\n");
       
  2383         return -EINVAL;
       
  2384     }
       
  2385 
       
  2386     ec_sdo_request_init(&request.req);
       
  2387     ec_sdo_request_address(&request.req, index, subindex);
       
  2388     if (ec_sdo_request_alloc(&request.req, data_size)) {
       
  2389         ec_sdo_request_clear(&request.req);
       
  2390         return -ENOMEM;
       
  2391     }
       
  2392 
       
  2393     memcpy(request.req.data, data, data_size);
       
  2394     request.req.data_size = data_size;
       
  2395     ecrt_sdo_request_write(&request.req);
       
  2396 
       
  2397     if (down_interruptible(&master->master_sem))
       
  2398         return -EINTR;
       
  2399 
       
  2400     if (!(request.slave = ec_master_find_slave(master, 0, slave_position))) {
       
  2401         up(&master->master_sem);
       
  2402         EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
       
  2403         ec_sdo_request_clear(&request.req);
       
  2404         return -EINVAL;
       
  2405     }
       
  2406 
       
  2407     EC_SLAVE_DBG(request.slave, 1, "Schedule SDO download request.\n");
       
  2408 
       
  2409     // schedule request.
       
  2410     list_add_tail(&request.list, &request.slave->slave_sdo_requests);
       
  2411 
       
  2412     up(&master->master_sem);
       
  2413 
       
  2414     // wait for processing through FSM
       
  2415     if (wait_event_interruptible(request.slave->sdo_queue,
       
  2416                 request.req.state != EC_INT_REQUEST_QUEUED)) {
       
  2417         // interrupted by signal
       
  2418         down(&master->master_sem);
       
  2419         if (request.req.state == EC_INT_REQUEST_QUEUED) {
       
  2420             list_del(&request.list);
       
  2421             up(&master->master_sem);
       
  2422             ec_sdo_request_clear(&request.req);
       
  2423             return -EINTR;
       
  2424         }
       
  2425         // request already processing: interrupt not possible.
       
  2426         up(&master->master_sem);
       
  2427     }
       
  2428 
       
  2429     // wait until master FSM has finished processing
       
  2430     wait_event(request.slave->sdo_queue,
       
  2431             request.req.state != EC_INT_REQUEST_BUSY);
       
  2432 
       
  2433     EC_SLAVE_DBG(request.slave, 1, "Finished SDO download request.\n");
       
  2434 
       
  2435     *abort_code = request.req.abort_code;
       
  2436 
       
  2437     if (request.req.state == EC_INT_REQUEST_SUCCESS) {
       
  2438         return 0;
       
  2439     } else if (request.req.errno) {
       
  2440         return -request.req.errno;
       
  2441     } else {
       
  2442         return -EIO;
       
  2443     }
       
  2444 }
       
  2445 
       
  2446 /*****************************************************************************/
       
  2447 
       
  2448 int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
       
  2449         uint16_t index, uint8_t subindex, uint8_t *target,
       
  2450         size_t target_size, size_t *result_size, uint32_t *abort_code)
       
  2451 {
       
  2452     ec_master_sdo_request_t request;
       
  2453     int retval = 0;
       
  2454 
       
  2455     EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
       
  2456             " slave_position = %u, index = 0x%04X, subindex = 0x%02X,"
       
  2457             " target = 0x%p, target_size = %zu, result_size = 0x%p,"
       
  2458             " abort_code = 0x%p)\n",
       
  2459             __func__, master, slave_position, index, subindex,
       
  2460             target, target_size, result_size, abort_code);
       
  2461 
       
  2462     ec_sdo_request_init(&request.req);
       
  2463     ec_sdo_request_address(&request.req, index, subindex);
       
  2464     ecrt_sdo_request_read(&request.req);
       
  2465 
       
  2466     if (down_interruptible(&master->master_sem)) {
       
  2467         return -EINTR;
       
  2468     }
       
  2469 
       
  2470     if (!(request.slave = ec_master_find_slave(master, 0, slave_position))) {
       
  2471         up(&master->master_sem);
       
  2472         ec_sdo_request_clear(&request.req);
       
  2473         EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
       
  2474         return -EINVAL;
       
  2475     }
       
  2476 
       
  2477     EC_SLAVE_DBG(request.slave, 1, "Schedule SDO upload request.\n");
       
  2478 
       
  2479     // schedule request.
       
  2480     list_add_tail(&request.list, &request.slave->slave_sdo_requests);
       
  2481 
       
  2482     up(&master->master_sem);
       
  2483 
       
  2484     // wait for processing through FSM
       
  2485     if (wait_event_interruptible(request.slave->sdo_queue,
       
  2486                 request.req.state != EC_INT_REQUEST_QUEUED)) {
       
  2487         // interrupted by signal
       
  2488         down(&master->master_sem);
       
  2489         if (request.req.state == EC_INT_REQUEST_QUEUED) {
       
  2490             list_del(&request.list);
       
  2491             up(&master->master_sem);
       
  2492             ec_sdo_request_clear(&request.req);
       
  2493             return -EINTR;
       
  2494         }
       
  2495         // request already processing: interrupt not possible.
       
  2496         up(&master->master_sem);
       
  2497     }
       
  2498 
       
  2499     // wait until master FSM has finished processing
       
  2500     wait_event(request.slave->sdo_queue,
       
  2501             request.req.state != EC_INT_REQUEST_BUSY);
       
  2502 
       
  2503     EC_SLAVE_DBG(request.slave, 1, "Finished SDO upload request.\n");
       
  2504 
       
  2505     *abort_code = request.req.abort_code;
       
  2506 
       
  2507     if (request.req.state != EC_INT_REQUEST_SUCCESS) {
       
  2508         *result_size = 0;
       
  2509         if (request.req.errno) {
       
  2510             retval = -request.req.errno;
       
  2511         } else {
       
  2512             retval = -EIO;
       
  2513         }
       
  2514     } else {
       
  2515         if (request.req.data_size > target_size) {
       
  2516             EC_MASTER_ERR(master, "Buffer too small.\n");
       
  2517             ec_sdo_request_clear(&request.req);
       
  2518             return -EOVERFLOW;
       
  2519         }
       
  2520         memcpy(target, request.req.data, request.req.data_size);
       
  2521         *result_size = request.req.data_size;
       
  2522     }
       
  2523 
       
  2524     ec_sdo_request_clear(&request.req);
       
  2525     return retval;
       
  2526 }
       
  2527 
       
  2528 /*****************************************************************************/
       
  2529 
  2369 int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
  2530 int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
  2370         uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size,
  2531         uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size,
  2371         uint16_t *error_code)
  2532         uint16_t *error_code)
  2372 {
  2533 {
  2373     ec_master_soe_request_t request;
  2534     ec_master_soe_request_t request;
  2552 EXPORT_SYMBOL(ecrt_master_application_time);
  2713 EXPORT_SYMBOL(ecrt_master_application_time);
  2553 EXPORT_SYMBOL(ecrt_master_sync_reference_clock);
  2714 EXPORT_SYMBOL(ecrt_master_sync_reference_clock);
  2554 EXPORT_SYMBOL(ecrt_master_sync_slave_clocks);
  2715 EXPORT_SYMBOL(ecrt_master_sync_slave_clocks);
  2555 EXPORT_SYMBOL(ecrt_master_sync_monitor_queue);
  2716 EXPORT_SYMBOL(ecrt_master_sync_monitor_queue);
  2556 EXPORT_SYMBOL(ecrt_master_sync_monitor_process);
  2717 EXPORT_SYMBOL(ecrt_master_sync_monitor_process);
       
  2718 EXPORT_SYMBOL(ecrt_master_sdo_download);
       
  2719 EXPORT_SYMBOL(ecrt_master_sdo_upload);
  2557 EXPORT_SYMBOL(ecrt_master_write_idn);
  2720 EXPORT_SYMBOL(ecrt_master_write_idn);
  2558 EXPORT_SYMBOL(ecrt_master_read_idn);
  2721 EXPORT_SYMBOL(ecrt_master_read_idn);
  2559 EXPORT_SYMBOL(ecrt_master_reset);
  2722 EXPORT_SYMBOL(ecrt_master_reset);
  2560 
  2723 
  2561 /** \endcond */
  2724 /** \endcond */