master/fsm.c
changeset 409 bc4c852e1b93
parent 407 b73c9f7be5a1
child 411 42d239bab6ae
equal deleted inserted replaced
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;