changeset 409 | bc4c852e1b93 |
parent 407 | b73c9f7be5a1 |
child 411 | 42d239bab6ae |
408:0eda82d1a8c1 | 409:bc4c852e1b93 |
---|---|
71 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *); |
71 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *); |
72 |
72 |
73 void ec_fsm_slaveconf_init(ec_fsm_t *); |
73 void ec_fsm_slaveconf_init(ec_fsm_t *); |
74 void ec_fsm_slaveconf_sync(ec_fsm_t *); |
74 void ec_fsm_slaveconf_sync(ec_fsm_t *); |
75 void ec_fsm_slaveconf_preop(ec_fsm_t *); |
75 void ec_fsm_slaveconf_preop(ec_fsm_t *); |
76 void ec_fsm_slaveconf_sdodict(ec_fsm_t *); |
|
77 void ec_fsm_slaveconf_sdoconf(ec_fsm_t *); |
|
76 void ec_fsm_slaveconf_fmmu(ec_fsm_t *); |
78 void ec_fsm_slaveconf_fmmu(ec_fsm_t *); |
77 void ec_fsm_slaveconf_sdoconf(ec_fsm_t *); |
|
78 void ec_fsm_slaveconf_saveop(ec_fsm_t *); |
79 void ec_fsm_slaveconf_saveop(ec_fsm_t *); |
79 void ec_fsm_slaveconf_op(ec_fsm_t *); |
80 void ec_fsm_slaveconf_op(ec_fsm_t *); |
80 |
81 |
81 void ec_fsm_sii_start_reading(ec_fsm_t *); |
82 void ec_fsm_sii_start_reading(ec_fsm_t *); |
82 void ec_fsm_sii_read_check(ec_fsm_t *); |
83 void ec_fsm_sii_read_check(ec_fsm_t *); |
89 void ec_fsm_change_check(ec_fsm_t *); |
90 void ec_fsm_change_check(ec_fsm_t *); |
90 void ec_fsm_change_status(ec_fsm_t *); |
91 void ec_fsm_change_status(ec_fsm_t *); |
91 void ec_fsm_change_code(ec_fsm_t *); |
92 void ec_fsm_change_code(ec_fsm_t *); |
92 void ec_fsm_change_ack(ec_fsm_t *); |
93 void ec_fsm_change_ack(ec_fsm_t *); |
93 void ec_fsm_change_check_ack(ec_fsm_t *); |
94 void ec_fsm_change_check_ack(ec_fsm_t *); |
95 |
|
96 void ec_fsm_coe_dict_start(ec_fsm_t *); |
|
97 void ec_fsm_coe_dict_request(ec_fsm_t *); |
|
98 void ec_fsm_coe_dict_check(ec_fsm_t *); |
|
99 void ec_fsm_coe_dict_response(ec_fsm_t *); |
|
100 void ec_fsm_coe_dict_desc_request(ec_fsm_t *); |
|
101 void ec_fsm_coe_dict_desc_check(ec_fsm_t *); |
|
102 void ec_fsm_coe_dict_desc_response(ec_fsm_t *); |
|
103 void ec_fsm_coe_dict_entry_request(ec_fsm_t *); |
|
104 void ec_fsm_coe_dict_entry_check(ec_fsm_t *); |
|
105 void ec_fsm_coe_dict_entry_response(ec_fsm_t *); |
|
94 |
106 |
95 void ec_fsm_coe_down_start(ec_fsm_t *); |
107 void ec_fsm_coe_down_start(ec_fsm_t *); |
96 void ec_fsm_coe_down_request(ec_fsm_t *); |
108 void ec_fsm_coe_down_request(ec_fsm_t *); |
97 void ec_fsm_coe_down_check(ec_fsm_t *); |
109 void ec_fsm_coe_down_check(ec_fsm_t *); |
98 void ec_fsm_coe_down_response(ec_fsm_t *); |
110 void ec_fsm_coe_down_response(ec_fsm_t *); |
659 } |
671 } |
660 |
672 |
661 /*****************************************************************************/ |
673 /*****************************************************************************/ |
662 |
674 |
663 /** |
675 /** |
664 Master state: STATES. |
676 Master state: READ STATES. |
665 Fetches the AL- and online state of a slave. |
677 Fetches the AL- and online state of a slave. |
666 */ |
678 */ |
667 |
679 |
668 void ec_fsm_master_read_states(ec_fsm_t *fsm /**< finite state machine */) |
680 void ec_fsm_master_read_states(ec_fsm_t *fsm /**< finite state machine */) |
669 { |
681 { |
830 } |
842 } |
831 |
843 |
832 /*****************************************************************************/ |
844 /*****************************************************************************/ |
833 |
845 |
834 /** |
846 /** |
835 Master state: ADDRESS. |
847 Master state: REWRITE ADDRESS. |
836 Checks, if the new station address has been written to the slave. |
848 Checks, if the new station address has been written to the slave. |
837 */ |
849 */ |
838 |
850 |
839 void ec_fsm_master_rewrite_addresses(ec_fsm_t *fsm |
851 void ec_fsm_master_rewrite_addresses(ec_fsm_t *fsm |
840 /**< finite state machine */ |
852 /**< finite state machine */ |
862 } |
874 } |
863 |
875 |
864 /*****************************************************************************/ |
876 /*****************************************************************************/ |
865 |
877 |
866 /** |
878 /** |
867 Master state: SCAN. |
879 Master state: SCAN SLAVES. |
868 Executes the sub-statemachine for the scanning of a slave. |
880 Executes the sub-statemachine for the scanning of a slave. |
869 */ |
881 */ |
870 |
882 |
871 void ec_fsm_master_scan_slaves(ec_fsm_t *fsm /**< finite state machine */) |
883 void ec_fsm_master_scan_slaves(ec_fsm_t *fsm /**< finite state machine */) |
872 { |
884 { |
909 } |
921 } |
910 |
922 |
911 /*****************************************************************************/ |
923 /*****************************************************************************/ |
912 |
924 |
913 /** |
925 /** |
914 Master state: CONF. |
926 Master state: CONFIGURE SLAVES. |
915 Starts configuring a slave. |
927 Starts configuring a slave. |
916 */ |
928 */ |
917 |
929 |
918 void ec_fsm_master_configure_slave(ec_fsm_t *fsm |
930 void ec_fsm_master_configure_slave(ec_fsm_t *fsm |
919 /**< finite state machine */ |
931 /**< finite state machine */ |
928 } |
940 } |
929 |
941 |
930 /*****************************************************************************/ |
942 /*****************************************************************************/ |
931 |
943 |
932 /** |
944 /** |
933 Master state: EEPROM. |
945 Master state: WRITE EEPROM. |
934 */ |
946 */ |
935 |
947 |
936 void ec_fsm_master_write_eeprom(ec_fsm_t *fsm /**< finite state machine */) |
948 void ec_fsm_master_write_eeprom(ec_fsm_t *fsm /**< finite state machine */) |
937 { |
949 { |
938 ec_slave_t *slave = fsm->slave; |
950 ec_slave_t *slave = fsm->slave; |
976 /****************************************************************************** |
988 /****************************************************************************** |
977 * slave scan state machine |
989 * slave scan state machine |
978 *****************************************************************************/ |
990 *****************************************************************************/ |
979 |
991 |
980 /** |
992 /** |
981 Slave state: START_READING. |
993 Slave scan state: START. |
982 First state of the slave state machine. Writes the station address to the |
994 First state of the slave state machine. Writes the station address to the |
983 slave, according to its ring position. |
995 slave, according to its ring position. |
984 */ |
996 */ |
985 |
997 |
986 void ec_fsm_slavescan_start(ec_fsm_t *fsm /**< finite state machine */) |
998 void ec_fsm_slavescan_start(ec_fsm_t *fsm /**< finite state machine */) |
995 } |
1007 } |
996 |
1008 |
997 /*****************************************************************************/ |
1009 /*****************************************************************************/ |
998 |
1010 |
999 /** |
1011 /** |
1000 Slave state: ADDRESS. |
1012 Slave scan state: ADDRESS. |
1001 */ |
1013 */ |
1002 |
1014 |
1003 void ec_fsm_slavescan_address(ec_fsm_t *fsm /**< finite state machine */) |
1015 void ec_fsm_slavescan_address(ec_fsm_t *fsm /**< finite state machine */) |
1004 { |
1016 { |
1005 ec_datagram_t *datagram = &fsm->datagram; |
1017 ec_datagram_t *datagram = &fsm->datagram; |
1020 } |
1032 } |
1021 |
1033 |
1022 /*****************************************************************************/ |
1034 /*****************************************************************************/ |
1023 |
1035 |
1024 /** |
1036 /** |
1025 Slave state: STATE. |
1037 Slave scan state: STATE. |
1026 */ |
1038 */ |
1027 |
1039 |
1028 void ec_fsm_slavescan_state(ec_fsm_t *fsm /**< finite state machine */) |
1040 void ec_fsm_slavescan_state(ec_fsm_t *fsm /**< finite state machine */) |
1029 { |
1041 { |
1030 ec_datagram_t *datagram = &fsm->datagram; |
1042 ec_datagram_t *datagram = &fsm->datagram; |
1052 } |
1064 } |
1053 |
1065 |
1054 /*****************************************************************************/ |
1066 /*****************************************************************************/ |
1055 |
1067 |
1056 /** |
1068 /** |
1057 Slave state: BASE. |
1069 Slave scan state: BASE. |
1058 */ |
1070 */ |
1059 |
1071 |
1060 void ec_fsm_slavescan_base(ec_fsm_t *fsm /**< finite state machine */) |
1072 void ec_fsm_slavescan_base(ec_fsm_t *fsm /**< finite state machine */) |
1061 { |
1073 { |
1062 ec_datagram_t *datagram = &fsm->datagram; |
1074 ec_datagram_t *datagram = &fsm->datagram; |
1087 } |
1099 } |
1088 |
1100 |
1089 /*****************************************************************************/ |
1101 /*****************************************************************************/ |
1090 |
1102 |
1091 /** |
1103 /** |
1092 Slave state: DATALINK. |
1104 Slave scan state: DATALINK. |
1093 */ |
1105 */ |
1094 |
1106 |
1095 void ec_fsm_slavescan_datalink(ec_fsm_t *fsm /**< finite state machine */) |
1107 void ec_fsm_slavescan_datalink(ec_fsm_t *fsm /**< finite state machine */) |
1096 { |
1108 { |
1097 ec_datagram_t *datagram = &fsm->datagram; |
1109 ec_datagram_t *datagram = &fsm->datagram; |
1125 } |
1137 } |
1126 |
1138 |
1127 /*****************************************************************************/ |
1139 /*****************************************************************************/ |
1128 |
1140 |
1129 /** |
1141 /** |
1130 Slave state: EEPROM_SIZE. |
1142 Slave scan state: EEPROM SIZE. |
1131 */ |
1143 */ |
1132 |
1144 |
1133 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *fsm /**< finite state machine */) |
1145 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *fsm /**< finite state machine */) |
1134 { |
1146 { |
1135 ec_slave_t *slave = fsm->slave; |
1147 ec_slave_t *slave = fsm->slave; |
1185 } |
1197 } |
1186 |
1198 |
1187 /*****************************************************************************/ |
1199 /*****************************************************************************/ |
1188 |
1200 |
1189 /** |
1201 /** |
1190 Slave state: EEPROM_DATA. |
1202 Slave scan state: EEPROM DATA. |
1191 */ |
1203 */ |
1192 |
1204 |
1193 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *fsm /**< finite state machine */) |
1205 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *fsm /**< finite state machine */) |
1194 { |
1206 { |
1195 ec_slave_t *slave = fsm->slave; |
1207 ec_slave_t *slave = fsm->slave; |
1299 /****************************************************************************** |
1311 /****************************************************************************** |
1300 * slave configuration state machine |
1312 * slave configuration state machine |
1301 *****************************************************************************/ |
1313 *****************************************************************************/ |
1302 |
1314 |
1303 /** |
1315 /** |
1304 Slave state: INIT. |
1316 Slave configuration state: INIT. |
1305 */ |
1317 */ |
1306 |
1318 |
1307 void ec_fsm_slaveconf_init(ec_fsm_t *fsm /**< finite state machine */) |
1319 void ec_fsm_slaveconf_init(ec_fsm_t *fsm /**< finite state machine */) |
1308 { |
1320 { |
1321 ec_master_t *master = fsm->master; |
|
1309 ec_slave_t *slave = fsm->slave; |
1322 ec_slave_t *slave = fsm->slave; |
1310 ec_datagram_t *datagram = &fsm->datagram; |
1323 ec_datagram_t *datagram = &fsm->datagram; |
1311 const ec_sii_sync_t *sync; |
1324 const ec_sii_sync_t *sync; |
1312 |
1325 |
1313 fsm->change_state(fsm); // execute state change state machine |
1326 fsm->change_state(fsm); // execute state change state machine |
1318 return; |
1331 return; |
1319 } |
1332 } |
1320 |
1333 |
1321 if (fsm->change_state != ec_fsm_end) return; |
1334 if (fsm->change_state != ec_fsm_end) return; |
1322 |
1335 |
1336 if (master->debug_level) { |
|
1337 EC_DBG("Slave %i is now in INIT.\n", slave->ring_position); |
|
1338 } |
|
1339 |
|
1323 // slave is now in INIT |
1340 // slave is now in INIT |
1324 if (slave->current_state == slave->requested_state) { |
1341 if (slave->current_state == slave->requested_state) { |
1325 fsm->slave_state = ec_fsm_end; // successful |
1342 fsm->slave_state = ec_fsm_end; // successful |
1343 if (master->debug_level) { |
|
1344 EC_DBG("Finished configuration of slave %i.\n", |
|
1345 slave->ring_position); |
|
1346 } |
|
1326 return; |
1347 return; |
1327 } |
1348 } |
1328 |
1349 |
1329 // check and reset CRC fault counters |
1350 // check and reset CRC fault counters |
1330 //ec_slave_check_crc(slave); |
1351 //ec_slave_check_crc(slave); |
1334 fsm->slave_state = ec_fsm_slaveconf_preop; |
1355 fsm->slave_state = ec_fsm_slaveconf_preop; |
1335 fsm->change_new = EC_SLAVE_STATE_PREOP; |
1356 fsm->change_new = EC_SLAVE_STATE_PREOP; |
1336 fsm->change_state = ec_fsm_change_start; |
1357 fsm->change_state = ec_fsm_change_start; |
1337 fsm->change_state(fsm); // execute immediately |
1358 fsm->change_state(fsm); // execute immediately |
1338 return; |
1359 return; |
1360 } |
|
1361 |
|
1362 if (master->debug_level) { |
|
1363 EC_DBG("Configuring sync managers of slave %i.\n", |
|
1364 slave->ring_position); |
|
1339 } |
1365 } |
1340 |
1366 |
1341 // configure sync managers |
1367 // configure sync managers |
1342 ec_datagram_npwr(datagram, slave->station_address, 0x0800, |
1368 ec_datagram_npwr(datagram, slave->station_address, 0x0800, |
1343 EC_SYNC_SIZE * slave->base_sync_count); |
1369 EC_SYNC_SIZE * slave->base_sync_count); |
1359 } |
1385 } |
1360 |
1386 |
1361 /*****************************************************************************/ |
1387 /*****************************************************************************/ |
1362 |
1388 |
1363 /** |
1389 /** |
1364 Slave state: SYNC. |
1390 Slave configuration state: SYNC. |
1365 */ |
1391 */ |
1366 |
1392 |
1367 void ec_fsm_slaveconf_sync(ec_fsm_t *fsm /**< finite state machine */) |
1393 void ec_fsm_slaveconf_sync(ec_fsm_t *fsm /**< finite state machine */) |
1368 { |
1394 { |
1369 ec_datagram_t *datagram = &fsm->datagram; |
1395 ec_datagram_t *datagram = &fsm->datagram; |
1385 } |
1411 } |
1386 |
1412 |
1387 /*****************************************************************************/ |
1413 /*****************************************************************************/ |
1388 |
1414 |
1389 /** |
1415 /** |
1390 Slave state: PREOP. |
1416 Slave configuration state: PREOP. |
1391 */ |
1417 */ |
1392 |
1418 |
1393 void ec_fsm_slaveconf_preop(ec_fsm_t *fsm /**< finite state machine */) |
1419 void ec_fsm_slaveconf_preop(ec_fsm_t *fsm /**< finite state machine */) |
1394 { |
1420 { |
1395 ec_slave_t *slave = fsm->slave; |
1421 ec_slave_t *slave = fsm->slave; |
1406 } |
1432 } |
1407 |
1433 |
1408 if (fsm->change_state != ec_fsm_end) return; |
1434 if (fsm->change_state != ec_fsm_end) return; |
1409 |
1435 |
1410 // slave is now in PREOP |
1436 // slave is now in PREOP |
1411 if (slave->current_state == slave->requested_state) { |
1437 |
1412 fsm->slave_state = ec_fsm_end; // successful |
1438 if (master->debug_level) { |
1413 return; |
1439 EC_DBG("Slave %i is now in PREOP.\n", slave->ring_position); |
1414 } |
1440 } |
1415 |
1441 |
1416 if (!slave->base_fmmu_count) { // skip FMMU configuration |
1442 if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) { |
1417 if (list_empty(&slave->sdo_confs)) { // skip SDO configuration |
1443 // slave does not support CoE. skip dictionary fetching |
1444 // and SDO configuration |
|
1445 |
|
1446 if (slave->current_state == slave->requested_state) { |
|
1447 fsm->slave_state = ec_fsm_end; // successful |
|
1448 if (master->debug_level) { |
|
1449 EC_DBG("Finished configuration of slave %i.\n", |
|
1450 slave->ring_position); |
|
1451 } |
|
1452 return; |
|
1453 } |
|
1454 |
|
1455 if (!slave->base_fmmu_count) { |
|
1456 // slave has no FMMUs. skip configuration and go to SAVEOP |
|
1418 fsm->slave_state = ec_fsm_slaveconf_saveop; |
1457 fsm->slave_state = ec_fsm_slaveconf_saveop; |
1419 fsm->change_new = EC_SLAVE_STATE_SAVEOP; |
1458 fsm->change_new = EC_SLAVE_STATE_SAVEOP; |
1420 fsm->change_state = ec_fsm_change_start; |
1459 fsm->change_state = ec_fsm_change_start; |
1421 fsm->change_state(fsm); // execute immediately |
1460 fsm->change_state(fsm); // execute immediately |
1422 return; |
1461 return; |
1423 } |
1462 } |
1463 |
|
1464 // configure FMMUs |
|
1465 ec_datagram_npwr(datagram, slave->station_address, |
|
1466 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count); |
|
1467 memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); |
|
1468 for (j = 0; j < slave->fmmu_count; j++) { |
|
1469 ec_fmmu_config(&slave->fmmus[j], slave, |
|
1470 datagram->data + EC_FMMU_SIZE * j); |
|
1471 } |
|
1472 |
|
1473 ec_master_queue_datagram(master, datagram); |
|
1474 fsm->slave_state = ec_fsm_slaveconf_fmmu; |
|
1475 return; |
|
1476 } |
|
1477 |
|
1478 if (!list_empty(&slave->sdo_dictionary)) { |
|
1479 // SDO dictionary already fetched |
|
1480 |
|
1481 if (master->debug_level) { |
|
1482 EC_DBG("SDO dictionary already present for slave %i.\n", |
|
1483 slave->ring_position); |
|
1484 } |
|
1485 |
|
1486 if (slave->current_state == slave->requested_state) { |
|
1487 fsm->slave_state = ec_fsm_end; // successful |
|
1488 if (master->debug_level) { |
|
1489 EC_DBG("Finished configuration of slave %i.\n", |
|
1490 slave->ring_position); |
|
1491 } |
|
1492 return; |
|
1493 } |
|
1494 |
|
1495 if (list_empty(&slave->sdo_confs)) { |
|
1496 // skip SDO configuration |
|
1497 |
|
1498 if (!slave->base_fmmu_count) { |
|
1499 // slave has no FMMUs. skip configuration and go to SAVEOP |
|
1500 fsm->slave_state = ec_fsm_slaveconf_saveop; |
|
1501 fsm->change_new = EC_SLAVE_STATE_SAVEOP; |
|
1502 fsm->change_state = ec_fsm_change_start; |
|
1503 fsm->change_state(fsm); // execute immediately |
|
1504 return; |
|
1505 } |
|
1506 |
|
1507 // configure FMMUs |
|
1508 ec_datagram_npwr(datagram, slave->station_address, |
|
1509 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count); |
|
1510 memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); |
|
1511 for (j = 0; j < slave->fmmu_count; j++) { |
|
1512 ec_fmmu_config(&slave->fmmus[j], slave, |
|
1513 datagram->data + EC_FMMU_SIZE * j); |
|
1514 } |
|
1515 |
|
1516 ec_master_queue_datagram(master, datagram); |
|
1517 fsm->slave_state = ec_fsm_slaveconf_fmmu; |
|
1518 return; |
|
1519 } |
|
1520 |
|
1521 // start SDO configuration |
|
1424 fsm->slave_state = ec_fsm_slaveconf_sdoconf; |
1522 fsm->slave_state = ec_fsm_slaveconf_sdoconf; |
1425 fsm->coe_sdodata = list_entry(slave->sdo_confs.next, ec_sdo_data_t, list); |
1523 fsm->coe_sdodata = list_entry(slave->sdo_confs.next, ec_sdo_data_t, list); |
1426 fsm->coe_state = ec_fsm_coe_down_start; |
1524 fsm->coe_state = ec_fsm_coe_down_start; |
1427 fsm->coe_state(fsm); // execute immediately |
1525 fsm->coe_state(fsm); // execute immediately |
1526 return; |
|
1527 } |
|
1528 |
|
1529 if (master->debug_level) { |
|
1530 EC_DBG("Fetching SDO dictionary of slave %i.\n", |
|
1531 slave->ring_position); |
|
1532 } |
|
1533 |
|
1534 // start fetching SDO dictionary |
|
1535 fsm->slave_state = ec_fsm_slaveconf_sdodict; |
|
1536 fsm->coe_state = ec_fsm_coe_dict_start; |
|
1537 fsm->coe_state(fsm); // execute immediately |
|
1538 } |
|
1539 |
|
1540 /*****************************************************************************/ |
|
1541 |
|
1542 /** |
|
1543 Slave configuration state: SDODICT. |
|
1544 */ |
|
1545 |
|
1546 void ec_fsm_slaveconf_sdodict(ec_fsm_t *fsm /**< finite state machine */) |
|
1547 { |
|
1548 ec_slave_t *slave = fsm->slave; |
|
1549 ec_datagram_t *datagram = &fsm->datagram; |
|
1550 ec_master_t *master = fsm->master; |
|
1551 unsigned int j; |
|
1552 |
|
1553 fsm->coe_state(fsm); // execute CoE state machine |
|
1554 |
|
1555 if (fsm->coe_state == ec_fsm_error) { |
|
1556 fsm->slave->error_flag = 1; |
|
1557 fsm->slave_state = ec_fsm_error; |
|
1558 return; |
|
1559 } |
|
1560 |
|
1561 if (fsm->coe_state != ec_fsm_end) return; |
|
1562 |
|
1563 // SDO dictionary fetching finished |
|
1564 |
|
1565 if (master->debug_level) { |
|
1566 EC_DBG("Finished fetching SDO dictionary of slave %i.\n", |
|
1567 slave->ring_position); |
|
1568 } |
|
1569 |
|
1570 if (slave->current_state == slave->requested_state) { |
|
1571 fsm->slave_state = ec_fsm_end; // successful |
|
1572 if (master->debug_level) { |
|
1573 EC_DBG("Finished configuration of slave %i.\n", |
|
1574 slave->ring_position); |
|
1575 } |
|
1576 return; |
|
1577 } |
|
1578 |
|
1579 if (list_empty(&slave->sdo_confs)) { |
|
1580 // skip SDO configuration |
|
1581 |
|
1582 if (!slave->base_fmmu_count) { |
|
1583 // slave has no FMMUs. skip configuration. |
|
1584 |
|
1585 // set state to SAVEOP |
|
1586 fsm->slave_state = ec_fsm_slaveconf_saveop; |
|
1587 fsm->change_new = EC_SLAVE_STATE_SAVEOP; |
|
1588 fsm->change_state = ec_fsm_change_start; |
|
1589 fsm->change_state(fsm); // execute immediately |
|
1590 return; |
|
1591 } |
|
1592 |
|
1593 // configure FMMUs |
|
1594 ec_datagram_npwr(datagram, slave->station_address, |
|
1595 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count); |
|
1596 memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); |
|
1597 for (j = 0; j < slave->fmmu_count; j++) { |
|
1598 ec_fmmu_config(&slave->fmmus[j], slave, |
|
1599 datagram->data + EC_FMMU_SIZE * j); |
|
1600 } |
|
1601 |
|
1602 ec_master_queue_datagram(master, datagram); |
|
1603 fsm->slave_state = ec_fsm_slaveconf_fmmu; |
|
1604 return; |
|
1605 } |
|
1606 |
|
1607 // start SDO configuration |
|
1608 fsm->slave_state = ec_fsm_slaveconf_sdoconf; |
|
1609 fsm->coe_sdodata = list_entry(slave->sdo_confs.next, ec_sdo_data_t, list); |
|
1610 fsm->coe_state = ec_fsm_coe_down_start; |
|
1611 fsm->coe_state(fsm); // execute immediately |
|
1612 } |
|
1613 |
|
1614 /*****************************************************************************/ |
|
1615 |
|
1616 /** |
|
1617 Slave configuration state: SDOCONF. |
|
1618 */ |
|
1619 |
|
1620 void ec_fsm_slaveconf_sdoconf(ec_fsm_t *fsm /**< finite state machine */) |
|
1621 { |
|
1622 ec_slave_t *slave = fsm->slave; |
|
1623 ec_datagram_t *datagram = &fsm->datagram; |
|
1624 ec_master_t *master = fsm->master; |
|
1625 unsigned int j; |
|
1626 |
|
1627 fsm->coe_state(fsm); // execute CoE state machine |
|
1628 |
|
1629 if (fsm->coe_state == ec_fsm_error) { |
|
1630 fsm->slave->error_flag = 1; |
|
1631 fsm->slave_state = ec_fsm_error; |
|
1632 return; |
|
1633 } |
|
1634 |
|
1635 if (fsm->coe_state != ec_fsm_end) return; |
|
1636 |
|
1637 // Another SDO to configure? |
|
1638 if (fsm->coe_sdodata->list.next != &fsm->slave->sdo_confs) { |
|
1639 fsm->coe_sdodata = list_entry(fsm->coe_sdodata->list.next, |
|
1640 ec_sdo_data_t, list); |
|
1641 fsm->coe_state = ec_fsm_coe_down_start; |
|
1642 fsm->coe_state(fsm); // execute immediately |
|
1643 return; |
|
1644 } |
|
1645 |
|
1646 // All SDOs are now configured. |
|
1647 |
|
1648 if (!slave->base_fmmu_count) { |
|
1649 // slave has no FMMUs. skip configuration. |
|
1650 |
|
1651 // set state to SAVEOP |
|
1652 fsm->slave_state = ec_fsm_slaveconf_saveop; |
|
1653 fsm->change_new = EC_SLAVE_STATE_SAVEOP; |
|
1654 fsm->change_state = ec_fsm_change_start; |
|
1655 fsm->change_state(fsm); // execute immediately |
|
1428 return; |
1656 return; |
1429 } |
1657 } |
1430 |
1658 |
1431 // configure FMMUs |
1659 // configure FMMUs |
1432 ec_datagram_npwr(datagram, slave->station_address, |
1660 ec_datagram_npwr(datagram, slave->station_address, |
1442 } |
1670 } |
1443 |
1671 |
1444 /*****************************************************************************/ |
1672 /*****************************************************************************/ |
1445 |
1673 |
1446 /** |
1674 /** |
1447 Slave state: FMMU. |
1675 Slave configuration state: FMMU. |
1448 */ |
1676 */ |
1449 |
1677 |
1450 void ec_fsm_slaveconf_fmmu(ec_fsm_t *fsm /**< finite state machine */) |
1678 void ec_fsm_slaveconf_fmmu(ec_fsm_t *fsm /**< finite state machine */) |
1451 { |
1679 { |
1452 ec_datagram_t *datagram = &fsm->datagram; |
1680 ec_datagram_t *datagram = &fsm->datagram; |
1453 ec_slave_t *slave = fsm->slave; |
|
1454 |
1681 |
1455 if (datagram->state != EC_DATAGRAM_RECEIVED |
1682 if (datagram->state != EC_DATAGRAM_RECEIVED |
1456 || datagram->working_counter != 1) { |
1683 || datagram->working_counter != 1) { |
1457 fsm->slave->error_flag = 1; |
1684 fsm->slave->error_flag = 1; |
1458 fsm->slave_state = ec_fsm_error; |
1685 fsm->slave_state = ec_fsm_error; |
1459 EC_ERR("Failed to set FMMUs on slave %i.\n", |
1686 EC_ERR("Failed to set FMMUs on slave %i.\n", |
1460 fsm->slave->ring_position); |
1687 fsm->slave->ring_position); |
1461 return; |
1688 return; |
1462 } |
1689 } |
1463 |
1690 |
1464 // No CoE configuration to be applied? Jump to SAVEOP state. |
|
1465 if (list_empty(&slave->sdo_confs)) { // skip SDO configuration |
|
1466 // set state to SAVEOP |
|
1467 fsm->slave_state = ec_fsm_slaveconf_saveop; |
|
1468 fsm->change_new = EC_SLAVE_STATE_SAVEOP; |
|
1469 fsm->change_state = ec_fsm_change_start; |
|
1470 fsm->change_state(fsm); // execute immediately |
|
1471 return; |
|
1472 } |
|
1473 |
|
1474 fsm->slave_state = ec_fsm_slaveconf_sdoconf; |
|
1475 fsm->coe_sdodata = list_entry(slave->sdo_confs.next, ec_sdo_data_t, list); |
|
1476 fsm->coe_state = ec_fsm_coe_down_start; |
|
1477 fsm->coe_state(fsm); // execute immediately |
|
1478 } |
|
1479 |
|
1480 /*****************************************************************************/ |
|
1481 |
|
1482 /** |
|
1483 Slave state: SDOCONF. |
|
1484 */ |
|
1485 |
|
1486 void ec_fsm_slaveconf_sdoconf(ec_fsm_t *fsm /**< finite state machine */) |
|
1487 { |
|
1488 fsm->coe_state(fsm); // execute CoE state machine |
|
1489 |
|
1490 if (fsm->coe_state == ec_fsm_error) { |
|
1491 fsm->slave->error_flag = 1; |
|
1492 fsm->slave_state = ec_fsm_error; |
|
1493 return; |
|
1494 } |
|
1495 |
|
1496 if (fsm->coe_state != ec_fsm_end) return; |
|
1497 |
|
1498 // Another SDO to configure? |
|
1499 if (fsm->coe_sdodata->list.next != &fsm->slave->sdo_confs) { |
|
1500 fsm->coe_sdodata = list_entry(fsm->coe_sdodata->list.next, |
|
1501 ec_sdo_data_t, list); |
|
1502 fsm->coe_state = ec_fsm_coe_down_start; |
|
1503 fsm->coe_state(fsm); // execute immediately |
|
1504 return; |
|
1505 } |
|
1506 |
|
1507 // All SDOs are now configured. |
|
1508 |
|
1509 // set state to SAVEOP |
1691 // set state to SAVEOP |
1510 fsm->slave_state = ec_fsm_slaveconf_saveop; |
1692 fsm->slave_state = ec_fsm_slaveconf_saveop; |
1511 fsm->change_new = EC_SLAVE_STATE_SAVEOP; |
1693 fsm->change_new = EC_SLAVE_STATE_SAVEOP; |
1512 fsm->change_state = ec_fsm_change_start; |
1694 fsm->change_state = ec_fsm_change_start; |
1513 fsm->change_state(fsm); // execute immediately |
1695 fsm->change_state(fsm); // execute immediately |
1514 } |
1696 } |
1515 |
1697 |
1516 /*****************************************************************************/ |
1698 /*****************************************************************************/ |
1517 |
1699 |
1518 /** |
1700 /** |
1519 Slave state: SAVEOP. |
1701 Slave configuration state: SAVEOP. |
1520 */ |
1702 */ |
1521 |
1703 |
1522 void ec_fsm_slaveconf_saveop(ec_fsm_t *fsm /**< finite state machine */) |
1704 void ec_fsm_slaveconf_saveop(ec_fsm_t *fsm /**< finite state machine */) |
1523 { |
1705 { |
1706 ec_master_t *master = fsm->master; |
|
1707 ec_slave_t *slave = fsm->slave; |
|
1708 |
|
1524 fsm->change_state(fsm); // execute state change state machine |
1709 fsm->change_state(fsm); // execute state change state machine |
1525 |
1710 |
1526 if (fsm->change_state == ec_fsm_error) { |
1711 if (fsm->change_state == ec_fsm_error) { |
1527 fsm->slave->error_flag = 1; |
1712 fsm->slave->error_flag = 1; |
1528 fsm->slave_state = ec_fsm_error; |
1713 fsm->slave_state = ec_fsm_error; |
1530 } |
1715 } |
1531 |
1716 |
1532 if (fsm->change_state != ec_fsm_end) return; |
1717 if (fsm->change_state != ec_fsm_end) return; |
1533 |
1718 |
1534 // slave is now in SAVEOP |
1719 // slave is now in SAVEOP |
1720 |
|
1721 if (master->debug_level) { |
|
1722 EC_DBG("Slave %i is now in PREOP.\n", slave->ring_position); |
|
1723 } |
|
1724 |
|
1535 if (fsm->slave->current_state == fsm->slave->requested_state) { |
1725 if (fsm->slave->current_state == fsm->slave->requested_state) { |
1536 fsm->slave_state = ec_fsm_end; // successful |
1726 fsm->slave_state = ec_fsm_end; // successful |
1727 if (master->debug_level) { |
|
1728 EC_DBG("Finished configuration of slave %i.\n", |
|
1729 slave->ring_position); |
|
1730 } |
|
1537 return; |
1731 return; |
1538 } |
1732 } |
1539 |
1733 |
1540 // set state to OP |
1734 // set state to OP |
1541 fsm->slave_state = ec_fsm_slaveconf_op; |
1735 fsm->slave_state = ec_fsm_slaveconf_op; |
1545 } |
1739 } |
1546 |
1740 |
1547 /*****************************************************************************/ |
1741 /*****************************************************************************/ |
1548 |
1742 |
1549 /** |
1743 /** |
1550 Slave state: OP |
1744 Slave configuration state: OP |
1551 */ |
1745 */ |
1552 |
1746 |
1553 void ec_fsm_slaveconf_op(ec_fsm_t *fsm /**< finite state machine */) |
1747 void ec_fsm_slaveconf_op(ec_fsm_t *fsm /**< finite state machine */) |
1554 { |
1748 { |
1749 ec_master_t *master = fsm->master; |
|
1750 ec_slave_t *slave = fsm->slave; |
|
1751 |
|
1555 fsm->change_state(fsm); // execute state change state machine |
1752 fsm->change_state(fsm); // execute state change state machine |
1556 |
1753 |
1557 if (fsm->change_state == ec_fsm_error) { |
1754 if (fsm->change_state == ec_fsm_error) { |
1558 fsm->slave->error_flag = 1; |
1755 slave->error_flag = 1; |
1559 fsm->slave_state = ec_fsm_error; |
1756 fsm->slave_state = ec_fsm_error; |
1560 return; |
1757 return; |
1561 } |
1758 } |
1562 |
1759 |
1563 if (fsm->change_state != ec_fsm_end) return; |
1760 if (fsm->change_state != ec_fsm_end) return; |
1564 |
1761 |
1565 // slave is now in OP |
1762 // slave is now in OP |
1763 |
|
1764 if (master->debug_level) { |
|
1765 EC_DBG("Slave %i is now in OP.\n", slave->ring_position); |
|
1766 EC_DBG("Finished configuration of slave %i.\n", slave->ring_position); |
|
1767 } |
|
1768 |
|
1566 fsm->slave_state = ec_fsm_end; // successful |
1769 fsm->slave_state = ec_fsm_end; // successful |
1567 } |
1770 } |
1568 |
1771 |
1569 /****************************************************************************** |
1772 /****************************************************************************** |
1570 * SII state machine |
1773 * SII state machine |
1571 *****************************************************************************/ |
1774 *****************************************************************************/ |
1572 |
1775 |
1573 /** |
1776 /** |
1574 SII state: START_READING. |
1777 SII state: START READING. |
1575 Starts reading the slave information interface. |
1778 Starts reading the slave information interface. |
1576 */ |
1779 */ |
1577 |
1780 |
1578 void ec_fsm_sii_start_reading(ec_fsm_t *fsm /**< finite state machine */) |
1781 void ec_fsm_sii_start_reading(ec_fsm_t *fsm /**< finite state machine */) |
1579 { |
1782 { |
1595 } |
1798 } |
1596 |
1799 |
1597 /*****************************************************************************/ |
1800 /*****************************************************************************/ |
1598 |
1801 |
1599 /** |
1802 /** |
1600 SII state: READ_CHECK. |
1803 SII state: READ CHECK. |
1601 Checks, if the SII-read-datagram has been sent and issues a fetch datagram. |
1804 Checks, if the SII-read-datagram has been sent and issues a fetch datagram. |
1602 */ |
1805 */ |
1603 |
1806 |
1604 void ec_fsm_sii_read_check(ec_fsm_t *fsm /**< finite state machine */) |
1807 void ec_fsm_sii_read_check(ec_fsm_t *fsm /**< finite state machine */) |
1605 { |
1808 { |
1628 } |
1831 } |
1629 |
1832 |
1630 /*****************************************************************************/ |
1833 /*****************************************************************************/ |
1631 |
1834 |
1632 /** |
1835 /** |
1633 SII state: READ_FETCH. |
1836 SII state: READ FETCH. |
1634 Fetches the result of an SII-read datagram. |
1837 Fetches the result of an SII-read datagram. |
1635 */ |
1838 */ |
1636 |
1839 |
1637 void ec_fsm_sii_read_fetch(ec_fsm_t *fsm /**< finite state machine */) |
1840 void ec_fsm_sii_read_fetch(ec_fsm_t *fsm /**< finite state machine */) |
1638 { |
1841 { |
1690 } |
1893 } |
1691 |
1894 |
1692 /*****************************************************************************/ |
1895 /*****************************************************************************/ |
1693 |
1896 |
1694 /** |
1897 /** |
1695 SII state: START_WRITING. |
1898 SII state: START WRITING. |
1696 Starts reading the slave information interface. |
1899 Starts reading the slave information interface. |
1697 */ |
1900 */ |
1698 |
1901 |
1699 void ec_fsm_sii_start_writing(ec_fsm_t *fsm /**< finite state machine */) |
1902 void ec_fsm_sii_start_writing(ec_fsm_t *fsm /**< finite state machine */) |
1700 { |
1903 { |
1711 } |
1914 } |
1712 |
1915 |
1713 /*****************************************************************************/ |
1916 /*****************************************************************************/ |
1714 |
1917 |
1715 /** |
1918 /** |
1716 SII state: WRITE_CHECK. |
1919 SII state: WRITE CHECK. |
1717 */ |
1920 */ |
1718 |
1921 |
1719 void ec_fsm_sii_write_check(ec_fsm_t *fsm /**< finite state machine */) |
1922 void ec_fsm_sii_write_check(ec_fsm_t *fsm /**< finite state machine */) |
1720 { |
1923 { |
1721 ec_datagram_t *datagram = &fsm->datagram; |
1924 ec_datagram_t *datagram = &fsm->datagram; |
1737 } |
1940 } |
1738 |
1941 |
1739 /*****************************************************************************/ |
1942 /*****************************************************************************/ |
1740 |
1943 |
1741 /** |
1944 /** |
1742 SII state: WRITE_CHECK2. |
1945 SII state: WRITE CHECK 2. |
1743 */ |
1946 */ |
1744 |
1947 |
1745 void ec_fsm_sii_write_check2(ec_fsm_t *fsm /**< finite state machine */) |
1948 void ec_fsm_sii_write_check2(ec_fsm_t *fsm /**< finite state machine */) |
1746 { |
1949 { |
1747 ec_datagram_t *datagram = &fsm->datagram; |
1950 ec_datagram_t *datagram = &fsm->datagram; |
2055 ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); |
2258 ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); |
2056 ec_master_queue_datagram(fsm->master, datagram); |
2259 ec_master_queue_datagram(fsm->master, datagram); |
2057 } |
2260 } |
2058 |
2261 |
2059 /****************************************************************************** |
2262 /****************************************************************************** |
2263 * CoE dictionary state machine |
|
2264 *****************************************************************************/ |
|
2265 |
|
2266 /** |
|
2267 CoE state: DICT START. |
|
2268 */ |
|
2269 |
|
2270 void ec_fsm_coe_dict_start(ec_fsm_t *fsm /**< finite state machine */) |
|
2271 { |
|
2272 ec_datagram_t *datagram = &fsm->datagram; |
|
2273 ec_slave_t *slave = fsm->slave; |
|
2274 uint8_t *data; |
|
2275 |
|
2276 if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8))) { |
|
2277 fsm->coe_state = ec_fsm_error; |
|
2278 return; |
|
2279 } |
|
2280 |
|
2281 EC_WRITE_U16(data, 0x8 << 12); // SDO information |
|
2282 EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request |
|
2283 EC_WRITE_U8 (data + 3, 0x00); |
|
2284 EC_WRITE_U16(data + 4, 0x0000); |
|
2285 EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs! |
|
2286 |
|
2287 ec_master_queue_datagram(fsm->master, datagram); |
|
2288 fsm->coe_state = ec_fsm_coe_dict_request; |
|
2289 } |
|
2290 |
|
2291 /*****************************************************************************/ |
|
2292 |
|
2293 /** |
|
2294 CoE state: DICT REQUEST. |
|
2295 */ |
|
2296 |
|
2297 void ec_fsm_coe_dict_request(ec_fsm_t *fsm /**< finite state machine */) |
|
2298 { |
|
2299 ec_datagram_t *datagram = &fsm->datagram; |
|
2300 ec_slave_t *slave = fsm->slave; |
|
2301 |
|
2302 if (datagram->state != EC_DATAGRAM_RECEIVED |
|
2303 || datagram->working_counter != 1) { |
|
2304 fsm->coe_state = ec_fsm_error; |
|
2305 EC_ERR("Reception of CoE dictionary request failed.\n"); |
|
2306 return; |
|
2307 } |
|
2308 |
|
2309 fsm->coe_start = datagram->cycles_sent; |
|
2310 |
|
2311 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
|
2312 ec_master_queue_datagram(fsm->master, datagram); |
|
2313 fsm->coe_state = ec_fsm_coe_dict_check; |
|
2314 } |
|
2315 |
|
2316 /*****************************************************************************/ |
|
2317 |
|
2318 /** |
|
2319 CoE state: DICT CHECK. |
|
2320 */ |
|
2321 |
|
2322 void ec_fsm_coe_dict_check(ec_fsm_t *fsm /**< finite state machine */) |
|
2323 { |
|
2324 ec_datagram_t *datagram = &fsm->datagram; |
|
2325 ec_slave_t *slave = fsm->slave; |
|
2326 |
|
2327 if (datagram->state != EC_DATAGRAM_RECEIVED |
|
2328 || datagram->working_counter != 1) { |
|
2329 fsm->coe_state = ec_fsm_error; |
|
2330 EC_ERR("Reception of CoE mailbox check datagram failed.\n"); |
|
2331 return; |
|
2332 } |
|
2333 |
|
2334 if (!ec_slave_mbox_check(datagram)) { |
|
2335 if (datagram->cycles_received |
|
2336 - fsm->coe_start >= (cycles_t) 100 * cpu_khz) { |
|
2337 fsm->coe_state = ec_fsm_error; |
|
2338 EC_ERR("Timeout while checking SDO dictionary on slave %i.\n", |
|
2339 slave->ring_position); |
|
2340 return; |
|
2341 } |
|
2342 |
|
2343 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
|
2344 ec_master_queue_datagram(fsm->master, datagram); |
|
2345 return; |
|
2346 } |
|
2347 |
|
2348 // Fetch response |
|
2349 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. |
|
2350 ec_master_queue_datagram(fsm->master, datagram); |
|
2351 fsm->coe_state = ec_fsm_coe_dict_response; |
|
2352 } |
|
2353 |
|
2354 /*****************************************************************************/ |
|
2355 |
|
2356 /** |
|
2357 CoE state: DICT RESPONSE. |
|
2358 */ |
|
2359 |
|
2360 void ec_fsm_coe_dict_response(ec_fsm_t *fsm /**< finite state machine */) |
|
2361 { |
|
2362 ec_master_t *master = fsm->master; |
|
2363 ec_datagram_t *datagram = &fsm->datagram; |
|
2364 ec_slave_t *slave = fsm->slave; |
|
2365 uint8_t *data, mbox_prot; |
|
2366 size_t rec_size; |
|
2367 unsigned int sdo_count, i; |
|
2368 uint16_t sdo_index; |
|
2369 ec_sdo_t *sdo; |
|
2370 |
|
2371 if (datagram->state != EC_DATAGRAM_RECEIVED |
|
2372 || datagram->working_counter != 1) { |
|
2373 fsm->coe_state = ec_fsm_error; |
|
2374 EC_ERR("Reception of CoE dictionary response failed.\n"); |
|
2375 return; |
|
2376 } |
|
2377 |
|
2378 if (!(data = ec_slave_mbox_fetch(slave, datagram, |
|
2379 &mbox_prot, &rec_size))) { |
|
2380 fsm->coe_state = ec_fsm_error; |
|
2381 return; |
|
2382 } |
|
2383 |
|
2384 if (mbox_prot != 0x03) { // CoE |
|
2385 EC_WARN("Received mailbox protocol 0x%02X as response.\n", mbox_prot); |
|
2386 fsm->coe_state = ec_fsm_error; |
|
2387 return; |
|
2388 } |
|
2389 |
|
2390 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
|
2391 (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response |
|
2392 EC_ERR("SDO information error response at slave %i!\n", |
|
2393 slave->ring_position); |
|
2394 ec_canopen_abort_msg(EC_READ_U32(data + 6)); |
|
2395 fsm->coe_state = ec_fsm_error; |
|
2396 return; |
|
2397 } |
|
2398 |
|
2399 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
|
2400 (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response |
|
2401 EC_ERR("Invalid SDO list response at slave %i!\n", |
|
2402 slave->ring_position); |
|
2403 ec_print_data(data, rec_size); |
|
2404 fsm->coe_state = ec_fsm_error; |
|
2405 return; |
|
2406 } |
|
2407 |
|
2408 if (rec_size < 8) { |
|
2409 EC_ERR("Invalid data size!\n"); |
|
2410 ec_print_data(data, rec_size); |
|
2411 fsm->coe_state = ec_fsm_error; |
|
2412 return; |
|
2413 } |
|
2414 |
|
2415 sdo_count = (rec_size - 8) / 2; |
|
2416 |
|
2417 if (master->debug_level) { |
|
2418 EC_DBG("Fetching %i SDOs.\n", sdo_count); |
|
2419 } |
|
2420 |
|
2421 for (i = 0; i < sdo_count; i++) { |
|
2422 sdo_index = EC_READ_U16(data + 8 + i * 2); |
|
2423 if (!sdo_index) { |
|
2424 // sometimes index is 0... ??? |
|
2425 if (master->debug_level) { |
|
2426 EC_DBG("Received SDO with index 0x0000.\n"); |
|
2427 } |
|
2428 continue; |
|
2429 } |
|
2430 |
|
2431 if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_ATOMIC))) { |
|
2432 EC_ERR("Failed to allocate memory for SDO!\n"); |
|
2433 fsm->coe_state = ec_fsm_error; |
|
2434 return; |
|
2435 } |
|
2436 |
|
2437 if (ec_sdo_init(sdo, sdo_index, slave)) { |
|
2438 EC_ERR("Failed to init SDO!\n"); |
|
2439 fsm->coe_state = ec_fsm_error; |
|
2440 return; |
|
2441 } |
|
2442 |
|
2443 if (kobject_add(&sdo->kobj)) { |
|
2444 EC_ERR("Failed to add kobject.\n"); |
|
2445 kobject_put(&sdo->kobj); // free |
|
2446 fsm->coe_state = ec_fsm_error; |
|
2447 return; |
|
2448 } |
|
2449 |
|
2450 list_add_tail(&sdo->list, &slave->sdo_dictionary); |
|
2451 } |
|
2452 |
|
2453 if (EC_READ_U8(data + 2) & 0x80) { // more messages waiting. check again. |
|
2454 fsm->coe_start = datagram->cycles_sent; |
|
2455 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
|
2456 ec_master_queue_datagram(fsm->master, datagram); |
|
2457 fsm->coe_state = ec_fsm_coe_dict_check; |
|
2458 return; |
|
2459 } |
|
2460 |
|
2461 if (list_empty(&slave->sdo_dictionary)) { |
|
2462 // no SDOs in dictionary. finished. |
|
2463 fsm->coe_state = ec_fsm_end; // success |
|
2464 return; |
|
2465 } |
|
2466 |
|
2467 // fetch SDO descriptions |
|
2468 fsm->coe_sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list); |
|
2469 |
|
2470 if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8))) { |
|
2471 fsm->coe_state = ec_fsm_error; |
|
2472 return; |
|
2473 } |
|
2474 |
|
2475 EC_WRITE_U16(data, 0x8 << 12); // SDO information |
|
2476 EC_WRITE_U8 (data + 2, 0x03); // Get object description request |
|
2477 EC_WRITE_U8 (data + 3, 0x00); |
|
2478 EC_WRITE_U16(data + 4, 0x0000); |
|
2479 EC_WRITE_U16(data + 6, fsm->coe_sdo->index); // SDO index |
|
2480 |
|
2481 ec_master_queue_datagram(fsm->master, datagram); |
|
2482 fsm->coe_state = ec_fsm_coe_dict_desc_request; |
|
2483 } |
|
2484 |
|
2485 /*****************************************************************************/ |
|
2486 |
|
2487 /** |
|
2488 CoE state: DICT DESC REQUEST. |
|
2489 */ |
|
2490 |
|
2491 void ec_fsm_coe_dict_desc_request(ec_fsm_t *fsm /**< finite state machine */) |
|
2492 { |
|
2493 ec_datagram_t *datagram = &fsm->datagram; |
|
2494 ec_slave_t *slave = fsm->slave; |
|
2495 |
|
2496 if (datagram->state != EC_DATAGRAM_RECEIVED |
|
2497 || datagram->working_counter != 1) { |
|
2498 fsm->coe_state = ec_fsm_error; |
|
2499 EC_ERR("Reception of CoE SDO description request failed.\n"); |
|
2500 return; |
|
2501 } |
|
2502 |
|
2503 fsm->coe_start = datagram->cycles_sent; |
|
2504 |
|
2505 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
|
2506 ec_master_queue_datagram(fsm->master, datagram); |
|
2507 fsm->coe_state = ec_fsm_coe_dict_desc_check; |
|
2508 } |
|
2509 |
|
2510 /*****************************************************************************/ |
|
2511 |
|
2512 /** |
|
2513 CoE state: DICT DESC CHECK. |
|
2514 */ |
|
2515 |
|
2516 void ec_fsm_coe_dict_desc_check(ec_fsm_t *fsm /**< finite state machine */) |
|
2517 { |
|
2518 ec_datagram_t *datagram = &fsm->datagram; |
|
2519 ec_slave_t *slave = fsm->slave; |
|
2520 |
|
2521 if (datagram->state != EC_DATAGRAM_RECEIVED |
|
2522 || datagram->working_counter != 1) { |
|
2523 fsm->coe_state = ec_fsm_error; |
|
2524 EC_ERR("Reception of CoE mailbox check datagram failed.\n"); |
|
2525 return; |
|
2526 } |
|
2527 |
|
2528 if (!ec_slave_mbox_check(datagram)) { |
|
2529 if (datagram->cycles_received |
|
2530 - fsm->coe_start >= (cycles_t) 100 * cpu_khz) { |
|
2531 fsm->coe_state = ec_fsm_error; |
|
2532 EC_ERR("Timeout while checking SDO description on slave %i.\n", |
|
2533 slave->ring_position); |
|
2534 return; |
|
2535 } |
|
2536 |
|
2537 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
|
2538 ec_master_queue_datagram(fsm->master, datagram); |
|
2539 return; |
|
2540 } |
|
2541 |
|
2542 // Fetch response |
|
2543 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. |
|
2544 ec_master_queue_datagram(fsm->master, datagram); |
|
2545 fsm->coe_state = ec_fsm_coe_dict_desc_response; |
|
2546 } |
|
2547 |
|
2548 /*****************************************************************************/ |
|
2549 |
|
2550 /** |
|
2551 CoE state: DICT DESC RESPONSE. |
|
2552 */ |
|
2553 |
|
2554 void ec_fsm_coe_dict_desc_response(ec_fsm_t *fsm /**< finite state machine */) |
|
2555 { |
|
2556 ec_master_t *master = fsm->master; |
|
2557 ec_datagram_t *datagram = &fsm->datagram; |
|
2558 ec_slave_t *slave = fsm->slave; |
|
2559 ec_sdo_t *sdo = fsm->coe_sdo; |
|
2560 uint8_t *data, mbox_prot; |
|
2561 size_t rec_size, name_size; |
|
2562 |
|
2563 if (datagram->state != EC_DATAGRAM_RECEIVED |
|
2564 || datagram->working_counter != 1) { |
|
2565 fsm->coe_state = ec_fsm_error; |
|
2566 EC_ERR("Reception of CoE SDO description response failed.\n"); |
|
2567 return; |
|
2568 } |
|
2569 |
|
2570 if (!(data = ec_slave_mbox_fetch(slave, datagram, |
|
2571 &mbox_prot, &rec_size))) { |
|
2572 fsm->coe_state = ec_fsm_error; |
|
2573 return; |
|
2574 } |
|
2575 |
|
2576 if (mbox_prot != 0x03) { // CoE |
|
2577 EC_WARN("Received mailbox protocol 0x%02X as response.\n", mbox_prot); |
|
2578 fsm->coe_state = ec_fsm_error; |
|
2579 return; |
|
2580 } |
|
2581 |
|
2582 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
|
2583 (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response |
|
2584 EC_ERR("SDO information error response at slave %i while" |
|
2585 " fetching SDO 0x%04X!\n", slave->ring_position, |
|
2586 sdo->index); |
|
2587 ec_canopen_abort_msg(EC_READ_U32(data + 6)); |
|
2588 fsm->coe_state = ec_fsm_error; |
|
2589 return; |
|
2590 } |
|
2591 |
|
2592 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
|
2593 (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response |
|
2594 EC_READ_U16(data + 6) != sdo->index) { // SDO index |
|
2595 EC_ERR("Invalid object description response at slave %i while" |
|
2596 " fetching SDO 0x%04X!\n", slave->ring_position, |
|
2597 sdo->index); |
|
2598 ec_print_data(data, rec_size); |
|
2599 fsm->coe_state = ec_fsm_error; |
|
2600 return; |
|
2601 } |
|
2602 |
|
2603 if (rec_size < 12) { |
|
2604 EC_ERR("Invalid data size!\n"); |
|
2605 ec_print_data(data, rec_size); |
|
2606 fsm->coe_state = ec_fsm_error; |
|
2607 return; |
|
2608 } |
|
2609 |
|
2610 sdo->subindices = EC_READ_U8(data + 10); |
|
2611 sdo->object_code = EC_READ_U8(data + 11); |
|
2612 |
|
2613 name_size = rec_size - 12; |
|
2614 if (name_size) { |
|
2615 if (!(sdo->name = kmalloc(name_size + 1, GFP_ATOMIC))) { |
|
2616 EC_ERR("Failed to allocate SDO name!\n"); |
|
2617 fsm->coe_state = ec_fsm_error; |
|
2618 return; |
|
2619 } |
|
2620 |
|
2621 memcpy(sdo->name, data + 12, name_size); |
|
2622 sdo->name[name_size] = 0; |
|
2623 } |
|
2624 |
|
2625 if (EC_READ_U8(data + 2) & 0x80) { |
|
2626 EC_ERR("Fragment follows (not implemented)!\n"); |
|
2627 fsm->coe_state = ec_fsm_error; |
|
2628 return; |
|
2629 } |
|
2630 |
|
2631 if (!sdo->subindices) { // no entries |
|
2632 // another SDO description to fetch? |
|
2633 if (fsm->coe_sdo->list.next != &slave->sdo_dictionary) { |
|
2634 fsm->coe_sdo = list_entry(fsm->coe_sdo->list.next, ec_sdo_t, list); |
|
2635 |
|
2636 if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8))) { |
|
2637 fsm->coe_state = ec_fsm_error; |
|
2638 return; |
|
2639 } |
|
2640 |
|
2641 EC_WRITE_U16(data, 0x8 << 12); // SDO information |
|
2642 EC_WRITE_U8 (data + 2, 0x03); // Get object description request |
|
2643 EC_WRITE_U8 (data + 3, 0x00); |
|
2644 EC_WRITE_U16(data + 4, 0x0000); |
|
2645 EC_WRITE_U16(data + 6, fsm->coe_sdo->index); // SDO index |
|
2646 |
|
2647 ec_master_queue_datagram(fsm->master, datagram); |
|
2648 fsm->coe_state = ec_fsm_coe_dict_desc_request; |
|
2649 return; |
|
2650 } |
|
2651 |
|
2652 if (master->debug_level) { |
|
2653 EC_DBG("Finished fetching SDO descriptions.\n"); |
|
2654 } |
|
2655 |
|
2656 fsm->coe_state = ec_fsm_end; |
|
2657 return; |
|
2658 } |
|
2659 |
|
2660 fsm->coe_subindex = 1; |
|
2661 |
|
2662 if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10))) { |
|
2663 fsm->coe_state = ec_fsm_error; |
|
2664 return; |
|
2665 } |
|
2666 |
|
2667 EC_WRITE_U16(data, 0x8 << 12); // SDO information |
|
2668 EC_WRITE_U8 (data + 2, 0x05); // Get entry description request |
|
2669 EC_WRITE_U8 (data + 3, 0x00); |
|
2670 EC_WRITE_U16(data + 4, 0x0000); |
|
2671 EC_WRITE_U16(data + 6, sdo->index); // SDO index |
|
2672 EC_WRITE_U8 (data + 8, fsm->coe_subindex); // SDO subindex |
|
2673 EC_WRITE_U8 (data + 9, 0x00); // value info (no values) |
|
2674 |
|
2675 ec_master_queue_datagram(fsm->master, datagram); |
|
2676 fsm->coe_state = ec_fsm_coe_dict_entry_request; |
|
2677 } |
|
2678 |
|
2679 /*****************************************************************************/ |
|
2680 |
|
2681 /** |
|
2682 CoE state: DICT ENTRY REQUEST. |
|
2683 */ |
|
2684 |
|
2685 void ec_fsm_coe_dict_entry_request(ec_fsm_t *fsm /**< finite state machine */) |
|
2686 { |
|
2687 ec_datagram_t *datagram = &fsm->datagram; |
|
2688 ec_slave_t *slave = fsm->slave; |
|
2689 |
|
2690 if (datagram->state != EC_DATAGRAM_RECEIVED |
|
2691 || datagram->working_counter != 1) { |
|
2692 fsm->coe_state = ec_fsm_error; |
|
2693 EC_ERR("Reception of CoE SDO entry request failed.\n"); |
|
2694 return; |
|
2695 } |
|
2696 |
|
2697 fsm->coe_start = datagram->cycles_sent; |
|
2698 |
|
2699 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
|
2700 ec_master_queue_datagram(fsm->master, datagram); |
|
2701 fsm->coe_state = ec_fsm_coe_dict_entry_check; |
|
2702 } |
|
2703 |
|
2704 /*****************************************************************************/ |
|
2705 |
|
2706 /** |
|
2707 CoE state: DICT ENTRY CHECK. |
|
2708 */ |
|
2709 |
|
2710 void ec_fsm_coe_dict_entry_check(ec_fsm_t *fsm /**< finite state machine */) |
|
2711 { |
|
2712 ec_datagram_t *datagram = &fsm->datagram; |
|
2713 ec_slave_t *slave = fsm->slave; |
|
2714 |
|
2715 if (datagram->state != EC_DATAGRAM_RECEIVED |
|
2716 || datagram->working_counter != 1) { |
|
2717 fsm->coe_state = ec_fsm_error; |
|
2718 EC_ERR("Reception of CoE mailbox check datagram failed.\n"); |
|
2719 return; |
|
2720 } |
|
2721 |
|
2722 if (!ec_slave_mbox_check(datagram)) { |
|
2723 if (datagram->cycles_received |
|
2724 - fsm->coe_start >= (cycles_t) 100 * cpu_khz) { |
|
2725 fsm->coe_state = ec_fsm_error; |
|
2726 EC_ERR("Timeout while checking SDO entry on slave %i.\n", |
|
2727 slave->ring_position); |
|
2728 return; |
|
2729 } |
|
2730 |
|
2731 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
|
2732 ec_master_queue_datagram(fsm->master, datagram); |
|
2733 return; |
|
2734 } |
|
2735 |
|
2736 // Fetch response |
|
2737 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. |
|
2738 ec_master_queue_datagram(fsm->master, datagram); |
|
2739 fsm->coe_state = ec_fsm_coe_dict_entry_response; |
|
2740 } |
|
2741 |
|
2742 /*****************************************************************************/ |
|
2743 |
|
2744 /** |
|
2745 CoE state: DICT ENTRY RESPONSE. |
|
2746 */ |
|
2747 |
|
2748 void ec_fsm_coe_dict_entry_response(ec_fsm_t *fsm /**< finite state machine */) |
|
2749 { |
|
2750 ec_master_t *master = fsm->master; |
|
2751 ec_datagram_t *datagram = &fsm->datagram; |
|
2752 ec_slave_t *slave = fsm->slave; |
|
2753 ec_sdo_t *sdo = fsm->coe_sdo; |
|
2754 uint8_t *data, mbox_prot; |
|
2755 size_t rec_size, data_size; |
|
2756 ec_sdo_entry_t *entry; |
|
2757 |
|
2758 if (datagram->state != EC_DATAGRAM_RECEIVED |
|
2759 || datagram->working_counter != 1) { |
|
2760 fsm->coe_state = ec_fsm_error; |
|
2761 EC_ERR("Reception of CoE SDO description response failed.\n"); |
|
2762 return; |
|
2763 } |
|
2764 |
|
2765 if (!(data = ec_slave_mbox_fetch(slave, datagram, |
|
2766 &mbox_prot, &rec_size))) { |
|
2767 fsm->coe_state = ec_fsm_error; |
|
2768 return; |
|
2769 } |
|
2770 |
|
2771 if (mbox_prot != 0x03) { // CoE |
|
2772 EC_WARN("Received mailbox protocol 0x%02X as response.\n", mbox_prot); |
|
2773 fsm->coe_state = ec_fsm_error; |
|
2774 return; |
|
2775 } |
|
2776 |
|
2777 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
|
2778 (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response |
|
2779 EC_ERR("SDO information error response at slave %i while" |
|
2780 " fetching SDO entry 0x%04X:%i!\n", slave->ring_position, |
|
2781 sdo->index, fsm->coe_subindex); |
|
2782 ec_canopen_abort_msg(EC_READ_U32(data + 6)); |
|
2783 fsm->coe_state = ec_fsm_error; |
|
2784 return; |
|
2785 } |
|
2786 |
|
2787 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
|
2788 (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response |
|
2789 EC_READ_U16(data + 6) != sdo->index || // SDO index |
|
2790 EC_READ_U8(data + 8) != fsm->coe_subindex) { // SDO subindex |
|
2791 EC_ERR("Invalid entry description response at slave %i while" |
|
2792 " fetching SDO entry 0x%04X:%i!\n", slave->ring_position, |
|
2793 sdo->index, fsm->coe_subindex); |
|
2794 ec_print_data(data, rec_size); |
|
2795 fsm->coe_state = ec_fsm_error; |
|
2796 return; |
|
2797 } |
|
2798 |
|
2799 if (rec_size < 16) { |
|
2800 EC_ERR("Invalid data size!\n"); |
|
2801 ec_print_data(data, rec_size); |
|
2802 fsm->coe_state = ec_fsm_error; |
|
2803 return; |
|
2804 } |
|
2805 |
|
2806 data_size = rec_size - 16; |
|
2807 |
|
2808 if (!(entry = (ec_sdo_entry_t *) |
|
2809 kmalloc(sizeof(ec_sdo_entry_t), GFP_ATOMIC))) { |
|
2810 EC_ERR("Failed to allocate entry!\n"); |
|
2811 fsm->coe_state = ec_fsm_error; |
|
2812 return; |
|
2813 } |
|
2814 |
|
2815 if (ec_sdo_entry_init(entry, fsm->coe_subindex, sdo)) { |
|
2816 EC_ERR("Failed to init entry!\n"); |
|
2817 fsm->coe_state = ec_fsm_error; |
|
2818 return; |
|
2819 } |
|
2820 |
|
2821 entry->data_type = EC_READ_U16(data + 10); |
|
2822 entry->bit_length = EC_READ_U16(data + 12); |
|
2823 |
|
2824 if (data_size) { |
|
2825 if (!(entry->description = kmalloc(data_size + 1, GFP_ATOMIC))) { |
|
2826 EC_ERR("Failed to allocate SDO entry name!\n"); |
|
2827 fsm->coe_state = ec_fsm_error; |
|
2828 return; |
|
2829 } |
|
2830 memcpy(entry->description, data + 16, data_size); |
|
2831 entry->description[data_size] = 0; |
|
2832 } |
|
2833 |
|
2834 if (kobject_add(&entry->kobj)) { |
|
2835 EC_ERR("Failed to add kobject.\n"); |
|
2836 kobject_put(&entry->kobj); // free |
|
2837 fsm->coe_state = ec_fsm_error; |
|
2838 return; |
|
2839 } |
|
2840 |
|
2841 list_add_tail(&entry->list, &sdo->entries); |
|
2842 |
|
2843 if (fsm->coe_subindex < sdo->subindices) { |
|
2844 fsm->coe_subindex++; |
|
2845 |
|
2846 if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10))) { |
|
2847 fsm->coe_state = ec_fsm_error; |
|
2848 return; |
|
2849 } |
|
2850 |
|
2851 EC_WRITE_U16(data, 0x8 << 12); // SDO information |
|
2852 EC_WRITE_U8 (data + 2, 0x05); // Get entry description request |
|
2853 EC_WRITE_U8 (data + 3, 0x00); |
|
2854 EC_WRITE_U16(data + 4, 0x0000); |
|
2855 EC_WRITE_U16(data + 6, sdo->index); // SDO index |
|
2856 EC_WRITE_U8 (data + 8, fsm->coe_subindex); // SDO subindex |
|
2857 EC_WRITE_U8 (data + 9, 0x00); // value info (no values) |
|
2858 |
|
2859 ec_master_queue_datagram(fsm->master, datagram); |
|
2860 fsm->coe_state = ec_fsm_coe_dict_entry_request; |
|
2861 return; |
|
2862 } |
|
2863 |
|
2864 // another SDO description to fetch? |
|
2865 if (fsm->coe_sdo->list.next != &slave->sdo_dictionary) { |
|
2866 fsm->coe_sdo = list_entry(fsm->coe_sdo->list.next, ec_sdo_t, list); |
|
2867 |
|
2868 if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8))) { |
|
2869 fsm->coe_state = ec_fsm_error; |
|
2870 return; |
|
2871 } |
|
2872 |
|
2873 EC_WRITE_U16(data, 0x8 << 12); // SDO information |
|
2874 EC_WRITE_U8 (data + 2, 0x03); // Get object description request |
|
2875 EC_WRITE_U8 (data + 3, 0x00); |
|
2876 EC_WRITE_U16(data + 4, 0x0000); |
|
2877 EC_WRITE_U16(data + 6, fsm->coe_sdo->index); // SDO index |
|
2878 |
|
2879 ec_master_queue_datagram(fsm->master, datagram); |
|
2880 fsm->coe_state = ec_fsm_coe_dict_desc_request; |
|
2881 return; |
|
2882 } |
|
2883 |
|
2884 if (master->debug_level) { |
|
2885 EC_DBG("Finished fetching SDO descriptions.\n"); |
|
2886 } |
|
2887 |
|
2888 fsm->coe_state = ec_fsm_end; |
|
2889 } |
|
2890 |
|
2891 /****************************************************************************** |
|
2060 * CoE state machine |
2892 * CoE state machine |
2061 *****************************************************************************/ |
2893 *****************************************************************************/ |
2062 |
2894 |
2063 /** |
2895 /** |
2064 CoE state: DOWN_START. |
2896 CoE state: DOWN START. |
2065 */ |
2897 */ |
2066 |
2898 |
2067 void ec_fsm_coe_down_start(ec_fsm_t *fsm /**< finite state machine */) |
2899 void ec_fsm_coe_down_start(ec_fsm_t *fsm /**< finite state machine */) |
2068 { |
2900 { |
2069 ec_datagram_t *datagram = &fsm->datagram; |
2901 ec_datagram_t *datagram = &fsm->datagram; |
2099 } |
2931 } |
2100 |
2932 |
2101 /*****************************************************************************/ |
2933 /*****************************************************************************/ |
2102 |
2934 |
2103 /** |
2935 /** |
2104 CoE state: DOWN_REQUEST. |
2936 CoE state: DOWN REQUEST. |
2105 */ |
2937 */ |
2106 |
2938 |
2107 void ec_fsm_coe_down_request(ec_fsm_t *fsm /**< finite state machine */) |
2939 void ec_fsm_coe_down_request(ec_fsm_t *fsm /**< finite state machine */) |
2108 { |
2940 { |
2109 ec_datagram_t *datagram = &fsm->datagram; |
2941 ec_datagram_t *datagram = &fsm->datagram; |
2124 } |
2956 } |
2125 |
2957 |
2126 /*****************************************************************************/ |
2958 /*****************************************************************************/ |
2127 |
2959 |
2128 /** |
2960 /** |
2129 CoE state: DOWN_CHECK. |
2961 CoE state: DOWN CHECK. |
2130 */ |
2962 */ |
2131 |
2963 |
2132 void ec_fsm_coe_down_check(ec_fsm_t *fsm /**< finite state machine */) |
2964 void ec_fsm_coe_down_check(ec_fsm_t *fsm /**< finite state machine */) |
2133 { |
2965 { |
2134 ec_datagram_t *datagram = &fsm->datagram; |
2966 ec_datagram_t *datagram = &fsm->datagram; |
2162 } |
2994 } |
2163 |
2995 |
2164 /*****************************************************************************/ |
2996 /*****************************************************************************/ |
2165 |
2997 |
2166 /** |
2998 /** |
2167 CoE state: DOWN_RESPONSE. |
2999 CoE state: DOWN RESPONSE. |
2168 */ |
3000 */ |
2169 |
3001 |
2170 void ec_fsm_coe_down_response(ec_fsm_t *fsm /**< finite state machine */) |
3002 void ec_fsm_coe_down_response(ec_fsm_t *fsm /**< finite state machine */) |
2171 { |
3003 { |
2172 ec_datagram_t *datagram = &fsm->datagram; |
3004 ec_datagram_t *datagram = &fsm->datagram; |