Add ability for user to specify whether RTS is high/low when sending in RS485 mode

This commit is contained in:
hedgecrw85 2020-01-22 15:28:20 -06:00
parent 0768e856ae
commit cc0d0315d9
21 changed files with 44 additions and 23 deletions

View File

@ -2,7 +2,7 @@
* SerialPort_Android.c * SerialPort_Android.c
* *
* Created on: Mar 13, 2015 * Created on: Mar 13, 2015
* Last Updated on: Nov 12, 2019 * Last Updated on: Jan 21, 2020
* Author: Will Hedgecock * Author: Will Hedgecock
* *
* Copyright (C) 2012-2020 Fazecast, Inc. * Copyright (C) 2012-2020 Fazecast, Inc.
@ -67,6 +67,7 @@ jfieldID flowControlField;
jfieldID sendDeviceQueueSizeField; jfieldID sendDeviceQueueSizeField;
jfieldID receiveDeviceQueueSizeField; jfieldID receiveDeviceQueueSizeField;
jfieldID rs485ModeField; jfieldID rs485ModeField;
jfieldID rs485ActiveHighField;
jfieldID rs485DelayBeforeField; jfieldID rs485DelayBeforeField;
jfieldID rs485DelayAfterField; jfieldID rs485DelayAfterField;
jfieldID timeoutModeField; jfieldID timeoutModeField;
@ -125,6 +126,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
sendDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "sendDeviceQueueSize", "I"); sendDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "sendDeviceQueueSize", "I");
receiveDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "receiveDeviceQueueSize", "I"); receiveDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "receiveDeviceQueueSize", "I");
rs485ModeField = (*env)->GetFieldID(env, serialCommClass, "rs485Mode", "Z"); rs485ModeField = (*env)->GetFieldID(env, serialCommClass, "rs485Mode", "Z");
rs485ActiveHighField = (*env)->GetFieldID(env, serialCommClass, "rs485ActiveHigh", "Z");
rs485DelayBeforeField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayBefore", "I"); rs485DelayBeforeField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayBefore", "I");
rs485DelayAfterField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayAfter", "I"); rs485DelayAfterField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayAfter", "I");
timeoutModeField = (*env)->GetFieldID(env, serialCommClass, "timeoutMode", "I"); timeoutModeField = (*env)->GetFieldID(env, serialCommClass, "timeoutMode", "I");
@ -203,6 +205,7 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
int rs485DelayAfter = (*env)->GetIntField(env, obj, rs485DelayAfterField); int rs485DelayAfter = (*env)->GetIntField(env, obj, rs485DelayAfterField);
unsigned char configDisabled = (*env)->GetBooleanField(env, obj, disableConfigField); unsigned char configDisabled = (*env)->GetBooleanField(env, obj, disableConfigField);
unsigned char rs485ModeEnabled = (*env)->GetBooleanField(env, obj, rs485ModeField); unsigned char rs485ModeEnabled = (*env)->GetBooleanField(env, obj, rs485ModeField);
unsigned char rs485ActiveHigh = (*env)->GetBooleanField(env, obj, rs485ActiveHighField);
unsigned char isDtrEnabled = (*env)->GetBooleanField(env, obj, isDtrEnabledField); unsigned char isDtrEnabled = (*env)->GetBooleanField(env, obj, isDtrEnabledField);
unsigned char isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField); unsigned char isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField);
tcflag_t byteSize = (byteSizeInt == 5) ? CS5 : (byteSizeInt == 6) ? CS6 : (byteSizeInt == 7) ? CS7 : CS8; tcflag_t byteSize = (byteSizeInt == 5) ? CS5 : (byteSizeInt == 6) ? CS6 : (byteSizeInt == 7) ? CS7 : CS8;
@ -271,9 +274,19 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
if (ioctl(serialPortFD, TIOCGRS485, &rs485Conf) == 0) if (ioctl(serialPortFD, TIOCGRS485, &rs485Conf) == 0)
{ {
if (rs485ModeEnabled) if (rs485ModeEnabled)
rs485Conf.flags |= SER_RS485_ENABLED; // Set these too? SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND rs485Conf.flags |= SER_RS485_ENABLED;
else else
rs485Conf.flags &= ~SER_RS485_ENABLED; // Clear these too? &= ~(SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND); rs485Conf.flags &= ~SER_RS485_ENABLED;
if (rs485ActiveHigh)
{
rs485Conf.flags |= SER_RS485_RTS_ON_SEND;
rs485Conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
}
else
{
rs485Conf.flags &= ~(SER_RS485_RTS_ON_SEND);
rs485Conf.flags |= SER_RS485_RTS_AFTER_SEND;
}
rs485Conf.delay_rts_before_send = rs485DelayBefore; rs485Conf.delay_rts_before_send = rs485DelayBefore;
rs485Conf.delay_rts_after_send = rs485DelayAfter; rs485Conf.delay_rts_after_send = rs485DelayAfter;
ioctl(serialPortFD, TIOCSRS485, &rs485Conf); ioctl(serialPortFD, TIOCSRS485, &rs485Conf);

View File

@ -2,7 +2,7 @@
* SerialPort_Posix.c * SerialPort_Posix.c
* *
* Created on: Feb 25, 2012 * Created on: Feb 25, 2012
* Last Updated on: Nov 12, 2019 * Last Updated on: Jan 21, 2020
* Author: Will Hedgecock * Author: Will Hedgecock
* *
* Copyright (C) 2012-2020 Fazecast, Inc. * Copyright (C) 2012-2020 Fazecast, Inc.
@ -65,6 +65,7 @@ jfieldID flowControlField;
jfieldID sendDeviceQueueSizeField; jfieldID sendDeviceQueueSizeField;
jfieldID receiveDeviceQueueSizeField; jfieldID receiveDeviceQueueSizeField;
jfieldID rs485ModeField; jfieldID rs485ModeField;
jfieldID rs485ActiveHighField;
jfieldID rs485DelayBeforeField; jfieldID rs485DelayBeforeField;
jfieldID rs485DelayAfterField; jfieldID rs485DelayAfterField;
jfieldID timeoutModeField; jfieldID timeoutModeField;
@ -229,6 +230,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
sendDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "sendDeviceQueueSize", "I"); sendDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "sendDeviceQueueSize", "I");
receiveDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "receiveDeviceQueueSize", "I"); receiveDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "receiveDeviceQueueSize", "I");
rs485ModeField = (*env)->GetFieldID(env, serialCommClass, "rs485Mode", "Z"); rs485ModeField = (*env)->GetFieldID(env, serialCommClass, "rs485Mode", "Z");
rs485ActiveHighField = (*env)->GetFieldID(env, serialCommClass, "rs485ActiveHigh", "Z");
rs485DelayBeforeField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayBefore", "I"); rs485DelayBeforeField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayBefore", "I");
rs485DelayAfterField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayAfter", "I"); rs485DelayAfterField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayAfter", "I");
timeoutModeField = (*env)->GetFieldID(env, serialCommClass, "timeoutMode", "I"); timeoutModeField = (*env)->GetFieldID(env, serialCommClass, "timeoutMode", "I");
@ -317,6 +319,7 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
int rs485DelayAfter = (*env)->GetIntField(env, obj, rs485DelayAfterField); int rs485DelayAfter = (*env)->GetIntField(env, obj, rs485DelayAfterField);
unsigned char configDisabled = (*env)->GetBooleanField(env, obj, disableConfigField); unsigned char configDisabled = (*env)->GetBooleanField(env, obj, disableConfigField);
unsigned char rs485ModeEnabled = (*env)->GetBooleanField(env, obj, rs485ModeField); unsigned char rs485ModeEnabled = (*env)->GetBooleanField(env, obj, rs485ModeField);
unsigned char rs485ActiveHigh = (*env)->GetBooleanField(env, obj, rs485ActiveHighField);
unsigned char isDtrEnabled = (*env)->GetBooleanField(env, obj, isDtrEnabledField); unsigned char isDtrEnabled = (*env)->GetBooleanField(env, obj, isDtrEnabledField);
unsigned char isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField); unsigned char isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField);
tcflag_t byteSize = (byteSizeInt == 5) ? CS5 : (byteSizeInt == 6) ? CS6 : (byteSizeInt == 7) ? CS7 : CS8; tcflag_t byteSize = (byteSizeInt == 5) ? CS5 : (byteSizeInt == 6) ? CS6 : (byteSizeInt == 7) ? CS7 : CS8;
@ -374,9 +377,19 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
if (ioctl(serialPortFD, TIOCGRS485, &rs485Conf) == 0) if (ioctl(serialPortFD, TIOCGRS485, &rs485Conf) == 0)
{ {
if (rs485ModeEnabled) if (rs485ModeEnabled)
rs485Conf.flags |= SER_RS485_ENABLED; // Set these too? SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND rs485Conf.flags |= SER_RS485_ENABLED;
else else
rs485Conf.flags &= ~SER_RS485_ENABLED; // Clear these too? &= ~(SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND); rs485Conf.flags &= ~SER_RS485_ENABLED;
if (rs485ActiveHigh)
{
rs485Conf.flags |= SER_RS485_RTS_ON_SEND;
rs485Conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
}
else
{
rs485Conf.flags &= ~(SER_RS485_RTS_ON_SEND);
rs485Conf.flags |= SER_RS485_RTS_AFTER_SEND;
}
rs485Conf.delay_rts_before_send = rs485DelayBefore; rs485Conf.delay_rts_before_send = rs485DelayBefore;
rs485Conf.delay_rts_after_send = rs485DelayAfter; rs485Conf.delay_rts_after_send = rs485DelayAfter;
ioctl(serialPortFD, TIOCSRS485, &rs485Conf); ioctl(serialPortFD, TIOCSRS485, &rs485Conf);

View File

@ -2,7 +2,7 @@
* SerialPort.java * SerialPort.java
* *
* Created on: Feb 25, 2012 * Created on: Feb 25, 2012
* Last Updated on: Jan 03, 2020 * Last Updated on: Jan 22, 2020
* Author: Will Hedgecock * Author: Will Hedgecock
* *
* Copyright (C) 2012-2020 Fazecast, Inc. * Copyright (C) 2012-2020 Fazecast, Inc.
@ -374,8 +374,8 @@ public final class SerialPort
private volatile SerialPortDataListener userDataListener = null; private volatile SerialPortDataListener userDataListener = null;
private volatile SerialPortEventListener serialEventListener = null; private volatile SerialPortEventListener serialEventListener = null;
private volatile String comPort, friendlyName, portDescription; private volatile String comPort, friendlyName, portDescription;
private volatile boolean isOpened = false, disableConfig = false; private volatile boolean isOpened = false, disableConfig = false, rs485Mode = false;
private volatile boolean rs485Mode = false, isRtsEnabled = true, isDtrEnabled = true; private volatile boolean rs485ActiveHigh = true, isRtsEnabled = true, isDtrEnabled = true;
/** /**
* Opens this serial port for reading and writing with an optional delay time and user-specified device buffer size. * Opens this serial port for reading and writing with an optional delay time and user-specified device buffer size.
@ -855,17 +855,7 @@ public final class SerialPort
*/ */
public final void setComPortParameters(int newBaudRate, int newDataBits, int newStopBits, int newParity) public final void setComPortParameters(int newBaudRate, int newDataBits, int newStopBits, int newParity)
{ {
baudRate = newBaudRate; setComPortParameters(newBaudRate, newDataBits, newStopBits, newParity, rs485Mode);
dataBits = newDataBits;
stopBits = newStopBits;
parity = newParity;
if (isOpened)
{
if (safetySleepTimeMS > 0)
try { Thread.sleep(safetySleepTimeMS); } catch (Exception e) { Thread.currentThread().interrupt(); }
configPort(portHandle);
}
} }
/** /**
@ -882,8 +872,8 @@ public final class SerialPort
* The parity parameter specifies how error detection is carried out. Again, the built-in constants should be used. * The parity parameter specifies how error detection is carried out. Again, the built-in constants should be used.
* Acceptable values are {@link #NO_PARITY}, {@link #EVEN_PARITY}, {@link #ODD_PARITY}, {@link #MARK_PARITY}, and {@link #SPACE_PARITY}. * Acceptable values are {@link #NO_PARITY}, {@link #EVEN_PARITY}, {@link #ODD_PARITY}, {@link #MARK_PARITY}, and {@link #SPACE_PARITY}.
* <p> * <p>
* RS-485 mode can be used to enable transmit/receive mode signaling using the RTS pin. This mode should be set if you plan * RS-485 mode can be used to enable transmit/receive mode signaling using the RTS pin. This mode should be set if you plan
* to use this library with an RS-485 device. Note that this mode requires support from the underlying device driver, so it * to use this library with an RS-485 device. Note that this mode requires support from the underlying device driver, so it
* may not work with all RS-485 devices. * may not work with all RS-485 devices.
* *
* @param newBaudRate The desired baud rate for this serial port. * @param newBaudRate The desired baud rate for this serial port.
@ -1123,16 +1113,21 @@ public final class SerialPort
* to use this library with an RS-485 device. Note that this mode requires support from the underlying device driver, so it * to use this library with an RS-485 device. Note that this mode requires support from the underlying device driver, so it
* may not work with all RS-485 devices. * may not work with all RS-485 devices.
* <p> * <p>
* The RTS "active high" parameter specifies that the logical level of the RTS line will be set to 1 when transmitting and
* 0 when receiving.
* <p>
* The delay parameters specify how long to wait before or after transmission of data before enabling or disabling * The delay parameters specify how long to wait before or after transmission of data before enabling or disabling
* transmission mode via the RTS pin. * transmission mode via the RTS pin.
* *
* @param useRS485Mode Whether to enable RS-485 mode. * @param useRS485Mode Whether to enable RS-485 mode.
* @param rs485RtsActiveHigh Whether to set the RTS line to 1 when transmitting.
* @param delayBeforeSendMicroseconds The time to wait after enabling transmit mode before sending the first data bit. * @param delayBeforeSendMicroseconds The time to wait after enabling transmit mode before sending the first data bit.
* @param delayAfterSendMicroseconds The time to wait after sending the last data bit before disabling transmit mode. * @param delayAfterSendMicroseconds The time to wait after sending the last data bit before disabling transmit mode.
*/ */
public final void setRs485ModeParameters(boolean useRS485Mode, int delayBeforeSendMicroseconds, int delayAfterSendMicroseconds) public final void setRs485ModeParameters(boolean useRS485Mode, boolean rs485RtsActiveHigh, int delayBeforeSendMicroseconds, int delayAfterSendMicroseconds)
{ {
rs485Mode = useRS485Mode; rs485Mode = useRS485Mode;
rs485ActiveHigh = rs485RtsActiveHigh;
rs485DelayBefore = delayBeforeSendMicroseconds; rs485DelayBefore = delayBeforeSendMicroseconds;
rs485DelayAfter = delayAfterSendMicroseconds; rs485DelayAfter = delayAfterSendMicroseconds;