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; |