master/fsm_master.c
changeset 1597 491dea6f4fd7
parent 1596 ea8d2b4ee742
child 1601 a784812c787f
equal deleted inserted replaced
1596:ea8d2b4ee742 1597:491dea6f4fd7
    56 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *);
    56 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *);
    57 void ec_fsm_master_state_write_sii(ec_fsm_master_t *);
    57 void ec_fsm_master_state_write_sii(ec_fsm_master_t *);
    58 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *);
    58 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *);
    59 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *);
    59 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *);
    60 void ec_fsm_master_state_reg_request(ec_fsm_master_t *);
    60 void ec_fsm_master_state_reg_request(ec_fsm_master_t *);
    61 void ec_fsm_master_state_foe_request(ec_fsm_master_t *);
       
    62 
    61 
    63 
    62 
    64 /*****************************************************************************/
    63 /*****************************************************************************/
    65 
    64 
    66 /** Constructor.
    65 /** Constructor.
    80     fsm->topology_change_pending = 0;
    79     fsm->topology_change_pending = 0;
    81     fsm->slave_states = EC_SLAVE_STATE_UNKNOWN;
    80     fsm->slave_states = EC_SLAVE_STATE_UNKNOWN;
    82 
    81 
    83     // init sub-state-machines
    82     // init sub-state-machines
    84     ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram);
    83     ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram);
    85     ec_fsm_foe_init(&fsm->fsm_foe, fsm->datagram);
       
    86     ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe);
    84     ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe);
    87     ec_fsm_change_init(&fsm->fsm_change, fsm->datagram);
    85     ec_fsm_change_init(&fsm->fsm_change, fsm->datagram);
    88     ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram,
    86     ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram,
    89             &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_pdo);
    87             &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_pdo);
    90     ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram,
    88     ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram,
   100         ec_fsm_master_t *fsm /**< Master state machine. */
    98         ec_fsm_master_t *fsm /**< Master state machine. */
   101         )
    99         )
   102 {
   100 {
   103     // clear sub-state machines
   101     // clear sub-state machines
   104     ec_fsm_coe_clear(&fsm->fsm_coe);
   102     ec_fsm_coe_clear(&fsm->fsm_coe);
   105     ec_fsm_foe_clear(&fsm->fsm_foe);
       
   106     ec_fsm_pdo_clear(&fsm->fsm_pdo);
   103     ec_fsm_pdo_clear(&fsm->fsm_pdo);
   107     ec_fsm_change_clear(&fsm->fsm_change);
   104     ec_fsm_change_clear(&fsm->fsm_change);
   108     ec_fsm_slave_config_clear(&fsm->fsm_slave_config);
   105     ec_fsm_slave_config_clear(&fsm->fsm_slave_config);
   109     ec_fsm_slave_scan_clear(&fsm->fsm_slave_scan);
   106     ec_fsm_slave_scan_clear(&fsm->fsm_slave_scan);
   110     ec_fsm_sii_clear(&fsm->fsm_sii);
   107     ec_fsm_sii_clear(&fsm->fsm_sii);
   454         }
   451         }
   455     }
   452     }
   456     return 0;
   453     return 0;
   457 }
   454 }
   458 
   455 
   459 /*****************************************************************************/
   456 
   460 
   457 /*****************************************************************************/
   461 /** Check for pending FoE requests and process one.
   458 
   462  *
   459 /** Master action: IDLE.
   463  * \return non-zero, if an FoE request is processed.
   460  *
   464  */
   461  * Does secondary work.
   465 int ec_fsm_master_action_process_foe(
   462  */
       
   463 void ec_fsm_master_action_idle(
   466         ec_fsm_master_t *fsm /**< Master state machine. */
   464         ec_fsm_master_t *fsm /**< Master state machine. */
   467         )
   465         )
   468 {
   466 {
   469     ec_master_t *master = fsm->master;
   467     ec_master_t *master = fsm->master;
   470     ec_slave_t *slave;
   468     ec_slave_t *slave;
   471     ec_master_foe_request_t *request;
   469 
   472 
   470     // Check for pending internal SDO requests
   473     // search the first request to be processed
       
   474     while (1) {
       
   475         if (list_empty(&master->foe_requests))
       
   476             break;
       
   477 
       
   478         // get first request
       
   479         request = list_entry(master->foe_requests.next,
       
   480                 ec_master_foe_request_t, list);
       
   481         list_del_init(&request->list); // dequeue
       
   482         request->req.state = EC_INT_REQUEST_BUSY;
       
   483         slave = request->slave;
       
   484 
       
   485         if (master->debug_level)
       
   486             EC_DBG("Processing FoE request for slave %u.\n",
       
   487                     slave->ring_position);
       
   488 
       
   489         fsm->foe_request = &request->req;
       
   490         fsm->slave = slave;
       
   491         fsm->state = ec_fsm_master_state_foe_request;
       
   492         fsm->idle = 0;
       
   493         ec_fsm_foe_transfer(&fsm->fsm_foe, slave, &request->req);
       
   494         ec_fsm_foe_exec(&fsm->fsm_foe);
       
   495         return 1;
       
   496     }
       
   497 
       
   498     return 0;
       
   499 }
       
   500 
       
   501 /*****************************************************************************/
       
   502 
       
   503 /** Master action: IDLE.
       
   504  *
       
   505  * Does secondary work.
       
   506  */
       
   507 void ec_fsm_master_action_idle(
       
   508         ec_fsm_master_t *fsm /**< Master state machine. */
       
   509         )
       
   510 {
       
   511     ec_master_t *master = fsm->master;
       
   512     ec_slave_t *slave;
       
   513 
       
   514     // Check for pending SDO requests
       
   515     if (ec_fsm_master_action_process_sdo(fsm))
   471     if (ec_fsm_master_action_process_sdo(fsm))
   516         return;
       
   517 
       
   518     // Check for pending FoE requests
       
   519     if (ec_fsm_master_action_process_foe(fsm))
       
   520         return;
   472         return;
   521 
   473 
   522     // check, if slaves have an SDO dictionary to read out.
   474     // check, if slaves have an SDO dictionary to read out.
   523     for (slave = master->slaves;
   475     for (slave = master->slaves;
   524             slave < master->slaves + master->slave_count;
   476             slave < master->slaves + master->slave_count;
   924     wake_up(&master->sii_queue);
   876     wake_up(&master->sii_queue);
   925 
   877 
   926     // check for another SII write request
   878     // check for another SII write request
   927     if (ec_fsm_master_action_process_sii(fsm))
   879     if (ec_fsm_master_action_process_sii(fsm))
   928         return; // processing another request
   880         return; // processing another request
   929 
       
   930     ec_fsm_master_restart(fsm);
       
   931 }
       
   932 
       
   933 /*****************************************************************************/
       
   934 
       
   935 /** Master state: WRITE FOE.
       
   936  */
       
   937 void ec_fsm_master_state_foe_request(
       
   938         ec_fsm_master_t *fsm /**< Master state machine. */
       
   939         )
       
   940 {
       
   941     ec_master_t *master = fsm->master;
       
   942     ec_foe_request_t *request = fsm->foe_request;
       
   943     ec_slave_t *slave = fsm->slave;
       
   944 
       
   945     if (ec_fsm_foe_exec(&fsm->fsm_foe))
       
   946         return;
       
   947 
       
   948     fsm->idle = 1;
       
   949 
       
   950     if (!ec_fsm_foe_success(&fsm->fsm_foe)) {
       
   951         EC_ERR("Failed to handle FoE request to slave %u.\n",
       
   952                 slave->ring_position);
       
   953         request->state = EC_INT_REQUEST_FAILURE;
       
   954         wake_up(&master->foe_queue);
       
   955         ec_fsm_master_restart(fsm);
       
   956         return;
       
   957     }
       
   958 
       
   959     // finished transferring FoE
       
   960     if (master->debug_level)
       
   961         EC_DBG("Successfully transferred %u bytes of FoE data from/to"
       
   962                 " slave %u.\n", request->data_size, slave->ring_position);
       
   963 
       
   964     request->state = EC_INT_REQUEST_SUCCESS;
       
   965     wake_up(&master->foe_queue);
       
   966 
   881 
   967     ec_fsm_master_restart(fsm);
   882     ec_fsm_master_restart(fsm);
   968 }
   883 }
   969 
   884 
   970 /*****************************************************************************/
   885 /*****************************************************************************/