diff --git a/README.md b/README.md index ae7db65d..fa446587 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ ease of use and embeddability in other libraries. * [RFC 2217](http://tools.ietf.org/html/rfc2217) support provided by incorporating the [jvser library](http://github.com/archiecobbs/jvser). +* RS485 support for Linux + ## And a bunch of bug fixes * Fixed the memory access error that causes OS X to crash the JVM when diff --git a/src/main/c/src/SerialImp.c b/src/main/c/src/SerialImp.c index b2b0f46e..9de01399 100644 --- a/src/main/c/src/SerialImp.c +++ b/src/main/c/src/SerialImp.c @@ -602,6 +602,48 @@ cf{get,set}{i,o}speed and shouldn't be provided or used. (*env)->SetIntField(env, jobj, jfparity, ( jint ) jparity ); } /*---------------------------------------------------------- +RXTXPort.controlRs485 + + accept: fd of the preopened device, + boolean if the bus enable (RTS) is active low, + delay of RTS edge to first data edge (not supported by all serial drivers), + delay of RTS edge after end of transmission (not supported by all serial drivers) + perform: set the rs485 config via ioctl + return: return code of ioctl +----------------------------------------------------------*/ +JNIEXPORT jint JNICALL RXTXPort(controlRs485)( + JNIEnv *env, + jobject jobj, + jint fd, + jboolean enable, + jboolean busEnableActiveLow, + jint delayRtsBeforeSendMs, + jint delayRtsAfterSendMs + ) +{ +#if defined(__linux__) + struct serial_rs485 rs485conf; + memset(&rs485conf, 0, sizeof(struct serial_rs485)); + + if(enable) { + rs485conf.flags |= SER_RS485_ENABLED; + } + + if(busEnableActiveLow) { + rs485conf.flags |= SER_RS485_RTS_AFTER_SEND; + } else { + rs485conf.flags |= SER_RS485_RTS_ON_SEND; + } + + rs485conf.delay_rts_before_send = delayRtsBeforeSendMs; + rs485conf.delay_rts_after_send = delayRtsAfterSendMs; + + return ioctl (fd, TIOCSRS485, &rs485conf); +#else + return -1; +#endif +} +/*---------------------------------------------------------- RXTXPort.open accept: The device to open. ie "/dev/ttyS0" diff --git a/src/main/java/gnu/io/NRSerialPort.java b/src/main/java/gnu/io/NRSerialPort.java index 40b223e6..18d94587 100644 --- a/src/main/java/gnu/io/NRSerialPort.java +++ b/src/main/java/gnu/io/NRSerialPort.java @@ -222,6 +222,32 @@ public int getBaud() return baud; } + /** + * Enables RS485 half-duplex bus communication for Linux. The Linux kernel uses the RTS pin as bus enable. If you use a device that is configured via the Linux + * device tree, take care to add "uart-has-rtscts" and to configure the RTS GPIO correctly. + * + * Before enabling RS485, the serial port must be connected/opened. + * + * See also: + * + * + * @param busEnableActiveLow + * true, if the bus enable signal (RTS) shall be low during transmission + * @param delayBusEnableBeforeSendMs + * delay of bus enable signal (RTS) edge to first data edge in ms (not supported by all serial drivers) + * @param delayBusEnableAfterSendMs + * delay of bus enable signal (RTS) edge after end of transmission in ms (not supported by all serial drivers) + * @return the ioctl() return value + */ + public int enableRs485(boolean busEnableActiveLow, int delayBusEnableBeforeSendMs, int delayBusEnableAfterSendMs) { + if(serial == null) + return -1; + + return serial.enableRs485(busEnableActiveLow, delayBusEnableBeforeSendMs, delayBusEnableAfterSendMs); + } public void notifyOnDataAvailable(boolean b) { diff --git a/src/main/java/gnu/io/RXTXPort.java b/src/main/java/gnu/io/RXTXPort.java index 8843340f..c5a00072 100644 --- a/src/main/java/gnu/io/RXTXPort.java +++ b/src/main/java/gnu/io/RXTXPort.java @@ -1075,6 +1075,7 @@ public void close() z.reportln( "RXTXPort:close detected bad File Descriptor" ); return; } + disableRs485(); setDTR(false); setDSR(false); if (debug) @@ -2238,5 +2239,16 @@ public boolean clearCommInput() return nativeClearCommInput(); } + + public int enableRs485(boolean busEnableActiveLow, int delayBusEnableBeforeSendMs, int delayBusEnableAfterSendMs) { + return controlRs485(fd, true, busEnableActiveLow, delayBusEnableBeforeSendMs, delayBusEnableAfterSendMs); + } + + public int disableRs485() { + return controlRs485(fd, false, false, 0, 0); + } + + private native synchronized int controlRs485(int fd, boolean enable, boolean busEnableActiveLow, int delayBusEnableBeforeSendMs, int delayBusEnableAfterSendMs); + /*------------------------ END OF CommAPI Extensions -----------------------*/ }