Add functionality to flush Rx/Tx serial buffers
This commit is contained in:
parent
b44e972ffe
commit
5dc13a33d5
|
@ -2,7 +2,7 @@
|
|||
* SerialPort_Posix.c
|
||||
*
|
||||
* Created on: Feb 25, 2012
|
||||
* Last Updated on: Dec 01, 2021
|
||||
* Last Updated on: Dec 07, 2021
|
||||
* Author: Will Hedgecock
|
||||
*
|
||||
* Copyright (C) 2012-2021 Fazecast, Inc.
|
||||
|
@ -33,6 +33,7 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#if defined(__linux__)
|
||||
#include <linux/serial.h>
|
||||
|
@ -52,6 +53,7 @@ jfieldID eventListenerRunningField;
|
|||
jfieldID disableConfigField;
|
||||
jfieldID isDtrEnabledField;
|
||||
jfieldID isRtsEnabledField;
|
||||
jfieldID autoFlushIOBuffersField;
|
||||
jfieldID baudRateField;
|
||||
jfieldID dataBitsField;
|
||||
jfieldID stopBitsField;
|
||||
|
@ -135,6 +137,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
|
|||
disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z");
|
||||
isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z");
|
||||
isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z");
|
||||
autoFlushIOBuffersField = (*env)->GetFieldID(env, serialCommClass, "autoFlushIOBuffers", "Z");
|
||||
baudRateField = (*env)->GetFieldID(env, serialCommClass, "baudRate", "I");
|
||||
dataBitsField = (*env)->GetFieldID(env, serialCommClass, "dataBits", "I");
|
||||
stopBitsField = (*env)->GetFieldID(env, serialCommClass, "stopBits", "I");
|
||||
|
@ -185,6 +188,7 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
|
|||
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
|
||||
unsigned char disableExclusiveLock = (*env)->GetBooleanField(env, obj, disableExclusiveLockField);
|
||||
unsigned char disableAutoConfig = (*env)->GetBooleanField(env, obj, disableConfigField);
|
||||
unsigned char autoFlushIOBuffers = (*env)->GetBooleanField(env, obj, autoFlushIOBuffersField);
|
||||
|
||||
// Ensure that the serial port still exists and is not already open
|
||||
serialPort *port = fetchPort(&serialPorts, portName);
|
||||
|
@ -220,6 +224,13 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
|
|||
errno = 0;
|
||||
port->handle = -1;
|
||||
}
|
||||
else if (autoFlushIOBuffers)
|
||||
{
|
||||
// Sleep to workaround kernel bug about flushing immediately after opening
|
||||
const struct timespec sleep_time = { 0, 10000000 };
|
||||
nanosleep(&sleep_time, NULL);
|
||||
Java_com_fazecast_jSerialComm_SerialPort_flushRxTxBuffers(env, obj, (jlong)(intptr_t)port);
|
||||
}
|
||||
}
|
||||
else
|
||||
port->errorNumber = errno;
|
||||
|
@ -427,6 +438,18 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
|
|||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_flushRxTxBuffers(JNIEnv *env, jobject obj, jlong serialPortPointer)
|
||||
{
|
||||
serialPort *port = (serialPort*)(intptr_t)serialPortPointer;
|
||||
if (tcflush(port->handle, TCIOFLUSH))
|
||||
{
|
||||
port->errorLineNumber = __LINE__ - 2;
|
||||
port->errorNumber = errno;
|
||||
return JNI_FALSE;
|
||||
}
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNIEnv *env, jobject obj, jlong serialPortPointer)
|
||||
{
|
||||
// Initialize the local variables
|
||||
|
|
|
@ -129,6 +129,14 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort
|
|||
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeouts
|
||||
(JNIEnv *, jobject, jlong, jint, jint, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: com_fazecast_jSerialComm_SerialPort
|
||||
* Method: flushRxTxBuffers
|
||||
* Signature: (J)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_flushRxTxBuffers
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_fazecast_jSerialComm_SerialPort
|
||||
* Method: waitForEvent
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* SerialPort_Windows.c
|
||||
*
|
||||
* Created on: Feb 25, 2012
|
||||
* Last Updated on: Dec 06, 2021
|
||||
* Last Updated on: Dec 07, 2021
|
||||
* Author: Will Hedgecock
|
||||
*
|
||||
* Copyright (C) 2012-2021 Fazecast, Inc.
|
||||
|
@ -49,6 +49,7 @@ jfieldID eventListenerRunningField;
|
|||
jfieldID disableConfigField;
|
||||
jfieldID isDtrEnabledField;
|
||||
jfieldID isRtsEnabledField;
|
||||
jfieldID autoFlushIOBuffersField;
|
||||
jfieldID baudRateField;
|
||||
jfieldID dataBitsField;
|
||||
jfieldID stopBitsField;
|
||||
|
@ -366,6 +367,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
|
|||
disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z");
|
||||
isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z");
|
||||
isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z");
|
||||
autoFlushIOBuffersField = (*env)->GetFieldID(env, serialCommClass, "autoFlushIOBuffers", "Z");
|
||||
baudRateField = (*env)->GetFieldID(env, serialCommClass, "baudRate", "I");
|
||||
dataBitsField = (*env)->GetFieldID(env, serialCommClass, "dataBits", "I");
|
||||
stopBitsField = (*env)->GetFieldID(env, serialCommClass, "stopBits", "I");
|
||||
|
@ -396,6 +398,7 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
|
|||
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
|
||||
const wchar_t *portName = (wchar_t*)(*env)->GetStringChars(env, portNameJString, NULL);
|
||||
unsigned char disableAutoConfig = (*env)->GetBooleanField(env, obj, disableConfigField);
|
||||
unsigned char autoFlushIOBuffers = (*env)->GetBooleanField(env, obj, autoFlushIOBuffersField);
|
||||
|
||||
// Ensure that the serial port still exists and is not already open
|
||||
serialPort *port = fetchPort(&serialPorts, portName);
|
||||
|
@ -423,6 +426,8 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
|
|||
CloseHandle(port->handle);
|
||||
port->handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
else if (autoFlushIOBuffers)
|
||||
Java_com_fazecast_jSerialComm_SerialPort_flushRxTxBuffers(env, obj, (jlong)(intptr_t)port);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -573,6 +578,18 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
|
|||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_flushRxTxBuffers(JNIEnv *env, jobject obj, jlong serialPortPointer)
|
||||
{
|
||||
serialPort *port = (serialPort*)(intptr_t)serialPortPointer;
|
||||
if (PurgeComm(port->handle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR) == 0)
|
||||
{
|
||||
port->errorLineNumber = __LINE__ - 2;
|
||||
port->errorNumber = GetLastError();
|
||||
return JNI_FALSE;
|
||||
}
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNIEnv *env, jobject obj, jlong serialPortPointer)
|
||||
{
|
||||
// Create an asynchronous event structure
|
||||
|
|
|
@ -421,7 +421,7 @@ public final class SerialPort
|
|||
private volatile String comPort, friendlyName, portDescription;
|
||||
private volatile boolean eventListenerRunning = false, disableConfig = false, disableExclusiveLock = false;
|
||||
private volatile boolean rs485Mode = false, rs485ActiveHigh = true, rs485RxDuringTx = false, rs485EnableTermination = false;
|
||||
private volatile boolean isRtsEnabled = true, isDtrEnabled = true;
|
||||
private volatile boolean isRtsEnabled = true, isDtrEnabled = true, autoFlushIOBuffers = false;
|
||||
private SerialPortInputStream inputStream = null;
|
||||
private SerialPortOutputStream outputStream = null;
|
||||
|
||||
|
@ -592,6 +592,7 @@ public final class SerialPort
|
|||
private final native long closePortNative(long portHandle); // Closes serial port
|
||||
private final native boolean configPort(long portHandle); // Changes/sets serial port parameters as defined by this class
|
||||
private final native boolean configTimeouts(long portHandle, int timeoutMode, int readTimeout, int writeTimeout, int eventsToMonitor); // Changes/sets serial port timeouts as defined by this class
|
||||
private final native boolean flushRxTxBuffers(long portHandle); // Flushes underlying RX/TX device buffers
|
||||
private final native int waitForEvent(long portHandle); // Waits for serial event to occur as specified in eventFlags
|
||||
private final native int bytesAvailable(long portHandle); // Returns number of bytes available for reading
|
||||
private final native int bytesAwaitingWrite(long portHandle); // Returns number of bytes still waiting to be written
|
||||
|
@ -966,6 +967,27 @@ public final class SerialPort
|
|||
return outputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the serial port's Rx/Tx device buffers.
|
||||
* <p>
|
||||
* If this function is called before the port is open, then the buffers will be flushed immediately after opening the port.
|
||||
* If called on an already-open port, flushing of the buffers will happen immediately.
|
||||
* <p>
|
||||
* Note that flushing serial buffers will always work on real serial ports; however, many USB-to-serial converters
|
||||
* do not accurately implement this functionality, so the flushing may not always work as expected, especially immediately
|
||||
* after opening a new port.
|
||||
*
|
||||
* @return Whether the IO buffers were (or will be) successfully flushed.
|
||||
*/
|
||||
public final synchronized boolean flushIOBuffers()
|
||||
{
|
||||
autoFlushIOBuffers = true;
|
||||
|
||||
if (portHandle > 0)
|
||||
return flushRxTxBuffers(portHandle);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all serial port parameters at one time.
|
||||
* <p>
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue