master/fsm.c
branchstable-1.0
changeset 1623 05622513f627
parent 1621 4bbe090553f7
child 1624 9dc190591c0f
equal deleted inserted replaced
1622:fe8777a69d4a 1623:05622513f627
    42 #include "fsm.h"
    42 #include "fsm.h"
    43 #include "master.h"
    43 #include "master.h"
    44 
    44 
    45 /*****************************************************************************/
    45 /*****************************************************************************/
    46 
    46 
    47 const ec_code_msg_t al_status_messages[];
       
    48 
       
    49 /*****************************************************************************/
       
    50 
       
    51 void ec_fsm_master_start(ec_fsm_t *);
    47 void ec_fsm_master_start(ec_fsm_t *);
    52 void ec_fsm_master_broadcast(ec_fsm_t *);
    48 void ec_fsm_master_broadcast(ec_fsm_t *);
    53 void ec_fsm_master_proc_states(ec_fsm_t *);
    49 void ec_fsm_master_proc_states(ec_fsm_t *);
    54 void ec_fsm_master_scan(ec_fsm_t *);
    50 void ec_fsm_master_scan(ec_fsm_t *);
    55 void ec_fsm_master_states(ec_fsm_t *);
    51 void ec_fsm_master_states(ec_fsm_t *);
  1673 }
  1669 }
  1674 
  1670 
  1675 /*****************************************************************************/
  1671 /*****************************************************************************/
  1676 
  1672 
  1677 /**
  1673 /**
  1678    Change state: CODE.
       
  1679 */
       
  1680 
       
  1681 void ec_fsm_change_code(ec_fsm_t *fsm /**< finite state machine */)
       
  1682 {
       
  1683     ec_command_t *command = &fsm->command;
       
  1684     ec_slave_t *slave = fsm->slave;
       
  1685     uint32_t code;
       
  1686     const ec_code_msg_t *al_msg;
       
  1687 
       
  1688     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1689         EC_ERR("Reception of AL status code command failed.\n");
       
  1690         slave->state_error = 1;
       
  1691         fsm->change_state = ec_fsm_change_error;
       
  1692         return;
       
  1693     }
       
  1694 
       
  1695     if ((code = EC_READ_U16(command->data))) {
       
  1696         for (al_msg = al_status_messages; al_msg->code; al_msg++) {
       
  1697             if (al_msg->code != code) continue;
       
  1698             EC_ERR("AL status message 0x%04X: \"%s\".\n",
       
  1699                    al_msg->code, al_msg->message);
       
  1700             break;
       
  1701         }
       
  1702         if (!al_msg->code)
       
  1703             EC_ERR("Unknown AL status code 0x%04X.\n", code);
       
  1704     }
       
  1705 
       
  1706     // acknowledge "old" slave state
       
  1707     ec_command_npwr(command, slave->station_address, 0x0120, 2);
       
  1708     EC_WRITE_U16(command->data, slave->current_state);
       
  1709     ec_master_queue_command(fsm->master, command);
       
  1710     fsm->change_state = ec_fsm_change_ack;
       
  1711 }
       
  1712 
       
  1713 /*****************************************************************************/
       
  1714 
       
  1715 /**
       
  1716    Change state: ACK.
       
  1717 */
       
  1718 
       
  1719 void ec_fsm_change_ack(ec_fsm_t *fsm /**< finite state machine */)
       
  1720 {
       
  1721     ec_command_t *command = &fsm->command;
       
  1722     ec_slave_t *slave = fsm->slave;
       
  1723 
       
  1724     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1725         EC_ERR("Reception of state ack command failed.\n");
       
  1726         slave->state_error = 1;
       
  1727         fsm->change_state = ec_fsm_change_error;
       
  1728         return;
       
  1729     }
       
  1730 
       
  1731     // read new AL status
       
  1732     ec_command_nprd(command, slave->station_address, 0x0130, 2);
       
  1733     ec_master_queue_command(fsm->master, command);
       
  1734     fsm->change_state = ec_fsm_change_ack2;
       
  1735 }
       
  1736 
       
  1737 /*****************************************************************************/
       
  1738 
       
  1739 /**
       
  1740    Change state: ACK.
       
  1741    Acknowledge 2.
       
  1742 */
       
  1743 
       
  1744 void ec_fsm_change_ack2(ec_fsm_t *fsm /**< finite state machine */)
       
  1745 {
       
  1746     ec_command_t *command = &fsm->command;
       
  1747     ec_slave_t *slave = fsm->slave;
       
  1748 
       
  1749     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1750         EC_ERR("Reception of state ack check command failed.\n");
       
  1751         slave->state_error = 1;
       
  1752         fsm->change_state = ec_fsm_change_error;
       
  1753         return;
       
  1754     }
       
  1755 
       
  1756     slave->current_state = EC_READ_U8(command->data);
       
  1757 
       
  1758     if (slave->current_state == fsm->change_new) {
       
  1759         EC_INFO("Acknowleged state 0x%02X on slave %i.\n",
       
  1760                 slave->current_state, slave->ring_position);
       
  1761         slave->state_error = 1;
       
  1762         fsm->change_state = ec_fsm_change_error;
       
  1763         return;
       
  1764     }
       
  1765 
       
  1766     EC_WARN("Failed to acknowledge state 0x%02X on slave %i"
       
  1767             " - Timeout!\n", fsm->change_new, slave->ring_position);
       
  1768     slave->state_error = 1;
       
  1769     fsm->change_state = ec_fsm_change_error;
       
  1770 }
       
  1771 
       
  1772 /*****************************************************************************/
       
  1773 
       
  1774 /**
       
  1775    Change state: END.
       
  1776 */
       
  1777 
       
  1778 void ec_fsm_change_end(ec_fsm_t *fsm /**< finite state machine */)
       
  1779 {
       
  1780 }
       
  1781 
       
  1782 /*****************************************************************************/
       
  1783 
       
  1784 /**
       
  1785    Change state: ERROR.
       
  1786 */
       
  1787 
       
  1788 void ec_fsm_change_error(ec_fsm_t *fsm /**< finite state machine */)
       
  1789 {
       
  1790 }
       
  1791 
       
  1792 /*****************************************************************************/
       
  1793 
       
  1794 /**
       
  1795    Application layer status messages.
  1674    Application layer status messages.
  1796 */
  1675 */
  1797 
  1676 
  1798 const ec_code_msg_t al_status_messages[] = {
  1677 const ec_code_msg_t al_status_messages[] = {
  1799     {0x0001, "Unspecified error"},
  1678     {0x0001, "Unspecified error"},
  1814     {0x0023, "Slave needs SAVEOP"},
  1693     {0x0023, "Slave needs SAVEOP"},
  1815     {}
  1694     {}
  1816 };
  1695 };
  1817 
  1696 
  1818 /*****************************************************************************/
  1697 /*****************************************************************************/
       
  1698 
       
  1699 /**
       
  1700    Change state: CODE.
       
  1701 */
       
  1702 
       
  1703 void ec_fsm_change_code(ec_fsm_t *fsm /**< finite state machine */)
       
  1704 {
       
  1705     ec_command_t *command = &fsm->command;
       
  1706     ec_slave_t *slave = fsm->slave;
       
  1707     uint32_t code;
       
  1708     const ec_code_msg_t *al_msg;
       
  1709 
       
  1710     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1711         EC_ERR("Reception of AL status code command failed.\n");
       
  1712         slave->state_error = 1;
       
  1713         fsm->change_state = ec_fsm_change_error;
       
  1714         return;
       
  1715     }
       
  1716 
       
  1717     if ((code = EC_READ_U16(command->data))) {
       
  1718         for (al_msg = al_status_messages; al_msg->code; al_msg++) {
       
  1719             if (al_msg->code != code) continue;
       
  1720             EC_ERR("AL status message 0x%04X: \"%s\".\n",
       
  1721                    al_msg->code, al_msg->message);
       
  1722             break;
       
  1723         }
       
  1724         if (!al_msg->code)
       
  1725             EC_ERR("Unknown AL status code 0x%04X.\n", code);
       
  1726     }
       
  1727 
       
  1728     // acknowledge "old" slave state
       
  1729     ec_command_npwr(command, slave->station_address, 0x0120, 2);
       
  1730     EC_WRITE_U16(command->data, slave->current_state);
       
  1731     ec_master_queue_command(fsm->master, command);
       
  1732     fsm->change_state = ec_fsm_change_ack;
       
  1733 }
       
  1734 
       
  1735 /*****************************************************************************/
       
  1736 
       
  1737 /**
       
  1738    Change state: ACK.
       
  1739 */
       
  1740 
       
  1741 void ec_fsm_change_ack(ec_fsm_t *fsm /**< finite state machine */)
       
  1742 {
       
  1743     ec_command_t *command = &fsm->command;
       
  1744     ec_slave_t *slave = fsm->slave;
       
  1745 
       
  1746     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1747         EC_ERR("Reception of state ack command failed.\n");
       
  1748         slave->state_error = 1;
       
  1749         fsm->change_state = ec_fsm_change_error;
       
  1750         return;
       
  1751     }
       
  1752 
       
  1753     // read new AL status
       
  1754     ec_command_nprd(command, slave->station_address, 0x0130, 2);
       
  1755     ec_master_queue_command(fsm->master, command);
       
  1756     fsm->change_state = ec_fsm_change_ack2;
       
  1757 }
       
  1758 
       
  1759 /*****************************************************************************/
       
  1760 
       
  1761 /**
       
  1762    Change state: ACK.
       
  1763    Acknowledge 2.
       
  1764 */
       
  1765 
       
  1766 void ec_fsm_change_ack2(ec_fsm_t *fsm /**< finite state machine */)
       
  1767 {
       
  1768     ec_command_t *command = &fsm->command;
       
  1769     ec_slave_t *slave = fsm->slave;
       
  1770 
       
  1771     if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) {
       
  1772         EC_ERR("Reception of state ack check command failed.\n");
       
  1773         slave->state_error = 1;
       
  1774         fsm->change_state = ec_fsm_change_error;
       
  1775         return;
       
  1776     }
       
  1777 
       
  1778     slave->current_state = EC_READ_U8(command->data);
       
  1779 
       
  1780     if (slave->current_state == fsm->change_new) {
       
  1781         EC_INFO("Acknowleged state 0x%02X on slave %i.\n",
       
  1782                 slave->current_state, slave->ring_position);
       
  1783         slave->state_error = 1;
       
  1784         fsm->change_state = ec_fsm_change_error;
       
  1785         return;
       
  1786     }
       
  1787 
       
  1788     EC_WARN("Failed to acknowledge state 0x%02X on slave %i"
       
  1789             " - Timeout!\n", fsm->change_new, slave->ring_position);
       
  1790     slave->state_error = 1;
       
  1791     fsm->change_state = ec_fsm_change_error;
       
  1792 }
       
  1793 
       
  1794 /*****************************************************************************/
       
  1795 
       
  1796 /**
       
  1797    Change state: END.
       
  1798 */
       
  1799 
       
  1800 void ec_fsm_change_end(ec_fsm_t *fsm /**< finite state machine */)
       
  1801 {
       
  1802 }
       
  1803 
       
  1804 /*****************************************************************************/
       
  1805 
       
  1806 /**
       
  1807    Change state: ERROR.
       
  1808 */
       
  1809 
       
  1810 void ec_fsm_change_error(ec_fsm_t *fsm /**< finite state machine */)
       
  1811 {
       
  1812 }
       
  1813 
       
  1814 /*****************************************************************************/