master/fsm.c
branchstable-1.0
changeset 1619 0d4119024f55
child 1621 4bbe090553f7
equal deleted inserted replaced
1618:5cff10efb927 1619:0d4119024f55
       
     1 /******************************************************************************
       
     2  *
       
     3  *  $Id$
       
     4  *
       
     5  *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
       
     6  *
       
     7  *  This file is part of the IgH EtherCAT Master.
       
     8  *
       
     9  *  The IgH EtherCAT Master is free software; you can redistribute it
       
    10  *  and/or modify it under the terms of the GNU General Public License
       
    11  *  as published by the Free Software Foundation; either version 2 of the
       
    12  *  License, or (at your option) any later version.
       
    13  *
       
    14  *  The IgH EtherCAT Master is distributed in the hope that it will be
       
    15  *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    17  *  GNU General Public License for more details.
       
    18  *
       
    19  *  You should have received a copy of the GNU General Public License
       
    20  *  along with the IgH EtherCAT Master; if not, write to the Free Software
       
    21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       
    22  *
       
    23  *  The right to use EtherCAT Technology is granted and comes free of
       
    24  *  charge under condition of compatibility of product made by
       
    25  *  Licensee. People intending to distribute/sell products based on the
       
    26  *  code, have to sign an agreement to guarantee that products using
       
    27  *  software based on IgH EtherCAT master stay compatible with the actual
       
    28  *  EtherCAT specification (which are released themselves as an open
       
    29  *  standard) as the (only) precondition to have the right to use EtherCAT
       
    30  *  Technology, IP and trade marks.
       
    31  *
       
    32  *****************************************************************************/
       
    33 
       
    34 /**
       
    35    \file
       
    36    EtherCAT finite state machines.
       
    37 */
       
    38 
       
    39 /*****************************************************************************/
       
    40 
       
    41 #include "globals.h"
       
    42 #include "fsm.h"
       
    43 #include "master.h"
       
    44 
       
    45 /*****************************************************************************/
       
    46 
       
    47 /**
       
    48    Size of memory to allocate while reading categories.
       
    49 */
       
    50 
       
    51 #define EC_CAT_MEM 0x100
       
    52 
       
    53 /*****************************************************************************/
       
    54 
       
    55 const ec_code_msg_t al_status_messages[];
       
    56 
       
    57 /*****************************************************************************/
       
    58 
       
    59 void ec_fsm_master_start(ec_fsm_t *);
       
    60 void ec_fsm_master_broadcast(ec_fsm_t *);
       
    61 void ec_fsm_master_proc_states(ec_fsm_t *);
       
    62 void ec_fsm_master_scan(ec_fsm_t *);
       
    63 void ec_fsm_master_states(ec_fsm_t *);
       
    64 void ec_fsm_master_validate_vendor(ec_fsm_t *);
       
    65 void ec_fsm_master_validate_product(ec_fsm_t *);
       
    66 void ec_fsm_master_reconfigure(ec_fsm_t *);
       
    67 void ec_fsm_master_address(ec_fsm_t *);
       
    68 void ec_fsm_master_conf(ec_fsm_t *);
       
    69 
       
    70 void ec_fsm_slave_start_reading(ec_fsm_t *);
       
    71 void ec_fsm_slave_read_status(ec_fsm_t *);
       
    72 void ec_fsm_slave_read_base(ec_fsm_t *);
       
    73 void ec_fsm_slave_read_dl(ec_fsm_t *);
       
    74 void ec_fsm_slave_prepare_sii(ec_fsm_t *);
       
    75 void ec_fsm_slave_read_sii(ec_fsm_t *);
       
    76 void ec_fsm_slave_category_header(ec_fsm_t *);
       
    77 void ec_fsm_slave_category_data(ec_fsm_t *);
       
    78 void ec_fsm_slave_end(ec_fsm_t *);
       
    79 
       
    80 void ec_fsm_slave_conf(ec_fsm_t *);
       
    81 void ec_fsm_slave_sync(ec_fsm_t *);
       
    82 void ec_fsm_slave_preop(ec_fsm_t *);
       
    83 void ec_fsm_slave_fmmu(ec_fsm_t *);
       
    84 void ec_fsm_slave_saveop(ec_fsm_t *);
       
    85 void ec_fsm_slave_op(ec_fsm_t *);
       
    86 void ec_fsm_slave_op2(ec_fsm_t *);
       
    87 
       
    88 void ec_fsm_sii_start_reading(ec_fsm_t *);
       
    89 void ec_fsm_sii_check(ec_fsm_t *);
       
    90 void ec_fsm_sii_fetch(ec_fsm_t *);
       
    91 void ec_fsm_sii_end(ec_fsm_t *);
       
    92 void ec_fsm_sii_error(ec_fsm_t *);
       
    93 
       
    94 void ec_fsm_change_start(ec_fsm_t *);
       
    95 void ec_fsm_change_check(ec_fsm_t *);
       
    96 void ec_fsm_change_status(ec_fsm_t *);
       
    97 void ec_fsm_change_code(ec_fsm_t *);
       
    98 void ec_fsm_change_ack(ec_fsm_t *);
       
    99 void ec_fsm_change_ack2(ec_fsm_t *);
       
   100 void ec_fsm_change_end(ec_fsm_t *);
       
   101 void ec_fsm_change_error(ec_fsm_t *);
       
   102 
       
   103 /*****************************************************************************/
       
   104 
       
   105 /**
       
   106    Constructor.
       
   107 */
       
   108 
       
   109 int ec_fsm_init(ec_fsm_t *fsm, /**< finite state machine */
       
   110                 ec_master_t *master /**< EtherCAT master */
       
   111                 )
       
   112 {
       
   113     fsm->master = master;
       
   114     fsm->master_state = ec_fsm_master_start;
       
   115     fsm->master_slaves_responding = 0;
       
   116     fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN;
       
   117     fsm->master_validation = 0;
       
   118     fsm->slave_cat_data = NULL;
       
   119 
       
   120     ec_command_init(&fsm->command);
       
   121     if (ec_command_prealloc(&fsm->command, EC_MAX_DATA_SIZE)) {
       
   122         EC_ERR("FSM failed to allocate FSM command.\n");
       
   123         return -1;
       
   124     }
       
   125 
       
   126     return 0;
       
   127 }
       
   128 
       
   129 /*****************************************************************************/
       
   130 
       
   131 /**
       
   132    Destructor.
       
   133 */
       
   134 
       
   135 void ec_fsm_clear(ec_fsm_t *fsm /**< finite state machine */)
       
   136 {
       
   137     if (fsm->slave_cat_data) kfree(fsm->slave_cat_data);
       
   138     ec_command_clear(&fsm->command);
       
   139 }
       
   140 
       
   141 /*****************************************************************************/
       
   142 
       
   143 /**
       
   144    Resets the state machine.
       
   145 */
       
   146 
       
   147 void ec_fsm_reset(ec_fsm_t *fsm /**< finite state machine */)
       
   148 {
       
   149     fsm->master_state = ec_fsm_master_start;
       
   150     fsm->master_slaves_responding = 0;
       
   151     fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN;
       
   152 
       
   153     if (fsm->slave_cat_data) {
       
   154         kfree(fsm->slave_cat_data);
       
   155         fsm->slave_cat_data = NULL;
       
   156     }
       
   157 }
       
   158 
       
   159 /*****************************************************************************/
       
   160 
       
   161 /**
       
   162    Executes the current state of the state machine.
       
   163 */
       
   164 
       
   165 void ec_fsm_execute(ec_fsm_t *fsm /**< finite state machine */)
       
   166 {
       
   167     fsm->master_state(fsm);
       
   168 }
       
   169 
       
   170 /******************************************************************************
       
   171  *  master state machine
       
   172  *****************************************************************************/
       
   173 
       
   174 /**
       
   175    Master state: START.
       
   176    Starts with getting slave count and slave states.
       
   177 */
       
   178 
       
   179 void ec_fsm_master_start(ec_fsm_t *fsm)
       
   180 {
       
   181     ec_command_brd(&fsm->command, 0x0130, 2);
       
   182     ec_master_queue_command(fsm->master, &fsm->command);
       
   183     fsm->master_state = ec_fsm_master_broadcast;
       
   184 }
       
   185 
       
   186 /*****************************************************************************/
       
   187 
       
   188 /**
       
   189    Master state: BROADCAST.
       
   190    Processes the broadcast read slave count and slaves states.
       
   191 */
       
   192 
       
   193 void ec_fsm_master_broadcast(ec_fsm_t *fsm /**< finite state machine */)
       
   194 {
       
   195     ec_command_t *command = &fsm->command;
       
   196     unsigned int topology_change, states_change, i;
       
   197     ec_slave_t *slave;
       
   198     ec_master_t *master = fsm->master;
       
   199 
       
   200     if (command->state != EC_CMD_RECEIVED) {
       
   201         if (!master->device->link_state) {
       
   202             fsm->master_slaves_responding = 0;
       
   203             list_for_each_entry(slave, &master->slaves, list) {
       
   204                 slave->online = 0;
       
   205             }
       
   206         }
       
   207         fsm->master_state = ec_fsm_master_start;
       
   208         fsm->master_state(fsm); // execute immediately
       
   209         return;
       
   210     }
       
   211 
       
   212     topology_change = (command->working_counter !=
       
   213                        fsm->master_slaves_responding);
       
   214     states_change = (EC_READ_U8(command->data) != fsm->master_slave_states);
       
   215 
       
   216     fsm->master_slave_states = EC_READ_U8(command->data);
       
   217     fsm->master_slaves_responding = command->working_counter;
       
   218 
       
   219     if (topology_change) {
       
   220         EC_INFO("%i slave%s responding.\n",
       
   221                 fsm->master_slaves_responding,
       
   222                 fsm->master_slaves_responding == 1 ? "" : "s");
       
   223 
       
   224         if (master->mode == EC_MASTER_MODE_RUNNING) {
       
   225             if (fsm->master_slaves_responding == master->slave_count) {
       
   226                 fsm->master_validation = 1; // start validation later
       
   227             }
       
   228             else {
       
   229                 EC_WARN("Invalid slave count. Bus in tainted state.\n");
       
   230             }
       
   231         }
       
   232     }
       
   233 
       
   234     if (states_change) {
       
   235         EC_INFO("Slave states: ");
       
   236         ec_print_states(fsm->master_slave_states);
       
   237         printk(".\n");
       
   238     }
       
   239 
       
   240     // topology change in free-run mode: clear all slaves and scan the bus
       
   241     if (topology_change && master->mode == EC_MASTER_MODE_FREERUN) {
       
   242         EC_INFO("Scanning bus.\n");
       
   243 
       
   244         ec_master_eoe_stop(master);
       
   245         ec_master_clear_slaves(master);
       
   246 
       
   247         if (!fsm->master_slaves_responding) {
       
   248             // no slaves present -> finish state machine.
       
   249             fsm->master_state = ec_fsm_master_start;
       
   250             fsm->master_state(fsm); // execute immediately
       
   251             return;
       
   252         }
       
   253 
       
   254         // init slaves
       
   255         for (i = 0; i < fsm->master_slaves_responding; i++) {
       
   256             if (!(slave = (ec_slave_t *) kmalloc(sizeof(ec_slave_t),
       
   257                                                  GFP_ATOMIC))) {
       
   258                 EC_ERR("Failed to allocate slave %i!\n", i);
       
   259                 fsm->master_state = ec_fsm_master_start;
       
   260                 fsm->master_state(fsm); // execute immediately
       
   261                 return;
       
   262             }
       
   263 
       
   264             if (ec_slave_init(slave, master, i, i + 1)) {
       
   265                 fsm->master_state = ec_fsm_master_start;
       
   266                 fsm->master_state(fsm); // execute immediately
       
   267                 return;
       
   268             }
       
   269 
       
   270             if (kobject_add(&slave->kobj)) {
       
   271                 EC_ERR("Failed to add kobject.\n");
       
   272                 kobject_put(&slave->kobj); // free
       
   273                 fsm->master_state = ec_fsm_master_start;
       
   274                 fsm->master_state(fsm); // execute immediately
       
   275                 return;
       
   276             }
       
   277 
       
   278             list_add_tail(&slave->list, &master->slaves);
       
   279         }
       
   280 
       
   281         // begin scanning of slaves
       
   282         fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
       
   283         fsm->slave_state = ec_fsm_slave_start_reading;
       
   284         fsm->master_state = ec_fsm_master_scan;
       
   285         fsm->master_state(fsm); // execute immediately
       
   286         return;
       
   287     }
       
   288 
       
   289     // fetch state from each slave
       
   290     fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
       
   291     ec_command_nprd(&fsm->command, fsm->slave->station_address, 0x0130, 2);
       
   292     ec_master_queue_command(master, &fsm->command);
       
   293     fsm->master_state = ec_fsm_master_states;
       
   294 }
       
   295 
       
   296 /*****************************************************************************/
       
   297 
       
   298 /**
       
   299    Master action: Get state of next slave.
       
   300 */
       
   301 
       
   302 void ec_fsm_master_action_next_slave_state(ec_fsm_t *fsm
       
   303                                            /**< finite state machine */)
       
   304 {
       
   305     ec_master_t *master = fsm->master;
       
   306     ec_slave_t *slave = fsm->slave;
       
   307 
       
   308     // have all states been read?
       
   309     if (slave->list.next == &master->slaves) {
       
   310 
       
   311         // check, if a bus validation has to be done
       
   312         if (fsm->master_validation) {
       
   313             fsm->master_validation = 0;
       
   314             list_for_each_entry(slave, &master->slaves, list) {
       
   315                 if (slave->online) continue;
       
   316 
       
   317                 // At least one slave is offline. validate!
       
   318                 EC_INFO("Validating bus.\n");
       
   319                 fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
       
   320                 fsm->master_state = ec_fsm_master_validate_vendor;
       
   321                 fsm->sii_offset = 0x0008; // vendor ID
       
   322                 fsm->sii_mode = 0;
       
   323                 fsm->sii_state = ec_fsm_sii_start_reading;
       
   324                 fsm->sii_state(fsm); // execute immediately
       
   325                 return;
       
   326             }
       
   327         }
       
   328 
       
   329         fsm->master_state = ec_fsm_master_proc_states;
       
   330         fsm->master_state(fsm); // execute immediately
       
   331         return;
       
   332     }
       
   333 
       
   334     // process next slave
       
   335     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   336     ec_command_nprd(&fsm->command, fsm->slave->station_address, 0x0130, 2);
       
   337     ec_master_queue_command(master, &fsm->command);
       
   338     fsm->master_state = ec_fsm_master_states;
       
   339 }
       
   340 
       
   341 /*****************************************************************************/
       
   342 
       
   343 /**
       
   344    Master state: STATES.
       
   345    Fetches the AL- and online state of a slave.
       
   346 */
       
   347 
       
   348 void ec_fsm_master_states(ec_fsm_t *fsm /**< finite state machine */)
       
   349 {
       
   350     ec_slave_t *slave = fsm->slave;
       
   351     ec_command_t *command = &fsm->command;
       
   352     uint8_t new_state;
       
   353 
       
   354     if (command->state != EC_CMD_RECEIVED) {
       
   355         fsm->master_state = ec_fsm_master_start;
       
   356         fsm->master_state(fsm); // execute immediately
       
   357         return;
       
   358     }
       
   359 
       
   360     // did the slave not respond to its station address?
       
   361     if (command->working_counter != 1) {
       
   362         if (slave->online) {
       
   363             slave->online = 0;
       
   364             EC_INFO("Slave %i: offline.\n", slave->ring_position);
       
   365         }
       
   366         ec_fsm_master_action_next_slave_state(fsm);
       
   367         return;
       
   368     }
       
   369 
       
   370     // slave responded
       
   371     new_state = EC_READ_U8(command->data);
       
   372     if (!slave->online) { // slave was offline before
       
   373         slave->online = 1;
       
   374         slave->state_error = 0;
       
   375         slave->current_state = new_state;
       
   376         EC_INFO("Slave %i: online (", slave->ring_position);
       
   377         ec_print_states(new_state);
       
   378         printk(").\n");
       
   379     }
       
   380     else if (new_state != slave->current_state) {
       
   381         EC_INFO("Slave %i: ", slave->ring_position);
       
   382         ec_print_states(slave->current_state);
       
   383         printk(" -> ");
       
   384         ec_print_states(new_state);
       
   385         printk(".\n");
       
   386         slave->current_state = new_state;
       
   387     }
       
   388 
       
   389     ec_fsm_master_action_next_slave_state(fsm);
       
   390 }
       
   391 
       
   392 /*****************************************************************************/
       
   393 
       
   394 /**
       
   395    Master state: PROC_STATES.
       
   396    Processes the slave states.
       
   397 */
       
   398 
       
   399 void ec_fsm_master_proc_states(ec_fsm_t *fsm /**< finite state machine */)
       
   400 {
       
   401     ec_master_t *master = fsm->master;
       
   402     ec_slave_t *slave;
       
   403 
       
   404     // check if any slaves are not in the state, they're supposed to be
       
   405     list_for_each_entry(slave, &master->slaves, list) {
       
   406         if (slave->state_error || !slave->online ||
       
   407             slave->requested_state == EC_SLAVE_STATE_UNKNOWN ||
       
   408             slave->current_state == slave->requested_state) continue;
       
   409 
       
   410         EC_INFO("Changing state of slave %i from ", slave->ring_position);
       
   411         ec_print_states(slave->current_state);
       
   412         printk(" to ");
       
   413         ec_print_states(slave->requested_state);
       
   414         printk(".\n");
       
   415 
       
   416         fsm->slave = slave;
       
   417         fsm->slave_state = ec_fsm_slave_conf;
       
   418         fsm->change_new = EC_SLAVE_STATE_INIT;
       
   419         fsm->change_state = ec_fsm_change_start;
       
   420         fsm->master_state = ec_fsm_master_conf;
       
   421         fsm->master_state(fsm); // execute immediately
       
   422         return;
       
   423     }
       
   424 
       
   425     // nothing to configure. restart master state machine.
       
   426     fsm->master_state = ec_fsm_master_start;
       
   427     fsm->master_state(fsm); // execute immediately
       
   428 }
       
   429 
       
   430 /*****************************************************************************/
       
   431 
       
   432 /**
       
   433    Master state: VALIDATE_VENDOR.
       
   434    Validates the vendor ID of a slave.
       
   435 */
       
   436 
       
   437 void ec_fsm_master_validate_vendor(ec_fsm_t *fsm /**< finite state machine */)
       
   438 {
       
   439     ec_slave_t *slave = fsm->slave;
       
   440 
       
   441     fsm->sii_state(fsm); // execute SII state machine
       
   442 
       
   443     if (fsm->sii_state == ec_fsm_sii_error) {
       
   444         EC_ERR("Failed to validate vendor ID of slave %i.\n",
       
   445                slave->ring_position);
       
   446         fsm->master_state = ec_fsm_master_start;
       
   447         fsm->master_state(fsm); // execute immediately
       
   448         return;
       
   449     }
       
   450 
       
   451     if (fsm->sii_state != ec_fsm_sii_end) return;
       
   452 
       
   453     if (fsm->sii_result != slave->sii_vendor_id) {
       
   454         EC_ERR("Slave %i: invalid vendor ID!\n", slave->ring_position);
       
   455         fsm->master_state = ec_fsm_master_start;
       
   456         fsm->master_state(fsm); // execute immediately
       
   457         return;
       
   458     }
       
   459 
       
   460     // vendor ID is ok. check product code.
       
   461     fsm->master_state = ec_fsm_master_validate_product;
       
   462     fsm->sii_offset = 0x000A; // product code
       
   463     fsm->sii_mode = 0;
       
   464     fsm->sii_state = ec_fsm_sii_start_reading;
       
   465     fsm->sii_state(fsm); // execute immediately
       
   466 }
       
   467 
       
   468 /*****************************************************************************/
       
   469 
       
   470 /**
       
   471    Master state: VALIDATE_PRODUCT.
       
   472    Validates the product ID of a slave.
       
   473 */
       
   474 
       
   475 void ec_fsm_master_validate_product(ec_fsm_t *fsm /**< finite state machine */)
       
   476 {
       
   477     ec_slave_t *slave = fsm->slave;
       
   478 
       
   479     fsm->sii_state(fsm); // execute SII state machine
       
   480 
       
   481     if (fsm->sii_state == ec_fsm_sii_error) {
       
   482         EC_ERR("Failed to validate product code of slave %i.\n",
       
   483                slave->ring_position);
       
   484         fsm->master_state = ec_fsm_master_start;
       
   485         fsm->master_state(fsm); // execute immediately
       
   486         return;
       
   487     }
       
   488 
       
   489     if (fsm->sii_state != ec_fsm_sii_end) return;
       
   490 
       
   491     if (fsm->sii_result != slave->sii_product_code) {
       
   492         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
       
   493         EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
       
   494                fsm->sii_result);
       
   495         fsm->master_state = ec_fsm_master_start;
       
   496         fsm->master_state(fsm); // execute immediately
       
   497         return;
       
   498     }
       
   499 
       
   500     // have all states been validated?
       
   501     if (slave->list.next == &fsm->master->slaves) {
       
   502         fsm->slave = list_entry(fsm->master->slaves.next, ec_slave_t, list);
       
   503         fsm->master_state = ec_fsm_master_reconfigure;
       
   504         return;
       
   505     }
       
   506 
       
   507     // validate next slave
       
   508     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   509     fsm->master_state = ec_fsm_master_validate_vendor;
       
   510     fsm->sii_offset = 0x0008; // vendor ID
       
   511     fsm->sii_mode = 0;
       
   512     fsm->sii_state = ec_fsm_sii_start_reading;
       
   513     fsm->sii_state(fsm); // execute immediately
       
   514 }
       
   515 
       
   516 /*****************************************************************************/
       
   517 
       
   518 /**
       
   519    Master state: RECONFIGURE.
       
   520    Looks for slave, that have lost their configuration and writes
       
   521    their station address, so that they can be reconfigured later.
       
   522 */
       
   523 
       
   524 void ec_fsm_master_reconfigure(ec_fsm_t *fsm /**< finite state machine */)
       
   525 {
       
   526     ec_command_t *command = &fsm->command;
       
   527 
       
   528     while (fsm->slave->online) {
       
   529         if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
       
   530             fsm->master_state = ec_fsm_master_start;
       
   531             fsm->master_state(fsm); // execute immediately
       
   532             return;
       
   533         }
       
   534         // check next slave
       
   535         fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   536     }
       
   537 
       
   538     EC_INFO("Reinitializing slave %i.\n", fsm->slave->ring_position);
       
   539 
       
   540     // write station address
       
   541     ec_command_apwr(command, fsm->slave->ring_position, 0x0010, 2);
       
   542     EC_WRITE_U16(command->data, fsm->slave->station_address);
       
   543     ec_master_queue_command(fsm->master, command);
       
   544     fsm->master_state = ec_fsm_master_address;
       
   545 }
       
   546 
       
   547 /*****************************************************************************/
       
   548 
       
   549 /**
       
   550    Master state: ADDRESS.
       
   551    Checks, if the new station address has been written to the slave.
       
   552 */
       
   553 
       
   554 void ec_fsm_master_address(ec_fsm_t *fsm /**< finite state machine */)
       
   555 {
       
   556     ec_slave_t *slave = fsm->slave;
       
   557     ec_command_t *command = &fsm->command;
       
   558 
       
   559     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
   560         EC_ERR("Failed to write station address on slave %i.\n",
       
   561                slave->ring_position);
       
   562     }
       
   563 
       
   564     if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
       
   565         fsm->master_state = ec_fsm_master_start;
       
   566         fsm->master_state(fsm); // execute immediately
       
   567         return;
       
   568     }
       
   569 
       
   570     // check next slave
       
   571     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   572     fsm->master_state = ec_fsm_master_reconfigure;
       
   573     fsm->master_state(fsm); // execute immediately
       
   574 }
       
   575 
       
   576 /*****************************************************************************/
       
   577 
       
   578 /**
       
   579    Master state: SCAN.
       
   580    Executes the sub-statemachine for the scanning of a slave.
       
   581 */
       
   582 
       
   583 void ec_fsm_master_scan(ec_fsm_t *fsm /**< finite state machine */)
       
   584 {
       
   585     ec_master_t *master = fsm->master;
       
   586     ec_slave_t *slave = fsm->slave;
       
   587     uint16_t coupler_index, coupler_subindex;
       
   588     uint16_t reverse_coupler_index, current_coupler_index;
       
   589     ec_slave_ident_t *ident;
       
   590 
       
   591     fsm->slave_state(fsm); // execute slave state machine
       
   592 
       
   593     if (fsm->slave_state != ec_fsm_slave_end) return;
       
   594 
       
   595     // have all slaves been fetched?
       
   596     if (slave->list.next == &master->slaves) {
       
   597         EC_INFO("Bus scanning completed.\n");
       
   598 
       
   599         // identify all slaves and calculate coupler addressing
       
   600 
       
   601         coupler_index = 0;
       
   602         reverse_coupler_index = 0xFFFF;
       
   603         current_coupler_index = 0x3FFF;
       
   604         coupler_subindex = 0;
       
   605 
       
   606         list_for_each_entry(slave, &master->slaves, list)
       
   607         {
       
   608             // search for identification in "database"
       
   609             ident = slave_idents;
       
   610             while (ident->type) {
       
   611                 if (ident->vendor_id == slave->sii_vendor_id
       
   612                     && ident->product_code == slave->sii_product_code) {
       
   613                     slave->type = ident->type;
       
   614                     break;
       
   615                 }
       
   616                 ident++;
       
   617             }
       
   618 
       
   619             if (!slave->type) {
       
   620                 EC_WARN("FSM: Unknown slave device (vendor 0x%08X,"
       
   621                         " code 0x%08X) at position %i.\n",
       
   622                         slave->sii_vendor_id, slave->sii_product_code,
       
   623                         slave->ring_position);
       
   624             }
       
   625             else {
       
   626                 // if the slave is a bus coupler, change adressing base
       
   627                 if (slave->type->special == EC_TYPE_BUS_COUPLER) {
       
   628                     if (slave->sii_alias)
       
   629                         current_coupler_index = reverse_coupler_index--;
       
   630                     else
       
   631                         current_coupler_index = coupler_index++;
       
   632                     coupler_subindex = 0;
       
   633                 }
       
   634             }
       
   635 
       
   636             // determine initial state.
       
   637             if ((slave->type && slave->type->special == EC_TYPE_BUS_COUPLER)) {
       
   638                 slave->requested_state = EC_SLAVE_STATE_OP;
       
   639             }
       
   640             else {
       
   641                 if (master->mode == EC_MASTER_MODE_RUNNING)
       
   642                     slave->requested_state = EC_SLAVE_STATE_PREOP;
       
   643                 else
       
   644                     slave->requested_state = EC_SLAVE_STATE_INIT;
       
   645             }
       
   646             slave->state_error = 0;
       
   647 
       
   648             // calculate coupler-based slave address
       
   649             slave->coupler_index = current_coupler_index;
       
   650             slave->coupler_subindex = coupler_subindex;
       
   651             coupler_subindex++;
       
   652         }
       
   653 
       
   654         if (master->mode == EC_MASTER_MODE_FREERUN) {
       
   655             // start EoE processing
       
   656             ec_master_eoe_start(master);
       
   657         }
       
   658 
       
   659         fsm->master_state = ec_fsm_master_start;
       
   660         fsm->master_state(fsm); // execute immediately
       
   661         return;
       
   662     }
       
   663 
       
   664     // process next slave
       
   665     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   666     fsm->slave_state = ec_fsm_slave_start_reading;
       
   667     fsm->slave_state(fsm); // execute immediately
       
   668 }
       
   669 
       
   670 /*****************************************************************************/
       
   671 
       
   672 /**
       
   673    Master state: CONF.
       
   674    Starts configuring a slave.
       
   675 */
       
   676 
       
   677 void ec_fsm_master_conf(ec_fsm_t *fsm /**< finite state machine */)
       
   678 {
       
   679     fsm->slave_state(fsm); // execute slave's state machine
       
   680     if (fsm->slave_state != ec_fsm_slave_end) return;
       
   681     fsm->master_state = ec_fsm_master_proc_states;
       
   682     fsm->master_state(fsm); // execute immediately
       
   683 }
       
   684 
       
   685 /******************************************************************************
       
   686  *  slave state machine
       
   687  *****************************************************************************/
       
   688 
       
   689 /**
       
   690    Slave state: START_READING.
       
   691    First state of the slave state machine. Writes the station address to the
       
   692    slave, according to its ring position.
       
   693 */
       
   694 
       
   695 void ec_fsm_slave_start_reading(ec_fsm_t *fsm /**< finite state machine */)
       
   696 {
       
   697     ec_command_t *command = &fsm->command;
       
   698 
       
   699     // write station address
       
   700     ec_command_apwr(command, fsm->slave->ring_position, 0x0010, 2);
       
   701     EC_WRITE_U16(command->data, fsm->slave->station_address);
       
   702     ec_master_queue_command(fsm->master, command);
       
   703     fsm->slave_state = ec_fsm_slave_read_status;
       
   704 }
       
   705 
       
   706 /*****************************************************************************/
       
   707 
       
   708 /**
       
   709    Slave state: READ_STATUS.
       
   710 */
       
   711 
       
   712 void ec_fsm_slave_read_status(ec_fsm_t *fsm /**< finite state machine */)
       
   713 {
       
   714     ec_command_t *command = &fsm->command;
       
   715 
       
   716     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
   717         EC_ERR("FSM failed to write station address of slave %i.\n",
       
   718                fsm->slave->ring_position);
       
   719         fsm->slave_state = ec_fsm_slave_end;
       
   720         return;
       
   721     }
       
   722 
       
   723     // read AL status
       
   724     ec_command_nprd(command, fsm->slave->station_address, 0x0130, 2);
       
   725     ec_master_queue_command(fsm->master, command);
       
   726     fsm->slave_state = ec_fsm_slave_read_base;
       
   727 }
       
   728 
       
   729 /*****************************************************************************/
       
   730 
       
   731 /**
       
   732    Slave state: READ_BASE.
       
   733 */
       
   734 
       
   735 void ec_fsm_slave_read_base(ec_fsm_t *fsm /**< finite state machine */)
       
   736 {
       
   737     ec_command_t *command = &fsm->command;
       
   738     ec_slave_t *slave = fsm->slave;
       
   739 
       
   740     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
   741         EC_ERR("FSM failed to read AL status of slave %i.\n",
       
   742                fsm->slave->ring_position);
       
   743         fsm->slave_state = ec_fsm_slave_end;
       
   744         return;
       
   745     }
       
   746 
       
   747     slave->current_state = EC_READ_U8(command->data);
       
   748     if (slave->current_state & EC_ACK) {
       
   749         EC_WARN("Slave %i has status error bit set (0x%02X)!\n",
       
   750                 slave->ring_position, slave->current_state);
       
   751         slave->current_state &= 0x0F;
       
   752     }
       
   753 
       
   754     // read base data
       
   755     ec_command_nprd(command, fsm->slave->station_address, 0x0000, 6);
       
   756     ec_master_queue_command(fsm->master, command);
       
   757     fsm->slave_state = ec_fsm_slave_read_dl;
       
   758 }
       
   759 
       
   760 /*****************************************************************************/
       
   761 
       
   762 /**
       
   763    Slave state: READ_DL.
       
   764 */
       
   765 
       
   766 void ec_fsm_slave_read_dl(ec_fsm_t *fsm /**< finite state machine */)
       
   767 {
       
   768     ec_command_t *command = &fsm->command;
       
   769     ec_slave_t *slave = fsm->slave;
       
   770 
       
   771     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
   772         EC_ERR("FSM failed to read base data of slave %i.\n",
       
   773                slave->ring_position);
       
   774         fsm->slave_state = ec_fsm_slave_end;
       
   775         return;
       
   776     }
       
   777 
       
   778     slave->base_type       = EC_READ_U8 (command->data);
       
   779     slave->base_revision   = EC_READ_U8 (command->data + 1);
       
   780     slave->base_build      = EC_READ_U16(command->data + 2);
       
   781     slave->base_fmmu_count = EC_READ_U8 (command->data + 4);
       
   782     slave->base_sync_count = EC_READ_U8 (command->data + 5);
       
   783 
       
   784     if (slave->base_fmmu_count > EC_MAX_FMMUS)
       
   785         slave->base_fmmu_count = EC_MAX_FMMUS;
       
   786 
       
   787     // read data link status
       
   788     ec_command_nprd(command, slave->station_address, 0x0110, 2);
       
   789     ec_master_queue_command(slave->master, command);
       
   790     fsm->slave_state = ec_fsm_slave_prepare_sii;
       
   791 }
       
   792 
       
   793 /*****************************************************************************/
       
   794 
       
   795 /**
       
   796    Slave state: PREPARE_SII.
       
   797 */
       
   798 
       
   799 void ec_fsm_slave_prepare_sii(ec_fsm_t *fsm /**< finite state machine */)
       
   800 {
       
   801     ec_command_t *command = &fsm->command;
       
   802     ec_slave_t *slave = fsm->slave;
       
   803     uint16_t dl_status;
       
   804     unsigned int i;
       
   805 
       
   806     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
   807         EC_ERR("FSM failed to read DL status of slave %i.\n",
       
   808                slave->ring_position);
       
   809         fsm->slave_state = ec_fsm_slave_end;
       
   810         return;
       
   811     }
       
   812 
       
   813     dl_status = EC_READ_U16(command->data);
       
   814 
       
   815     for (i = 0; i < 4; i++) {
       
   816         slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
       
   817         slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
       
   818         slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
       
   819     }
       
   820 
       
   821     fsm->sii_offset = 0x0004;
       
   822     fsm->sii_mode = 1;
       
   823     fsm->sii_state = ec_fsm_sii_start_reading;
       
   824     fsm->slave_sii_num = 0;
       
   825     fsm->slave_state = ec_fsm_slave_read_sii;
       
   826     fsm->slave_state(fsm); // execute state immediately
       
   827 }
       
   828 
       
   829 /*****************************************************************************/
       
   830 
       
   831 /**
       
   832    Slave state: READ_SII.
       
   833 */
       
   834 
       
   835 void ec_fsm_slave_read_sii(ec_fsm_t *fsm /**< finite state machine */)
       
   836 {
       
   837     ec_slave_t *slave = fsm->slave;
       
   838 
       
   839     // execute SII state machine
       
   840     fsm->sii_state(fsm);
       
   841 
       
   842     if (fsm->sii_state == ec_fsm_sii_error) {
       
   843         fsm->slave_state = ec_fsm_slave_end;
       
   844         EC_ERR("FSM failed to read SII data at 0x%04X on slave %i.\n",
       
   845                fsm->sii_offset, slave->ring_position);
       
   846         return;
       
   847     }
       
   848 
       
   849     if (fsm->sii_state != ec_fsm_sii_end) return;
       
   850 
       
   851     switch (fsm->slave_sii_num) {
       
   852         case 0:
       
   853             slave->sii_alias = fsm->sii_result & 0xFFFF;
       
   854             fsm->sii_offset = 0x0008;
       
   855             break;
       
   856         case 1:
       
   857             slave->sii_vendor_id = fsm->sii_result;
       
   858             fsm->sii_offset = 0x000A;
       
   859             break;
       
   860         case 2:
       
   861             slave->sii_product_code = fsm->sii_result;
       
   862             fsm->sii_offset = 0x000C;
       
   863             break;
       
   864         case 3:
       
   865             slave->sii_revision_number = fsm->sii_result;
       
   866             fsm->sii_offset = 0x000E;
       
   867             break;
       
   868         case 4:
       
   869             slave->sii_serial_number = fsm->sii_result;
       
   870             fsm->sii_offset = 0x0018;
       
   871             break;
       
   872         case 5:
       
   873             slave->sii_rx_mailbox_offset = fsm->sii_result & 0xFFFF;
       
   874             slave->sii_rx_mailbox_size = fsm->sii_result >> 16;
       
   875             fsm->sii_offset = 0x001A;
       
   876             break;
       
   877         case 6:
       
   878             slave->sii_tx_mailbox_offset = fsm->sii_result & 0xFFFF;
       
   879             slave->sii_tx_mailbox_size = fsm->sii_result >> 16;
       
   880             fsm->sii_offset = 0x001C;
       
   881             break;
       
   882         case 7:
       
   883             slave->sii_mailbox_protocols = fsm->sii_result & 0xFFFF;
       
   884 
       
   885             fsm->slave_cat_offset = 0x0040;
       
   886 
       
   887             if (fsm->slave_cat_data) {
       
   888                 EC_INFO("FSM freeing old category data on slave %i...\n",
       
   889                         fsm->slave->ring_position);
       
   890                 kfree(fsm->slave_cat_data);
       
   891             }
       
   892 
       
   893             if (!(fsm->slave_cat_data =
       
   894                   (uint8_t *) kmalloc(EC_CAT_MEM, GFP_ATOMIC))) {
       
   895                 EC_ERR("FSM Failed to allocate category data.\n");
       
   896                 fsm->slave_state = ec_fsm_slave_end;
       
   897                 return;
       
   898             }
       
   899 
       
   900             // start reading first category header
       
   901             fsm->sii_offset = fsm->slave_cat_offset;
       
   902             fsm->sii_state = ec_fsm_sii_start_reading;
       
   903 
       
   904             fsm->slave_state = ec_fsm_slave_category_header;
       
   905             fsm->slave_state(fsm); // execute state immediately
       
   906             return;
       
   907     }
       
   908 
       
   909     fsm->slave_sii_num++;
       
   910     fsm->sii_state = ec_fsm_sii_start_reading;
       
   911     fsm->slave_state(fsm); // execute state immediately
       
   912 }
       
   913 
       
   914 /*****************************************************************************/
       
   915 
       
   916 /**
       
   917    Slave state: CATEGORY_HEADER.
       
   918    Start reading categories.
       
   919 */
       
   920 
       
   921 void ec_fsm_slave_category_header(ec_fsm_t *fsm /**< finite state machine */)
       
   922 {
       
   923     // execute SII state machine
       
   924     fsm->sii_state(fsm);
       
   925 
       
   926     if (fsm->sii_state == ec_fsm_sii_error) {
       
   927         kfree(fsm->slave_cat_data);
       
   928         fsm->slave_cat_data = NULL;
       
   929         fsm->slave_state = ec_fsm_slave_end;
       
   930         EC_ERR("FSM failed to read category header at 0x%04X on slave %i.\n",
       
   931                fsm->slave_cat_offset, fsm->slave->ring_position);
       
   932         return;
       
   933     }
       
   934 
       
   935     if (fsm->sii_state != ec_fsm_sii_end) return;
       
   936 
       
   937     // last category?
       
   938     if ((fsm->sii_result & 0xFFFF) == 0xFFFF) {
       
   939         kfree(fsm->slave_cat_data);
       
   940         fsm->slave_cat_data = NULL;
       
   941         fsm->slave_state = ec_fsm_slave_end;
       
   942         return;
       
   943     }
       
   944 
       
   945     fsm->slave_cat_type = fsm->sii_result & 0x7FFF;
       
   946     fsm->slave_cat_words = (fsm->sii_result >> 16) & 0xFFFF;
       
   947 
       
   948     if (fsm->slave_cat_words > EC_CAT_MEM * 2) {
       
   949         EC_ERR("FSM category memory too small! %i words needed.\n",
       
   950                fsm->slave_cat_words);
       
   951         fsm->slave_state = ec_fsm_slave_end;
       
   952         return;
       
   953     }
       
   954 
       
   955     // start reading category data
       
   956     fsm->slave_cat_data_offset = 0;
       
   957     fsm->sii_offset = (fsm->slave_cat_offset + 2 +
       
   958                        fsm->slave_cat_data_offset);
       
   959     fsm->sii_mode = 1;
       
   960     fsm->sii_state = ec_fsm_sii_start_reading;
       
   961     fsm->slave_state = ec_fsm_slave_category_data;
       
   962     fsm->slave_state(fsm); // execute state immediately
       
   963 }
       
   964 
       
   965 /*****************************************************************************/
       
   966 
       
   967 /**
       
   968    Slave state: CATEGORY_DATA.
       
   969    Reads category data.
       
   970 */
       
   971 
       
   972 void ec_fsm_slave_category_data(ec_fsm_t *fsm /**< finite state machine */)
       
   973 {
       
   974     // execute SII state machine
       
   975     fsm->sii_state(fsm);
       
   976 
       
   977     if (fsm->sii_state == ec_fsm_sii_error) {
       
   978         kfree(fsm->slave_cat_data);
       
   979         fsm->slave_cat_data = NULL;
       
   980         fsm->slave_state = ec_fsm_slave_end;
       
   981         EC_ERR("FSM failed to read category 0x%02X data at 0x%04X"
       
   982                " on slave %i.\n", fsm->slave_cat_type, fsm->sii_offset,
       
   983                fsm->slave->ring_position);
       
   984         return;
       
   985     }
       
   986 
       
   987     if (fsm->sii_state != ec_fsm_sii_end) return;
       
   988 
       
   989     fsm->slave_cat_data[fsm->slave_cat_data_offset * 2] =
       
   990         fsm->sii_result & 0xFF;
       
   991     fsm->slave_cat_data[fsm->slave_cat_data_offset * 2 + 1] =
       
   992         (fsm->sii_result >> 8) & 0xFF;
       
   993 
       
   994     // read second word "on the fly"
       
   995     if (fsm->slave_cat_data_offset + 1 < fsm->slave_cat_words) {
       
   996         fsm->slave_cat_data_offset++;
       
   997         fsm->slave_cat_data[fsm->slave_cat_data_offset * 2] =
       
   998             (fsm->sii_result >> 16) & 0xFF;
       
   999         fsm->slave_cat_data[fsm->slave_cat_data_offset * 2 + 1] =
       
  1000             (fsm->sii_result >> 24) & 0xFF;
       
  1001     }
       
  1002 
       
  1003     fsm->slave_cat_data_offset++;
       
  1004 
       
  1005     if (fsm->slave_cat_data_offset < fsm->slave_cat_words) {
       
  1006         fsm->sii_offset = (fsm->slave_cat_offset + 2 +
       
  1007                            fsm->slave_cat_data_offset);
       
  1008         fsm->sii_mode = 1;
       
  1009         fsm->sii_state = ec_fsm_sii_start_reading;
       
  1010         fsm->slave_state = ec_fsm_slave_category_data;
       
  1011         fsm->slave_state(fsm); // execute state immediately
       
  1012         return;
       
  1013     }
       
  1014 
       
  1015     // category data complete
       
  1016     switch (fsm->slave_cat_type)
       
  1017     {
       
  1018         case 0x000A:
       
  1019             if (ec_slave_fetch_strings(fsm->slave, fsm->slave_cat_data))
       
  1020                 goto out_free;
       
  1021             break;
       
  1022         case 0x001E:
       
  1023             if (ec_slave_fetch_general(fsm->slave, fsm->slave_cat_data))
       
  1024                 goto out_free;
       
  1025             break;
       
  1026         case 0x0028:
       
  1027             break;
       
  1028         case 0x0029:
       
  1029             if (ec_slave_fetch_sync(fsm->slave, fsm->slave_cat_data,
       
  1030                                     fsm->slave_cat_words))
       
  1031                 goto out_free;
       
  1032             break;
       
  1033         case 0x0032:
       
  1034             if (ec_slave_fetch_pdo(fsm->slave, fsm->slave_cat_data,
       
  1035                                    fsm->slave_cat_words,
       
  1036                                    EC_TX_PDO))
       
  1037                 goto out_free;
       
  1038             break;
       
  1039         case 0x0033:
       
  1040             if (ec_slave_fetch_pdo(fsm->slave, fsm->slave_cat_data,
       
  1041                                    fsm->slave_cat_words,
       
  1042                                    EC_RX_PDO))
       
  1043                 goto out_free;
       
  1044             break;
       
  1045         default:
       
  1046             EC_WARN("FSM: Unknown category type 0x%04X in slave %i.\n",
       
  1047                     fsm->slave_cat_type, fsm->slave->ring_position);
       
  1048     }
       
  1049 
       
  1050     // start reading next category header
       
  1051     fsm->slave_cat_offset += 2 + fsm->slave_cat_words;
       
  1052     fsm->sii_offset = fsm->slave_cat_offset;
       
  1053     fsm->sii_mode = 1;
       
  1054     fsm->sii_state = ec_fsm_sii_start_reading;
       
  1055     fsm->slave_state = ec_fsm_slave_category_header;
       
  1056     fsm->slave_state(fsm); // execute state immediately
       
  1057     return;
       
  1058 
       
  1059  out_free:
       
  1060     kfree(fsm->slave_cat_data);
       
  1061     fsm->slave_cat_data = NULL;
       
  1062     fsm->slave_state = ec_fsm_slave_end;
       
  1063 }
       
  1064 
       
  1065 /*****************************************************************************/
       
  1066 
       
  1067 /**
       
  1068    Slave state: CONF.
       
  1069 */
       
  1070 
       
  1071 void ec_fsm_slave_conf(ec_fsm_t *fsm /**< finite state machine */)
       
  1072 {
       
  1073     ec_slave_t *slave = fsm->slave;
       
  1074     ec_master_t *master = fsm->master;
       
  1075     ec_command_t *command = &fsm->command;
       
  1076 
       
  1077     fsm->change_state(fsm); // execute state change state machine
       
  1078 
       
  1079     if (fsm->change_state == ec_fsm_change_error) {
       
  1080         fsm->slave_state = ec_fsm_slave_end;
       
  1081         return;
       
  1082     }
       
  1083 
       
  1084     if (fsm->change_state != ec_fsm_change_end) return;
       
  1085 
       
  1086     // slave is now in INIT
       
  1087     if (slave->current_state == slave->requested_state) {
       
  1088         fsm->slave_state = ec_fsm_slave_end;
       
  1089         return;
       
  1090     }
       
  1091 
       
  1092     // check for slave registration
       
  1093     if (!slave->type) {
       
  1094         EC_WARN("Slave %i has unknown type!\n", slave->ring_position);
       
  1095     }
       
  1096 
       
  1097     // check and reset CRC fault counters
       
  1098     //ec_slave_check_crc(slave);
       
  1099 
       
  1100     if (!slave->base_fmmu_count) { // no fmmus
       
  1101         fsm->slave_state = ec_fsm_slave_sync;
       
  1102         fsm->slave_state(fsm); // execute immediately
       
  1103         return;
       
  1104     }
       
  1105 
       
  1106     // reset FMMUs
       
  1107     ec_command_npwr(command, slave->station_address, 0x0600,
       
  1108                     EC_FMMU_SIZE * slave->base_fmmu_count);
       
  1109     memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
       
  1110     ec_master_queue_command(master, command);
       
  1111     fsm->slave_state = ec_fsm_slave_sync;
       
  1112 }
       
  1113 
       
  1114 /*****************************************************************************/
       
  1115 
       
  1116 /**
       
  1117    Slave state: SYNC.
       
  1118    Configure sync managers.
       
  1119 */
       
  1120 
       
  1121 void ec_fsm_slave_sync(ec_fsm_t *fsm /**< finite state machine */)
       
  1122 {
       
  1123     ec_command_t *command = &fsm->command;
       
  1124     ec_slave_t *slave = fsm->slave;
       
  1125     unsigned int j;
       
  1126     const ec_sync_t *sync;
       
  1127     ec_eeprom_sync_t *eeprom_sync, mbox_sync;
       
  1128 
       
  1129     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1130         EC_ERR("Failed to reset FMMUs of slave %i.\n",
       
  1131                slave->ring_position);
       
  1132         slave->state_error = 1;
       
  1133         fsm->slave_state = ec_fsm_slave_end;
       
  1134         return;
       
  1135     }
       
  1136 
       
  1137     if (!slave->base_sync_count) { // no sync managers
       
  1138         fsm->slave_state = ec_fsm_slave_preop;
       
  1139         fsm->slave_state(fsm); // execute immediately
       
  1140         return;
       
  1141     }
       
  1142 
       
  1143     // configure sync managers
       
  1144     ec_command_npwr(command, slave->station_address, 0x0800,
       
  1145                     EC_SYNC_SIZE * slave->base_sync_count);
       
  1146     memset(command->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
       
  1147 
       
  1148     // known slave type, take type's SM information
       
  1149     if (slave->type) {
       
  1150         for (j = 0; slave->type->sync_managers[j] && j < EC_MAX_SYNC; j++) {
       
  1151             sync = slave->type->sync_managers[j];
       
  1152             ec_sync_config(sync, command->data + EC_SYNC_SIZE * j);
       
  1153         }
       
  1154     }
       
  1155 
       
  1156     // unknown type, but slave has mailbox
       
  1157     else if (slave->sii_mailbox_protocols)
       
  1158     {
       
  1159         // does it supply sync manager configurations in its EEPROM?
       
  1160         if (!list_empty(&slave->eeprom_syncs)) {
       
  1161             list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
       
  1162                 if (eeprom_sync->index >= slave->base_sync_count) {
       
  1163                     EC_ERR("Invalid sync manager configuration found!");
       
  1164                     fsm->slave_state = ec_fsm_slave_end;
       
  1165                     return;
       
  1166                 }
       
  1167                 ec_eeprom_sync_config(eeprom_sync,
       
  1168                                       command->data + EC_SYNC_SIZE
       
  1169                                       * eeprom_sync->index);
       
  1170             }
       
  1171         }
       
  1172 
       
  1173         // no sync manager information; guess mailbox settings
       
  1174         else {
       
  1175             mbox_sync.physical_start_address =
       
  1176                 slave->sii_rx_mailbox_offset;
       
  1177             mbox_sync.length = slave->sii_rx_mailbox_size;
       
  1178             mbox_sync.control_register = 0x26;
       
  1179             mbox_sync.enable = 1;
       
  1180             ec_eeprom_sync_config(&mbox_sync, command->data);
       
  1181 
       
  1182             mbox_sync.physical_start_address =
       
  1183                 slave->sii_tx_mailbox_offset;
       
  1184             mbox_sync.length = slave->sii_tx_mailbox_size;
       
  1185             mbox_sync.control_register = 0x22;
       
  1186             mbox_sync.enable = 1;
       
  1187             ec_eeprom_sync_config(&mbox_sync,
       
  1188                                   command->data + EC_SYNC_SIZE);
       
  1189         }
       
  1190 
       
  1191         EC_INFO("Mailbox configured for unknown slave %i\n",
       
  1192                 slave->ring_position);
       
  1193     }
       
  1194 
       
  1195     ec_master_queue_command(fsm->master, command);
       
  1196     fsm->slave_state = ec_fsm_slave_preop;
       
  1197 }
       
  1198 
       
  1199 /*****************************************************************************/
       
  1200 
       
  1201 /**
       
  1202    Slave state: PREOP.
       
  1203    Change slave state to PREOP.
       
  1204 */
       
  1205 
       
  1206 void ec_fsm_slave_preop(ec_fsm_t *fsm /**< finite state machine */)
       
  1207 {
       
  1208     ec_command_t *command = &fsm->command;
       
  1209     ec_slave_t *slave = fsm->slave;
       
  1210 
       
  1211     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1212         EC_ERR("Failed to set sync managers on slave %i.\n",
       
  1213                slave->ring_position);
       
  1214         slave->state_error = 1;
       
  1215         fsm->slave_state = ec_fsm_slave_end;
       
  1216         return;
       
  1217     }
       
  1218 
       
  1219     fsm->change_new = EC_SLAVE_STATE_PREOP;
       
  1220     fsm->change_state = ec_fsm_change_start;
       
  1221     fsm->slave_state = ec_fsm_slave_fmmu;
       
  1222     fsm->change_state(fsm); // execute immediately
       
  1223 }
       
  1224 
       
  1225 /*****************************************************************************/
       
  1226 
       
  1227 /**
       
  1228    Slave state: FMMU.
       
  1229    Configure FMMUs.
       
  1230 */
       
  1231 
       
  1232 void ec_fsm_slave_fmmu(ec_fsm_t *fsm /**< finite state machine */)
       
  1233 {
       
  1234     ec_slave_t *slave = fsm->slave;
       
  1235     ec_master_t *master = fsm->master;
       
  1236     ec_command_t *command = &fsm->command;
       
  1237     unsigned int j;
       
  1238 
       
  1239     fsm->change_state(fsm); // execute state change state machine
       
  1240 
       
  1241     if (fsm->change_state == ec_fsm_change_error) {
       
  1242         fsm->slave_state = ec_fsm_slave_end;
       
  1243         return;
       
  1244     }
       
  1245 
       
  1246     if (fsm->change_state != ec_fsm_change_end) return;
       
  1247 
       
  1248     // slave is now in PREOP
       
  1249     if (slave->current_state == slave->requested_state) {
       
  1250         fsm->slave_state = ec_fsm_slave_end;
       
  1251         return;
       
  1252     }
       
  1253 
       
  1254     // stop activation here for slaves without type
       
  1255     if (!slave->type) {
       
  1256         fsm->slave_state = ec_fsm_slave_end;
       
  1257         return;
       
  1258     }
       
  1259 
       
  1260     if (!slave->base_fmmu_count) {
       
  1261         fsm->slave_state = ec_fsm_slave_saveop;
       
  1262         fsm->slave_state(fsm); // execute immediately
       
  1263         return;
       
  1264     }
       
  1265 
       
  1266     // configure FMMUs
       
  1267     ec_command_npwr(command, slave->station_address,
       
  1268                     0x0600, EC_FMMU_SIZE * slave->base_fmmu_count);
       
  1269     memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
       
  1270     for (j = 0; j < slave->fmmu_count; j++) {
       
  1271         ec_fmmu_config(&slave->fmmus[j], command->data + EC_FMMU_SIZE * j);
       
  1272     }
       
  1273 
       
  1274     ec_master_queue_command(master, command);
       
  1275     fsm->slave_state = ec_fsm_slave_saveop;
       
  1276 }
       
  1277 
       
  1278 /*****************************************************************************/
       
  1279 
       
  1280 /**
       
  1281    Slave state: SAVEOP.
       
  1282    Set slave state to SAVEOP.
       
  1283 */
       
  1284 
       
  1285 void ec_fsm_slave_saveop(ec_fsm_t *fsm /**< finite state machine */)
       
  1286 {
       
  1287     ec_command_t *command = &fsm->command;
       
  1288 
       
  1289     if (fsm->slave->base_fmmu_count && (command->state != EC_CMD_RECEIVED ||
       
  1290                                         command->working_counter != 1)) {
       
  1291         EC_ERR("FSM failed to set FMMUs on slave %i.\n",
       
  1292                fsm->slave->ring_position);
       
  1293         fsm->slave->state_error = 1;
       
  1294         fsm->slave_state = ec_fsm_slave_end;
       
  1295         return;
       
  1296     }
       
  1297 
       
  1298     // set state to SAVEOP
       
  1299     fsm->slave_state = ec_fsm_slave_op;
       
  1300     fsm->change_new = EC_SLAVE_STATE_SAVEOP;
       
  1301     fsm->change_state = ec_fsm_change_start;
       
  1302     fsm->change_state(fsm); // execute immediately
       
  1303 }
       
  1304 
       
  1305 /*****************************************************************************/
       
  1306 
       
  1307 /**
       
  1308    Slave state: OP.
       
  1309    Set slave state to OP.
       
  1310 */
       
  1311 
       
  1312 void ec_fsm_slave_op(ec_fsm_t *fsm /**< finite state machine */)
       
  1313 {
       
  1314     fsm->change_state(fsm); // execute state change state machine
       
  1315 
       
  1316     if (fsm->change_state == ec_fsm_change_error) {
       
  1317         fsm->slave_state = ec_fsm_slave_end;
       
  1318         return;
       
  1319     }
       
  1320 
       
  1321     if (fsm->change_state != ec_fsm_change_end) return;
       
  1322 
       
  1323     // slave is now in SAVEOP
       
  1324     if (fsm->slave->current_state == fsm->slave->requested_state) {
       
  1325         fsm->slave_state = ec_fsm_slave_end;
       
  1326         return;
       
  1327     }
       
  1328 
       
  1329     // set state to OP
       
  1330     fsm->slave_state = ec_fsm_slave_op2;
       
  1331     fsm->change_new = EC_SLAVE_STATE_OP;
       
  1332     fsm->change_state = ec_fsm_change_start;
       
  1333     fsm->change_state(fsm); // execute immediately
       
  1334 }
       
  1335 
       
  1336 /*****************************************************************************/
       
  1337 
       
  1338 /**
       
  1339    Slave state: OP2
       
  1340    Executes the change state machine, until the OP state is set.
       
  1341 */
       
  1342 
       
  1343 void ec_fsm_slave_op2(ec_fsm_t *fsm /**< finite state machine */)
       
  1344 {
       
  1345     fsm->change_state(fsm); // execute state change state machine
       
  1346 
       
  1347     if (fsm->change_state == ec_fsm_change_error) {
       
  1348         fsm->slave_state = ec_fsm_slave_end;
       
  1349         return;
       
  1350     }
       
  1351 
       
  1352     if (fsm->change_state != ec_fsm_change_end) return;
       
  1353 
       
  1354     // slave is now in OP
       
  1355     fsm->slave_state = ec_fsm_slave_end;
       
  1356 }
       
  1357 
       
  1358 /*****************************************************************************/
       
  1359 
       
  1360 /**
       
  1361    Slave state: END.
       
  1362    End state of the slave state machine.
       
  1363 */
       
  1364 
       
  1365 void ec_fsm_slave_end(ec_fsm_t *fsm /**< finite state machine */)
       
  1366 {
       
  1367 }
       
  1368 
       
  1369 /******************************************************************************
       
  1370  *  SII state machine
       
  1371  *****************************************************************************/
       
  1372 
       
  1373 /**
       
  1374    SII state: START_READING.
       
  1375    Starts reading the slave information interface.
       
  1376 */
       
  1377 
       
  1378 void ec_fsm_sii_start_reading(ec_fsm_t *fsm /**< finite state machine */)
       
  1379 {
       
  1380     ec_command_t *command = &fsm->command;
       
  1381 
       
  1382     // initiate read operation
       
  1383     if (fsm->sii_mode) {
       
  1384         ec_command_npwr(command, fsm->slave->station_address, 0x502, 4);
       
  1385     }
       
  1386     else {
       
  1387         ec_command_apwr(command, fsm->slave->ring_position, 0x502, 4);
       
  1388     }
       
  1389 
       
  1390     EC_WRITE_U8 (command->data,     0x00); // read-only access
       
  1391     EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
       
  1392     EC_WRITE_U16(command->data + 2, fsm->sii_offset);
       
  1393     ec_master_queue_command(fsm->master, command);
       
  1394     fsm->sii_state = ec_fsm_sii_check;
       
  1395 }
       
  1396 
       
  1397 /*****************************************************************************/
       
  1398 
       
  1399 /**
       
  1400    SII state: CHECK.
       
  1401    Checks, if the SII-read-command has been sent and issues a fetch command.
       
  1402 */
       
  1403 
       
  1404 void ec_fsm_sii_check(ec_fsm_t *fsm /**< finite state machine */)
       
  1405 {
       
  1406     ec_command_t *command = &fsm->command;
       
  1407 
       
  1408     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1409         EC_ERR("SII: Reception of read command failed.\n");
       
  1410         fsm->sii_state = ec_fsm_sii_error;
       
  1411         return;
       
  1412     }
       
  1413 
       
  1414     fsm->sii_start = get_cycles();
       
  1415 
       
  1416     // issue check/fetch command
       
  1417     if (fsm->sii_mode) {
       
  1418         ec_command_nprd(command, fsm->slave->station_address, 0x502, 10);
       
  1419     }
       
  1420     else {
       
  1421         ec_command_aprd(command, fsm->slave->ring_position, 0x502, 10);
       
  1422     }
       
  1423 
       
  1424     ec_master_queue_command(fsm->master, command);
       
  1425     fsm->sii_state = ec_fsm_sii_fetch;
       
  1426 }
       
  1427 
       
  1428 /*****************************************************************************/
       
  1429 
       
  1430 /**
       
  1431    SII state: FETCH.
       
  1432    Fetches the result of an SII-read command.
       
  1433 */
       
  1434 
       
  1435 void ec_fsm_sii_fetch(ec_fsm_t *fsm /**< finite state machine */)
       
  1436 {
       
  1437     ec_command_t *command = &fsm->command;
       
  1438 
       
  1439     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1440         EC_ERR("SII: Reception of check/fetch command failed.\n");
       
  1441         fsm->sii_state = ec_fsm_sii_error;
       
  1442         return;
       
  1443     }
       
  1444 
       
  1445     // check "busy bit"
       
  1446     if (EC_READ_U8(command->data + 1) & 0x81) {
       
  1447         // still busy... timeout?
       
  1448         if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
       
  1449             EC_ERR("SII: Timeout.\n");
       
  1450             fsm->sii_state = ec_fsm_sii_error;
       
  1451 #if 0
       
  1452             EC_DBG("SII busy: %02X %02X %02X %02X\n",
       
  1453                    EC_READ_U8(command->data + 0),
       
  1454                    EC_READ_U8(command->data + 1),
       
  1455                    EC_READ_U8(command->data + 2),
       
  1456                    EC_READ_U8(command->data + 3));
       
  1457 #endif
       
  1458         }
       
  1459 
       
  1460         // issue check/fetch command again
       
  1461         if (fsm->sii_mode) {
       
  1462             ec_command_nprd(command, fsm->slave->station_address, 0x502, 10);
       
  1463         }
       
  1464         else {
       
  1465             ec_command_aprd(command, fsm->slave->ring_position, 0x502, 10);
       
  1466         }
       
  1467         ec_master_queue_command(fsm->master, command);
       
  1468         return;
       
  1469     }
       
  1470 
       
  1471 #if 0
       
  1472     EC_DBG("SII rec: %02X %02X %02X %02X - %02X %02X %02X %02X\n",
       
  1473            EC_READ_U8(command->data + 0), EC_READ_U8(command->data + 1),
       
  1474            EC_READ_U8(command->data + 2), EC_READ_U8(command->data + 3),
       
  1475            EC_READ_U8(command->data + 6), EC_READ_U8(command->data + 7),
       
  1476            EC_READ_U8(command->data + 8), EC_READ_U8(command->data + 9));
       
  1477 #endif
       
  1478 
       
  1479     // SII value received.
       
  1480     fsm->sii_result = EC_READ_U32(command->data + 6);
       
  1481     fsm->sii_state = ec_fsm_sii_end;
       
  1482 }
       
  1483 
       
  1484 /*****************************************************************************/
       
  1485 
       
  1486 /**
       
  1487    SII state: END.
       
  1488    End state of the slave SII state machine.
       
  1489 */
       
  1490 
       
  1491 void ec_fsm_sii_end(ec_fsm_t *fsm /**< finite state machine */)
       
  1492 {
       
  1493 }
       
  1494 
       
  1495 /*****************************************************************************/
       
  1496 
       
  1497 /**
       
  1498    SII state: ERROR.
       
  1499    End state of the slave SII state machine.
       
  1500 */
       
  1501 
       
  1502 void ec_fsm_sii_error(ec_fsm_t *fsm /**< finite state machine */)
       
  1503 {
       
  1504 }
       
  1505 
       
  1506 /******************************************************************************
       
  1507  *  state change state machine
       
  1508  *****************************************************************************/
       
  1509 
       
  1510 /**
       
  1511    Change state: START.
       
  1512 */
       
  1513 
       
  1514 void ec_fsm_change_start(ec_fsm_t *fsm /**< finite state machine */)
       
  1515 {
       
  1516     ec_command_t *command = &fsm->command;
       
  1517     ec_slave_t *slave = fsm->slave;
       
  1518 
       
  1519     // write new state to slave
       
  1520     ec_command_npwr(command, slave->station_address, 0x0120, 2);
       
  1521     EC_WRITE_U16(command->data, fsm->change_new);
       
  1522     ec_master_queue_command(fsm->master, command);
       
  1523     fsm->change_state = ec_fsm_change_check;
       
  1524 }
       
  1525 
       
  1526 /*****************************************************************************/
       
  1527 
       
  1528 /**
       
  1529    Change state: CHECK.
       
  1530 */
       
  1531 
       
  1532 void ec_fsm_change_check(ec_fsm_t *fsm /**< finite state machine */)
       
  1533 {
       
  1534     ec_command_t *command = &fsm->command;
       
  1535     ec_slave_t *slave = fsm->slave;
       
  1536 
       
  1537     if (command->state != EC_CMD_RECEIVED) {
       
  1538         EC_ERR("Failed to send state command to slave %i!\n",
       
  1539                fsm->slave->ring_position);
       
  1540         slave->state_error = 1;
       
  1541         fsm->change_state = ec_fsm_change_error;
       
  1542         return;
       
  1543     }
       
  1544 
       
  1545     if (command->working_counter != 1) {
       
  1546         EC_ERR("Failed to set state 0x%02X on slave %i: Slave did not"
       
  1547                " respond.\n", fsm->change_new, fsm->slave->ring_position);
       
  1548         slave->state_error = 1;
       
  1549         fsm->change_state = ec_fsm_change_error;
       
  1550         return;
       
  1551     }
       
  1552 
       
  1553     fsm->change_start = get_cycles();
       
  1554 
       
  1555     // read AL status from slave
       
  1556     ec_command_nprd(command, slave->station_address, 0x0130, 2);
       
  1557     ec_master_queue_command(fsm->master, command);
       
  1558     fsm->change_state = ec_fsm_change_status;
       
  1559 }
       
  1560 
       
  1561 /*****************************************************************************/
       
  1562 
       
  1563 /**
       
  1564    Change state: STATUS.
       
  1565 */
       
  1566 
       
  1567 void ec_fsm_change_status(ec_fsm_t *fsm /**< finite state machine */)
       
  1568 {
       
  1569     ec_command_t *command = &fsm->command;
       
  1570     ec_slave_t *slave = fsm->slave;
       
  1571 
       
  1572     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1573         EC_ERR("Failed to check state 0x%02X on slave %i.\n",
       
  1574                fsm->change_new, slave->ring_position);
       
  1575         slave->state_error = 1;
       
  1576         fsm->change_state = ec_fsm_change_error;
       
  1577         return;
       
  1578     }
       
  1579 
       
  1580     slave->current_state = EC_READ_U8(command->data);
       
  1581 
       
  1582     if (slave->current_state == fsm->change_new) {
       
  1583         // state has been set successfully
       
  1584         fsm->change_state = ec_fsm_change_end;
       
  1585         return;
       
  1586     }
       
  1587 
       
  1588     if (slave->current_state & 0x10) {
       
  1589         // state change error
       
  1590         fsm->change_new = slave->current_state & 0x0F;
       
  1591         EC_ERR("Failed to set state 0x%02X - Slave %i refused state change"
       
  1592                " (code 0x%02X)!\n", fsm->change_new, slave->ring_position,
       
  1593                slave->current_state);
       
  1594         // fetch AL status error code
       
  1595         ec_command_nprd(command, slave->station_address, 0x0134, 2);
       
  1596         ec_master_queue_command(fsm->master, command);
       
  1597         fsm->change_state = ec_fsm_change_code;
       
  1598         return;
       
  1599     }
       
  1600 
       
  1601     if (get_cycles() - fsm->change_start >= (cycles_t) 10 * cpu_khz) {
       
  1602         // timeout while checking
       
  1603         slave->state_error = 1;
       
  1604         fsm->change_state = ec_fsm_change_error;
       
  1605         EC_ERR("Timeout while setting state 0x%02X on slave %i.\n",
       
  1606                fsm->change_new, slave->ring_position);
       
  1607         return;
       
  1608     }
       
  1609 
       
  1610     // still old state: check again
       
  1611     ec_command_nprd(command, slave->station_address, 0x0130, 2);
       
  1612     ec_master_queue_command(fsm->master, command);
       
  1613 }
       
  1614 
       
  1615 /*****************************************************************************/
       
  1616 
       
  1617 /**
       
  1618    Change state: CODE.
       
  1619 */
       
  1620 
       
  1621 void ec_fsm_change_code(ec_fsm_t *fsm /**< finite state machine */)
       
  1622 {
       
  1623     ec_command_t *command = &fsm->command;
       
  1624     ec_slave_t *slave = fsm->slave;
       
  1625     uint32_t code;
       
  1626     const ec_code_msg_t *al_msg;
       
  1627 
       
  1628     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1629         EC_ERR("Reception of AL status code command failed.\n");
       
  1630         slave->state_error = 1;
       
  1631         fsm->change_state = ec_fsm_change_error;
       
  1632         return;
       
  1633     }
       
  1634 
       
  1635     if ((code = EC_READ_U16(command->data))) {
       
  1636         for (al_msg = al_status_messages; al_msg->code; al_msg++) {
       
  1637             if (al_msg->code != code) continue;
       
  1638             EC_ERR("AL status message 0x%04X: \"%s\".\n",
       
  1639                    al_msg->code, al_msg->message);
       
  1640             break;
       
  1641         }
       
  1642         if (!al_msg->code)
       
  1643             EC_ERR("Unknown AL status code 0x%04X.\n", code);
       
  1644     }
       
  1645 
       
  1646     // acknowledge "old" slave state
       
  1647     ec_command_npwr(command, slave->station_address, 0x0120, 2);
       
  1648     EC_WRITE_U16(command->data, slave->current_state);
       
  1649     ec_master_queue_command(fsm->master, command);
       
  1650     fsm->change_state = ec_fsm_change_ack;
       
  1651 }
       
  1652 
       
  1653 /*****************************************************************************/
       
  1654 
       
  1655 /**
       
  1656    Change state: ACK.
       
  1657 */
       
  1658 
       
  1659 void ec_fsm_change_ack(ec_fsm_t *fsm /**< finite state machine */)
       
  1660 {
       
  1661     ec_command_t *command = &fsm->command;
       
  1662     ec_slave_t *slave = fsm->slave;
       
  1663 
       
  1664     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1665         EC_ERR("Reception of state ack command failed.\n");
       
  1666         slave->state_error = 1;
       
  1667         fsm->change_state = ec_fsm_change_error;
       
  1668         return;
       
  1669     }
       
  1670 
       
  1671     // read new AL status
       
  1672     ec_command_nprd(command, slave->station_address, 0x0130, 2);
       
  1673     ec_master_queue_command(fsm->master, command);
       
  1674     fsm->change_state = ec_fsm_change_ack2;
       
  1675 }
       
  1676 
       
  1677 /*****************************************************************************/
       
  1678 
       
  1679 /**
       
  1680    Change state: ACK.
       
  1681    Acknowledge 2.
       
  1682 */
       
  1683 
       
  1684 void ec_fsm_change_ack2(ec_fsm_t *fsm /**< finite state machine */)
       
  1685 {
       
  1686     ec_command_t *command = &fsm->command;
       
  1687     ec_slave_t *slave = fsm->slave;
       
  1688 
       
  1689     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1690         EC_ERR("Reception of state ack check command failed.\n");
       
  1691         slave->state_error = 1;
       
  1692         fsm->change_state = ec_fsm_change_error;
       
  1693         return;
       
  1694     }
       
  1695 
       
  1696     slave->current_state = EC_READ_U8(command->data);
       
  1697 
       
  1698     if (slave->current_state == fsm->change_new) {
       
  1699         EC_INFO("Acknowleged state 0x%02X on slave %i.\n",
       
  1700                 slave->current_state, slave->ring_position);
       
  1701         slave->state_error = 1;
       
  1702         fsm->change_state = ec_fsm_change_error;
       
  1703         return;
       
  1704     }
       
  1705 
       
  1706     EC_WARN("Failed to acknowledge state 0x%02X on slave %i"
       
  1707             " - Timeout!\n", fsm->change_new, slave->ring_position);
       
  1708     slave->state_error = 1;
       
  1709     fsm->change_state = ec_fsm_change_error;
       
  1710 }
       
  1711 
       
  1712 /*****************************************************************************/
       
  1713 
       
  1714 /**
       
  1715    Change state: END.
       
  1716 */
       
  1717 
       
  1718 void ec_fsm_change_end(ec_fsm_t *fsm /**< finite state machine */)
       
  1719 {
       
  1720 }
       
  1721 
       
  1722 /*****************************************************************************/
       
  1723 
       
  1724 /**
       
  1725    Change state: ERROR.
       
  1726 */
       
  1727 
       
  1728 void ec_fsm_change_error(ec_fsm_t *fsm /**< finite state machine */)
       
  1729 {
       
  1730 }
       
  1731 
       
  1732 /*****************************************************************************/
       
  1733 
       
  1734 /**
       
  1735    Application layer status messages.
       
  1736 */
       
  1737 
       
  1738 const ec_code_msg_t al_status_messages[] = {
       
  1739     {0x0001, "Unspecified error"},
       
  1740     {0x0011, "Invalud requested state change"},
       
  1741     {0x0012, "Unknown requested state"},
       
  1742     {0x0013, "Bootstrap not supported"},
       
  1743     {0x0014, "No valid firmware"},
       
  1744     {0x0015, "Invalid mailbox configuration"},
       
  1745     {0x0016, "Invalid mailbox configuration"},
       
  1746     {0x0017, "Invalid sync manager configuration"},
       
  1747     {0x0018, "No valid inputs available"},
       
  1748     {0x0019, "No valid outputs"},
       
  1749     {0x001A, "Synchronisation error"},
       
  1750     {0x001B, "Sync manager watchdog"},
       
  1751     {0x0020, "Slave needs cold start"},
       
  1752     {0x0021, "Slave needs INIT"},
       
  1753     {0x0022, "Slave needs PREOP"},
       
  1754     {0x0023, "Slave needs SAVEOP"},
       
  1755     {}
       
  1756 };
       
  1757 
       
  1758 /*****************************************************************************/