Lines Matching +full:rs +full:- +full:485
5 * SPDX-License-Identifier: Apache-2.0
14 * Copyright 2003-2020 Silicon Laboratories Inc. www.silabs.com
16 * SPDX-License-Identifier: APACHE-2.0
20 * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
34 struct modbus_serial_config *cfg = ctx->cfg; in modbus_serial_tx_on()
36 if (cfg->de != NULL) { in modbus_serial_tx_on()
37 gpio_pin_set(cfg->de->port, cfg->de->pin, 1); in modbus_serial_tx_on()
40 uart_irq_tx_enable(cfg->dev); in modbus_serial_tx_on()
45 struct modbus_serial_config *cfg = ctx->cfg; in modbus_serial_tx_off()
47 uart_irq_tx_disable(cfg->dev); in modbus_serial_tx_off()
48 if (cfg->de != NULL) { in modbus_serial_tx_off()
49 gpio_pin_set(cfg->de->port, cfg->de->pin, 0); in modbus_serial_tx_off()
55 struct modbus_serial_config *cfg = ctx->cfg; in modbus_serial_rx_on()
57 if (cfg->re != NULL) { in modbus_serial_rx_on()
58 gpio_pin_set(cfg->re->port, cfg->re->pin, 1); in modbus_serial_rx_on()
61 uart_irq_rx_enable(cfg->dev); in modbus_serial_rx_on()
66 struct modbus_serial_config *cfg = ctx->cfg; in modbus_serial_rx_off()
68 uart_irq_rx_disable(cfg->dev); in modbus_serial_rx_off()
69 if (cfg->re != NULL) { in modbus_serial_rx_off()
70 gpio_pin_set(cfg->re->port, cfg->re->pin, 0); in modbus_serial_rx_off()
75 /* The function calculates an 8-bit Longitudinal Redundancy Check. */
82 while (length-- > 0) { in modbus_ascii_get_lrc()
101 struct modbus_serial_config *cfg = ctx->cfg; in modbus_ascii_rx_adu()
108 rx_size = cfg->uart_buf_ctr; in modbus_ascii_rx_adu()
109 prx_data = &ctx->rx_adu.data[0]; in modbus_ascii_rx_adu()
113 return -EMSGSIZE; in modbus_ascii_rx_adu()
118 return -EMSGSIZE; in modbus_ascii_rx_adu()
121 if ((cfg->uart_buf[0] != MODBUS_ASCII_START_FRAME_CHAR) || in modbus_ascii_rx_adu()
122 (cfg->uart_buf[rx_size - 2] != MODBUS_ASCII_END_FRAME_CHAR1) || in modbus_ascii_rx_adu()
123 (cfg->uart_buf[rx_size - 1] != MODBUS_ASCII_END_FRAME_CHAR2)) { in modbus_ascii_rx_adu()
125 return -EMSGSIZE; in modbus_ascii_rx_adu()
129 rx_size -= 3; in modbus_ascii_rx_adu()
131 pmsg = &cfg->uart_buf[1]; in modbus_ascii_rx_adu()
133 hex2bin(pmsg, 2, &ctx->rx_adu.unit_id, 1); in modbus_ascii_rx_adu()
135 rx_size -= 2; in modbus_ascii_rx_adu()
136 hex2bin(pmsg, 2, &ctx->rx_adu.fc, 1); in modbus_ascii_rx_adu()
138 rx_size -= 2; in modbus_ascii_rx_adu()
141 ctx->rx_adu.length = 0; in modbus_ascii_rx_adu()
146 rx_size -= 2; in modbus_ascii_rx_adu()
148 ctx->rx_adu.length++; in modbus_ascii_rx_adu()
153 ctx->rx_adu.crc = frame_lrc; in modbus_ascii_rx_adu()
161 calc_lrc = modbus_ascii_get_lrc(&cfg->uart_buf[1], in modbus_ascii_rx_adu()
162 (cfg->uart_buf_ctr - 5) / 2); in modbus_ascii_rx_adu()
166 return -EIO; in modbus_ascii_rx_adu()
187 struct modbus_serial_config *cfg = ctx->cfg; in modbus_ascii_tx_adu()
192 /* Place the start-of-frame character into output buffer */ in modbus_ascii_tx_adu()
193 cfg->uart_buf[0] = MODBUS_ASCII_START_FRAME_CHAR; in modbus_ascii_tx_adu()
196 pbuf = &cfg->uart_buf[1]; in modbus_ascii_tx_adu()
197 pbuf = modbus_ascii_bin2hex(ctx->tx_adu.unit_id, pbuf); in modbus_ascii_tx_adu()
199 pbuf = modbus_ascii_bin2hex(ctx->tx_adu.fc, pbuf); in modbus_ascii_tx_adu()
202 for (int i = 0; i < ctx->tx_adu.length; i++) { in modbus_ascii_tx_adu()
203 pbuf = modbus_ascii_bin2hex(ctx->tx_adu.data[i], pbuf); in modbus_ascii_tx_adu()
215 lrc = modbus_ascii_get_lrc(&cfg->uart_buf[1], (tx_bytes - 1) / 2); in modbus_ascii_tx_adu()
224 cfg->uart_buf_ctr = tx_bytes; in modbus_ascii_tx_adu()
225 cfg->uart_buf_ptr = &cfg->uart_buf[0]; in modbus_ascii_tx_adu()
245 struct modbus_serial_config *cfg = ctx->cfg; in modbus_rtu_rx_adu()
251 if ((cfg->uart_buf_ctr < MODBUS_RTU_MIN_MSG_SIZE) || in modbus_rtu_rx_adu()
252 (cfg->uart_buf_ctr > CONFIG_MODBUS_BUFFER_SIZE)) { in modbus_rtu_rx_adu()
254 return -EMSGSIZE; in modbus_rtu_rx_adu()
257 ctx->rx_adu.unit_id = cfg->uart_buf[0]; in modbus_rtu_rx_adu()
258 ctx->rx_adu.fc = cfg->uart_buf[1]; in modbus_rtu_rx_adu()
259 data_ptr = &cfg->uart_buf[2]; in modbus_rtu_rx_adu()
261 ctx->rx_adu.length = cfg->uart_buf_ctr - 4; in modbus_rtu_rx_adu()
263 crc_idx = cfg->uart_buf_ctr - sizeof(uint16_t); in modbus_rtu_rx_adu()
265 memcpy(ctx->rx_adu.data, data_ptr, ctx->rx_adu.length); in modbus_rtu_rx_adu()
267 ctx->rx_adu.crc = sys_get_le16(&cfg->uart_buf[crc_idx]); in modbus_rtu_rx_adu()
269 calc_crc = crc16_ansi(&cfg->uart_buf[0], in modbus_rtu_rx_adu()
270 cfg->uart_buf_ctr - sizeof(ctx->rx_adu.crc)); in modbus_rtu_rx_adu()
272 if (ctx->rx_adu.crc != calc_crc) { in modbus_rtu_rx_adu()
274 return -EIO; in modbus_rtu_rx_adu()
282 struct modbus_serial_config *cfg = ctx->cfg; in rtu_tx_adu()
286 cfg->uart_buf[0] = ctx->tx_adu.unit_id; in rtu_tx_adu()
287 cfg->uart_buf[1] = ctx->tx_adu.fc; in rtu_tx_adu()
288 tx_bytes = 2 + ctx->tx_adu.length; in rtu_tx_adu()
289 data_ptr = &cfg->uart_buf[2]; in rtu_tx_adu()
291 memcpy(data_ptr, ctx->tx_adu.data, ctx->tx_adu.length); in rtu_tx_adu()
293 ctx->tx_adu.crc = crc16_ansi(&cfg->uart_buf[0], ctx->tx_adu.length + 2); in rtu_tx_adu()
294 sys_put_le16(ctx->tx_adu.crc, in rtu_tx_adu()
295 &cfg->uart_buf[ctx->tx_adu.length + 2]); in rtu_tx_adu()
298 cfg->uart_buf_ctr = tx_bytes; in rtu_tx_adu()
299 cfg->uart_buf_ptr = &cfg->uart_buf[0]; in rtu_tx_adu()
301 LOG_HEXDUMP_DBG(cfg->uart_buf, cfg->uart_buf_ctr, "uart_buf"); in rtu_tx_adu()
313 struct modbus_serial_config *cfg = ctx->cfg; in cb_handler_rx()
315 if ((ctx->mode == MODBUS_MODE_ASCII) && in cb_handler_rx()
319 if (uart_fifo_read(cfg->dev, &c, 1) != 1) { in cb_handler_rx()
326 cfg->uart_buf_ptr = &cfg->uart_buf[0]; in cb_handler_rx()
327 cfg->uart_buf_ctr = 0; in cb_handler_rx()
330 if (cfg->uart_buf_ctr < CONFIG_MODBUS_BUFFER_SIZE) { in cb_handler_rx()
331 *cfg->uart_buf_ptr++ = c; in cb_handler_rx()
332 cfg->uart_buf_ctr++; in cb_handler_rx()
336 k_work_submit(&ctx->server_work); in cb_handler_rx()
342 if (cfg->uart_buf_ctr == CONFIG_MODBUS_BUFFER_SIZE) { in cb_handler_rx()
349 k_timer_start(&cfg->rtu_timer, in cb_handler_rx()
350 K_USEC(cfg->rtu_timeout), K_NO_WAIT); in cb_handler_rx()
352 n = uart_fifo_read(cfg->dev, cfg->uart_buf_ptr, in cb_handler_rx()
353 (CONFIG_MODBUS_BUFFER_SIZE - in cb_handler_rx()
354 cfg->uart_buf_ctr)); in cb_handler_rx()
356 cfg->uart_buf_ptr += n; in cb_handler_rx()
357 cfg->uart_buf_ctr += n; in cb_handler_rx()
363 struct modbus_serial_config *cfg = ctx->cfg; in cb_handler_tx()
366 if (cfg->uart_buf_ctr > 0) { in cb_handler_tx()
367 n = uart_fifo_fill(cfg->dev, cfg->uart_buf_ptr, in cb_handler_tx()
368 cfg->uart_buf_ctr); in cb_handler_tx()
369 cfg->uart_buf_ctr -= n; in cb_handler_tx()
370 cfg->uart_buf_ptr += n; in cb_handler_tx()
375 * RS-485 transceiver could be disabled before all data has in cb_handler_tx()
378 if (uart_irq_tx_complete(cfg->dev)) { in cb_handler_tx()
380 cfg->uart_buf_ptr = &cfg->uart_buf[0]; in cb_handler_tx()
419 k_work_submit(&ctx->server_work); in rtu_tmr_handler()
424 struct modbus_serial_config *cfg = ctx->cfg; in configure_gpio()
426 if (cfg->de != NULL) { in configure_gpio()
427 if (!device_is_ready(cfg->de->port)) { in configure_gpio()
428 return -ENODEV; in configure_gpio()
431 if (gpio_pin_configure_dt(cfg->de, GPIO_OUTPUT_INACTIVE)) { in configure_gpio()
432 return -EIO; in configure_gpio()
437 if (cfg->re != NULL) { in configure_gpio()
438 if (!device_is_ready(cfg->re->port)) { in configure_gpio()
439 return -ENODEV; in configure_gpio()
442 if (gpio_pin_configure_dt(cfg->re, GPIO_OUTPUT_INACTIVE)) { in configure_gpio()
443 return -EIO; in configure_gpio()
453 struct modbus_serial_config *cfg = ctx->cfg; in configure_uart()
455 .baudrate = param->serial.baud, in configure_uart()
459 if (ctx->mode == MODBUS_MODE_ASCII) { in configure_uart()
465 switch (param->serial.parity) { in configure_uart()
468 uart_cfg.parity = param->serial.parity; in configure_uart()
473 uart_cfg.parity = param->serial.parity; in configure_uart()
477 return -EINVAL; in configure_uart()
480 if (ctx->client) { in configure_uart()
482 switch (param->serial.stop_bits_client) { in configure_uart()
487 uart_cfg.stop_bits = param->serial.stop_bits_client; in configure_uart()
490 return -EINVAL; in configure_uart()
494 if (uart_configure(cfg->dev, &uart_cfg) != 0) { in configure_uart()
496 return -EINVAL; in configure_uart()
514 struct modbus_serial_config *cfg = ctx->cfg; in modbus_serial_rx_adu()
517 switch (ctx->mode) { in modbus_serial_rx_adu()
523 return -ENOTSUP; in modbus_serial_rx_adu()
530 return -ENOTSUP; in modbus_serial_rx_adu()
533 cfg->uart_buf_ctr = 0; in modbus_serial_rx_adu()
534 cfg->uart_buf_ptr = &cfg->uart_buf[0]; in modbus_serial_rx_adu()
541 switch (ctx->mode) { in modbus_serial_tx_adu()
554 return -ENOTSUP; in modbus_serial_tx_adu()
560 struct modbus_serial_config *cfg = ctx->cfg; in modbus_serial_init()
567 ctx->mode = param.mode; in modbus_serial_init()
570 return -ENOTSUP; in modbus_serial_init()
573 if (!device_is_ready(cfg->dev)) { in modbus_serial_init()
574 LOG_ERR("Bus device %s is not ready", cfg->dev->name); in modbus_serial_init()
575 return -ENODEV; in modbus_serial_init()
580 return -EINVAL; in modbus_serial_init()
585 cfg->rtu_timeout = (numof_bits * if_delay_max) / in modbus_serial_init()
588 cfg->rtu_timeout = (numof_bits * if_delay_max) / 38400; in modbus_serial_init()
592 return -EIO; in modbus_serial_init()
595 cfg->uart_buf_ctr = 0; in modbus_serial_init()
596 cfg->uart_buf_ptr = &cfg->uart_buf[0]; in modbus_serial_init()
598 uart_irq_callback_user_data_set(cfg->dev, uart_cb_handler, ctx); in modbus_serial_init()
599 k_timer_init(&cfg->rtu_timer, rtu_tmr_handler, NULL); in modbus_serial_init()
600 k_timer_user_data_set(&cfg->rtu_timer, ctx); in modbus_serial_init()
603 LOG_INF("RTU timeout %u us", cfg->rtu_timeout); in modbus_serial_init()
612 k_timer_stop(&ctx->cfg->rtu_timer); in modbus_serial_disable()