57 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *); |
57 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *); |
58 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
58 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
59 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
59 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
60 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
60 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
61 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
61 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
|
62 void ec_fsm_master_state_phy_request(ec_fsm_master_t *); |
62 |
63 |
63 /*****************************************************************************/ |
64 /*****************************************************************************/ |
64 |
65 |
65 /** Constructor. |
66 /** Constructor. |
66 */ |
67 */ |
322 return 0; |
323 return 0; |
323 } |
324 } |
324 |
325 |
325 /*****************************************************************************/ |
326 /*****************************************************************************/ |
326 |
327 |
|
328 /** Check for pending phy requests and process one. |
|
329 * |
|
330 * \return non-zero, if a phy request is processed. |
|
331 */ |
|
332 int ec_fsm_master_action_process_phy( |
|
333 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
334 ) |
|
335 { |
|
336 ec_master_t *master = fsm->master; |
|
337 ec_phy_request_t *request; |
|
338 |
|
339 // search the first request to be processed |
|
340 while (1) { |
|
341 if (list_empty(&master->phy_requests)) |
|
342 break; |
|
343 |
|
344 // get first request |
|
345 request = list_entry(master->phy_requests.next, |
|
346 ec_phy_request_t, list); |
|
347 list_del_init(&request->list); // dequeue |
|
348 request->state = EC_REQUEST_BUSY; |
|
349 |
|
350 // found pending request; process it! |
|
351 if (master->debug_level) |
|
352 EC_DBG("Processing phy request for slave %u...\n", |
|
353 request->slave->ring_position); |
|
354 fsm->phy_request = request; |
|
355 |
|
356 if (request->dir == EC_DIR_INPUT) { |
|
357 ec_datagram_fprd(fsm->datagram, request->slave->station_address, |
|
358 request->offset, request->length); |
|
359 } else { |
|
360 if (request->length > fsm->datagram->mem_size) { |
|
361 EC_ERR("Request length (%u) exceeds maximum datagram size (%u)!\n", |
|
362 request->length, fsm->datagram->mem_size); |
|
363 request->state = EC_REQUEST_FAILURE; |
|
364 wake_up(&master->phy_queue); |
|
365 continue; |
|
366 } |
|
367 ec_datagram_fpwr(fsm->datagram, request->slave->station_address, |
|
368 request->offset, request->length); |
|
369 memcpy(fsm->datagram->data, request->data, request->length); |
|
370 } |
|
371 fsm->retries = EC_FSM_RETRIES; |
|
372 fsm->state = ec_fsm_master_state_phy_request; |
|
373 return 1; |
|
374 } |
|
375 |
|
376 return 0; |
|
377 } |
|
378 |
|
379 /*****************************************************************************/ |
|
380 |
327 /** Check for pending Sdo requests and process one. |
381 /** Check for pending Sdo requests and process one. |
328 * |
382 * |
329 * \return non-zero, if an Sdo request is processed. |
383 * \return non-zero, if an Sdo request is processed. |
330 */ |
384 */ |
331 int ec_fsm_master_action_process_sdo( |
385 int ec_fsm_master_action_process_sdo( |
457 } |
511 } |
458 |
512 |
459 // check for pending SII write operations. |
513 // check for pending SII write operations. |
460 if (ec_fsm_master_action_process_sii(fsm)) |
514 if (ec_fsm_master_action_process_sii(fsm)) |
461 return; // SII write request found |
515 return; // SII write request found |
|
516 |
|
517 // check for pending phy requests. |
|
518 if (ec_fsm_master_action_process_phy(fsm)) |
|
519 return; // phy request processing |
462 |
520 |
463 ec_fsm_master_restart(fsm); |
521 ec_fsm_master_restart(fsm); |
464 } |
522 } |
465 |
523 |
466 /*****************************************************************************/ |
524 /*****************************************************************************/ |
860 |
918 |
861 ec_fsm_master_restart(fsm); |
919 ec_fsm_master_restart(fsm); |
862 } |
920 } |
863 |
921 |
864 /*****************************************************************************/ |
922 /*****************************************************************************/ |
|
923 |
|
924 /** Master state: PHY. |
|
925 */ |
|
926 void ec_fsm_master_state_phy_request( |
|
927 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
928 ) |
|
929 { |
|
930 ec_master_t *master = fsm->master; |
|
931 ec_datagram_t *datagram = fsm->datagram; |
|
932 ec_phy_request_t *request = fsm->phy_request; |
|
933 |
|
934 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
935 EC_ERR("Failed to receive phy request datagram (state %u).\n", |
|
936 datagram->state); |
|
937 request->state = EC_REQUEST_FAILURE; |
|
938 wake_up(&master->phy_queue); |
|
939 ec_fsm_master_restart(fsm); |
|
940 return; |
|
941 } |
|
942 |
|
943 if (request->dir == EC_DIR_INPUT) { // read request |
|
944 if (request->data) |
|
945 kfree(request->data); |
|
946 request->data = kmalloc(request->length, GFP_KERNEL); |
|
947 if (!request->data) { |
|
948 EC_ERR("Failed to allocate %u bytes of memory for phy request.\n", |
|
949 request->length); |
|
950 request->state = EC_REQUEST_FAILURE; |
|
951 wake_up(&master->phy_queue); |
|
952 ec_fsm_master_restart(fsm); |
|
953 return; |
|
954 } |
|
955 memcpy(request->data, datagram->data, request->length); |
|
956 } |
|
957 |
|
958 request->state = EC_REQUEST_SUCCESS; |
|
959 wake_up(&master->phy_queue); |
|
960 |
|
961 // check for another PHY request |
|
962 if (ec_fsm_master_action_process_phy(fsm)) |
|
963 return; // processing another request |
|
964 |
|
965 ec_fsm_master_restart(fsm); |
|
966 } |
|
967 |
|
968 /*****************************************************************************/ |