2 * Generic MODBUS Library for STM32
4 * (c) 2019 Martin Mareš <mj@ucw.cz>
14 #include <libopencm3/cm3/nvic.h>
15 #include <libopencm3/stm32/gpio.h>
16 #include <libopencm3/stm32/usart.h>
17 #include <libopencm3/stm32/timer.h>
19 /*** Configuration ***/
21 // You should set the following parameters in config.h
23 // USART (pins are expected to be configured by the caller)
24 // #define MODBUS_USART USART2
25 // #define MODBUS_NVIC_USART_IRQ NVIC_USART2_IRQ
26 // #define MODBUS_USART_ISR usart2_isr
28 // GPIO pin for transmitter enable (pins is expected to be configured by the caller)
29 // #define MODBUS_TXEN_GPIO_PORT GPIOA
30 // #define MODBUS_TXEN_GPIO_PIN GPIO1
33 // #define MODBUS_TIMER TIM2
34 // #define MODBUS_NVIC_TIMER_IRQ NVIC_TIM2_IRQ
35 // #define MODBUS_TIMER_ISR tim2_isr
37 // Slave address we are responding at
38 // #define MODBUS_OUR_ADDRESS 42
41 #ifndef MODBUS_BAUD_RATE
42 #define MODBUS_BAUD_RATE 19200
45 // CPU clock frequency
46 // #define CPU_CLOCK_MHZ 72
48 // Receive buffer size (standard specifies 256 bytes, you can make it shorter if necessary)
49 #ifndef MODBUS_RX_BUFSIZE
50 #define MODBUS_RX_BUFSIZE 256
53 // Transmit buffer size (standard specifies 256 bytes, you can make it shorter if necessary)
54 #ifndef MODBUS_TX_BUFSIZE
55 #define MODBUS_TX_BUFSIZE 256
58 // Receive timeout in microseconds
59 #ifndef MODBUS_RX_TIMEOUT
60 #if MODBUS_BAUD_RATE <= 19200
61 // For low baud rates, the standard specifies timeout of 1.5 character times
62 // (1 character = start bit + 8 data bits + parity bit + stop bit = 11 bits)
63 #define MODBUS_RX_TIMEOUT (1000000*11*3/2/MODBUS_BAUD_RATE)
65 // For high rates, the timeout is fixed to 750 μs
66 #define MODBUS_RX_TIMEOUT 750
81 static byte rx_buf[MODBUS_RX_BUFSIZE];
84 static byte state; // STATE_xxx
86 static byte *rx_frame;
87 static byte *rx_frame_end;
89 static byte tx_buf[MODBUS_TX_BUFSIZE];
93 static bool check_frame(void);
94 static void process_frame(void);
96 /*** Low-level layer ***/
98 static void rx_init(void)
103 usart_set_mode(MODBUS_USART, USART_MODE_RX);
104 usart_enable_rx_interrupt(MODBUS_USART);
107 static void rx_done(void)
109 state = STATE_RX_DONE;
110 usart_disable_rx_interrupt(MODBUS_USART);
113 static void tx_init(void)
117 gpio_set(MODBUS_TXEN_GPIO_PORT, MODBUS_TXEN_GPIO_PIN);
118 usart_set_mode(MODBUS_USART, USART_MODE_TX);
119 usart_enable_tx_interrupt(MODBUS_USART);
122 static void tx_done(void)
124 state = STATE_TX_DONE;
125 // usart_disable_tx_interrupt(MODBUS_USART); // Already done by irq handler
126 gpio_clear(MODBUS_TXEN_GPIO_PORT, MODBUS_TXEN_GPIO_PIN);
129 void modbus_init(void)
131 timer_set_prescaler(MODBUS_TIMER, CPU_CLOCK_MHZ-1); // 1 tick = 1 μs
132 timer_set_mode(MODBUS_TIMER, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_DOWN);
133 timer_update_on_overflow(MODBUS_TIMER);
134 timer_disable_preload(MODBUS_TIMER);
135 timer_one_shot_mode(MODBUS_TIMER);
136 timer_enable_irq(MODBUS_TIMER, TIM_DIER_UIE);
137 nvic_enable_irq(MODBUS_NVIC_TIMER_IRQ);
139 gpio_clear(MODBUS_TXEN_GPIO_PORT, MODBUS_TXEN_GPIO_PIN);
141 usart_set_baudrate(MODBUS_USART, MODBUS_BAUD_RATE);
142 usart_set_databits(MODBUS_USART, 9);
143 usart_set_stopbits(MODBUS_USART, USART_STOPBITS_1);
144 usart_set_parity(MODBUS_USART, USART_PARITY_EVEN);
145 usart_set_flow_control(MODBUS_USART, USART_FLOWCONTROL_NONE);
149 nvic_enable_irq(MODBUS_NVIC_USART_IRQ);
150 usart_enable(MODBUS_USART);
153 void MODBUS_USART_ISR(void)
155 u32 status = USART_SR(MODBUS_USART);
157 if (status & USART_SR_RXNE) {
158 uint ch = usart_recv(MODBUS_USART);
159 if (state == STATE_RX) {
160 if (status & (USART_SR_FE | USART_SR_ORE | USART_SR_NE)) {
162 } else if (rx_size < MODBUS_RX_BUFSIZE) {
163 rx_buf[rx_size++] = ch;
168 timer_set_period(MODBUS_TIMER, MODBUS_RX_TIMEOUT);
169 timer_generate_event(MODBUS_TIMER, TIM_EGR_UG);
170 timer_enable_counter(MODBUS_TIMER);
174 if (state == STATE_TX) {
175 if (status & USART_SR_TXE) {
176 if (tx_pos < tx_size) {
177 usart_send(MODBUS_USART, tx_buf[tx_pos++]);
179 // The transmitter is double-buffered, so at this moment, it is transmitting
180 // the last byte of the frame. Wait until transfer is completed.
181 usart_disable_tx_interrupt(MODBUS_USART);
182 USART_CR1(MODBUS_USART) |= USART_CR1_TCIE;
183 state = STATE_TX_LAST;
186 } else if (state == STATE_TX_LAST) {
187 if (status & USART_SR_TC) {
188 // Transfer of the last byte is complete. Release the bus.
189 USART_CR1(MODBUS_USART) &= ~USART_CR1_TCIE;
196 void MODBUS_TIMER_ISR(void)
198 if (TIM_SR(MODBUS_TIMER) & TIM_SR_UIF) {
199 TIM_SR(MODBUS_TIMER) &= ~TIM_SR_UIF;
200 if (state == STATE_RX)
205 void modbus_loop(void)
207 if (state != STATE_RX_DONE)
209 state = STATE_PROCESSING;
211 if (!check_frame()) {
216 if (rx_buf[0] == MODBUS_OUR_ADDRESS) {
217 // Frame addressed to us: process and reply
220 } else if (rx_buf[0] == 0x00) {
221 // Broadcast frame: process, but do not reply
225 // Somebody else's frame: discard
232 static const byte crc_hi[] = {
233 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0,
234 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
235 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0,
236 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
237 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1,
238 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41,
239 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1,
240 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
241 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0,
242 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40,
243 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1,
244 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
245 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0,
246 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40,
247 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0,
248 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40,
249 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0,
250 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
251 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0,
252 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
253 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0,
254 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40,
255 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1,
256 0x81, 0x40, 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41,
257 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 0x01, 0xc0,
258 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40
261 static const byte crc_lo[] = {
262 0x00, 0xc0, 0xc1, 0x01, 0xc3, 0x03, 0x02, 0xc2, 0xc6, 0x06,
263 0x07, 0xc7, 0x05, 0xc5, 0xc4, 0x04, 0xcc, 0x0c, 0x0d, 0xcd,
264 0x0f, 0xcf, 0xce, 0x0e, 0x0a, 0xca, 0xcb, 0x0b, 0xc9, 0x09,
265 0x08, 0xc8, 0xd8, 0x18, 0x19, 0xd9, 0x1b, 0xdb, 0xda, 0x1a,
266 0x1e, 0xde, 0xdf, 0x1f, 0xdd, 0x1d, 0x1c, 0xdc, 0x14, 0xd4,
267 0xd5, 0x15, 0xd7, 0x17, 0x16, 0xd6, 0xd2, 0x12, 0x13, 0xd3,
268 0x11, 0xd1, 0xd0, 0x10, 0xf0, 0x30, 0x31, 0xf1, 0x33, 0xf3,
269 0xf2, 0x32, 0x36, 0xf6, 0xf7, 0x37, 0xf5, 0x35, 0x34, 0xf4,
270 0x3c, 0xfc, 0xfd, 0x3d, 0xff, 0x3f, 0x3e, 0xfe, 0xfa, 0x3a,
271 0x3b, 0xfb, 0x39, 0xf9, 0xf8, 0x38, 0x28, 0xe8, 0xe9, 0x29,
272 0xeb, 0x2b, 0x2a, 0xea, 0xee, 0x2e, 0x2f, 0xef, 0x2d, 0xed,
273 0xec, 0x2c, 0xe4, 0x24, 0x25, 0xe5, 0x27, 0xe7, 0xe6, 0x26,
274 0x22, 0xe2, 0xe3, 0x23, 0xe1, 0x21, 0x20, 0xe0, 0xa0, 0x60,
275 0x61, 0xa1, 0x63, 0xa3, 0xa2, 0x62, 0x66, 0xa6, 0xa7, 0x67,
276 0xa5, 0x65, 0x64, 0xa4, 0x6c, 0xac, 0xad, 0x6d, 0xaf, 0x6f,
277 0x6e, 0xae, 0xaa, 0x6a, 0x6b, 0xab, 0x69, 0xa9, 0xa8, 0x68,
278 0x78, 0xb8, 0xb9, 0x79, 0xbb, 0x7b, 0x7a, 0xba, 0xbe, 0x7e,
279 0x7f, 0xbf, 0x7d, 0xbd, 0xbc, 0x7c, 0xb4, 0x74, 0x75, 0xb5,
280 0x77, 0xb7, 0xb6, 0x76, 0x72, 0xb2, 0xb3, 0x73, 0xb1, 0x71,
281 0x70, 0xb0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
282 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9c, 0x5c,
283 0x5d, 0x9d, 0x5f, 0x9f, 0x9e, 0x5e, 0x5a, 0x9a, 0x9b, 0x5b,
284 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4b, 0x8b,
285 0x8a, 0x4a, 0x4e, 0x8e, 0x8f, 0x4f, 0x8d, 0x4d, 0x4c, 0x8c,
286 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
287 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
290 static u16 crc16(byte *buf, u16 len)
292 byte hi = 0xff, lo = 0xff;
295 byte i = hi ^ *buf++;
300 return (hi << 8 | lo);
303 /*** High-level layer ***/
305 static bool check_frame(void)
308 // FIXME: Error counters?
313 // FIXME: Error counters?
317 u16 crc = crc16(rx_buf, rx_size - 2);
318 u16 rx_crc = (rx_buf[rx_size-2] << 8) | rx_buf[rx_size-1];
320 // FIXME: Error counters?
324 rx_frame = rx_buf + 1;
325 rx_frame_end = rx_frame + rx_size - 2;
330 FUNC_READ_COILS = 0x01,
331 FUNC_READ_DISCRETE_INPUTS = 0x02,
332 FUNC_READ_HOLDING_REGISTERS = 0x03,
333 FUNC_READ_INPUT_REGISTERS = 0x04,
334 FUNC_WRITE_SINGLE_COIL = 0x05,
335 FUNC_WRITE_SINGLE_REGISTER = 0x06,
336 FUNC_READ_EXCEPTION_STATUS = 0x07,
337 FUNC_DIAGNOSTICS = 0x08,
338 FUNC_GET_COMM_EVENT_COUNTER = 0x0b,
339 FUNC_GET_COMM_EVENT_LOG = 0x0c,
340 FUNC_WRITE_MULTIPLE_COILS = 0x0f,
341 FUNC_WRITE_MULTIPLE_REGISTERS = 0x10,
342 FUNC_REPORT_SLAVE_ID = 0x11,
343 FUNC_READ_FILE_RECORD = 0x14,
344 FUNC_WRITE_FILE_RECORD = 0x15,
345 FUNC_MASK_WRITE_REGISTER = 0x16,
346 FUNC_READ_WRITE_MULTIPLE_REGISTERS = 0x17,
347 FUNC_READ_FIFO_QUEUE = 0x18,
348 FUNC_ENCAPSULATED_INTERFACE_TRANSPORT = 0x2b,
352 ERR_ILLEGAL_FUNCTION = 0x01,
353 ERR_ILLEGAL_DATA_ADDRESS = 0x02,
354 ERR_ILLEGAL_DATA_VALUE = 0x03,
357 static uint read_remains(void)
359 return rx_frame_end - rx_frame;
362 static byte read_byte(void)
367 static u16 read_u16(void)
369 byte hi = *rx_frame++;
370 byte lo = *rx_frame++;
371 return (hi << 8) | lo;
374 static void write_byte(byte v)
376 tx_buf[tx_size++] = v;
379 static void write_u16(u16 v)
385 static bool body_fits(uint body_len)
387 // body_len excludes slave address, function code, and CRC
388 return (2 + body_len + 2 <= MODBUS_TX_BUFSIZE);
391 static void report_error(byte code)
393 // Discard the partially constructed body of the reply and rewrite the header
399 static void func_read_bits(bool coils)
401 if (read_remains() < 4)
402 return report_error(ERR_ILLEGAL_DATA_VALUE);
404 u16 start = read_u16();
405 u16 count = read_u16();
407 uint bytes = (count+7) / 8;
408 if (!body_fits(1 + bytes))
409 return report_error(ERR_ILLEGAL_DATA_VALUE);
411 for (u16 i = 0; i < count; i++)
412 if (!(coils ? modbus_check_coil : modbus_check_discrete_input)(start + i))
413 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
416 for (u16 i = 0; i < bytes; i++) {
418 for (byte j = 0; j < 8 && 8*i + j < count; j++) {
419 uint addr = start + 8*i + j;
420 if ((coils ? modbus_get_coil : modbus_get_discrete_input)(addr))
427 static void func_read_registers(byte holding)
429 if (read_remains() < 4)
430 return report_error(ERR_ILLEGAL_DATA_VALUE);
432 u16 start = read_u16();
433 u16 count = read_u16();
435 uint bytes = 2*count;
436 if (!body_fits(1 + bytes))
437 return report_error(ERR_ILLEGAL_DATA_VALUE);
439 for (u16 i = 0; i < count; i++)
440 if (!(holding ? modbus_check_holding_register : modbus_check_input_register)(start + i))
441 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
443 // FIXME: Reporting of slave failures?
445 for (u16 i = 0; i < count; i++)
446 write_u16((holding ? modbus_get_holding_register : modbus_get_input_register)(start + i));
449 static void func_write_single_coil(void)
451 if (read_remains() < 4)
452 return report_error(ERR_ILLEGAL_DATA_VALUE);
454 u16 addr = read_u16();
455 u16 value = read_u16();
457 if (!modbus_check_coil(addr))
458 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
459 if (value != 0x0000 && value != 0xff00)
460 return report_error(ERR_ILLEGAL_DATA_VALUE);
462 modbus_set_coil(addr, value);
465 static void func_write_single_register(void)
467 if (read_remains() < 4)
468 return report_error(ERR_ILLEGAL_DATA_VALUE);
470 u16 addr = read_u16();
471 u16 value = read_u16();
473 if (!modbus_check_holding_register(addr))
474 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
476 modbus_set_holding_register(addr, value);
479 static void func_write_multiple_coils(void)
481 if (read_remains() < 5)
482 return report_error(ERR_ILLEGAL_DATA_VALUE);
484 u16 start = read_u16();
485 u16 count = read_u16();
486 byte bytes = read_byte();
488 if (read_remains() < bytes || bytes != (count+7) / 8)
489 return report_error(ERR_ILLEGAL_DATA_VALUE);
491 for (u16 i = 0; i < count; i++)
492 if (!modbus_check_coil(start + i))
493 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
495 for (u16 i = 0; i < count; i++)
496 modbus_set_coil(start + i, rx_frame[i/8] & (1U << (i%8)));
499 static void func_write_multiple_registers(void)
501 if (read_remains() < 5)
502 return report_error(ERR_ILLEGAL_DATA_VALUE);
504 u16 start = read_u16();
505 u16 count = read_u16();
506 byte bytes = read_byte();
508 if (read_remains() < bytes || bytes != 2*count)
509 return report_error(ERR_ILLEGAL_DATA_VALUE);
511 for (u16 i = 0; i < count; i++)
512 if (!modbus_check_holding_register(start + i))
513 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
515 for (u16 i = 0; i < count; i++)
516 modbus_set_holding_register(start + i, read_u16());
519 static void func_mask_write_register(void)
521 if (read_remains() < 6)
522 return report_error(ERR_ILLEGAL_DATA_VALUE);
524 u16 addr = read_u16();
525 u16 and_mask = read_u16();
526 u16 or_mask = read_u16();
528 if (!modbus_check_holding_register(addr))
529 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
531 u16 reg = modbus_get_holding_register(addr);
532 reg = (reg & and_mask) | (or_mask & ~and_mask);
533 modbus_set_holding_register(addr, reg);
536 static void func_read_write_multiple_registers(void)
538 if (read_remains() < 9)
539 return report_error(ERR_ILLEGAL_DATA_VALUE);
541 u16 read_start = read_u16();
542 u16 read_count = read_u16();
543 u16 write_start = read_u16();
544 u16 write_count = read_u16();
545 byte write_bytes = read_byte();
547 if (read_remains() < write_bytes || write_bytes != 2*write_count)
548 return report_error(ERR_ILLEGAL_DATA_VALUE);
550 for (u16 i = 0; i < read_count; i++)
551 if (!modbus_check_holding_register(read_start + i))
552 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
554 for (u16 i = 0; i < write_count; i++)
555 if (!modbus_check_holding_register(write_start + i))
556 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
558 byte read_bytes = 2*write_count;
559 if (!body_fits(1 + read_bytes))
560 return report_error(ERR_ILLEGAL_DATA_VALUE);
562 for (u16 i = 0; i < write_count; i++)
563 modbus_set_holding_register(write_start + i, read_u16());
565 write_byte(read_bytes);
566 for (u16 i = 0; i < read_count; i++)
567 modbus_get_holding_register(read_start + i);
570 static void func_encapsulated_interface_transport(void)
572 if (read_remains() < 3 ||
574 return report_error(ERR_ILLEGAL_DATA_VALUE);
576 byte action = read_byte();
577 byte id = read_byte();
579 byte range_min, range_max;
582 // Streaming access to basic identification
583 range_min = MODBUS_ID_VENDOR_NAME;
584 range_max = MODBUS_ID_MAJOR_MINOR_REVISION;
587 // Streaming access to regular identification
588 range_min = MODBUS_ID_VENDOR_URL;
589 range_max = MODBUS_ID_USER_APP_NAME;
593 if (id >= MODBUS_ID_MAX || !modbus_id_strings[id])
594 return report_error(ERR_ILLEGAL_DATA_ADDRESS);
595 range_min = range_max = id;
598 return report_error(ERR_ILLEGAL_DATA_VALUE);
602 if (id < range_min || id > range_max)
606 write_byte(0x0e); // Repeat a part of the request
610 if (modbus_id_strings[MODBUS_ID_VENDOR_URL] ||
611 modbus_id_strings[MODBUS_ID_PRODUCT_NAME] ||
612 modbus_id_strings[MODBUS_ID_USER_APP_NAME])
613 write_byte(0x82); // Regular identification, both stream and individual access supported
615 write_byte(0x81); // Basic identification only
617 u16 more_follows_at = tx_size;
618 write_byte(0); // More follows: so far not
619 write_byte(0); // Next object ID: so far none
620 write_byte(0); // Number of objects
622 for (id = range_min; id <= range_max; id++) {
623 if (modbus_id_strings[id]) {
624 byte len = strlen(modbus_id_strings[id]);
625 byte remains = MODBUS_TX_BUFSIZE - 4 - tx_size; // 2 for CRC, 2 for object header
627 // If it is the only object, cut it
628 if (!tx_buf[more_follows_at + 2])
631 // More follows, report the next ID
632 tx_buf[more_follows_at] = 0xff;
633 tx_buf[more_follows_at + 1] = id;
637 tx_buf[more_follows_at + 2] ++;
640 memcpy(tx_buf + tx_size, modbus_id_strings[id], len);
646 static void process_frame(void)
648 byte func = read_byte();
650 // Prepare reply frame
651 tx_buf[0] = MODBUS_OUR_ADDRESS;
652 tx_buf[1] = rx_buf[1];
656 case FUNC_READ_COILS:
657 func_read_bits(true);
659 case FUNC_READ_DISCRETE_INPUTS:
660 func_read_bits(false);
662 case FUNC_READ_HOLDING_REGISTERS:
663 func_read_registers(true);
665 case FUNC_READ_INPUT_REGISTERS:
666 func_read_registers(false);
668 case FUNC_WRITE_SINGLE_COIL:
669 func_write_single_coil();
671 case FUNC_WRITE_SINGLE_REGISTER:
672 func_write_single_register();
674 case FUNC_WRITE_MULTIPLE_COILS:
675 func_write_multiple_coils();
677 case FUNC_WRITE_MULTIPLE_REGISTERS:
678 func_write_multiple_registers();
680 case FUNC_MASK_WRITE_REGISTER:
681 func_mask_write_register();
683 case FUNC_READ_WRITE_MULTIPLE_REGISTERS:
684 func_read_write_multiple_registers();
686 case FUNC_ENCAPSULATED_INTERFACE_TRANSPORT:
687 func_encapsulated_interface_transport();
690 report_error(ERR_ILLEGAL_FUNCTION);
693 // Finish reply frame
694 write_u16(crc16(tx_buf, tx_size));