master/fsm.c
changeset 462 e6fac0c8bc92
parent 461 b9eda9235173
child 470 4ec31555832b
equal deleted inserted replaced
461:b9eda9235173 462:e6fac0c8bc92
    66 void ec_fsm_slavescan_base(ec_fsm_t *);
    66 void ec_fsm_slavescan_base(ec_fsm_t *);
    67 void ec_fsm_slavescan_datalink(ec_fsm_t *);
    67 void ec_fsm_slavescan_datalink(ec_fsm_t *);
    68 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *);
    68 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *);
    69 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *);
    69 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *);
    70 
    70 
    71 void ec_fsm_slaveconf_start(ec_fsm_t *);
    71 void ec_fsm_slaveconf_state_start(ec_fsm_t *);
    72 void ec_fsm_slaveconf_init(ec_fsm_t *);
    72 void ec_fsm_slaveconf_state_init(ec_fsm_t *);
    73 void ec_fsm_slaveconf_sync(ec_fsm_t *);
    73 void ec_fsm_slaveconf_state_clear_fmmus(ec_fsm_t *);
    74 void ec_fsm_slaveconf_preop(ec_fsm_t *);
    74 void ec_fsm_slaveconf_state_sync(ec_fsm_t *);
    75 void ec_fsm_slaveconf_fmmu(ec_fsm_t *);
    75 void ec_fsm_slaveconf_state_preop(ec_fsm_t *);
    76 void ec_fsm_slaveconf_sdoconf(ec_fsm_t *);
    76 void ec_fsm_slaveconf_state_fmmu(ec_fsm_t *);
    77 void ec_fsm_slaveconf_saveop(ec_fsm_t *);
    77 void ec_fsm_slaveconf_state_sdoconf(ec_fsm_t *);
    78 void ec_fsm_slaveconf_op(ec_fsm_t *);
    78 void ec_fsm_slaveconf_state_saveop(ec_fsm_t *);
    79 
    79 void ec_fsm_slaveconf_state_op(ec_fsm_t *);
    80 void ec_fsm_slave_end(ec_fsm_t *);
    80 
    81 void ec_fsm_slave_error(ec_fsm_t *);
    81 void ec_fsm_slaveconf_enter_sync(ec_fsm_t *);
       
    82 void ec_fsm_slaveconf_enter_preop(ec_fsm_t *);
       
    83 void ec_fsm_slaveconf_enter_sdoconf(ec_fsm_t *);
       
    84 void ec_fsm_slaveconf_enter_saveop(ec_fsm_t *);
       
    85 
       
    86 void ec_fsm_slave_state_end(ec_fsm_t *);
       
    87 void ec_fsm_slave_state_error(ec_fsm_t *);
    82 
    88 
    83 /*****************************************************************************/
    89 /*****************************************************************************/
    84 
    90 
    85 /**
    91 /**
    86    Constructor.
    92    Constructor.
   330             }
   336             }
   331         }
   337         }
   332 
   338 
   333         fsm->master_state = ec_fsm_master_configure_slave;
   339         fsm->master_state = ec_fsm_master_configure_slave;
   334         fsm->slave = slave;
   340         fsm->slave = slave;
   335         fsm->slave_state = ec_fsm_slaveconf_start;
   341         fsm->slave_state = ec_fsm_slaveconf_state_start;
   336         fsm->slave_state(fsm); // execute immediately
   342         fsm->slave_state(fsm); // execute immediately
   337         return;
   343         return;
   338     }
   344     }
   339 
   345 
   340     // Check, if EoE processing has to be started
   346     // Check, if EoE processing has to be started
   711     ec_master_t *master = fsm->master;
   717     ec_master_t *master = fsm->master;
   712     ec_slave_t *slave = fsm->slave;
   718     ec_slave_t *slave = fsm->slave;
   713 
   719 
   714     fsm->slave_state(fsm); // execute slave state machine
   720     fsm->slave_state(fsm); // execute slave state machine
   715 
   721 
   716     if (fsm->slave_state != ec_fsm_slave_end
   722     if (fsm->slave_state != ec_fsm_slave_state_end
   717         && fsm->slave_state != ec_fsm_slave_error) return;
   723         && fsm->slave_state != ec_fsm_slave_state_error) return;
   718 
   724 
   719     // another slave to fetch?
   725     // another slave to fetch?
   720     if (slave->list.next != &master->slaves) {
   726     if (slave->list.next != &master->slaves) {
   721         fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   727         fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   722         fsm->slave_state = ec_fsm_slavescan_start;
   728         fsm->slave_state = ec_fsm_slavescan_start;
   748                                    /**< finite state machine */
   754                                    /**< finite state machine */
   749                                    )
   755                                    )
   750 {
   756 {
   751     fsm->slave_state(fsm); // execute slave's state machine
   757     fsm->slave_state(fsm); // execute slave's state machine
   752 
   758 
   753     if (fsm->slave_state != ec_fsm_slave_end
   759     if (fsm->slave_state != ec_fsm_slave_state_end
   754         && fsm->slave_state != ec_fsm_slave_error) return;
   760         && fsm->slave_state != ec_fsm_slave_state_error) return;
   755 
   761 
   756     ec_fsm_master_action_process_states(fsm);
   762     ec_fsm_master_action_process_states(fsm);
   757 }
   763 }
   758 
   764 
   759 /*****************************************************************************/
   765 /*****************************************************************************/
   915     ec_datagram_t *datagram = &fsm->datagram;
   921     ec_datagram_t *datagram = &fsm->datagram;
   916 
   922 
   917     if (datagram->state != EC_DATAGRAM_RECEIVED
   923     if (datagram->state != EC_DATAGRAM_RECEIVED
   918         || datagram->working_counter != 1) {
   924         || datagram->working_counter != 1) {
   919         fsm->slave->error_flag = 1;
   925         fsm->slave->error_flag = 1;
   920         fsm->slave_state = ec_fsm_slave_error;
   926         fsm->slave_state = ec_fsm_slave_state_error;
   921         EC_ERR("Failed to write station address of slave %i.\n",
   927         EC_ERR("Failed to write station address of slave %i.\n",
   922                fsm->slave->ring_position);
   928                fsm->slave->ring_position);
   923         return;
   929         return;
   924     }
   930     }
   925 
   931 
   941     ec_slave_t *slave = fsm->slave;
   947     ec_slave_t *slave = fsm->slave;
   942 
   948 
   943     if (datagram->state != EC_DATAGRAM_RECEIVED
   949     if (datagram->state != EC_DATAGRAM_RECEIVED
   944         || datagram->working_counter != 1) {
   950         || datagram->working_counter != 1) {
   945         fsm->slave->error_flag = 1;
   951         fsm->slave->error_flag = 1;
   946         fsm->slave_state = ec_fsm_slave_error;
   952         fsm->slave_state = ec_fsm_slave_state_error;
   947         EC_ERR("Failed to read AL state of slave %i.\n",
   953         EC_ERR("Failed to read AL state of slave %i.\n",
   948                fsm->slave->ring_position);
   954                fsm->slave->ring_position);
   949         return;
   955         return;
   950     }
   956     }
   951 
   957 
   975     ec_slave_t *slave = fsm->slave;
   981     ec_slave_t *slave = fsm->slave;
   976 
   982 
   977     if (datagram->state != EC_DATAGRAM_RECEIVED
   983     if (datagram->state != EC_DATAGRAM_RECEIVED
   978         || datagram->working_counter != 1) {
   984         || datagram->working_counter != 1) {
   979         fsm->slave->error_flag = 1;
   985         fsm->slave->error_flag = 1;
   980         fsm->slave_state = ec_fsm_slave_error;
   986         fsm->slave_state = ec_fsm_slave_state_error;
   981         EC_ERR("Failed to read base data of slave %i.\n",
   987         EC_ERR("Failed to read base data of slave %i.\n",
   982                slave->ring_position);
   988                slave->ring_position);
   983         return;
   989         return;
   984     }
   990     }
   985 
   991 
  1012     unsigned int i;
  1018     unsigned int i;
  1013 
  1019 
  1014     if (datagram->state != EC_DATAGRAM_RECEIVED
  1020     if (datagram->state != EC_DATAGRAM_RECEIVED
  1015         || datagram->working_counter != 1) {
  1021         || datagram->working_counter != 1) {
  1016         fsm->slave->error_flag = 1;
  1022         fsm->slave->error_flag = 1;
  1017         fsm->slave_state = ec_fsm_slave_error;
  1023         fsm->slave_state = ec_fsm_slave_state_error;
  1018         EC_ERR("Failed to read DL status of slave %i.\n",
  1024         EC_ERR("Failed to read DL status of slave %i.\n",
  1019                slave->ring_position);
  1025                slave->ring_position);
  1020         return;
  1026         return;
  1021     }
  1027     }
  1022 
  1028 
  1048 
  1054 
  1049     if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
  1055     if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
  1050 
  1056 
  1051     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
  1057     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
  1052         fsm->slave->error_flag = 1;
  1058         fsm->slave->error_flag = 1;
  1053         fsm->slave_state = ec_fsm_slave_error;
  1059         fsm->slave_state = ec_fsm_slave_state_error;
  1054         EC_ERR("Failed to read EEPROM size of slave %i.\n",
  1060         EC_ERR("Failed to read EEPROM size of slave %i.\n",
  1055                slave->ring_position);
  1061                slave->ring_position);
  1056         return;
  1062         return;
  1057     }
  1063     }
  1058 
  1064 
  1076     }
  1082     }
  1077 
  1083 
  1078     if (!(slave->eeprom_data =
  1084     if (!(slave->eeprom_data =
  1079           (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
  1085           (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
  1080         fsm->slave->error_flag = 1;
  1086         fsm->slave->error_flag = 1;
  1081         fsm->slave_state = ec_fsm_slave_error;
  1087         fsm->slave_state = ec_fsm_slave_state_error;
  1082         EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
  1088         EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
  1083                slave->ring_position);
  1089                slave->ring_position);
  1084         return;
  1090         return;
  1085     }
  1091     }
  1086 
  1092 
  1105 
  1111 
  1106     if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
  1112     if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
  1107 
  1113 
  1108     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
  1114     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
  1109         fsm->slave->error_flag = 1;
  1115         fsm->slave->error_flag = 1;
  1110         fsm->slave_state = ec_fsm_slave_error;
  1116         fsm->slave_state = ec_fsm_slave_state_error;
  1111         EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
  1117         EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
  1112                slave->ring_position);
  1118                slave->ring_position);
  1113         return;
  1119         return;
  1114     }
  1120     }
  1115 
  1121 
  1194         }
  1200         }
  1195 
  1201 
  1196         cat_word += cat_size + 2;
  1202         cat_word += cat_size + 2;
  1197     }
  1203     }
  1198 
  1204 
  1199     fsm->slave_state = ec_fsm_slave_end;
  1205     fsm->slave_state = ec_fsm_slave_state_end;
  1200     return;
  1206     return;
  1201 
  1207 
  1202 end:
  1208 end:
  1203     EC_ERR("Failed to analyze category data.\n");
  1209     EC_ERR("Failed to analyze category data.\n");
  1204     fsm->slave->error_flag = 1;
  1210     fsm->slave->error_flag = 1;
  1205     fsm->slave_state = ec_fsm_slave_error;
  1211     fsm->slave_state = ec_fsm_slave_state_error;
  1206 }
  1212 }
  1207 
  1213 
  1208 /******************************************************************************
  1214 /******************************************************************************
  1209  *  slave configuration state machine
  1215  *  slave configuration state machine
  1210  *****************************************************************************/
  1216  *****************************************************************************/
  1211 
  1217 
  1212 /**
  1218 /**
  1213    Slave configuration state: START.
  1219    Slave configuration state: START.
  1214 */
  1220 */
  1215 
  1221 
  1216 void ec_fsm_slaveconf_start(ec_fsm_t *fsm /**< finite state machine */)
  1222 void ec_fsm_slaveconf_state_start(ec_fsm_t *fsm /**< finite state machine */)
  1217 {
  1223 {
  1218     if (fsm->master->debug_level) {
  1224     if (fsm->master->debug_level) {
  1219         EC_DBG("Configuring slave %i...\n", fsm->slave->ring_position);
  1225         EC_DBG("Configuring slave %i...\n", fsm->slave->ring_position);
  1220     }
  1226     }
  1221 
  1227 
  1222     ec_fsm_change_start(&fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_INIT);
  1228     ec_fsm_change_start(&fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_INIT);
  1223     ec_fsm_change_exec(&fsm->fsm_change);
  1229     ec_fsm_change_exec(&fsm->fsm_change);
  1224     fsm->slave_state = ec_fsm_slaveconf_init;
  1230     fsm->slave_state = ec_fsm_slaveconf_state_init;
  1225 }
  1231 }
  1226 
  1232 
  1227 /*****************************************************************************/
  1233 /*****************************************************************************/
  1228 
  1234 
  1229 /**
  1235 /**
  1230    Slave configuration state: INIT.
  1236    Slave configuration state: INIT.
  1231 */
  1237 */
  1232 
  1238 
  1233 void ec_fsm_slaveconf_init(ec_fsm_t *fsm /**< finite state machine */)
  1239 void ec_fsm_slaveconf_state_init(ec_fsm_t *fsm /**< finite state machine */)
       
  1240 {
       
  1241     ec_master_t *master = fsm->master;
       
  1242     ec_slave_t *slave = fsm->slave;
       
  1243     ec_datagram_t *datagram = &fsm->datagram;
       
  1244 
       
  1245     if (ec_fsm_change_exec(&fsm->fsm_change)) return;
       
  1246 
       
  1247     if (!ec_fsm_change_success(&fsm->fsm_change)) {
       
  1248         slave->error_flag = 1;
       
  1249         fsm->slave_state = ec_fsm_slave_state_error;
       
  1250         return;
       
  1251     }
       
  1252 
       
  1253     slave->configured = 1;
       
  1254 
       
  1255     if (master->debug_level) {
       
  1256         EC_DBG("Slave %i is now in INIT.\n", slave->ring_position);
       
  1257     }
       
  1258 
       
  1259     // check and reset CRC fault counters
       
  1260     //ec_slave_check_crc(slave);
       
  1261     // TODO: Implement state machine for CRC checking.
       
  1262 
       
  1263     if (!slave->base_fmmu_count) { // skip FMMU configuration
       
  1264         ec_fsm_slaveconf_enter_sync(fsm);
       
  1265         return;
       
  1266     }
       
  1267 
       
  1268     if (master->debug_level)
       
  1269         EC_DBG("Clearing FMMU configurations of slave %i...\n",
       
  1270                slave->ring_position);
       
  1271 
       
  1272     // clear FMMU configurations
       
  1273     ec_datagram_npwr(datagram, slave->station_address,
       
  1274                      0x0600, EC_FMMU_SIZE * slave->base_fmmu_count);
       
  1275     memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
       
  1276     ec_master_queue_datagram(master, datagram);
       
  1277     fsm->slave_state = ec_fsm_slaveconf_state_clear_fmmus;
       
  1278 }
       
  1279 
       
  1280 /*****************************************************************************/
       
  1281 
       
  1282 /**
       
  1283    Slave configuration state: CLEAR FMMU.
       
  1284 */
       
  1285 
       
  1286 void ec_fsm_slaveconf_state_clear_fmmus(ec_fsm_t *fsm
       
  1287                                         /**< finite state machine */)
       
  1288 {
       
  1289     ec_datagram_t *datagram = &fsm->datagram;
       
  1290 
       
  1291     if (datagram->state != EC_DATAGRAM_RECEIVED
       
  1292         || datagram->working_counter != 1) {
       
  1293         fsm->slave->error_flag = 1;
       
  1294         fsm->slave_state = ec_fsm_slave_state_error;
       
  1295         EC_ERR("Failed to clear FMMUs on slave %i.\n",
       
  1296                fsm->slave->ring_position);
       
  1297         return;
       
  1298     }
       
  1299 
       
  1300     ec_fsm_slaveconf_enter_sync(fsm);
       
  1301 }
       
  1302 
       
  1303 /*****************************************************************************/
       
  1304 
       
  1305 /**
       
  1306 */
       
  1307 
       
  1308 void ec_fsm_slaveconf_enter_sync(ec_fsm_t *fsm /**< finite state machine */)
  1234 {
  1309 {
  1235     ec_master_t *master = fsm->master;
  1310     ec_master_t *master = fsm->master;
  1236     ec_slave_t *slave = fsm->slave;
  1311     ec_slave_t *slave = fsm->slave;
  1237     ec_datagram_t *datagram = &fsm->datagram;
  1312     ec_datagram_t *datagram = &fsm->datagram;
  1238     const ec_sii_sync_t *sync;
  1313     const ec_sii_sync_t *sync;
  1239     ec_sii_sync_t mbox_sync;
  1314     ec_sii_sync_t mbox_sync;
  1240 
  1315 
  1241     if (ec_fsm_change_exec(&fsm->fsm_change)) return;
       
  1242 
       
  1243     if (!ec_fsm_change_success(&fsm->fsm_change)) {
       
  1244         slave->error_flag = 1;
       
  1245         fsm->slave_state = ec_fsm_slave_error;
       
  1246         return;
       
  1247     }
       
  1248 
       
  1249     slave->configured = 1;
       
  1250 
       
  1251     if (master->debug_level) {
       
  1252         EC_DBG("Slave %i is now in INIT.\n", slave->ring_position);
       
  1253     }
       
  1254 
       
  1255     // slave is now in INIT
  1316     // slave is now in INIT
  1256     if (slave->current_state == slave->requested_state) {
  1317     if (slave->current_state == slave->requested_state) {
  1257         fsm->slave_state = ec_fsm_slave_end; // successful
  1318         fsm->slave_state = ec_fsm_slave_state_end; // successful
  1258         if (master->debug_level) {
  1319         if (master->debug_level) {
  1259             EC_DBG("Finished configuration of slave %i.\n",
  1320             EC_DBG("Finished configuration of slave %i.\n",
  1260                    slave->ring_position);
  1321                    slave->ring_position);
  1261         }
  1322         }
  1262         return;
  1323         return;
  1263     }
  1324     }
  1264 
  1325 
  1265     // check and reset CRC fault counters
       
  1266     //ec_slave_check_crc(slave);
       
  1267     // TODO: Implement state machine for CRC checking.
       
  1268 
       
  1269     if (!slave->base_sync_count) { // no sync managers
  1326     if (!slave->base_sync_count) { // no sync managers
  1270         fsm->slave_state = ec_fsm_slaveconf_preop;
  1327         ec_fsm_slaveconf_enter_preop(fsm);
  1271         ec_fsm_change_start(&fsm->fsm_change, slave, EC_SLAVE_STATE_PREOP);
       
  1272         ec_fsm_change_exec(&fsm->fsm_change); // execute immediately
       
  1273         return;
  1328         return;
  1274     }
  1329     }
  1275 
  1330 
  1276     if (master->debug_level) {
  1331     if (master->debug_level) {
  1277         EC_DBG("Configuring sync managers of slave %i.\n",
  1332         EC_DBG("Configuring sync managers of slave %i.\n",
  1309     else {
  1364     else {
  1310         list_for_each_entry(sync, &slave->sii_syncs, list) {
  1365         list_for_each_entry(sync, &slave->sii_syncs, list) {
  1311             if (sync->index >= slave->base_sync_count) {
  1366             if (sync->index >= slave->base_sync_count) {
  1312                 EC_ERR("Invalid sync manager configuration found!");
  1367                 EC_ERR("Invalid sync manager configuration found!");
  1313                 fsm->slave->error_flag = 1;
  1368                 fsm->slave->error_flag = 1;
  1314                 fsm->slave_state = ec_fsm_slave_error;
  1369                 fsm->slave_state = ec_fsm_slave_state_error;
  1315                 return;
  1370                 return;
  1316             }
  1371             }
  1317             ec_sync_config(sync, slave,
  1372             ec_sync_config(sync, slave,
  1318                            datagram->data + EC_SYNC_SIZE * sync->index);
  1373                            datagram->data + EC_SYNC_SIZE * sync->index);
  1319         }
  1374         }
  1320     }
  1375     }
  1321 
  1376 
  1322     ec_master_queue_datagram(fsm->master, datagram);
  1377     ec_master_queue_datagram(fsm->master, datagram);
  1323     fsm->slave_state = ec_fsm_slaveconf_sync;
  1378     fsm->slave_state = ec_fsm_slaveconf_state_sync;
  1324 }
  1379 }
  1325 
  1380 
  1326 /*****************************************************************************/
  1381 /*****************************************************************************/
  1327 
  1382 
  1328 /**
  1383 /**
  1329    Slave configuration state: SYNC.
  1384    Slave configuration state: SYNC.
  1330 */
  1385 */
  1331 
  1386 
  1332 void ec_fsm_slaveconf_sync(ec_fsm_t *fsm /**< finite state machine */)
  1387 void ec_fsm_slaveconf_state_sync(ec_fsm_t *fsm /**< finite state machine */)
  1333 {
  1388 {
  1334     ec_datagram_t *datagram = &fsm->datagram;
  1389     ec_datagram_t *datagram = &fsm->datagram;
  1335     ec_slave_t *slave = fsm->slave;
  1390     ec_slave_t *slave = fsm->slave;
  1336 
  1391 
  1337     if (datagram->state != EC_DATAGRAM_RECEIVED
  1392     if (datagram->state != EC_DATAGRAM_RECEIVED
  1338         || datagram->working_counter != 1) {
  1393         || datagram->working_counter != 1) {
  1339         slave->error_flag = 1;
  1394         slave->error_flag = 1;
  1340         fsm->slave_state = ec_fsm_slave_error;
  1395         fsm->slave_state = ec_fsm_slave_state_error;
  1341         EC_ERR("Failed to set sync managers on slave %i.\n",
  1396         EC_ERR("Failed to set sync managers on slave %i.\n",
  1342                slave->ring_position);
  1397                slave->ring_position);
  1343         return;
  1398         return;
  1344     }
  1399     }
  1345 
  1400 
  1346     fsm->slave_state = ec_fsm_slaveconf_preop;
  1401     ec_fsm_slaveconf_enter_preop(fsm);
  1347     ec_fsm_change_start(&fsm->fsm_change, slave, EC_SLAVE_STATE_PREOP);
  1402 }
       
  1403 
       
  1404 /*****************************************************************************/
       
  1405 
       
  1406 /**
       
  1407  */
       
  1408 
       
  1409 void ec_fsm_slaveconf_enter_preop(ec_fsm_t *fsm /**< finite state machine */)
       
  1410 {
       
  1411     fsm->slave_state = ec_fsm_slaveconf_state_preop;
       
  1412     ec_fsm_change_start(&fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_PREOP);
  1348     ec_fsm_change_exec(&fsm->fsm_change); // execute immediately
  1413     ec_fsm_change_exec(&fsm->fsm_change); // execute immediately
  1349 }
  1414 }
  1350 
  1415 
  1351 /*****************************************************************************/
  1416 /*****************************************************************************/
  1352 
  1417 
  1353 /**
  1418 /**
  1354    Slave configuration state: PREOP.
  1419    Slave configuration state: PREOP.
  1355 */
  1420 */
  1356 
  1421 
  1357 void ec_fsm_slaveconf_preop(ec_fsm_t *fsm /**< finite state machine */)
  1422 void ec_fsm_slaveconf_state_preop(ec_fsm_t *fsm /**< finite state machine */)
  1358 {
  1423 {
  1359     ec_slave_t *slave = fsm->slave;
  1424     ec_slave_t *slave = fsm->slave;
  1360     ec_master_t *master = fsm->master;
  1425     ec_master_t *master = fsm->master;
  1361     ec_datagram_t *datagram = &fsm->datagram;
  1426     ec_datagram_t *datagram = &fsm->datagram;
  1362     unsigned int j;
  1427     unsigned int j;
  1363 
  1428 
  1364     if (ec_fsm_change_exec(&fsm->fsm_change)) return;
  1429     if (ec_fsm_change_exec(&fsm->fsm_change)) return;
  1365 
  1430 
  1366     if (!ec_fsm_change_success(&fsm->fsm_change)) {
  1431     if (!ec_fsm_change_success(&fsm->fsm_change)) {
  1367         slave->error_flag = 1;
  1432         slave->error_flag = 1;
  1368         fsm->slave_state = ec_fsm_slave_error;
  1433         fsm->slave_state = ec_fsm_slave_state_error;
  1369         return;
  1434         return;
  1370     }
  1435     }
  1371 
  1436 
  1372     // slave is now in PREOP
  1437     // slave is now in PREOP
  1373     slave->jiffies_preop = fsm->datagram.jiffies_received;
  1438     slave->jiffies_preop = fsm->datagram.jiffies_received;
  1375     if (master->debug_level) {
  1440     if (master->debug_level) {
  1376         EC_DBG("Slave %i is now in PREOP.\n", slave->ring_position);
  1441         EC_DBG("Slave %i is now in PREOP.\n", slave->ring_position);
  1377     }
  1442     }
  1378 
  1443 
  1379     if (slave->current_state == slave->requested_state) {
  1444     if (slave->current_state == slave->requested_state) {
  1380         fsm->slave_state = ec_fsm_slave_end; // successful
  1445         fsm->slave_state = ec_fsm_slave_state_end; // successful
  1381         if (master->debug_level) {
  1446         if (master->debug_level) {
  1382             EC_DBG("Finished configuration of slave %i.\n",
  1447             EC_DBG("Finished configuration of slave %i.\n",
  1383                    slave->ring_position);
  1448                    slave->ring_position);
  1384         }
  1449         }
  1385         return;
  1450         return;
  1386     }
  1451     }
  1387 
  1452 
  1388     if (!slave->base_fmmu_count) { // skip FMMU configuration
  1453     if (!slave->base_fmmu_count) { // skip FMMU configuration
  1389         if (list_empty(&slave->sdo_confs)) { // skip SDO configuration
  1454         if (list_empty(&slave->sdo_confs)) { // skip SDO configuration
  1390             fsm->slave_state = ec_fsm_slaveconf_saveop;
  1455             ec_fsm_slaveconf_enter_saveop(fsm);
  1391             ec_fsm_change_start(&fsm->fsm_change, slave,
       
  1392                                 EC_SLAVE_STATE_SAVEOP);
       
  1393             ec_fsm_change_exec(&fsm->fsm_change); // execute immediately
       
  1394             return;
  1456             return;
  1395         }
  1457         }
  1396 
  1458 
  1397         // start SDO configuration
  1459         ec_fsm_slaveconf_enter_sdoconf(fsm);
  1398         fsm->slave_state = ec_fsm_slaveconf_sdoconf;
       
  1399         fsm->sdodata = list_entry(slave->sdo_confs.next, ec_sdo_data_t, list);
       
  1400         ec_fsm_coe_download(&fsm->fsm_coe, slave, fsm->sdodata);
       
  1401         ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
       
  1402         return;
  1460         return;
  1403     }
  1461     }
  1404 
  1462 
  1405     // configure FMMUs
  1463     // configure FMMUs
  1406     ec_datagram_npwr(datagram, slave->station_address,
  1464     ec_datagram_npwr(datagram, slave->station_address,
  1410         ec_fmmu_config(&slave->fmmus[j], slave,
  1468         ec_fmmu_config(&slave->fmmus[j], slave,
  1411                        datagram->data + EC_FMMU_SIZE * j);
  1469                        datagram->data + EC_FMMU_SIZE * j);
  1412     }
  1470     }
  1413 
  1471 
  1414     ec_master_queue_datagram(master, datagram);
  1472     ec_master_queue_datagram(master, datagram);
  1415     fsm->slave_state = ec_fsm_slaveconf_fmmu;
  1473     fsm->slave_state = ec_fsm_slaveconf_state_fmmu;
  1416 }
  1474 }
  1417 
  1475 
  1418 /*****************************************************************************/
  1476 /*****************************************************************************/
  1419 
  1477 
  1420 /**
  1478 /**
  1421    Slave configuration state: FMMU.
  1479    Slave configuration state: FMMU.
  1422 */
  1480 */
  1423 
  1481 
  1424 void ec_fsm_slaveconf_fmmu(ec_fsm_t *fsm /**< finite state machine */)
  1482 void ec_fsm_slaveconf_state_fmmu(ec_fsm_t *fsm /**< finite state machine */)
  1425 {
  1483 {
  1426     ec_datagram_t *datagram = &fsm->datagram;
  1484     ec_datagram_t *datagram = &fsm->datagram;
  1427     ec_slave_t *slave = fsm->slave;
  1485     ec_slave_t *slave = fsm->slave;
  1428 
  1486 
  1429     if (datagram->state != EC_DATAGRAM_RECEIVED
  1487     if (datagram->state != EC_DATAGRAM_RECEIVED
  1430         || datagram->working_counter != 1) {
  1488         || datagram->working_counter != 1) {
  1431         fsm->slave->error_flag = 1;
  1489         fsm->slave->error_flag = 1;
  1432         fsm->slave_state = ec_fsm_slave_error;
  1490         fsm->slave_state = ec_fsm_slave_state_error;
  1433         EC_ERR("Failed to set FMMUs on slave %i.\n",
  1491         EC_ERR("Failed to set FMMUs on slave %i.\n",
  1434                fsm->slave->ring_position);
  1492                fsm->slave->ring_position);
  1435         return;
  1493         return;
  1436     }
  1494     }
  1437 
  1495 
  1438     // No CoE configuration to be applied? Jump to SAVEOP state.
  1496     // No CoE configuration to be applied? Jump to SAVEOP state.
  1439     if (list_empty(&slave->sdo_confs)) { // skip SDO configuration
  1497     if (list_empty(&slave->sdo_confs)) { // skip SDO configuration
  1440         // set state to SAVEOP
  1498         ec_fsm_slaveconf_enter_saveop(fsm);
  1441         fsm->slave_state = ec_fsm_slaveconf_saveop;
  1499         return;
  1442         ec_fsm_change_start(&fsm->fsm_change, slave, EC_SLAVE_STATE_SAVEOP);
  1500     }
  1443         ec_fsm_change_exec(&fsm->fsm_change); // execute immediately
  1501 
  1444         return;
  1502     ec_fsm_slaveconf_enter_sdoconf(fsm);
  1445     }
  1503 }
  1446 
  1504 
       
  1505 /*****************************************************************************/
       
  1506 
       
  1507 /**
       
  1508  */
       
  1509 
       
  1510 void ec_fsm_slaveconf_enter_sdoconf(ec_fsm_t *fsm /**< finite state machine */)
       
  1511 {
  1447     // start SDO configuration
  1512     // start SDO configuration
  1448     fsm->slave_state = ec_fsm_slaveconf_sdoconf;
  1513     fsm->slave_state = ec_fsm_slaveconf_state_sdoconf;
  1449     fsm->sdodata = list_entry(slave->sdo_confs.next, ec_sdo_data_t, list);
  1514     fsm->sdodata = list_entry(fsm->slave->sdo_confs.next, ec_sdo_data_t, list);
  1450     ec_fsm_coe_download(&fsm->fsm_coe, slave, fsm->sdodata);
  1515     ec_fsm_coe_download(&fsm->fsm_coe, fsm->slave, fsm->sdodata);
  1451     ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
  1516     ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
  1452 }
  1517 }
  1453 
  1518 
  1454 /*****************************************************************************/
  1519 /*****************************************************************************/
  1455 
  1520 
  1456 /**
  1521 /**
  1457    Slave configuration state: SDOCONF.
  1522    Slave configuration state: SDOCONF.
  1458 */
  1523 */
  1459 
  1524 
  1460 void ec_fsm_slaveconf_sdoconf(ec_fsm_t *fsm /**< finite state machine */)
  1525 void ec_fsm_slaveconf_state_sdoconf(ec_fsm_t *fsm /**< finite state machine */)
  1461 {
  1526 {
  1462     if (ec_fsm_coe_exec(&fsm->fsm_coe)) return;
  1527     if (ec_fsm_coe_exec(&fsm->fsm_coe)) return;
  1463 
  1528 
  1464     if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
  1529     if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
  1465         fsm->slave->error_flag = 1;
  1530         fsm->slave->error_flag = 1;
  1466         fsm->slave_state = ec_fsm_slave_error;
  1531         fsm->slave_state = ec_fsm_slave_state_error;
  1467         return;
  1532         return;
  1468     }
  1533     }
  1469 
  1534 
  1470     // Another SDO to configure?
  1535     // Another SDO to configure?
  1471     if (fsm->sdodata->list.next != &fsm->slave->sdo_confs) {
  1536     if (fsm->sdodata->list.next != &fsm->slave->sdo_confs) {
  1477     }
  1542     }
  1478 
  1543 
  1479     // All SDOs are now configured.
  1544     // All SDOs are now configured.
  1480 
  1545 
  1481     // set state to SAVEOP
  1546     // set state to SAVEOP
  1482     fsm->slave_state = ec_fsm_slaveconf_saveop;
  1547     ec_fsm_slaveconf_enter_saveop(fsm);
       
  1548 }
       
  1549 
       
  1550 /*****************************************************************************/
       
  1551 
       
  1552 /**
       
  1553  */
       
  1554 
       
  1555 void ec_fsm_slaveconf_enter_saveop(ec_fsm_t *fsm /**< finite state machine */)
       
  1556 {
       
  1557     fsm->slave_state = ec_fsm_slaveconf_state_saveop;
  1483     ec_fsm_change_start(&fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_SAVEOP);
  1558     ec_fsm_change_start(&fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_SAVEOP);
  1484     ec_fsm_change_exec(&fsm->fsm_change); // execute immediately
  1559     ec_fsm_change_exec(&fsm->fsm_change); // execute immediately
  1485 }
  1560 }
  1486 
  1561 
  1487 /*****************************************************************************/
  1562 /*****************************************************************************/
  1488 
  1563 
  1489 /**
  1564 /**
  1490    Slave configuration state: SAVEOP.
  1565    Slave configuration state: SAVEOP.
  1491 */
  1566 */
  1492 
  1567 
  1493 void ec_fsm_slaveconf_saveop(ec_fsm_t *fsm /**< finite state machine */)
  1568 void ec_fsm_slaveconf_state_saveop(ec_fsm_t *fsm /**< finite state machine */)
  1494 {
  1569 {
  1495     ec_master_t *master = fsm->master;
  1570     ec_master_t *master = fsm->master;
  1496     ec_slave_t *slave = fsm->slave;
  1571     ec_slave_t *slave = fsm->slave;
  1497 
  1572 
  1498     if (ec_fsm_change_exec(&fsm->fsm_change)) return;
  1573     if (ec_fsm_change_exec(&fsm->fsm_change)) return;
  1499 
  1574 
  1500     if (!ec_fsm_change_success(&fsm->fsm_change)) {
  1575     if (!ec_fsm_change_success(&fsm->fsm_change)) {
  1501         fsm->slave->error_flag = 1;
  1576         fsm->slave->error_flag = 1;
  1502         fsm->slave_state = ec_fsm_slave_error;
  1577         fsm->slave_state = ec_fsm_slave_state_error;
  1503         return;
  1578         return;
  1504     }
  1579     }
  1505 
  1580 
  1506     // slave is now in SAVEOP
  1581     // slave is now in SAVEOP
  1507 
  1582 
  1508     if (master->debug_level) {
  1583     if (master->debug_level) {
  1509         EC_DBG("Slave %i is now in SAVEOP.\n", slave->ring_position);
  1584         EC_DBG("Slave %i is now in SAVEOP.\n", slave->ring_position);
  1510     }
  1585     }
  1511 
  1586 
  1512     if (fsm->slave->current_state == fsm->slave->requested_state) {
  1587     if (fsm->slave->current_state == fsm->slave->requested_state) {
  1513         fsm->slave_state = ec_fsm_slave_end; // successful
  1588         fsm->slave_state = ec_fsm_slave_state_end; // successful
  1514         if (master->debug_level) {
  1589         if (master->debug_level) {
  1515             EC_DBG("Finished configuration of slave %i.\n",
  1590             EC_DBG("Finished configuration of slave %i.\n",
  1516                    slave->ring_position);
  1591                    slave->ring_position);
  1517         }
  1592         }
  1518         return;
  1593         return;
  1519     }
  1594     }
  1520 
  1595 
  1521     // set state to OP
  1596     // set state to OP
  1522     fsm->slave_state = ec_fsm_slaveconf_op;
  1597     fsm->slave_state = ec_fsm_slaveconf_state_op;
  1523     ec_fsm_change_start(&fsm->fsm_change, slave, EC_SLAVE_STATE_OP);
  1598     ec_fsm_change_start(&fsm->fsm_change, slave, EC_SLAVE_STATE_OP);
  1524     ec_fsm_change_exec(&fsm->fsm_change); // execute immediately
  1599     ec_fsm_change_exec(&fsm->fsm_change); // execute immediately
  1525 }
  1600 }
  1526 
  1601 
  1527 /*****************************************************************************/
  1602 /*****************************************************************************/
  1528 
  1603 
  1529 /**
  1604 /**
  1530    Slave configuration state: OP
  1605    Slave configuration state: OP
  1531 */
  1606 */
  1532 
  1607 
  1533 void ec_fsm_slaveconf_op(ec_fsm_t *fsm /**< finite state machine */)
  1608 void ec_fsm_slaveconf_state_op(ec_fsm_t *fsm /**< finite state machine */)
  1534 {
  1609 {
  1535     ec_master_t *master = fsm->master;
  1610     ec_master_t *master = fsm->master;
  1536     ec_slave_t *slave = fsm->slave;
  1611     ec_slave_t *slave = fsm->slave;
  1537 
  1612 
  1538     if (ec_fsm_change_exec(&fsm->fsm_change)) return;
  1613     if (ec_fsm_change_exec(&fsm->fsm_change)) return;
  1539 
  1614 
  1540     if (!ec_fsm_change_success(&fsm->fsm_change)) {
  1615     if (!ec_fsm_change_success(&fsm->fsm_change)) {
  1541         slave->error_flag = 1;
  1616         slave->error_flag = 1;
  1542         fsm->slave_state = ec_fsm_slave_error;
  1617         fsm->slave_state = ec_fsm_slave_state_error;
  1543         return;
  1618         return;
  1544     }
  1619     }
  1545 
  1620 
  1546     // slave is now in OP
  1621     // slave is now in OP
  1547 
  1622 
  1548     if (master->debug_level) {
  1623     if (master->debug_level) {
  1549         EC_DBG("Slave %i is now in OP.\n", slave->ring_position);
  1624         EC_DBG("Slave %i is now in OP.\n", slave->ring_position);
  1550         EC_DBG("Finished configuration of slave %i.\n", slave->ring_position);
  1625         EC_DBG("Finished configuration of slave %i.\n", slave->ring_position);
  1551     }
  1626     }
  1552 
  1627 
  1553     fsm->slave_state = ec_fsm_slave_end; // successful
  1628     fsm->slave_state = ec_fsm_slave_state_end; // successful
  1554 }
  1629 }
  1555 
  1630 
  1556 /******************************************************************************
  1631 /******************************************************************************
  1557  *  Common state functions
  1632  *  Common state functions
  1558  *****************************************************************************/
  1633  *****************************************************************************/
  1559 
  1634 
  1560 /**
  1635 /**
  1561    State: ERROR.
  1636    State: ERROR.
  1562 */
  1637 */
  1563 
  1638 
  1564 void ec_fsm_slave_error(ec_fsm_t *fsm /**< finite state machine */)
  1639 void ec_fsm_slave_state_error(ec_fsm_t *fsm /**< finite state machine */)
  1565 {
  1640 {
  1566 }
  1641 }
  1567 
  1642 
  1568 /*****************************************************************************/
  1643 /*****************************************************************************/
  1569 
  1644 
  1570 /**
  1645 /**
  1571    State: END.
  1646    State: END.
  1572 */
  1647 */
  1573 
  1648 
  1574 void ec_fsm_slave_end(ec_fsm_t *fsm /**< finite state machine */)
  1649 void ec_fsm_slave_state_end(ec_fsm_t *fsm /**< finite state machine */)
  1575 {
  1650 {
  1576 }
  1651 }
  1577 
  1652 
  1578 /*****************************************************************************/
  1653 /*****************************************************************************/