2 * Generic MODBUS Library for STM32
4 * (c) 2019 Martin Mareš <mj@ucw.cz>
13 #include <libopencm3/cm3/nvic.h>
14 #include <libopencm3/stm32/gpio.h>
15 #include <libopencm3/stm32/usart.h>
16 #include <libopencm3/stm32/timer.h>
18 /*** Configuration ***/
20 // You should set the following parameters in config.h
22 // USART (pins are expected to be configured by the caller)
23 // #define MODBUS_USART USART2
24 // #define MODBUS_NVIC_USART_IRQ NVIC_USART2_IRQ
25 // #define MODBUS_USART_ISR usart2_isr
27 // GPIO pin for transmitter enable (pins is expected to be configured by the caller)
28 // #define MODBUS_TXEN_GPIO_PORT GPIOA
29 // #define MODBUS_TXEN_GPIO_PIN GPIO1
32 // #define MODBUS_TIMER TIM2
33 // #define MODBUS_NVIC_TIMER_IRQ NVIC_TIM2_IRQ
34 // #define MODBUS_TIMER_ISR tim2_isr
36 // Slave address we are responding at
37 // #define MODBUS_OUR_ADDRESS 42
40 #ifndef MODBUS_BAUD_RATE
41 #define MODBUS_BAUD_RATE 19200
44 // CPU clock frequency
45 // #define CPU_CLOCK_MHZ 72
47 // Receive buffer size (standard specifies 256 bytes, you can make it shorter if necessary)
48 #ifndef MODBUS_RX_BUFSIZE
49 #define MODBUS_RX_BUFSIZE 256
52 // Transmit buffer size (standard specifies 256 bytes, you can make it shorter if necessary)
53 #ifndef MODBUS_TX_BUFSIZE
54 #define MODBUS_TX_BUFSIZE 256
57 // Receive timeout in microseconds
58 #ifndef MODBUS_RX_TIMEOUT
59 #if MODBUS_BAUD_RATE <= 19200
60 // For low baud rates, the standard specifies timeout of 1.5 character times
61 // (1 character = start bit + 8 data bits + parity bit + stop bit = 11 bits)
62 #define MODBUS_RX_TIMEOUT (1000000*11*3/2/MODBUS_BAUD_RATE)
64 // For high rates, the timeout is fixed to 750 μs
65 #define MODBUS_RX_TIMEOUT 750
80 static byte rx_buf[MODBUS_RX_BUFSIZE];
83 static byte state; // STATE_xxx
85 static byte *rx_frame;
86 static byte *rx_frame_end;
88 static byte tx_buf[MODBUS_TX_BUFSIZE];
92 static bool check_frame(void);
93 static void process_frame(void);
95 /*** Low-level layer ***/
97 static void rx_init(void)
102 usart_set_mode(MODBUS_USART, USART_MODE_RX);
103 usart_enable_rx_interrupt(MODBUS_USART);
106 static void rx_done(void)
108 state = STATE_RX_DONE;
109 usart_disable_rx_interrupt(MODBUS_USART);
112 static void tx_init(void)
116 gpio_set(MODBUS_TXEN_GPIO_PORT, MODBUS_TXEN_GPIO_PIN);
117 usart_set_mode(MODBUS_USART, USART_MODE_TX);
118 usart_enable_tx_interrupt(MODBUS_USART);
121 static void tx_done(void)
123 state = STATE_TX_DONE;
124 // usart_disable_tx_interrupt(MODBUS_USART); // Already done by irq handler
125 gpio_clear(MODBUS_TXEN_GPIO_PORT, MODBUS_TXEN_GPIO_PIN);
128 void modbus_init(void)
130 timer_set_prescaler(MODBUS_TIMER, CPU_CLOCK_MHZ-1); // 1 tick = 1 μs
131 timer_set_mode(MODBUS_TIMER, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_DOWN);
132 timer_update_on_overflow(MODBUS_TIMER);
133 timer_disable_preload(MODBUS_TIMER);
134 timer_one_shot_mode(MODBUS_TIMER);
135 timer_enable_irq(MODBUS_TIMER, TIM_DIER_UIE);
136 nvic_enable_irq(MODBUS_NVIC_TIMER_IRQ);
138 gpio_clear(MODBUS_TXEN_GPIO_PORT, MODBUS_TXEN_GPIO_PIN);
140 usart_set_baudrate(MODBUS_USART, MODBUS_BAUD_RATE);
141 usart_set_databits(MODBUS_USART, 9);
142 usart_set_stopbits(MODBUS_USART, USART_STOPBITS_1);
143 usart_set_parity(MODBUS_USART, USART_PARITY_EVEN);
144 usart_set_flow_control(MODBUS_USART, USART_FLOWCONTROL_NONE);
148 nvic_enable_irq(MODBUS_NVIC_USART_IRQ);
149 usart_enable(MODBUS_USART);
152 void MODBUS_USART_ISR(void)
154 u32 status = USART_SR(MODBUS_USART);
156 if (status & USART_SR_RXNE) {
157 uint ch = usart_recv(MODBUS_USART);
158 if (state == STATE_RX) {
159 if (status & (USART_SR_FE | USART_SR_ORE | USART_SR_NE)) {
161 } else if (rx_size < MODBUS_RX_BUFSIZE) {
162 rx_buf[rx_size++] = ch;
167 timer_set_period(MODBUS_TIMER, MODBUS_RX_TIMEOUT);
168 timer_generate_event(MODBUS_TIMER, TIM_EGR_UG);
169 timer_enable_counter(MODBUS_TIMER);
173 if (state == STATE_TX) {
174 if (status & USART_SR_TXE) {
175 if (tx_pos < tx_size) {
176 usart_send(MODBUS_USART, tx_buf[tx_pos++]);
178 // The transmitter is double-buffered, so at this moment, it is transmitting
179 // the last byte of the frame. Wait until transfer is completed.
180 usart_disable_tx_interrupt(MODBUS_USART);
181 USART_CR1(MODBUS_USART) |= USART_CR1_TCIE;
182 state = STATE_TX_LAST;
185 } else if (state == STATE_TX_LAST) {
186 if (status & USART_SR_TC) {
187 // Transfer of the last byte is complete. Release the bus.
188 USART_CR1(MODBUS_USART) &= ~USART_CR1_TCIE;
195 void MODBUS_TIMER_ISR(void)
197 if (TIM_SR(MODBUS_TIMER) & TIM_SR_UIF) {
198 TIM_SR(MODBUS_TIMER) &= ~TIM_SR_UIF;
199 if (state == STATE_RX)
204 void modbus_loop(void)
206 if (state != STATE_RX_DONE)
208 state = STATE_PROCESSING;
210 if (!check_frame()) {
215 if (rx_buf[0] == MODBUS_OUR_ADDRESS) {
216 // Frame addressed to us: process and reply
219 } else if (rx_buf[0] == 0x00) {
220 // Broadcast frame: process, but do not reply
224 // Somebody else's frame: discard
231 static const byte crc_hi[] = {
232 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0,
233 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
234 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0,
235 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
236 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1,
237 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41,
238 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1,
239 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
240 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0,
241 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40,
242 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1,
243 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
244 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0,
245 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40,
246 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0,
247 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
248 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0,
249 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
250 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0,
251 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
252 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0,
253 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40,
254 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1,
255 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
256 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0,
257 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40
260 static const byte crc_lo[] = {
261 0x00, 0xc0, 0xc1, 0x01, 0xc3, 0x03, 0x02, 0xc2, 0xc6, 0x06,
262 0x07, 0xc7, 0x05, 0xc5, 0xc4, 0x04, 0xcc, 0x0c, 0x0d, 0xcd,
263 0x0f, 0xcf, 0xce, 0x0e, 0x0a, 0xca, 0xcb, 0x0b, 0xc9, 0x09,
264 0x08, 0xc8, 0xd8, 0x18, 0x19, 0xd9, 0x1b, 0xdb, 0xda, 0x1a,
265 0x1e, 0xde, 0xdf, 0x1f, 0xdd, 0x1d, 0x1c, 0xdc, 0x14, 0xd4,
266 0xd5, 0x15, 0xd7, 0x17, 0x16, 0xd6, 0xd2, 0x12, 0x13, 0xd3,
267 0x11, 0xd1, 0xd0, 0x10, 0xf0, 0x30, 0x31, 0xf1, 0x33, 0xf3,
268 0xf2, 0x32, 0x36, 0xf6, 0xf7, 0x37, 0xf5, 0x35, 0x34, 0xf4,
269 0x3c, 0xfc, 0xfd, 0x3d, 0xff, 0x3f, 0x3e, 0xfe, 0xfa, 0x3a,
270 0x3b, 0xfb, 0x39, 0xf9, 0xf8, 0x38, 0x28, 0xe8, 0xe9, 0x29,
271 0xeb, 0x2b, 0x2a, 0xea, 0xee, 0x2e, 0x2f, 0xef, 0x2d, 0xed,
272 0xec, 0x2c, 0xe4, 0x24, 0x25, 0xe5, 0x27, 0xe7, 0xe6, 0x26,
273 0x22, 0xe2, 0xe3, 0x23, 0xe1, 0x21, 0x20, 0xe0, 0xa0, 0x60,
274 0x61, 0xa1, 0x63, 0xa3, 0xa2, 0x62, 0x66, 0xa6, 0xa7, 0x67,
275 0xa5, 0x65, 0x64, 0xa4, 0x6c, 0xac, 0xad, 0x6d, 0xaf, 0x6f,
276 0x6e, 0xae, 0xaa, 0x6a, 0x6b, 0xab, 0x69, 0xa9, 0xa8, 0x68,
277 0x78, 0xb8, 0xb9, 0x79, 0xbb, 0x7b, 0x7a, 0xba, 0xbe, 0x7e,
278 0x7f, 0xbf, 0x7d, 0xbd, 0xbc, 0x7c, 0xb4, 0x74, 0x75, 0xb5,
279 0x77, 0xb7, 0xb6, 0x76, 0x72, 0xb2, 0xb3, 0x73, 0xb1, 0x71,
280 0x70, 0xb0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
281 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9c, 0x5c,
282 0x5d, 0x9d, 0x5f, 0x9f, 0x9e, 0x5e, 0x5a, 0x9a, 0x9b, 0x5b,
283 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4b, 0x8b,
284 0x8a, 0x4a, 0x4e, 0x8e, 0x8f, 0x4f, 0x8d, 0x4d, 0x4c, 0x8c,
285 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
286 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
289 static u16 crc16(byte *buf, u16 len)
291 byte hi = 0xff, lo = 0xff;
294 byte i = hi ^ *buf++;
299 return (hi << 8 | lo);
302 /*** High-level layer ***/
304 static bool check_frame(void)
307 // FIXME: Error counters?
312 // FIXME: Error counters?
316 u16 crc = crc16(rx_buf, rx_size - 2);
317 u16 rx_crc = (rx_buf[rx_size-2] << 8) | rx_buf[rx_size-1];
319 // FIXME: Error counters?
323 rx_frame = rx_buf + 1;
324 rx_frame_end = rx_frame + rx_size - 2;
329 FUNC_READ_COILS = 0x01,
330 FUNC_READ_DISCRETE_INPUTS = 0x02,
331 FUNC_READ_HOLDING_REGISTERS = 0x03,
332 FUNC_READ_INPUT_REGISTERS = 0x04,
333 FUNC_WRITE_SINGLE_COIL = 0x05,
334 FUNC_WRITE_SINGLE_REGISTER = 0x06,
335 FUNC_READ_EXCEPTION_STATUS = 0x07,
336 FUNC_DIAGNOSTICS = 0x08,
337 FUNC_GET_COMM_EVENT_COUNTER = 0x0b,
338 FUNC_GET_COMM_EVENT_LOG = 0x0c,
339 FUNC_WRITE_MULTIPLE_COILS = 0x0f,
340 FUNC_WRITE_MULTIPLE_REGISTERS = 0x10,
341 FUNC_REPORT_SLAVE_ID = 0x11,
342 FUNC_READ_FILE_RECORD = 0x14,
343 FUNC_WRITE_FILE_RECORD = 0x15,
344 FUNC_MASK_WRITE_REGISTER = 0x16,
345 FUNC_READ_WRITE_MULTIPLE_REGISTERS = 0x17,
346 FUNC_READ_FIFO_QUEUE = 0x18,
347 FUNC_ENCAPSULATED_INTERFACE_TRANSPORT = 0x2b,
351 ERR_ILLEGAL_FUNCTION = 0x01,
352 ERR_ILLEGAL_DATA_ADDRESS = 0x02,
353 ERR_ILLEGAL_DATA_VALUE = 0x03,
356 static uint read_remains(void)
358 return rx_frame_end - rx_frame;
361 static byte read_byte(void)
366 static u16 read_u16(void)
368 byte hi = *rx_frame++;
369 byte lo = *rx_frame++;
370 return (hi << 8) | lo;
373 static void write_byte(byte v)
375 tx_buf[tx_size++] = v;
378 static void write_u16(u16 v)
384 static bool body_fits(uint body_len)
386 // body_len excludes slave address, function code, and CRC
387 return (2 + body_len + 2 <= MODBUS_TX_BUFSIZE);
390 static void report_error(byte code)
392 // Discard the partially constructed body of the reply and rewrite the header
398 static void func_read_bits(bool coils)
400 if (read_remains() < 4)
401 return report_error(ERR_ILLEGAL_DATA_VALUE);
403 u16 start = read_u16();
404 u16 count = read_u16();
406 uint bytes = (count+7) / 8;
407 if (!body_fits(1 + bytes))
408 return report_error(ERR_ILLEGAL_DATA_VALUE);
410 for (u16 i = 0; i < count; i++)
411 if (!(coils ? modbus_check_coil : modbus_check_discrete_input)(start + i))
412 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
415 for (u16 i = 0; i < bytes; i++) {
417 for (byte j = 0; j < 8 && 8*i + j < count; j++) {
418 uint addr = start + 8*i + j;
419 if ((coils ? modbus_get_coil : modbus_get_discrete_input)(addr))
426 static void func_read_registers(byte holding)
428 if (read_remains() < 4)
429 return report_error(ERR_ILLEGAL_DATA_VALUE);
431 u16 start = read_u16();
432 u16 count = read_u16();
434 uint bytes = 2*count;
435 if (!body_fits(1 + bytes))
436 return report_error(ERR_ILLEGAL_DATA_VALUE);
438 for (u16 i = 0; i < count; i++)
439 if (!(holding ? modbus_check_holding_register : modbus_check_input_register)(start + i))
440 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
442 // FIXME: Reporting of slave failures?
444 for (u16 i = 0; i < count; i++)
445 write_u16((holding ? modbus_get_holding_register : modbus_get_input_register)(start + i));
448 static void func_write_single_coil(void)
450 if (read_remains() < 4)
451 return report_error(ERR_ILLEGAL_DATA_VALUE);
453 u16 addr = read_u16();
454 u16 value = read_u16();
456 if (!modbus_check_coil(addr))
457 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
458 if (value != 0x0000 && value != 0xff00)
459 return report_error(ERR_ILLEGAL_DATA_VALUE);
461 modbus_set_coil(addr, value);
464 static void func_write_single_register(void)
466 if (read_remains() < 4)
467 return report_error(ERR_ILLEGAL_DATA_VALUE);
469 u16 addr = read_u16();
470 u16 value = read_u16();
472 if (!modbus_check_holding_register(addr))
473 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
475 modbus_set_holding_register(addr, value);
478 static void func_write_multiple_coils(void)
480 if (read_remains() < 5)
481 return report_error(ERR_ILLEGAL_DATA_VALUE);
483 u16 start = read_u16();
484 u16 count = read_u16();
485 byte bytes = read_byte();
487 if (read_remains() < bytes || bytes != (count+7) / 8)
488 return report_error(ERR_ILLEGAL_DATA_VALUE);
490 for (u16 i = 0; i < count; i++)
491 if (!modbus_check_coil(start + i))
492 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
494 for (u16 i = 0; i < count; i++)
495 modbus_set_coil(start + i, rx_frame[i/8] & (1U << (i%8)));
498 static void func_write_multiple_registers(void)
500 if (read_remains() < 5)
501 return report_error(ERR_ILLEGAL_DATA_VALUE);
503 u16 start = read_u16();
504 u16 count = read_u16();
505 byte bytes = read_byte();
507 if (read_remains() < bytes || bytes != 2*count)
508 return report_error(ERR_ILLEGAL_DATA_VALUE);
510 for (u16 i = 0; i < count; i++)
511 if (!modbus_check_holding_register(start + i))
512 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
514 for (u16 i = 0; i < count; i++)
515 modbus_set_holding_register(start + i, read_u16());
518 static void func_mask_write_register(void)
520 if (read_remains() < 6)
521 return report_error(ERR_ILLEGAL_DATA_VALUE);
523 u16 addr = read_u16();
524 u16 and_mask = read_u16();
525 u16 or_mask = read_u16();
527 if (!modbus_check_holding_register(addr))
528 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
530 u16 reg = modbus_get_holding_register(addr);
531 reg = (reg & and_mask) | (or_mask & ~and_mask);
532 modbus_set_holding_register(addr, reg);
535 static void func_read_write_multiple_registers(void)
537 if (read_remains() < 9)
538 return report_error(ERR_ILLEGAL_DATA_VALUE);
540 u16 read_start = read_u16();
541 u16 read_count = read_u16();
542 u16 write_start = read_u16();
543 u16 write_count = read_u16();
544 byte write_bytes = read_byte();
546 if (read_remains() < write_bytes || write_bytes != 2*write_count)
547 return report_error(ERR_ILLEGAL_DATA_VALUE);
549 for (u16 i = 0; i < read_count; i++)
550 if (!modbus_check_holding_register(read_start + i))
551 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
553 for (u16 i = 0; i < write_count; i++)
554 if (!modbus_check_holding_register(write_start + i))
555 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
557 byte read_bytes = 2*write_count;
558 if (!body_fits(1 + read_bytes))
559 return report_error(ERR_ILLEGAL_DATA_VALUE);
561 for (u16 i = 0; i < write_count; i++)
562 modbus_set_holding_register(write_start + i, read_u16());
564 write_byte(read_bytes);
565 for (u16 i = 0; i < read_count; i++)
566 modbus_get_holding_register(read_start + i);
569 static void func_encapsulated_interface_transport(void)
571 if (read_remains() < 3 ||
573 return report_error(ERR_ILLEGAL_DATA_VALUE);
575 byte action = read_byte();
576 byte id = read_byte();
578 byte range_min, range_max;
581 // Streaming access to basic identification
582 range_min = MODBUS_ID_VENDOR_NAME;
583 range_max = MODBUS_ID_MAJOR_MINOR_REVISION;
586 // Streaming access to regular identification
587 range_min = MODBUS_ID_VENDOR_URL;
588 range_max = MODBUS_ID_USER_APP_NAME;
592 if (id >= MODBUS_ID_MAX || !modbus_id_strings[id])
593 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
594 range_min = range_max = id;
597 return report_error(ERR_ILLEGAL_DATA_VALUE);
601 if (id < range_min || id > range_max)
605 write_byte(0x0e); // Repeat a part of the request
609 if (modbus_id_strings[MODBUS_ID_VENDOR_URL] ||
610 modbus_id_strings[MODBUS_ID_PRODUCT_NAME] ||
611 modbus_id_strings[MODBUS_ID_USER_APP_NAME])
612 write_byte(0x82); // Regular identification, both stream and individual access supported
614 write_byte(0x81); // Basic identification only
616 u16 more_follows_at = tx_size;
617 write_byte(0); // More follows: so far not
618 write_byte(0); // Next object ID: so far none
619 write_byte(0); // Number of objects
621 for (id = range_min; id <= range_max; id++) {
622 if (modbus_id_strings[id]) {
623 byte len = strlen(modbus_id_strings[id]);
624 byte remains = MODBUS_TX_BUFSIZE - 4 - tx_size; // 2 for CRC, 2 for object header
626 // If it is the only object, cut it
627 if (!tx_buf[more_follows_at + 2])
630 // More follows, report the next ID
631 tx_buf[more_follows_at] = 0xff;
632 tx_buf[more_follows_at + 1] = id;
636 tx_buf[more_follows_at + 2] ++;
639 memcpy(tx_buf + tx_size, modbus_id_strings[id], len);
645 static void process_frame(void)
647 byte func = read_byte();
649 // Prepare reply frame
650 tx_buf[0] = MODBUS_OUR_ADDRESS;
651 tx_buf[1] = rx_buf[1];
655 case FUNC_READ_COILS:
656 func_read_bits(true);
658 case FUNC_READ_DISCRETE_INPUTS:
659 func_read_bits(false);
661 case FUNC_READ_HOLDING_REGISTERS:
662 func_read_registers(true);
664 case FUNC_READ_INPUT_REGISTERS:
665 func_read_registers(false);
667 case FUNC_WRITE_SINGLE_COIL:
668 func_write_single_coil();
670 case FUNC_WRITE_SINGLE_REGISTER:
671 func_write_single_register();
673 case FUNC_WRITE_MULTIPLE_COILS:
674 func_write_multiple_coils();
676 case FUNC_WRITE_MULTIPLE_REGISTERS:
677 func_write_multiple_registers();
679 case FUNC_MASK_WRITE_REGISTER:
680 func_mask_write_register();
682 case FUNC_READ_WRITE_MULTIPLE_REGISTERS:
683 func_read_write_multiple_registers();
685 case FUNC_ENCAPSULATED_INTERFACE_TRANSPORT:
686 func_encapsulated_interface_transport();
689 report_error(ERR_ILLEGAL_FUNCTION);
692 // Finish reply frame
693 write_u16(crc16(tx_buf, tx_size));