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
*
* Created on: Mar 13, 2015
* Last Updated on: Nov 12, 2019
* Last Updated on: Jan 21, 2020
* Author: Will Hedgecock
*
* Copyright (C) 2012-2020 Fazecast, Inc.
@ -67,6 +67,7 @@ jfieldID flowControlField;
jfieldID sendDeviceQueueSizeField;
jfieldID receiveDeviceQueueSizeField;
jfieldID rs485ModeField;
jfieldID rs485ActiveHighField;
jfieldID rs485DelayBeforeField;
jfieldID rs485DelayAfterField;
jfieldID timeoutModeField;
@ -125,6 +126,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
sendDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "sendDeviceQueueSize", "I");
receiveDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "receiveDeviceQueueSize", "I");
rs485ModeField = (*env)->GetFieldID(env, serialCommClass, "rs485Mode", "Z");
rs485ActiveHighField = (*env)->GetFieldID(env, serialCommClass, "rs485ActiveHigh", "Z");
rs485DelayBeforeField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayBefore", "I");
rs485DelayAfterField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayAfter", "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);
unsigned char configDisabled = (*env)->GetBooleanField(env, obj, disableConfigField);
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 isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField);
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 (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
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_after_send = rs485DelayAfter;
ioctl(serialPortFD, TIOCSRS485, &rs485Conf);

View File

@ -2,7 +2,7 @@
* SerialPort_Posix.c
*
* Created on: Feb 25, 2012
* Last Updated on: Nov 12, 2019
* Last Updated on: Jan 21, 2020
* Author: Will Hedgecock
*
* Copyright (C) 2012-2020 Fazecast, Inc.
@ -65,6 +65,7 @@ jfieldID flowControlField;
jfieldID sendDeviceQueueSizeField;
jfieldID receiveDeviceQueueSizeField;
jfieldID rs485ModeField;
jfieldID rs485ActiveHighField;
jfieldID rs485DelayBeforeField;
jfieldID rs485DelayAfterField;
jfieldID timeoutModeField;
@ -229,6 +230,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
sendDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "sendDeviceQueueSize", "I");
receiveDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "receiveDeviceQueueSize", "I");
rs485ModeField = (*env)->GetFieldID(env, serialCommClass, "rs485Mode", "Z");
rs485ActiveHighField = (*env)->GetFieldID(env, serialCommClass, "rs485ActiveHigh", "Z");
rs485DelayBeforeField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayBefore", "I");
rs485DelayAfterField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayAfter", "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);
unsigned char configDisabled = (*env)->GetBooleanField(env, obj, disableConfigField);
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 isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField);
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 (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
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_after_send = rs485DelayAfter;
ioctl(serialPortFD, TIOCSRS485, &rs485Conf);

View File

@ -2,7 +2,7 @@
* SerialPort.java
*
* Created on: Feb 25, 2012
* Last Updated on: Jan 03, 2020
* Last Updated on: Jan 22, 2020
* Author: Will Hedgecock
*
* Copyright (C) 2012-2020 Fazecast, Inc.
@ -374,8 +374,8 @@ public final class SerialPort
private volatile SerialPortDataListener userDataListener = null;
private volatile SerialPortEventListener serialEventListener = null;
private volatile String comPort, friendlyName, portDescription;
private volatile boolean isOpened = false, disableConfig = false;
private volatile boolean rs485Mode = false, isRtsEnabled = true, isDtrEnabled = true;
private volatile boolean isOpened = false, disableConfig = false, rs485Mode = false;
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.
@ -855,17 +855,7 @@ public final class SerialPort
*/
public final void setComPortParameters(int newBaudRate, int newDataBits, int newStopBits, int newParity)
{
baudRate = newBaudRate;
dataBits = newDataBits;
stopBits = newStopBits;
parity = newParity;
if (isOpened)
{
if (safetySleepTimeMS > 0)
try { Thread.sleep(safetySleepTimeMS); } catch (Exception e) { Thread.currentThread().interrupt(); }
configPort(portHandle);
}
setComPortParameters(newBaudRate, newDataBits, newStopBits, newParity, rs485Mode);
}
/**
@ -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.
* Acceptable values are {@link #NO_PARITY}, {@link #EVEN_PARITY}, {@link #ODD_PARITY}, {@link #MARK_PARITY}, and {@link #SPACE_PARITY}.
* <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
* to use this library with an RS-485 device. Note that this mode requires support from the underlying device driver, so it
* 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
* may not work with all RS-485 devices.
*
* @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
* may not work with all RS-485 devices.
* <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
* transmission mode via the RTS pin.
*
* @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 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;
rs485ActiveHigh = rs485RtsActiveHigh;
rs485DelayBefore = delayBeforeSendMicroseconds;
rs485DelayAfter = delayAfterSendMicroseconds;