master/fsm.c
changeset 309 42e69cf31495
parent 308 d50b139c8601
child 310 b7e7709fd40e
equal deleted inserted replaced
308:d50b139c8601 309:42e69cf31495
    61 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *);
    61 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *);
    62 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *);
    62 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *);
    63 void ec_fsm_slavescan_eeprom_data2(ec_fsm_t *);
    63 void ec_fsm_slavescan_eeprom_data2(ec_fsm_t *);
    64 void ec_fsm_slavescan_end(ec_fsm_t *);
    64 void ec_fsm_slavescan_end(ec_fsm_t *);
    65 
    65 
    66 void ec_fsm_slaveconf_start(ec_fsm_t *);
    66 void ec_fsm_slaveconf_init(ec_fsm_t *);
    67 void ec_fsm_slaveconf_sync(ec_fsm_t *);
    67 void ec_fsm_slaveconf_sync(ec_fsm_t *);
    68 void ec_fsm_slaveconf_preop(ec_fsm_t *);
    68 void ec_fsm_slaveconf_preop(ec_fsm_t *);
    69 void ec_fsm_slaveconf_fmmu(ec_fsm_t *);
    69 void ec_fsm_slaveconf_fmmu(ec_fsm_t *);
    70 void ec_fsm_slaveconf_saveop(ec_fsm_t *);
    70 void ec_fsm_slaveconf_saveop(ec_fsm_t *);
    71 void ec_fsm_slaveconf_op(ec_fsm_t *);
    71 void ec_fsm_slaveconf_op(ec_fsm_t *);
    72 void ec_fsm_slaveconf_op2(ec_fsm_t *);
       
    73 void ec_fsm_slaveconf_end(ec_fsm_t *);
    72 void ec_fsm_slaveconf_end(ec_fsm_t *);
    74 
    73 
    75 void ec_fsm_sii_start_reading(ec_fsm_t *);
    74 void ec_fsm_sii_start_reading(ec_fsm_t *);
    76 void ec_fsm_sii_read_check(ec_fsm_t *);
    75 void ec_fsm_sii_read_check(ec_fsm_t *);
    77 void ec_fsm_sii_read_fetch(ec_fsm_t *);
    76 void ec_fsm_sii_read_fetch(ec_fsm_t *);
   302         printk(" to ");
   301         printk(" to ");
   303         ec_print_states(slave->requested_state);
   302         ec_print_states(slave->requested_state);
   304         printk(".\n");
   303         printk(".\n");
   305 
   304 
   306         fsm->slave = slave;
   305         fsm->slave = slave;
   307         fsm->slave_state = ec_fsm_slaveconf_start;
   306         fsm->slave_state = ec_fsm_slaveconf_init;
   308         fsm->change_new = EC_SLAVE_STATE_INIT;
   307         fsm->change_new = EC_SLAVE_STATE_INIT;
   309         fsm->change_state = ec_fsm_change_start;
   308         fsm->change_state = ec_fsm_change_start;
   310         fsm->master_state = ec_fsm_master_configure_slave;
   309         fsm->master_state = ec_fsm_master_configure_slave;
   311         fsm->master_state(fsm); // execute immediately
   310         fsm->master_state(fsm); // execute immediately
   312         return;
   311         return;
  1080 /******************************************************************************
  1079 /******************************************************************************
  1081  *  slave configuration sub state machine
  1080  *  slave configuration sub state machine
  1082  *****************************************************************************/
  1081  *****************************************************************************/
  1083 
  1082 
  1084 /**
  1083 /**
  1085    Slave state: CONF.
  1084    Slave state: INIT.
  1086 */
  1085 */
  1087 
  1086 
  1088 void ec_fsm_slaveconf_start(ec_fsm_t *fsm /**< finite state machine */)
  1087 void ec_fsm_slaveconf_init(ec_fsm_t *fsm /**< finite state machine */)
  1089 {
  1088 {
  1090     ec_slave_t *slave = fsm->slave;
  1089     ec_slave_t *slave = fsm->slave;
  1091     ec_master_t *master = fsm->master;
  1090     ec_datagram_t *datagram = &fsm->datagram;
  1092     ec_datagram_t *datagram = &fsm->datagram;
  1091     const ec_sync_t *sync;
       
  1092     ec_eeprom_sync_t *eeprom_sync, mbox_sync;
       
  1093     unsigned int j;
  1093 
  1094 
  1094     fsm->change_state(fsm); // execute state change state machine
  1095     fsm->change_state(fsm); // execute state change state machine
  1095 
  1096 
  1096     if (fsm->change_state == ec_fsm_change_error) {
  1097     if (fsm->change_state == ec_fsm_change_error) {
  1097         slave->error_flag = 1;
  1098         slave->error_flag = 1;
  1112         EC_WARN("Slave %i has unknown type!\n", slave->ring_position);
  1113         EC_WARN("Slave %i has unknown type!\n", slave->ring_position);
  1113     }
  1114     }
  1114 
  1115 
  1115     // check and reset CRC fault counters
  1116     // check and reset CRC fault counters
  1116     //ec_slave_check_crc(slave);
  1117     //ec_slave_check_crc(slave);
  1117 
  1118     // TODO!
  1118     if (!slave->base_fmmu_count) { // no fmmus
       
  1119         fsm->slave_state = ec_fsm_slaveconf_sync;
       
  1120         fsm->slave_state(fsm); // execute immediately
       
  1121         return;
       
  1122     }
       
  1123 
       
  1124     // reset FMMUs
       
  1125     ec_datagram_npwr(datagram, slave->station_address, 0x0600,
       
  1126                      EC_FMMU_SIZE * slave->base_fmmu_count);
       
  1127     memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
       
  1128     ec_master_queue_datagram(master, datagram);
       
  1129     fsm->slave_state = ec_fsm_slaveconf_sync;
       
  1130 }
       
  1131 
       
  1132 /*****************************************************************************/
       
  1133 
       
  1134 /**
       
  1135    Slave state: SYNC.
       
  1136    Configure sync managers.
       
  1137 */
       
  1138 
       
  1139 void ec_fsm_slaveconf_sync(ec_fsm_t *fsm /**< finite state machine */)
       
  1140 {
       
  1141     ec_datagram_t *datagram = &fsm->datagram;
       
  1142     ec_slave_t *slave = fsm->slave;
       
  1143     unsigned int j;
       
  1144     const ec_sync_t *sync;
       
  1145     ec_eeprom_sync_t *eeprom_sync, mbox_sync;
       
  1146 
       
  1147     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
       
  1148         slave->error_flag = 1;
       
  1149         fsm->slave_state = ec_fsm_slaveconf_end;
       
  1150         EC_ERR("Failed to reset FMMUs of slave %i.\n",
       
  1151                slave->ring_position);
       
  1152         return;
       
  1153     }
       
  1154 
  1119 
  1155     if (!slave->base_sync_count) { // no sync managers
  1120     if (!slave->base_sync_count) { // no sync managers
  1156         fsm->slave_state = ec_fsm_slaveconf_preop;
  1121         fsm->slave_state = ec_fsm_slaveconf_preop;
  1157         fsm->slave_state(fsm); // execute immediately
  1122         fsm->change_new = EC_SLAVE_STATE_PREOP;
       
  1123         fsm->change_state = ec_fsm_change_start;
       
  1124         fsm->change_state(fsm); // execute immediately
  1158         return;
  1125         return;
  1159     }
  1126     }
  1160 
  1127 
  1161     // configure sync managers
  1128     // configure sync managers
  1162     ec_datagram_npwr(datagram, slave->station_address, 0x0800,
  1129     ec_datagram_npwr(datagram, slave->station_address, 0x0800,
  1209         EC_INFO("Mailbox configured for unknown slave %i\n",
  1176         EC_INFO("Mailbox configured for unknown slave %i\n",
  1210                 slave->ring_position);
  1177                 slave->ring_position);
  1211     }
  1178     }
  1212 
  1179 
  1213     ec_master_queue_datagram(fsm->master, datagram);
  1180     ec_master_queue_datagram(fsm->master, datagram);
  1214     fsm->slave_state = ec_fsm_slaveconf_preop;
  1181     fsm->slave_state = ec_fsm_slaveconf_sync;
  1215 }
  1182 }
  1216 
  1183 
  1217 /*****************************************************************************/
  1184 /*****************************************************************************/
  1218 
  1185 
  1219 /**
  1186 /**
  1220    Slave state: PREOP.
  1187    Slave state: SYNC.
  1221    Change slave state to PREOP.
  1188 */
  1222 */
  1189 
  1223 
  1190 void ec_fsm_slaveconf_sync(ec_fsm_t *fsm /**< finite state machine */)
  1224 void ec_fsm_slaveconf_preop(ec_fsm_t *fsm /**< finite state machine */)
       
  1225 {
  1191 {
  1226     ec_datagram_t *datagram = &fsm->datagram;
  1192     ec_datagram_t *datagram = &fsm->datagram;
  1227     ec_slave_t *slave = fsm->slave;
  1193     ec_slave_t *slave = fsm->slave;
  1228 
  1194 
  1229     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1195     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1232         EC_ERR("Failed to set sync managers on slave %i.\n",
  1198         EC_ERR("Failed to set sync managers on slave %i.\n",
  1233                slave->ring_position);
  1199                slave->ring_position);
  1234         return;
  1200         return;
  1235     }
  1201     }
  1236 
  1202 
       
  1203     fsm->slave_state = ec_fsm_slaveconf_preop;
  1237     fsm->change_new = EC_SLAVE_STATE_PREOP;
  1204     fsm->change_new = EC_SLAVE_STATE_PREOP;
  1238     fsm->change_state = ec_fsm_change_start;
  1205     fsm->change_state = ec_fsm_change_start;
  1239     fsm->slave_state = ec_fsm_slaveconf_fmmu;
       
  1240     fsm->change_state(fsm); // execute immediately
  1206     fsm->change_state(fsm); // execute immediately
  1241 }
  1207 }
  1242 
  1208 
  1243 /*****************************************************************************/
  1209 /*****************************************************************************/
  1244 
  1210 
  1245 /**
  1211 /**
  1246    Slave state: FMMU.
  1212    Slave state: PREOP.
  1247    Configure FMMUs.
  1213 */
  1248 */
  1214 
  1249 
  1215 void ec_fsm_slaveconf_preop(ec_fsm_t *fsm /**< finite state machine */)
  1250 void ec_fsm_slaveconf_fmmu(ec_fsm_t *fsm /**< finite state machine */)
       
  1251 {
  1216 {
  1252     ec_slave_t *slave = fsm->slave;
  1217     ec_slave_t *slave = fsm->slave;
  1253     ec_master_t *master = fsm->master;
  1218     ec_master_t *master = fsm->master;
  1254     ec_datagram_t *datagram = &fsm->datagram;
  1219     ec_datagram_t *datagram = &fsm->datagram;
  1255     unsigned int j;
  1220     unsigned int j;
  1276         return;
  1241         return;
  1277     }
  1242     }
  1278 
  1243 
  1279     if (!slave->base_fmmu_count) {
  1244     if (!slave->base_fmmu_count) {
  1280         fsm->slave_state = ec_fsm_slaveconf_saveop;
  1245         fsm->slave_state = ec_fsm_slaveconf_saveop;
  1281         fsm->slave_state(fsm); // execute immediately
  1246         fsm->change_new = EC_SLAVE_STATE_SAVEOP;
       
  1247         fsm->change_state = ec_fsm_change_start;
       
  1248         fsm->change_state(fsm); // execute immediately
  1282         return;
  1249         return;
  1283     }
  1250     }
  1284 
  1251 
  1285     // configure FMMUs
  1252     // configure FMMUs
  1286     ec_datagram_npwr(datagram, slave->station_address,
  1253     ec_datagram_npwr(datagram, slave->station_address,
  1290         ec_fmmu_config(&slave->fmmus[j], slave,
  1257         ec_fmmu_config(&slave->fmmus[j], slave,
  1291                        datagram->data + EC_FMMU_SIZE * j);
  1258                        datagram->data + EC_FMMU_SIZE * j);
  1292     }
  1259     }
  1293 
  1260 
  1294     ec_master_queue_datagram(master, datagram);
  1261     ec_master_queue_datagram(master, datagram);
  1295     fsm->slave_state = ec_fsm_slaveconf_saveop;
  1262     fsm->slave_state = ec_fsm_slaveconf_fmmu;
  1296 }
  1263 }
  1297 
  1264 
  1298 /*****************************************************************************/
  1265 /*****************************************************************************/
  1299 
  1266 
  1300 /**
  1267 /**
  1301    Slave state: SAVEOP.
  1268    Slave state: FMMU.
  1302    Set slave state to SAVEOP.
  1269 */
  1303 */
  1270 
  1304 
  1271 void ec_fsm_slaveconf_fmmu(ec_fsm_t *fsm /**< finite state machine */)
  1305 void ec_fsm_slaveconf_saveop(ec_fsm_t *fsm /**< finite state machine */)
  1272 {
  1306 {
  1273     ec_datagram_t *datagram = &fsm->datagram;
  1307     ec_datagram_t *datagram = &fsm->datagram;
  1274 
  1308 
  1275     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1309     if (fsm->slave->base_fmmu_count && (datagram->state != EC_CMD_RECEIVED ||
       
  1310                                         datagram->working_counter != 1)) {
       
  1311         fsm->slave->error_flag = 1;
  1276         fsm->slave->error_flag = 1;
  1312         fsm->slave_state = ec_fsm_slaveconf_end;
  1277         fsm->slave_state = ec_fsm_slaveconf_end;
  1313         EC_ERR("Failed to set FMMUs on slave %i.\n",
  1278         EC_ERR("Failed to set FMMUs on slave %i.\n",
  1314                fsm->slave->ring_position);
  1279                fsm->slave->ring_position);
  1315         return;
  1280         return;
  1316     }
  1281     }
  1317 
  1282 
  1318     // set state to SAVEOP
  1283     // set state to SAVEOP
  1319     fsm->slave_state = ec_fsm_slaveconf_op;
  1284     fsm->slave_state = ec_fsm_slaveconf_saveop;
  1320     fsm->change_new = EC_SLAVE_STATE_SAVEOP;
  1285     fsm->change_new = EC_SLAVE_STATE_SAVEOP;
  1321     fsm->change_state = ec_fsm_change_start;
  1286     fsm->change_state = ec_fsm_change_start;
  1322     fsm->change_state(fsm); // execute immediately
  1287     fsm->change_state(fsm); // execute immediately
  1323 }
  1288 }
  1324 
  1289 
  1325 /*****************************************************************************/
  1290 /*****************************************************************************/
  1326 
  1291 
  1327 /**
  1292 /**
  1328    Slave state: OP.
  1293    Slave state: SAVEOP.
  1329    Set slave state to OP.
  1294 */
  1330 */
  1295 
  1331 
  1296 void ec_fsm_slaveconf_saveop(ec_fsm_t *fsm /**< finite state machine */)
  1332 void ec_fsm_slaveconf_op(ec_fsm_t *fsm /**< finite state machine */)
       
  1333 {
  1297 {
  1334     fsm->change_state(fsm); // execute state change state machine
  1298     fsm->change_state(fsm); // execute state change state machine
  1335 
  1299 
  1336     if (fsm->change_state == ec_fsm_change_error) {
  1300     if (fsm->change_state == ec_fsm_change_error) {
  1337         fsm->slave->error_flag = 1;
  1301         fsm->slave->error_flag = 1;
  1346         fsm->slave_state = ec_fsm_slaveconf_end; // successful
  1310         fsm->slave_state = ec_fsm_slaveconf_end; // successful
  1347         return;
  1311         return;
  1348     }
  1312     }
  1349 
  1313 
  1350     // set state to OP
  1314     // set state to OP
  1351     fsm->slave_state = ec_fsm_slaveconf_op2;
  1315     fsm->slave_state = ec_fsm_slaveconf_op;
  1352     fsm->change_new = EC_SLAVE_STATE_OP;
  1316     fsm->change_new = EC_SLAVE_STATE_OP;
  1353     fsm->change_state = ec_fsm_change_start;
  1317     fsm->change_state = ec_fsm_change_start;
  1354     fsm->change_state(fsm); // execute immediately
  1318     fsm->change_state(fsm); // execute immediately
  1355 }
  1319 }
  1356 
  1320 
  1357 /*****************************************************************************/
  1321 /*****************************************************************************/
  1358 
  1322 
  1359 /**
  1323 /**
  1360    Slave state: OP2
  1324    Slave state: OP
  1361    Executes the change state machine, until the OP state is set.
  1325 */
  1362 */
  1326 
  1363 
  1327 void ec_fsm_slaveconf_op(ec_fsm_t *fsm /**< finite state machine */)
  1364 void ec_fsm_slaveconf_op2(ec_fsm_t *fsm /**< finite state machine */)
       
  1365 {
  1328 {
  1366     fsm->change_state(fsm); // execute state change state machine
  1329     fsm->change_state(fsm); // execute state change state machine
  1367 
  1330 
  1368     if (fsm->change_state == ec_fsm_change_error) {
  1331     if (fsm->change_state == ec_fsm_change_error) {
  1369         fsm->slave->error_flag = 1;
  1332         fsm->slave->error_flag = 1;