master/fsm.c
branchstable-1.0
changeset 1624 9dc190591c0f
parent 1623 05622513f627
equal deleted inserted replaced
1623:05622513f627 1624:9dc190591c0f
    44 
    44 
    45 /*****************************************************************************/
    45 /*****************************************************************************/
    46 
    46 
    47 void ec_fsm_master_start(ec_fsm_t *);
    47 void ec_fsm_master_start(ec_fsm_t *);
    48 void ec_fsm_master_broadcast(ec_fsm_t *);
    48 void ec_fsm_master_broadcast(ec_fsm_t *);
    49 void ec_fsm_master_proc_states(ec_fsm_t *);
    49 void ec_fsm_master_read_states(ec_fsm_t *);
    50 void ec_fsm_master_scan(ec_fsm_t *);
       
    51 void ec_fsm_master_states(ec_fsm_t *);
       
    52 void ec_fsm_master_validate_vendor(ec_fsm_t *);
    50 void ec_fsm_master_validate_vendor(ec_fsm_t *);
    53 void ec_fsm_master_validate_product(ec_fsm_t *);
    51 void ec_fsm_master_validate_product(ec_fsm_t *);
    54 void ec_fsm_master_reconfigure(ec_fsm_t *);
    52 void ec_fsm_master_rewrite_addresses(ec_fsm_t *);
    55 void ec_fsm_master_address(ec_fsm_t *);
    53 void ec_fsm_master_configure_slave(ec_fsm_t *);
    56 void ec_fsm_master_conf(ec_fsm_t *);
    54 void ec_fsm_master_scan_slaves(ec_fsm_t *);
    57 void ec_fsm_master_eeprom(ec_fsm_t *);
    55 void ec_fsm_master_write_eeprom(ec_fsm_t *);
    58 
    56 
    59 void ec_fsm_slave_start_reading(ec_fsm_t *);
    57 void ec_fsm_slavescan_start(ec_fsm_t *);
    60 void ec_fsm_slave_read_status(ec_fsm_t *);
    58 void ec_fsm_slavescan_address(ec_fsm_t *);
    61 void ec_fsm_slave_read_base(ec_fsm_t *);
    59 void ec_fsm_slavescan_state(ec_fsm_t *);
    62 void ec_fsm_slave_read_dl(ec_fsm_t *);
    60 void ec_fsm_slavescan_base(ec_fsm_t *);
    63 void ec_fsm_slave_eeprom_size(ec_fsm_t *);
    61 void ec_fsm_slavescan_datalink(ec_fsm_t *);
    64 void ec_fsm_slave_fetch_eeprom(ec_fsm_t *);
    62 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *);
    65 void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *);
    63 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *);
    66 void ec_fsm_slave_end(ec_fsm_t *);
    64 void ec_fsm_slavescan_end(ec_fsm_t *);
    67 
    65 
    68 void ec_fsm_slave_conf(ec_fsm_t *);
    66 void ec_fsm_slaveconf_init(ec_fsm_t *);
    69 void ec_fsm_slave_sync(ec_fsm_t *);
    67 void ec_fsm_slaveconf_sync(ec_fsm_t *);
    70 void ec_fsm_slave_preop(ec_fsm_t *);
    68 void ec_fsm_slaveconf_preop(ec_fsm_t *);
    71 void ec_fsm_slave_fmmu(ec_fsm_t *);
    69 void ec_fsm_slaveconf_fmmu(ec_fsm_t *);
    72 void ec_fsm_slave_saveop(ec_fsm_t *);
    70 void ec_fsm_slaveconf_saveop(ec_fsm_t *);
    73 void ec_fsm_slave_op(ec_fsm_t *);
    71 void ec_fsm_slaveconf_op(ec_fsm_t *);
    74 void ec_fsm_slave_op2(ec_fsm_t *);
    72 void ec_fsm_slaveconf_end(ec_fsm_t *);
    75 
    73 
    76 void ec_fsm_sii_start_reading(ec_fsm_t *);
    74 void ec_fsm_sii_start_reading(ec_fsm_t *);
    77 void ec_fsm_sii_read_check(ec_fsm_t *);
    75 void ec_fsm_sii_read_check(ec_fsm_t *);
    78 void ec_fsm_sii_read_fetch(ec_fsm_t *);
    76 void ec_fsm_sii_read_fetch(ec_fsm_t *);
    79 void ec_fsm_sii_start_writing(ec_fsm_t *);
    77 void ec_fsm_sii_start_writing(ec_fsm_t *);
    85 void ec_fsm_change_start(ec_fsm_t *);
    83 void ec_fsm_change_start(ec_fsm_t *);
    86 void ec_fsm_change_check(ec_fsm_t *);
    84 void ec_fsm_change_check(ec_fsm_t *);
    87 void ec_fsm_change_status(ec_fsm_t *);
    85 void ec_fsm_change_status(ec_fsm_t *);
    88 void ec_fsm_change_code(ec_fsm_t *);
    86 void ec_fsm_change_code(ec_fsm_t *);
    89 void ec_fsm_change_ack(ec_fsm_t *);
    87 void ec_fsm_change_ack(ec_fsm_t *);
    90 void ec_fsm_change_ack2(ec_fsm_t *);
    88 void ec_fsm_change_check_ack(ec_fsm_t *);
    91 void ec_fsm_change_end(ec_fsm_t *);
    89 void ec_fsm_change_end(ec_fsm_t *);
    92 void ec_fsm_change_error(ec_fsm_t *);
    90 void ec_fsm_change_error(ec_fsm_t *);
    93 
    91 
    94 /*****************************************************************************/
    92 /*****************************************************************************/
    95 
    93 
    97    Constructor.
    95    Constructor.
    98 */
    96 */
    99 
    97 
   100 int ec_fsm_init(ec_fsm_t *fsm, /**< finite state machine */
    98 int ec_fsm_init(ec_fsm_t *fsm, /**< finite state machine */
   101                 ec_master_t *master /**< EtherCAT master */
    99                 ec_master_t *master /**< EtherCAT master */
   102                 )
   100     )
   103 {
   101 {
   104     fsm->master = master;
   102     fsm->master = master;
   105     fsm->master_state = ec_fsm_master_start;
   103     fsm->master_state = ec_fsm_master_start;
   106     fsm->master_slaves_responding = 0;
   104     fsm->master_slaves_responding = 0;
   107     fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN;
   105     fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN;
   108     fsm->master_validation = 0;
   106     fsm->master_validation = 0;
   109 
   107 
   110     ec_command_init(&fsm->command);
   108     ec_datagram_init(&fsm->datagram);
   111     if (ec_command_prealloc(&fsm->command, EC_MAX_DATA_SIZE)) {
   109     if (ec_datagram_prealloc(&fsm->datagram, EC_MAX_DATA_SIZE)) {
   112         EC_ERR("FSM failed to allocate FSM command.\n");
   110         EC_ERR("Failed to allocate FSM datagram.\n");
   113         return -1;
   111         return -1;
   114     }
   112     }
   115 
   113 
   116     return 0;
   114     return 0;
   117 }
   115 }
   122    Destructor.
   120    Destructor.
   123 */
   121 */
   124 
   122 
   125 void ec_fsm_clear(ec_fsm_t *fsm /**< finite state machine */)
   123 void ec_fsm_clear(ec_fsm_t *fsm /**< finite state machine */)
   126 {
   124 {
   127     ec_command_clear(&fsm->command);
   125     ec_datagram_clear(&fsm->datagram);
   128 }
   126 }
   129 
   127 
   130 /*****************************************************************************/
   128 /*****************************************************************************/
   131 
   129 
   132 /**
   130 /**
   160    Starts with getting slave count and slave states.
   158    Starts with getting slave count and slave states.
   161 */
   159 */
   162 
   160 
   163 void ec_fsm_master_start(ec_fsm_t *fsm)
   161 void ec_fsm_master_start(ec_fsm_t *fsm)
   164 {
   162 {
   165     ec_command_brd(&fsm->command, 0x0130, 2);
   163     ec_datagram_brd(&fsm->datagram, 0x0130, 2);
   166     ec_master_queue_command(fsm->master, &fsm->command);
   164     ec_master_queue_datagram(fsm->master, &fsm->datagram);
   167     fsm->master_state = ec_fsm_master_broadcast;
   165     fsm->master_state = ec_fsm_master_broadcast;
   168 }
   166 }
   169 
   167 
   170 /*****************************************************************************/
   168 /*****************************************************************************/
   171 
   169 
   174    Processes the broadcast read slave count and slaves states.
   172    Processes the broadcast read slave count and slaves states.
   175 */
   173 */
   176 
   174 
   177 void ec_fsm_master_broadcast(ec_fsm_t *fsm /**< finite state machine */)
   175 void ec_fsm_master_broadcast(ec_fsm_t *fsm /**< finite state machine */)
   178 {
   176 {
   179     ec_command_t *command = &fsm->command;
   177     ec_datagram_t *datagram = &fsm->datagram;
   180     unsigned int topology_change, states_change, i;
   178     unsigned int topology_change, states_change, i;
   181     ec_slave_t *slave;
   179     ec_slave_t *slave;
   182     ec_master_t *master = fsm->master;
   180     ec_master_t *master = fsm->master;
   183 
   181 
   184     if (command->state != EC_CMD_RECEIVED) {
   182     if (datagram->state != EC_CMD_RECEIVED) {
   185         if (!master->device->link_state) {
   183         if (!master->device->link_state) {
   186             fsm->master_slaves_responding = 0;
   184             fsm->master_slaves_responding = 0;
   187             list_for_each_entry(slave, &master->slaves, list) {
   185             list_for_each_entry(slave, &master->slaves, list) {
   188                 slave->online = 0;
   186                 slave->online = 0;
   189             }
   187             }
   191         fsm->master_state = ec_fsm_master_start;
   189         fsm->master_state = ec_fsm_master_start;
   192         fsm->master_state(fsm); // execute immediately
   190         fsm->master_state(fsm); // execute immediately
   193         return;
   191         return;
   194     }
   192     }
   195 
   193 
   196     topology_change = (command->working_counter !=
   194     topology_change = (datagram->working_counter !=
   197                        fsm->master_slaves_responding);
   195                        fsm->master_slaves_responding);
   198     states_change = (EC_READ_U8(command->data) != fsm->master_slave_states);
   196     states_change = (EC_READ_U8(datagram->data) != fsm->master_slave_states);
   199 
   197 
   200     fsm->master_slave_states = EC_READ_U8(command->data);
   198     fsm->master_slave_states = EC_READ_U8(datagram->data);
   201     fsm->master_slaves_responding = command->working_counter;
   199     fsm->master_slaves_responding = datagram->working_counter;
   202 
   200 
   203     if (topology_change) {
   201     if (topology_change) {
   204         EC_INFO("%i slave%s responding.\n",
   202         EC_INFO("%i slave%s responding.\n",
   205                 fsm->master_slaves_responding,
   203                 fsm->master_slaves_responding,
   206                 fsm->master_slaves_responding == 1 ? "" : "s");
   204                 fsm->master_slaves_responding == 1 ? "" : "s");
   219         EC_INFO("Slave states: ");
   217         EC_INFO("Slave states: ");
   220         ec_print_states(fsm->master_slave_states);
   218         ec_print_states(fsm->master_slave_states);
   221         printk(".\n");
   219         printk(".\n");
   222     }
   220     }
   223 
   221 
   224     // topology change in free-run mode: clear all slaves and scan the bus
   222     // topology change in idle mode: clear all slaves and scan the bus
   225     if (topology_change && master->mode == EC_MASTER_MODE_FREERUN) {
   223     if (topology_change && master->mode == EC_MASTER_MODE_IDLE) {
   226         EC_INFO("Scanning bus.\n");
   224         EC_INFO("Scanning bus.\n");
   227 
   225 
   228         ec_master_eoe_stop(master);
   226         ec_master_eoe_stop(master);
   229         ec_master_clear_slaves(master);
   227         ec_master_clear_slaves(master);
   230 
   228 
   262             list_add_tail(&slave->list, &master->slaves);
   260             list_add_tail(&slave->list, &master->slaves);
   263         }
   261         }
   264 
   262 
   265         // begin scanning of slaves
   263         // begin scanning of slaves
   266         fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   264         fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   267         fsm->slave_state = ec_fsm_slave_start_reading;
   265         fsm->slave_state = ec_fsm_slavescan_start;
   268         fsm->master_state = ec_fsm_master_scan;
   266         fsm->master_state = ec_fsm_master_scan_slaves;
   269         fsm->master_state(fsm); // execute immediately
   267         fsm->master_state(fsm); // execute immediately
   270         return;
   268         return;
   271     }
   269     }
   272 
   270 
   273     // fetch state from each slave
   271     // fetch state from each slave
   274     fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   272     fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   275     ec_command_nprd(&fsm->command, fsm->slave->station_address, 0x0130, 2);
   273     ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address, 0x0130, 2);
   276     ec_master_queue_command(master, &fsm->command);
   274     ec_master_queue_datagram(master, &fsm->datagram);
   277     fsm->master_state = ec_fsm_master_states;
   275     fsm->master_state = ec_fsm_master_read_states;
       
   276 }
       
   277 
       
   278 /*****************************************************************************/
       
   279 
       
   280 /**
       
   281    Master action: PROC_STATES.
       
   282    Processes the slave states.
       
   283 */
       
   284 
       
   285 void ec_fsm_master_action_process_states(ec_fsm_t *fsm
       
   286                                          /**< finite state machine */
       
   287                                          )
       
   288 {
       
   289     ec_master_t *master = fsm->master;
       
   290     ec_slave_t *slave;
       
   291 
       
   292     // check if any slaves are not in the state, they're supposed to be
       
   293     list_for_each_entry(slave, &master->slaves, list) {
       
   294         if (slave->error_flag ||
       
   295             !slave->online ||
       
   296             slave->requested_state == EC_SLAVE_STATE_UNKNOWN ||
       
   297             slave->current_state == slave->requested_state) continue;
       
   298 
       
   299         EC_INFO("Changing state of slave %i from ", slave->ring_position);
       
   300         ec_print_states(slave->current_state);
       
   301         printk(" to ");
       
   302         ec_print_states(slave->requested_state);
       
   303         printk(".\n");
       
   304 
       
   305         fsm->slave = slave;
       
   306         fsm->slave_state = ec_fsm_slaveconf_init;
       
   307         fsm->change_new = EC_SLAVE_STATE_INIT;
       
   308         fsm->change_state = ec_fsm_change_start;
       
   309         fsm->master_state = ec_fsm_master_configure_slave;
       
   310         fsm->master_state(fsm); // execute immediately
       
   311         return;
       
   312     }
       
   313 
       
   314     if (master->mode == EC_MASTER_MODE_IDLE) {
       
   315         // nothing to configure. check for pending EEPROM write operations.
       
   316         list_for_each_entry(slave, &master->slaves, list) {
       
   317             if (!slave->new_eeprom_data) continue;
       
   318 
       
   319             if (!slave->online || slave->error_flag) {
       
   320                 kfree(slave->new_eeprom_data);
       
   321                 slave->new_eeprom_data = NULL;
       
   322                 EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
       
   323                        slave->ring_position);
       
   324                 continue;
       
   325             }
       
   326 
       
   327             // found pending EEPROM write operation. execute it!
       
   328             EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
       
   329             fsm->sii_offset = 0x0000;
       
   330             memcpy(fsm->sii_value, slave->new_eeprom_data, 2);
       
   331             fsm->sii_mode = 1;
       
   332             fsm->sii_state = ec_fsm_sii_start_writing;
       
   333             fsm->slave = slave;
       
   334             fsm->master_state = ec_fsm_master_write_eeprom;
       
   335             fsm->master_state(fsm); // execute immediately
       
   336             return;
       
   337         }
       
   338     }
       
   339 
       
   340     // nothing to do. restart master state machine.
       
   341     fsm->master_state = ec_fsm_master_start;
       
   342     fsm->master_state(fsm); // execute immediately
   278 }
   343 }
   279 
   344 
   280 /*****************************************************************************/
   345 /*****************************************************************************/
   281 
   346 
   282 /**
   347 /**
   287                                            /**< finite state machine */)
   352                                            /**< finite state machine */)
   288 {
   353 {
   289     ec_master_t *master = fsm->master;
   354     ec_master_t *master = fsm->master;
   290     ec_slave_t *slave = fsm->slave;
   355     ec_slave_t *slave = fsm->slave;
   291 
   356 
   292     // have all states been read?
   357     // is there another slave to query?
   293     if (slave->list.next == &master->slaves) {
   358     if (slave->list.next != &master->slaves) {
   294 
   359         // process next slave
   295         // check, if a bus validation has to be done
   360         fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   296         if (fsm->master_validation) {
   361         ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address,
   297             fsm->master_validation = 0;
   362                          0x0130, 2);
   298             list_for_each_entry(slave, &master->slaves, list) {
   363         ec_master_queue_datagram(master, &fsm->datagram);
   299                 if (slave->online) continue;
   364         fsm->master_state = ec_fsm_master_read_states;
   300 
   365         return;
   301                 // At least one slave is offline. validate!
   366     }
   302                 EC_INFO("Validating bus.\n");
   367 
   303                 fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   368     // all slave states read
   304                 fsm->master_state = ec_fsm_master_validate_vendor;
   369 
   305                 fsm->sii_offset = 0x0008; // vendor ID
   370     // check, if a bus validation has to be done
   306                 fsm->sii_mode = 0;
   371     if (fsm->master_validation) {
   307                 fsm->sii_state = ec_fsm_sii_start_reading;
   372         fsm->master_validation = 0;
   308                 fsm->sii_state(fsm); // execute immediately
   373         list_for_each_entry(slave, &master->slaves, list) {
   309                 return;
   374             if (slave->online) continue;
   310             }
   375 
       
   376             // At least one slave is offline. validate!
       
   377             EC_INFO("Validating bus.\n");
       
   378             fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
       
   379             fsm->master_state = ec_fsm_master_validate_vendor;
       
   380             fsm->sii_offset = 0x0008; // vendor ID
       
   381             fsm->sii_mode = 0;
       
   382             fsm->sii_state = ec_fsm_sii_start_reading;
       
   383             fsm->sii_state(fsm); // execute immediately
       
   384             return;
   311         }
   385         }
   312 
   386     }
   313         fsm->master_state = ec_fsm_master_proc_states;
   387 
   314         fsm->master_state(fsm); // execute immediately
   388     ec_fsm_master_action_process_states(fsm);
   315         return;
       
   316     }
       
   317 
       
   318     // process next slave
       
   319     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   320     ec_command_nprd(&fsm->command, fsm->slave->station_address, 0x0130, 2);
       
   321     ec_master_queue_command(master, &fsm->command);
       
   322     fsm->master_state = ec_fsm_master_states;
       
   323 }
   389 }
   324 
   390 
   325 /*****************************************************************************/
   391 /*****************************************************************************/
   326 
   392 
   327 /**
   393 /**
   328    Master state: STATES.
   394    Master state: STATES.
   329    Fetches the AL- and online state of a slave.
   395    Fetches the AL- and online state of a slave.
   330 */
   396 */
   331 
   397 
   332 void ec_fsm_master_states(ec_fsm_t *fsm /**< finite state machine */)
   398 void ec_fsm_master_read_states(ec_fsm_t *fsm /**< finite state machine */)
   333 {
   399 {
   334     ec_slave_t *slave = fsm->slave;
   400     ec_slave_t *slave = fsm->slave;
   335     ec_command_t *command = &fsm->command;
   401     ec_datagram_t *datagram = &fsm->datagram;
   336     uint8_t new_state;
   402     uint8_t new_state;
   337 
   403 
   338     if (command->state != EC_CMD_RECEIVED) {
   404     if (datagram->state != EC_CMD_RECEIVED) {
   339         fsm->master_state = ec_fsm_master_start;
   405         fsm->master_state = ec_fsm_master_start;
   340         fsm->master_state(fsm); // execute immediately
   406         fsm->master_state(fsm); // execute immediately
   341         return;
   407         return;
   342     }
   408     }
   343 
   409 
   344     // did the slave not respond to its station address?
   410     // did the slave not respond to its station address?
   345     if (command->working_counter != 1) {
   411     if (datagram->working_counter != 1) {
   346         if (slave->online) {
   412         if (slave->online) {
   347             slave->online = 0;
   413             slave->online = 0;
   348             EC_INFO("Slave %i: offline.\n", slave->ring_position);
   414             EC_INFO("Slave %i: offline.\n", slave->ring_position);
   349         }
   415         }
   350         ec_fsm_master_action_next_slave_state(fsm);
   416         ec_fsm_master_action_next_slave_state(fsm);
   351         return;
   417         return;
   352     }
   418     }
   353 
   419 
   354     // slave responded
   420     // slave responded
   355     new_state = EC_READ_U8(command->data);
   421     new_state = EC_READ_U8(datagram->data);
   356     if (!slave->online) { // slave was offline before
   422     if (!slave->online) { // slave was offline before
   357         slave->online = 1;
   423         slave->online = 1;
   358         slave->state_error = 0;
   424         slave->error_flag = 0; // clear error flag
   359         slave->current_state = new_state;
   425         slave->current_state = new_state;
   360         EC_INFO("Slave %i: online (", slave->ring_position);
   426         EC_INFO("Slave %i: online (", slave->ring_position);
   361         ec_print_states(new_state);
   427         ec_print_states(new_state);
   362         printk(").\n");
   428         printk(").\n");
   363     }
   429     }
   374 }
   440 }
   375 
   441 
   376 /*****************************************************************************/
   442 /*****************************************************************************/
   377 
   443 
   378 /**
   444 /**
   379    Master state: PROC_STATES.
       
   380    Processes the slave states.
       
   381 */
       
   382 
       
   383 void ec_fsm_master_proc_states(ec_fsm_t *fsm /**< finite state machine */)
       
   384 {
       
   385     ec_master_t *master = fsm->master;
       
   386     ec_slave_t *slave;
       
   387 
       
   388     // check if any slaves are not in the state, they're supposed to be
       
   389     list_for_each_entry(slave, &master->slaves, list) {
       
   390         if (slave->state_error || !slave->online ||
       
   391             slave->requested_state == EC_SLAVE_STATE_UNKNOWN ||
       
   392             slave->current_state == slave->requested_state) continue;
       
   393 
       
   394         EC_INFO("Changing state of slave %i from ", slave->ring_position);
       
   395         ec_print_states(slave->current_state);
       
   396         printk(" to ");
       
   397         ec_print_states(slave->requested_state);
       
   398         printk(".\n");
       
   399 
       
   400         fsm->slave = slave;
       
   401         fsm->slave_state = ec_fsm_slave_conf;
       
   402         fsm->change_new = EC_SLAVE_STATE_INIT;
       
   403         fsm->change_state = ec_fsm_change_start;
       
   404         fsm->master_state = ec_fsm_master_conf;
       
   405         fsm->master_state(fsm); // execute immediately
       
   406         return;
       
   407     }
       
   408 
       
   409     if (master->mode == EC_MASTER_MODE_FREERUN) {
       
   410         // nothing to configure. check for pending EEPROM write operations.
       
   411         list_for_each_entry(slave, &master->slaves, list) {
       
   412             if (!slave->new_eeprom_data) continue;
       
   413 
       
   414             // found pending EEPROM write operation. execute it!
       
   415             EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
       
   416             fsm->sii_offset = 0x0000;
       
   417             memcpy(fsm->sii_value, slave->new_eeprom_data, 2);
       
   418             fsm->sii_mode = 1;
       
   419             fsm->sii_state = ec_fsm_sii_start_writing;
       
   420             fsm->slave = slave;
       
   421             fsm->master_state = ec_fsm_master_eeprom;
       
   422             fsm->master_state(fsm); // execute immediately
       
   423             return;
       
   424         }
       
   425     }
       
   426 
       
   427     // nothing to do. restart master state machine.
       
   428     fsm->master_state = ec_fsm_master_start;
       
   429     fsm->master_state(fsm); // execute immediately
       
   430 }
       
   431 
       
   432 /*****************************************************************************/
       
   433 
       
   434 /**
       
   435    Master state: VALIDATE_VENDOR.
   445    Master state: VALIDATE_VENDOR.
   436    Validates the vendor ID of a slave.
   446    Validates the vendor ID of a slave.
   437 */
   447 */
   438 
   448 
   439 void ec_fsm_master_validate_vendor(ec_fsm_t *fsm /**< finite state machine */)
   449 void ec_fsm_master_validate_vendor(ec_fsm_t *fsm /**< finite state machine */)
   441     ec_slave_t *slave = fsm->slave;
   451     ec_slave_t *slave = fsm->slave;
   442 
   452 
   443     fsm->sii_state(fsm); // execute SII state machine
   453     fsm->sii_state(fsm); // execute SII state machine
   444 
   454 
   445     if (fsm->sii_state == ec_fsm_sii_error) {
   455     if (fsm->sii_state == ec_fsm_sii_error) {
       
   456         fsm->slave->error_flag = 1;
   446         EC_ERR("Failed to validate vendor ID of slave %i.\n",
   457         EC_ERR("Failed to validate vendor ID of slave %i.\n",
   447                slave->ring_position);
   458                slave->ring_position);
   448         fsm->master_state = ec_fsm_master_start;
   459         fsm->master_state = ec_fsm_master_start;
   449         fsm->master_state(fsm); // execute immediately
   460         fsm->master_state(fsm); // execute immediately
   450         return;
   461         return;
   468 }
   479 }
   469 
   480 
   470 /*****************************************************************************/
   481 /*****************************************************************************/
   471 
   482 
   472 /**
   483 /**
   473    Master state: VALIDATE_PRODUCT.
   484    Master action: ADDRESS.
   474    Validates the product ID of a slave.
       
   475 */
       
   476 
       
   477 void ec_fsm_master_validate_product(ec_fsm_t *fsm /**< finite state machine */)
       
   478 {
       
   479     ec_slave_t *slave = fsm->slave;
       
   480 
       
   481     fsm->sii_state(fsm); // execute SII state machine
       
   482 
       
   483     if (fsm->sii_state == ec_fsm_sii_error) {
       
   484         EC_ERR("Failed to validate product code of slave %i.\n",
       
   485                slave->ring_position);
       
   486         fsm->master_state = ec_fsm_master_start;
       
   487         fsm->master_state(fsm); // execute immediately
       
   488         return;
       
   489     }
       
   490 
       
   491     if (fsm->sii_state != ec_fsm_sii_end) return;
       
   492 
       
   493     if (EC_READ_U32(fsm->sii_value) != slave->sii_product_code) {
       
   494         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
       
   495         EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
       
   496                EC_READ_U32(fsm->sii_value));
       
   497         fsm->master_state = ec_fsm_master_start;
       
   498         fsm->master_state(fsm); // execute immediately
       
   499         return;
       
   500     }
       
   501 
       
   502     // have all states been validated?
       
   503     if (slave->list.next == &fsm->master->slaves) {
       
   504         fsm->slave = list_entry(fsm->master->slaves.next, ec_slave_t, list);
       
   505         fsm->master_state = ec_fsm_master_reconfigure;
       
   506         return;
       
   507     }
       
   508 
       
   509     // validate next slave
       
   510     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   511     fsm->master_state = ec_fsm_master_validate_vendor;
       
   512     fsm->sii_offset = 0x0008; // vendor ID
       
   513     fsm->sii_mode = 0;
       
   514     fsm->sii_state = ec_fsm_sii_start_reading;
       
   515     fsm->sii_state(fsm); // execute immediately
       
   516 }
       
   517 
       
   518 /*****************************************************************************/
       
   519 
       
   520 /**
       
   521    Master state: RECONFIGURE.
       
   522    Looks for slave, that have lost their configuration and writes
   485    Looks for slave, that have lost their configuration and writes
   523    their station address, so that they can be reconfigured later.
   486    their station address, so that they can be reconfigured later.
   524 */
   487 */
   525 
   488 
   526 void ec_fsm_master_reconfigure(ec_fsm_t *fsm /**< finite state machine */)
   489 void ec_fsm_master_action_addresses(ec_fsm_t *fsm /**< finite state machine */)
   527 {
   490 {
   528     ec_command_t *command = &fsm->command;
   491     ec_datagram_t *datagram = &fsm->datagram;
   529 
   492 
   530     while (fsm->slave->online) {
   493     while (fsm->slave->online) {
   531         if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
   494         if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
   532             fsm->master_state = ec_fsm_master_start;
   495             fsm->master_state = ec_fsm_master_start;
   533             fsm->master_state(fsm); // execute immediately
   496             fsm->master_state(fsm); // execute immediately
   538     }
   501     }
   539 
   502 
   540     EC_INFO("Reinitializing slave %i.\n", fsm->slave->ring_position);
   503     EC_INFO("Reinitializing slave %i.\n", fsm->slave->ring_position);
   541 
   504 
   542     // write station address
   505     // write station address
   543     ec_command_apwr(command, fsm->slave->ring_position, 0x0010, 2);
   506     ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2);
   544     EC_WRITE_U16(command->data, fsm->slave->station_address);
   507     EC_WRITE_U16(datagram->data, fsm->slave->station_address);
   545     ec_master_queue_command(fsm->master, command);
   508     ec_master_queue_datagram(fsm->master, datagram);
   546     fsm->master_state = ec_fsm_master_address;
   509     fsm->master_state = ec_fsm_master_rewrite_addresses;
       
   510 }
       
   511 
       
   512 /*****************************************************************************/
       
   513 
       
   514 /**
       
   515    Master state: VALIDATE_PRODUCT.
       
   516    Validates the product ID of a slave.
       
   517 */
       
   518 
       
   519 void ec_fsm_master_validate_product(ec_fsm_t *fsm /**< finite state machine */)
       
   520 {
       
   521     ec_slave_t *slave = fsm->slave;
       
   522 
       
   523     fsm->sii_state(fsm); // execute SII state machine
       
   524 
       
   525     if (fsm->sii_state == ec_fsm_sii_error) {
       
   526         fsm->slave->error_flag = 1;
       
   527         EC_ERR("Failed to validate product code of slave %i.\n",
       
   528                slave->ring_position);
       
   529         fsm->master_state = ec_fsm_master_start;
       
   530         fsm->master_state(fsm); // execute immediately
       
   531         return;
       
   532     }
       
   533 
       
   534     if (fsm->sii_state != ec_fsm_sii_end) return;
       
   535 
       
   536     if (EC_READ_U32(fsm->sii_value) != slave->sii_product_code) {
       
   537         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
       
   538         EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
       
   539                EC_READ_U32(fsm->sii_value));
       
   540         fsm->master_state = ec_fsm_master_start;
       
   541         fsm->master_state(fsm); // execute immediately
       
   542         return;
       
   543     }
       
   544 
       
   545     // have all states been validated?
       
   546     if (slave->list.next == &fsm->master->slaves) {
       
   547         fsm->slave = list_entry(fsm->master->slaves.next, ec_slave_t, list);
       
   548         // start writing addresses to offline slaves
       
   549         ec_fsm_master_action_addresses(fsm);
       
   550         return;
       
   551     }
       
   552 
       
   553     // validate next slave
       
   554     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   555     fsm->master_state = ec_fsm_master_validate_vendor;
       
   556     fsm->sii_offset = 0x0008; // vendor ID
       
   557     fsm->sii_mode = 0;
       
   558     fsm->sii_state = ec_fsm_sii_start_reading;
       
   559     fsm->sii_state(fsm); // execute immediately
   547 }
   560 }
   548 
   561 
   549 /*****************************************************************************/
   562 /*****************************************************************************/
   550 
   563 
   551 /**
   564 /**
   552    Master state: ADDRESS.
   565    Master state: ADDRESS.
   553    Checks, if the new station address has been written to the slave.
   566    Checks, if the new station address has been written to the slave.
   554 */
   567 */
   555 
   568 
   556 void ec_fsm_master_address(ec_fsm_t *fsm /**< finite state machine */)
   569 void ec_fsm_master_rewrite_addresses(ec_fsm_t *fsm
   557 {
   570                                      /**< finite state machine */
   558     ec_slave_t *slave = fsm->slave;
   571                                      )
   559     ec_command_t *command = &fsm->command;
   572 {
   560 
   573     ec_slave_t *slave = fsm->slave;
   561     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
   574     ec_datagram_t *datagram = &fsm->datagram;
       
   575 
       
   576     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   562         EC_ERR("Failed to write station address on slave %i.\n",
   577         EC_ERR("Failed to write station address on slave %i.\n",
   563                slave->ring_position);
   578                slave->ring_position);
   564     }
   579     }
   565 
   580 
   566     if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
   581     if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
   569         return;
   584         return;
   570     }
   585     }
   571 
   586 
   572     // check next slave
   587     // check next slave
   573     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   588     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   574     fsm->master_state = ec_fsm_master_reconfigure;
   589     // Write new station address to slave
   575     fsm->master_state(fsm); // execute immediately
   590     ec_fsm_master_action_addresses(fsm);
   576 }
   591 }
   577 
   592 
   578 /*****************************************************************************/
   593 /*****************************************************************************/
   579 
   594 
   580 /**
   595 /**
   581    Master state: SCAN.
   596    Master state: SCAN.
   582    Executes the sub-statemachine for the scanning of a slave.
   597    Executes the sub-statemachine for the scanning of a slave.
   583 */
   598 */
   584 
   599 
   585 void ec_fsm_master_scan(ec_fsm_t *fsm /**< finite state machine */)
   600 void ec_fsm_master_scan_slaves(ec_fsm_t *fsm /**< finite state machine */)
   586 {
   601 {
   587     ec_master_t *master = fsm->master;
   602     ec_master_t *master = fsm->master;
   588     ec_slave_t *slave = fsm->slave;
   603     ec_slave_t *slave = fsm->slave;
   589     uint16_t coupler_index, coupler_subindex;
   604     uint16_t coupler_index, coupler_subindex;
   590     uint16_t reverse_coupler_index, current_coupler_index;
   605     uint16_t reverse_coupler_index, current_coupler_index;
   591     ec_slave_ident_t *ident;
   606     ec_slave_ident_t *ident;
   592 
   607 
   593     fsm->slave_state(fsm); // execute slave state machine
   608     fsm->slave_state(fsm); // execute slave state machine
   594 
   609 
   595     if (fsm->slave_state != ec_fsm_slave_end) return;
   610     if (fsm->slave_state != ec_fsm_slavescan_end) return;
   596 
   611 
   597     // have all slaves been fetched?
   612     // have all slaves been fetched?
   598     if (slave->list.next == &master->slaves) {
   613     if (slave->list.next == &master->slaves) {
   599         EC_INFO("Bus scanning completed.\n");
   614         EC_INFO("Bus scanning completed.\n");
   600 
   615 
   617                 }
   632                 }
   618                 ident++;
   633                 ident++;
   619             }
   634             }
   620 
   635 
   621             if (!slave->type) {
   636             if (!slave->type) {
   622                 EC_WARN("FSM: Unknown slave device (vendor 0x%08X,"
   637                 EC_WARN("Unknown slave device (vendor 0x%08X,"
   623                         " code 0x%08X) at position %i.\n",
   638                         " code 0x%08X) at position %i.\n",
   624                         slave->sii_vendor_id, slave->sii_product_code,
   639                         slave->sii_vendor_id, slave->sii_product_code,
   625                         slave->ring_position);
   640                         slave->ring_position);
   626             }
   641             }
   627             else {
   642             else {
   634                     coupler_subindex = 0;
   649                     coupler_subindex = 0;
   635                 }
   650                 }
   636             }
   651             }
   637 
   652 
   638             // determine initial state.
   653             // determine initial state.
   639             if ((slave->type && slave->type->special == EC_TYPE_BUS_COUPLER)) {
   654             if ((slave->type &&
       
   655                  (slave->type->special == EC_TYPE_BUS_COUPLER ||
       
   656                   slave->type->special == EC_TYPE_INFRA))) {
   640                 slave->requested_state = EC_SLAVE_STATE_OP;
   657                 slave->requested_state = EC_SLAVE_STATE_OP;
   641             }
   658             }
   642             else {
   659             else {
   643                 if (master->mode == EC_MASTER_MODE_RUNNING)
   660                 if (master->mode == EC_MASTER_MODE_RUNNING)
   644                     slave->requested_state = EC_SLAVE_STATE_PREOP;
   661                     slave->requested_state = EC_SLAVE_STATE_PREOP;
   645                 else
   662                 else
   646                     slave->requested_state = EC_SLAVE_STATE_INIT;
   663                     slave->requested_state = EC_SLAVE_STATE_INIT;
   647             }
   664             }
   648             slave->state_error = 0;
   665             slave->error_flag = 0;
   649 
   666 
   650             // calculate coupler-based slave address
   667             // calculate coupler-based slave address
   651             slave->coupler_index = current_coupler_index;
   668             slave->coupler_index = current_coupler_index;
   652             slave->coupler_subindex = coupler_subindex;
   669             slave->coupler_subindex = coupler_subindex;
   653             coupler_subindex++;
   670             coupler_subindex++;
   654         }
   671         }
   655 
   672 
   656         if (master->mode == EC_MASTER_MODE_FREERUN) {
   673         if (master->mode == EC_MASTER_MODE_IDLE) {
   657             // start EoE processing
   674             // start EoE processing
   658             ec_master_eoe_start(master);
   675             ec_master_eoe_start(master);
   659         }
   676         }
   660 
   677 
   661         fsm->master_state = ec_fsm_master_start;
   678         fsm->master_state = ec_fsm_master_start;
   663         return;
   680         return;
   664     }
   681     }
   665 
   682 
   666     // process next slave
   683     // process next slave
   667     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   684     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   668     fsm->slave_state = ec_fsm_slave_start_reading;
   685     fsm->slave_state = ec_fsm_slavescan_start;
   669     fsm->slave_state(fsm); // execute immediately
   686     fsm->slave_state(fsm); // execute immediately
   670 }
   687 }
   671 
   688 
   672 /*****************************************************************************/
   689 /*****************************************************************************/
   673 
   690 
   674 /**
   691 /**
   675    Master state: CONF.
   692    Master state: CONF.
   676    Starts configuring a slave.
   693    Starts configuring a slave.
   677 */
   694 */
   678 
   695 
   679 void ec_fsm_master_conf(ec_fsm_t *fsm /**< finite state machine */)
   696 void ec_fsm_master_configure_slave(ec_fsm_t *fsm
       
   697                                    /**< finite state machine */
       
   698                                    )
   680 {
   699 {
   681     fsm->slave_state(fsm); // execute slave's state machine
   700     fsm->slave_state(fsm); // execute slave's state machine
   682     if (fsm->slave_state != ec_fsm_slave_end) return;
   701     if (fsm->slave_state != ec_fsm_slaveconf_end) return;
   683     fsm->master_state = ec_fsm_master_proc_states;
   702 
   684     fsm->master_state(fsm); // execute immediately
   703     ec_fsm_master_action_process_states(fsm);
   685 }
   704 }
   686 
   705 
   687 /*****************************************************************************/
   706 /*****************************************************************************/
   688 
   707 
   689 /**
   708 /**
   690    Master state: EEPROM.
   709    Master state: EEPROM.
   691 */
   710 */
   692 
   711 
   693 void ec_fsm_master_eeprom(ec_fsm_t *fsm /**< finite state machine */)
   712 void ec_fsm_master_write_eeprom(ec_fsm_t *fsm /**< finite state machine */)
   694 {
   713 {
   695     ec_slave_t *slave = fsm->slave;
   714     ec_slave_t *slave = fsm->slave;
   696 
   715 
   697     fsm->sii_state(fsm); // execute SII state machine
   716     fsm->sii_state(fsm); // execute SII state machine
   698 
   717 
   699     if (fsm->sii_state == ec_fsm_sii_error) {
   718     if (fsm->sii_state == ec_fsm_sii_error) {
       
   719         fsm->slave->error_flag = 1;
   700         EC_ERR("Failed to write EEPROM contents to slave %i.\n",
   720         EC_ERR("Failed to write EEPROM contents to slave %i.\n",
   701                slave->ring_position);
   721                slave->ring_position);
   702         kfree(slave->new_eeprom_data);
   722         kfree(slave->new_eeprom_data);
   703         slave->new_eeprom_data = NULL;
   723         slave->new_eeprom_data = NULL;
   704         fsm->master_state = ec_fsm_master_start;
   724         fsm->master_state = ec_fsm_master_start;
   720     EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position);
   740     EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position);
   721     kfree(slave->new_eeprom_data);
   741     kfree(slave->new_eeprom_data);
   722     slave->new_eeprom_data = NULL;
   742     slave->new_eeprom_data = NULL;
   723 
   743 
   724     // restart master state machine.
   744     // restart master state machine.
   725     fsm->master_state = ec_fsm_master_start;
   745     fsm->master_state = ec_fsm_master_start; // TODO: Evaluate new contents!
   726     fsm->master_state(fsm); // execute immediately
   746     fsm->master_state(fsm); // execute immediately
   727     return;
   747     return;
   728 }
   748 }
   729 
   749 
   730 /******************************************************************************
   750 /******************************************************************************
   731  *  slave state machine
   751  *  slave scan sub state machine
   732  *****************************************************************************/
   752  *****************************************************************************/
   733 
   753 
   734 /**
   754 /**
   735    Slave state: START_READING.
   755    Slave state: START_READING.
   736    First state of the slave state machine. Writes the station address to the
   756    First state of the slave state machine. Writes the station address to the
   737    slave, according to its ring position.
   757    slave, according to its ring position.
   738 */
   758 */
   739 
   759 
   740 void ec_fsm_slave_start_reading(ec_fsm_t *fsm /**< finite state machine */)
   760 void ec_fsm_slavescan_start(ec_fsm_t *fsm /**< finite state machine */)
   741 {
   761 {
   742     ec_command_t *command = &fsm->command;
   762     ec_datagram_t *datagram = &fsm->datagram;
   743 
   763 
   744     // write station address
   764     // write station address
   745     ec_command_apwr(command, fsm->slave->ring_position, 0x0010, 2);
   765     ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2);
   746     EC_WRITE_U16(command->data, fsm->slave->station_address);
   766     EC_WRITE_U16(datagram->data, fsm->slave->station_address);
   747     ec_master_queue_command(fsm->master, command);
   767     ec_master_queue_datagram(fsm->master, datagram);
   748     fsm->slave_state = ec_fsm_slave_read_status;
   768     fsm->slave_state = ec_fsm_slavescan_address;
   749 }
   769 }
   750 
   770 
   751 /*****************************************************************************/
   771 /*****************************************************************************/
   752 
   772 
   753 /**
   773 /**
   754    Slave state: READ_STATUS.
   774    Slave state: ADDRESS.
   755 */
   775 */
   756 
   776 
   757 void ec_fsm_slave_read_status(ec_fsm_t *fsm /**< finite state machine */)
   777 void ec_fsm_slavescan_address(ec_fsm_t *fsm /**< finite state machine */)
   758 {
   778 {
   759     ec_command_t *command = &fsm->command;
   779     ec_datagram_t *datagram = &fsm->datagram;
   760 
   780 
   761     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
   781     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   762         EC_ERR("FSM failed to write station address of slave %i.\n",
   782         fsm->slave->error_flag = 1;
       
   783         fsm->slave_state = ec_fsm_slavescan_end;
       
   784         EC_ERR("Failed to write station address of slave %i.\n",
   763                fsm->slave->ring_position);
   785                fsm->slave->ring_position);
   764         fsm->slave_state = ec_fsm_slave_end;
   786         return;
   765         return;
   787     }
   766     }
   788 
   767 
   789     // Read AL state
   768     // read AL status
   790     ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0130, 2);
   769     ec_command_nprd(command, fsm->slave->station_address, 0x0130, 2);
   791     ec_master_queue_datagram(fsm->master, datagram);
   770     ec_master_queue_command(fsm->master, command);
   792     fsm->slave_state = ec_fsm_slavescan_state;
   771     fsm->slave_state = ec_fsm_slave_read_base;
   793 }
   772 }
   794 
   773 
   795 /*****************************************************************************/
   774 /*****************************************************************************/
   796 
   775 
   797 /**
   776 /**
   798    Slave state: STATE.
   777    Slave state: READ_BASE.
   799 */
   778 */
   800 
   779 
   801 void ec_fsm_slavescan_state(ec_fsm_t *fsm /**< finite state machine */)
   780 void ec_fsm_slave_read_base(ec_fsm_t *fsm /**< finite state machine */)
   802 {
   781 {
   803     ec_datagram_t *datagram = &fsm->datagram;
   782     ec_command_t *command = &fsm->command;
   804     ec_slave_t *slave = fsm->slave;
   783     ec_slave_t *slave = fsm->slave;
   805 
   784 
   806     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   785     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
   807         fsm->slave->error_flag = 1;
   786         EC_ERR("FSM failed to read AL status of slave %i.\n",
   808         fsm->slave_state = ec_fsm_slavescan_end;
       
   809         EC_ERR("Failed to read AL state of slave %i.\n",
   787                fsm->slave->ring_position);
   810                fsm->slave->ring_position);
   788         fsm->slave_state = ec_fsm_slave_end;
   811         return;
   789         return;
   812     }
   790     }
   813 
   791 
   814     slave->current_state = EC_READ_U8(datagram->data);
   792     slave->current_state = EC_READ_U8(command->data);
       
   793     if (slave->current_state & EC_ACK) {
   815     if (slave->current_state & EC_ACK) {
   794         EC_WARN("Slave %i has status error bit set (0x%02X)!\n",
   816         EC_WARN("Slave %i has state error bit set (0x%02X)!\n",
   795                 slave->ring_position, slave->current_state);
   817                 slave->ring_position, slave->current_state);
   796         slave->current_state &= 0x0F;
   818         slave->current_state &= 0x0F;
   797     }
   819     }
   798 
   820 
   799     // read base data
   821     // read base data
   800     ec_command_nprd(command, fsm->slave->station_address, 0x0000, 6);
   822     ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0000, 6);
   801     ec_master_queue_command(fsm->master, command);
   823     ec_master_queue_datagram(fsm->master, datagram);
   802     fsm->slave_state = ec_fsm_slave_read_dl;
   824     fsm->slave_state = ec_fsm_slavescan_base;
   803 }
   825 }
   804 
   826 
   805 /*****************************************************************************/
   827 /*****************************************************************************/
   806 
   828 
   807 /**
   829 /**
   808    Slave state: READ_DL.
   830    Slave state: BASE.
   809 */
   831 */
   810 
   832 
   811 void ec_fsm_slave_read_dl(ec_fsm_t *fsm /**< finite state machine */)
   833 void ec_fsm_slavescan_base(ec_fsm_t *fsm /**< finite state machine */)
   812 {
   834 {
   813     ec_command_t *command = &fsm->command;
   835     ec_datagram_t *datagram = &fsm->datagram;
   814     ec_slave_t *slave = fsm->slave;
   836     ec_slave_t *slave = fsm->slave;
   815 
   837 
   816     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
   838     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   817         EC_ERR("FSM failed to read base data of slave %i.\n",
   839         fsm->slave->error_flag = 1;
       
   840         fsm->slave_state = ec_fsm_slavescan_end;
       
   841         EC_ERR("Failed to read base data of slave %i.\n",
   818                slave->ring_position);
   842                slave->ring_position);
   819         fsm->slave_state = ec_fsm_slave_end;
   843         return;
   820         return;
   844     }
   821     }
   845 
   822 
   846     slave->base_type       = EC_READ_U8 (datagram->data);
   823     slave->base_type       = EC_READ_U8 (command->data);
   847     slave->base_revision   = EC_READ_U8 (datagram->data + 1);
   824     slave->base_revision   = EC_READ_U8 (command->data + 1);
   848     slave->base_build      = EC_READ_U16(datagram->data + 2);
   825     slave->base_build      = EC_READ_U16(command->data + 2);
   849     slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4);
   826     slave->base_fmmu_count = EC_READ_U8 (command->data + 4);
   850     slave->base_sync_count = EC_READ_U8 (datagram->data + 5);
   827     slave->base_sync_count = EC_READ_U8 (command->data + 5);
       
   828 
   851 
   829     if (slave->base_fmmu_count > EC_MAX_FMMUS)
   852     if (slave->base_fmmu_count > EC_MAX_FMMUS)
   830         slave->base_fmmu_count = EC_MAX_FMMUS;
   853         slave->base_fmmu_count = EC_MAX_FMMUS;
   831 
   854 
   832     // read data link status
   855     // read data link status
   833     ec_command_nprd(command, slave->station_address, 0x0110, 2);
   856     ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2);
   834     ec_master_queue_command(slave->master, command);
   857     ec_master_queue_datagram(slave->master, datagram);
   835     fsm->slave_state = ec_fsm_slave_eeprom_size;
   858     fsm->slave_state = ec_fsm_slavescan_datalink;
   836 }
   859 }
   837 
   860 
   838 /*****************************************************************************/
   861 /*****************************************************************************/
   839 
   862 
   840 /**
   863 /**
   841    Slave state: EEPROM_SIZE.
   864    Slave state: DATALINK.
   842    Read the actual size of the EEPROM to allocate the EEPROM image.
   865 */
   843 */
   866 
   844 
   867 void ec_fsm_slavescan_datalink(ec_fsm_t *fsm /**< finite state machine */)
   845 void ec_fsm_slave_eeprom_size(ec_fsm_t *fsm /**< finite state machine */)
   868 {
   846 {
   869     ec_datagram_t *datagram = &fsm->datagram;
   847     ec_command_t *command = &fsm->command;
       
   848     ec_slave_t *slave = fsm->slave;
   870     ec_slave_t *slave = fsm->slave;
   849     uint16_t dl_status;
   871     uint16_t dl_status;
   850     unsigned int i;
   872     unsigned int i;
   851 
   873 
   852     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
   874     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   853         EC_ERR("FSM failed to read DL status of slave %i.\n",
   875         fsm->slave->error_flag = 1;
       
   876         fsm->slave_state = ec_fsm_slavescan_end;
       
   877         EC_ERR("Failed to read DL status of slave %i.\n",
   854                slave->ring_position);
   878                slave->ring_position);
   855         fsm->slave_state = ec_fsm_slave_end;
   879         return;
   856         return;
   880     }
   857     }
   881 
   858 
   882     dl_status = EC_READ_U16(datagram->data);
   859     dl_status = EC_READ_U16(command->data);
       
   860     for (i = 0; i < 4; i++) {
   883     for (i = 0; i < 4; i++) {
   861         slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
   884         slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
   862         slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
   885         slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
   863         slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
   886         slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
   864     }
   887     }
   866     // Start fetching EEPROM size
   889     // Start fetching EEPROM size
   867 
   890 
   868     fsm->sii_offset = 0x0040; // first category header
   891     fsm->sii_offset = 0x0040; // first category header
   869     fsm->sii_mode = 1;
   892     fsm->sii_mode = 1;
   870     fsm->sii_state = ec_fsm_sii_start_reading;
   893     fsm->sii_state = ec_fsm_sii_start_reading;
   871     fsm->slave_state = ec_fsm_slave_fetch_eeprom;
   894     fsm->slave_state = ec_fsm_slavescan_eeprom_size;
   872     fsm->slave_state(fsm); // execute state immediately
   895     fsm->slave_state(fsm); // execute state immediately
   873 }
   896 }
   874 
   897 
   875 /*****************************************************************************/
   898 /*****************************************************************************/
   876 
   899 
   877 /**
   900 /**
   878    Slave state: FETCH_EEPROM.
   901    Slave state: EEPROM_SIZE.
   879 */
   902 */
   880 
   903 
   881 void ec_fsm_slave_fetch_eeprom(ec_fsm_t *fsm /**< finite state machine */)
   904 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *fsm /**< finite state machine */)
   882 {
   905 {
   883     ec_slave_t *slave = fsm->slave;
   906     ec_slave_t *slave = fsm->slave;
   884     uint16_t cat_type, cat_size;
   907     uint16_t cat_type, cat_size;
   885 
   908 
   886     // execute SII state machine
   909     // execute SII state machine
   887     fsm->sii_state(fsm);
   910     fsm->sii_state(fsm);
   888 
   911 
   889     if (fsm->sii_state == ec_fsm_sii_error) {
   912     if (fsm->sii_state == ec_fsm_sii_error) {
   890         fsm->slave_state = ec_fsm_slave_end;
   913         fsm->slave->error_flag = 1;
       
   914         fsm->slave_state = ec_fsm_slavescan_end;
   891         EC_ERR("Failed to read EEPROM size of slave %i.\n",
   915         EC_ERR("Failed to read EEPROM size of slave %i.\n",
   892                slave->ring_position);
   916                slave->ring_position);
   893         return;
   917         return;
   894     }
   918     }
   895 
   919 
   913         kfree(slave->eeprom_data);
   937         kfree(slave->eeprom_data);
   914     }
   938     }
   915 
   939 
   916     if (!(slave->eeprom_data =
   940     if (!(slave->eeprom_data =
   917           (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
   941           (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
       
   942         fsm->slave->error_flag = 1;
       
   943         fsm->slave_state = ec_fsm_slavescan_end;
   918         EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
   944         EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
   919                slave->ring_position);
   945                slave->ring_position);
   920         fsm->slave_state = ec_fsm_slave_end;
       
   921         return;
   946         return;
   922     }
   947     }
   923 
   948 
   924     // Start fetching EEPROM contents
   949     // Start fetching EEPROM contents
   925 
   950 
   926     fsm->sii_offset = 0x0000;
   951     fsm->sii_offset = 0x0000;
   927     fsm->sii_mode = 1;
   952     fsm->sii_mode = 1;
   928     fsm->sii_state = ec_fsm_sii_start_reading;
   953     fsm->sii_state = ec_fsm_sii_start_reading;
   929     fsm->slave_state = ec_fsm_slave_fetch_eeprom2;
   954     fsm->slave_state = ec_fsm_slavescan_eeprom_data;
   930     fsm->slave_state(fsm); // execute state immediately
   955     fsm->slave_state(fsm); // execute state immediately
   931 }
   956 }
   932 
   957 
   933 /*****************************************************************************/
   958 /*****************************************************************************/
   934 
   959 
   935 /**
   960 /**
   936    Slave state: FETCH_EEPROM2.
   961    Slave state: EEPROM_DATA.
   937 */
   962 */
   938 
   963 
   939 void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *fsm /**< finite state machine */)
   964 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *fsm /**< finite state machine */)
   940 {
   965 {
   941     ec_slave_t *slave = fsm->slave;
   966     ec_slave_t *slave = fsm->slave;
   942     uint16_t *cat_word, cat_type, cat_size;
   967     uint16_t *cat_word, cat_type, cat_size;
   943 
   968 
   944     // execute SII state machine
   969     // execute SII state machine
   945     fsm->sii_state(fsm);
   970     fsm->sii_state(fsm);
   946 
   971 
   947     if (fsm->sii_state == ec_fsm_sii_error) {
   972     if (fsm->sii_state == ec_fsm_sii_error) {
   948         fsm->slave_state = ec_fsm_slave_end;
   973         fsm->slave->error_flag = 1;
       
   974         fsm->slave_state = ec_fsm_slavescan_end;
   949         EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
   975         EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
   950                slave->ring_position);
   976                slave->ring_position);
   951         return;
   977         return;
   952     }
   978     }
   953 
   979 
  1031         }
  1057         }
  1032 
  1058 
  1033         cat_word += cat_size + 2;
  1059         cat_word += cat_size + 2;
  1034     }
  1060     }
  1035 
  1061 
  1036  end:
  1062     fsm->slave_state = ec_fsm_slavescan_end;
  1037     fsm->slave_state = ec_fsm_slave_end;
  1063 
  1038 }
  1064 end:
  1039 
  1065     fsm->slave->error_flag = 1;
  1040 /*****************************************************************************/
  1066     fsm->slave_state = ec_fsm_slavescan_end;
  1041 
  1067 }
  1042 /**
  1068 
  1043    Slave state: CONF.
  1069 /*****************************************************************************/
  1044 */
  1070 
  1045 
  1071 /**
  1046 void ec_fsm_slave_conf(ec_fsm_t *fsm /**< finite state machine */)
  1072    Slave state: END.
  1047 {
  1073    End state of the slave state machine.
  1048     ec_slave_t *slave = fsm->slave;
  1074 */
  1049     ec_master_t *master = fsm->master;
  1075 
  1050     ec_command_t *command = &fsm->command;
  1076 void ec_fsm_slavescan_end(ec_fsm_t *fsm /**< finite state machine */)
       
  1077 {
       
  1078 }
       
  1079 
       
  1080 /******************************************************************************
       
  1081  *  slave configuration sub state machine
       
  1082  *****************************************************************************/
       
  1083 
       
  1084 /**
       
  1085    Slave state: INIT.
       
  1086 */
       
  1087 
       
  1088 void ec_fsm_slaveconf_init(ec_fsm_t *fsm /**< finite state machine */)
       
  1089 {
       
  1090     ec_slave_t *slave = fsm->slave;
       
  1091     ec_datagram_t *datagram = &fsm->datagram;
       
  1092     const ec_sync_t *sync;
       
  1093     ec_eeprom_sync_t *eeprom_sync, mbox_sync;
       
  1094     unsigned int j;
  1051 
  1095 
  1052     fsm->change_state(fsm); // execute state change state machine
  1096     fsm->change_state(fsm); // execute state change state machine
  1053 
  1097 
  1054     if (fsm->change_state == ec_fsm_change_error) {
  1098     if (fsm->change_state == ec_fsm_change_error) {
  1055         fsm->slave_state = ec_fsm_slave_end;
  1099         slave->error_flag = 1;
       
  1100         fsm->slave_state = ec_fsm_slaveconf_end;
  1056         return;
  1101         return;
  1057     }
  1102     }
  1058 
  1103 
  1059     if (fsm->change_state != ec_fsm_change_end) return;
  1104     if (fsm->change_state != ec_fsm_change_end) return;
  1060 
  1105 
  1061     // slave is now in INIT
  1106     // slave is now in INIT
  1062     if (slave->current_state == slave->requested_state) {
  1107     if (slave->current_state == slave->requested_state) {
  1063         fsm->slave_state = ec_fsm_slave_end;
  1108         fsm->slave_state = ec_fsm_slaveconf_end; // successful
  1064         return;
  1109         return;
  1065     }
  1110     }
  1066 
  1111 
  1067     // check for slave registration
  1112     // check for slave registration
  1068     if (!slave->type) {
  1113     if (!slave->type) {
  1069         EC_WARN("Slave %i has unknown type!\n", slave->ring_position);
  1114         EC_WARN("Slave %i has unknown type!\n", slave->ring_position);
  1070     }
  1115     }
  1071 
  1116 
  1072     // check and reset CRC fault counters
  1117     // check and reset CRC fault counters
  1073     //ec_slave_check_crc(slave);
  1118     //ec_slave_check_crc(slave);
  1074 
  1119     // TODO!
  1075     if (!slave->base_fmmu_count) { // no fmmus
       
  1076         fsm->slave_state = ec_fsm_slave_sync;
       
  1077         fsm->slave_state(fsm); // execute immediately
       
  1078         return;
       
  1079     }
       
  1080 
       
  1081     // reset FMMUs
       
  1082     ec_command_npwr(command, slave->station_address, 0x0600,
       
  1083                     EC_FMMU_SIZE * slave->base_fmmu_count);
       
  1084     memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
       
  1085     ec_master_queue_command(master, command);
       
  1086     fsm->slave_state = ec_fsm_slave_sync;
       
  1087 }
       
  1088 
       
  1089 /*****************************************************************************/
       
  1090 
       
  1091 /**
       
  1092    Slave state: SYNC.
       
  1093    Configure sync managers.
       
  1094 */
       
  1095 
       
  1096 void ec_fsm_slave_sync(ec_fsm_t *fsm /**< finite state machine */)
       
  1097 {
       
  1098     ec_command_t *command = &fsm->command;
       
  1099     ec_slave_t *slave = fsm->slave;
       
  1100     unsigned int j;
       
  1101     const ec_sync_t *sync;
       
  1102     ec_eeprom_sync_t *eeprom_sync, mbox_sync;
       
  1103 
       
  1104     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1105         EC_ERR("Failed to reset FMMUs of slave %i.\n",
       
  1106                slave->ring_position);
       
  1107         slave->state_error = 1;
       
  1108         fsm->slave_state = ec_fsm_slave_end;
       
  1109         return;
       
  1110     }
       
  1111 
  1120 
  1112     if (!slave->base_sync_count) { // no sync managers
  1121     if (!slave->base_sync_count) { // no sync managers
  1113         fsm->slave_state = ec_fsm_slave_preop;
  1122         fsm->slave_state = ec_fsm_slaveconf_preop;
  1114         fsm->slave_state(fsm); // execute immediately
  1123         fsm->change_new = EC_SLAVE_STATE_PREOP;
       
  1124         fsm->change_state = ec_fsm_change_start;
       
  1125         fsm->change_state(fsm); // execute immediately
  1115         return;
  1126         return;
  1116     }
  1127     }
  1117 
  1128 
  1118     // configure sync managers
  1129     // configure sync managers
  1119     ec_command_npwr(command, slave->station_address, 0x0800,
  1130     ec_datagram_npwr(datagram, slave->station_address, 0x0800,
  1120                     EC_SYNC_SIZE * slave->base_sync_count);
  1131                      EC_SYNC_SIZE * slave->base_sync_count);
  1121     memset(command->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
  1132     memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
       
  1133 
       
  1134     // does the slave supply sync manager configurations in its EEPROM?
       
  1135     if (!list_empty(&slave->eeprom_syncs)) {
       
  1136         list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
       
  1137             if (eeprom_sync->index >= slave->base_sync_count) {
       
  1138                 fsm->slave->error_flag = 1;
       
  1139                 fsm->slave_state = ec_fsm_slaveconf_end;
       
  1140                 EC_ERR("Invalid sync manager configuration found!");
       
  1141                 return;
       
  1142             }
       
  1143             ec_eeprom_sync_config(eeprom_sync, slave,
       
  1144                                   datagram->data + EC_SYNC_SIZE
       
  1145                                   * eeprom_sync->index);
       
  1146         }
       
  1147     }
  1122 
  1148 
  1123     // known slave type, take type's SM information
  1149     // known slave type, take type's SM information
  1124     if (slave->type) {
  1150     else if (slave->type) {
  1125         for (j = 0; slave->type->sync_managers[j] && j < EC_MAX_SYNC; j++) {
  1151         for (j = 0; slave->type->sync_managers[j] && j < EC_MAX_SYNC; j++) {
  1126             sync = slave->type->sync_managers[j];
  1152             sync = slave->type->sync_managers[j];
  1127             ec_sync_config(sync, slave, command->data + EC_SYNC_SIZE * j);
  1153             ec_sync_config(sync, slave, datagram->data + EC_SYNC_SIZE * j);
  1128         }
  1154         }
  1129     }
  1155     }
  1130 
  1156 
  1131     // unknown type, but slave has mailbox
  1157     // unknown type, but slave has mailbox
  1132     else if (slave->sii_mailbox_protocols)
  1158     else if (slave->sii_mailbox_protocols)
  1133     {
  1159     {
  1134         // does it supply sync manager configurations in its EEPROM?
  1160         // guess mailbox settings
  1135         if (!list_empty(&slave->eeprom_syncs)) {
  1161         mbox_sync.physical_start_address =
  1136             list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
  1162             slave->sii_rx_mailbox_offset;
  1137                 if (eeprom_sync->index >= slave->base_sync_count) {
  1163         mbox_sync.length = slave->sii_rx_mailbox_size;
  1138                     EC_ERR("Invalid sync manager configuration found!");
  1164         mbox_sync.control_register = 0x26;
  1139                     fsm->slave_state = ec_fsm_slave_end;
  1165         mbox_sync.enable = 1;
  1140                     return;
  1166         ec_eeprom_sync_config(&mbox_sync, slave, datagram->data);
  1141                 }
  1167 
  1142                 ec_eeprom_sync_config(eeprom_sync,
  1168         mbox_sync.physical_start_address =
  1143                                       command->data + EC_SYNC_SIZE
  1169             slave->sii_tx_mailbox_offset;
  1144                                       * eeprom_sync->index);
  1170         mbox_sync.length = slave->sii_tx_mailbox_size;
  1145             }
  1171         mbox_sync.control_register = 0x22;
  1146         }
  1172         mbox_sync.enable = 1;
  1147 
  1173         ec_eeprom_sync_config(&mbox_sync, slave,
  1148         // no sync manager information; guess mailbox settings
  1174                               datagram->data + EC_SYNC_SIZE);
  1149         else {
       
  1150             mbox_sync.physical_start_address =
       
  1151                 slave->sii_rx_mailbox_offset;
       
  1152             mbox_sync.length = slave->sii_rx_mailbox_size;
       
  1153             mbox_sync.control_register = 0x26;
       
  1154             mbox_sync.enable = 1;
       
  1155             ec_eeprom_sync_config(&mbox_sync, command->data);
       
  1156 
       
  1157             mbox_sync.physical_start_address =
       
  1158                 slave->sii_tx_mailbox_offset;
       
  1159             mbox_sync.length = slave->sii_tx_mailbox_size;
       
  1160             mbox_sync.control_register = 0x22;
       
  1161             mbox_sync.enable = 1;
       
  1162             ec_eeprom_sync_config(&mbox_sync,
       
  1163                                   command->data + EC_SYNC_SIZE);
       
  1164         }
       
  1165 
  1175 
  1166         EC_INFO("Mailbox configured for unknown slave %i\n",
  1176         EC_INFO("Mailbox configured for unknown slave %i\n",
  1167                 slave->ring_position);
  1177                 slave->ring_position);
  1168     }
  1178     }
  1169 
  1179 
  1170     ec_master_queue_command(fsm->master, command);
  1180     ec_master_queue_datagram(fsm->master, datagram);
  1171     fsm->slave_state = ec_fsm_slave_preop;
  1181     fsm->slave_state = ec_fsm_slaveconf_sync;
  1172 }
  1182 }
  1173 
  1183 
  1174 /*****************************************************************************/
  1184 /*****************************************************************************/
  1175 
  1185 
  1176 /**
  1186 /**
  1177    Slave state: PREOP.
  1187    Slave state: SYNC.
  1178    Change slave state to PREOP.
  1188 */
  1179 */
  1189 
  1180 
  1190 void ec_fsm_slaveconf_sync(ec_fsm_t *fsm /**< finite state machine */)
  1181 void ec_fsm_slave_preop(ec_fsm_t *fsm /**< finite state machine */)
  1191 {
  1182 {
  1192     ec_datagram_t *datagram = &fsm->datagram;
  1183     ec_command_t *command = &fsm->command;
  1193     ec_slave_t *slave = fsm->slave;
  1184     ec_slave_t *slave = fsm->slave;
  1194 
  1185 
  1195     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1186     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
  1196         slave->error_flag = 1;
       
  1197         fsm->slave_state = ec_fsm_slaveconf_end;
  1187         EC_ERR("Failed to set sync managers on slave %i.\n",
  1198         EC_ERR("Failed to set sync managers on slave %i.\n",
  1188                slave->ring_position);
  1199                slave->ring_position);
  1189         slave->state_error = 1;
  1200         return;
  1190         fsm->slave_state = ec_fsm_slave_end;
  1201     }
  1191         return;
  1202 
  1192     }
  1203     fsm->slave_state = ec_fsm_slaveconf_preop;
  1193 
       
  1194     fsm->change_new = EC_SLAVE_STATE_PREOP;
  1204     fsm->change_new = EC_SLAVE_STATE_PREOP;
  1195     fsm->change_state = ec_fsm_change_start;
  1205     fsm->change_state = ec_fsm_change_start;
  1196     fsm->slave_state = ec_fsm_slave_fmmu;
       
  1197     fsm->change_state(fsm); // execute immediately
  1206     fsm->change_state(fsm); // execute immediately
  1198 }
  1207 }
  1199 
  1208 
  1200 /*****************************************************************************/
  1209 /*****************************************************************************/
  1201 
  1210 
  1202 /**
  1211 /**
  1203    Slave state: FMMU.
  1212    Slave state: PREOP.
  1204    Configure FMMUs.
  1213 */
  1205 */
  1214 
  1206 
  1215 void ec_fsm_slaveconf_preop(ec_fsm_t *fsm /**< finite state machine */)
  1207 void ec_fsm_slave_fmmu(ec_fsm_t *fsm /**< finite state machine */)
       
  1208 {
  1216 {
  1209     ec_slave_t *slave = fsm->slave;
  1217     ec_slave_t *slave = fsm->slave;
  1210     ec_master_t *master = fsm->master;
  1218     ec_master_t *master = fsm->master;
  1211     ec_command_t *command = &fsm->command;
  1219     ec_datagram_t *datagram = &fsm->datagram;
  1212     unsigned int j;
  1220     unsigned int j;
  1213 
  1221 
  1214     fsm->change_state(fsm); // execute state change state machine
  1222     fsm->change_state(fsm); // execute state change state machine
  1215 
  1223 
  1216     if (fsm->change_state == ec_fsm_change_error) {
  1224     if (fsm->change_state == ec_fsm_change_error) {
  1217         fsm->slave_state = ec_fsm_slave_end;
  1225         slave->error_flag = 1;
       
  1226         fsm->slave_state = ec_fsm_slaveconf_end;
  1218         return;
  1227         return;
  1219     }
  1228     }
  1220 
  1229 
  1221     if (fsm->change_state != ec_fsm_change_end) return;
  1230     if (fsm->change_state != ec_fsm_change_end) return;
  1222 
  1231 
  1223     // slave is now in PREOP
  1232     // slave is now in PREOP
  1224     if (slave->current_state == slave->requested_state) {
  1233     if (slave->current_state == slave->requested_state) {
  1225         fsm->slave_state = ec_fsm_slave_end;
  1234         fsm->slave_state = ec_fsm_slaveconf_end; // successful
  1226         return;
  1235         return;
  1227     }
  1236     }
  1228 
  1237 
  1229     // stop activation here for slaves without type
  1238     // stop activation here for slaves without type
  1230     if (!slave->type) {
  1239     if (!slave->type) {
  1231         fsm->slave_state = ec_fsm_slave_end;
  1240         fsm->slave_state = ec_fsm_slaveconf_end; // successful
  1232         return;
  1241         return;
  1233     }
  1242     }
  1234 
  1243 
  1235     if (!slave->base_fmmu_count) {
  1244     if (!slave->base_fmmu_count) {
  1236         fsm->slave_state = ec_fsm_slave_saveop;
  1245         fsm->slave_state = ec_fsm_slaveconf_saveop;
  1237         fsm->slave_state(fsm); // execute immediately
  1246         fsm->change_new = EC_SLAVE_STATE_SAVEOP;
       
  1247         fsm->change_state = ec_fsm_change_start;
       
  1248         fsm->change_state(fsm); // execute immediately
  1238         return;
  1249         return;
  1239     }
  1250     }
  1240 
  1251 
  1241     // configure FMMUs
  1252     // configure FMMUs
  1242     ec_command_npwr(command, slave->station_address,
  1253     ec_datagram_npwr(datagram, slave->station_address,
  1243                     0x0600, EC_FMMU_SIZE * slave->base_fmmu_count);
  1254                      0x0600, EC_FMMU_SIZE * slave->base_fmmu_count);
  1244     memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
  1255     memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
  1245     for (j = 0; j < slave->fmmu_count; j++) {
  1256     for (j = 0; j < slave->fmmu_count; j++) {
  1246         ec_fmmu_config(&slave->fmmus[j], slave,
  1257         ec_fmmu_config(&slave->fmmus[j], slave,
  1247                        command->data + EC_FMMU_SIZE * j);
  1258                        datagram->data + EC_FMMU_SIZE * j);
  1248     }
  1259     }
  1249 
  1260 
  1250     ec_master_queue_command(master, command);
  1261     ec_master_queue_datagram(master, datagram);
  1251     fsm->slave_state = ec_fsm_slave_saveop;
  1262     fsm->slave_state = ec_fsm_slaveconf_fmmu;
  1252 }
  1263 }
  1253 
  1264 
  1254 /*****************************************************************************/
  1265 /*****************************************************************************/
  1255 
  1266 
  1256 /**
  1267 /**
  1257    Slave state: SAVEOP.
  1268    Slave state: FMMU.
  1258    Set slave state to SAVEOP.
  1269 */
  1259 */
  1270 
  1260 
  1271 void ec_fsm_slaveconf_fmmu(ec_fsm_t *fsm /**< finite state machine */)
  1261 void ec_fsm_slave_saveop(ec_fsm_t *fsm /**< finite state machine */)
  1272 {
  1262 {
  1273     ec_datagram_t *datagram = &fsm->datagram;
  1263     ec_command_t *command = &fsm->command;
  1274 
  1264 
  1275     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1265     if (fsm->slave->base_fmmu_count && (command->state != EC_CMD_RECEIVED ||
  1276         fsm->slave->error_flag = 1;
  1266                                         command->working_counter != 1)) {
  1277         fsm->slave_state = ec_fsm_slaveconf_end;
  1267         EC_ERR("FSM failed to set FMMUs on slave %i.\n",
  1278         EC_ERR("Failed to set FMMUs on slave %i.\n",
  1268                fsm->slave->ring_position);
  1279                fsm->slave->ring_position);
  1269         fsm->slave->state_error = 1;
       
  1270         fsm->slave_state = ec_fsm_slave_end;
       
  1271         return;
  1280         return;
  1272     }
  1281     }
  1273 
  1282 
  1274     // set state to SAVEOP
  1283     // set state to SAVEOP
  1275     fsm->slave_state = ec_fsm_slave_op;
  1284     fsm->slave_state = ec_fsm_slaveconf_saveop;
  1276     fsm->change_new = EC_SLAVE_STATE_SAVEOP;
  1285     fsm->change_new = EC_SLAVE_STATE_SAVEOP;
  1277     fsm->change_state = ec_fsm_change_start;
  1286     fsm->change_state = ec_fsm_change_start;
  1278     fsm->change_state(fsm); // execute immediately
  1287     fsm->change_state(fsm); // execute immediately
  1279 }
  1288 }
  1280 
  1289 
  1281 /*****************************************************************************/
  1290 /*****************************************************************************/
  1282 
  1291 
  1283 /**
  1292 /**
  1284    Slave state: OP.
  1293    Slave state: SAVEOP.
  1285    Set slave state to OP.
  1294 */
  1286 */
  1295 
  1287 
  1296 void ec_fsm_slaveconf_saveop(ec_fsm_t *fsm /**< finite state machine */)
  1288 void ec_fsm_slave_op(ec_fsm_t *fsm /**< finite state machine */)
       
  1289 {
  1297 {
  1290     fsm->change_state(fsm); // execute state change state machine
  1298     fsm->change_state(fsm); // execute state change state machine
  1291 
  1299 
  1292     if (fsm->change_state == ec_fsm_change_error) {
  1300     if (fsm->change_state == ec_fsm_change_error) {
  1293         fsm->slave_state = ec_fsm_slave_end;
  1301         fsm->slave->error_flag = 1;
       
  1302         fsm->slave_state = ec_fsm_slaveconf_end;
  1294         return;
  1303         return;
  1295     }
  1304     }
  1296 
  1305 
  1297     if (fsm->change_state != ec_fsm_change_end) return;
  1306     if (fsm->change_state != ec_fsm_change_end) return;
  1298 
  1307 
  1299     // slave is now in SAVEOP
  1308     // slave is now in SAVEOP
  1300     if (fsm->slave->current_state == fsm->slave->requested_state) {
  1309     if (fsm->slave->current_state == fsm->slave->requested_state) {
  1301         fsm->slave_state = ec_fsm_slave_end;
  1310         fsm->slave_state = ec_fsm_slaveconf_end; // successful
  1302         return;
  1311         return;
  1303     }
  1312     }
  1304 
  1313 
  1305     // set state to OP
  1314     // set state to OP
  1306     fsm->slave_state = ec_fsm_slave_op2;
  1315     fsm->slave_state = ec_fsm_slaveconf_op;
  1307     fsm->change_new = EC_SLAVE_STATE_OP;
  1316     fsm->change_new = EC_SLAVE_STATE_OP;
  1308     fsm->change_state = ec_fsm_change_start;
  1317     fsm->change_state = ec_fsm_change_start;
  1309     fsm->change_state(fsm); // execute immediately
  1318     fsm->change_state(fsm); // execute immediately
  1310 }
  1319 }
  1311 
  1320 
  1312 /*****************************************************************************/
  1321 /*****************************************************************************/
  1313 
  1322 
  1314 /**
  1323 /**
  1315    Slave state: OP2
  1324    Slave state: OP
  1316    Executes the change state machine, until the OP state is set.
  1325 */
  1317 */
  1326 
  1318 
  1327 void ec_fsm_slaveconf_op(ec_fsm_t *fsm /**< finite state machine */)
  1319 void ec_fsm_slave_op2(ec_fsm_t *fsm /**< finite state machine */)
       
  1320 {
  1328 {
  1321     fsm->change_state(fsm); // execute state change state machine
  1329     fsm->change_state(fsm); // execute state change state machine
  1322 
  1330 
  1323     if (fsm->change_state == ec_fsm_change_error) {
  1331     if (fsm->change_state == ec_fsm_change_error) {
  1324         fsm->slave_state = ec_fsm_slave_end;
  1332         fsm->slave->error_flag = 1;
       
  1333         fsm->slave_state = ec_fsm_slaveconf_end;
  1325         return;
  1334         return;
  1326     }
  1335     }
  1327 
  1336 
  1328     if (fsm->change_state != ec_fsm_change_end) return;
  1337     if (fsm->change_state != ec_fsm_change_end) return;
  1329 
  1338 
  1330     // slave is now in OP
  1339     // slave is now in OP
  1331     fsm->slave_state = ec_fsm_slave_end;
  1340     fsm->slave_state = ec_fsm_slaveconf_end; // successful
  1332 }
  1341 }
  1333 
  1342 
  1334 /*****************************************************************************/
  1343 /*****************************************************************************/
  1335 
  1344 
  1336 /**
  1345 /**
  1337    Slave state: END.
  1346    Slave state: END.
  1338    End state of the slave state machine.
  1347    End state of the slave state machine.
  1339 */
  1348 */
  1340 
  1349 
  1341 void ec_fsm_slave_end(ec_fsm_t *fsm /**< finite state machine */)
  1350 void ec_fsm_slaveconf_end(ec_fsm_t *fsm /**< finite state machine */)
  1342 {
  1351 {
  1343 }
  1352 }
  1344 
  1353 
  1345 /******************************************************************************
  1354 /******************************************************************************
  1346  *  SII state machine
  1355  *  SII sub state machine
  1347  *****************************************************************************/
  1356  *****************************************************************************/
  1348 
  1357 
  1349 /**
  1358 /**
  1350    SII state: START_READING.
  1359    SII state: START_READING.
  1351    Starts reading the slave information interface.
  1360    Starts reading the slave information interface.
  1352 */
  1361 */
  1353 
  1362 
  1354 void ec_fsm_sii_start_reading(ec_fsm_t *fsm /**< finite state machine */)
  1363 void ec_fsm_sii_start_reading(ec_fsm_t *fsm /**< finite state machine */)
  1355 {
  1364 {
  1356     ec_command_t *command = &fsm->command;
  1365     ec_datagram_t *datagram = &fsm->datagram;
  1357 
  1366 
  1358     // initiate read operation
  1367     // initiate read operation
  1359     if (fsm->sii_mode) {
  1368     if (fsm->sii_mode) {
  1360         ec_command_npwr(command, fsm->slave->station_address, 0x502, 4);
  1369         ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 4);
  1361     }
  1370     }
  1362     else {
  1371     else {
  1363         ec_command_apwr(command, fsm->slave->ring_position, 0x502, 4);
  1372         ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x502, 4);
  1364     }
  1373     }
  1365 
  1374 
  1366     EC_WRITE_U8 (command->data,     0x00); // read-only access
  1375     EC_WRITE_U8 (datagram->data,     0x00); // read-only access
  1367     EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
  1376     EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation
  1368     EC_WRITE_U16(command->data + 2, fsm->sii_offset);
  1377     EC_WRITE_U16(datagram->data + 2, fsm->sii_offset);
  1369     ec_master_queue_command(fsm->master, command);
  1378     ec_master_queue_datagram(fsm->master, datagram);
  1370     fsm->sii_state = ec_fsm_sii_read_check;
  1379     fsm->sii_state = ec_fsm_sii_read_check;
  1371 }
  1380 }
  1372 
  1381 
  1373 /*****************************************************************************/
  1382 /*****************************************************************************/
  1374 
  1383 
  1375 /**
  1384 /**
  1376    SII state: READ_CHECK.
  1385    SII state: READ_CHECK.
  1377    Checks, if the SII-read-command has been sent and issues a fetch command.
  1386    Checks, if the SII-read-datagram has been sent and issues a fetch datagram.
  1378 */
  1387 */
  1379 
  1388 
  1380 void ec_fsm_sii_read_check(ec_fsm_t *fsm /**< finite state machine */)
  1389 void ec_fsm_sii_read_check(ec_fsm_t *fsm /**< finite state machine */)
  1381 {
  1390 {
  1382     ec_command_t *command = &fsm->command;
  1391     ec_datagram_t *datagram = &fsm->datagram;
  1383 
  1392 
  1384     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
  1393     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1385         EC_ERR("SII: Reception of read command failed.\n");
  1394         EC_ERR("SII: Reception of read datagram failed.\n");
  1386         fsm->sii_state = ec_fsm_sii_error;
  1395         fsm->sii_state = ec_fsm_sii_error;
  1387         return;
  1396         return;
  1388     }
  1397     }
  1389 
  1398 
  1390     fsm->sii_start = get_cycles();
  1399     fsm->sii_start = get_cycles();
  1391 
  1400 
  1392     // issue check/fetch command
  1401     // issue check/fetch datagram
  1393     if (fsm->sii_mode) {
  1402     if (fsm->sii_mode) {
  1394         ec_command_nprd(command, fsm->slave->station_address, 0x502, 10);
  1403         ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10);
  1395     }
  1404     }
  1396     else {
  1405     else {
  1397         ec_command_aprd(command, fsm->slave->ring_position, 0x502, 10);
  1406         ec_datagram_aprd(datagram, fsm->slave->ring_position, 0x502, 10);
  1398     }
  1407     }
  1399 
  1408 
  1400     ec_master_queue_command(fsm->master, command);
  1409     ec_master_queue_datagram(fsm->master, datagram);
  1401     fsm->sii_state = ec_fsm_sii_read_fetch;
  1410     fsm->sii_state = ec_fsm_sii_read_fetch;
  1402 }
  1411 }
  1403 
  1412 
  1404 /*****************************************************************************/
  1413 /*****************************************************************************/
  1405 
  1414 
  1406 /**
  1415 /**
  1407    SII state: READ_FETCH.
  1416    SII state: READ_FETCH.
  1408    Fetches the result of an SII-read command.
  1417    Fetches the result of an SII-read datagram.
  1409 */
  1418 */
  1410 
  1419 
  1411 void ec_fsm_sii_read_fetch(ec_fsm_t *fsm /**< finite state machine */)
  1420 void ec_fsm_sii_read_fetch(ec_fsm_t *fsm /**< finite state machine */)
  1412 {
  1421 {
  1413     ec_command_t *command = &fsm->command;
  1422     ec_datagram_t *datagram = &fsm->datagram;
  1414 
  1423 
  1415     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
  1424     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1416         EC_ERR("SII: Reception of check/fetch command failed.\n");
  1425         EC_ERR("SII: Reception of check/fetch datagram failed.\n");
  1417         fsm->sii_state = ec_fsm_sii_error;
  1426         fsm->sii_state = ec_fsm_sii_error;
  1418         return;
  1427         return;
  1419     }
  1428     }
  1420 
  1429 
  1421     // check "busy bit"
  1430     // check "busy bit"
  1422     if (EC_READ_U8(command->data + 1) & 0x81) {
  1431     if (EC_READ_U8(datagram->data + 1) & 0x81) {
  1423         // still busy... timeout?
  1432         // still busy... timeout?
  1424         if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
  1433         if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
  1425             EC_ERR("SII: Timeout.\n");
  1434             EC_ERR("SII: Timeout.\n");
  1426             fsm->sii_state = ec_fsm_sii_error;
  1435             fsm->sii_state = ec_fsm_sii_error;
  1427 #if 0
  1436 #if 0
  1428             EC_DBG("SII busy: %02X %02X %02X %02X\n",
  1437             EC_DBG("SII busy: %02X %02X %02X %02X\n",
  1429                    EC_READ_U8(command->data + 0),
  1438                    EC_READ_U8(datagram->data + 0),
  1430                    EC_READ_U8(command->data + 1),
  1439                    EC_READ_U8(datagram->data + 1),
  1431                    EC_READ_U8(command->data + 2),
  1440                    EC_READ_U8(datagram->data + 2),
  1432                    EC_READ_U8(command->data + 3));
  1441                    EC_READ_U8(datagram->data + 3));
  1433 #endif
  1442 #endif
  1434         }
  1443         }
  1435 
  1444 
  1436         // issue check/fetch command again
  1445         // issue check/fetch datagram again
  1437         if (fsm->sii_mode) {
  1446         if (fsm->sii_mode) {
  1438             ec_command_nprd(command, fsm->slave->station_address, 0x502, 10);
  1447             ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10);
  1439         }
  1448         }
  1440         else {
  1449         else {
  1441             ec_command_aprd(command, fsm->slave->ring_position, 0x502, 10);
  1450             ec_datagram_aprd(datagram, fsm->slave->ring_position, 0x502, 10);
  1442         }
  1451         }
  1443         ec_master_queue_command(fsm->master, command);
  1452         ec_master_queue_datagram(fsm->master, datagram);
  1444         return;
  1453         return;
  1445     }
  1454     }
  1446 
  1455 
  1447 #if 0
  1456 #if 0
  1448     EC_DBG("SII rec: %02X %02X %02X %02X - %02X %02X %02X %02X\n",
  1457     EC_DBG("SII rec: %02X %02X %02X %02X - %02X %02X %02X %02X\n",
  1449            EC_READ_U8(command->data + 0), EC_READ_U8(command->data + 1),
  1458            EC_READ_U8(datagram->data + 0), EC_READ_U8(datagram->data + 1),
  1450            EC_READ_U8(command->data + 2), EC_READ_U8(command->data + 3),
  1459            EC_READ_U8(datagram->data + 2), EC_READ_U8(datagram->data + 3),
  1451            EC_READ_U8(command->data + 6), EC_READ_U8(command->data + 7),
  1460            EC_READ_U8(datagram->data + 6), EC_READ_U8(datagram->data + 7),
  1452            EC_READ_U8(command->data + 8), EC_READ_U8(command->data + 9));
  1461            EC_READ_U8(datagram->data + 8), EC_READ_U8(datagram->data + 9));
  1453 #endif
  1462 #endif
  1454 
  1463 
  1455     // SII value received.
  1464     // SII value received.
  1456     memcpy(fsm->sii_value, command->data + 6, 4);
  1465     memcpy(fsm->sii_value, datagram->data + 6, 4);
  1457     fsm->sii_state = ec_fsm_sii_end;
  1466     fsm->sii_state = ec_fsm_sii_end;
  1458 }
  1467 }
  1459 
  1468 
  1460 /*****************************************************************************/
  1469 /*****************************************************************************/
  1461 
  1470 
  1464    Starts reading the slave information interface.
  1473    Starts reading the slave information interface.
  1465 */
  1474 */
  1466 
  1475 
  1467 void ec_fsm_sii_start_writing(ec_fsm_t *fsm /**< finite state machine */)
  1476 void ec_fsm_sii_start_writing(ec_fsm_t *fsm /**< finite state machine */)
  1468 {
  1477 {
  1469     ec_command_t *command = &fsm->command;
  1478     ec_datagram_t *datagram = &fsm->datagram;
  1470 
  1479 
  1471     // initiate write operation
  1480     // initiate write operation
  1472     ec_command_npwr(command, fsm->slave->station_address, 0x502, 8);
  1481     ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 8);
  1473     EC_WRITE_U8 (command->data,     0x01); // enable write access
  1482     EC_WRITE_U8 (datagram->data,     0x01); // enable write access
  1474     EC_WRITE_U8 (command->data + 1, 0x02); // request write operation
  1483     EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation
  1475     EC_WRITE_U32(command->data + 2, fsm->sii_offset);
  1484     EC_WRITE_U32(datagram->data + 2, fsm->sii_offset);
  1476     memcpy(command->data + 6, fsm->sii_value, 2);
  1485     memcpy(datagram->data + 6, fsm->sii_value, 2);
  1477     ec_master_queue_command(fsm->master, command);
  1486     ec_master_queue_datagram(fsm->master, datagram);
  1478     fsm->sii_state = ec_fsm_sii_write_check;
  1487     fsm->sii_state = ec_fsm_sii_write_check;
  1479 }
  1488 }
  1480 
  1489 
  1481 /*****************************************************************************/
  1490 /*****************************************************************************/
  1482 
  1491 
  1484    SII state: WRITE_CHECK.
  1493    SII state: WRITE_CHECK.
  1485 */
  1494 */
  1486 
  1495 
  1487 void ec_fsm_sii_write_check(ec_fsm_t *fsm /**< finite state machine */)
  1496 void ec_fsm_sii_write_check(ec_fsm_t *fsm /**< finite state machine */)
  1488 {
  1497 {
  1489     ec_command_t *command = &fsm->command;
  1498     ec_datagram_t *datagram = &fsm->datagram;
  1490 
  1499 
  1491     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
  1500     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1492         EC_ERR("SII: Reception of write command failed.\n");
  1501         EC_ERR("SII: Reception of write datagram failed.\n");
  1493         fsm->sii_state = ec_fsm_sii_error;
  1502         fsm->sii_state = ec_fsm_sii_error;
  1494         return;
  1503         return;
  1495     }
  1504     }
  1496 
  1505 
  1497     fsm->sii_start = get_cycles();
  1506     fsm->sii_start = get_cycles();
  1498 
  1507 
  1499     // issue check/fetch command
  1508     // issue check/fetch datagram
  1500     ec_command_nprd(command, fsm->slave->station_address, 0x502, 2);
  1509     ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 2);
  1501     ec_master_queue_command(fsm->master, command);
  1510     ec_master_queue_datagram(fsm->master, datagram);
  1502     fsm->sii_state = ec_fsm_sii_write_check2;
  1511     fsm->sii_state = ec_fsm_sii_write_check2;
  1503 }
  1512 }
  1504 
  1513 
  1505 /*****************************************************************************/
  1514 /*****************************************************************************/
  1506 
  1515 
  1508    SII state: WRITE_CHECK2.
  1517    SII state: WRITE_CHECK2.
  1509 */
  1518 */
  1510 
  1519 
  1511 void ec_fsm_sii_write_check2(ec_fsm_t *fsm /**< finite state machine */)
  1520 void ec_fsm_sii_write_check2(ec_fsm_t *fsm /**< finite state machine */)
  1512 {
  1521 {
  1513     ec_command_t *command = &fsm->command;
  1522     ec_datagram_t *datagram = &fsm->datagram;
  1514 
  1523 
  1515     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
  1524     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1516         EC_ERR("SII: Reception of write check command failed.\n");
  1525         EC_ERR("SII: Reception of write check datagram failed.\n");
  1517         fsm->sii_state = ec_fsm_sii_error;
  1526         fsm->sii_state = ec_fsm_sii_error;
  1518         return;
  1527         return;
  1519     }
  1528     }
  1520 
  1529 
  1521     if (EC_READ_U8(command->data + 1) & 0x82) {
  1530     if (EC_READ_U8(datagram->data + 1) & 0x82) {
  1522         // still busy... timeout?
  1531         // still busy... timeout?
  1523         if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
  1532         if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
  1524             EC_ERR("SII: Write timeout.\n");
  1533             EC_ERR("SII: Write timeout.\n");
  1525             fsm->sii_state = ec_fsm_sii_error;
  1534             fsm->sii_state = ec_fsm_sii_error;
  1526         }
  1535         }
  1527 
  1536 
  1528         // issue check/fetch command again
  1537         // issue check/fetch datagram again
  1529         ec_master_queue_command(fsm->master, command);
  1538         ec_master_queue_datagram(fsm->master, datagram);
  1530     }
  1539     }
  1531     else if (EC_READ_U8(command->data + 1) & 0x40) {
  1540     else if (EC_READ_U8(datagram->data + 1) & 0x40) {
  1532         EC_ERR("SII: Write operation failed!\n");
  1541         EC_ERR("SII: Write operation failed!\n");
  1533         fsm->sii_state = ec_fsm_sii_error;
  1542         fsm->sii_state = ec_fsm_sii_error;
  1534     }
  1543     }
  1535     else { // success
  1544     else { // success
  1536         fsm->sii_state = ec_fsm_sii_end;
  1545         fsm->sii_state = ec_fsm_sii_end;
  1558 void ec_fsm_sii_error(ec_fsm_t *fsm /**< finite state machine */)
  1567 void ec_fsm_sii_error(ec_fsm_t *fsm /**< finite state machine */)
  1559 {
  1568 {
  1560 }
  1569 }
  1561 
  1570 
  1562 /******************************************************************************
  1571 /******************************************************************************
  1563  *  state change state machine
  1572  *  state change sub state machine
  1564  *****************************************************************************/
  1573  *****************************************************************************/
  1565 
  1574 
  1566 /**
  1575 /**
  1567    Change state: START.
  1576    Change state: START.
  1568 */
  1577 */
  1569 
  1578 
  1570 void ec_fsm_change_start(ec_fsm_t *fsm /**< finite state machine */)
  1579 void ec_fsm_change_start(ec_fsm_t *fsm /**< finite state machine */)
  1571 {
  1580 {
  1572     ec_command_t *command = &fsm->command;
  1581     ec_datagram_t *datagram = &fsm->datagram;
  1573     ec_slave_t *slave = fsm->slave;
  1582     ec_slave_t *slave = fsm->slave;
  1574 
  1583 
  1575     // write new state to slave
  1584     // write new state to slave
  1576     ec_command_npwr(command, slave->station_address, 0x0120, 2);
  1585     ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2);
  1577     EC_WRITE_U16(command->data, fsm->change_new);
  1586     EC_WRITE_U16(datagram->data, fsm->change_new);
  1578     ec_master_queue_command(fsm->master, command);
  1587     ec_master_queue_datagram(fsm->master, datagram);
  1579     fsm->change_state = ec_fsm_change_check;
  1588     fsm->change_state = ec_fsm_change_check;
  1580 }
  1589 }
  1581 
  1590 
  1582 /*****************************************************************************/
  1591 /*****************************************************************************/
  1583 
  1592 
  1585    Change state: CHECK.
  1594    Change state: CHECK.
  1586 */
  1595 */
  1587 
  1596 
  1588 void ec_fsm_change_check(ec_fsm_t *fsm /**< finite state machine */)
  1597 void ec_fsm_change_check(ec_fsm_t *fsm /**< finite state machine */)
  1589 {
  1598 {
  1590     ec_command_t *command = &fsm->command;
  1599     ec_datagram_t *datagram = &fsm->datagram;
  1591     ec_slave_t *slave = fsm->slave;
  1600     ec_slave_t *slave = fsm->slave;
  1592 
  1601 
  1593     if (command->state != EC_CMD_RECEIVED) {
  1602     if (datagram->state != EC_CMD_RECEIVED) {
  1594         EC_ERR("Failed to send state command to slave %i!\n",
  1603         fsm->change_state = ec_fsm_change_error;
       
  1604         EC_ERR("Failed to send state datagram to slave %i!\n",
  1595                fsm->slave->ring_position);
  1605                fsm->slave->ring_position);
  1596         slave->state_error = 1;
  1606         return;
       
  1607     }
       
  1608 
       
  1609     if (datagram->working_counter != 1) {
  1597         fsm->change_state = ec_fsm_change_error;
  1610         fsm->change_state = ec_fsm_change_error;
  1598         return;
       
  1599     }
       
  1600 
       
  1601     if (command->working_counter != 1) {
       
  1602         EC_ERR("Failed to set state 0x%02X on slave %i: Slave did not"
  1611         EC_ERR("Failed to set state 0x%02X on slave %i: Slave did not"
  1603                " respond.\n", fsm->change_new, fsm->slave->ring_position);
  1612                " respond.\n", fsm->change_new, fsm->slave->ring_position);
  1604         slave->state_error = 1;
  1613         return;
       
  1614     }
       
  1615 
       
  1616     fsm->change_start = get_cycles();
       
  1617 
       
  1618     // read AL status from slave
       
  1619     ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
       
  1620     ec_master_queue_datagram(fsm->master, datagram);
       
  1621     fsm->change_state = ec_fsm_change_status;
       
  1622 }
       
  1623 
       
  1624 /*****************************************************************************/
       
  1625 
       
  1626 /**
       
  1627    Change state: STATUS.
       
  1628 */
       
  1629 
       
  1630 void ec_fsm_change_status(ec_fsm_t *fsm /**< finite state machine */)
       
  1631 {
       
  1632     ec_datagram_t *datagram = &fsm->datagram;
       
  1633     ec_slave_t *slave = fsm->slave;
       
  1634 
       
  1635     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1605         fsm->change_state = ec_fsm_change_error;
  1636         fsm->change_state = ec_fsm_change_error;
  1606         return;
       
  1607     }
       
  1608 
       
  1609     fsm->change_start = get_cycles();
       
  1610 
       
  1611     // read AL status from slave
       
  1612     ec_command_nprd(command, slave->station_address, 0x0130, 2);
       
  1613     ec_master_queue_command(fsm->master, command);
       
  1614     fsm->change_state = ec_fsm_change_status;
       
  1615 }
       
  1616 
       
  1617 /*****************************************************************************/
       
  1618 
       
  1619 /**
       
  1620    Change state: STATUS.
       
  1621 */
       
  1622 
       
  1623 void ec_fsm_change_status(ec_fsm_t *fsm /**< finite state machine */)
       
  1624 {
       
  1625     ec_command_t *command = &fsm->command;
       
  1626     ec_slave_t *slave = fsm->slave;
       
  1627 
       
  1628     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1629         EC_ERR("Failed to check state 0x%02X on slave %i.\n",
  1637         EC_ERR("Failed to check state 0x%02X on slave %i.\n",
  1630                fsm->change_new, slave->ring_position);
  1638                fsm->change_new, slave->ring_position);
  1631         slave->state_error = 1;
  1639         return;
  1632         fsm->change_state = ec_fsm_change_error;
  1640     }
  1633         return;
  1641 
  1634     }
  1642     slave->current_state = EC_READ_U8(datagram->data);
  1635 
       
  1636     slave->current_state = EC_READ_U8(command->data);
       
  1637 
  1643 
  1638     if (slave->current_state == fsm->change_new) {
  1644     if (slave->current_state == fsm->change_new) {
  1639         // state has been set successfully
  1645         // state has been set successfully
  1640         fsm->change_state = ec_fsm_change_end;
  1646         fsm->change_state = ec_fsm_change_end;
  1641         return;
  1647         return;
  1646         fsm->change_new = slave->current_state & 0x0F;
  1652         fsm->change_new = slave->current_state & 0x0F;
  1647         EC_ERR("Failed to set state 0x%02X - Slave %i refused state change"
  1653         EC_ERR("Failed to set state 0x%02X - Slave %i refused state change"
  1648                " (code 0x%02X)!\n", fsm->change_new, slave->ring_position,
  1654                " (code 0x%02X)!\n", fsm->change_new, slave->ring_position,
  1649                slave->current_state);
  1655                slave->current_state);
  1650         // fetch AL status error code
  1656         // fetch AL status error code
  1651         ec_command_nprd(command, slave->station_address, 0x0134, 2);
  1657         ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2);
  1652         ec_master_queue_command(fsm->master, command);
  1658         ec_master_queue_datagram(fsm->master, datagram);
  1653         fsm->change_state = ec_fsm_change_code;
  1659         fsm->change_state = ec_fsm_change_code;
  1654         return;
  1660         return;
  1655     }
  1661     }
  1656 
  1662 
  1657     if (get_cycles() - fsm->change_start >= (cycles_t) 10 * cpu_khz) {
  1663     if (get_cycles() - fsm->change_start >= (cycles_t) 10 * cpu_khz) {
  1658         // timeout while checking
  1664         // timeout while checking
  1659         slave->state_error = 1;
       
  1660         fsm->change_state = ec_fsm_change_error;
  1665         fsm->change_state = ec_fsm_change_error;
  1661         EC_ERR("Timeout while setting state 0x%02X on slave %i.\n",
  1666         EC_ERR("Timeout while setting state 0x%02X on slave %i.\n",
  1662                fsm->change_new, slave->ring_position);
  1667                fsm->change_new, slave->ring_position);
  1663         return;
  1668         return;
  1664     }
  1669     }
  1665 
  1670 
  1666     // still old state: check again
  1671     // still old state: check again
  1667     ec_command_nprd(command, slave->station_address, 0x0130, 2);
  1672     ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
  1668     ec_master_queue_command(fsm->master, command);
  1673     ec_master_queue_datagram(fsm->master, datagram);
  1669 }
  1674 }
  1670 
  1675 
  1671 /*****************************************************************************/
  1676 /*****************************************************************************/
  1672 
  1677 
  1673 /**
  1678 /**
  1685     {0x0017, "Invalid sync manager configuration"},
  1690     {0x0017, "Invalid sync manager configuration"},
  1686     {0x0018, "No valid inputs available"},
  1691     {0x0018, "No valid inputs available"},
  1687     {0x0019, "No valid outputs"},
  1692     {0x0019, "No valid outputs"},
  1688     {0x001A, "Synchronisation error"},
  1693     {0x001A, "Synchronisation error"},
  1689     {0x001B, "Sync manager watchdog"},
  1694     {0x001B, "Sync manager watchdog"},
       
  1695     {0x001C, "Invalid sync manager types"},
       
  1696     {0x001D, "Invalid output configuration"},
       
  1697     {0x001E, "Invalid input configuration"},
       
  1698     {0x001F, "Invalid watchdog configuration"},
  1690     {0x0020, "Slave needs cold start"},
  1699     {0x0020, "Slave needs cold start"},
  1691     {0x0021, "Slave needs INIT"},
  1700     {0x0021, "Slave needs INIT"},
  1692     {0x0022, "Slave needs PREOP"},
  1701     {0x0022, "Slave needs PREOP"},
  1693     {0x0023, "Slave needs SAVEOP"},
  1702     {0x0023, "Slave needs SAVEOP"},
       
  1703     {0x0030, "Invalid DC SYNCH configuration"},
       
  1704     {0x0031, "Invalid DC latch configuration"},
       
  1705     {0x0032, "PLL error"},
       
  1706     {0x0033, "Invalid DC IO error"},
       
  1707     {0x0034, "Invalid DC timeout error"},
       
  1708     {0x0042, "MBOX EOE"},
       
  1709     {0x0043, "MBOX COE"},
       
  1710     {0x0044, "MBOX FOE"},
       
  1711     {0x0045, "MBOX SOE"},
       
  1712     {0x004F, "MBOX VOE"},
  1694     {}
  1713     {}
  1695 };
  1714 };
  1696 
  1715 
  1697 /*****************************************************************************/
  1716 /*****************************************************************************/
  1698 
  1717 
  1700    Change state: CODE.
  1719    Change state: CODE.
  1701 */
  1720 */
  1702 
  1721 
  1703 void ec_fsm_change_code(ec_fsm_t *fsm /**< finite state machine */)
  1722 void ec_fsm_change_code(ec_fsm_t *fsm /**< finite state machine */)
  1704 {
  1723 {
  1705     ec_command_t *command = &fsm->command;
  1724     ec_datagram_t *datagram = &fsm->datagram;
  1706     ec_slave_t *slave = fsm->slave;
  1725     ec_slave_t *slave = fsm->slave;
  1707     uint32_t code;
  1726     uint32_t code;
  1708     const ec_code_msg_t *al_msg;
  1727     const ec_code_msg_t *al_msg;
  1709 
  1728 
  1710     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
  1729     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1711         EC_ERR("Reception of AL status code command failed.\n");
       
  1712         slave->state_error = 1;
       
  1713         fsm->change_state = ec_fsm_change_error;
  1730         fsm->change_state = ec_fsm_change_error;
  1714         return;
  1731         EC_ERR("Reception of AL status code datagram failed.\n");
  1715     }
  1732         return;
  1716 
  1733     }
  1717     if ((code = EC_READ_U16(command->data))) {
  1734 
       
  1735     if ((code = EC_READ_U16(datagram->data))) {
  1718         for (al_msg = al_status_messages; al_msg->code; al_msg++) {
  1736         for (al_msg = al_status_messages; al_msg->code; al_msg++) {
  1719             if (al_msg->code != code) continue;
  1737             if (al_msg->code != code) continue;
  1720             EC_ERR("AL status message 0x%04X: \"%s\".\n",
  1738             EC_ERR("AL status message 0x%04X: \"%s\".\n",
  1721                    al_msg->code, al_msg->message);
  1739                    al_msg->code, al_msg->message);
  1722             break;
  1740             break;
  1724         if (!al_msg->code)
  1742         if (!al_msg->code)
  1725             EC_ERR("Unknown AL status code 0x%04X.\n", code);
  1743             EC_ERR("Unknown AL status code 0x%04X.\n", code);
  1726     }
  1744     }
  1727 
  1745 
  1728     // acknowledge "old" slave state
  1746     // acknowledge "old" slave state
  1729     ec_command_npwr(command, slave->station_address, 0x0120, 2);
  1747     ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2);
  1730     EC_WRITE_U16(command->data, slave->current_state);
  1748     EC_WRITE_U16(datagram->data, slave->current_state);
  1731     ec_master_queue_command(fsm->master, command);
  1749     ec_master_queue_datagram(fsm->master, datagram);
  1732     fsm->change_state = ec_fsm_change_ack;
  1750     fsm->change_state = ec_fsm_change_ack;
  1733 }
  1751 }
  1734 
  1752 
  1735 /*****************************************************************************/
  1753 /*****************************************************************************/
  1736 
  1754 
  1738    Change state: ACK.
  1756    Change state: ACK.
  1739 */
  1757 */
  1740 
  1758 
  1741 void ec_fsm_change_ack(ec_fsm_t *fsm /**< finite state machine */)
  1759 void ec_fsm_change_ack(ec_fsm_t *fsm /**< finite state machine */)
  1742 {
  1760 {
  1743     ec_command_t *command = &fsm->command;
  1761     ec_datagram_t *datagram = &fsm->datagram;
  1744     ec_slave_t *slave = fsm->slave;
  1762     ec_slave_t *slave = fsm->slave;
  1745 
  1763 
  1746     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
  1764     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1747         EC_ERR("Reception of state ack command failed.\n");
       
  1748         slave->state_error = 1;
       
  1749         fsm->change_state = ec_fsm_change_error;
  1765         fsm->change_state = ec_fsm_change_error;
  1750         return;
  1766         EC_ERR("Reception of state ack datagram failed.\n");
  1751     }
  1767         return;
       
  1768     }
       
  1769 
       
  1770     fsm->change_start = get_cycles();
  1752 
  1771 
  1753     // read new AL status
  1772     // read new AL status
  1754     ec_command_nprd(command, slave->station_address, 0x0130, 2);
  1773     ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
  1755     ec_master_queue_command(fsm->master, command);
  1774     ec_master_queue_datagram(fsm->master, datagram);
  1756     fsm->change_state = ec_fsm_change_ack2;
  1775     fsm->change_state = ec_fsm_change_check_ack;
  1757 }
  1776 }
  1758 
  1777 
  1759 /*****************************************************************************/
  1778 /*****************************************************************************/
  1760 
  1779 
  1761 /**
  1780 /**
  1762    Change state: ACK.
  1781    Change state: CHECK ACK.
  1763    Acknowledge 2.
  1782 */
  1764 */
  1783 
  1765 
  1784 void ec_fsm_change_check_ack(ec_fsm_t *fsm /**< finite state machine */)
  1766 void ec_fsm_change_ack2(ec_fsm_t *fsm /**< finite state machine */)
  1785 {
  1767 {
  1786     ec_datagram_t *datagram = &fsm->datagram;
  1768     ec_command_t *command = &fsm->command;
  1787     ec_slave_t *slave = fsm->slave;
  1769     ec_slave_t *slave = fsm->slave;
  1788     ec_slave_state_t ack_state;
  1770 
  1789 
  1771     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
  1790     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1772         EC_ERR("Reception of state ack check command failed.\n");
       
  1773         slave->state_error = 1;
       
  1774         fsm->change_state = ec_fsm_change_error;
  1791         fsm->change_state = ec_fsm_change_error;
  1775         return;
  1792         EC_ERR("Reception of state ack check datagram failed.\n");
  1776     }
  1793         return;
  1777 
  1794     }
  1778     slave->current_state = EC_READ_U8(command->data);
  1795 
  1779 
  1796     ack_state = EC_READ_U8(datagram->data);
  1780     if (slave->current_state == fsm->change_new) {
  1797 
       
  1798     if (ack_state == slave->current_state) {
       
  1799         fsm->change_state = ec_fsm_change_error;
  1781         EC_INFO("Acknowleged state 0x%02X on slave %i.\n",
  1800         EC_INFO("Acknowleged state 0x%02X on slave %i.\n",
  1782                 slave->current_state, slave->ring_position);
  1801                 slave->current_state, slave->ring_position);
  1783         slave->state_error = 1;
  1802         return;
       
  1803     }
       
  1804 
       
  1805     if (get_cycles() - fsm->change_start >= (cycles_t) 100 * cpu_khz) {
       
  1806         // timeout while checking
       
  1807         slave->current_state = EC_SLAVE_STATE_UNKNOWN;
  1784         fsm->change_state = ec_fsm_change_error;
  1808         fsm->change_state = ec_fsm_change_error;
  1785         return;
  1809         EC_ERR("Timeout while acknowleging state 0x%02X on slave %i.\n",
  1786     }
  1810                fsm->change_new, slave->ring_position);
  1787 
  1811         return;
  1788     EC_WARN("Failed to acknowledge state 0x%02X on slave %i"
  1812     }
  1789             " - Timeout!\n", fsm->change_new, slave->ring_position);
  1813 
  1790     slave->state_error = 1;
  1814     // reread new AL status
  1791     fsm->change_state = ec_fsm_change_error;
  1815     ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
       
  1816     ec_master_queue_datagram(fsm->master, datagram);
  1792 }
  1817 }
  1793 
  1818 
  1794 /*****************************************************************************/
  1819 /*****************************************************************************/
  1795 
  1820 
  1796 /**
  1821 /**