static u16 tx_size;
static u16 tx_pos;
+static bool check_frame(void);
+static void process_frame(void);
+
+/*** Low-level layer ***/
+
static void rx_init(void)
{
state = STATE_RX;
}
}
-// CRC tables
+void modbus_loop(void)
+{
+ if (state != STATE_RX_DONE)
+ return;
+ state = STATE_PROCESSING;
+
+ if (!check_frame()) {
+ rx_init();
+ return;
+ }
+
+ if (rx_buf[0] == MODBUS_OUR_ADDRESS) {
+ // Frame addressed to us: process and reply
+ process_frame();
+ tx_init();
+ } else if (rx_buf[0] == 0x00) {
+ // Broadcast frame: process, but do not reply
+ process_frame();
+ rx_init();
+ } else {
+ // Somebody else's frame: discard
+ rx_init();
+ }
+}
+
+/** CRC ***/
static const byte crc_hi[] = {
0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0,
return (hi << 8 | lo);
}
+/*** High-level layer ***/
+
static bool check_frame(void)
{
if (rx_bad) {
// Finish reply frame
write_u16(crc16(tx_buf, tx_size));
}
-
-void modbus_loop(void)
-{
- if (state != STATE_RX_DONE)
- return;
- state = STATE_PROCESSING;
-
- if (!check_frame()) {
- rx_init();
- return;
- }
-
- if (rx_buf[0] == MODBUS_OUR_ADDRESS) {
- // Frame addressed to us: process and reply
- process_frame();
- tx_init();
- } else if (rx_buf[0] == 0x00) {
- // Broadcast frame: process, but do not reply
- process_frame();
- rx_init();
- } else {
- // Somebody else's frame: discard
- rx_init();
- }
-}
-
-/*** Callbacks ***/
-
-bool modbus_check_discrete_input(u16 addr UNUSED)
-{
- return false;
-}
-
-bool modbus_get_discrete_input(u16 addr UNUSED)
-{
- return false;
-}
-
-bool modbus_check_coil(u16 addr UNUSED)
-{
- return false;
-}
-
-bool modbus_get_coil(u16 addr UNUSED)
-{
- return false;
-}
-
-void modbus_set_coil(u16 addr UNUSED, bool value UNUSED)
-{
-}
-
-bool modbus_check_input_register(u16 addr UNUSED)
-{
- return false;
-}
-
-u16 modbus_get_input_register(u16 addr UNUSED)
-{
- return 0;
-}
-
-bool modbus_check_holding_register(u16 addr UNUSED)
-{
- return (addr == 0);
-}
-
-u16 modbus_get_holding_register(u16 addr UNUSED)
-{
- return 0xbeef;
-}
-
-void modbus_set_holding_register(u16 addr UNUSED, u16 value UNUSED)
-{
-}
-
-const char * const modbus_id_strings[MODBUS_ID_MAX] = {
- [MODBUS_ID_VENDOR_NAME] = "United Computer Wizards",
- [MODBUS_ID_PRODUCT_CODE] = "42",
- [MODBUS_ID_MAJOR_MINOR_REVISION] = "1.0",
- [MODBUS_ID_VENDOR_URL] = "http://www.ucw.cz/",
- [MODBUS_ID_PRODUCT_NAME] = "Magic Gadget",
- [MODBUS_ID_USER_APP_NAME] = NULL,
-};
return 0;
}
+
+/*** Modbus callbacks ***/
+
+bool modbus_check_discrete_input(u16 addr UNUSED)
+{
+ return false;
+}
+
+bool modbus_get_discrete_input(u16 addr UNUSED)
+{
+ return false;
+}
+
+bool modbus_check_coil(u16 addr UNUSED)
+{
+ return false;
+}
+
+bool modbus_get_coil(u16 addr UNUSED)
+{
+ return false;
+}
+
+void modbus_set_coil(u16 addr UNUSED, bool value UNUSED)
+{
+}
+
+bool modbus_check_input_register(u16 addr UNUSED)
+{
+ return false;
+}
+
+u16 modbus_get_input_register(u16 addr UNUSED)
+{
+ return 0;
+}
+
+bool modbus_check_holding_register(u16 addr UNUSED)
+{
+ return (addr == 0);
+}
+
+u16 modbus_get_holding_register(u16 addr UNUSED)
+{
+ return 0xbeef;
+}
+
+void modbus_set_holding_register(u16 addr UNUSED, u16 value UNUSED)
+{
+}
+
+const char * const modbus_id_strings[MODBUS_ID_MAX] = {
+ [MODBUS_ID_VENDOR_NAME] = "United Computer Wizards",
+ [MODBUS_ID_PRODUCT_CODE] = "42",
+ [MODBUS_ID_MAJOR_MINOR_REVISION] = "1.0",
+ [MODBUS_ID_VENDOR_URL] = "http://www.ucw.cz/",
+ [MODBUS_ID_PRODUCT_NAME] = "Magic Gadget",
+ [MODBUS_ID_USER_APP_NAME] = NULL,
+};