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 /*****************************************************************************/ |