master/fsm_master.c
changeset 1200 ce1a65f06efc
parent 1186 ff481f097c97
child 1209 8be462afb7f4
equal deleted inserted replaced
1199:30714bab3a04 1200:ce1a65f06efc
    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 /*****************************************************************************/