00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00039
00040
00041 #include "globals.h"
00042 #include "fsm.h"
00043 #include "master.h"
00044 #include "mailbox.h"
00045
00046
00047
00048 void ec_fsm_master_start(ec_fsm_t *);
00049 void ec_fsm_master_broadcast(ec_fsm_t *);
00050 void ec_fsm_master_read_states(ec_fsm_t *);
00051 void ec_fsm_master_acknowledge(ec_fsm_t *);
00052 void ec_fsm_master_validate_vendor(ec_fsm_t *);
00053 void ec_fsm_master_validate_product(ec_fsm_t *);
00054 void ec_fsm_master_rewrite_addresses(ec_fsm_t *);
00055 void ec_fsm_master_configure_slave(ec_fsm_t *);
00056 void ec_fsm_master_scan_slaves(ec_fsm_t *);
00057 void ec_fsm_master_write_eeprom(ec_fsm_t *);
00058 void ec_fsm_master_sdodict(ec_fsm_t *);
00059 void ec_fsm_master_sdo_request(ec_fsm_t *);
00060 void ec_fsm_master_end(ec_fsm_t *);
00061 void ec_fsm_master_error(ec_fsm_t *);
00062
00063 void ec_fsm_slavescan_start(ec_fsm_t *);
00064 void ec_fsm_slavescan_address(ec_fsm_t *);
00065 void ec_fsm_slavescan_state(ec_fsm_t *);
00066 void ec_fsm_slavescan_base(ec_fsm_t *);
00067 void ec_fsm_slavescan_datalink(ec_fsm_t *);
00068 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *);
00069 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *);
00070
00071 void ec_fsm_slaveconf_state_start(ec_fsm_t *);
00072 void ec_fsm_slaveconf_state_init(ec_fsm_t *);
00073 void ec_fsm_slaveconf_state_clear_fmmus(ec_fsm_t *);
00074 void ec_fsm_slaveconf_state_sync(ec_fsm_t *);
00075 void ec_fsm_slaveconf_state_preop(ec_fsm_t *);
00076 void ec_fsm_slaveconf_state_sync2(ec_fsm_t *);
00077 void ec_fsm_slaveconf_state_fmmu(ec_fsm_t *);
00078 void ec_fsm_slaveconf_state_sdoconf(ec_fsm_t *);
00079 void ec_fsm_slaveconf_state_saveop(ec_fsm_t *);
00080 void ec_fsm_slaveconf_state_op(ec_fsm_t *);
00081
00082 void ec_fsm_slaveconf_enter_sync(ec_fsm_t *);
00083 void ec_fsm_slaveconf_enter_preop(ec_fsm_t *);
00084 void ec_fsm_slaveconf_enter_sync2(ec_fsm_t *);
00085 void ec_fsm_slaveconf_enter_fmmu(ec_fsm_t *);
00086 void ec_fsm_slaveconf_enter_sdoconf(ec_fsm_t *);
00087 void ec_fsm_slaveconf_enter_saveop(ec_fsm_t *);
00088
00089 void ec_fsm_slave_state_end(ec_fsm_t *);
00090 void ec_fsm_slave_state_error(ec_fsm_t *);
00091
00092
00093
00098 int ec_fsm_init(ec_fsm_t *fsm,
00099 ec_master_t *master
00100 )
00101 {
00102 fsm->master = master;
00103 fsm->master_state = ec_fsm_master_start;
00104 fsm->master_slaves_responding = 0;
00105 fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN;
00106 fsm->master_validation = 0;
00107
00108 ec_datagram_init(&fsm->datagram);
00109 if (ec_datagram_prealloc(&fsm->datagram, EC_MAX_DATA_SIZE)) {
00110 EC_ERR("Failed to allocate FSM datagram.\n");
00111 return -1;
00112 }
00113
00114
00115 ec_fsm_sii_init(&fsm->fsm_sii, &fsm->datagram);
00116 ec_fsm_change_init(&fsm->fsm_change, &fsm->datagram);
00117 ec_fsm_coe_init(&fsm->fsm_coe, &fsm->datagram);
00118
00119 return 0;
00120 }
00121
00122
00123
00128 void ec_fsm_clear(ec_fsm_t *fsm )
00129 {
00130
00131 ec_fsm_sii_clear(&fsm->fsm_sii);
00132 ec_fsm_change_clear(&fsm->fsm_change);
00133 ec_fsm_coe_clear(&fsm->fsm_coe);
00134
00135 ec_datagram_clear(&fsm->datagram);
00136 }
00137
00138
00139
00145 int ec_fsm_exec(ec_fsm_t *fsm )
00146 {
00147 fsm->master_state(fsm);
00148
00149 return ec_fsm_running(fsm);
00150 }
00151
00152
00153
00158 int ec_fsm_running(ec_fsm_t *fsm )
00159 {
00160 return fsm->master_state != ec_fsm_master_end
00161 && fsm->master_state != ec_fsm_master_error;
00162 }
00163
00164
00165
00170 int ec_fsm_success(ec_fsm_t *fsm )
00171 {
00172 return fsm->master_state == ec_fsm_master_end;
00173 }
00174
00175
00176
00177
00178
00184 void ec_fsm_master_start(ec_fsm_t *fsm)
00185 {
00186 ec_datagram_brd(&fsm->datagram, 0x0130, 2);
00187 ec_master_queue_datagram(fsm->master, &fsm->datagram);
00188 fsm->master_state = ec_fsm_master_broadcast;
00189 }
00190
00191
00192
00198 void ec_fsm_master_broadcast(ec_fsm_t *fsm )
00199 {
00200 ec_datagram_t *datagram = &fsm->datagram;
00201 unsigned int topology_change, states_change, i;
00202 ec_slave_t *slave;
00203 ec_master_t *master = fsm->master;
00204
00205 if (datagram->state != EC_DATAGRAM_RECEIVED) {
00206 if (!master->device->link_state) {
00207 fsm->master_slaves_responding = 0;
00208 list_for_each_entry(slave, &master->slaves, list) {
00209 slave->online = 0;
00210 }
00211 }
00212 else {
00213 EC_ERR("Failed to receive broadcast datagram.\n");
00214 }
00215 fsm->master_state = ec_fsm_master_error;
00216 return;
00217 }
00218
00219 topology_change = (datagram->working_counter !=
00220 fsm->master_slaves_responding);
00221 states_change = (EC_READ_U8(datagram->data) != fsm->master_slave_states);
00222
00223 fsm->master_slave_states = EC_READ_U8(datagram->data);
00224 fsm->master_slaves_responding = datagram->working_counter;
00225
00226 if (topology_change) {
00227 EC_INFO("%i slave%s responding.\n",
00228 fsm->master_slaves_responding,
00229 fsm->master_slaves_responding == 1 ? "" : "s");
00230
00231 if (master->mode == EC_MASTER_MODE_OPERATION) {
00232 if (fsm->master_slaves_responding == master->slave_count) {
00233 fsm->master_validation = 1;
00234 }
00235 else {
00236 EC_WARN("Invalid slave count. Bus in tainted state.\n");
00237 }
00238 }
00239 }
00240
00241 if (states_change) {
00242 char states[EC_STATE_STRING_SIZE];
00243 ec_state_string(fsm->master_slave_states, states);
00244 EC_INFO("Slave states: %s.\n", states);
00245 }
00246
00247
00248 if (topology_change && master->mode == EC_MASTER_MODE_IDLE) {
00249
00250 ec_master_eoe_stop(master);
00251 ec_master_destroy_slaves(master);
00252
00253 master->slave_count = datagram->working_counter;
00254
00255 if (!master->slave_count) {
00256
00257 fsm->master_state = ec_fsm_master_end;
00258 return;
00259 }
00260
00261
00262 for (i = 0; i < master->slave_count; i++) {
00263 if (!(slave = (ec_slave_t *) kmalloc(sizeof(ec_slave_t),
00264 GFP_ATOMIC))) {
00265 EC_ERR("Failed to allocate slave %i!\n", i);
00266 ec_master_destroy_slaves(master);
00267 fsm->master_state = ec_fsm_master_error;
00268 return;
00269 }
00270
00271 if (ec_slave_init(slave, master, i, i + 1)) {
00272
00273 ec_master_destroy_slaves(master);
00274 fsm->master_state = ec_fsm_master_error;
00275 return;
00276 }
00277
00278 list_add_tail(&slave->list, &master->slaves);
00279 }
00280
00281 EC_INFO("Scanning bus.\n");
00282
00283
00284 fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
00285 fsm->slave_state = ec_fsm_slavescan_start;
00286 fsm->master_state = ec_fsm_master_scan_slaves;
00287 fsm->master_state(fsm);
00288 return;
00289 }
00290
00291
00292 fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
00293 ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address, 0x0130, 2);
00294 ec_master_queue_datagram(master, &fsm->datagram);
00295 fsm->master_state = ec_fsm_master_read_states;
00296 }
00297
00298
00299
00305 void ec_fsm_master_action_process_states(ec_fsm_t *fsm
00307 )
00308 {
00309 ec_master_t *master = fsm->master;
00310 ec_slave_t *slave;
00311 char old_state[EC_STATE_STRING_SIZE], new_state[EC_STATE_STRING_SIZE];
00312
00313
00314 list_for_each_entry(slave, &master->slaves, list) {
00315 if (slave->error_flag
00316 || !slave->online
00317 || slave->requested_state == EC_SLAVE_STATE_UNKNOWN
00318 || (slave->current_state == slave->requested_state
00319 && slave->configured)) continue;
00320
00321 if (master->debug_level) {
00322 ec_state_string(slave->current_state, old_state);
00323 if (slave->current_state != slave->requested_state) {
00324 ec_state_string(slave->requested_state, new_state);
00325 EC_DBG("Changing state of slave %i (%s -> %s).\n",
00326 slave->ring_position, old_state, new_state);
00327 }
00328 else if (!slave->configured) {
00329 EC_DBG("Reconfiguring slave %i (%s).\n",
00330 slave->ring_position, old_state);
00331 }
00332 }
00333
00334 fsm->master_state = ec_fsm_master_configure_slave;
00335 fsm->slave = slave;
00336 fsm->slave_state = ec_fsm_slaveconf_state_start;
00337 fsm->slave_state(fsm);
00338 return;
00339 }
00340
00341
00342 ec_master_eoe_start(master);
00343
00344 if (master->mode == EC_MASTER_MODE_IDLE) {
00345
00346
00347 if (master->sdo_seq_master != master->sdo_seq_user) {
00348 if (master->debug_level)
00349 EC_DBG("Processing SDO request...\n");
00350 slave = master->sdo_request->sdo->slave;
00351 if (slave->current_state == EC_SLAVE_STATE_INIT
00352 || !slave->online) {
00353 EC_ERR("Failed to process SDO request, slave %i not ready.\n",
00354 slave->ring_position);
00355 master->sdo_request->return_code = -1;
00356 master->sdo_seq_master++;
00357 }
00358 else {
00359
00360 fsm->slave = slave;
00361 fsm->master_state = ec_fsm_master_sdo_request;
00362 fsm->sdo_request = master->sdo_request;
00363 ec_fsm_coe_upload(&fsm->fsm_coe, slave, fsm->sdo_request);
00364 ec_fsm_coe_exec(&fsm->fsm_coe);
00365 return;
00366 }
00367 }
00368
00369
00370 list_for_each_entry(slave, &master->slaves, list) {
00371 if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)
00372 || slave->sdo_dictionary_fetched
00373 || slave->current_state == EC_SLAVE_STATE_INIT
00374 || jiffies - slave->jiffies_preop < EC_WAIT_SDO_DICT * HZ
00375 || !slave->online
00376 || slave->error_flag) continue;
00377
00378 if (master->debug_level) {
00379 EC_DBG("Fetching SDO dictionary from slave %i.\n",
00380 slave->ring_position);
00381 }
00382
00383 slave->sdo_dictionary_fetched = 1;
00384
00385
00386 fsm->slave = slave;
00387 fsm->master_state = ec_fsm_master_sdodict;
00388 ec_fsm_coe_dictionary(&fsm->fsm_coe, slave);
00389 ec_fsm_coe_exec(&fsm->fsm_coe);
00390 return;
00391 }
00392
00393
00394 list_for_each_entry(slave, &master->slaves, list) {
00395 if (!slave->new_eeprom_data) continue;
00396
00397 if (!slave->online || slave->error_flag) {
00398 kfree(slave->new_eeprom_data);
00399 slave->new_eeprom_data = NULL;
00400 EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
00401 slave->ring_position);
00402 continue;
00403 }
00404
00405
00406 EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
00407 fsm->slave = slave;
00408 fsm->sii_offset = 0x0000;
00409 ec_fsm_sii_write(&fsm->fsm_sii, slave, fsm->sii_offset,
00410 slave->new_eeprom_data, EC_FSM_SII_NODE);
00411 fsm->master_state = ec_fsm_master_write_eeprom;
00412 fsm->master_state(fsm);
00413 return;
00414 }
00415 }
00416
00417 fsm->master_state = ec_fsm_master_end;
00418 }
00419
00420
00421
00426 void ec_fsm_master_action_next_slave_state(ec_fsm_t *fsm)
00428 {
00429 ec_master_t *master = fsm->master;
00430 ec_slave_t *slave = fsm->slave;
00431
00432
00433 if (slave->list.next != &master->slaves) {
00434
00435 fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
00436 ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address,
00437 0x0130, 2);
00438 ec_master_queue_datagram(master, &fsm->datagram);
00439 fsm->master_state = ec_fsm_master_read_states;
00440 return;
00441 }
00442
00443
00444
00445
00446 if (fsm->master_validation) {
00447 fsm->master_validation = 0;
00448 list_for_each_entry(slave, &master->slaves, list) {
00449 if (slave->online) continue;
00450
00451
00452 EC_INFO("Validating bus.\n");
00453 fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
00454 fsm->master_state = ec_fsm_master_validate_vendor;
00455 ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x0008, EC_FSM_SII_POSITION);
00456 ec_fsm_sii_exec(&fsm->fsm_sii);
00457 return;
00458 }
00459 }
00460
00461 ec_fsm_master_action_process_states(fsm);
00462 }
00463
00464
00465
00471 void ec_fsm_master_read_states(ec_fsm_t *fsm )
00472 {
00473 ec_slave_t *slave = fsm->slave;
00474 ec_datagram_t *datagram = &fsm->datagram;
00475 uint8_t new_state;
00476
00477 if (datagram->state != EC_DATAGRAM_RECEIVED) {
00478 EC_ERR("Failed to receive AL state datagram for slave %i!\n",
00479 slave->ring_position);
00480 fsm->master_state = ec_fsm_master_error;
00481 return;
00482 }
00483
00484
00485 if (datagram->working_counter != 1) {
00486 if (slave->online) {
00487 slave->online = 0;
00488 if (slave->master->debug_level)
00489 EC_DBG("Slave %i: offline.\n", slave->ring_position);
00490 }
00491 ec_fsm_master_action_next_slave_state(fsm);
00492 return;
00493 }
00494
00495
00496 new_state = EC_READ_U8(datagram->data);
00497 if (!slave->online) {
00498 slave->online = 1;
00499 slave->error_flag = 0;
00500 slave->current_state = new_state;
00501 if (slave->master->debug_level) {
00502 char cur_state[EC_STATE_STRING_SIZE];
00503 ec_state_string(slave->current_state, cur_state);
00504 EC_DBG("Slave %i: online (%s).\n",
00505 slave->ring_position, cur_state);
00506 }
00507 }
00508 else if (new_state != slave->current_state) {
00509 if (slave->master->debug_level) {
00510 char old_state[EC_STATE_STRING_SIZE],
00511 cur_state[EC_STATE_STRING_SIZE];
00512 ec_state_string(slave->current_state, old_state);
00513 ec_state_string(new_state, cur_state);
00514 EC_DBG("Slave %i: %s -> %s.\n",
00515 slave->ring_position, old_state, cur_state);
00516 }
00517 slave->current_state = new_state;
00518 }
00519
00520
00521 if (slave->current_state & EC_SLAVE_STATE_ACK_ERR && !slave->error_flag) {
00522 ec_fsm_change_ack(&fsm->fsm_change, slave);
00523 ec_fsm_change_exec(&fsm->fsm_change);
00524 fsm->master_state = ec_fsm_master_acknowledge;
00525 return;
00526 }
00527
00528 ec_fsm_master_action_next_slave_state(fsm);
00529 }
00530
00531
00532
00537 void ec_fsm_master_acknowledge(ec_fsm_t *fsm )
00538 {
00539 ec_slave_t *slave = fsm->slave;
00540
00541 if (ec_fsm_change_exec(&fsm->fsm_change)) return;
00542
00543 if (!ec_fsm_change_success(&fsm->fsm_change)) {
00544 fsm->slave->error_flag = 1;
00545 EC_ERR("Failed to acknowledge state change on slave %i.\n",
00546 slave->ring_position);
00547 fsm->master_state = ec_fsm_master_error;
00548 return;
00549 }
00550
00551 ec_fsm_master_action_next_slave_state(fsm);
00552 }
00553
00554
00555
00561 void ec_fsm_master_validate_vendor(ec_fsm_t *fsm )
00562 {
00563 ec_slave_t *slave = fsm->slave;
00564
00565 if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
00566
00567 if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
00568 fsm->slave->error_flag = 1;
00569 EC_ERR("Failed to validate vendor ID of slave %i.\n",
00570 slave->ring_position);
00571 fsm->master_state = ec_fsm_master_error;
00572 return;
00573 }
00574
00575 if (EC_READ_U32(fsm->fsm_sii.value) != slave->sii_vendor_id) {
00576 EC_ERR("Slave %i has an invalid vendor ID!\n", slave->ring_position);
00577 fsm->master_state = ec_fsm_master_error;
00578 return;
00579 }
00580
00581
00582 fsm->master_state = ec_fsm_master_validate_product;
00583 ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x000A, EC_FSM_SII_POSITION);
00584 ec_fsm_sii_exec(&fsm->fsm_sii);
00585 }
00586
00587
00588
00595 void ec_fsm_master_action_addresses(ec_fsm_t *fsm )
00596 {
00597 ec_datagram_t *datagram = &fsm->datagram;
00598
00599 while (fsm->slave->online) {
00600 if (fsm->slave->list.next == &fsm->master->slaves) {
00601 fsm->master_state = ec_fsm_master_start;
00602 fsm->master_state(fsm);
00603 return;
00604 }
00605
00606 fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
00607 }
00608
00609 if (fsm->master->debug_level)
00610 EC_DBG("Reinitializing slave %i.\n", fsm->slave->ring_position);
00611
00612
00613 ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2);
00614 EC_WRITE_U16(datagram->data, fsm->slave->station_address);
00615 ec_master_queue_datagram(fsm->master, datagram);
00616 fsm->master_state = ec_fsm_master_rewrite_addresses;
00617 }
00618
00619
00620
00626 void ec_fsm_master_validate_product(ec_fsm_t *fsm )
00627 {
00628 ec_slave_t *slave = fsm->slave;
00629
00630 if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
00631
00632 if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
00633 fsm->slave->error_flag = 1;
00634 EC_ERR("Failed to validate product code of slave %i.\n",
00635 slave->ring_position);
00636 fsm->master_state = ec_fsm_master_error;
00637 return;
00638 }
00639
00640 if (EC_READ_U32(fsm->fsm_sii.value) != slave->sii_product_code) {
00641 EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
00642 EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
00643 EC_READ_U32(fsm->fsm_sii.value));
00644 fsm->master_state = ec_fsm_master_error;
00645 return;
00646 }
00647
00648
00649 if (slave->list.next == &fsm->master->slaves) {
00650 fsm->slave = list_entry(fsm->master->slaves.next, ec_slave_t, list);
00651
00652 ec_fsm_master_action_addresses(fsm);
00653 return;
00654 }
00655
00656
00657 fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
00658 fsm->master_state = ec_fsm_master_validate_vendor;
00659 ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x0008, EC_FSM_SII_POSITION);
00660 ec_fsm_sii_exec(&fsm->fsm_sii);
00661 }
00662
00663
00664
00670 void ec_fsm_master_rewrite_addresses(ec_fsm_t *fsm
00672 )
00673 {
00674 ec_slave_t *slave = fsm->slave;
00675 ec_datagram_t *datagram = &fsm->datagram;
00676
00677 if (datagram->state != EC_DATAGRAM_RECEIVED
00678 || datagram->working_counter != 1) {
00679 EC_ERR("Failed to write station address on slave %i.\n",
00680 slave->ring_position);
00681 }
00682
00683 if (fsm->slave->list.next == &fsm->master->slaves) {
00684 fsm->master_state = ec_fsm_master_start;
00685 fsm->master_state(fsm);
00686 return;
00687 }
00688
00689
00690 fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
00691
00692 ec_fsm_master_action_addresses(fsm);
00693 }
00694
00695
00696
00702 void ec_fsm_master_scan_slaves(ec_fsm_t *fsm )
00703 {
00704 ec_master_t *master = fsm->master;
00705 ec_slave_t *slave = fsm->slave;
00706
00707 fsm->slave_state(fsm);
00708
00709 if (fsm->slave_state != ec_fsm_slave_state_end
00710 && fsm->slave_state != ec_fsm_slave_state_error) return;
00711
00712
00713 if (slave->list.next != &master->slaves) {
00714 fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
00715 fsm->slave_state = ec_fsm_slavescan_start;
00716 fsm->slave_state(fsm);
00717 return;
00718 }
00719
00720 EC_INFO("Bus scanning completed.\n");
00721
00722 ec_master_calc_addressing(master);
00723
00724
00725
00726 list_for_each_entry(slave, &master->slaves, list) {
00727 ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
00728 }
00729
00730 fsm->master_state = ec_fsm_master_end;
00731 }
00732
00733
00734
00740 void ec_fsm_master_configure_slave(ec_fsm_t *fsm
00742 )
00743 {
00744 fsm->slave_state(fsm);
00745
00746 if (fsm->slave_state != ec_fsm_slave_state_end
00747 && fsm->slave_state != ec_fsm_slave_state_error) return;
00748
00749 ec_fsm_master_action_process_states(fsm);
00750 }
00751
00752
00753
00758 void ec_fsm_master_write_eeprom(ec_fsm_t *fsm )
00759 {
00760 ec_slave_t *slave = fsm->slave;
00761
00762 if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
00763
00764 if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
00765 fsm->slave->error_flag = 1;
00766 EC_ERR("Failed to write EEPROM contents to slave %i.\n",
00767 slave->ring_position);
00768 kfree(slave->new_eeprom_data);
00769 slave->new_eeprom_data = NULL;
00770 fsm->master_state = ec_fsm_master_error;
00771 return;
00772 }
00773
00774 fsm->sii_offset++;
00775 if (fsm->sii_offset < slave->new_eeprom_size) {
00776 ec_fsm_sii_write(&fsm->fsm_sii, slave, fsm->sii_offset,
00777 slave->new_eeprom_data + fsm->sii_offset,
00778 EC_FSM_SII_NODE);
00779 ec_fsm_sii_exec(&fsm->fsm_sii);
00780 return;
00781 }
00782
00783
00784 EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position);
00785 kfree(slave->new_eeprom_data);
00786 slave->new_eeprom_data = NULL;
00787
00788
00789
00790
00791 fsm->master_state = ec_fsm_master_start;
00792 fsm->master_state(fsm);
00793 }
00794
00795
00796
00801 void ec_fsm_master_sdodict(ec_fsm_t *fsm )
00802 {
00803 ec_slave_t *slave = fsm->slave;
00804 ec_master_t *master = fsm->master;
00805
00806 if (ec_fsm_coe_exec(&fsm->fsm_coe)) return;
00807
00808 if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
00809 fsm->master_state = ec_fsm_master_error;
00810 return;
00811 }
00812
00813
00814
00815 if (master->debug_level) {
00816 unsigned int sdo_count, entry_count;
00817 ec_slave_sdo_dict_info(slave, &sdo_count, &entry_count);
00818 EC_DBG("Fetched %i SDOs and %i entries from slave %i.\n",
00819 sdo_count, entry_count, slave->ring_position);
00820 }
00821
00822
00823 fsm->master_state = ec_fsm_master_start;
00824 fsm->master_state(fsm);
00825 }
00826
00827
00828
00833 void ec_fsm_master_sdo_request(ec_fsm_t *fsm )
00834 {
00835 ec_master_t *master = fsm->master;
00836 ec_sdo_request_t *request = fsm->sdo_request;
00837
00838 if (ec_fsm_coe_exec(&fsm->fsm_coe)) return;
00839
00840 if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
00841 request->return_code = -1;
00842 master->sdo_seq_master++;
00843 fsm->master_state = ec_fsm_master_error;
00844 return;
00845 }
00846
00847
00848
00849 request->return_code = 1;
00850 master->sdo_seq_master++;
00851
00852
00853 fsm->master_state = ec_fsm_master_start;
00854 fsm->master_state(fsm);
00855 }
00856
00857
00858
00863 void ec_fsm_master_error(ec_fsm_t *fsm )
00864 {
00865 fsm->master_state = ec_fsm_master_start;
00866 }
00867
00868
00869
00874 void ec_fsm_master_end(ec_fsm_t *fsm )
00875 {
00876 fsm->master_state = ec_fsm_master_start;
00877 }
00878
00879
00880
00881
00882
00889 void ec_fsm_slavescan_start(ec_fsm_t *fsm )
00890 {
00891 ec_datagram_t *datagram = &fsm->datagram;
00892
00893
00894 ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2);
00895 EC_WRITE_U16(datagram->data, fsm->slave->station_address);
00896 ec_master_queue_datagram(fsm->master, datagram);
00897 fsm->slave_state = ec_fsm_slavescan_address;
00898 }
00899
00900
00901
00906 void ec_fsm_slavescan_address(ec_fsm_t *fsm )
00907 {
00908 ec_datagram_t *datagram = &fsm->datagram;
00909
00910 if (datagram->state != EC_DATAGRAM_RECEIVED
00911 || datagram->working_counter != 1) {
00912 fsm->slave->error_flag = 1;
00913 fsm->slave_state = ec_fsm_slave_state_error;
00914 EC_ERR("Failed to write station address of slave %i.\n",
00915 fsm->slave->ring_position);
00916 return;
00917 }
00918
00919
00920 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0130, 2);
00921 ec_master_queue_datagram(fsm->master, datagram);
00922 fsm->slave_state = ec_fsm_slavescan_state;
00923 }
00924
00925
00926
00931 void ec_fsm_slavescan_state(ec_fsm_t *fsm )
00932 {
00933 ec_datagram_t *datagram = &fsm->datagram;
00934 ec_slave_t *slave = fsm->slave;
00935
00936 if (datagram->state != EC_DATAGRAM_RECEIVED
00937 || datagram->working_counter != 1) {
00938 fsm->slave->error_flag = 1;
00939 fsm->slave_state = ec_fsm_slave_state_error;
00940 EC_ERR("Failed to read AL state of slave %i.\n",
00941 fsm->slave->ring_position);
00942 return;
00943 }
00944
00945 slave->current_state = EC_READ_U8(datagram->data);
00946 if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
00947 char state_str[EC_STATE_STRING_SIZE];
00948 ec_state_string(slave->current_state, state_str);
00949 EC_WARN("Slave %i has state error bit set (%s)!\n",
00950 slave->ring_position, state_str);
00951 }
00952
00953
00954 ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0000, 6);
00955 ec_master_queue_datagram(fsm->master, datagram);
00956 fsm->slave_state = ec_fsm_slavescan_base;
00957 }
00958
00959
00960
00965 void ec_fsm_slavescan_base(ec_fsm_t *fsm )
00966 {
00967 ec_datagram_t *datagram = &fsm->datagram;
00968 ec_slave_t *slave = fsm->slave;
00969
00970 if (datagram->state != EC_DATAGRAM_RECEIVED
00971 || datagram->working_counter != 1) {
00972 fsm->slave->error_flag = 1;
00973 fsm->slave_state = ec_fsm_slave_state_error;
00974 EC_ERR("Failed to read base data of slave %i.\n",
00975 slave->ring_position);
00976 return;
00977 }
00978
00979 slave->base_type = EC_READ_U8 (datagram->data);
00980 slave->base_revision = EC_READ_U8 (datagram->data + 1);
00981 slave->base_build = EC_READ_U16(datagram->data + 2);
00982 slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4);
00983 slave->base_sync_count = EC_READ_U8 (datagram->data + 5);
00984
00985 if (slave->base_fmmu_count > EC_MAX_FMMUS)
00986 slave->base_fmmu_count = EC_MAX_FMMUS;
00987
00988
00989 ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2);
00990 ec_master_queue_datagram(slave->master, datagram);
00991 fsm->slave_state = ec_fsm_slavescan_datalink;
00992 }
00993
00994
00995
01000 void ec_fsm_slavescan_datalink(ec_fsm_t *fsm )
01001 {
01002 ec_datagram_t *datagram = &fsm->datagram;
01003 ec_slave_t *slave = fsm->slave;
01004 uint16_t dl_status;
01005 unsigned int i;
01006
01007 if (datagram->state != EC_DATAGRAM_RECEIVED
01008 || datagram->working_counter != 1) {
01009 fsm->slave->error_flag = 1;
01010 fsm->slave_state = ec_fsm_slave_state_error;
01011 EC_ERR("Failed to read DL status of slave %i.\n",
01012 slave->ring_position);
01013 return;
01014 }
01015
01016 dl_status = EC_READ_U16(datagram->data);
01017 for (i = 0; i < 4; i++) {
01018 slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
01019 slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
01020 slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
01021 }
01022
01023
01024
01025 fsm->sii_offset = 0x0040;
01026 ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset, EC_FSM_SII_NODE);
01027 fsm->slave_state = ec_fsm_slavescan_eeprom_size;
01028 fsm->slave_state(fsm);
01029 }
01030
01031
01032
01037 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *fsm )
01038 {
01039 ec_slave_t *slave = fsm->slave;
01040 uint16_t cat_type, cat_size;
01041
01042 if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
01043
01044 if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
01045 fsm->slave->error_flag = 1;
01046 fsm->slave_state = ec_fsm_slave_state_error;
01047 EC_ERR("Failed to read EEPROM size of slave %i.\n",
01048 slave->ring_position);
01049 return;
01050 }
01051
01052 cat_type = EC_READ_U16(fsm->fsm_sii.value);
01053 cat_size = EC_READ_U16(fsm->fsm_sii.value + 2);
01054
01055 if (cat_type != 0xFFFF) {
01056 fsm->sii_offset += cat_size + 2;
01057 ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
01058 EC_FSM_SII_NODE);
01059 ec_fsm_sii_exec(&fsm->fsm_sii);
01060 return;
01061 }
01062
01063 slave->eeprom_size = (fsm->sii_offset + 1) * 2;
01064
01065 if (slave->eeprom_data) {
01066 EC_INFO("Freeing old EEPROM data on slave %i...\n",
01067 slave->ring_position);
01068 kfree(slave->eeprom_data);
01069 }
01070
01071 if (!(slave->eeprom_data =
01072 (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
01073 fsm->slave->error_flag = 1;
01074 fsm->slave_state = ec_fsm_slave_state_error;
01075 EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
01076 slave->ring_position);
01077 return;
01078 }
01079
01080
01081
01082 fsm->slave_state = ec_fsm_slavescan_eeprom_data;
01083 fsm->sii_offset = 0x0000;
01084 ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset, EC_FSM_SII_NODE);
01085 ec_fsm_sii_exec(&fsm->fsm_sii);
01086 }
01087
01088
01089
01094 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *fsm )
01095 {
01096 ec_slave_t *slave = fsm->slave;
01097 uint16_t *cat_word, cat_type, cat_size;
01098
01099 if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
01100
01101 if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
01102 fsm->slave->error_flag = 1;
01103 fsm->slave_state = ec_fsm_slave_state_error;
01104 EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
01105 slave->ring_position);
01106 return;
01107 }
01108
01109
01110
01111 if (fsm->sii_offset + 2 <= slave->eeprom_size / 2) {
01112 memcpy(slave->eeprom_data + fsm->sii_offset * 2,
01113 fsm->fsm_sii.value, 4);
01114 }
01115 else {
01116 memcpy(slave->eeprom_data + fsm->sii_offset * 2,
01117 fsm->fsm_sii.value, 2);
01118 }
01119
01120 if (fsm->sii_offset + 2 < slave->eeprom_size / 2) {
01121
01122 fsm->sii_offset += 2;
01123 ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
01124 EC_FSM_SII_NODE);
01125 ec_fsm_sii_exec(&fsm->fsm_sii);
01126 return;
01127 }
01128
01129
01130
01131 slave->sii_alias =
01132 EC_READ_U16(slave->eeprom_data + 2 * 0x0004);
01133 slave->sii_vendor_id =
01134 EC_READ_U32(slave->eeprom_data + 2 * 0x0008);
01135 slave->sii_product_code =
01136 EC_READ_U32(slave->eeprom_data + 2 * 0x000A);
01137 slave->sii_revision_number =
01138 EC_READ_U32(slave->eeprom_data + 2 * 0x000C);
01139 slave->sii_serial_number =
01140 EC_READ_U32(slave->eeprom_data + 2 * 0x000E);
01141 slave->sii_rx_mailbox_offset =
01142 EC_READ_U16(slave->eeprom_data + 2 * 0x0018);
01143 slave->sii_rx_mailbox_size =
01144 EC_READ_U16(slave->eeprom_data + 2 * 0x0019);
01145 slave->sii_tx_mailbox_offset =
01146 EC_READ_U16(slave->eeprom_data + 2 * 0x001A);
01147 slave->sii_tx_mailbox_size =
01148 EC_READ_U16(slave->eeprom_data + 2 * 0x001B);
01149 slave->sii_mailbox_protocols =
01150 EC_READ_U16(slave->eeprom_data + 2 * 0x001C);
01151
01152
01153 cat_word = (uint16_t *) slave->eeprom_data + 0x0040;
01154 while (EC_READ_U16(cat_word) != 0xFFFF) {
01155 cat_type = EC_READ_U16(cat_word) & 0x7FFF;
01156 cat_size = EC_READ_U16(cat_word + 1);
01157
01158 switch (cat_type) {
01159 case 0x000A:
01160 if (ec_slave_fetch_strings(slave, (uint8_t *) (cat_word + 2)))
01161 goto end;
01162 break;
01163 case 0x001E:
01164 ec_slave_fetch_general(slave, (uint8_t *) (cat_word + 2));
01165 break;
01166 case 0x0028:
01167 break;
01168 case 0x0029:
01169 if (ec_slave_fetch_sync(slave, (uint8_t *) (cat_word + 2),
01170 cat_size))
01171 goto end;
01172 break;
01173 case 0x0032:
01174 if (ec_slave_fetch_pdo(slave, (uint8_t *) (cat_word + 2),
01175 cat_size, EC_TX_PDO))
01176 goto end;
01177 break;
01178 case 0x0033:
01179 if (ec_slave_fetch_pdo(slave, (uint8_t *) (cat_word + 2),
01180 cat_size, EC_RX_PDO))
01181 goto end;
01182 break;
01183 default:
01184 if (fsm->master->debug_level)
01185 EC_WARN("Unknown category type 0x%04X in slave %i.\n",
01186 cat_type, slave->ring_position);
01187 }
01188
01189 cat_word += cat_size + 2;
01190 }
01191
01192 fsm->slave_state = ec_fsm_slave_state_end;
01193 return;
01194
01195 end:
01196 EC_ERR("Failed to analyze category data.\n");
01197 fsm->slave->error_flag = 1;
01198 fsm->slave_state = ec_fsm_slave_state_error;
01199 }
01200
01201
01202
01203
01204
01209 void ec_fsm_slaveconf_state_start(ec_fsm_t *fsm )
01210 {
01211 if (fsm->master->debug_level) {
01212 EC_DBG("Configuring slave %i...\n", fsm->slave->ring_position);
01213 }
01214
01215 ec_fsm_change_start(&fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_INIT);
01216 ec_fsm_change_exec(&fsm->fsm_change);
01217 fsm->slave_state = ec_fsm_slaveconf_state_init;
01218 }
01219
01220
01221
01226 void ec_fsm_slaveconf_state_init(ec_fsm_t *fsm )
01227 {
01228 ec_master_t *master = fsm->master;
01229 ec_slave_t *slave = fsm->slave;
01230 ec_datagram_t *datagram = &fsm->datagram;
01231
01232 if (ec_fsm_change_exec(&fsm->fsm_change)) return;
01233
01234 if (!ec_fsm_change_success(&fsm->fsm_change)) {
01235 slave->error_flag = 1;
01236 fsm->slave_state = ec_fsm_slave_state_error;
01237 return;
01238 }
01239
01240 slave->configured = 1;
01241
01242 if (master->debug_level) {
01243 EC_DBG("Slave %i is now in INIT.\n", slave->ring_position);
01244 }
01245
01246
01247
01248
01249
01250 if (!slave->base_fmmu_count) {
01251 ec_fsm_slaveconf_enter_sync(fsm);
01252 return;
01253 }
01254
01255 if (master->debug_level)
01256 EC_DBG("Clearing FMMU configurations of slave %i...\n",
01257 slave->ring_position);
01258
01259
01260 ec_datagram_npwr(datagram, slave->station_address,
01261 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count);
01262 memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
01263 ec_master_queue_datagram(master, datagram);
01264 fsm->slave_state = ec_fsm_slaveconf_state_clear_fmmus;
01265 }
01266
01267
01268
01273 void ec_fsm_slaveconf_state_clear_fmmus(ec_fsm_t *fsm)
01275 {
01276 ec_datagram_t *datagram = &fsm->datagram;
01277
01278 if (datagram->state != EC_DATAGRAM_RECEIVED
01279 || datagram->working_counter != 1) {
01280 fsm->slave->error_flag = 1;
01281 fsm->slave_state = ec_fsm_slave_state_error;
01282 EC_ERR("Failed to clear FMMUs on slave %i.\n",
01283 fsm->slave->ring_position);
01284 return;
01285 }
01286
01287 ec_fsm_slaveconf_enter_sync(fsm);
01288 }
01289
01290
01291
01295 void ec_fsm_slaveconf_enter_sync(ec_fsm_t *fsm )
01296 {
01297 ec_master_t *master = fsm->master;
01298 ec_slave_t *slave = fsm->slave;
01299 ec_datagram_t *datagram = &fsm->datagram;
01300 const ec_sii_sync_t *sync;
01301 ec_sii_sync_t mbox_sync;
01302
01303
01304 if (slave->current_state == slave->requested_state) {
01305 fsm->slave_state = ec_fsm_slave_state_end;
01306 if (master->debug_level) {
01307 EC_DBG("Finished configuration of slave %i.\n",
01308 slave->ring_position);
01309 }
01310 return;
01311 }
01312
01313 if (!slave->base_sync_count) {
01314 ec_fsm_slaveconf_enter_preop(fsm);
01315 return;
01316 }
01317
01318 if (master->debug_level) {
01319 EC_DBG("Configuring sync managers of slave %i.\n",
01320 slave->ring_position);
01321 }
01322
01323
01324 ec_datagram_npwr(datagram, slave->station_address, 0x0800,
01325 EC_SYNC_SIZE * slave->base_sync_count);
01326 memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
01327
01328 if (list_empty(&slave->sii_syncs)) {
01329 if (slave->sii_rx_mailbox_offset && slave->sii_tx_mailbox_offset) {
01330 if (slave->master->debug_level)
01331 EC_DBG("Guessing sync manager settings for slave %i.\n",
01332 slave->ring_position);
01333 mbox_sync.index = 0;
01334 mbox_sync.physical_start_address = slave->sii_tx_mailbox_offset;
01335 mbox_sync.length = slave->sii_tx_mailbox_size;
01336 mbox_sync.control_register = 0x26;
01337 mbox_sync.enable = 0x01;
01338 mbox_sync.est_length = 0;
01339 ec_sync_config(&mbox_sync, slave,
01340 datagram->data + EC_SYNC_SIZE * mbox_sync.index);
01341 mbox_sync.index = 1;
01342 mbox_sync.physical_start_address = slave->sii_rx_mailbox_offset;
01343 mbox_sync.length = slave->sii_rx_mailbox_size;
01344 mbox_sync.control_register = 0x22;
01345 mbox_sync.enable = 0x01;
01346 mbox_sync.est_length = 0;
01347 ec_sync_config(&mbox_sync, slave,
01348 datagram->data + EC_SYNC_SIZE * mbox_sync.index);
01349 }
01350 }
01351 else if (slave->sii_mailbox_protocols) {
01352 list_for_each_entry(sync, &slave->sii_syncs, list) {
01353
01354 if (sync->index != 0 && sync->index != 1) continue;
01355 ec_sync_config(sync, slave,
01356 datagram->data + EC_SYNC_SIZE * sync->index);
01357 }
01358 }
01359
01360 ec_master_queue_datagram(fsm->master, datagram);
01361 fsm->slave_state = ec_fsm_slaveconf_state_sync;
01362 }
01363
01364
01365
01370 void ec_fsm_slaveconf_state_sync(ec_fsm_t *fsm )
01371 {
01372 ec_datagram_t *datagram = &fsm->datagram;
01373 ec_slave_t *slave = fsm->slave;
01374
01375 if (datagram->state != EC_DATAGRAM_RECEIVED
01376 || datagram->working_counter != 1) {
01377 slave->error_flag = 1;
01378 fsm->slave_state = ec_fsm_slave_state_error;
01379 EC_ERR("Failed to set sync managers on slave %i.\n",
01380 slave->ring_position);
01381 return;
01382 }
01383
01384 ec_fsm_slaveconf_enter_preop(fsm);
01385 }
01386
01387
01388
01392 void ec_fsm_slaveconf_enter_preop(ec_fsm_t *fsm )
01393 {
01394 fsm->slave_state = ec_fsm_slaveconf_state_preop;
01395 ec_fsm_change_start(&fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_PREOP);
01396 ec_fsm_change_exec(&fsm->fsm_change);
01397 }
01398
01399
01400
01405 void ec_fsm_slaveconf_state_preop(ec_fsm_t *fsm )
01406 {
01407 ec_slave_t *slave = fsm->slave;
01408 ec_master_t *master = fsm->master;
01409
01410 if (ec_fsm_change_exec(&fsm->fsm_change)) return;
01411
01412 if (!ec_fsm_change_success(&fsm->fsm_change)) {
01413 slave->error_flag = 1;
01414 fsm->slave_state = ec_fsm_slave_state_error;
01415 return;
01416 }
01417
01418
01419 slave->jiffies_preop = fsm->datagram.jiffies_received;
01420
01421 if (master->debug_level) {
01422 EC_DBG("Slave %i is now in PREOP.\n", slave->ring_position);
01423 }
01424
01425 if (slave->current_state == slave->requested_state) {
01426 fsm->slave_state = ec_fsm_slave_state_end;
01427 if (master->debug_level) {
01428 EC_DBG("Finished configuration of slave %i.\n",
01429 slave->ring_position);
01430 }
01431 return;
01432 }
01433
01434 ec_fsm_slaveconf_enter_sync2(fsm);
01435 }
01436
01437
01438
01442 void ec_fsm_slaveconf_enter_sync2(ec_fsm_t *fsm )
01443 {
01444 ec_slave_t *slave = fsm->slave;
01445 ec_datagram_t *datagram = &fsm->datagram;
01446 ec_sii_sync_t *sync;
01447
01448 if (list_empty(&slave->sii_syncs)) {
01449 ec_fsm_slaveconf_enter_fmmu(fsm);
01450 return;
01451 }
01452
01453
01454 ec_datagram_npwr(datagram, slave->station_address, 0x0800,
01455 EC_SYNC_SIZE * slave->base_sync_count);
01456 memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
01457
01458 list_for_each_entry(sync, &slave->sii_syncs, list) {
01459 ec_sync_config(sync, slave,
01460 datagram->data + EC_SYNC_SIZE * sync->index);
01461 }
01462
01463 ec_master_queue_datagram(fsm->master, datagram);
01464 fsm->slave_state = ec_fsm_slaveconf_state_sync2;
01465 }
01466
01467
01468
01473 void ec_fsm_slaveconf_state_sync2(ec_fsm_t *fsm )
01474 {
01475 ec_datagram_t *datagram = &fsm->datagram;
01476 ec_slave_t *slave = fsm->slave;
01477
01478 if (datagram->state != EC_DATAGRAM_RECEIVED
01479 || datagram->working_counter != 1) {
01480 slave->error_flag = 1;
01481 fsm->slave_state = ec_fsm_slave_state_error;
01482 EC_ERR("Failed to set process data sync managers on slave %i.\n",
01483 slave->ring_position);
01484 return;
01485 }
01486
01487 ec_fsm_slaveconf_enter_fmmu(fsm);
01488 }
01489
01490
01491
01495 void ec_fsm_slaveconf_enter_fmmu(ec_fsm_t *fsm )
01496 {
01497 ec_slave_t *slave = fsm->slave;
01498 ec_master_t *master = slave->master;
01499 ec_datagram_t *datagram = &fsm->datagram;
01500 unsigned int j;
01501
01502 if (!slave->base_fmmu_count) {
01503 ec_fsm_slaveconf_enter_sdoconf(fsm);
01504 return;
01505 }
01506
01507
01508 ec_datagram_npwr(datagram, slave->station_address,
01509 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count);
01510 memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
01511 for (j = 0; j < slave->fmmu_count; j++) {
01512 ec_fmmu_config(&slave->fmmus[j], slave,
01513 datagram->data + EC_FMMU_SIZE * j);
01514 }
01515
01516 ec_master_queue_datagram(master, datagram);
01517 fsm->slave_state = ec_fsm_slaveconf_state_fmmu;
01518 }
01519
01520
01521
01526 void ec_fsm_slaveconf_state_fmmu(ec_fsm_t *fsm )
01527 {
01528 ec_datagram_t *datagram = &fsm->datagram;
01529 ec_slave_t *slave = fsm->slave;
01530
01531 if (datagram->state != EC_DATAGRAM_RECEIVED
01532 || datagram->working_counter != 1) {
01533 fsm->slave->error_flag = 1;
01534 fsm->slave_state = ec_fsm_slave_state_error;
01535 EC_ERR("Failed to set FMMUs on slave %i.\n",
01536 fsm->slave->ring_position);
01537 return;
01538 }
01539
01540
01541 if (list_empty(&slave->sdo_confs)) {
01542 ec_fsm_slaveconf_enter_saveop(fsm);
01543 return;
01544 }
01545
01546 ec_fsm_slaveconf_enter_sdoconf(fsm);
01547 }
01548
01549
01550
01554 void ec_fsm_slaveconf_enter_sdoconf(ec_fsm_t *fsm )
01555 {
01556 ec_slave_t *slave = fsm->slave;
01557
01558 if (list_empty(&slave->sdo_confs)) {
01559 ec_fsm_slaveconf_enter_saveop(fsm);
01560 return;
01561 }
01562
01563
01564 fsm->slave_state = ec_fsm_slaveconf_state_sdoconf;
01565 fsm->sdodata = list_entry(fsm->slave->sdo_confs.next, ec_sdo_data_t, list);
01566 ec_fsm_coe_download(&fsm->fsm_coe, fsm->slave, fsm->sdodata);
01567 ec_fsm_coe_exec(&fsm->fsm_coe);
01568 }
01569
01570
01571
01576 void ec_fsm_slaveconf_state_sdoconf(ec_fsm_t *fsm )
01577 {
01578 if (ec_fsm_coe_exec(&fsm->fsm_coe)) return;
01579
01580 if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
01581 fsm->slave->error_flag = 1;
01582 fsm->slave_state = ec_fsm_slave_state_error;
01583 return;
01584 }
01585
01586
01587 if (fsm->sdodata->list.next != &fsm->slave->sdo_confs) {
01588 fsm->sdodata = list_entry(fsm->sdodata->list.next,
01589 ec_sdo_data_t, list);
01590 ec_fsm_coe_download(&fsm->fsm_coe, fsm->slave, fsm->sdodata);
01591 ec_fsm_coe_exec(&fsm->fsm_coe);
01592 return;
01593 }
01594
01595
01596
01597
01598 ec_fsm_slaveconf_enter_saveop(fsm);
01599 }
01600
01601
01602
01606 void ec_fsm_slaveconf_enter_saveop(ec_fsm_t *fsm )
01607 {
01608 fsm->slave_state = ec_fsm_slaveconf_state_saveop;
01609 ec_fsm_change_start(&fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_SAVEOP);
01610 ec_fsm_change_exec(&fsm->fsm_change);
01611 }
01612
01613
01614
01619 void ec_fsm_slaveconf_state_saveop(ec_fsm_t *fsm )
01620 {
01621 ec_master_t *master = fsm->master;
01622 ec_slave_t *slave = fsm->slave;
01623
01624 if (ec_fsm_change_exec(&fsm->fsm_change)) return;
01625
01626 if (!ec_fsm_change_success(&fsm->fsm_change)) {
01627 fsm->slave->error_flag = 1;
01628 fsm->slave_state = ec_fsm_slave_state_error;
01629 return;
01630 }
01631
01632
01633
01634 if (master->debug_level) {
01635 EC_DBG("Slave %i is now in SAVEOP.\n", slave->ring_position);
01636 }
01637
01638 if (fsm->slave->current_state == fsm->slave->requested_state) {
01639 fsm->slave_state = ec_fsm_slave_state_end;
01640 if (master->debug_level) {
01641 EC_DBG("Finished configuration of slave %i.\n",
01642 slave->ring_position);
01643 }
01644 return;
01645 }
01646
01647
01648 fsm->slave_state = ec_fsm_slaveconf_state_op;
01649 ec_fsm_change_start(&fsm->fsm_change, slave, EC_SLAVE_STATE_OP);
01650 ec_fsm_change_exec(&fsm->fsm_change);
01651 }
01652
01653
01654
01659 void ec_fsm_slaveconf_state_op(ec_fsm_t *fsm )
01660 {
01661 ec_master_t *master = fsm->master;
01662 ec_slave_t *slave = fsm->slave;
01663
01664 if (ec_fsm_change_exec(&fsm->fsm_change)) return;
01665
01666 if (!ec_fsm_change_success(&fsm->fsm_change)) {
01667 slave->error_flag = 1;
01668 fsm->slave_state = ec_fsm_slave_state_error;
01669 return;
01670 }
01671
01672
01673
01674 if (master->debug_level) {
01675 EC_DBG("Slave %i is now in OP.\n", slave->ring_position);
01676 EC_DBG("Finished configuration of slave %i.\n", slave->ring_position);
01677 }
01678
01679 fsm->slave_state = ec_fsm_slave_state_end;
01680 }
01681
01682
01683
01684
01685
01690 void ec_fsm_slave_state_error(ec_fsm_t *fsm )
01691 {
01692 }
01693
01694
01695
01700 void ec_fsm_slave_state_end(ec_fsm_t *fsm )
01701 {
01702 }
01703
01704