master/fsm.c
changeset 433 100f51f28cf2
parent 430 74754f45d5fa
child 434 0180d8277311
equal deleted inserted replaced
432:5e883e0ef95f 433:100f51f28cf2
    78 void ec_fsm_slaveconf_fmmu(ec_fsm_t *);
    78 void ec_fsm_slaveconf_fmmu(ec_fsm_t *);
    79 void ec_fsm_slaveconf_sdoconf(ec_fsm_t *);
    79 void ec_fsm_slaveconf_sdoconf(ec_fsm_t *);
    80 void ec_fsm_slaveconf_saveop(ec_fsm_t *);
    80 void ec_fsm_slaveconf_saveop(ec_fsm_t *);
    81 void ec_fsm_slaveconf_op(ec_fsm_t *);
    81 void ec_fsm_slaveconf_op(ec_fsm_t *);
    82 
    82 
    83 void ec_fsm_sii_start_reading(ec_fsm_t *);
       
    84 void ec_fsm_sii_read_check(ec_fsm_t *);
       
    85 void ec_fsm_sii_read_fetch(ec_fsm_t *);
       
    86 void ec_fsm_sii_start_writing(ec_fsm_t *);
       
    87 void ec_fsm_sii_write_check(ec_fsm_t *);
       
    88 void ec_fsm_sii_write_check2(ec_fsm_t *);
       
    89 
       
    90 void ec_fsm_change_start(ec_fsm_t *);
    83 void ec_fsm_change_start(ec_fsm_t *);
    91 void ec_fsm_change_check(ec_fsm_t *);
    84 void ec_fsm_change_check(ec_fsm_t *);
    92 void ec_fsm_change_status(ec_fsm_t *);
    85 void ec_fsm_change_status(ec_fsm_t *);
    93 void ec_fsm_change_code(ec_fsm_t *);
    86 void ec_fsm_change_code(ec_fsm_t *);
    94 void ec_fsm_change_ack(ec_fsm_t *);
    87 void ec_fsm_change_ack(ec_fsm_t *);
   143     if (ec_datagram_prealloc(&fsm->datagram, EC_MAX_DATA_SIZE)) {
   136     if (ec_datagram_prealloc(&fsm->datagram, EC_MAX_DATA_SIZE)) {
   144         EC_ERR("Failed to allocate FSM datagram.\n");
   137         EC_ERR("Failed to allocate FSM datagram.\n");
   145         return -1;
   138         return -1;
   146     }
   139     }
   147 
   140 
       
   141     ec_fsm_sii_init(&fsm->fsm_sii, &fsm->datagram);
       
   142 
   148     return 0;
   143     return 0;
   149 }
   144 }
   150 
   145 
   151 /*****************************************************************************/
   146 /*****************************************************************************/
   152 
   147 
   154    Destructor.
   149    Destructor.
   155 */
   150 */
   156 
   151 
   157 void ec_fsm_clear(ec_fsm_t *fsm /**< finite state machine */)
   152 void ec_fsm_clear(ec_fsm_t *fsm /**< finite state machine */)
   158 {
   153 {
       
   154     ec_fsm_sii_clear(&fsm->fsm_sii);
       
   155 
   159     ec_datagram_clear(&fsm->datagram);
   156     ec_datagram_clear(&fsm->datagram);
   160 }
   157 }
   161 
   158 
   162 /*****************************************************************************/
   159 /*****************************************************************************/
   163 
   160 
   686             }
   683             }
   687 
   684 
   688             // found pending EEPROM write operation. execute it!
   685             // found pending EEPROM write operation. execute it!
   689             EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
   686             EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
   690             fsm->sii_offset = 0x0000;
   687             fsm->sii_offset = 0x0000;
   691             memcpy(fsm->sii_value, slave->new_eeprom_data, 2);
   688             ec_fsm_sii_write(&fsm->fsm_sii, slave, fsm->sii_offset,
   692             fsm->sii_mode = 1;
   689                              slave->new_eeprom_data, EC_FSM_SII_NODE);
   693             fsm->sii_state = ec_fsm_sii_start_writing;
       
   694             fsm->slave = slave;
       
   695             fsm->master_state = ec_fsm_master_write_eeprom;
   690             fsm->master_state = ec_fsm_master_write_eeprom;
   696             fsm->master_state(fsm); // execute immediately
   691             fsm->master_state(fsm); // execute immediately
   697             return;
   692             return;
   698         }
   693         }
   699     }
   694     }
   736 
   731 
   737             // At least one slave is offline. validate!
   732             // At least one slave is offline. validate!
   738             EC_INFO("Validating bus.\n");
   733             EC_INFO("Validating bus.\n");
   739             fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   734             fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   740             fsm->master_state = ec_fsm_master_validate_vendor;
   735             fsm->master_state = ec_fsm_master_validate_vendor;
   741             fsm->sii_offset = 0x0008; // vendor ID
   736             ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x0008, EC_FSM_SII_POSITION);
   742             fsm->sii_mode = 0;
   737             ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
   743             fsm->sii_state = ec_fsm_sii_start_reading;
       
   744             fsm->sii_state(fsm); // execute immediately
       
   745             return;
   738             return;
   746         }
   739         }
   747     }
   740     }
   748 
   741 
   749     ec_fsm_master_action_process_states(fsm);
   742     ec_fsm_master_action_process_states(fsm);
   809 
   802 
   810 void ec_fsm_master_validate_vendor(ec_fsm_t *fsm /**< finite state machine */)
   803 void ec_fsm_master_validate_vendor(ec_fsm_t *fsm /**< finite state machine */)
   811 {
   804 {
   812     ec_slave_t *slave = fsm->slave;
   805     ec_slave_t *slave = fsm->slave;
   813 
   806 
   814     fsm->sii_state(fsm); // execute SII state machine
   807     ec_fsm_sii_exec(&fsm->fsm_sii); // execute SII state machine
   815 
   808 
   816     if (fsm->sii_state == ec_fsm_error) {
   809     if (ec_fsm_sii_running(&fsm->fsm_sii)) return;
       
   810 
       
   811     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
   817         fsm->slave->error_flag = 1;
   812         fsm->slave->error_flag = 1;
   818         EC_ERR("Failed to validate vendor ID of slave %i.\n",
   813         EC_ERR("Failed to validate vendor ID of slave %i.\n",
   819                slave->ring_position);
   814                slave->ring_position);
   820         fsm->master_state = ec_fsm_master_start;
   815         fsm->master_state = ec_fsm_master_start;
   821         fsm->master_state(fsm); // execute immediately
   816         fsm->master_state(fsm); // execute immediately
   822         return;
   817         return;
   823     }
   818     }
   824 
   819 
   825     if (fsm->sii_state != ec_fsm_end) return;
   820     if (EC_READ_U32(fsm->fsm_sii.value) != slave->sii_vendor_id) {
   826 
       
   827     if (EC_READ_U32(fsm->sii_value) != slave->sii_vendor_id) {
       
   828         EC_ERR("Slave %i: invalid vendor ID!\n", slave->ring_position);
   821         EC_ERR("Slave %i: invalid vendor ID!\n", slave->ring_position);
   829         fsm->master_state = ec_fsm_master_start;
   822         fsm->master_state = ec_fsm_master_start;
   830         fsm->master_state(fsm); // execute immediately
   823         fsm->master_state(fsm); // execute immediately
   831         return;
   824         return;
   832     }
   825     }
   833 
   826 
   834     // vendor ID is ok. check product code.
   827     // vendor ID is ok. check product code.
   835     fsm->master_state = ec_fsm_master_validate_product;
   828     fsm->master_state = ec_fsm_master_validate_product;
   836     fsm->sii_offset = 0x000A; // product code
   829     ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x000A, EC_FSM_SII_POSITION);
   837     fsm->sii_mode = 0;
   830     ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
   838     fsm->sii_state = ec_fsm_sii_start_reading;
       
   839     fsm->sii_state(fsm); // execute immediately
       
   840 }
   831 }
   841 
   832 
   842 /*****************************************************************************/
   833 /*****************************************************************************/
   843 
   834 
   844 /**
   835 /**
   879 
   870 
   880 void ec_fsm_master_validate_product(ec_fsm_t *fsm /**< finite state machine */)
   871 void ec_fsm_master_validate_product(ec_fsm_t *fsm /**< finite state machine */)
   881 {
   872 {
   882     ec_slave_t *slave = fsm->slave;
   873     ec_slave_t *slave = fsm->slave;
   883 
   874 
   884     fsm->sii_state(fsm); // execute SII state machine
   875     ec_fsm_sii_exec(&fsm->fsm_sii); // execute SII state machine
   885 
   876 
   886     if (fsm->sii_state == ec_fsm_error) {
   877     if (ec_fsm_sii_running(&fsm->fsm_sii)) return;
       
   878 
       
   879     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
   887         fsm->slave->error_flag = 1;
   880         fsm->slave->error_flag = 1;
   888         EC_ERR("Failed to validate product code of slave %i.\n",
   881         EC_ERR("Failed to validate product code of slave %i.\n",
   889                slave->ring_position);
   882                slave->ring_position);
   890         fsm->master_state = ec_fsm_master_start;
   883         fsm->master_state = ec_fsm_master_start;
   891         fsm->master_state(fsm); // execute immediately
   884         fsm->master_state(fsm); // execute immediately
   892         return;
   885         return;
   893     }
   886     }
   894 
   887 
   895     if (fsm->sii_state != ec_fsm_end) return;
   888     if (EC_READ_U32(fsm->fsm_sii.value) != slave->sii_product_code) {
   896 
       
   897     if (EC_READ_U32(fsm->sii_value) != slave->sii_product_code) {
       
   898         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
   889         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
   899         EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
   890         EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
   900                EC_READ_U32(fsm->sii_value));
   891                EC_READ_U32(fsm->fsm_sii.value));
   901         fsm->master_state = ec_fsm_master_start;
   892         fsm->master_state = ec_fsm_master_start;
   902         fsm->master_state(fsm); // execute immediately
   893         fsm->master_state(fsm); // execute immediately
   903         return;
   894         return;
   904     }
   895     }
   905 
   896 
   912     }
   903     }
   913 
   904 
   914     // validate next slave
   905     // validate next slave
   915     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   906     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   916     fsm->master_state = ec_fsm_master_validate_vendor;
   907     fsm->master_state = ec_fsm_master_validate_vendor;
   917     fsm->sii_offset = 0x0008; // vendor ID
   908     ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x0008, EC_FSM_SII_POSITION);
   918     fsm->sii_mode = 0;
   909     ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
   919     fsm->sii_state = ec_fsm_sii_start_reading;
       
   920     fsm->sii_state(fsm); // execute immediately
       
   921 }
   910 }
   922 
   911 
   923 /*****************************************************************************/
   912 /*****************************************************************************/
   924 
   913 
   925 /**
   914 /**
  1018 
  1007 
  1019 void ec_fsm_master_write_eeprom(ec_fsm_t *fsm /**< finite state machine */)
  1008 void ec_fsm_master_write_eeprom(ec_fsm_t *fsm /**< finite state machine */)
  1020 {
  1009 {
  1021     ec_slave_t *slave = fsm->slave;
  1010     ec_slave_t *slave = fsm->slave;
  1022 
  1011 
  1023     fsm->sii_state(fsm); // execute SII state machine
  1012     ec_fsm_sii_exec(&fsm->fsm_sii); // execute SII state machine
  1024 
  1013 
  1025     if (fsm->sii_state == ec_fsm_error) {
  1014     if (ec_fsm_sii_running(&fsm->fsm_sii)) return;
       
  1015 
       
  1016     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
  1026         fsm->slave->error_flag = 1;
  1017         fsm->slave->error_flag = 1;
  1027         EC_ERR("Failed to write EEPROM contents to slave %i.\n",
  1018         EC_ERR("Failed to write EEPROM contents to slave %i.\n",
  1028                slave->ring_position);
  1019                slave->ring_position);
  1029         kfree(slave->new_eeprom_data);
  1020         kfree(slave->new_eeprom_data);
  1030         slave->new_eeprom_data = NULL;
  1021         slave->new_eeprom_data = NULL;
  1031         fsm->master_state = ec_fsm_master_start;
  1022         fsm->master_state = ec_fsm_master_start;
  1032         fsm->master_state(fsm); // execute immediately
  1023         fsm->master_state(fsm); // execute immediately
  1033         return;
  1024         return;
  1034     }
  1025     }
  1035 
  1026 
  1036     if (fsm->sii_state != ec_fsm_end) return;
       
  1037 
       
  1038     fsm->sii_offset++;
  1027     fsm->sii_offset++;
  1039     if (fsm->sii_offset < slave->new_eeprom_size) {
  1028     if (fsm->sii_offset < slave->new_eeprom_size) {
  1040         memcpy(fsm->sii_value, slave->new_eeprom_data + fsm->sii_offset, 2);
  1029         ec_fsm_sii_write(&fsm->fsm_sii, slave, fsm->sii_offset,
  1041         fsm->sii_state = ec_fsm_sii_start_writing;
  1030                          slave->new_eeprom_data + fsm->sii_offset,
  1042         fsm->sii_state(fsm); // execute immediately
  1031                          EC_FSM_SII_NODE);
       
  1032         ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
  1043         return;
  1033         return;
  1044     }
  1034     }
  1045 
  1035 
  1046     // finished writing EEPROM
  1036     // finished writing EEPROM
  1047     EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position);
  1037     EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position);
  1266     }
  1256     }
  1267 
  1257 
  1268     // Start fetching EEPROM size
  1258     // Start fetching EEPROM size
  1269 
  1259 
  1270     fsm->sii_offset = 0x0040; // first category header
  1260     fsm->sii_offset = 0x0040; // first category header
  1271     fsm->sii_mode = 1;
  1261     ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset, EC_FSM_SII_NODE);
  1272     fsm->sii_state = ec_fsm_sii_start_reading;
       
  1273     fsm->slave_state = ec_fsm_slavescan_eeprom_size;
  1262     fsm->slave_state = ec_fsm_slavescan_eeprom_size;
  1274     fsm->slave_state(fsm); // execute state immediately
  1263     fsm->slave_state(fsm); // execute state immediately
  1275 }
  1264 }
  1276 
  1265 
  1277 /*****************************************************************************/
  1266 /*****************************************************************************/
  1284 {
  1273 {
  1285     ec_slave_t *slave = fsm->slave;
  1274     ec_slave_t *slave = fsm->slave;
  1286     uint16_t cat_type, cat_size;
  1275     uint16_t cat_type, cat_size;
  1287 
  1276 
  1288     // execute SII state machine
  1277     // execute SII state machine
  1289     fsm->sii_state(fsm);
  1278     ec_fsm_sii_exec(&fsm->fsm_sii);
  1290 
  1279 
  1291     if (fsm->sii_state == ec_fsm_error) {
  1280     if (ec_fsm_sii_running(&fsm->fsm_sii)) return;
       
  1281 
       
  1282     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
  1292         fsm->slave->error_flag = 1;
  1283         fsm->slave->error_flag = 1;
  1293         fsm->slave_state = ec_fsm_error;
  1284         fsm->slave_state = ec_fsm_error;
  1294         EC_ERR("Failed to read EEPROM size of slave %i.\n",
  1285         EC_ERR("Failed to read EEPROM size of slave %i.\n",
  1295                slave->ring_position);
  1286                slave->ring_position);
  1296         return;
  1287         return;
  1297     }
  1288     }
  1298 
  1289 
  1299     if (fsm->sii_state != ec_fsm_end) return;
  1290     cat_type = EC_READ_U16(fsm->fsm_sii.value);
  1300 
  1291     cat_size = EC_READ_U16(fsm->fsm_sii.value + 2);
  1301     cat_type = EC_READ_U16(fsm->sii_value);
       
  1302     cat_size = EC_READ_U16(fsm->sii_value + 2);
       
  1303 
  1292 
  1304     if (cat_type != 0xFFFF) { // not the last category
  1293     if (cat_type != 0xFFFF) { // not the last category
  1305         fsm->sii_offset += cat_size + 2;
  1294         fsm->sii_offset += cat_size + 2;
  1306         fsm->sii_state = ec_fsm_sii_start_reading;
  1295         ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
  1307         fsm->sii_state(fsm); // execute state immediately
  1296                         EC_FSM_SII_NODE);
       
  1297         ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
  1308         return;
  1298         return;
  1309     }
  1299     }
  1310 
  1300 
  1311     slave->eeprom_size = (fsm->sii_offset + 1) * 2;
  1301     slave->eeprom_size = (fsm->sii_offset + 1) * 2;
  1312 
  1302 
  1325         return;
  1315         return;
  1326     }
  1316     }
  1327 
  1317 
  1328     // Start fetching EEPROM contents
  1318     // Start fetching EEPROM contents
  1329 
  1319 
       
  1320     fsm->slave_state = ec_fsm_slavescan_eeprom_data;
  1330     fsm->sii_offset = 0x0000;
  1321     fsm->sii_offset = 0x0000;
  1331     fsm->sii_mode = 1;
  1322     ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset, EC_FSM_SII_NODE);
  1332     fsm->sii_state = ec_fsm_sii_start_reading;
  1323     ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
  1333     fsm->slave_state = ec_fsm_slavescan_eeprom_data;
       
  1334     fsm->slave_state(fsm); // execute state immediately
       
  1335 }
  1324 }
  1336 
  1325 
  1337 /*****************************************************************************/
  1326 /*****************************************************************************/
  1338 
  1327 
  1339 /**
  1328 /**
  1344 {
  1333 {
  1345     ec_slave_t *slave = fsm->slave;
  1334     ec_slave_t *slave = fsm->slave;
  1346     uint16_t *cat_word, cat_type, cat_size;
  1335     uint16_t *cat_word, cat_type, cat_size;
  1347 
  1336 
  1348     // execute SII state machine
  1337     // execute SII state machine
  1349     fsm->sii_state(fsm);
  1338     ec_fsm_sii_exec(&fsm->fsm_sii);
  1350 
  1339 
  1351     if (fsm->sii_state == ec_fsm_error) {
  1340     if (ec_fsm_sii_running(&fsm->fsm_sii)) return;
       
  1341 
       
  1342     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
  1352         fsm->slave->error_flag = 1;
  1343         fsm->slave->error_flag = 1;
  1353         fsm->slave_state = ec_fsm_error;
  1344         fsm->slave_state = ec_fsm_error;
  1354         EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
  1345         EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
  1355                slave->ring_position);
  1346                slave->ring_position);
  1356         return;
  1347         return;
  1357     }
  1348     }
  1358 
  1349 
  1359     if (fsm->sii_state != ec_fsm_end) return;
       
  1360 
       
  1361     // 2 words fetched
  1350     // 2 words fetched
  1362 
  1351 
  1363     if (fsm->sii_offset + 2 <= slave->eeprom_size / 2) { // 2 words fit
  1352     if (fsm->sii_offset + 2 <= slave->eeprom_size / 2) { // 2 words fit
  1364         memcpy(slave->eeprom_data + fsm->sii_offset * 2, fsm->sii_value, 4);
  1353         memcpy(slave->eeprom_data + fsm->sii_offset * 2,
       
  1354                fsm->fsm_sii.value, 4);
  1365     }
  1355     }
  1366     else { // copy the last word
  1356     else { // copy the last word
  1367         memcpy(slave->eeprom_data + fsm->sii_offset * 2, fsm->sii_value, 2);
  1357         memcpy(slave->eeprom_data + fsm->sii_offset * 2,
       
  1358                fsm->fsm_sii.value, 2);
  1368     }
  1359     }
  1369 
  1360 
  1370     if (fsm->sii_offset + 2 < slave->eeprom_size / 2) {
  1361     if (fsm->sii_offset + 2 < slave->eeprom_size / 2) {
  1371         // fetch the next 2 words
  1362         // fetch the next 2 words
  1372         fsm->sii_offset += 2;
  1363         fsm->sii_offset += 2;
  1373         fsm->sii_state = ec_fsm_sii_start_reading;
  1364         ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
  1374         fsm->sii_state(fsm); // execute state immediately
  1365                         EC_FSM_SII_NODE);
       
  1366         ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
  1375         return;
  1367         return;
  1376     }
  1368     }
  1377 
  1369 
  1378     // Evaluate EEPROM contents
  1370     // Evaluate EEPROM contents
  1379 
  1371 
  1788         EC_DBG("Slave %i is now in OP.\n", slave->ring_position);
  1780         EC_DBG("Slave %i is now in OP.\n", slave->ring_position);
  1789         EC_DBG("Finished configuration of slave %i.\n", slave->ring_position);
  1781         EC_DBG("Finished configuration of slave %i.\n", slave->ring_position);
  1790     }
  1782     }
  1791 
  1783 
  1792     fsm->slave_state = ec_fsm_end; // successful
  1784     fsm->slave_state = ec_fsm_end; // successful
  1793 }
       
  1794 
       
  1795 /******************************************************************************
       
  1796  *  SII state machine
       
  1797  *****************************************************************************/
       
  1798 
       
  1799 /**
       
  1800    SII state: START READING.
       
  1801    Starts reading the slave information interface.
       
  1802 */
       
  1803 
       
  1804 void ec_fsm_sii_start_reading(ec_fsm_t *fsm /**< finite state machine */)
       
  1805 {
       
  1806     ec_datagram_t *datagram = &fsm->datagram;
       
  1807 
       
  1808     // initiate read operation
       
  1809     if (fsm->sii_mode) {
       
  1810         ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 4);
       
  1811     }
       
  1812     else {
       
  1813         ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x502, 4);
       
  1814     }
       
  1815 
       
  1816     EC_WRITE_U8 (datagram->data,     0x00); // read-only access
       
  1817     EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation
       
  1818     EC_WRITE_U16(datagram->data + 2, fsm->sii_offset);
       
  1819     ec_master_queue_datagram(fsm->master, datagram);
       
  1820     fsm->sii_state = ec_fsm_sii_read_check;
       
  1821 }
       
  1822 
       
  1823 /*****************************************************************************/
       
  1824 
       
  1825 /**
       
  1826    SII state: READ CHECK.
       
  1827    Checks, if the SII-read-datagram has been sent and issues a fetch datagram.
       
  1828 */
       
  1829 
       
  1830 void ec_fsm_sii_read_check(ec_fsm_t *fsm /**< finite state machine */)
       
  1831 {
       
  1832     ec_datagram_t *datagram = &fsm->datagram;
       
  1833 
       
  1834     if (datagram->state != EC_DATAGRAM_RECEIVED
       
  1835         || datagram->working_counter != 1) {
       
  1836         EC_ERR("SII: Reception of read datagram failed.\n");
       
  1837         fsm->sii_state = ec_fsm_error;
       
  1838         return;
       
  1839     }
       
  1840 
       
  1841     fsm->sii_start = datagram->cycles_sent;
       
  1842     fsm->sii_check_once_more = 1;
       
  1843 
       
  1844     // issue check/fetch datagram
       
  1845     if (fsm->sii_mode) {
       
  1846         ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10);
       
  1847     }
       
  1848     else {
       
  1849         ec_datagram_aprd(datagram, fsm->slave->ring_position, 0x502, 10);
       
  1850     }
       
  1851 
       
  1852     ec_master_queue_datagram(fsm->master, datagram);
       
  1853     fsm->sii_state = ec_fsm_sii_read_fetch;
       
  1854 }
       
  1855 
       
  1856 /*****************************************************************************/
       
  1857 
       
  1858 /**
       
  1859    SII state: READ FETCH.
       
  1860    Fetches the result of an SII-read datagram.
       
  1861 */
       
  1862 
       
  1863 void ec_fsm_sii_read_fetch(ec_fsm_t *fsm /**< finite state machine */)
       
  1864 {
       
  1865     ec_datagram_t *datagram = &fsm->datagram;
       
  1866 
       
  1867     if (datagram->state != EC_DATAGRAM_RECEIVED
       
  1868         || datagram->working_counter != 1) {
       
  1869         EC_ERR("SII: Reception of check/fetch datagram failed.\n");
       
  1870         fsm->sii_state = ec_fsm_error;
       
  1871         return;
       
  1872     }
       
  1873 
       
  1874     // check "busy bit"
       
  1875     if (EC_READ_U8(datagram->data + 1) & 0x81) {
       
  1876         // still busy... timeout?
       
  1877         if (datagram->cycles_received
       
  1878             - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
       
  1879             if (!fsm->sii_check_once_more) {
       
  1880                 EC_ERR("SII: Read timeout.\n");
       
  1881                 fsm->sii_state = ec_fsm_error;
       
  1882 #if 0
       
  1883                 EC_DBG("SII busy: %02X %02X %02X %02X\n",
       
  1884                        EC_READ_U8(datagram->data + 0),
       
  1885                        EC_READ_U8(datagram->data + 1),
       
  1886                        EC_READ_U8(datagram->data + 2),
       
  1887                        EC_READ_U8(datagram->data + 3));
       
  1888 #endif
       
  1889                 return;
       
  1890             }
       
  1891             fsm->sii_check_once_more = 0;
       
  1892         }
       
  1893 
       
  1894         // issue check/fetch datagram again
       
  1895         if (fsm->sii_mode) {
       
  1896             ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10);
       
  1897         }
       
  1898         else {
       
  1899             ec_datagram_aprd(datagram, fsm->slave->ring_position, 0x502, 10);
       
  1900         }
       
  1901         ec_master_queue_datagram(fsm->master, datagram);
       
  1902         return;
       
  1903     }
       
  1904 
       
  1905 #if 0
       
  1906     EC_DBG("SII rec: %02X %02X %02X %02X - %02X %02X %02X %02X\n",
       
  1907            EC_READ_U8(datagram->data + 0), EC_READ_U8(datagram->data + 1),
       
  1908            EC_READ_U8(datagram->data + 2), EC_READ_U8(datagram->data + 3),
       
  1909            EC_READ_U8(datagram->data + 6), EC_READ_U8(datagram->data + 7),
       
  1910            EC_READ_U8(datagram->data + 8), EC_READ_U8(datagram->data + 9));
       
  1911 #endif
       
  1912 
       
  1913     // SII value received.
       
  1914     memcpy(fsm->sii_value, datagram->data + 6, 4);
       
  1915     fsm->sii_state = ec_fsm_end;
       
  1916 }
       
  1917 
       
  1918 /*****************************************************************************/
       
  1919 
       
  1920 /**
       
  1921    SII state: START WRITING.
       
  1922    Starts reading the slave information interface.
       
  1923 */
       
  1924 
       
  1925 void ec_fsm_sii_start_writing(ec_fsm_t *fsm /**< finite state machine */)
       
  1926 {
       
  1927     ec_datagram_t *datagram = &fsm->datagram;
       
  1928 
       
  1929     // initiate write operation
       
  1930     ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 8);
       
  1931     EC_WRITE_U8 (datagram->data,     0x01); // enable write access
       
  1932     EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation
       
  1933     EC_WRITE_U32(datagram->data + 2, fsm->sii_offset);
       
  1934     memcpy(datagram->data + 6, fsm->sii_value, 2);
       
  1935     ec_master_queue_datagram(fsm->master, datagram);
       
  1936     fsm->sii_state = ec_fsm_sii_write_check;
       
  1937 }
       
  1938 
       
  1939 /*****************************************************************************/
       
  1940 
       
  1941 /**
       
  1942    SII state: WRITE CHECK.
       
  1943 */
       
  1944 
       
  1945 void ec_fsm_sii_write_check(ec_fsm_t *fsm /**< finite state machine */)
       
  1946 {
       
  1947     ec_datagram_t *datagram = &fsm->datagram;
       
  1948 
       
  1949     if (datagram->state != EC_DATAGRAM_RECEIVED
       
  1950         || datagram->working_counter != 1) {
       
  1951         EC_ERR("SII: Reception of write datagram failed.\n");
       
  1952         fsm->sii_state = ec_fsm_error;
       
  1953         return;
       
  1954     }
       
  1955 
       
  1956     fsm->sii_start = datagram->cycles_sent;
       
  1957     fsm->sii_check_once_more = 1;
       
  1958 
       
  1959     // issue check/fetch datagram
       
  1960     ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 2);
       
  1961     ec_master_queue_datagram(fsm->master, datagram);
       
  1962     fsm->sii_state = ec_fsm_sii_write_check2;
       
  1963 }
       
  1964 
       
  1965 /*****************************************************************************/
       
  1966 
       
  1967 /**
       
  1968    SII state: WRITE CHECK 2.
       
  1969 */
       
  1970 
       
  1971 void ec_fsm_sii_write_check2(ec_fsm_t *fsm /**< finite state machine */)
       
  1972 {
       
  1973     ec_datagram_t *datagram = &fsm->datagram;
       
  1974 
       
  1975     if (datagram->state != EC_DATAGRAM_RECEIVED
       
  1976         || datagram->working_counter != 1) {
       
  1977         EC_ERR("SII: Reception of write check datagram failed.\n");
       
  1978         fsm->sii_state = ec_fsm_error;
       
  1979         return;
       
  1980     }
       
  1981 
       
  1982     if (EC_READ_U8(datagram->data + 1) & 0x82) {
       
  1983         // still busy... timeout?
       
  1984         if (datagram->cycles_received
       
  1985             - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
       
  1986             if (!fsm->sii_check_once_more) {
       
  1987                 EC_ERR("SII: Write timeout.\n");
       
  1988                 fsm->sii_state = ec_fsm_error;
       
  1989                 return;
       
  1990             }
       
  1991             fsm->sii_check_once_more = 0;
       
  1992         }
       
  1993 
       
  1994         // issue check/fetch datagram again
       
  1995         ec_master_queue_datagram(fsm->master, datagram);
       
  1996         return;
       
  1997     }
       
  1998 
       
  1999     if (EC_READ_U8(datagram->data + 1) & 0x40) {
       
  2000         EC_ERR("SII: Write operation failed!\n");
       
  2001         fsm->sii_state = ec_fsm_error;
       
  2002         return;
       
  2003     }
       
  2004 
       
  2005     // success
       
  2006     fsm->sii_state = ec_fsm_end;
       
  2007 }
  1785 }
  2008 
  1786 
  2009 /******************************************************************************
  1787 /******************************************************************************
  2010  *  state change state machine
  1788  *  state change state machine
  2011  *****************************************************************************/
  1789  *****************************************************************************/