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