master/fsm_master.c
changeset 1031 000593b576dd
parent 1029 61ffe5f22306
child 1064 5f27403587a8
equal deleted inserted replaced
1030:d7970e934dba 1031:000593b576dd
    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_end(ec_fsm_master_t *);
       
    63 void ec_fsm_master_state_error(ec_fsm_master_t *);
       
    64 
    62 
    65 /*****************************************************************************/
    63 /*****************************************************************************/
    66 
    64 
    67 /** Constructor.
    65 /** Constructor.
    68  */
    66  */
   111 
   109 
   112 /** Executes the current state of the state machine.
   110 /** Executes the current state of the state machine.
   113  *
   111  *
   114  * If the state machine's datagram is not sent or received yet, the execution
   112  * If the state machine's datagram is not sent or received yet, the execution
   115  * of the state machine is delayed to the next cycle.
   113  * of the state machine is delayed to the next cycle.
   116  *
   114  */
   117  * \return false, if state machine has terminated
   115 void ec_fsm_master_exec(
   118  */
       
   119 int ec_fsm_master_exec(
       
   120         ec_fsm_master_t *fsm /**< Master state machine. */
   116         ec_fsm_master_t *fsm /**< Master state machine. */
   121         )
   117         )
   122 {
   118 {
   123     if (fsm->datagram->state == EC_DATAGRAM_SENT
   119     if (fsm->datagram->state == EC_DATAGRAM_SENT
   124         || fsm->datagram->state == EC_DATAGRAM_QUEUED) {
   120         || fsm->datagram->state == EC_DATAGRAM_QUEUED) {
   125         // datagram was not sent or received yet.
   121         // datagram was not sent or received yet.
   126         return ec_fsm_master_running(fsm);
   122         return;
   127     }
   123     }
   128 
   124 
   129     fsm->state(fsm);
   125     fsm->state(fsm);
   130     return ec_fsm_master_running(fsm);
       
   131 }
       
   132 
       
   133 /*****************************************************************************/
       
   134 
       
   135 /**
       
   136  * \return false, if state machine has terminated
       
   137  */
       
   138 int ec_fsm_master_running(
       
   139         const ec_fsm_master_t *fsm /**< Master state machine. */
       
   140         )
       
   141 {
       
   142     return fsm->state != ec_fsm_master_state_end
       
   143         && fsm->state != ec_fsm_master_state_error;
       
   144 }
   126 }
   145 
   127 
   146 /*****************************************************************************/
   128 /*****************************************************************************/
   147 
   129 
   148 /**
   130 /**
   151 int ec_fsm_master_idle(
   133 int ec_fsm_master_idle(
   152         const ec_fsm_master_t *fsm /**< Master state machine. */
   134         const ec_fsm_master_t *fsm /**< Master state machine. */
   153         )
   135         )
   154 {
   136 {
   155     return fsm->idle;
   137     return fsm->idle;
       
   138 }
       
   139 
       
   140 /*****************************************************************************/
       
   141 
       
   142 /** Restarts the master state machine.
       
   143  */
       
   144 void ec_fsm_master_restart(
       
   145         ec_fsm_master_t *fsm /**< Master state machine. */
       
   146         )
       
   147 {
       
   148     fsm->state = ec_fsm_master_state_start;
       
   149     fsm->state(fsm); // execute immediately
   156 }
   150 }
   157 
   151 
   158 /******************************************************************************
   152 /******************************************************************************
   159  * Master state machine
   153  * Master state machine
   160  *****************************************************************************/
   154  *****************************************************************************/
   196         fsm->slaves_responding = datagram->working_counter;
   190         fsm->slaves_responding = datagram->working_counter;
   197         EC_INFO("%u slave(s) responding.\n", fsm->slaves_responding);
   191         EC_INFO("%u slave(s) responding.\n", fsm->slaves_responding);
   198     }
   192     }
   199 
   193 
   200     if (datagram->state != EC_DATAGRAM_RECEIVED) { // link is down
   194     if (datagram->state != EC_DATAGRAM_RECEIVED) { // link is down
   201         fsm->state = ec_fsm_master_state_error;
   195         ec_fsm_master_restart(fsm);
   202         return;
   196         return;
   203     }
   197     }
   204 
   198 
   205     if (fsm->slaves_responding) {
   199     if (fsm->slaves_responding) {
   206         uint8_t states = EC_READ_U8(datagram->data);
   200         uint8_t states = EC_READ_U8(datagram->data);
   238 
   232 
   239             if (!master->slave_count) {
   233             if (!master->slave_count) {
   240                 // no slaves present -> finish state machine.
   234                 // no slaves present -> finish state machine.
   241                 master->scan_busy = 0;
   235                 master->scan_busy = 0;
   242                 wake_up_interruptible(&master->scan_queue);
   236                 wake_up_interruptible(&master->scan_queue);
   243                 fsm->state = ec_fsm_master_state_end;
   237                 ec_fsm_master_restart(fsm);
   244                 return;
   238                 return;
   245             }
   239             }
   246 
   240 
   247             size = sizeof(ec_slave_t) * master->slave_count;
   241             size = sizeof(ec_slave_t) * master->slave_count;
   248             if (!(master->slaves = (ec_slave_t *) kmalloc(size, GFP_KERNEL))) {
   242             if (!(master->slaves = (ec_slave_t *) kmalloc(size, GFP_KERNEL))) {
   249                 EC_ERR("Failed to allocate %u bytes of slave memory!\n",
   243                 EC_ERR("Failed to allocate %u bytes of slave memory!\n",
   250                         size);
   244                         size);
   251                 master->slave_count = 0; // FIXME avoid scanning!
   245                 master->slave_count = 0; // FIXME avoid scanning!
   252                 master->scan_busy = 0;
   246                 master->scan_busy = 0;
   253                 wake_up_interruptible(&master->scan_queue);
   247                 wake_up_interruptible(&master->scan_queue);
   254                 fsm->state = ec_fsm_master_state_error;
   248                 ec_fsm_master_restart(fsm);
   255                 return;
   249                 return;
   256             }
   250             }
   257 
   251 
   258             // init slaves
   252             // init slaves
   259             for (i = 0; i < master->slave_count; i++) {
   253             for (i = 0; i < master->slave_count; i++) {
   281         ec_datagram_fprd(fsm->datagram, fsm->slave->station_address,
   275         ec_datagram_fprd(fsm->datagram, fsm->slave->station_address,
   282                 0x0130, 2);
   276                 0x0130, 2);
   283         fsm->retries = EC_FSM_RETRIES;
   277         fsm->retries = EC_FSM_RETRIES;
   284         fsm->state = ec_fsm_master_state_read_state;
   278         fsm->state = ec_fsm_master_state_read_state;
   285     } else {
   279     } else {
   286         fsm->state = ec_fsm_master_state_end;
   280         ec_fsm_master_restart(fsm);
   287     }
   281     }
   288 }
   282 }
   289 
   283 
   290 /*****************************************************************************/
   284 /*****************************************************************************/
   291 
   285 
   469 
   463 
   470     // check for pending SII write operations.
   464     // check for pending SII write operations.
   471     if (ec_fsm_master_action_process_sii(fsm))
   465     if (ec_fsm_master_action_process_sii(fsm))
   472         return; // SII write request found
   466         return; // SII write request found
   473 
   467 
   474     fsm->state = ec_fsm_master_state_end;
   468     ec_fsm_master_restart(fsm);
   475 }
   469 }
   476 
   470 
   477 /*****************************************************************************/
   471 /*****************************************************************************/
   478 
   472 
   479 /** Master action: Get state of next slave.
   473 /** Master action: Get state of next slave.
   566 
   560 
   567     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   561     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   568         EC_ERR("Failed to receive AL state datagram for slave %u"
   562         EC_ERR("Failed to receive AL state datagram for slave %u"
   569                 " (datagram state %u)\n",
   563                 " (datagram state %u)\n",
   570                 slave->ring_position, datagram->state);
   564                 slave->ring_position, datagram->state);
   571         fsm->state = ec_fsm_master_state_error;
   565         ec_fsm_master_restart(fsm);
   572         return;
   566         return;
   573     }
   567     }
   574 
   568 
   575     // did the slave not respond to its station address?
   569     // did the slave not respond to its station address?
   576     if (datagram->working_counter != 1) {
   570     if (datagram->working_counter != 1) {
   579             if (fsm->master->debug_level)
   573             if (fsm->master->debug_level)
   580                 EC_DBG("Slave %u did not respond to state query.\n",
   574                 EC_DBG("Slave %u did not respond to state query.\n",
   581                         fsm->slave->ring_position);
   575                         fsm->slave->ring_position);
   582         }
   576         }
   583         fsm->topology_change_pending = 1;
   577         fsm->topology_change_pending = 1;
   584         fsm->state = ec_fsm_master_state_error;
   578         ec_fsm_master_restart(fsm);
   585         return;
   579         return;
   586     }
   580     }
   587 
   581 
   588     // A single slave responded
   582     // A single slave responded
   589     ec_slave_set_state(slave, EC_READ_U8(datagram->data));
   583     ec_slave_set_state(slave, EC_READ_U8(datagram->data));
   646     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   640     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   647         EC_ERR("Failed to receive address clearing datagram (state %u).\n",
   641         EC_ERR("Failed to receive address clearing datagram (state %u).\n",
   648                 datagram->state);
   642                 datagram->state);
   649         master->scan_busy = 0;
   643         master->scan_busy = 0;
   650         wake_up_interruptible(&master->scan_queue);
   644         wake_up_interruptible(&master->scan_queue);
   651         fsm->state = ec_fsm_master_state_error;
   645         ec_fsm_master_restart(fsm);
   652         return;
   646         return;
   653     }
   647     }
   654 
   648 
   655     if (datagram->working_counter != master->slave_count) {
   649     if (datagram->working_counter != master->slave_count) {
   656         EC_WARN("Failed to clear all station addresses: Cleared %u of %u",
   650         EC_WARN("Failed to clear all station addresses: Cleared %u of %u",
   719 #ifdef EC_EOE
   713 #ifdef EC_EOE
   720     // check if EoE processing has to be started
   714     // check if EoE processing has to be started
   721     ec_master_eoe_start(master);
   715     ec_master_eoe_start(master);
   722 #endif
   716 #endif
   723 
   717 
   724     fsm->state = ec_fsm_master_state_end;
   718     ec_fsm_master_restart(fsm);
   725 }
   719 }
   726 
   720 
   727 /*****************************************************************************/
   721 /*****************************************************************************/
   728 
   722 
   729 /** Master state: CONFIGURE SLAVE.
   723 /** Master state: CONFIGURE SLAVE.
   768     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
   762     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
   769         EC_ERR("Failed to write SII data to slave %u.\n",
   763         EC_ERR("Failed to write SII data to slave %u.\n",
   770                 slave->ring_position);
   764                 slave->ring_position);
   771         request->state = EC_REQUEST_FAILURE;
   765         request->state = EC_REQUEST_FAILURE;
   772         wake_up(&master->sii_queue);
   766         wake_up(&master->sii_queue);
   773         fsm->state = ec_fsm_master_state_error;
   767         ec_fsm_master_restart(fsm);
   774         return;
   768         return;
   775     }
   769     }
   776 
   770 
   777     fsm->sii_index++;
   771     fsm->sii_index++;
   778     if (fsm->sii_index < request->nwords) {
   772     if (fsm->sii_index < request->nwords) {
   795 
   789 
   796     // check for another SII write request
   790     // check for another SII write request
   797     if (ec_fsm_master_action_process_sii(fsm))
   791     if (ec_fsm_master_action_process_sii(fsm))
   798         return; // processing another request
   792         return; // processing another request
   799 
   793 
   800     fsm->state = ec_fsm_master_state_end;
   794     ec_fsm_master_restart(fsm);
   801 }
   795 }
   802 
   796 
   803 /*****************************************************************************/
   797 /*****************************************************************************/
   804 
   798 
   805 /** Master state: SDO DICTIONARY.
   799 /** Master state: SDO DICTIONARY.
   812     ec_master_t *master = fsm->master;
   806     ec_master_t *master = fsm->master;
   813 
   807 
   814     if (ec_fsm_coe_exec(&fsm->fsm_coe)) return;
   808     if (ec_fsm_coe_exec(&fsm->fsm_coe)) return;
   815 
   809 
   816     if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
   810     if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
   817         fsm->state = ec_fsm_master_state_error;
   811         ec_fsm_master_restart(fsm);
   818         return;
   812         return;
   819     }
   813     }
   820 
   814 
   821     // Sdo dictionary fetching finished
   815     // Sdo dictionary fetching finished
   822 
   816 
   825         ec_slave_sdo_dict_info(slave, &sdo_count, &entry_count);
   819         ec_slave_sdo_dict_info(slave, &sdo_count, &entry_count);
   826         EC_DBG("Fetched %u Sdos and %u entries from slave %u.\n",
   820         EC_DBG("Fetched %u Sdos and %u entries from slave %u.\n",
   827                sdo_count, entry_count, slave->ring_position);
   821                sdo_count, entry_count, slave->ring_position);
   828     }
   822     }
   829 
   823 
   830     fsm->state = ec_fsm_master_state_end;
   824     ec_fsm_master_restart(fsm);
   831 }
   825 }
   832 
   826 
   833 /*****************************************************************************/
   827 /*****************************************************************************/
   834 
   828 
   835 /** Master state: SDO REQUEST.
   829 /** Master state: SDO REQUEST.
   846     if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
   840     if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
   847         EC_DBG("Failed to process Sdo request for slave %u.\n",
   841         EC_DBG("Failed to process Sdo request for slave %u.\n",
   848                 fsm->slave->ring_position);
   842                 fsm->slave->ring_position);
   849         request->state = EC_REQUEST_FAILURE;
   843         request->state = EC_REQUEST_FAILURE;
   850         wake_up(&master->sdo_queue);
   844         wake_up(&master->sdo_queue);
   851         fsm->state = ec_fsm_master_state_error;
   845         ec_fsm_master_restart(fsm);
   852         return;
   846         return;
   853     }
   847     }
   854 
   848 
   855     // Sdo request finished 
   849     // Sdo request finished 
   856     request->state = EC_REQUEST_SUCCESS;
   850     request->state = EC_REQUEST_SUCCESS;
   862 
   856 
   863     // check for another Sdo request
   857     // check for another Sdo request
   864     if (ec_fsm_master_action_process_sdo(fsm))
   858     if (ec_fsm_master_action_process_sdo(fsm))
   865         return; // processing another request
   859         return; // processing another request
   866 
   860 
   867     fsm->state = ec_fsm_master_state_end;
   861     ec_fsm_master_restart(fsm);
   868 }
   862 }
   869 
   863 
   870 /*****************************************************************************/
   864 /*****************************************************************************/
   871 
       
   872 /** State: ERROR.
       
   873  */
       
   874 void ec_fsm_master_state_error(
       
   875         ec_fsm_master_t *fsm /**< Master state machine. */
       
   876         )
       
   877 {
       
   878     fsm->state = ec_fsm_master_state_start;
       
   879 }
       
   880 
       
   881 /*****************************************************************************/
       
   882 
       
   883 /** State: END.
       
   884  */
       
   885 void ec_fsm_master_state_end(
       
   886         ec_fsm_master_t *fsm /**< Master state machine. */
       
   887         )
       
   888 {
       
   889     fsm->state = ec_fsm_master_state_start;
       
   890 }
       
   891 
       
   892 /*****************************************************************************/