master/fsm.c
changeset 269 a03be9a6fed6
parent 266 0234b0c26c52
child 275 ba51285d4ef6
equal deleted inserted replaced
268:4f9c149fb71f 269:a03be9a6fed6
    56 void ec_fsm_master_validate_vendor(ec_fsm_t *);
    56 void ec_fsm_master_validate_vendor(ec_fsm_t *);
    57 void ec_fsm_master_validate_product(ec_fsm_t *);
    57 void ec_fsm_master_validate_product(ec_fsm_t *);
    58 void ec_fsm_master_reconfigure(ec_fsm_t *);
    58 void ec_fsm_master_reconfigure(ec_fsm_t *);
    59 void ec_fsm_master_address(ec_fsm_t *);
    59 void ec_fsm_master_address(ec_fsm_t *);
    60 void ec_fsm_master_conf(ec_fsm_t *);
    60 void ec_fsm_master_conf(ec_fsm_t *);
       
    61 void ec_fsm_master_eeprom(ec_fsm_t *);
    61 
    62 
    62 void ec_fsm_slave_start_reading(ec_fsm_t *);
    63 void ec_fsm_slave_start_reading(ec_fsm_t *);
    63 void ec_fsm_slave_read_status(ec_fsm_t *);
    64 void ec_fsm_slave_read_status(ec_fsm_t *);
    64 void ec_fsm_slave_read_base(ec_fsm_t *);
    65 void ec_fsm_slave_read_base(ec_fsm_t *);
    65 void ec_fsm_slave_read_dl(ec_fsm_t *);
    66 void ec_fsm_slave_read_dl(ec_fsm_t *);
    75 void ec_fsm_slave_saveop(ec_fsm_t *);
    76 void ec_fsm_slave_saveop(ec_fsm_t *);
    76 void ec_fsm_slave_op(ec_fsm_t *);
    77 void ec_fsm_slave_op(ec_fsm_t *);
    77 void ec_fsm_slave_op2(ec_fsm_t *);
    78 void ec_fsm_slave_op2(ec_fsm_t *);
    78 
    79 
    79 void ec_fsm_sii_start_reading(ec_fsm_t *);
    80 void ec_fsm_sii_start_reading(ec_fsm_t *);
    80 void ec_fsm_sii_check(ec_fsm_t *);
    81 void ec_fsm_sii_read_check(ec_fsm_t *);
    81 void ec_fsm_sii_fetch(ec_fsm_t *);
    82 void ec_fsm_sii_read_fetch(ec_fsm_t *);
       
    83 void ec_fsm_sii_start_writing(ec_fsm_t *);
       
    84 void ec_fsm_sii_write_check(ec_fsm_t *);
       
    85 void ec_fsm_sii_write_check2(ec_fsm_t *);
    82 void ec_fsm_sii_end(ec_fsm_t *);
    86 void ec_fsm_sii_end(ec_fsm_t *);
    83 void ec_fsm_sii_error(ec_fsm_t *);
    87 void ec_fsm_sii_error(ec_fsm_t *);
    84 
    88 
    85 void ec_fsm_change_start(ec_fsm_t *);
    89 void ec_fsm_change_start(ec_fsm_t *);
    86 void ec_fsm_change_check(ec_fsm_t *);
    90 void ec_fsm_change_check(ec_fsm_t *);
   404         fsm->master_state = ec_fsm_master_conf;
   408         fsm->master_state = ec_fsm_master_conf;
   405         fsm->master_state(fsm); // execute immediately
   409         fsm->master_state(fsm); // execute immediately
   406         return;
   410         return;
   407     }
   411     }
   408 
   412 
   409     // nothing to configure. restart master state machine.
   413     if (master->mode == EC_MASTER_MODE_FREERUN) {
       
   414         // nothing to configure. check for pending EEPROM write operations.
       
   415         list_for_each_entry(slave, &master->slaves, list) {
       
   416             if (!slave->new_eeprom_data) continue;
       
   417 
       
   418             // found pending EEPROM write operation. execute it!
       
   419             EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
       
   420             fsm->sii_offset = 0x0000;
       
   421             memcpy(fsm->sii_value, slave->new_eeprom_data, 2);
       
   422             fsm->sii_mode = 1;
       
   423             fsm->sii_state = ec_fsm_sii_start_writing;
       
   424             fsm->slave = slave;
       
   425             fsm->master_state = ec_fsm_master_eeprom;
       
   426             fsm->master_state(fsm); // execute immediately
       
   427             return;
       
   428         }
       
   429     }
       
   430 
       
   431     // nothing to do. restart master state machine.
   410     fsm->master_state = ec_fsm_master_start;
   432     fsm->master_state = ec_fsm_master_start;
   411     fsm->master_state(fsm); // execute immediately
   433     fsm->master_state(fsm); // execute immediately
   412 }
   434 }
   413 
   435 
   414 /*****************************************************************************/
   436 /*****************************************************************************/
   432         return;
   454         return;
   433     }
   455     }
   434 
   456 
   435     if (fsm->sii_state != ec_fsm_sii_end) return;
   457     if (fsm->sii_state != ec_fsm_sii_end) return;
   436 
   458 
   437     if (EC_READ_U32(fsm->sii_result) != slave->sii_vendor_id) {
   459     if (EC_READ_U32(fsm->sii_value) != slave->sii_vendor_id) {
   438         EC_ERR("Slave %i: invalid vendor ID!\n", slave->ring_position);
   460         EC_ERR("Slave %i: invalid vendor ID!\n", slave->ring_position);
   439         fsm->master_state = ec_fsm_master_start;
   461         fsm->master_state = ec_fsm_master_start;
   440         fsm->master_state(fsm); // execute immediately
   462         fsm->master_state(fsm); // execute immediately
   441         return;
   463         return;
   442     }
   464     }
   470         return;
   492         return;
   471     }
   493     }
   472 
   494 
   473     if (fsm->sii_state != ec_fsm_sii_end) return;
   495     if (fsm->sii_state != ec_fsm_sii_end) return;
   474 
   496 
   475     if (EC_READ_U32(fsm->sii_result) != slave->sii_product_code) {
   497     if (EC_READ_U32(fsm->sii_value) != slave->sii_product_code) {
   476         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
   498         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
   477         EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
   499         EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
   478                EC_READ_U32(fsm->sii_result));
   500                EC_READ_U32(fsm->sii_value));
   479         fsm->master_state = ec_fsm_master_start;
   501         fsm->master_state = ec_fsm_master_start;
   480         fsm->master_state(fsm); // execute immediately
   502         fsm->master_state(fsm); // execute immediately
   481         return;
   503         return;
   482     }
   504     }
   483 
   505 
   664     if (fsm->slave_state != ec_fsm_slave_end) return;
   686     if (fsm->slave_state != ec_fsm_slave_end) return;
   665     fsm->master_state = ec_fsm_master_proc_states;
   687     fsm->master_state = ec_fsm_master_proc_states;
   666     fsm->master_state(fsm); // execute immediately
   688     fsm->master_state(fsm); // execute immediately
   667 }
   689 }
   668 
   690 
       
   691 /*****************************************************************************/
       
   692 
       
   693 /**
       
   694    Master state: EEPROM.
       
   695 */
       
   696 
       
   697 void ec_fsm_master_eeprom(ec_fsm_t *fsm /**< finite state machine */)
       
   698 {
       
   699     ec_slave_t *slave = fsm->slave;
       
   700 
       
   701     fsm->sii_state(fsm); // execute SII state machine
       
   702 
       
   703     if (fsm->sii_state == ec_fsm_sii_error) {
       
   704         EC_ERR("Failed to write EEPROM contents to slave %i.\n",
       
   705                slave->ring_position);
       
   706         kfree(slave->new_eeprom_data);
       
   707         slave->new_eeprom_data = NULL;
       
   708         fsm->master_state = ec_fsm_master_start;
       
   709         fsm->master_state(fsm); // execute immediately
       
   710         return;
       
   711     }
       
   712 
       
   713     if (fsm->sii_state != ec_fsm_sii_end) return;
       
   714 
       
   715     fsm->sii_offset++;
       
   716     if (fsm->sii_offset < slave->new_eeprom_size) {
       
   717         memcpy(fsm->sii_value, slave->new_eeprom_data + fsm->sii_offset, 2);
       
   718         fsm->sii_state = ec_fsm_sii_start_writing;
       
   719         fsm->sii_state(fsm); // execute immediately
       
   720         return;
       
   721     }
       
   722 
       
   723     // finished writing EEPROM
       
   724     EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position);
       
   725     kfree(slave->new_eeprom_data);
       
   726     slave->new_eeprom_data = NULL;
       
   727 
       
   728     // restart master state machine.
       
   729     fsm->master_state = ec_fsm_master_start;
       
   730     fsm->master_state(fsm); // execute immediately
       
   731     return;
       
   732 }
       
   733 
   669 /******************************************************************************
   734 /******************************************************************************
   670  *  slave state machine
   735  *  slave state machine
   671  *****************************************************************************/
   736  *****************************************************************************/
   672 
   737 
   673 /**
   738 /**
   832         return;
   897         return;
   833     }
   898     }
   834 
   899 
   835     if (fsm->sii_state != ec_fsm_sii_end) return;
   900     if (fsm->sii_state != ec_fsm_sii_end) return;
   836 
   901 
   837     cat_type = EC_READ_U16(fsm->sii_result);
   902     cat_type = EC_READ_U16(fsm->sii_value);
   838     cat_size = EC_READ_U16(fsm->sii_result + 2);
   903     cat_size = EC_READ_U16(fsm->sii_value + 2);
   839 
   904 
   840     if (cat_type != 0xFFFF) { // not the last category
   905     if (cat_type != 0xFFFF) { // not the last category
   841         fsm->sii_offset += cat_size + 2;
   906         fsm->sii_offset += cat_size + 2;
   842         fsm->sii_state = ec_fsm_sii_start_reading;
   907         fsm->sii_state = ec_fsm_sii_start_reading;
   843         fsm->sii_state(fsm); // execute state immediately
   908         fsm->sii_state(fsm); // execute state immediately
   893     if (fsm->sii_state != ec_fsm_sii_end) return;
   958     if (fsm->sii_state != ec_fsm_sii_end) return;
   894 
   959 
   895     // 2 words fetched
   960     // 2 words fetched
   896 
   961 
   897     if (fsm->sii_offset + 2 <= slave->eeprom_size / 2) { // 2 words fit
   962     if (fsm->sii_offset + 2 <= slave->eeprom_size / 2) { // 2 words fit
   898         memcpy(slave->eeprom_data + fsm->sii_offset * 2, fsm->sii_result, 4);
   963         memcpy(slave->eeprom_data + fsm->sii_offset * 2, fsm->sii_value, 4);
   899     }
   964     }
   900     else { // copy the last word
   965     else { // copy the last word
   901         memcpy(slave->eeprom_data + fsm->sii_offset * 2, fsm->sii_result, 2);
   966         memcpy(slave->eeprom_data + fsm->sii_offset * 2, fsm->sii_value, 2);
   902     }
   967     }
   903 
   968 
   904     if (fsm->sii_offset + 2 < slave->eeprom_size / 2) {
   969     if (fsm->sii_offset + 2 < slave->eeprom_size / 2) {
   905         // fetch the next 2 words
   970         // fetch the next 2 words
   906         fsm->sii_offset += 2;
   971         fsm->sii_offset += 2;
  1303 
  1368 
  1304     EC_WRITE_U8 (command->data,     0x00); // read-only access
  1369     EC_WRITE_U8 (command->data,     0x00); // read-only access
  1305     EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
  1370     EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
  1306     EC_WRITE_U16(command->data + 2, fsm->sii_offset);
  1371     EC_WRITE_U16(command->data + 2, fsm->sii_offset);
  1307     ec_master_queue_command(fsm->master, command);
  1372     ec_master_queue_command(fsm->master, command);
  1308     fsm->sii_state = ec_fsm_sii_check;
  1373     fsm->sii_state = ec_fsm_sii_read_check;
  1309 }
  1374 }
  1310 
  1375 
  1311 /*****************************************************************************/
  1376 /*****************************************************************************/
  1312 
  1377 
  1313 /**
  1378 /**
  1314    SII state: CHECK.
  1379    SII state: READ_CHECK.
  1315    Checks, if the SII-read-command has been sent and issues a fetch command.
  1380    Checks, if the SII-read-command has been sent and issues a fetch command.
  1316 */
  1381 */
  1317 
  1382 
  1318 void ec_fsm_sii_check(ec_fsm_t *fsm /**< finite state machine */)
  1383 void ec_fsm_sii_read_check(ec_fsm_t *fsm /**< finite state machine */)
  1319 {
  1384 {
  1320     ec_command_t *command = &fsm->command;
  1385     ec_command_t *command = &fsm->command;
  1321 
  1386 
  1322     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
  1387     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
  1323         EC_ERR("SII: Reception of read command failed.\n");
  1388         EC_ERR("SII: Reception of read command failed.\n");
  1334     else {
  1399     else {
  1335         ec_command_aprd(command, fsm->slave->ring_position, 0x502, 10);
  1400         ec_command_aprd(command, fsm->slave->ring_position, 0x502, 10);
  1336     }
  1401     }
  1337 
  1402 
  1338     ec_master_queue_command(fsm->master, command);
  1403     ec_master_queue_command(fsm->master, command);
  1339     fsm->sii_state = ec_fsm_sii_fetch;
  1404     fsm->sii_state = ec_fsm_sii_read_fetch;
  1340 }
  1405 }
  1341 
  1406 
  1342 /*****************************************************************************/
  1407 /*****************************************************************************/
  1343 
  1408 
  1344 /**
  1409 /**
  1345    SII state: FETCH.
  1410    SII state: READ_FETCH.
  1346    Fetches the result of an SII-read command.
  1411    Fetches the result of an SII-read command.
  1347 */
  1412 */
  1348 
  1413 
  1349 void ec_fsm_sii_fetch(ec_fsm_t *fsm /**< finite state machine */)
  1414 void ec_fsm_sii_read_fetch(ec_fsm_t *fsm /**< finite state machine */)
  1350 {
  1415 {
  1351     ec_command_t *command = &fsm->command;
  1416     ec_command_t *command = &fsm->command;
  1352 
  1417 
  1353     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
  1418     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
  1354         EC_ERR("SII: Reception of check/fetch command failed.\n");
  1419         EC_ERR("SII: Reception of check/fetch command failed.\n");
  1389            EC_READ_U8(command->data + 6), EC_READ_U8(command->data + 7),
  1454            EC_READ_U8(command->data + 6), EC_READ_U8(command->data + 7),
  1390            EC_READ_U8(command->data + 8), EC_READ_U8(command->data + 9));
  1455            EC_READ_U8(command->data + 8), EC_READ_U8(command->data + 9));
  1391 #endif
  1456 #endif
  1392 
  1457 
  1393     // SII value received.
  1458     // SII value received.
  1394     memcpy(fsm->sii_result, command->data + 6, 4);
  1459     memcpy(fsm->sii_value, command->data + 6, 4);
  1395     fsm->sii_state = ec_fsm_sii_end;
  1460     fsm->sii_state = ec_fsm_sii_end;
       
  1461 }
       
  1462 
       
  1463 /*****************************************************************************/
       
  1464 
       
  1465 /**
       
  1466    SII state: START_WRITING.
       
  1467    Starts reading the slave information interface.
       
  1468 */
       
  1469 
       
  1470 void ec_fsm_sii_start_writing(ec_fsm_t *fsm /**< finite state machine */)
       
  1471 {
       
  1472     ec_command_t *command = &fsm->command;
       
  1473 
       
  1474     // initiate write operation
       
  1475     ec_command_npwr(command, fsm->slave->station_address, 0x502, 8);
       
  1476     EC_WRITE_U8 (command->data,     0x01); // enable write access
       
  1477     EC_WRITE_U8 (command->data + 1, 0x02); // request write operation
       
  1478     EC_WRITE_U32(command->data + 2, fsm->sii_offset);
       
  1479     memcpy(command->data + 6, fsm->sii_value, 2);
       
  1480     ec_master_queue_command(fsm->master, command);
       
  1481     fsm->sii_state = ec_fsm_sii_write_check;
       
  1482 }
       
  1483 
       
  1484 /*****************************************************************************/
       
  1485 
       
  1486 /**
       
  1487    SII state: WRITE_CHECK.
       
  1488 */
       
  1489 
       
  1490 void ec_fsm_sii_write_check(ec_fsm_t *fsm /**< finite state machine */)
       
  1491 {
       
  1492     ec_command_t *command = &fsm->command;
       
  1493 
       
  1494     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1495         EC_ERR("SII: Reception of write command failed.\n");
       
  1496         fsm->sii_state = ec_fsm_sii_error;
       
  1497         return;
       
  1498     }
       
  1499 
       
  1500     fsm->sii_start = get_cycles();
       
  1501 
       
  1502     // issue check/fetch command
       
  1503     ec_command_nprd(command, fsm->slave->station_address, 0x502, 2);
       
  1504     ec_master_queue_command(fsm->master, command);
       
  1505     fsm->sii_state = ec_fsm_sii_write_check2;
       
  1506 }
       
  1507 
       
  1508 /*****************************************************************************/
       
  1509 
       
  1510 /**
       
  1511    SII state: WRITE_CHECK2.
       
  1512 */
       
  1513 
       
  1514 void ec_fsm_sii_write_check2(ec_fsm_t *fsm /**< finite state machine */)
       
  1515 {
       
  1516     ec_command_t *command = &fsm->command;
       
  1517 
       
  1518     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1519         EC_ERR("SII: Reception of write check command failed.\n");
       
  1520         fsm->sii_state = ec_fsm_sii_error;
       
  1521         return;
       
  1522     }
       
  1523 
       
  1524     if (EC_READ_U8(command->data + 1) & 0x82) {
       
  1525         // still busy... timeout?
       
  1526         if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
       
  1527             EC_ERR("SII: Write timeout.\n");
       
  1528             fsm->sii_state = ec_fsm_sii_error;
       
  1529         }
       
  1530 
       
  1531         // issue check/fetch command again
       
  1532         ec_master_queue_command(fsm->master, command);
       
  1533     }
       
  1534     else if (EC_READ_U8(command->data + 1) & 0x40) {
       
  1535         EC_ERR("SII: Write operation failed!\n");
       
  1536         fsm->sii_state = ec_fsm_sii_error;
       
  1537     }
       
  1538     else { // success
       
  1539         fsm->sii_state = ec_fsm_sii_end;
       
  1540     }
  1396 }
  1541 }
  1397 
  1542 
  1398 /*****************************************************************************/
  1543 /*****************************************************************************/
  1399 
  1544 
  1400 /**
  1545 /**