master/fsm_master.c
changeset 1335 09c6fce1ae45
parent 1327 4d179b06dd3c
child 1336 e27b37e80a99
equal deleted inserted replaced
1334:da3d22a27500 1335:09c6fce1ae45
    37 #ifdef EC_EOE
    37 #ifdef EC_EOE
    38 #include "ethernet.h"
    38 #include "ethernet.h"
    39 #endif
    39 #endif
    40 
    40 
    41 #include "fsm_master.h"
    41 #include "fsm_master.h"
       
    42 #include "fsm_foe.h"
    42 
    43 
    43 /*****************************************************************************/
    44 /*****************************************************************************/
    44 
    45 
    45 void ec_fsm_master_state_start(ec_fsm_master_t *);
    46 void ec_fsm_master_state_start(ec_fsm_master_t *);
    46 void ec_fsm_master_state_broadcast(ec_fsm_master_t *);
    47 void ec_fsm_master_state_broadcast(ec_fsm_master_t *);
    51 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *);
    52 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *);
    52 void ec_fsm_master_state_write_sii(ec_fsm_master_t *);
    53 void ec_fsm_master_state_write_sii(ec_fsm_master_t *);
    53 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *);
    54 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *);
    54 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *);
    55 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *);
    55 void ec_fsm_master_state_phy_request(ec_fsm_master_t *);
    56 void ec_fsm_master_state_phy_request(ec_fsm_master_t *);
       
    57 void ec_fsm_master_state_foe_request(ec_fsm_master_t *);
    56 
    58 
    57 /*****************************************************************************/
    59 /*****************************************************************************/
    58 
    60 
    59 /** Constructor.
    61 /** Constructor.
    60  */
    62  */
    72     fsm->topology_change_pending = 0;
    74     fsm->topology_change_pending = 0;
    73     fsm->slave_states = EC_SLAVE_STATE_UNKNOWN;
    75     fsm->slave_states = EC_SLAVE_STATE_UNKNOWN;
    74 
    76 
    75     // init sub-state-machines
    77     // init sub-state-machines
    76     ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram);
    78     ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram);
       
    79     ec_fsm_foe_init(&fsm->fsm_foe, fsm->datagram);
    77     ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe);
    80     ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe);
    78     ec_fsm_change_init(&fsm->fsm_change, fsm->datagram);
    81     ec_fsm_change_init(&fsm->fsm_change, fsm->datagram);
    79     ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram,
    82     ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram,
    80             &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_pdo);
    83             &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_pdo);
    81     ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram,
    84     ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram,
    91         ec_fsm_master_t *fsm /**< Master state machine. */
    94         ec_fsm_master_t *fsm /**< Master state machine. */
    92         )
    95         )
    93 {
    96 {
    94     // clear sub-state machines
    97     // clear sub-state machines
    95     ec_fsm_coe_clear(&fsm->fsm_coe);
    98     ec_fsm_coe_clear(&fsm->fsm_coe);
       
    99     ec_fsm_foe_clear(&fsm->fsm_foe);
    96     ec_fsm_pdo_clear(&fsm->fsm_pdo);
   100     ec_fsm_pdo_clear(&fsm->fsm_pdo);
    97     ec_fsm_change_clear(&fsm->fsm_change);
   101     ec_fsm_change_clear(&fsm->fsm_change);
    98     ec_fsm_slave_config_clear(&fsm->fsm_slave_config);
   102     ec_fsm_slave_config_clear(&fsm->fsm_slave_config);
    99     ec_fsm_slave_scan_clear(&fsm->fsm_slave_scan);
   103     ec_fsm_slave_scan_clear(&fsm->fsm_slave_scan);
   100     ec_fsm_sii_clear(&fsm->fsm_sii);
   104     ec_fsm_sii_clear(&fsm->fsm_sii);
   209         if (!master->allow_scan) {
   213         if (!master->allow_scan) {
   210             up(&master->scan_sem);
   214             up(&master->scan_sem);
   211         } else {
   215         } else {
   212             master->scan_busy = 1;
   216             master->scan_busy = 1;
   213             up(&master->scan_sem);
   217             up(&master->scan_sem);
   214             
   218 
   215             // topology change when scan is allowed:
   219             // topology change when scan is allowed:
   216             // clear all slaves and scan the bus
   220             // clear all slaves and scan the bus
   217             fsm->topology_change_pending = 0;
   221             fsm->topology_change_pending = 0;
   218             fsm->idle = 0;
   222             fsm->idle = 0;
   219             fsm->scan_jiffies = jiffies;
   223             fsm->scan_jiffies = jiffies;
   279 }
   283 }
   280 
   284 
   281 /*****************************************************************************/
   285 /*****************************************************************************/
   282 
   286 
   283 /** Check for pending SII write requests and process one.
   287 /** Check for pending SII write requests and process one.
   284  * 
   288  *
   285  * \return non-zero, if an SII write request is processed.
   289  * \return non-zero, if an SII write request is processed.
   286  */
   290  */
   287 int ec_fsm_master_action_process_sii(
   291 int ec_fsm_master_action_process_sii(
   288         ec_fsm_master_t *fsm /**< Master state machine. */
   292         ec_fsm_master_t *fsm /**< Master state machine. */
   289         )
   293         )
   373 }
   377 }
   374 
   378 
   375 /*****************************************************************************/
   379 /*****************************************************************************/
   376 
   380 
   377 /** Check for pending SDO requests and process one.
   381 /** Check for pending SDO requests and process one.
   378  * 
   382  *
   379  * \return non-zero, if an SDO request is processed.
   383  * \return non-zero, if an SDO request is processed.
   380  */
   384  */
   381 int ec_fsm_master_action_process_sdo(
   385 int ec_fsm_master_action_process_sdo(
   382         ec_fsm_master_t *fsm /**< Master state machine. */
   386         ec_fsm_master_t *fsm /**< Master state machine. */
   383         )
   387         )
   422                 ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
   426                 ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
   423                 return 1;
   427                 return 1;
   424             }
   428             }
   425         }
   429         }
   426     }
   430     }
   427     
   431 
   428     // search the first external request to be processed
   432     // search the first external request to be processed
   429     while (1) {
   433     while (1) {
   430         if (list_empty(&master->slave_sdo_requests))
   434         if (list_empty(&master->slave_sdo_requests))
   431             break;
   435             break;
   432 
   436 
   455         fsm->sdo_request = &request->req;
   459         fsm->sdo_request = &request->req;
   456         fsm->slave = slave;
   460         fsm->slave = slave;
   457         fsm->state = ec_fsm_master_state_sdo_request;
   461         fsm->state = ec_fsm_master_state_sdo_request;
   458         ec_fsm_coe_transfer(&fsm->fsm_coe, slave, &request->req);
   462         ec_fsm_coe_transfer(&fsm->fsm_coe, slave, &request->req);
   459         ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
   463         ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
       
   464         return 1;
       
   465     }
       
   466 
       
   467     return 0;
       
   468 }
       
   469 
       
   470 /*****************************************************************************/
       
   471 
       
   472 /** Check for pending FoE requests and process one.
       
   473  *
       
   474  * \return non-zero, if an FoE request is processed.
       
   475  */
       
   476 int ec_fsm_master_action_process_foe(
       
   477         ec_fsm_master_t *fsm /**< Master state machine. */
       
   478         )
       
   479 {
       
   480     ec_master_t *master = fsm->master;
       
   481     ec_slave_t *slave;
       
   482     ec_master_foe_request_t *request;
       
   483 
       
   484     // search the first request to be processed
       
   485     while (1) {
       
   486         if (list_empty(&master->foe_requests))
       
   487             break;
       
   488 
       
   489         // get first request
       
   490         request = list_entry(master->foe_requests.next,
       
   491                 ec_master_foe_request_t, list);
       
   492         list_del_init(&request->list); // dequeue
       
   493         request->req.state = EC_REQUEST_BUSY;
       
   494         slave = request->slave;
       
   495 
       
   496         EC_DBG("---- Master read command from queue ----\n");
       
   497         // found pending FOE write operation. execute it!
       
   498         if (master->debug_level)
       
   499             EC_DBG("Writing FOE data to slave %u...\n",
       
   500                     request->slave->ring_position);
       
   501 
       
   502         fsm->foe_request = &request->req;
       
   503         fsm->slave = slave;
       
   504         fsm->state = ec_fsm_master_state_foe_request;
       
   505         ec_fsm_foe_transfer(&fsm->fsm_foe, slave, &request->req);
       
   506         //(&fsm->fsm_foe, request->slave, request->offset, request->words);
       
   507         ec_fsm_foe_exec(&fsm->fsm_foe);
   460         return 1;
   508         return 1;
   461     }
   509     }
   462 
   510 
   463     return 0;
   511     return 0;
   464 }
   512 }
   719 void ec_fsm_master_state_scan_slave(
   767 void ec_fsm_master_state_scan_slave(
   720         ec_fsm_master_t *fsm /**< Master state machine. */
   768         ec_fsm_master_t *fsm /**< Master state machine. */
   721         )
   769         )
   722 {
   770 {
   723     ec_master_t *master = fsm->master;
   771     ec_master_t *master = fsm->master;
       
   772 #ifdef EC_EOE
   724     ec_slave_t *slave = fsm->slave;
   773     ec_slave_t *slave = fsm->slave;
   725 
   774 #endif
   726     if (ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan))
   775     if (ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan))
   727         return;
   776         return;
   728 
   777 
   729 #ifdef EC_EOE
   778 #ifdef EC_EOE
   730     if (slave->sii.mailbox_protocols & EC_MBOX_EOE) {
   779     if (slave->sii.mailbox_protocols & EC_MBOX_EOE) {
   838     if (request->offset <= 4 && request->offset + request->nwords > 4) {
   887     if (request->offset <= 4 && request->offset + request->nwords > 4) {
   839         // alias was written
   888         // alias was written
   840         slave->sii.alias = EC_READ_U16(request->words + 4);
   889         slave->sii.alias = EC_READ_U16(request->words + 4);
   841     }
   890     }
   842     // TODO: Evaluate other SII contents!
   891     // TODO: Evaluate other SII contents!
   843     
   892 
   844     request->state = EC_INT_REQUEST_SUCCESS;
   893     request->state = EC_INT_REQUEST_SUCCESS;
   845     wake_up(&master->sii_queue);
   894     wake_up(&master->sii_queue);
   846 
   895 
   847     // check for another SII write request
   896     // check for another SII write request
   848     if (ec_fsm_master_action_process_sii(fsm))
   897     if (ec_fsm_master_action_process_sii(fsm))
   849         return; // processing another request
   898         return; // processing another request
       
   899 
       
   900     ec_fsm_master_restart(fsm);
       
   901 }
       
   902 
       
   903 /*****************************************************************************/
       
   904 
       
   905 /** Master state: WRITE FOE.
       
   906  */
       
   907 void ec_fsm_master_state_foe_request(
       
   908 		ec_fsm_master_t *fsm /**< Master state machine. */
       
   909         )
       
   910 {
       
   911     ec_master_t *master = fsm->master;
       
   912     ec_foe_request_t *request = fsm->foe_request;
       
   913     ec_slave_t *slave = fsm->slave;
       
   914 
       
   915     if (ec_fsm_foe_exec(&fsm->fsm_foe)) return;
       
   916 
       
   917     if (!ec_fsm_foe_success(&fsm->fsm_foe)) {
       
   918         EC_ERR("Failed to handle FOE request to slave %u.\n",
       
   919                 slave->ring_position);
       
   920         request->state = EC_INT_REQUEST_FAILURE;
       
   921         wake_up(&master->foe_queue);
       
   922         ec_fsm_master_restart(fsm);
       
   923         return;
       
   924     }
       
   925 
       
   926     // finished writing FOE
       
   927     if (master->debug_level)
       
   928         EC_DBG("Finished writing %u words of FOE data to slave %u.\n",
       
   929                 request->data_size, slave->ring_position);
       
   930 
       
   931     request->state = EC_INT_REQUEST_SUCCESS;
       
   932     wake_up(&master->foe_queue);
   850 
   933 
   851     ec_fsm_master_restart(fsm);
   934     ec_fsm_master_restart(fsm);
   852 }
   935 }
   853 
   936 
   854 /*****************************************************************************/
   937 /*****************************************************************************/
   904         wake_up(&master->sdo_queue);
   987         wake_up(&master->sdo_queue);
   905         ec_fsm_master_restart(fsm);
   988         ec_fsm_master_restart(fsm);
   906         return;
   989         return;
   907     }
   990     }
   908 
   991 
   909     // SDO request finished 
   992     // SDO request finished
   910     request->state = EC_INT_REQUEST_SUCCESS;
   993     request->state = EC_INT_REQUEST_SUCCESS;
   911     wake_up(&master->sdo_queue);
   994     wake_up(&master->sdo_queue);
   912 
   995 
   913     if (master->debug_level)
   996     if (master->debug_level)
   914         EC_DBG("Finished SDO request for slave %u.\n",
   997         EC_DBG("Finished SDO request for slave %u.\n",