Hi!
I've added stty RS485 config options for serial devices/drivers which
are supporting the ioctl based configurations documented in:
https://www.kernel.org/doc/Documentation/serial/serial-rs485.txt
I've tested the patches in my workstation (Linux Debian squeeze
2.6.32-5-686 kernel), and with my Freescale iMX286 based embedded board too.
I'll be happy if this patches can be the official part of the BusyBox
packages. (This work is a part of my project: adding RS485 support for
Freescale mxs-auart serial driver)
Thanks.
Best Regards,
Janos Angeli
BusyBox stty: Add RS485 config options
The patch adds RS485 config options for serial devices/drivers
which are supporting the ioctl based configurations documented in:
https://www.kernel.org/doc/Documentation/serial/serial-rs485.txt
New config parameters:
rs485 - Switch on/off the RS485 mode
rs485rtsonsend - Set logical level for RTS pin when sending
rs485rtsaftersend - Set logical level for RTS pin after sent
rs485rxduringtx - Switch on/off Rx enable during packet transmit
rs485delaybefore 0 - Set delay between RTS signaling and the
transmission of the first bit
rs485delayafter 0 - Set delay between the transmission of the last
bit and the RTS state change
New read only parameter:
rs485delaylastchartx 0 - Shows the automatically calculated delay
between the serial port Tx FIFO empty
state and the last bit transmission
Currently the following serial drivers supports the RS485 options:
- crisv10.c ETRAX 100LX
- atmel_serial.c Atmel AT91 / AT32
- mxs-auart.c Freescale STMP37XX/STMP378X iMX28
Signed-off-by: Janos Angeli <[email protected]>
---
Index: busybox-1.19.4/coreutils/stty.c
===================================================================
--- busybox-1.19.4.orig/coreutils/stty.c
+++ busybox-1.19.4/coreutils/stty.c
@@ -19,6 +19,8 @@
Special for busybox ported by Vladimir Oleynik <[email protected]> 2001
+ RS485 options added by Janos Angeli <[email protected]> 2013
+
*/
//usage:#define stty_trivial_usage
@@ -32,6 +34,27 @@
//usage: "\n [SETTING] See manpage"
#include "libbb.h"
+#include <asm-generic/ioctls.h>
+#include <linux/ioctl.h>
+
+//#include <linux/serial.h>
+//We don't include <linux/serial.h> now, because it is missing some RS485 definitions.
+//We need only the serial_rs485 struct from it and the __u32 def from <linux/types.h>
+//In later versions we will be able to switch back to the original include.
+#include <linux/types.h>
+struct serial_rs485 {
+ __u32 flags; /* RS485 feature flags */
+#define SER_RS485_ENABLED (1 << 0) /* If enabled */
+#define SER_RS485_RTS_ON_SEND (1 << 1) /* Logical level for RTS pin when sending */
+#define SER_RS485_RTS_AFTER_SEND (1 << 2) /* Logical level for RTS pin after sent */
+#define SER_RS485_RX_DURING_TX (1 << 4)
+ __u32 delay_rts_before_send; /* Delay before send */
+ __u32 delay_rts_after_send; /* Delay after send */
+ __u32 delay_rts_last_char_tx; /* Delay for last char Tx from FIFO (microseconds)
+ This delay is automatically calculated from baudrate */
+ __u32 padding[4]; /* Memory is cheap, new structs are a royal PITA .. */
+};
+//End of temporally include <linux/serial.h>
#ifndef _POSIX_VDISABLE
# define _POSIX_VDISABLE ((unsigned char) 0)
@@ -966,11 +989,27 @@ static int find_param(const char *name)
return i;
}
-static int recover_mode(const char *arg, struct termios *mode)
+static int find_rs485config(const char *name)
+{
+ static const char params[] ALIGN1 =
+ "rs485\0" /* 1 */
+ "rs485rtsonsend\0" /* 2 */
+ "rs485rtsaftersend\0" /* 3 */
+ "rs485rxduringtx\0" /* 4 */
+ "rs485delaybefore\0" /* 5 */
+ "rs485delayafter\0"; /* 6 */
+ int i = index_in_strings(params, name) + 1;
+ if ((i == 5) || (i == 6))
+ i |= 0x80;
+ return i;
+}
+
+static int recover_mode(const char *arg, struct termios *mode, struct serial_rs485 *rs485conf, int paramcheck, int rs485)
{
int i, n;
unsigned chr;
unsigned long iflag, oflag, cflag, lflag;
+ unsigned long rsflags, rsdelaybefore, rsdelayafter;
/* Scan into temporaries since it is too much trouble to figure out
the right format for 'tcflag_t' */
@@ -989,15 +1028,28 @@ static int recover_mode(const char *arg,
arg += n;
}
+ if (rs485 >= 0) {
+ if (sscanf(arg, ":%lx:%lx:%lx%n", &rsflags, &rsdelaybefore, &rsdelayafter, &n) != 3)
+ return 0;
+ rs485conf->flags = rsflags;
+ rs485conf->delay_rts_before_send = rsdelaybefore;
+ rs485conf->delay_rts_after_send = rsdelayafter;
+ arg += n;
+ }
+
/* Fail if there are too many fields */
- if (*arg != '\0')
+ if (*arg != '\0') {
+ /* In the first pass of params verify we don't know the port device
+ have RS485 support or not, so give a try for the extra RS485 params */
+ if ((paramcheck) && (sscanf(arg, ":%lx:%lx:%lx%n", &rsflags, &rsdelaybefore, &rsdelayafter, &n) == 3))
+ return 1;
return 0;
-
+ }
return 1;
}
-static void display_recoverable(const struct termios *mode,
- int UNUSED_PARAM dummy)
+static void display_recoverable(const struct termios *mode, const struct serial_rs485 *rs485conf,
+ int UNUSED_PARAM dummy, int rs485)
{
int i;
printf("%lx:%lx:%lx:%lx",
@@ -1005,6 +1057,12 @@ static void display_recoverable(const st
(unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag);
for (i = 0; i < NCCS; ++i)
printf(":%x", (unsigned int) mode->c_cc[i]);
+ if (rs485 >= 0) {
+ printf(":%lx:%lx:%lx",
+ (unsigned long) rs485conf->flags,
+ (unsigned long) rs485conf->delay_rts_before_send,
+ (unsigned long) rs485conf->delay_rts_after_send);
+ }
bb_putchar('\n');
}
@@ -1025,7 +1083,7 @@ static void display_speed(const struct t
wrapf(fmt_str, tty_baud_to_value(ispeed), tty_baud_to_value(ospeed));
}
-static void do_display(const struct termios *mode, int all)
+static void do_display(const struct termios *mode, const struct serial_rs485 *rs485conf, int all, int rs485)
{
int i;
tcflag_t *bitsp;
@@ -1086,6 +1144,25 @@ static void do_display(const struct term
}
}
newline();
+
+ if (rs485 < 0) {
+ if (all) {
+ wrapf("RS485 not supported");
+ newline();
+ }
+ } else {
+ wrapf("%srs485 %srs485rtsonsend %srs485rtsaftersend %srs485rxduringtx",
+ (rs485conf->flags & SER_RS485_ENABLED) ? "" : "-",
+ (rs485conf->flags & SER_RS485_RTS_ON_SEND) ? "" : "-",
+ (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) ? "" : "-",
+ (rs485conf->flags & SER_RS485_RX_DURING_TX) ? "" : "-");
+ newline();
+ wrapf("rs485delaybefore = %d; rs485delayafter = %d; rs485delaylastchartx = %d;\n",
+ rs485conf->delay_rts_before_send,
+ rs485conf->delay_rts_after_send,
+ rs485conf->delay_rts_last_char_tx);
+ newline();
+ }
}
static void sane_mode(struct termios *mode)
@@ -1277,11 +1354,14 @@ int stty_main(int argc, char **argv) MAI
int stty_main(int argc UNUSED_PARAM, char **argv)
{
struct termios mode;
- void (*output_func)(const struct termios *, int);
+ struct serial_rs485 rs485conf;
+ void (*output_func)(const struct termios *, const struct serial_rs485 *, int, int);
const char *file_name = NULL;
int display_all = 0;
int stty_state;
int k;
+ int rs485_supported;
+ int rs485_setconfig;
INIT_G();
@@ -1306,6 +1386,11 @@ int stty_main(int argc UNUSED_PARAM, cha
stty_state &= ~STTY_noargs;
continue;
}
+ param = find_rs485config(arg+1);
+ if ((param) && ((param & param_need_arg) == 0)) {
+ stty_state &= ~STTY_noargs;
+ continue;
+ }
/* It is an option - parse it */
i = 0;
while (arg[++i]) {
@@ -1360,6 +1445,17 @@ int stty_main(int argc UNUSED_PARAM, cha
continue;
}
+ param = find_rs485config(arg);
+ if (param & param_need_arg) {
+ if (!argnext)
+ bb_error_msg_and_die(bb_msg_requires_arg, arg);
+ ++k;
+ }
+ if (param) {
+ stty_state &= ~STTY_noargs;
+ continue;
+ }
+
param = find_param(arg);
if (param & param_need_arg) {
if (!argnext)
@@ -1394,7 +1490,7 @@ int stty_main(int argc UNUSED_PARAM, cha
set_speed_or_die(output_speed, argnext, &mode);
break;
default:
- if (recover_mode(arg, &mode) == 1) break;
+ if (recover_mode(arg, &mode, &rs485conf, 1, -1) == 1) break;
if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) break;
invalid_argument:
bb_error_msg_and_die("invalid argument '%s'", arg);
@@ -1425,15 +1521,17 @@ int stty_main(int argc UNUSED_PARAM, cha
memset(&mode, 0, sizeof(mode));
if (tcgetattr(STDIN_FILENO, &mode))
perror_on_device_and_die("%s");
+ rs485_supported = ioctl(STDIN_FILENO, TIOCGRS485, &rs485conf);
if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) {
get_terminal_width_height(STDOUT_FILENO, &G.max_col, NULL);
- output_func(&mode, display_all);
+ output_func(&mode, &rs485conf, display_all, rs485_supported);
return EXIT_SUCCESS;
}
/* Second pass: perform actions */
k = 0;
+ rs485_setconfig = 0;
while (argv[++k]) {
const struct mode_info *mp;
const struct control_info *cp;
@@ -1447,6 +1545,23 @@ int stty_main(int argc UNUSED_PARAM, cha
set_mode(mp, 1 /* reversed */, &mode);
stty_state |= STTY_require_set_attr;
}
+ param = find_rs485config(arg+1);
+ if ((param) && ((param & param_need_arg) == 0)) {
+ rs485_setconfig = 1;
+ switch (param) {
+ case 1:
+ rs485conf.flags &= ~SER_RS485_ENABLED;
+ break;
+ case 2:
+ rs485conf.flags &= ~SER_RS485_RTS_ON_SEND;
+ break;
+ case 3:
+ rs485conf.flags &= ~SER_RS485_RTS_AFTER_SEND;
+ break;
+ case 4:
+ rs485conf.flags &= ~SER_RS485_RX_DURING_TX;
+ }
+ }
/* It is an option - already parsed. Skip it */
continue;
}
@@ -1466,6 +1581,33 @@ int stty_main(int argc UNUSED_PARAM, cha
continue;
}
+ param = find_rs485config(arg);
+ if (param) {
+ rs485_setconfig = 1;
+ if (param & param_need_arg)
+ ++k;
+ switch (param & 0x7F) {
+ case 1:
+ rs485conf.flags |= SER_RS485_ENABLED;
+ break;
+ case 2:
+ rs485conf.flags |= SER_RS485_RTS_ON_SEND;
+ break;
+ case 3:
+ rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
+ break;
+ case 4:
+ rs485conf.flags |= SER_RS485_RX_DURING_TX;
+ break;
+ case 5:
+ rs485conf.delay_rts_before_send = xatoul_sfx(argnext, stty_suffixes);
+ break;
+ case 6:
+ rs485conf.delay_rts_after_send = xatoul_sfx(argnext, stty_suffixes);
+ }
+ continue;
+ }
+
param = find_param(arg);
if (param & param_need_arg) {
++k;
@@ -1502,9 +1644,11 @@ int stty_main(int argc UNUSED_PARAM, cha
stty_state |= (STTY_require_set_attr | STTY_speed_was_set);
break;
default:
- if (recover_mode(arg, &mode) == 1)
+ if (recover_mode(arg, &mode, &rs485conf, 0, rs485_supported) == 1) {
stty_state |= STTY_require_set_attr;
- else /* true: if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) */{
+ if (rs485_supported >= 0)
+ rs485_setconfig = 1;
+ } else /* true: if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) */{
set_speed_or_die(both_speeds, arg, &mode);
stty_state |= (STTY_require_set_attr | STTY_speed_was_set);
} /* else - impossible (caught in the first pass):
@@ -1550,5 +1694,10 @@ int stty_main(int argc UNUSED_PARAM, cha
}
}
+ if (rs485_setconfig) {
+ if (ioctl (STDIN_FILENO, TIOCSRS485, &rs485conf) < 0)
+ perror_on_device_and_die("%s: cannot set RS485 options");
+ }
+
return EXIT_SUCCESS;
}
BusyBox stty: Add RS485 config options
The patch adds RS485 config options for serial devices/drivers
which are supporting the ioctl based configurations documented in:
https://www.kernel.org/doc/Documentation/serial/serial-rs485.txt
New config parameters:
rs485 - Switch on/off the RS485 mode
rs485rtsonsend - Set logical level for RTS pin when sending
rs485rtsaftersend - Set logical level for RTS pin after sent
rs485rxduringtx - Switch on/off Rx enable during packet transmit
rs485delaybefore 0 - Set delay between RTS signaling and the
transmission of the first bit
rs485delayafter 0 - Set delay between the transmission of the last
bit and the RTS state change
New read only parameter:
rs485delaylastchartx 0 - Shows the automatically calculated delay
between the serial port Tx FIFO empty
state and the last bit transmission
Currently the following serial drivers supports the RS485 options:
- crisv10.c ETRAX 100LX
- atmel_serial.c Atmel AT91 / AT32
- mxs-auart.c Freescale STMP37XX/STMP378X iMX28
Signed-off-by: Janos Angeli <[email protected]>
---
Index: busybox-1.21.0/coreutils/stty.c
===================================================================
--- busybox-1.21.0.orig/coreutils/stty.c
+++ busybox-1.21.0/coreutils/stty.c
@@ -19,6 +19,8 @@
Special for busybox ported by Vladimir Oleynik <[email protected]> 2001
+ RS485 options added by Janos Angeli <[email protected]> 2013
+
*/
//usage:#define stty_trivial_usage
@@ -32,6 +34,27 @@
//usage: "\n [SETTING] See manpage"
#include "libbb.h"
+#include <asm-generic/ioctls.h>
+#include <linux/ioctl.h>
+
+//#include <linux/serial.h>
+//We don't include <linux/serial.h> now, because it is missing some RS485 definitions.
+//We need only the serial_rs485 struct from it and the __u32 def from <linux/types.h>
+//In later versions we will be able to switch back to the original include.
+#include <linux/types.h>
+struct serial_rs485 {
+ __u32 flags; /* RS485 feature flags */
+#define SER_RS485_ENABLED (1 << 0) /* If enabled */
+#define SER_RS485_RTS_ON_SEND (1 << 1) /* Logical level for RTS pin when sending */
+#define SER_RS485_RTS_AFTER_SEND (1 << 2) /* Logical level for RTS pin after sent */
+#define SER_RS485_RX_DURING_TX (1 << 4)
+ __u32 delay_rts_before_send; /* Delay before send */
+ __u32 delay_rts_after_send; /* Delay after send */
+ __u32 delay_rts_last_char_tx; /* Delay for last char Tx from FIFO (microseconds)
+ This delay is automatically calculated from baudrate */
+ __u32 padding[4]; /* Memory is cheap, new structs are a royal PITA .. */
+};
+//End of temporally include <linux/serial.h>
#ifndef _POSIX_VDISABLE
# define _POSIX_VDISABLE ((unsigned char) 0)
@@ -966,11 +989,27 @@ static int find_param(const char *name)
return i;
}
-static int recover_mode(const char *arg, struct termios *mode)
+static int find_rs485config(const char *name)
+{
+ static const char params[] ALIGN1 =
+ "rs485\0" /* 1 */
+ "rs485rtsonsend\0" /* 2 */
+ "rs485rtsaftersend\0" /* 3 */
+ "rs485rxduringtx\0" /* 4 */
+ "rs485delaybefore\0" /* 5 */
+ "rs485delayafter\0"; /* 6 */
+ int i = index_in_strings(params, name) + 1;
+ if ((i == 5) || (i == 6))
+ i |= 0x80;
+ return i;
+}
+
+static int recover_mode(const char *arg, struct termios *mode, struct serial_rs485 *rs485conf, int paramcheck, int rs485)
{
int i, n;
unsigned chr;
unsigned long iflag, oflag, cflag, lflag;
+ unsigned long rsflags, rsdelaybefore, rsdelayafter;
/* Scan into temporaries since it is too much trouble to figure out
the right format for 'tcflag_t' */
@@ -989,15 +1028,28 @@ static int recover_mode(const char *arg,
arg += n;
}
+ if (rs485 >= 0) {
+ if (sscanf(arg, ":%lx:%lx:%lx%n", &rsflags, &rsdelaybefore, &rsdelayafter, &n) != 3)
+ return 0;
+ rs485conf->flags = rsflags;
+ rs485conf->delay_rts_before_send = rsdelaybefore;
+ rs485conf->delay_rts_after_send = rsdelayafter;
+ arg += n;
+ }
+
/* Fail if there are too many fields */
- if (*arg != '\0')
+ if (*arg != '\0') {
+ /* In the first pass of params verify we don't know the port device
+ have RS485 support or not, so give a try for the extra RS485 params */
+ if ((paramcheck) && (sscanf(arg, ":%lx:%lx:%lx%n", &rsflags, &rsdelaybefore, &rsdelayafter, &n) == 3))
+ return 1;
return 0;
-
+ }
return 1;
}
-static void display_recoverable(const struct termios *mode,
- int UNUSED_PARAM dummy)
+static void display_recoverable(const struct termios *mode, const struct serial_rs485 *rs485conf,
+ int UNUSED_PARAM dummy, int rs485)
{
int i;
printf("%lx:%lx:%lx:%lx",
@@ -1005,6 +1057,12 @@ static void display_recoverable(const st
(unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag);
for (i = 0; i < NCCS; ++i)
printf(":%x", (unsigned int) mode->c_cc[i]);
+ if (rs485 >= 0) {
+ printf(":%lx:%lx:%lx",
+ (unsigned long) rs485conf->flags,
+ (unsigned long) rs485conf->delay_rts_before_send,
+ (unsigned long) rs485conf->delay_rts_after_send);
+ }
bb_putchar('\n');
}
@@ -1025,7 +1083,7 @@ static void display_speed(const struct t
wrapf(fmt_str, tty_baud_to_value(ispeed), tty_baud_to_value(ospeed));
}
-static void do_display(const struct termios *mode, int all)
+static void do_display(const struct termios *mode, const struct serial_rs485 *rs485conf, int all, int rs485)
{
int i;
tcflag_t *bitsp;
@@ -1086,6 +1144,25 @@ static void do_display(const struct term
}
}
newline();
+
+ if (rs485 < 0) {
+ if (all) {
+ wrapf("RS485 not supported");
+ newline();
+ }
+ } else {
+ wrapf("%srs485 %srs485rtsonsend %srs485rtsaftersend %srs485rxduringtx",
+ (rs485conf->flags & SER_RS485_ENABLED) ? "" : "-",
+ (rs485conf->flags & SER_RS485_RTS_ON_SEND) ? "" : "-",
+ (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) ? "" : "-",
+ (rs485conf->flags & SER_RS485_RX_DURING_TX) ? "" : "-");
+ newline();
+ wrapf("rs485delaybefore = %d; rs485delayafter = %d; rs485delaylastchartx = %d;\n",
+ rs485conf->delay_rts_before_send,
+ rs485conf->delay_rts_after_send,
+ rs485conf->delay_rts_last_char_tx);
+ newline();
+ }
}
static void sane_mode(struct termios *mode)
@@ -1277,11 +1354,14 @@ int stty_main(int argc, char **argv) MAI
int stty_main(int argc UNUSED_PARAM, char **argv)
{
struct termios mode;
- void (*output_func)(const struct termios *, int);
+ struct serial_rs485 rs485conf;
+ void (*output_func)(const struct termios *, const struct serial_rs485 *, int, int);
const char *file_name = NULL;
int display_all = 0;
int stty_state;
int k;
+ int rs485_supported;
+ int rs485_setconfig;
INIT_G();
@@ -1306,6 +1386,11 @@ int stty_main(int argc UNUSED_PARAM, cha
stty_state &= ~STTY_noargs;
continue;
}
+ param = find_rs485config(arg+1);
+ if ((param) && ((param & param_need_arg) == 0)) {
+ stty_state &= ~STTY_noargs;
+ continue;
+ }
/* It is an option - parse it */
i = 0;
while (arg[++i]) {
@@ -1360,6 +1445,17 @@ int stty_main(int argc UNUSED_PARAM, cha
continue;
}
+ param = find_rs485config(arg);
+ if (param & param_need_arg) {
+ if (!argnext)
+ bb_error_msg_and_die(bb_msg_requires_arg, arg);
+ ++k;
+ }
+ if (param) {
+ stty_state &= ~STTY_noargs;
+ continue;
+ }
+
param = find_param(arg);
if (param & param_need_arg) {
if (!argnext)
@@ -1394,7 +1490,7 @@ int stty_main(int argc UNUSED_PARAM, cha
set_speed_or_die(output_speed, argnext, &mode);
break;
default:
- if (recover_mode(arg, &mode) == 1) break;
+ if (recover_mode(arg, &mode, &rs485conf, 1, -1) == 1) break;
if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) break;
invalid_argument:
bb_error_msg_and_die("invalid argument '%s'", arg);
@@ -1427,15 +1523,17 @@ int stty_main(int argc UNUSED_PARAM, cha
memset(&mode, 0, sizeof(mode));
if (tcgetattr(STDIN_FILENO, &mode))
perror_on_device_and_die("%s");
+ rs485_supported = ioctl(STDIN_FILENO, TIOCGRS485, &rs485conf);
if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) {
get_terminal_width_height(STDOUT_FILENO, &G.max_col, NULL);
- output_func(&mode, display_all);
+ output_func(&mode, &rs485conf, display_all, rs485_supported);
return EXIT_SUCCESS;
}
/* Second pass: perform actions */
k = 0;
+ rs485_setconfig = 0;
while (argv[++k]) {
const struct mode_info *mp;
const struct control_info *cp;
@@ -1449,6 +1547,23 @@ int stty_main(int argc UNUSED_PARAM, cha
set_mode(mp, 1 /* reversed */, &mode);
stty_state |= STTY_require_set_attr;
}
+ param = find_rs485config(arg+1);
+ if ((param) && ((param & param_need_arg) == 0)) {
+ rs485_setconfig = 1;
+ switch (param) {
+ case 1:
+ rs485conf.flags &= ~SER_RS485_ENABLED;
+ break;
+ case 2:
+ rs485conf.flags &= ~SER_RS485_RTS_ON_SEND;
+ break;
+ case 3:
+ rs485conf.flags &= ~SER_RS485_RTS_AFTER_SEND;
+ break;
+ case 4:
+ rs485conf.flags &= ~SER_RS485_RX_DURING_TX;
+ }
+ }
/* It is an option - already parsed. Skip it */
continue;
}
@@ -1468,6 +1583,33 @@ int stty_main(int argc UNUSED_PARAM, cha
continue;
}
+ param = find_rs485config(arg);
+ if (param) {
+ rs485_setconfig = 1;
+ if (param & param_need_arg)
+ ++k;
+ switch (param & 0x7F) {
+ case 1:
+ rs485conf.flags |= SER_RS485_ENABLED;
+ break;
+ case 2:
+ rs485conf.flags |= SER_RS485_RTS_ON_SEND;
+ break;
+ case 3:
+ rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
+ break;
+ case 4:
+ rs485conf.flags |= SER_RS485_RX_DURING_TX;
+ break;
+ case 5:
+ rs485conf.delay_rts_before_send = xatoul_sfx(argnext, stty_suffixes);
+ break;
+ case 6:
+ rs485conf.delay_rts_after_send = xatoul_sfx(argnext, stty_suffixes);
+ }
+ continue;
+ }
+
param = find_param(arg);
if (param & param_need_arg) {
++k;
@@ -1504,9 +1646,11 @@ int stty_main(int argc UNUSED_PARAM, cha
stty_state |= (STTY_require_set_attr | STTY_speed_was_set);
break;
default:
- if (recover_mode(arg, &mode) == 1)
+ if (recover_mode(arg, &mode, &rs485conf, 0, rs485_supported) == 1) {
stty_state |= STTY_require_set_attr;
- else /* true: if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) */{
+ if (rs485_supported >= 0)
+ rs485_setconfig = 1;
+ } else /* true: if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) */{
set_speed_or_die(both_speeds, arg, &mode);
stty_state |= (STTY_require_set_attr | STTY_speed_was_set);
} /* else - impossible (caught in the first pass):
@@ -1552,5 +1696,10 @@ int stty_main(int argc UNUSED_PARAM, cha
}
}
+ if (rs485_setconfig) {
+ if (ioctl (STDIN_FILENO, TIOCSRS485, &rs485conf) < 0)
+ perror_on_device_and_die("%s: cannot set RS485 options");
+ }
+
return EXIT_SUCCESS;
}
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox