diff --git a/hal/src/main/java/edu/wpi/first/hal/SerialPortJNI.java b/hal/src/main/java/edu/wpi/first/hal/SerialPortJNI.java index db98b9c547..267947bba0 100644 --- a/hal/src/main/java/edu/wpi/first/hal/SerialPortJNI.java +++ b/hal/src/main/java/edu/wpi/first/hal/SerialPortJNI.java @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */ +/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ @@ -8,41 +8,41 @@ package edu.wpi.first.hal; public class SerialPortJNI extends JNIWrapper { - public static native void serialInitializePort(byte port); + public static native int serialInitializePort(byte port); - public static native void serialInitializePortDirect(byte port, String portName); + public static native int serialInitializePortDirect(byte port, String portName); - public static native void serialSetBaudRate(byte port, int baud); + public static native void serialSetBaudRate(int handle, int baud); - public static native void serialSetDataBits(byte port, byte bits); + public static native void serialSetDataBits(int handle, byte bits); - public static native void serialSetParity(byte port, byte parity); + public static native void serialSetParity(int handle, byte parity); - public static native void serialSetStopBits(byte port, byte stopBits); + public static native void serialSetStopBits(int handle, byte stopBits); - public static native void serialSetWriteMode(byte port, byte mode); + public static native void serialSetWriteMode(int handle, byte mode); - public static native void serialSetFlowControl(byte port, byte flow); + public static native void serialSetFlowControl(int handle, byte flow); - public static native void serialSetTimeout(byte port, double timeout); + public static native void serialSetTimeout(int handle, double timeout); - public static native void serialEnableTermination(byte port, char terminator); + public static native void serialEnableTermination(int handle, char terminator); - public static native void serialDisableTermination(byte port); + public static native void serialDisableTermination(int handle); - public static native void serialSetReadBufferSize(byte port, int size); + public static native void serialSetReadBufferSize(int handle, int size); - public static native void serialSetWriteBufferSize(byte port, int size); + public static native void serialSetWriteBufferSize(int handle, int size); - public static native int serialGetBytesReceived(byte port); + public static native int serialGetBytesReceived(int handle); - public static native int serialRead(byte port, byte[] buffer, int count); + public static native int serialRead(int handle, byte[] buffer, int count); - public static native int serialWrite(byte port, byte[] buffer, int count); + public static native int serialWrite(int handle, byte[] buffer, int count); - public static native void serialFlush(byte port); + public static native void serialFlush(int handle); - public static native void serialClear(byte port); + public static native void serialClear(int handle); - public static native void serialClose(byte port); + public static native void serialClose(int handle); } diff --git a/hal/src/main/native/athena/SerialPort.cpp b/hal/src/main/native/athena/SerialPort.cpp index d2597a94cd..7ef9b7068f 100644 --- a/hal/src/main/native/athena/SerialPort.cpp +++ b/hal/src/main/native/athena/SerialPort.cpp @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */ +/* Copyright (c) 2019 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ @@ -7,168 +7,493 @@ #include "hal/SerialPort.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include #include +#include -#include "HALInitializer.h" #include "hal/cpp/SerialHelper.h" -#include "visa/visa.h" +#include "hal/handles/HandlesInternal.h" +#include "hal/handles/IndexedHandleResource.h" -static int32_t resourceManagerHandle{0}; -static HAL_SerialPort portHandles[4]; +namespace { +struct SerialPort { + int portId; + struct termios tty; + int baudRate; + + double timeout = 0; + + bool termination = false; + char terminationChar = '\n'; +}; +} // namespace + +namespace hal { +IndexedHandleResource* serialPortHandles; +} // namespace hal namespace hal { namespace init { -void InitializeSerialPort() {} +void InitializeSerialPort() { + static IndexedHandleResource + spH; + serialPortHandles = &spH; +} } // namespace init } // namespace hal +using namespace hal; + extern "C" { - -void HAL_InitializeSerialPort(HAL_SerialPort port, int32_t* status) { - hal::init::CheckInit(); - std::string portName; - - if (resourceManagerHandle == 0) - viOpenDefaultRM(reinterpret_cast(&resourceManagerHandle)); +HAL_SerialPortHandle HAL_InitializeSerialPort(HAL_SerialPort port, + int32_t* status) { + // hal::init::CheckInit(); hal::SerialHelper serialHelper; - portName = serialHelper.GetVISASerialPortName(port, status); + std::string portName = serialHelper.GetOSSerialPortName(port, status); if (*status < 0) { + return HAL_kInvalidHandle; + } + + return HAL_InitializeSerialPortDirect(port, portName.c_str(), status); +} +HAL_SerialPortHandle HAL_InitializeSerialPortDirect(HAL_SerialPort port, + const char* portName, + int32_t* status) { + auto handle = serialPortHandles->Allocate(static_cast(port), status); + + if (*status != 0) { + return HAL_kInvalidHandle; + } + + auto serialPort = serialPortHandles->Get(handle); + + if (serialPort == nullptr) { + *status = HAL_HANDLE_ERROR; + return HAL_kInvalidHandle; + } + + serialPort->portId = open(portName, O_RDWR | O_NOCTTY); + if (serialPort->portId < 0) { + *status = errno; + serialPortHandles->Free(handle); + return HAL_kInvalidHandle; + } + + std::memset(&serialPort->tty, 0, sizeof(serialPort->tty)); + + serialPort->baudRate = B9600; + cfsetospeed(&serialPort->tty, static_cast(serialPort->baudRate)); + cfsetispeed(&serialPort->tty, static_cast(serialPort->baudRate)); + + serialPort->tty.c_cflag &= ~PARENB; + serialPort->tty.c_cflag &= ~CSTOPB; + serialPort->tty.c_cflag &= ~CSIZE; + serialPort->tty.c_cflag |= CS8; + + serialPort->tty.c_cc[VMIN] = 0; + serialPort->tty.c_cc[VTIME] = 10; + + serialPort->tty.c_cflag |= CREAD | CLOCAL; + + serialPort->tty.c_lflag &= ~(ICANON | ECHO | ISIG); + serialPort->tty.c_iflag &= ~(IXON | IXOFF | IXANY); + /* Raw output mode, sends the raw and unprocessed data (send as it is). + * If it is in canonical mode and sending new line char then CR + * will be added as prefix and send as CR LF + */ + serialPort->tty.c_oflag = ~OPOST; + + tcflush(serialPort->portId, TCIOFLUSH); + if (tcsetattr(serialPort->portId, TCSANOW, &serialPort->tty) != 0) { + *status = errno; + close(serialPort->portId); + serialPortHandles->Free(handle); + return HAL_kInvalidHandle; + } + return handle; +} + +void HAL_CloseSerial(HAL_SerialPortHandle handle, int32_t* status) { + auto port = serialPortHandles->Get(handle); + serialPortHandles->Free(handle); + + if (port) { + close(port->portId); + } +} + +int HAL_GetSerialFD(HAL_SerialPortHandle handle, int32_t* status) { + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return -1; + } + return port->portId; +} + +#define BAUDCASE(BAUD) \ + case BAUD: \ + port->baudRate = B##BAUD; \ + break; + +void HAL_SetSerialBaudRate(HAL_SerialPortHandle handle, int32_t baud, + int32_t* status) { + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; return; } - *status = viOpen(resourceManagerHandle, const_cast(portName.c_str()), - VI_NULL, VI_NULL, - reinterpret_cast(&portHandles[port])); - if (*status > 0) *status = 0; + switch (baud) { + BAUDCASE(50) + BAUDCASE(75) + BAUDCASE(110) + BAUDCASE(134) + BAUDCASE(150) + BAUDCASE(200) + BAUDCASE(300) + BAUDCASE(600) + BAUDCASE(1200) + BAUDCASE(1800) + BAUDCASE(2400) + BAUDCASE(4800) + BAUDCASE(9600) + BAUDCASE(19200) + BAUDCASE(38400) + BAUDCASE(57600) + BAUDCASE(115200) + BAUDCASE(230400) + BAUDCASE(460800) + BAUDCASE(500000) + BAUDCASE(576000) + BAUDCASE(921600) + BAUDCASE(1000000) + BAUDCASE(1152000) + BAUDCASE(1500000) + BAUDCASE(2000000) + BAUDCASE(2500000) + BAUDCASE(3000000) + BAUDCASE(3500000) + BAUDCASE(4000000) + default: + *status = PARAMETER_OUT_OF_RANGE; + return; + } + int err = cfsetospeed(&port->tty, static_cast(port->baudRate)); + if (err < 0) { + *status = errno; + return; + } + err = cfsetispeed(&port->tty, static_cast(port->baudRate)); + if (err < 0) { + *status = errno; + return; + } + err = tcsetattr(port->portId, TCSANOW, &port->tty); + if (err < 0) { + *status = errno; + } } -void HAL_InitializeSerialPortDirect(HAL_SerialPort port, const char* portName, - int32_t* status) { - *status = viOpen(resourceManagerHandle, const_cast(portName), VI_NULL, - VI_NULL, reinterpret_cast(&portHandles[port])); - if (*status > 0) *status = 0; -} - -void HAL_SetSerialBaudRate(HAL_SerialPort port, int32_t baud, int32_t* status) { - *status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_BAUD, baud); - if (*status > 0) *status = 0; -} - -void HAL_SetSerialDataBits(HAL_SerialPort port, int32_t bits, int32_t* status) { - *status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_DATA_BITS, bits); - if (*status > 0) *status = 0; -} - -void HAL_SetSerialParity(HAL_SerialPort port, int32_t parity, int32_t* status) { - *status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_PARITY, parity); - if (*status > 0) *status = 0; -} - -void HAL_SetSerialStopBits(HAL_SerialPort port, int32_t stopBits, +void HAL_SetSerialDataBits(HAL_SerialPortHandle handle, int32_t bits, int32_t* status) { - *status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_STOP_BITS, stopBits); - if (*status > 0) *status = 0; + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return; + } + + int bitFlag = -1; + switch (bits) { + case 5: + bitFlag = CS5; + break; + case 6: + bitFlag = CS6; + break; + case 7: + bitFlag = CS7; + break; + case 8: + bitFlag = CS8; + break; + default: + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + port->tty.c_cflag &= ~CSIZE; + port->tty.c_cflag |= bitFlag; + + int err = tcsetattr(port->portId, TCSANOW, &port->tty); + if (err < 0) { + *status = errno; + } } -void HAL_SetSerialWriteMode(HAL_SerialPort port, int32_t mode, +void HAL_SetSerialParity(HAL_SerialPortHandle handle, int32_t parity, + int32_t* status) { + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return; + } + + switch (parity) { + case 0: // None + port->tty.c_cflag &= ~PARENB; + port->tty.c_cflag &= ~CMSPAR; + break; + case 1: // Odd + port->tty.c_cflag |= PARENB; + port->tty.c_cflag &= ~CMSPAR; + port->tty.c_cflag &= ~PARODD; + break; + case 2: // Even + port->tty.c_cflag |= PARENB; + port->tty.c_cflag &= ~CMSPAR; + port->tty.c_cflag |= PARODD; + break; + case 3: // Mark + port->tty.c_cflag |= PARENB; + port->tty.c_cflag |= CMSPAR; + port->tty.c_cflag |= PARODD; + break; + case 4: // Space + port->tty.c_cflag |= PARENB; + port->tty.c_cflag |= CMSPAR; + port->tty.c_cflag &= ~PARODD; + break; + default: + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + int err = tcsetattr(port->portId, TCSANOW, &port->tty); + if (err < 0) { + *status = errno; + } +} + +void HAL_SetSerialStopBits(HAL_SerialPortHandle handle, int32_t stopBits, + int32_t* status) { + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return; + } + + switch (stopBits) { + case 10: // 1 + port->tty.c_cflag &= ~CSTOPB; + break; + case 15: // 1.5 + case 20: // 2 + port->tty.c_cflag |= CSTOPB; + break; + default: + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + int err = tcsetattr(port->portId, TCSANOW, &port->tty); + if (err < 0) { + *status = errno; + } +} + +void HAL_SetSerialWriteMode(HAL_SerialPortHandle handle, int32_t mode, int32_t* status) { - *status = viSetAttribute(portHandles[port], VI_ATTR_WR_BUF_OPER_MODE, mode); - if (*status > 0) *status = 0; + // This seems to be a no op on the NI serial port driver } -void HAL_SetSerialFlowControl(HAL_SerialPort port, int32_t flow, +void HAL_SetSerialFlowControl(HAL_SerialPortHandle handle, int32_t flow, int32_t* status) { - *status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_FLOW_CNTRL, flow); - if (*status > 0) *status = 0; + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return; + } + + switch (flow) { + case 0: + port->tty.c_cflag &= ~CRTSCTS; + break; + case 1: + port->tty.c_cflag &= ~CRTSCTS; + port->tty.c_iflag &= IXON | IXOFF; + break; + case 2: + port->tty.c_cflag |= CRTSCTS; + break; + default: + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + int err = tcsetattr(port->portId, TCSANOW, &port->tty); + if (err < 0) { + *status = errno; + } } -void HAL_SetSerialTimeout(HAL_SerialPort port, double timeout, +void HAL_SetSerialTimeout(HAL_SerialPortHandle handle, double timeout, int32_t* status) { - *status = viSetAttribute(portHandles[port], VI_ATTR_TMO_VALUE, - static_cast(timeout * 1e3)); - if (*status > 0) *status = 0; + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return; + } + port->timeout = timeout; + port->tty.c_cc[VTIME] = static_cast(timeout * 10); + int err = tcsetattr(port->portId, TCSANOW, &port->tty); + if (err < 0) { + *status = errno; + } } -void HAL_EnableSerialTermination(HAL_SerialPort port, char terminator, +void HAL_EnableSerialTermination(HAL_SerialPortHandle handle, char terminator, int32_t* status) { - viSetAttribute(portHandles[port], VI_ATTR_TERMCHAR_EN, VI_TRUE); - viSetAttribute(portHandles[port], VI_ATTR_TERMCHAR, terminator); - *status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_END_IN, - VI_ASRL_END_TERMCHAR); - if (*status > 0) *status = 0; + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return; + } + port->termination = true; + port->terminationChar = terminator; } -void HAL_DisableSerialTermination(HAL_SerialPort port, int32_t* status) { - viSetAttribute(portHandles[port], VI_ATTR_TERMCHAR_EN, VI_FALSE); - *status = - viSetAttribute(portHandles[port], VI_ATTR_ASRL_END_IN, VI_ASRL_END_NONE); - if (*status > 0) *status = 0; -} - -void HAL_SetSerialReadBufferSize(HAL_SerialPort port, int32_t size, - int32_t* status) { - *status = viSetBuf(portHandles[port], VI_READ_BUF, size); - if (*status > 0) *status = 0; -} - -void HAL_SetSerialWriteBufferSize(HAL_SerialPort port, int32_t size, +void HAL_DisableSerialTermination(HAL_SerialPortHandle handle, int32_t* status) { - *status = viSetBuf(portHandles[port], VI_WRITE_BUF, size); - if (*status > 0) *status = 0; + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return; + } + port->termination = false; } -int32_t HAL_GetSerialBytesReceived(HAL_SerialPort port, int32_t* status) { - int32_t bytes = 0; +void HAL_SetSerialReadBufferSize(HAL_SerialPortHandle handle, int32_t size, + int32_t* status) { + // NO OP currently +} - *status = viGetAttribute(portHandles[port], VI_ATTR_ASRL_AVAIL_NUM, &bytes); - if (*status > 0) *status = 0; +void HAL_SetSerialWriteBufferSize(HAL_SerialPortHandle handle, int32_t size, + int32_t* status) { + // NO OP currently +} + +int32_t HAL_GetSerialBytesReceived(HAL_SerialPortHandle handle, + int32_t* status) { + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return -1; + } + int bytes = 0; + int err = ioctl(port->portId, FIONREAD, &bytes); + if (err < 0) { + *status = errno; + } return bytes; } -int32_t HAL_ReadSerial(HAL_SerialPort port, char* buffer, int32_t count, +int32_t HAL_ReadSerial(HAL_SerialPortHandle handle, char* buffer, int32_t count, int32_t* status) { - uint32_t retCount = 0; + // Don't do anything if 0 bytes were requested + if (count == 0) return 0; - *status = - viRead(portHandles[port], (ViPBuf)buffer, count, (ViPUInt32)&retCount); - - if (*status == VI_ERROR_IO || *status == VI_ERROR_ASRL_OVERRUN || - *status == VI_ERROR_ASRL_FRAMING || *status == VI_ERROR_ASRL_PARITY) { - int32_t localStatus = 0; - HAL_ClearSerial(port, &localStatus); + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return -1; } - if (*status == VI_ERROR_TMO || *status > 0) *status = 0; - return static_cast(retCount); + int n = 0, loc = 0; + char buf = '\0'; + std::memset(buffer, '\0', count); + *status = 0; + + do { + n = read(port->portId, &buf, 1); + if (n == 1) { + buffer[loc] = buf; + loc++; + // If buffer is full, return + if (loc == count) { + return loc; + } + // If terminating, and termination was hit return; + if (port->termination && buf == port->terminationChar) { + return loc; + } + } else if (n == -1) { + // ERROR + *status = errno; + return loc; + } else { + // If nothing read, timeout + return loc; + } + } while (true); } -int32_t HAL_WriteSerial(HAL_SerialPort port, const char* buffer, int32_t count, - int32_t* status) { - uint32_t retCount = 0; +int32_t HAL_WriteSerial(HAL_SerialPortHandle handle, const char* buffer, + int32_t count, int32_t* status) { + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return -1; + } - *status = - viWrite(portHandles[port], (ViPBuf)buffer, count, (ViPUInt32)&retCount); - - if (*status > 0) *status = 0; - return static_cast(retCount); + int written = 0, spot = 0; + do { + written = write(port->portId, buffer + spot, count - spot); + if (written < 0) { + *status = errno; + return spot; + } + spot += written; + } while (spot < count); + return spot; } -void HAL_FlushSerial(HAL_SerialPort port, int32_t* status) { - *status = viFlush(portHandles[port], VI_WRITE_BUF); - if (*status > 0) *status = 0; +void HAL_FlushSerial(HAL_SerialPortHandle handle, int32_t* status) { + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return; + } + int err = tcdrain(port->portId); + if (err < 0) { + *status = errno; + } } - -void HAL_ClearSerial(HAL_SerialPort port, int32_t* status) { - *status = viClear(portHandles[port]); - if (*status > 0) *status = 0; +void HAL_ClearSerial(HAL_SerialPortHandle handle, int32_t* status) { + auto port = serialPortHandles->Get(handle); + if (!port) { + *status = HAL_HANDLE_ERROR; + return; + } + int err = tcflush(port->portId, TCIOFLUSH); + if (err < 0) { + *status = errno; + } } - -void HAL_CloseSerial(HAL_SerialPort port, int32_t* status) { - *status = viClose(portHandles[port]); - if (*status > 0) *status = 0; -} - } // extern "C" diff --git a/hal/src/main/native/cpp/jni/SerialPortJNI.cpp b/hal/src/main/native/cpp/jni/SerialPortJNI.cpp index d127e740a0..9fe9d92a33 100644 --- a/hal/src/main/native/cpp/jni/SerialPortJNI.cpp +++ b/hal/src/main/native/cpp/jni/SerialPortJNI.cpp @@ -23,185 +23,197 @@ extern "C" { /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialInitializePort - * Signature: (B)V + * Signature: (B)I */ -JNIEXPORT void JNICALL +JNIEXPORT jint JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialInitializePort (JNIEnv* env, jclass, jbyte port) { int32_t status = 0; - HAL_InitializeSerialPort(static_cast(port), &status); + auto handle = + HAL_InitializeSerialPort(static_cast(port), &status); CheckStatusForceThrow(env, status); + return static_cast(handle); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialInitializePortDirect - * Signature: (BLjava/lang/String;)V + * Signature: (BLjava/lang/String;)I */ -JNIEXPORT void JNICALL +JNIEXPORT jint JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialInitializePortDirect (JNIEnv* env, jclass, jbyte port, jstring portName) { JStringRef portNameRef{env, portName}; int32_t status = 0; - HAL_InitializeSerialPortDirect(static_cast(port), - portNameRef.c_str(), &status); + auto handle = HAL_InitializeSerialPortDirect( + static_cast(port), portNameRef.c_str(), &status); CheckStatusForceThrow(env, status); + return static_cast(handle); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialSetBaudRate - * Signature: (BI)V + * Signature: (II)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialSetBaudRate - (JNIEnv* env, jclass, jbyte port, jint rate) + (JNIEnv* env, jclass, jint handle, jint rate) { int32_t status = 0; - HAL_SetSerialBaudRate(static_cast(port), rate, &status); + HAL_SetSerialBaudRate(static_cast(handle), rate, + &status); CheckStatus(env, status); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialSetDataBits - * Signature: (BB)V + * Signature: (IB)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialSetDataBits - (JNIEnv* env, jclass, jbyte port, jbyte bits) + (JNIEnv* env, jclass, jint handle, jbyte bits) { int32_t status = 0; - HAL_SetSerialDataBits(static_cast(port), bits, &status); + HAL_SetSerialDataBits(static_cast(handle), bits, + &status); CheckStatus(env, status); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialSetParity - * Signature: (BB)V + * Signature: (IB)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialSetParity - (JNIEnv* env, jclass, jbyte port, jbyte parity) + (JNIEnv* env, jclass, jint handle, jbyte parity) { int32_t status = 0; - HAL_SetSerialParity(static_cast(port), parity, &status); + HAL_SetSerialParity(static_cast(handle), parity, + &status); CheckStatus(env, status); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialSetStopBits - * Signature: (BB)V + * Signature: (IB)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialSetStopBits - (JNIEnv* env, jclass, jbyte port, jbyte bits) + (JNIEnv* env, jclass, jint handle, jbyte bits) { int32_t status = 0; - HAL_SetSerialStopBits(static_cast(port), bits, &status); + HAL_SetSerialStopBits(static_cast(handle), bits, + &status); CheckStatus(env, status); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialSetWriteMode - * Signature: (BB)V + * Signature: (IB)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialSetWriteMode - (JNIEnv* env, jclass, jbyte port, jbyte mode) + (JNIEnv* env, jclass, jint handle, jbyte mode) { int32_t status = 0; - HAL_SetSerialWriteMode(static_cast(port), mode, &status); + HAL_SetSerialWriteMode(static_cast(handle), mode, + &status); CheckStatus(env, status); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialSetFlowControl - * Signature: (BB)V + * Signature: (IB)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialSetFlowControl - (JNIEnv* env, jclass, jbyte port, jbyte flow) + (JNIEnv* env, jclass, jint handle, jbyte flow) { int32_t status = 0; - HAL_SetSerialFlowControl(static_cast(port), flow, &status); + HAL_SetSerialFlowControl(static_cast(handle), flow, + &status); CheckStatus(env, status); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialSetTimeout - * Signature: (BD)V + * Signature: (ID)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialSetTimeout - (JNIEnv* env, jclass, jbyte port, jdouble timeout) + (JNIEnv* env, jclass, jint handle, jdouble timeout) { int32_t status = 0; - HAL_SetSerialTimeout(static_cast(port), timeout, &status); + HAL_SetSerialTimeout(static_cast(handle), timeout, + &status); CheckStatus(env, status); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialEnableTermination - * Signature: (BC)V + * Signature: (IC)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialEnableTermination - (JNIEnv* env, jclass, jbyte port, jchar terminator) + (JNIEnv* env, jclass, jint handle, jchar terminator) { int32_t status = 0; - HAL_EnableSerialTermination(static_cast(port), terminator, - &status); + HAL_EnableSerialTermination(static_cast(handle), + terminator, &status); CheckStatus(env, status); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialDisableTermination - * Signature: (B)V + * Signature: (I)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialDisableTermination - (JNIEnv* env, jclass, jbyte port) + (JNIEnv* env, jclass, jint handle) { int32_t status = 0; - HAL_DisableSerialTermination(static_cast(port), &status); + HAL_DisableSerialTermination(static_cast(handle), + &status); CheckStatus(env, status); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialSetReadBufferSize - * Signature: (BI)V + * Signature: (II)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialSetReadBufferSize - (JNIEnv* env, jclass, jbyte port, jint size) + (JNIEnv* env, jclass, jint handle, jint size) { int32_t status = 0; - HAL_SetSerialReadBufferSize(static_cast(port), size, &status); + HAL_SetSerialReadBufferSize(static_cast(handle), size, + &status); CheckStatus(env, status); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialSetWriteBufferSize - * Signature: (BI)V + * Signature: (II)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialSetWriteBufferSize - (JNIEnv* env, jclass, jbyte port, jint size) + (JNIEnv* env, jclass, jint handle, jint size) { int32_t status = 0; - HAL_SetSerialWriteBufferSize(static_cast(port), size, + HAL_SetSerialWriteBufferSize(static_cast(handle), size, &status); CheckStatus(env, status); } @@ -209,15 +221,15 @@ Java_edu_wpi_first_hal_SerialPortJNI_serialSetWriteBufferSize /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialGetBytesReceived - * Signature: (B)I + * Signature: (I)I */ JNIEXPORT jint JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialGetBytesReceived - (JNIEnv* env, jclass, jbyte port) + (JNIEnv* env, jclass, jint handle) { int32_t status = 0; - jint retVal = - HAL_GetSerialBytesReceived(static_cast(port), &status); + jint retVal = HAL_GetSerialBytesReceived( + static_cast(handle), &status); CheckStatus(env, status); return retVal; } @@ -225,16 +237,16 @@ Java_edu_wpi_first_hal_SerialPortJNI_serialGetBytesReceived /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialRead - * Signature: (B[BI)I + * Signature: (I[BI)I */ JNIEXPORT jint JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialRead - (JNIEnv* env, jclass, jbyte port, jbyteArray dataReceived, jint size) + (JNIEnv* env, jclass, jint handle, jbyteArray dataReceived, jint size) { wpi::SmallVector recvBuf; recvBuf.resize(size); int32_t status = 0; - jint retVal = HAL_ReadSerial(static_cast(port), + jint retVal = HAL_ReadSerial(static_cast(handle), recvBuf.data(), size, &status); env->SetByteArrayRegion(dataReceived, 0, size, reinterpret_cast(recvBuf.data())); @@ -245,15 +257,15 @@ Java_edu_wpi_first_hal_SerialPortJNI_serialRead /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialWrite - * Signature: (B[BI)I + * Signature: (I[BI)I */ JNIEXPORT jint JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialWrite - (JNIEnv* env, jclass, jbyte port, jbyteArray dataToSend, jint size) + (JNIEnv* env, jclass, jint handle, jbyteArray dataToSend, jint size) { int32_t status = 0; jint retVal = - HAL_WriteSerial(static_cast(port), + HAL_WriteSerial(static_cast(handle), reinterpret_cast( JByteArrayRef(env, dataToSend).array().data()), size, &status); @@ -264,42 +276,42 @@ Java_edu_wpi_first_hal_SerialPortJNI_serialWrite /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialFlush - * Signature: (B)V + * Signature: (I)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialFlush - (JNIEnv* env, jclass, jbyte port) + (JNIEnv* env, jclass, jint handle) { int32_t status = 0; - HAL_FlushSerial(static_cast(port), &status); + HAL_FlushSerial(static_cast(handle), &status); CheckStatus(env, status); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialClear - * Signature: (B)V + * Signature: (I)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialClear - (JNIEnv* env, jclass, jbyte port) + (JNIEnv* env, jclass, jint handle) { int32_t status = 0; - HAL_ClearSerial(static_cast(port), &status); + HAL_ClearSerial(static_cast(handle), &status); CheckStatus(env, status); } /* * Class: edu_wpi_first_hal_SerialPortJNI * Method: serialClose - * Signature: (B)V + * Signature: (I)V */ JNIEXPORT void JNICALL Java_edu_wpi_first_hal_SerialPortJNI_serialClose - (JNIEnv* env, jclass, jbyte port) + (JNIEnv* env, jclass, jint handle) { int32_t status = 0; - HAL_CloseSerial(static_cast(port), &status); + HAL_CloseSerial(static_cast(handle), &status); CheckStatus(env, status); } diff --git a/hal/src/main/native/include/hal/SerialPort.h b/hal/src/main/native/include/hal/SerialPort.h index c2fd1051cd..226a2cb211 100644 --- a/hal/src/main/native/include/hal/SerialPort.h +++ b/hal/src/main/native/include/hal/SerialPort.h @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */ +/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ @@ -38,39 +38,51 @@ extern "C" { * * @param port the serial port to initialize */ -void HAL_InitializeSerialPort(HAL_SerialPort port, int32_t* status); +HAL_SerialPortHandle HAL_InitializeSerialPort(HAL_SerialPort port, + int32_t* status); /** * Initializes a serial port with a direct name. * - * This name is the VISA name for a specific port (find this in the web dash). + * This name is the /dev name for a specific port. * Note these are not always consistent between roboRIO reboots. * * @param port the serial port to initialize - * @param portName the VISA port name + * @param portName the dev port name */ -void HAL_InitializeSerialPortDirect(HAL_SerialPort port, const char* portName, - int32_t* status); +HAL_SerialPortHandle HAL_InitializeSerialPortDirect(HAL_SerialPort port, + const char* portName, + int32_t* status); + +/** + * Gets the raw serial port file descriptor from a handle. + * + * @param handle the serial port handle + * @return the raw port descriptor + */ +int HAL_GetSerialFD(HAL_SerialPortHandle handle, int32_t* status); /** * Sets the baud rate of a serial port. * * Any value between 0 and 0xFFFFFFFF may be used. Default is 9600. * - * @param port the serial port - * @param baud the baud rate to set + * @param handle the serial port handle + * @param baud the baud rate to set */ -void HAL_SetSerialBaudRate(HAL_SerialPort port, int32_t baud, int32_t* status); +void HAL_SetSerialBaudRate(HAL_SerialPortHandle handle, int32_t baud, + int32_t* status); /** * Sets the number of data bits on a serial port. * * Defaults to 8. * - * @param port the serial port - * @param bits the number of data bits (5-8) + * @param handle the serial port handle + * @param bits the number of data bits (5-8) */ -void HAL_SetSerialDataBits(HAL_SerialPort port, int32_t bits, int32_t* status); +void HAL_SetSerialDataBits(HAL_SerialPortHandle handle, int32_t bits, + int32_t* status); /** * Sets the number of parity bits on a serial port. @@ -82,10 +94,11 @@ void HAL_SetSerialDataBits(HAL_SerialPort port, int32_t bits, int32_t* status); * 3: Mark - Means exists and always 1 * 4: Space - Means exists and always 0 * - * @param port the serial port + * @param handle the serial port handle * @param parity the parity bit mode (see remarks for valid values) */ -void HAL_SetSerialParity(HAL_SerialPort port, int32_t parity, int32_t* status); +void HAL_SetSerialParity(HAL_SerialPortHandle handle, int32_t parity, + int32_t* status); /** * Sets the number of stop bits on a serial port. @@ -95,10 +108,10 @@ void HAL_SetSerialParity(HAL_SerialPort port, int32_t parity, int32_t* status); * 15: One and a half stop bits * 20: Two stop bits * - * @param port the serial port + * @param handle the serial port handle * @param stopBits the stop bit value (see remarks for valid values) */ -void HAL_SetSerialStopBits(HAL_SerialPort port, int32_t stopBits, +void HAL_SetSerialStopBits(HAL_SerialPortHandle handle, int32_t stopBits, int32_t* status); /** @@ -108,10 +121,11 @@ void HAL_SetSerialStopBits(HAL_SerialPort port, int32_t stopBits, * 1: Flush on access * 2: Flush when full (default) * - * @param port the serial port - * @param mode the mode to set (see remarks for valid values) + * @param handle the serial port handle + * @param mode the mode to set (see remarks for valid values) */ -void HAL_SetSerialWriteMode(HAL_SerialPort port, int32_t mode, int32_t* status); +void HAL_SetSerialWriteMode(HAL_SerialPortHandle handle, int32_t mode, + int32_t* status); /** * Sets the flow control mode of a serial port. @@ -122,63 +136,65 @@ void HAL_SetSerialWriteMode(HAL_SerialPort port, int32_t mode, int32_t* status); * 2: RTS-CTS * 3: DTR-DSR * - * @param port the serial port - * @param flow the mode to set (see remarks for valid values) + * @param handle the serial port handle + * @param flow the mode to set (see remarks for valid values) */ -void HAL_SetSerialFlowControl(HAL_SerialPort port, int32_t flow, +void HAL_SetSerialFlowControl(HAL_SerialPortHandle handle, int32_t flow, int32_t* status); /** * Sets the minimum serial read timeout of a port. * - * @param port the serial port + * @param handle the serial port handle * @param timeout the timeout in milliseconds */ -void HAL_SetSerialTimeout(HAL_SerialPort port, double timeout, int32_t* status); +void HAL_SetSerialTimeout(HAL_SerialPortHandle handle, double timeout, + int32_t* status); /** * Sets the termination character that terminates a read. * * By default this is disabled. * - * @param port the serial port + * @param handle the serial port handle * @param terminator the termination character to set */ -void HAL_EnableSerialTermination(HAL_SerialPort port, char terminator, +void HAL_EnableSerialTermination(HAL_SerialPortHandle handle, char terminator, int32_t* status); /** * Disables a termination character for reads. * - * @param port the serial port + * @param handle the serial port handle */ -void HAL_DisableSerialTermination(HAL_SerialPort port, int32_t* status); +void HAL_DisableSerialTermination(HAL_SerialPortHandle handle, int32_t* status); /** * Sets the size of the read buffer. * - * @param port the serial port - * @param size the read buffer size + * @param handle the serial port handle + * @param size the read buffer size */ -void HAL_SetSerialReadBufferSize(HAL_SerialPort port, int32_t size, +void HAL_SetSerialReadBufferSize(HAL_SerialPortHandle handle, int32_t size, int32_t* status); /** * Sets the size of the write buffer. * - * @param port the serial port - * @param size the write buffer size + * @param handle the serial port handle + * @param size the write buffer size */ -void HAL_SetSerialWriteBufferSize(HAL_SerialPort port, int32_t size, +void HAL_SetSerialWriteBufferSize(HAL_SerialPortHandle handle, int32_t size, int32_t* status); /** * Gets the number of bytes currently in the read buffer. * - * @param port the serial port - * @return the number of bytes in the read buffer + * @param handle the serial port handle + * @return the number of bytes in the read buffer */ -int32_t HAL_GetSerialBytesReceived(HAL_SerialPort port, int32_t* status); +int32_t HAL_GetSerialBytesReceived(HAL_SerialPortHandle handle, + int32_t* status); /** * Reads data from the serial port. @@ -186,44 +202,44 @@ int32_t HAL_GetSerialBytesReceived(HAL_SerialPort port, int32_t* status); * Will wait for either timeout (if set), the termination char (if set), or the * count to be full. Whichever one comes first. * - * @param port the serial port - * @param count the number of bytes maximum to read - * @return the number of bytes actually read + * @param handle the serial port handle + * @param count the number of bytes maximum to read + * @return the number of bytes actually read */ -int32_t HAL_ReadSerial(HAL_SerialPort port, char* buffer, int32_t count, +int32_t HAL_ReadSerial(HAL_SerialPortHandle handle, char* buffer, int32_t count, int32_t* status); /** * Writes data to the serial port. * - * @param port the serial port + * @param handle the serial port handle * @param buffer the buffer to write * @param count the number of bytes to write from the buffer * @return the number of bytes actually written */ -int32_t HAL_WriteSerial(HAL_SerialPort port, const char* buffer, int32_t count, - int32_t* status); +int32_t HAL_WriteSerial(HAL_SerialPortHandle handle, const char* buffer, + int32_t count, int32_t* status); /** * Flushes the serial write buffer out to the port. * - * @param port the serial port + * @param handle the serial port handle */ -void HAL_FlushSerial(HAL_SerialPort port, int32_t* status); +void HAL_FlushSerial(HAL_SerialPortHandle handle, int32_t* status); /** * Clears the receive buffer of the serial port. * - * @param port the serial port + * @param handle the serial port handle */ -void HAL_ClearSerial(HAL_SerialPort port, int32_t* status); +void HAL_ClearSerial(HAL_SerialPortHandle handle, int32_t* status); /** * Closes a serial port. * - * @param port the serial port to close + * @param handle the serial port handle to close */ -void HAL_CloseSerial(HAL_SerialPort port, int32_t* status); +void HAL_CloseSerial(HAL_SerialPortHandle handle, int32_t* status); #ifdef __cplusplus } // extern "C" #endif diff --git a/hal/src/main/native/include/hal/Types.h b/hal/src/main/native/include/hal/Types.h index 45bb540964..3d3065627e 100644 --- a/hal/src/main/native/include/hal/Types.h +++ b/hal/src/main/native/include/hal/Types.h @@ -49,6 +49,8 @@ typedef HAL_Handle HAL_RelayHandle; typedef HAL_Handle HAL_SolenoidHandle; +typedef HAL_Handle HAL_SerialPortHandle; + typedef HAL_Handle HAL_CANHandle; typedef HAL_CANHandle HAL_PDPHandle; diff --git a/hal/src/main/native/include/hal/handles/HandlesInternal.h b/hal/src/main/native/include/hal/handles/HandlesInternal.h index 85b349347c..5340d82fcf 100644 --- a/hal/src/main/native/include/hal/handles/HandlesInternal.h +++ b/hal/src/main/native/include/hal/handles/HandlesInternal.h @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */ +/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ @@ -65,6 +65,7 @@ enum class HAL_HandleEnum { Vendor = 17, SimulationJni = 18, CAN = 19, + SerialPort = 20, }; /** diff --git a/hal/src/main/native/sim/SerialPort.cpp b/hal/src/main/native/sim/SerialPort.cpp index bc085667f7..2df2ebef6e 100644 --- a/hal/src/main/native/sim/SerialPort.cpp +++ b/hal/src/main/native/sim/SerialPort.cpp @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */ +/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ @@ -16,62 +16,72 @@ void InitializeSerialPort() {} } // namespace hal extern "C" { -void HAL_InitializeSerialPort(HAL_SerialPort port, int32_t* status) { +HAL_SerialPortHandle HAL_InitializeSerialPort(HAL_SerialPort port, + int32_t* status) { hal::init::CheckInit(); + return HAL_kInvalidHandle; } -void HAL_InitializeSerialPortDirect(HAL_SerialPort port, const char* portName, - int32_t* status) {} - -void HAL_SetSerialBaudRate(HAL_SerialPort port, int32_t baud, int32_t* status) { +HAL_SerialPortHandle HAL_InitializeSerialPortDirect(HAL_SerialPort port, + const char* portName, + int32_t* status) { + hal::init::CheckInit(); + return HAL_kInvalidHandle; } -void HAL_SetSerialDataBits(HAL_SerialPort port, int32_t bits, int32_t* status) { -} +int HAL_GetSerialFD(HAL_SerialPortHandle handle, int32_t* status) { return -1; } -void HAL_SetSerialParity(HAL_SerialPort port, int32_t parity, int32_t* status) { -} - -void HAL_SetSerialStopBits(HAL_SerialPort port, int32_t stopBits, +void HAL_SetSerialBaudRate(HAL_SerialPortHandle handle, int32_t baud, int32_t* status) {} -void HAL_SetSerialWriteMode(HAL_SerialPort port, int32_t mode, +void HAL_SetSerialDataBits(HAL_SerialPortHandle handle, int32_t bits, + int32_t* status) {} + +void HAL_SetSerialParity(HAL_SerialPortHandle handle, int32_t parity, + int32_t* status) {} + +void HAL_SetSerialStopBits(HAL_SerialPortHandle handle, int32_t stopBits, + int32_t* status) {} + +void HAL_SetSerialWriteMode(HAL_SerialPortHandle handle, int32_t mode, int32_t* status) {} -void HAL_SetSerialFlowControl(HAL_SerialPort port, int32_t flow, +void HAL_SetSerialFlowControl(HAL_SerialPortHandle handle, int32_t flow, int32_t* status) {} -void HAL_SetSerialTimeout(HAL_SerialPort port, double timeout, +void HAL_SetSerialTimeout(HAL_SerialPortHandle handle, double timeout, int32_t* status) {} -void HAL_EnableSerialTermination(HAL_SerialPort port, char terminator, +void HAL_EnableSerialTermination(HAL_SerialPortHandle handle, char terminator, int32_t* status) {} -void HAL_DisableSerialTermination(HAL_SerialPort port, int32_t* status) {} - -void HAL_SetSerialReadBufferSize(HAL_SerialPort port, int32_t size, - int32_t* status) {} - -void HAL_SetSerialWriteBufferSize(HAL_SerialPort port, int32_t size, +void HAL_DisableSerialTermination(HAL_SerialPortHandle handle, int32_t* status) {} -int32_t HAL_GetSerialBytesReceived(HAL_SerialPort port, int32_t* status) { +void HAL_SetSerialReadBufferSize(HAL_SerialPortHandle handle, int32_t size, + int32_t* status) {} + +void HAL_SetSerialWriteBufferSize(HAL_SerialPortHandle handle, int32_t size, + int32_t* status) {} + +int32_t HAL_GetSerialBytesReceived(HAL_SerialPortHandle handle, + int32_t* status) { return 0; } -int32_t HAL_ReadSerial(HAL_SerialPort port, char* buffer, int32_t count, +int32_t HAL_ReadSerial(HAL_SerialPortHandle handle, char* buffer, int32_t count, int32_t* status) { return 0; } -int32_t HAL_WriteSerial(HAL_SerialPort port, const char* buffer, int32_t count, - int32_t* status) { +int32_t HAL_WriteSerial(HAL_SerialPortHandle handle, const char* buffer, + int32_t count, int32_t* status) { return 0; } -void HAL_FlushSerial(HAL_SerialPort port, int32_t* status) {} +void HAL_FlushSerial(HAL_SerialPortHandle handle, int32_t* status) {} -void HAL_ClearSerial(HAL_SerialPort port, int32_t* status) {} +void HAL_ClearSerial(HAL_SerialPortHandle handle, int32_t* status) {} -void HAL_CloseSerial(HAL_SerialPort port, int32_t* status) {} +void HAL_CloseSerial(HAL_SerialPortHandle handle, int32_t* status) {} } // extern "C" diff --git a/wpilibc/src/main/native/cpp/SerialPort.cpp b/wpilibc/src/main/native/cpp/SerialPort.cpp index a399f4d7e8..46e02c8ae2 100644 --- a/wpilibc/src/main/native/cpp/SerialPort.cpp +++ b/wpilibc/src/main/native/cpp/SerialPort.cpp @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */ +/* Copyright (c) 2008-2019 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ @@ -12,9 +12,6 @@ #include #include -// static ViStatus _VI_FUNCH ioCompleteHandler (ViSession vi, ViEventType -// eventType, ViEvent event, ViAddr userHandle); - using namespace frc; SerialPort::SerialPort(int baudRate, Port port, int dataBits, @@ -22,19 +19,18 @@ SerialPort::SerialPort(int baudRate, Port port, int dataBits, SerialPort::StopBits stopBits) { int32_t status = 0; - m_port = port; - - HAL_InitializeSerialPort(static_cast(port), &status); + m_portHandle = + HAL_InitializeSerialPort(static_cast(port), &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); // Don't continue if initialization failed if (status < 0) return; - HAL_SetSerialBaudRate(static_cast(port), baudRate, &status); + HAL_SetSerialBaudRate(m_portHandle, baudRate, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); - HAL_SetSerialDataBits(static_cast(port), dataBits, &status); + HAL_SetSerialDataBits(m_portHandle, dataBits, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); - HAL_SetSerialParity(static_cast(port), parity, &status); + HAL_SetSerialParity(m_portHandle, parity, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); - HAL_SetSerialStopBits(static_cast(port), stopBits, &status); + HAL_SetSerialStopBits(m_portHandle, stopBits, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); // Set the default timeout to 5 seconds. @@ -43,11 +39,7 @@ SerialPort::SerialPort(int baudRate, Port port, int dataBits, // Don't wait until the buffer is full to transmit. SetWriteBufferMode(kFlushOnAccess); - EnableTermination(); - - // viInstallHandler(m_portHandle, VI_EVENT_IO_COMPLETION, ioCompleteHandler, - // this); - // viEnableEvent(m_portHandle, VI_EVENT_IO_COMPLETION, VI_HNDLR, VI_NULL); + DisableTermination(); HAL_Report(HALUsageReporting::kResourceType_SerialPort, 0); } @@ -57,23 +49,21 @@ SerialPort::SerialPort(int baudRate, const wpi::Twine& portName, Port port, SerialPort::StopBits stopBits) { int32_t status = 0; - m_port = port; - wpi::SmallVector buf; const char* portNameC = portName.toNullTerminatedStringRef(buf).data(); - HAL_InitializeSerialPortDirect(static_cast(port), portNameC, - &status); + m_portHandle = HAL_InitializeSerialPortDirect( + static_cast(port), portNameC, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); // Don't continue if initialization failed if (status < 0) return; - HAL_SetSerialBaudRate(static_cast(port), baudRate, &status); + HAL_SetSerialBaudRate(m_portHandle, baudRate, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); - HAL_SetSerialDataBits(static_cast(port), dataBits, &status); + HAL_SetSerialDataBits(m_portHandle, dataBits, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); - HAL_SetSerialParity(static_cast(port), parity, &status); + HAL_SetSerialParity(m_portHandle, parity, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); - HAL_SetSerialStopBits(static_cast(port), stopBits, &status); + HAL_SetSerialStopBits(m_portHandle, stopBits, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); // Set the default timeout to 5 seconds. @@ -82,72 +72,45 @@ SerialPort::SerialPort(int baudRate, const wpi::Twine& portName, Port port, // Don't wait until the buffer is full to transmit. SetWriteBufferMode(kFlushOnAccess); - EnableTermination(); - - // viInstallHandler(m_portHandle, VI_EVENT_IO_COMPLETION, ioCompleteHandler, - // this); - // viEnableEvent(m_portHandle, VI_EVENT_IO_COMPLETION, VI_HNDLR, VI_NULL); + DisableTermination(); HAL_Report(HALUsageReporting::kResourceType_SerialPort, 0); } SerialPort::~SerialPort() { int32_t status = 0; - HAL_CloseSerial(static_cast(m_port), &status); + HAL_CloseSerial(m_portHandle, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } -SerialPort::SerialPort(SerialPort&& rhs) - : ErrorBase(std::move(rhs)), - m_resourceManagerHandle(std::move(rhs.m_resourceManagerHandle)), - m_portHandle(std::move(rhs.m_portHandle)), - m_consoleModeEnabled(std::move(rhs.m_consoleModeEnabled)) { - std::swap(m_port, rhs.m_port); -} - -SerialPort& SerialPort::operator=(SerialPort&& rhs) { - ErrorBase::operator=(std::move(rhs)); - - m_resourceManagerHandle = std::move(rhs.m_resourceManagerHandle); - m_portHandle = std::move(rhs.m_portHandle); - m_consoleModeEnabled = std::move(rhs.m_consoleModeEnabled); - std::swap(m_port, rhs.m_port); - - return *this; -} - void SerialPort::SetFlowControl(SerialPort::FlowControl flowControl) { int32_t status = 0; - HAL_SetSerialFlowControl(static_cast(m_port), flowControl, - &status); + HAL_SetSerialFlowControl(m_portHandle, flowControl, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } void SerialPort::EnableTermination(char terminator) { int32_t status = 0; - HAL_EnableSerialTermination(static_cast(m_port), terminator, - &status); + HAL_EnableSerialTermination(m_portHandle, terminator, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } void SerialPort::DisableTermination() { int32_t status = 0; - HAL_DisableSerialTermination(static_cast(m_port), &status); + HAL_DisableSerialTermination(m_portHandle, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } int SerialPort::GetBytesReceived() { int32_t status = 0; - int retVal = - HAL_GetSerialBytesReceived(static_cast(m_port), &status); + int retVal = HAL_GetSerialBytesReceived(m_portHandle, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); return retVal; } int SerialPort::Read(char* buffer, int count) { int32_t status = 0; - int retVal = HAL_ReadSerial(static_cast(m_port), buffer, - count, &status); + int retVal = HAL_ReadSerial(m_portHandle, buffer, count, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); return retVal; } @@ -158,46 +121,44 @@ int SerialPort::Write(const char* buffer, int count) { int SerialPort::Write(wpi::StringRef buffer) { int32_t status = 0; - int retVal = HAL_WriteSerial(static_cast(m_port), - buffer.data(), buffer.size(), &status); + int retVal = + HAL_WriteSerial(m_portHandle, buffer.data(), buffer.size(), &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); return retVal; } void SerialPort::SetTimeout(double timeout) { int32_t status = 0; - HAL_SetSerialTimeout(static_cast(m_port), timeout, &status); + HAL_SetSerialTimeout(m_portHandle, timeout, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } void SerialPort::SetReadBufferSize(int size) { int32_t status = 0; - HAL_SetSerialReadBufferSize(static_cast(m_port), size, - &status); + HAL_SetSerialReadBufferSize(m_portHandle, size, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } void SerialPort::SetWriteBufferSize(int size) { int32_t status = 0; - HAL_SetSerialWriteBufferSize(static_cast(m_port), size, - &status); + HAL_SetSerialWriteBufferSize(m_portHandle, size, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } void SerialPort::SetWriteBufferMode(SerialPort::WriteBufferMode mode) { int32_t status = 0; - HAL_SetSerialWriteMode(static_cast(m_port), mode, &status); + HAL_SetSerialWriteMode(m_portHandle, mode, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } void SerialPort::Flush() { int32_t status = 0; - HAL_FlushSerial(static_cast(m_port), &status); + HAL_FlushSerial(m_portHandle, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } void SerialPort::Reset() { int32_t status = 0; - HAL_ClearSerial(static_cast(m_port), &status); + HAL_ClearSerial(m_portHandle, &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } diff --git a/wpilibc/src/main/native/include/frc/SerialPort.h b/wpilibc/src/main/native/include/frc/SerialPort.h index e9e38ef296..f9edb84240 100644 --- a/wpilibc/src/main/native/include/frc/SerialPort.h +++ b/wpilibc/src/main/native/include/frc/SerialPort.h @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */ +/* Copyright (c) 2008-2019 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -73,6 +74,9 @@ class SerialPort : public ErrorBase { /** * Create an instance of a Serial Port class. * + * Prefer to use the constructor that doesn't take a port name, but in some + * cases the automatic detection might not work correctly. + * * @param baudRate The baud rate to configure the serial port. * @param port The physical port to use * @param portName The direct port name to use @@ -82,15 +86,14 @@ class SerialPort : public ErrorBase { * @param stopBits The number of stop bits to use as defined by the enum * StopBits. */ - WPI_DEPRECATED("Will be removed for 2020") SerialPort(int baudRate, const wpi::Twine& portName, Port port = kOnboard, int dataBits = 8, Parity parity = kParity_None, StopBits stopBits = kStopBits_One); ~SerialPort(); - SerialPort(SerialPort&& rhs); - SerialPort& operator=(SerialPort&& rhs); + SerialPort(SerialPort&& rhs) = default; + SerialPort& operator=(SerialPort&& rhs) = default; /** * Set the type of flow control to enable on this port. @@ -214,10 +217,7 @@ class SerialPort : public ErrorBase { void Reset(); private: - int m_resourceManagerHandle = 0; - int m_portHandle = 0; - bool m_consoleModeEnabled = false; - Port m_port = kOnboard; + hal::Handle m_portHandle; }; } // namespace frc diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/SerialPort.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/SerialPort.java index 4c392f54e8..9cf0dcb818 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/SerialPort.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/SerialPort.java @@ -14,19 +14,11 @@ import edu.wpi.first.hal.HAL; import edu.wpi.first.hal.SerialPortJNI; /** - * Driver for the RS-232 serial port on the roboRIO. - * - *

The current implementation uses the VISA formatted I/O mode. This means that all traffic goes - * through the formatted buffers. This allows the intermingled use of print(), readString(), and the - * raw buffer accessors read() and write(). - * - *

More information can be found in the NI-VISA User Manual here: http://www.ni - * .com/pdf/manuals/370423a.pdf and the NI-VISA Programmer's Reference Manual here: - * http://www.ni.com/pdf/manuals/370132c.pdf + * Driver for the serial ports (USB, MXP, Onboard) on the roboRIO. */ @SuppressWarnings("PMD.TooManyMethods") public class SerialPort implements AutoCloseable { - private byte m_port; + private int m_portHandle; public enum Port { kOnboard(0), kMXP(1), kUSB(2), kUSB1(2), kUSB2(3); @@ -82,7 +74,7 @@ public class SerialPort implements AutoCloseable { } /** - * Represents which type of buffer mode to use when writing to a serial m_port. + * Represents which type of buffer mode to use when writing to a serial port. */ public enum WriteBufferMode { kFlushOnAccess(1), kFlushWhenFull(2); @@ -98,6 +90,9 @@ public class SerialPort implements AutoCloseable { /** * Create an instance of a Serial Port class. * + *

Prefer to use the constructor that doesn't take a port name, but in some + * cases the automatic detection might not work correctly. + * * @param baudRate The baud rate to configure the serial port. * @param port The Serial port to use * @param portName The direct portName to use @@ -106,16 +101,13 @@ public class SerialPort implements AutoCloseable { * @param stopBits The number of stop bits to use as defined by the enum StopBits. * @deprecated Will be removed for 2019 */ - @Deprecated public SerialPort(final int baudRate, String portName, Port port, final int dataBits, Parity parity, StopBits stopBits) { - m_port = (byte) port.value; - - SerialPortJNI.serialInitializePortDirect(m_port, portName); - SerialPortJNI.serialSetBaudRate(m_port, baudRate); - SerialPortJNI.serialSetDataBits(m_port, (byte) dataBits); - SerialPortJNI.serialSetParity(m_port, (byte) parity.value); - SerialPortJNI.serialSetStopBits(m_port, (byte) stopBits.value); + m_portHandle = SerialPortJNI.serialInitializePortDirect((byte) port.value, portName); + SerialPortJNI.serialSetBaudRate(m_portHandle, baudRate); + SerialPortJNI.serialSetDataBits(m_portHandle, (byte) dataBits); + SerialPortJNI.serialSetParity(m_portHandle, (byte) parity.value); + SerialPortJNI.serialSetStopBits(m_portHandle, (byte) stopBits.value); // Set the default read buffer size to 1 to return bytes immediately setReadBufferSize(1); @@ -142,13 +134,11 @@ public class SerialPort implements AutoCloseable { */ public SerialPort(final int baudRate, Port port, final int dataBits, Parity parity, StopBits stopBits) { - m_port = (byte) port.value; - - SerialPortJNI.serialInitializePort(m_port); - SerialPortJNI.serialSetBaudRate(m_port, baudRate); - SerialPortJNI.serialSetDataBits(m_port, (byte) dataBits); - SerialPortJNI.serialSetParity(m_port, (byte) parity.value); - SerialPortJNI.serialSetStopBits(m_port, (byte) stopBits.value); + m_portHandle = SerialPortJNI.serialInitializePort((byte) port.value); + SerialPortJNI.serialSetBaudRate(m_portHandle, baudRate); + SerialPortJNI.serialSetDataBits(m_portHandle, (byte) dataBits); + SerialPortJNI.serialSetParity(m_portHandle, (byte) parity.value); + SerialPortJNI.serialSetStopBits(m_portHandle, (byte) stopBits.value); // Set the default read buffer size to 1 to return bytes immediately setReadBufferSize(1); @@ -197,7 +187,7 @@ public class SerialPort implements AutoCloseable { @Override public void close() { - SerialPortJNI.serialClose(m_port); + SerialPortJNI.serialClose(m_portHandle); } /** @@ -208,7 +198,7 @@ public class SerialPort implements AutoCloseable { * @param flowControl the FlowControl m_value to use */ public void setFlowControl(FlowControl flowControl) { - SerialPortJNI.serialSetFlowControl(m_port, (byte) flowControl.value); + SerialPortJNI.serialSetFlowControl(m_portHandle, (byte) flowControl.value); } /** @@ -221,7 +211,7 @@ public class SerialPort implements AutoCloseable { * @param terminator The character to use for termination. */ public void enableTermination(char terminator) { - SerialPortJNI.serialEnableTermination(m_port, terminator); + SerialPortJNI.serialEnableTermination(m_portHandle, terminator); } /** @@ -241,7 +231,7 @@ public class SerialPort implements AutoCloseable { * Disable termination behavior. */ public void disableTermination() { - SerialPortJNI.serialDisableTermination(m_port); + SerialPortJNI.serialDisableTermination(m_portHandle); } /** @@ -250,7 +240,7 @@ public class SerialPort implements AutoCloseable { * @return The number of bytes available to read. */ public int getBytesReceived() { - return SerialPortJNI.serialGetBytesReceived(m_port); + return SerialPortJNI.serialGetBytesReceived(m_portHandle); } /** @@ -281,7 +271,7 @@ public class SerialPort implements AutoCloseable { */ public byte[] read(final int count) { byte[] dataReceivedBuffer = new byte[count]; - int gotten = SerialPortJNI.serialRead(m_port, dataReceivedBuffer, count); + int gotten = SerialPortJNI.serialRead(m_portHandle, dataReceivedBuffer, count); if (gotten == count) { return dataReceivedBuffer; } @@ -301,7 +291,7 @@ public class SerialPort implements AutoCloseable { if (buffer.length < count) { throw new IllegalArgumentException("buffer is too small, must be at least " + count); } - return SerialPortJNI.serialWrite(m_port, buffer, count); + return SerialPortJNI.serialWrite(m_portHandle, buffer, count); } /** @@ -323,7 +313,7 @@ public class SerialPort implements AutoCloseable { * @param timeout The number of seconds to to wait for I/O. */ public void setTimeout(double timeout) { - SerialPortJNI.serialSetTimeout(m_port, timeout); + SerialPortJNI.serialSetTimeout(m_portHandle, timeout); } /** @@ -338,7 +328,7 @@ public class SerialPort implements AutoCloseable { * @param size The read buffer size. */ public void setReadBufferSize(int size) { - SerialPortJNI.serialSetReadBufferSize(m_port, size); + SerialPortJNI.serialSetReadBufferSize(m_portHandle, size); } /** @@ -349,7 +339,7 @@ public class SerialPort implements AutoCloseable { * @param size The write buffer size. */ public void setWriteBufferSize(int size) { - SerialPortJNI.serialSetWriteBufferSize(m_port, size); + SerialPortJNI.serialSetWriteBufferSize(m_portHandle, size); } /** @@ -364,7 +354,7 @@ public class SerialPort implements AutoCloseable { * @param mode The write buffer mode. */ public void setWriteBufferMode(WriteBufferMode mode) { - SerialPortJNI.serialSetWriteMode(m_port, (byte) mode.value); + SerialPortJNI.serialSetWriteMode(m_portHandle, (byte) mode.value); } /** @@ -374,7 +364,7 @@ public class SerialPort implements AutoCloseable { * buffer is full. */ public void flush() { - SerialPortJNI.serialFlush(m_port); + SerialPortJNI.serialFlush(m_portHandle); } /** @@ -383,6 +373,6 @@ public class SerialPort implements AutoCloseable { *

Empty the transmit and receive buffers in the device and formatted I/O. */ public void reset() { - SerialPortJNI.serialClear(m_port); + SerialPortJNI.serialClear(m_portHandle); } }