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
00034
00035
00036 #include "globals.h"
00037 #include "master.h"
00038 #include "mailbox.h"
00039 #include "slave_config.h"
00040 #ifdef EC_EOE
00041 #include "ethernet.h"
00042 #endif
00043
00044 #include "fsm_master.h"
00045 #include "fsm_foe.h"
00046
00047
00048
00051 #define EC_SYSTEM_TIME_TOLERANCE_NS 1000000
00052
00053
00054
00055 void ec_fsm_master_state_start(ec_fsm_master_t *);
00056 void ec_fsm_master_state_broadcast(ec_fsm_master_t *);
00057 void ec_fsm_master_state_read_state(ec_fsm_master_t *);
00058 void ec_fsm_master_state_acknowledge(ec_fsm_master_t *);
00059 void ec_fsm_master_state_configure_slave(ec_fsm_master_t *);
00060 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *);
00061 void ec_fsm_master_state_dc_measure_delays(ec_fsm_master_t *);
00062 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *);
00063 void ec_fsm_master_state_dc_read_offset(ec_fsm_master_t *);
00064 void ec_fsm_master_state_dc_write_offset(ec_fsm_master_t *);
00065 void ec_fsm_master_state_write_sii(ec_fsm_master_t *);
00066 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *);
00067 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *);
00068
00069 void ec_fsm_master_enter_clear_addresses(ec_fsm_master_t *);
00070 void ec_fsm_master_enter_write_system_times(ec_fsm_master_t *);
00071
00072
00073
00076 void ec_fsm_master_init(
00077 ec_fsm_master_t *fsm,
00078 ec_master_t *master,
00079 ec_datagram_t *datagram
00080 )
00081 {
00082 fsm->master = master;
00083 fsm->datagram = datagram;
00084
00085 ec_fsm_master_reset(fsm);
00086
00087
00088 ec_fsm_coe_init(&fsm->fsm_coe);
00089 ec_fsm_soe_init(&fsm->fsm_soe);
00090 ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe);
00091 ec_fsm_change_init(&fsm->fsm_change, fsm->datagram);
00092 ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram,
00093 &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_soe, &fsm->fsm_pdo);
00094 ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram,
00095 &fsm->fsm_slave_config, &fsm->fsm_pdo);
00096 ec_fsm_sii_init(&fsm->fsm_sii, fsm->datagram);
00097 }
00098
00099
00100
00103 void ec_fsm_master_clear(
00104 ec_fsm_master_t *fsm
00105 )
00106 {
00107
00108 ec_fsm_coe_clear(&fsm->fsm_coe);
00109 ec_fsm_soe_clear(&fsm->fsm_soe);
00110 ec_fsm_pdo_clear(&fsm->fsm_pdo);
00111 ec_fsm_change_clear(&fsm->fsm_change);
00112 ec_fsm_slave_config_clear(&fsm->fsm_slave_config);
00113 ec_fsm_slave_scan_clear(&fsm->fsm_slave_scan);
00114 ec_fsm_sii_clear(&fsm->fsm_sii);
00115 }
00116
00117
00118
00121 void ec_fsm_master_reset(
00122 ec_fsm_master_t *fsm
00123 )
00124 {
00125 ec_device_index_t dev_idx;
00126
00127 fsm->state = ec_fsm_master_state_start;
00128 fsm->idle = 0;
00129 fsm->dev_idx = EC_DEVICE_MAIN;
00130
00131 for (dev_idx = EC_DEVICE_MAIN;
00132 dev_idx < ec_master_num_devices(fsm->master); dev_idx++) {
00133 fsm->link_state[dev_idx] = 0;
00134 fsm->slaves_responding[dev_idx] = 0;
00135 fsm->slave_states[dev_idx] = EC_SLAVE_STATE_UNKNOWN;
00136 }
00137
00138 fsm->rescan_required = 0;
00139 }
00140
00141
00142
00150 int ec_fsm_master_exec(
00151 ec_fsm_master_t *fsm
00152 )
00153 {
00154 if (fsm->datagram->state == EC_DATAGRAM_SENT
00155 || fsm->datagram->state == EC_DATAGRAM_QUEUED) {
00156
00157 return 0;
00158 }
00159
00160 fsm->state(fsm);
00161 return 1;
00162 }
00163
00164
00165
00169 int ec_fsm_master_idle(
00170 const ec_fsm_master_t *fsm
00171 )
00172 {
00173 return fsm->idle;
00174 }
00175
00176
00177
00180 void ec_fsm_master_restart(
00181 ec_fsm_master_t *fsm
00182 )
00183 {
00184 fsm->dev_idx = EC_DEVICE_MAIN;
00185 fsm->state = ec_fsm_master_state_start;
00186 fsm->state(fsm);
00187 }
00188
00189
00190
00191
00192
00197 void ec_fsm_master_state_start(
00198 ec_fsm_master_t *fsm
00199 )
00200 {
00201 ec_master_t *master = fsm->master;
00202
00203 fsm->idle = 1;
00204
00205
00206 if (!list_empty(&master->emerg_reg_requests)) {
00207 ec_reg_request_t *request;
00208
00209
00210 request = list_entry(master->emerg_reg_requests.next,
00211 ec_reg_request_t, list);
00212 list_del_init(&request->list);
00213 request->state = EC_INT_REQUEST_BUSY;
00214
00215 if (request->transfer_size > fsm->datagram->mem_size) {
00216 EC_MASTER_ERR(master, "Emergency request data too large!\n");
00217 request->state = EC_INT_REQUEST_FAILURE;
00218 wake_up_all(&master->request_queue);
00219 fsm->state(fsm);
00220 return;
00221 }
00222
00223 if (request->dir != EC_DIR_OUTPUT) {
00224 EC_MASTER_ERR(master, "Emergency requests must be"
00225 " write requests!\n");
00226 request->state = EC_INT_REQUEST_FAILURE;
00227 wake_up_all(&master->request_queue);
00228 fsm->state(fsm);
00229 return;
00230 }
00231
00232 EC_MASTER_DBG(master, 1, "Writing emergency register request...\n");
00233 ec_datagram_apwr(fsm->datagram, request->ring_position,
00234 request->address, request->transfer_size);
00235 memcpy(fsm->datagram->data, request->data, request->transfer_size);
00236 fsm->datagram->device_index = EC_DEVICE_MAIN;
00237 request->state = EC_INT_REQUEST_SUCCESS;
00238 wake_up_all(&master->request_queue);
00239 return;
00240 }
00241
00242 ec_datagram_brd(fsm->datagram, 0x0130, 2);
00243 ec_datagram_zero(fsm->datagram);
00244 fsm->datagram->device_index = fsm->dev_idx;
00245 fsm->state = ec_fsm_master_state_broadcast;
00246 }
00247
00248
00249
00254 void ec_fsm_master_state_broadcast(
00255 ec_fsm_master_t *fsm
00256 )
00257 {
00258 ec_datagram_t *datagram = fsm->datagram;
00259 unsigned int i, size;
00260 ec_slave_t *slave;
00261 ec_master_t *master = fsm->master;
00262
00263
00264 if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) {
00265 fsm->rescan_required = 1;
00266 fsm->slaves_responding[fsm->dev_idx] = datagram->working_counter;
00267 EC_MASTER_INFO(master, "%u slave(s) responding on %s device.\n",
00268 fsm->slaves_responding[fsm->dev_idx],
00269 ec_device_names[fsm->dev_idx != 0]);
00270 }
00271
00272 if (fsm->link_state[fsm->dev_idx] &&
00273 !master->devices[fsm->dev_idx].link_state) {
00274 ec_device_index_t dev_idx;
00275
00276 EC_MASTER_DBG(master, 1, "Master state machine detected "
00277 "link down on %s device. Clearing slave list.\n",
00278 ec_device_names[fsm->dev_idx != 0]);
00279
00280 #ifdef EC_EOE
00281 ec_master_eoe_stop(master);
00282 ec_master_clear_eoe_handlers(master);
00283 #endif
00284 ec_master_clear_slaves(master);
00285
00286 for (dev_idx = EC_DEVICE_MAIN;
00287 dev_idx < ec_master_num_devices(master); dev_idx++) {
00288 fsm->slave_states[dev_idx] = 0x00;
00289 fsm->slaves_responding[dev_idx] = 0;
00290
00291 }
00292 }
00293 fsm->link_state[fsm->dev_idx] = master->devices[fsm->dev_idx].link_state;
00294
00295 if (datagram->state == EC_DATAGRAM_RECEIVED &&
00296 fsm->slaves_responding[fsm->dev_idx]) {
00297 uint8_t states = EC_READ_U8(datagram->data);
00298 if (states != fsm->slave_states[fsm->dev_idx]) {
00299
00300 char state_str[EC_STATE_STRING_SIZE];
00301 fsm->slave_states[fsm->dev_idx] = states;
00302 ec_state_string(states, state_str, 1);
00303 EC_MASTER_INFO(master, "Slave states on %s device: %s.\n",
00304 ec_device_names[fsm->dev_idx != 0], state_str);
00305 }
00306 } else {
00307 fsm->slave_states[fsm->dev_idx] = 0x00;
00308 }
00309
00310 fsm->dev_idx++;
00311 if (fsm->dev_idx < ec_master_num_devices(master)) {
00312
00313 fsm->state = ec_fsm_master_state_start;
00314 fsm->state(fsm);
00315 return;
00316 }
00317
00318 if (fsm->rescan_required) {
00319 down(&master->scan_sem);
00320 if (!master->allow_scan) {
00321 up(&master->scan_sem);
00322 } else {
00323 unsigned int count = 0, next_dev_slave, ring_position;
00324 ec_device_index_t dev_idx;
00325
00326 master->scan_busy = 1;
00327 up(&master->scan_sem);
00328
00329
00330 fsm->rescan_required = 0;
00331 fsm->idle = 0;
00332 fsm->scan_jiffies = jiffies;
00333
00334 #ifdef EC_EOE
00335 ec_master_eoe_stop(master);
00336 ec_master_clear_eoe_handlers(master);
00337 #endif
00338 ec_master_clear_slaves(master);
00339
00340 for (dev_idx = EC_DEVICE_MAIN;
00341 dev_idx < ec_master_num_devices(master); dev_idx++) {
00342 count += fsm->slaves_responding[dev_idx];
00343 }
00344
00345 if (!count) {
00346
00347 master->scan_busy = 0;
00348 wake_up_interruptible(&master->scan_queue);
00349 ec_fsm_master_restart(fsm);
00350 return;
00351 }
00352
00353 size = sizeof(ec_slave_t) * count;
00354 if (!(master->slaves =
00355 (ec_slave_t *) kmalloc(size, GFP_KERNEL))) {
00356 EC_MASTER_ERR(master, "Failed to allocate %u bytes"
00357 " of slave memory!\n", size);
00358 master->scan_busy = 0;
00359 wake_up_interruptible(&master->scan_queue);
00360 ec_fsm_master_restart(fsm);
00361 return;
00362 }
00363
00364
00365 dev_idx = EC_DEVICE_MAIN;
00366 next_dev_slave = fsm->slaves_responding[dev_idx];
00367 ring_position = 0;
00368 for (i = 0; i < count; i++, ring_position++) {
00369 slave = master->slaves + i;
00370 while (i >= next_dev_slave) {
00371 dev_idx++;
00372 next_dev_slave += fsm->slaves_responding[dev_idx];
00373 ring_position = 0;
00374 }
00375
00376 ec_slave_init(slave, master, dev_idx, ring_position, i + 1);
00377
00378
00379
00380 if (master->phase != EC_OPERATION) {
00381 slave->force_config = 1;
00382 }
00383 }
00384 master->slave_count = count;
00385 master->fsm_slave = master->slaves;
00386
00387
00388
00389 fsm->dev_idx = EC_DEVICE_MAIN;
00390 while (!fsm->slaves_responding[fsm->dev_idx]) {
00391 fsm->dev_idx++;
00392 }
00393
00394 ec_fsm_master_enter_clear_addresses(fsm);
00395 return;
00396 }
00397 }
00398
00399 if (master->slave_count) {
00400
00401
00402 if (master->config_changed) {
00403 master->config_changed = 0;
00404
00405 EC_MASTER_DBG(master, 1, "Configuration changed.\n");
00406
00407 fsm->slave = master->slaves;
00408 ec_fsm_master_enter_write_system_times(fsm);
00409
00410 } else {
00411
00412 fsm->slave = master->slaves;
00413 ec_datagram_fprd(fsm->datagram, fsm->slave->station_address,
00414 0x0130, 2);
00415 ec_datagram_zero(datagram);
00416 fsm->datagram->device_index = fsm->slave->device_index;
00417 fsm->retries = EC_FSM_RETRIES;
00418 fsm->state = ec_fsm_master_state_read_state;
00419 }
00420 } else {
00421 ec_fsm_master_restart(fsm);
00422 }
00423 }
00424
00425
00426
00431 int ec_fsm_master_action_process_sii(
00432 ec_fsm_master_t *fsm
00433 )
00434 {
00435 ec_master_t *master = fsm->master;
00436 ec_sii_write_request_t *request;
00437
00438
00439 while (1) {
00440 if (list_empty(&master->sii_requests))
00441 break;
00442
00443
00444 request = list_entry(master->sii_requests.next,
00445 ec_sii_write_request_t, list);
00446 list_del_init(&request->list);
00447 request->state = EC_INT_REQUEST_BUSY;
00448
00449
00450 EC_SLAVE_DBG(request->slave, 1, "Writing SII data...\n");
00451 fsm->sii_request = request;
00452 fsm->sii_index = 0;
00453 ec_fsm_sii_write(&fsm->fsm_sii, request->slave, request->offset,
00454 request->words, EC_FSM_SII_USE_CONFIGURED_ADDRESS);
00455 fsm->state = ec_fsm_master_state_write_sii;
00456 fsm->state(fsm);
00457 return 1;
00458 }
00459
00460 return 0;
00461 }
00462
00463
00464
00469 int ec_fsm_master_action_process_sdo(
00470 ec_fsm_master_t *fsm
00471 )
00472 {
00473 ec_master_t *master = fsm->master;
00474 ec_slave_t *slave;
00475 ec_sdo_request_t *req;
00476
00477
00478 for (slave = master->slaves;
00479 slave < master->slaves + master->slave_count;
00480 slave++) {
00481
00482 if (!slave->config) {
00483 continue;
00484 }
00485
00486 list_for_each_entry(req, &slave->config->sdo_requests, list) {
00487 if (req->state == EC_INT_REQUEST_QUEUED) {
00488
00489 if (ec_sdo_request_timed_out(req)) {
00490 req->state = EC_INT_REQUEST_FAILURE;
00491 EC_SLAVE_DBG(slave, 1, "Internal SDO request"
00492 " timed out.\n");
00493 continue;
00494 }
00495
00496 if (slave->current_state == EC_SLAVE_STATE_INIT) {
00497 req->state = EC_INT_REQUEST_FAILURE;
00498 continue;
00499 }
00500
00501 req->state = EC_INT_REQUEST_BUSY;
00502 EC_SLAVE_DBG(slave, 1, "Processing internal"
00503 " SDO request...\n");
00504 fsm->idle = 0;
00505 fsm->sdo_request = req;
00506 fsm->slave = slave;
00507 fsm->state = ec_fsm_master_state_sdo_request;
00508 ec_fsm_coe_transfer(&fsm->fsm_coe, slave, req);
00509 ec_fsm_coe_exec(&fsm->fsm_coe, fsm->datagram);
00510 return 1;
00511 }
00512 }
00513 }
00514 return 0;
00515 }
00516
00517
00518
00523 void ec_fsm_master_action_idle(
00524 ec_fsm_master_t *fsm
00525 )
00526 {
00527 ec_master_t *master = fsm->master;
00528 ec_slave_t *slave;
00529
00530
00531 if (ec_fsm_master_action_process_sdo(fsm)) {
00532 return;
00533 }
00534
00535
00536 for (slave = master->slaves;
00537 slave < master->slaves + master->slave_count;
00538 slave++) {
00539 ec_fsm_slave_set_ready(&slave->fsm);
00540 }
00541
00542
00543 for (slave = master->slaves;
00544 slave < master->slaves + master->slave_count;
00545 slave++) {
00546 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)
00547 || (slave->sii.has_general
00548 && !slave->sii.coe_details.enable_sdo_info)
00549 || slave->sdo_dictionary_fetched
00550 || slave->current_state == EC_SLAVE_STATE_INIT
00551 || slave->current_state == EC_SLAVE_STATE_UNKNOWN
00552 || jiffies - slave->jiffies_preop < EC_WAIT_SDO_DICT * HZ
00553 ) continue;
00554
00555 EC_SLAVE_DBG(slave, 1, "Fetching SDO dictionary.\n");
00556
00557 slave->sdo_dictionary_fetched = 1;
00558
00559
00560 fsm->idle = 0;
00561 fsm->slave = slave;
00562 fsm->state = ec_fsm_master_state_sdo_dictionary;
00563 ec_fsm_coe_dictionary(&fsm->fsm_coe, slave);
00564 ec_fsm_coe_exec(&fsm->fsm_coe, fsm->datagram);
00565 fsm->datagram->device_index = fsm->slave->device_index;
00566 return;
00567 }
00568
00569
00570 if (ec_fsm_master_action_process_sii(fsm)) {
00571 return;
00572 }
00573
00574 ec_fsm_master_restart(fsm);
00575 }
00576
00577
00578
00581 void ec_fsm_master_action_next_slave_state(
00582 ec_fsm_master_t *fsm
00583 )
00584 {
00585 ec_master_t *master = fsm->master;
00586
00587
00588 fsm->slave++;
00589 if (fsm->slave < master->slaves + master->slave_count) {
00590
00591 fsm->idle = 1;
00592 ec_datagram_fprd(fsm->datagram,
00593 fsm->slave->station_address, 0x0130, 2);
00594 ec_datagram_zero(fsm->datagram);
00595 fsm->datagram->device_index = fsm->slave->device_index;
00596 fsm->retries = EC_FSM_RETRIES;
00597 fsm->state = ec_fsm_master_state_read_state;
00598 return;
00599 }
00600
00601
00602 ec_fsm_master_action_idle(fsm);
00603 }
00604
00605
00606
00609 void ec_fsm_master_action_configure(
00610 ec_fsm_master_t *fsm
00611 )
00612 {
00613 ec_master_t *master = fsm->master;
00614 ec_slave_t *slave = fsm->slave;
00615
00616 if (master->config_changed) {
00617 master->config_changed = 0;
00618
00619
00620
00621
00622 EC_MASTER_DBG(master, 1, "Configuration changed"
00623 " (aborting state check).\n");
00624
00625 fsm->slave = master->slaves;
00626 ec_fsm_master_enter_write_system_times(fsm);
00627 return;
00628 }
00629
00630
00631 if ((slave->current_state != slave->requested_state
00632 || slave->force_config) && !slave->error_flag) {
00633
00634
00635 down(&master->config_sem);
00636 master->config_busy = 1;
00637 up(&master->config_sem);
00638
00639 if (master->debug_level) {
00640 char old_state[EC_STATE_STRING_SIZE],
00641 new_state[EC_STATE_STRING_SIZE];
00642 ec_state_string(slave->current_state, old_state, 0);
00643 ec_state_string(slave->requested_state, new_state, 0);
00644 EC_SLAVE_DBG(slave, 1, "Changing state from %s to %s%s.\n",
00645 old_state, new_state,
00646 slave->force_config ? " (forced)" : "");
00647 }
00648
00649 fsm->idle = 0;
00650 fsm->state = ec_fsm_master_state_configure_slave;
00651 ec_fsm_slave_config_start(&fsm->fsm_slave_config, slave);
00652 fsm->state(fsm);
00653 fsm->datagram->device_index = fsm->slave->device_index;
00654 return;
00655 }
00656
00657
00658 ec_fsm_master_action_next_slave_state(fsm);
00659 }
00660
00661
00662
00667 void ec_fsm_master_state_read_state(
00668 ec_fsm_master_t *fsm
00669 )
00670 {
00671 ec_slave_t *slave = fsm->slave;
00672 ec_datagram_t *datagram = fsm->datagram;
00673
00674 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
00675 return;
00676 }
00677
00678 if (datagram->state != EC_DATAGRAM_RECEIVED) {
00679 EC_SLAVE_ERR(slave, "Failed to receive AL state datagram: ");
00680 ec_datagram_print_state(datagram);
00681 ec_fsm_master_restart(fsm);
00682 return;
00683 }
00684
00685
00686 if (datagram->working_counter != 1) {
00687 if (!slave->error_flag) {
00688 slave->error_flag = 1;
00689 EC_SLAVE_DBG(slave, 1, "Slave did not respond to state query.\n");
00690 }
00691 fsm->rescan_required = 1;
00692 ec_fsm_master_restart(fsm);
00693 return;
00694 }
00695
00696
00697 ec_slave_set_state(slave, EC_READ_U8(datagram->data));
00698
00699 if (!slave->error_flag) {
00700
00701 if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
00702 fsm->idle = 0;
00703 fsm->state = ec_fsm_master_state_acknowledge;
00704 ec_fsm_change_ack(&fsm->fsm_change, slave);
00705 fsm->state(fsm);
00706 return;
00707 }
00708
00709
00710 ec_fsm_master_action_configure(fsm);
00711 return;
00712 }
00713
00714
00715 ec_fsm_master_action_next_slave_state(fsm);
00716 }
00717
00718
00719
00722 void ec_fsm_master_state_acknowledge(
00723 ec_fsm_master_t *fsm
00724 )
00725 {
00726 ec_slave_t *slave = fsm->slave;
00727
00728 if (ec_fsm_change_exec(&fsm->fsm_change)) {
00729 return;
00730 }
00731
00732 if (!ec_fsm_change_success(&fsm->fsm_change)) {
00733 fsm->slave->error_flag = 1;
00734 EC_SLAVE_ERR(slave, "Failed to acknowledge state change.\n");
00735 }
00736
00737 ec_fsm_master_action_configure(fsm);
00738 }
00739
00740
00741
00744 void ec_fsm_master_enter_clear_addresses(
00745 ec_fsm_master_t *fsm
00746 )
00747 {
00748
00749 ec_datagram_bwr(fsm->datagram, 0x0010, 2);
00750 EC_WRITE_U16(fsm->datagram->data, 0x0000);
00751 fsm->datagram->device_index = fsm->dev_idx;
00752 fsm->retries = EC_FSM_RETRIES;
00753 fsm->state = ec_fsm_master_state_clear_addresses;
00754 }
00755
00756
00757
00760 void ec_fsm_master_state_clear_addresses(
00761 ec_fsm_master_t *fsm
00762 )
00763 {
00764 ec_master_t *master = fsm->master;
00765 ec_datagram_t *datagram = fsm->datagram;
00766
00767 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
00768 return;
00769 }
00770
00771 if (datagram->state != EC_DATAGRAM_RECEIVED) {
00772 EC_MASTER_ERR(master, "Failed to receive address"
00773 " clearing datagram on %s link: ",
00774 ec_device_names[fsm->dev_idx != 0]);
00775 ec_datagram_print_state(datagram);
00776 master->scan_busy = 0;
00777 wake_up_interruptible(&master->scan_queue);
00778 ec_fsm_master_restart(fsm);
00779 return;
00780 }
00781
00782 if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) {
00783 EC_MASTER_WARN(master, "Failed to clear station addresses on %s link:"
00784 " Cleared %u of %u",
00785 ec_device_names[fsm->dev_idx != 0], datagram->working_counter,
00786 fsm->slaves_responding[fsm->dev_idx]);
00787 }
00788
00789 EC_MASTER_DBG(master, 1, "Sending broadcast-write"
00790 " to measure transmission delays on %s link.\n",
00791 ec_device_names[fsm->dev_idx != 0]);
00792
00793 ec_datagram_bwr(datagram, 0x0900, 1);
00794 ec_datagram_zero(datagram);
00795 fsm->datagram->device_index = fsm->dev_idx;
00796 fsm->retries = EC_FSM_RETRIES;
00797 fsm->state = ec_fsm_master_state_dc_measure_delays;
00798 }
00799
00800
00801
00804 void ec_fsm_master_state_dc_measure_delays(
00805 ec_fsm_master_t *fsm
00806 )
00807 {
00808 ec_master_t *master = fsm->master;
00809 ec_datagram_t *datagram = fsm->datagram;
00810
00811 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
00812 return;
00813 }
00814
00815 if (datagram->state != EC_DATAGRAM_RECEIVED) {
00816 EC_MASTER_ERR(master, "Failed to receive delay measuring datagram"
00817 " on %s link: ", ec_device_names[fsm->dev_idx != 0]);
00818 ec_datagram_print_state(datagram);
00819 master->scan_busy = 0;
00820 wake_up_interruptible(&master->scan_queue);
00821 ec_fsm_master_restart(fsm);
00822 return;
00823 }
00824
00825 EC_MASTER_DBG(master, 1, "%u slaves responded to delay measuring"
00826 " on %s link.\n",
00827 datagram->working_counter, ec_device_names[fsm->dev_idx != 0]);
00828
00829 do {
00830 fsm->dev_idx++;
00831 } while (fsm->dev_idx < ec_master_num_devices(master) &&
00832 !fsm->slaves_responding[fsm->dev_idx]);
00833 if (fsm->dev_idx < ec_master_num_devices(master)) {
00834 ec_fsm_master_enter_clear_addresses(fsm);
00835 return;
00836 }
00837
00838 EC_MASTER_INFO(master, "Scanning bus.\n");
00839
00840
00841 fsm->slave = master->slaves;
00842 EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n",
00843 fsm->slave->ring_position,
00844 ec_device_names[fsm->slave->device_index != 0]);
00845 fsm->state = ec_fsm_master_state_scan_slave;
00846 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave);
00847 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan);
00848 fsm->datagram->device_index = fsm->slave->device_index;
00849 }
00850
00851
00852
00857 void ec_fsm_master_state_scan_slave(
00858 ec_fsm_master_t *fsm
00859 )
00860 {
00861 ec_master_t *master = fsm->master;
00862 #ifdef EC_EOE
00863 ec_slave_t *slave = fsm->slave;
00864 #endif
00865
00866 if (ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan)) {
00867 return;
00868 }
00869
00870 #ifdef EC_EOE
00871 if (slave->sii.mailbox_protocols & EC_MBOX_EOE) {
00872
00873 ec_eoe_t *eoe;
00874 if (!(eoe = kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
00875 EC_SLAVE_ERR(slave, "Failed to allocate EoE handler memory!\n");
00876 } else if (ec_eoe_init(eoe, slave)) {
00877 EC_SLAVE_ERR(slave, "Failed to init EoE handler!\n");
00878 kfree(eoe);
00879 } else {
00880 list_add_tail(&eoe->list, &master->eoe_handlers);
00881 }
00882 }
00883 #endif
00884
00885
00886 fsm->slave++;
00887 if (fsm->slave < master->slaves + master->slave_count) {
00888 EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n",
00889 fsm->slave->ring_position,
00890 ec_device_names[fsm->slave->device_index != 0]);
00891 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave);
00892 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan);
00893 fsm->datagram->device_index = fsm->slave->device_index;
00894 return;
00895 }
00896
00897 EC_MASTER_INFO(master, "Bus scanning completed in %lu ms.\n",
00898 (jiffies - fsm->scan_jiffies) * 1000 / HZ);
00899
00900 master->scan_busy = 0;
00901 wake_up_interruptible(&master->scan_queue);
00902
00903 ec_master_calc_dc(master);
00904
00905
00906 ec_master_attach_slave_configs(master);
00907
00908 #ifdef EC_EOE
00909
00910 ec_master_eoe_start(master);
00911 #endif
00912
00913 if (master->slave_count) {
00914 master->config_changed = 0;
00915
00916 fsm->slave = master->slaves;
00917 ec_fsm_master_enter_write_system_times(fsm);
00918 } else {
00919 ec_fsm_master_restart(fsm);
00920 }
00921 }
00922
00923
00924
00929 void ec_fsm_master_state_configure_slave(
00930 ec_fsm_master_t *fsm
00931 )
00932 {
00933 ec_master_t *master = fsm->master;
00934
00935 if (ec_fsm_slave_config_exec(&fsm->fsm_slave_config)) {
00936 return;
00937 }
00938
00939 fsm->slave->force_config = 0;
00940
00941
00942 master->config_busy = 0;
00943 wake_up_interruptible(&master->config_queue);
00944
00945 if (!ec_fsm_slave_config_success(&fsm->fsm_slave_config)) {
00946
00947 }
00948
00949 fsm->idle = 1;
00950 ec_fsm_master_action_next_slave_state(fsm);
00951 }
00952
00953
00954
00957 void ec_fsm_master_enter_write_system_times(
00958 ec_fsm_master_t *fsm
00959 )
00960 {
00961 ec_master_t *master = fsm->master;
00962
00963 if (master->has_app_time) {
00964
00965 while (fsm->slave < master->slaves + master->slave_count) {
00966 if (!fsm->slave->base_dc_supported
00967 || !fsm->slave->has_dc_system_time) {
00968 fsm->slave++;
00969 continue;
00970 }
00971
00972 EC_SLAVE_DBG(fsm->slave, 1, "Checking system time offset.\n");
00973
00974
00975
00976
00977 ec_datagram_fprd(fsm->datagram, fsm->slave->station_address,
00978 0x0910, 24);
00979 fsm->datagram->device_index = fsm->slave->device_index;
00980 fsm->retries = EC_FSM_RETRIES;
00981 fsm->state = ec_fsm_master_state_dc_read_offset;
00982 return;
00983 }
00984
00985 } else {
00986 if (master->active) {
00987 EC_MASTER_WARN(master, "No app_time received up to now,"
00988 " but master already active.\n");
00989 } else {
00990 EC_MASTER_DBG(master, 1, "No app_time received up to now.\n");
00991 }
00992 }
00993
00994
00995 ec_master_request_op(master);
00996 ec_fsm_master_restart(fsm);
00997 }
00998
00999
01000
01005 u64 ec_fsm_master_dc_offset32(
01006 ec_fsm_master_t *fsm,
01007 u64 system_time,
01008 u64 old_offset,
01009 unsigned long jiffies_since_read
01010 )
01011 {
01012 ec_slave_t *slave = fsm->slave;
01013 u32 correction, system_time32, old_offset32, new_offset;
01014 s32 time_diff;
01015
01016 system_time32 = (u32) system_time;
01017 old_offset32 = (u32) old_offset;
01018
01019
01020 correction = jiffies_since_read * 1000 / HZ * 1000000;
01021 system_time32 += correction;
01022 time_diff = (u32) slave->master->app_time - system_time32;
01023
01024 EC_SLAVE_DBG(slave, 1, "DC 32 bit system time offset calculation:"
01025 " system_time=%u (corrected with %u),"
01026 " app_time=%llu, diff=%i\n",
01027 system_time32, correction,
01028 slave->master->app_time, time_diff);
01029
01030 if (EC_ABS(time_diff) > EC_SYSTEM_TIME_TOLERANCE_NS) {
01031 new_offset = time_diff + old_offset32;
01032 EC_SLAVE_DBG(slave, 1, "Setting time offset to %u (was %u)\n",
01033 new_offset, old_offset32);
01034 return (u64) new_offset;
01035 } else {
01036 EC_SLAVE_DBG(slave, 1, "Not touching time offset.\n");
01037 return old_offset;
01038 }
01039 }
01040
01041
01042
01047 u64 ec_fsm_master_dc_offset64(
01048 ec_fsm_master_t *fsm,
01049 u64 system_time,
01050 u64 old_offset,
01051 unsigned long jiffies_since_read
01052 )
01053 {
01054 ec_slave_t *slave = fsm->slave;
01055 u64 new_offset, correction;
01056 s64 time_diff;
01057
01058
01059 correction = (u64) (jiffies_since_read * 1000 / HZ) * 1000000;
01060 system_time += correction;
01061 time_diff = fsm->slave->master->app_time - system_time;
01062
01063 EC_SLAVE_DBG(slave, 1, "DC 64 bit system time offset calculation:"
01064 " system_time=%llu (corrected with %llu),"
01065 " app_time=%llu, diff=%lli\n",
01066 system_time, correction,
01067 slave->master->app_time, time_diff);
01068
01069 if (EC_ABS(time_diff) > EC_SYSTEM_TIME_TOLERANCE_NS) {
01070 new_offset = time_diff + old_offset;
01071 EC_SLAVE_DBG(slave, 1, "Setting time offset to %llu (was %llu)\n",
01072 new_offset, old_offset);
01073 } else {
01074 new_offset = old_offset;
01075 EC_SLAVE_DBG(slave, 1, "Not touching time offset.\n");
01076 }
01077
01078 return new_offset;
01079 }
01080
01081
01082
01085 void ec_fsm_master_state_dc_read_offset(
01086 ec_fsm_master_t *fsm
01087 )
01088 {
01089 ec_datagram_t *datagram = fsm->datagram;
01090 ec_slave_t *slave = fsm->slave;
01091 u64 system_time, old_offset, new_offset;
01092 unsigned long jiffies_since_read;
01093
01094 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
01095 return;
01096
01097 if (datagram->state != EC_DATAGRAM_RECEIVED) {
01098 EC_SLAVE_ERR(slave, "Failed to receive DC times datagram: ");
01099 ec_datagram_print_state(datagram);
01100 fsm->slave++;
01101 ec_fsm_master_enter_write_system_times(fsm);
01102 return;
01103 }
01104
01105 if (datagram->working_counter != 1) {
01106 EC_SLAVE_WARN(slave, "Failed to get DC times: ");
01107 ec_datagram_print_wc_error(datagram);
01108 fsm->slave++;
01109 ec_fsm_master_enter_write_system_times(fsm);
01110 return;
01111 }
01112
01113 system_time = EC_READ_U64(datagram->data);
01114 old_offset = EC_READ_U64(datagram->data + 16);
01115 jiffies_since_read = jiffies - datagram->jiffies_sent;
01116
01117 if (slave->base_dc_range == EC_DC_32) {
01118 new_offset = ec_fsm_master_dc_offset32(fsm,
01119 system_time, old_offset, jiffies_since_read);
01120 } else {
01121 new_offset = ec_fsm_master_dc_offset64(fsm,
01122 system_time, old_offset, jiffies_since_read);
01123 }
01124
01125
01126 ec_datagram_fpwr(datagram, slave->station_address, 0x0920, 12);
01127 EC_WRITE_U64(datagram->data, new_offset);
01128 EC_WRITE_U32(datagram->data + 8, slave->transmission_delay);
01129 fsm->datagram->device_index = slave->device_index;
01130 fsm->retries = EC_FSM_RETRIES;
01131 fsm->state = ec_fsm_master_state_dc_write_offset;
01132 }
01133
01134
01135
01138 void ec_fsm_master_state_dc_write_offset(
01139 ec_fsm_master_t *fsm
01140 )
01141 {
01142 ec_datagram_t *datagram = fsm->datagram;
01143 ec_slave_t *slave = fsm->slave;
01144
01145 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
01146 return;
01147
01148 if (datagram->state != EC_DATAGRAM_RECEIVED) {
01149 EC_SLAVE_ERR(slave,
01150 "Failed to receive DC system time offset datagram: ");
01151 ec_datagram_print_state(datagram);
01152 fsm->slave++;
01153 ec_fsm_master_enter_write_system_times(fsm);
01154 return;
01155 }
01156
01157 if (datagram->working_counter != 1) {
01158 EC_SLAVE_ERR(slave, "Failed to set DC system time offset: ");
01159 ec_datagram_print_wc_error(datagram);
01160 fsm->slave++;
01161 ec_fsm_master_enter_write_system_times(fsm);
01162 return;
01163 }
01164
01165 fsm->slave++;
01166 ec_fsm_master_enter_write_system_times(fsm);
01167 }
01168
01169
01170
01173 void ec_fsm_master_state_write_sii(
01174 ec_fsm_master_t *fsm
01175 )
01176 {
01177 ec_master_t *master = fsm->master;
01178 ec_sii_write_request_t *request = fsm->sii_request;
01179 ec_slave_t *slave = request->slave;
01180
01181 if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
01182
01183 if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
01184 EC_SLAVE_ERR(slave, "Failed to write SII data.\n");
01185 request->state = EC_INT_REQUEST_FAILURE;
01186 wake_up_all(&master->request_queue);
01187 ec_fsm_master_restart(fsm);
01188 return;
01189 }
01190
01191 fsm->sii_index++;
01192 if (fsm->sii_index < request->nwords) {
01193 ec_fsm_sii_write(&fsm->fsm_sii, slave,
01194 request->offset + fsm->sii_index,
01195 request->words + fsm->sii_index,
01196 EC_FSM_SII_USE_CONFIGURED_ADDRESS);
01197 ec_fsm_sii_exec(&fsm->fsm_sii);
01198 return;
01199 }
01200
01201
01202 EC_SLAVE_DBG(slave, 1, "Finished writing %zu words of SII data.\n",
01203 request->nwords);
01204
01205 if (request->offset <= 4 && request->offset + request->nwords > 4) {
01206
01207 slave->sii.alias = EC_READ_U16(request->words + 4);
01208
01209 slave->effective_alias = slave->sii.alias;
01210 }
01211
01212
01213 request->state = EC_INT_REQUEST_SUCCESS;
01214 wake_up_all(&master->request_queue);
01215
01216
01217 if (ec_fsm_master_action_process_sii(fsm))
01218 return;
01219
01220 ec_fsm_master_restart(fsm);
01221 }
01222
01223
01224
01227 void ec_fsm_master_state_sdo_dictionary(
01228 ec_fsm_master_t *fsm
01229 )
01230 {
01231 ec_slave_t *slave = fsm->slave;
01232 ec_master_t *master = fsm->master;
01233
01234 if (ec_fsm_coe_exec(&fsm->fsm_coe, fsm->datagram)) {
01235 return;
01236 }
01237
01238 if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
01239 ec_fsm_master_restart(fsm);
01240 return;
01241 }
01242
01243
01244
01245 if (master->debug_level) {
01246 unsigned int sdo_count, entry_count;
01247 ec_slave_sdo_dict_info(slave, &sdo_count, &entry_count);
01248 EC_SLAVE_DBG(slave, 1, "Fetched %u SDOs and %u entries.\n",
01249 sdo_count, entry_count);
01250 }
01251
01252
01253 ec_slave_attach_pdo_names(slave);
01254
01255 ec_fsm_master_restart(fsm);
01256 }
01257
01258
01259
01262 void ec_fsm_master_state_sdo_request(
01263 ec_fsm_master_t *fsm
01264 )
01265 {
01266 ec_sdo_request_t *request = fsm->sdo_request;
01267
01268 if (!request) {
01269
01270 ec_fsm_master_restart(fsm);
01271 return;
01272 }
01273
01274 if (ec_fsm_coe_exec(&fsm->fsm_coe, fsm->datagram)) {
01275 return;
01276 }
01277
01278 if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
01279 EC_SLAVE_DBG(fsm->slave, 1,
01280 "Failed to process internal SDO request.\n");
01281 request->state = EC_INT_REQUEST_FAILURE;
01282 wake_up_all(&fsm->master->request_queue);
01283 ec_fsm_master_restart(fsm);
01284 return;
01285 }
01286
01287
01288 request->state = EC_INT_REQUEST_SUCCESS;
01289 wake_up_all(&fsm->master->request_queue);
01290
01291 EC_SLAVE_DBG(fsm->slave, 1, "Finished internal SDO request.\n");
01292
01293
01294 if (ec_fsm_master_action_process_sdo(fsm)) {
01295 return;
01296 }
01297
01298 ec_fsm_master_restart(fsm);
01299 }
01300
01301