From 2e3503517d966698ab0a704a122dd0facf00a75e Mon Sep 17 00:00:00 2001 From: Thad House Date: Wed, 4 Jan 2017 19:38:17 -0800 Subject: [PATCH] Add OS level serial port (#426) --- hal/include/HAL/Errors.h | 10 +- hal/include/HAL/OSSerialPort.h | 50 +++ hal/lib/athena/HAL.cpp | 4 + hal/lib/athena/OSSerialPort.cpp | 232 +++++++++++++ wpilibj/athena.gradle | 1 + .../src/athena/cpp/lib/OSSerialPortJNI.cpp | 319 ++++++++++++++++++ .../first/wpilibj/hal/OSSerialPortJNI.java | 48 +++ 7 files changed, 663 insertions(+), 1 deletion(-) create mode 100644 hal/include/HAL/OSSerialPort.h create mode 100644 hal/lib/athena/OSSerialPort.cpp create mode 100644 wpilibj/src/athena/cpp/lib/OSSerialPortJNI.cpp create mode 100644 wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/OSSerialPortJNI.java diff --git a/hal/include/HAL/Errors.h b/hal/include/HAL/Errors.h index c8c53e6497..a31fa9f569 100644 --- a/hal/include/HAL/Errors.h +++ b/hal/include/HAL/Errors.h @@ -85,7 +85,15 @@ #define HAL_SERIAL_PORT_NOT_FOUND -1123 #define HAL_SERIAL_PORT_NOT_FOUND_MESSAGE \ - "HAL: The specified serial port device was not found"; + "HAL: The specified serial port device was not found" + +#define HAL_SERIAL_PORT_OPEN_ERROR -1124 +#define HAL_SERIAL_PORT_OPEN_ERROR_MESSAGE \ + "HAL: The serial port could not be opened" + +#define HAL_SERIAL_PORT_ERROR -1125 +#define HAL_SERIAL_PORT_ERROR_MESSAGE \ + "HAL: There was an error on the serial port" #define HAL_THREAD_PRIORITY_ERROR -1152 #define HAL_THREAD_PRIORITY_ERROR_MESSAGE \ diff --git a/hal/include/HAL/OSSerialPort.h b/hal/include/HAL/OSSerialPort.h new file mode 100644 index 0000000000..21696cc3b4 --- /dev/null +++ b/hal/include/HAL/OSSerialPort.h @@ -0,0 +1,50 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) FIRST 2016-2017. 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. */ +/*----------------------------------------------------------------------------*/ + +#pragma once + +#include + +#include "SerialPort.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void HAL_InitializeOSSerialPort(HAL_SerialPort port, int32_t* status); +void HAL_SetOSSerialBaudRate(HAL_SerialPort port, int32_t baud, + int32_t* status); +void HAL_SetOSSerialDataBits(HAL_SerialPort port, int32_t bits, + int32_t* status); +void HAL_SetOSSerialParity(HAL_SerialPort port, int32_t parity, + int32_t* status); +void HAL_SetOSSerialStopBits(HAL_SerialPort port, int32_t stopBits, + int32_t* status); +void HAL_SetOSSerialWriteMode(HAL_SerialPort port, int32_t mode, + int32_t* status); +void HAL_SetOSSerialFlowControl(HAL_SerialPort port, int32_t flow, + int32_t* status); +void HAL_SetOSSerialTimeout(HAL_SerialPort port, double timeout, + int32_t* status); +void HAL_EnableOSSerialTermination(HAL_SerialPort port, char terminator, + int32_t* status); +void HAL_DisableOSSerialTermination(HAL_SerialPort port, int32_t* status); +void HAL_SetOSSerialReadBufferSize(HAL_SerialPort port, int32_t size, + int32_t* status); +void HAL_SetOSSerialWriteBufferSize(HAL_SerialPort port, int32_t size, + int32_t* status); +int32_t HAL_GetOSSerialBytesReceived(HAL_SerialPort port, int32_t* status); +int32_t HAL_ReadOSSerial(HAL_SerialPort port, char* buffer, int32_t count, + int32_t* status); +int32_t HAL_WriteOSSerial(HAL_SerialPort port, const char* buffer, + int32_t count, int32_t* status); +void HAL_FlushOSSerial(HAL_SerialPort port, int32_t* status); +void HAL_ClearOSSerial(HAL_SerialPort port, int32_t* status); +void HAL_CloseOSSerial(HAL_SerialPort port, int32_t* status); +#ifdef __cplusplus +} +#endif diff --git a/hal/lib/athena/HAL.cpp b/hal/lib/athena/HAL.cpp index 2cf6973028..708ca1b929 100644 --- a/hal/lib/athena/HAL.cpp +++ b/hal/lib/athena/HAL.cpp @@ -170,6 +170,10 @@ const char* HAL_GetErrorMessage(int32_t code) { return HAL_THREAD_PRIORITY_ERROR_MESSAGE; case HAL_THREAD_PRIORITY_RANGE_ERROR: return HAL_THREAD_PRIORITY_RANGE_ERROR_MESSAGE; + case HAL_SERIAL_PORT_OPEN_ERROR: + return HAL_SERIAL_PORT_OPEN_ERROR_MESSAGE; + case HAL_SERIAL_PORT_ERROR: + return HAL_SERIAL_PORT_ERROR_MESSAGE; default: return "Unknown error status"; } diff --git a/hal/lib/athena/OSSerialPort.cpp b/hal/lib/athena/OSSerialPort.cpp new file mode 100644 index 0000000000..95c467d8c1 --- /dev/null +++ b/hal/lib/athena/OSSerialPort.cpp @@ -0,0 +1,232 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) FIRST 2017. 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. */ +/*----------------------------------------------------------------------------*/ + +#include "HAL/OSSerialPort.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include "HAL/Errors.h" +#include "HAL/cpp/SerialHelper.h" + +static int portHandles[4]{-1, -1, -1, -1}; +static std::chrono::milliseconds portTimeouts[4]{ + std::chrono::milliseconds(0), std::chrono::milliseconds(0), + std::chrono::milliseconds(0), std::chrono::milliseconds(0)}; + +extern "C" { + +void HAL_InitializeOSSerialPort(HAL_SerialPort port, int32_t* status) { + std::string portName; + + hal::SerialHelper serialHelper; + + portName = serialHelper.GetOSSerialPortName(port, status); + + if (*status < 0) { + return; + } + + int fs = open(portName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); + if (fs == -1) { + *status = HAL_SERIAL_PORT_OPEN_ERROR; + return; + } + portHandles[port] = fs; + + struct termios options; + tcgetattr(fs, &options); + options.c_cflag = B9600 | CS8 | CLOCAL | CREAD; + options.c_iflag = 0; + options.c_oflag = 0; + options.c_lflag = 0; + tcflush(fs, TCIFLUSH); + tcsetattr(fs, TCSANOW, &options); +} + +void HAL_SetOSSerialBaudRate(HAL_SerialPort port, int32_t baud, + int32_t* status) { + int baudRate = -1; + switch (baud) { + case 9600: + baudRate = B9600; + break; + case 19200: + baudRate = B19200; + break; + case 38400: + baudRate = B38400; + break; + case 57600: + baudRate = B57600; + break; + case 115200: + baudRate = B115200; + break; + default: + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + struct termios options; + tcgetattr(portHandles[port], &options); + auto set = cfsetospeed(&options, baudRate); + if (set != 0) { + *status = HAL_SERIAL_PORT_ERROR; + return; + } + set = tcsetattr(portHandles[port], TCSANOW, &options); + if (set != 0) { + *status = HAL_SERIAL_PORT_ERROR; + return; + } +} + +void HAL_SetOSSerialDataBits(HAL_SerialPort port, int32_t bits, + int32_t* status) { + int numBits = -1; + switch (bits) { + case 5: + numBits = CS5; + break; + case 6: + numBits = CS6; + break; + case 7: + numBits = CS7; + break; + case 8: + numBits = CS8; + break; + default: + *status = PARAMETER_OUT_OF_RANGE; + return; + } + + struct termios options; + tcgetattr(portHandles[port], &options); + options.c_cflag &= ~CSIZE; + options.c_cflag |= numBits; + auto set = tcsetattr(portHandles[port], TCSANOW, &options); + if (set != 0) { + *status = HAL_SERIAL_PORT_ERROR; + return; + } +} + +void HAL_SetOSSerialParity(HAL_SerialPort port, int32_t parity, + int32_t* status) { + // Just set none parity + struct termios options; + tcgetattr(portHandles[port], &options); + options.c_cflag &= ~PARENB; + auto set = tcsetattr(portHandles[port], TCSANOW, &options); + if (set != 0) { + *status = HAL_SERIAL_PORT_ERROR; + return; + } +} + +void HAL_SetOSSerialStopBits(HAL_SerialPort port, int32_t stopBits, + int32_t* status) { + // Force 1 stop bit + struct termios options; + tcgetattr(portHandles[port], &options); + options.c_cflag &= ~CSTOPB; + auto set = tcsetattr(portHandles[port], TCSANOW, &options); + if (set != 0) { + *status = HAL_SERIAL_PORT_ERROR; + return; + } +} + +void HAL_SetOSSerialWriteMode(HAL_SerialPort port, int32_t mode, + int32_t* status) { + // No op +} + +void HAL_SetOSSerialFlowControl(HAL_SerialPort port, int32_t flow, + int32_t* status) { + // No op +} + +void HAL_SetOSSerialTimeout(HAL_SerialPort port, double timeout, + int32_t* status) { + // Convert to millis + int t = timeout / 1000; + portTimeouts[port] = std::chrono::milliseconds(t); +} + +void HAL_EnableOSSerialTermination(HAL_SerialPort port, char terminator, + int32_t* status) { + // \n is hardcoded for now. Will fix later + // Seems like a VISA only setting, need to check +} + +void HAL_DisableOSSerialTermination(HAL_SerialPort port, int32_t* status) { + // Seems like a VISA only setting, need to check +} + +void HAL_SetOSSerialReadBufferSize(HAL_SerialPort port, int32_t size, + int32_t* status) { + // No op +} + +void HAL_SetOSSerialWriteBufferSize(HAL_SerialPort port, int32_t size, + int32_t* status) { + // No op +} + +int32_t HAL_GetOSSerialBytesReceived(HAL_SerialPort port, int32_t* status) { + int bytes = 0; + ioctl(portHandles[port], FIONREAD, &bytes); + return bytes; +} + +int32_t HAL_ReadOSSerial(HAL_SerialPort port, char* buffer, int32_t count, + int32_t* status) { + auto endTime = std::chrono::steady_clock::now() + portTimeouts[port]; + + int bytesRead = 0; + + unsigned char buf[256]; + + do { + int rx = read(portHandles[port], buf, count - bytesRead); + std::memcpy(&buffer[bytesRead], buf, rx); + bytesRead += rx; + if (bytesRead >= count) break; + llvm::StringRef tmp(buffer, bytesRead); + auto loc = tmp.find('\n'); + if (loc != llvm::StringRef::npos) { + bytesRead = loc; + break; + } + } while (std::chrono::steady_clock::now() < endTime); + return bytesRead; +} + +int32_t HAL_WriteOSSerial(HAL_SerialPort port, const char* buffer, + int32_t count, int32_t* status) { + return write(portHandles[port], buffer, count); +} +void HAL_FlushOSSerial(HAL_SerialPort port, int32_t* status) { + tcdrain(portHandles[port]); +} +void HAL_ClearOSSerial(HAL_SerialPort port, int32_t* status) { + tcflush(portHandles[port], TCIOFLUSH); +} +void HAL_CloseOSSerial(HAL_SerialPort port, int32_t* status) { + close(portHandles[port]); +} +} diff --git a/wpilibj/athena.gradle b/wpilibj/athena.gradle index 2f5dccdf17..8cf22de1b0 100644 --- a/wpilibj/athena.gradle +++ b/wpilibj/athena.gradle @@ -175,6 +175,7 @@ task jniHeaders { args 'edu.wpi.first.wpilibj.hal.PDPJNI' args 'edu.wpi.first.wpilibj.hal.PowerJNI' args 'edu.wpi.first.wpilibj.hal.SerialPortJNI' + args 'edu.wpi.first.wpilibj.hal.OSSerialPortJNI' args 'edu.wpi.first.wpilibj.hal.ThreadsJNI' } } diff --git a/wpilibj/src/athena/cpp/lib/OSSerialPortJNI.cpp b/wpilibj/src/athena/cpp/lib/OSSerialPortJNI.cpp new file mode 100644 index 0000000000..2e1c147de6 --- /dev/null +++ b/wpilibj/src/athena/cpp/lib/OSSerialPortJNI.cpp @@ -0,0 +1,319 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) FIRST 2016. 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. */ +/*----------------------------------------------------------------------------*/ + +#include +#include +#include "HAL/cpp/Log.h" + +#include "edu_wpi_first_wpilibj_hal_OSSerialPortJNI.h" + +#include "HAL/OSSerialPort.h" +#include "HALUtil.h" + +using namespace frc; + +// set the logging level +TLogLevel osserialJNILogLevel = logWARNING; + +#define SERIALJNI_LOG(level) \ + if (level > osserialJNILogLevel) \ + ; \ + else \ + Log().Get(level) + +extern "C" { + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialInitializePort + * Signature: (B)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialInitializePort( + JNIEnv* env, jclass, jbyte port) { + SERIALJNI_LOG(logDEBUG) << "Calling Serial Initialize"; + SERIALJNI_LOG(logDEBUG) << "Port = " << (jint)port; + int32_t status = 0; + HAL_InitializeOSSerialPort(static_cast(port), &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatusForceThrow(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialSetBaudRate + * Signature: (BI)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialSetBaudRate( + JNIEnv* env, jclass, jbyte port, jint rate) { + SERIALJNI_LOG(logDEBUG) << "Setting Serial Baud Rate"; + SERIALJNI_LOG(logDEBUG) << "Baud: " << rate; + int32_t status = 0; + HAL_SetOSSerialBaudRate(static_cast(port), rate, &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialSetDataBits + * Signature: (BB)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialSetDataBits( + JNIEnv* env, jclass, jbyte port, jbyte bits) { + SERIALJNI_LOG(logDEBUG) << "Setting Serial Data Bits"; + SERIALJNI_LOG(logDEBUG) << "Data Bits: " << bits; + int32_t status = 0; + HAL_SetOSSerialDataBits(static_cast(port), bits, &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialSetParity + * Signature: (BB)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialSetParity( + JNIEnv* env, jclass, jbyte port, jbyte parity) { + SERIALJNI_LOG(logDEBUG) << "Setting Serial Parity"; + SERIALJNI_LOG(logDEBUG) << "Parity: " << parity; + int32_t status = 0; + HAL_SetOSSerialParity(static_cast(port), parity, &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialSetStopBits + * Signature: (BB)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialSetStopBits( + JNIEnv* env, jclass, jbyte port, jbyte bits) { + SERIALJNI_LOG(logDEBUG) << "Setting Serial Stop Bits"; + SERIALJNI_LOG(logDEBUG) << "Stop Bits: " << bits; + int32_t status = 0; + HAL_SetOSSerialStopBits(static_cast(port), bits, &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialSetWriteMode + * Signature: (BB)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialSetWriteMode( + JNIEnv* env, jclass, jbyte port, jbyte mode) { + SERIALJNI_LOG(logDEBUG) << "Setting Serial Write Mode"; + SERIALJNI_LOG(logDEBUG) << "Write mode: " << mode; + int32_t status = 0; + HAL_SetOSSerialWriteMode(static_cast(port), mode, &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialSetFlowControl + * Signature: (BB)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialSetFlowControl( + JNIEnv* env, jclass, jbyte port, jbyte flow) { + SERIALJNI_LOG(logDEBUG) << "Setting Serial Flow Control"; + SERIALJNI_LOG(logDEBUG) << "Flow Control: " << flow; + int32_t status = 0; + HAL_SetOSSerialFlowControl(static_cast(port), flow, &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialSetTimeout + * Signature: (BD)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialSetTimeout( + JNIEnv* env, jclass, jbyte port, jdouble timeout) { + SERIALJNI_LOG(logDEBUG) << "Setting Serial Timeout"; + SERIALJNI_LOG(logDEBUG) << "Timeout: " << timeout; + int32_t status = 0; + HAL_SetOSSerialTimeout(static_cast(port), timeout, &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialEnableTermination + * Signature: (BC)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialEnableTermination( + JNIEnv* env, jclass, jbyte port, jchar terminator) { + SERIALJNI_LOG(logDEBUG) << "Setting Serial Enable Termination"; + SERIALJNI_LOG(logDEBUG) << "Terminator: " << terminator; + int32_t status = 0; + HAL_EnableOSSerialTermination(static_cast(port), terminator, &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialDisableTermination + * Signature: (B)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialDisableTermination( + JNIEnv* env, jclass, jbyte port) { + SERIALJNI_LOG(logDEBUG) << "Setting Serial Disable termination"; + int32_t status = 0; + HAL_DisableOSSerialTermination(static_cast(port), &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialSetReadBufferSize + * Signature: (BI)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialSetReadBufferSize( + JNIEnv* env, jclass, jbyte port, jint size) { + SERIALJNI_LOG(logDEBUG) << "Setting Serial Read Buffer Size"; + SERIALJNI_LOG(logDEBUG) << "Size: " << size; + int32_t status = 0; + HAL_SetOSSerialReadBufferSize(static_cast(port), size, &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialSetWriteBufferSize + * Signature: (BI)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialSetWriteBufferSize( + JNIEnv* env, jclass, jbyte port, jint size) { + SERIALJNI_LOG(logDEBUG) << "Setting Serial Write Buffer Size"; + SERIALJNI_LOG(logDEBUG) << "Size: " << size; + int32_t status = 0; + HAL_SetOSSerialWriteBufferSize(static_cast(port), size, &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialGetBytesRecieved + * Signature: (B)I + */ +JNIEXPORT jint JNICALL +Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialGetBytesRecieved( + JNIEnv* env, jclass, jbyte port) { + SERIALJNI_LOG(logDEBUG) << "Serial Get Bytes Received"; + int32_t status = 0; + jint retVal = HAL_GetOSSerialBytesReceived(static_cast(port), &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); + return retVal; +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialRead + * Signature: (BLjava/nio/ByteBuffer;I)I + */ +JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialRead( + JNIEnv* env, jclass, jbyte port, jobject dataReceived, jint size) { + SERIALJNI_LOG(logDEBUG) << "Serial Read"; + jbyte* dataReceivedPtr = nullptr; + dataReceivedPtr = (jbyte*)env->GetDirectBufferAddress(dataReceived); + int32_t status = 0; + jint retVal = HAL_ReadOSSerial(static_cast(port), reinterpret_cast(dataReceivedPtr), + size, &status); + SERIALJNI_LOG(logDEBUG) << "ReturnValue = " << retVal; + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); + return retVal; +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialWrite + * Signature: (BLjava/nio/ByteBuffer;I)I + */ +JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialWrite( + JNIEnv* env, jclass, jbyte port, jobject dataToSend, jint size) { + SERIALJNI_LOG(logDEBUG) << "Serial Write"; + jbyte* dataToSendPtr = nullptr; + if (dataToSend != 0) { + dataToSendPtr = (jbyte*)env->GetDirectBufferAddress(dataToSend); + } + int32_t status = 0; + jint retVal = HAL_WriteOSSerial(static_cast(port), reinterpret_cast(dataToSendPtr), + size, &status); + SERIALJNI_LOG(logDEBUG) << "ReturnValue = " << retVal; + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); + return retVal; +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialFlush + * Signature: (B)V + */ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialFlush( + JNIEnv* env, jclass, jbyte port) { + SERIALJNI_LOG(logDEBUG) << "Serial Flush"; + int32_t status = 0; + HAL_FlushOSSerial(static_cast(port), &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialClear + * Signature: (B)V + */ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialClear( + JNIEnv* env, jclass, jbyte port) { + SERIALJNI_LOG(logDEBUG) << "Serial Clear"; + int32_t status = 0; + HAL_ClearOSSerial(static_cast(port), &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +/* + * Class: edu_wpi_first_wpilibj_hal_OSSerialPortJNI + * Method: serialClose + * Signature: (B)V + */ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_OSSerialPortJNI_serialClose( + JNIEnv* env, jclass, jbyte port) { + SERIALJNI_LOG(logDEBUG) << "Serial Close"; + int32_t status = 0; + HAL_CloseOSSerial(static_cast(port), &status); + SERIALJNI_LOG(logDEBUG) << "Status = " << status; + CheckStatus(env, status); +} + +} // extern "C" diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/OSSerialPortJNI.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/OSSerialPortJNI.java new file mode 100644 index 0000000000..4fd18fd9c8 --- /dev/null +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/OSSerialPortJNI.java @@ -0,0 +1,48 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) FIRST 2016-2017. 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. */ +/*----------------------------------------------------------------------------*/ + +package edu.wpi.first.wpilibj.hal; + +import java.nio.ByteBuffer; + +public class OSSerialPortJNI extends JNIWrapper { + public static native void serialInitializePort(byte port); + + public static native void serialSetBaudRate(byte port, int baud); + + public static native void serialSetDataBits(byte port, byte bits); + + public static native void serialSetParity(byte port, byte parity); + + public static native void serialSetStopBits(byte port, byte stopBits); + + public static native void serialSetWriteMode(byte port, byte mode); + + public static native void serialSetFlowControl(byte port, byte flow); + + public static native void serialSetTimeout(byte port, double timeout); + + public static native void serialEnableTermination(byte port, char terminator); + + public static native void serialDisableTermination(byte port); + + public static native void serialSetReadBufferSize(byte port, int size); + + public static native void serialSetWriteBufferSize(byte port, int size); + + public static native int serialGetBytesRecieved(byte port); + + public static native int serialRead(byte port, ByteBuffer buffer, int count); + + public static native int serialWrite(byte port, ByteBuffer buffer, int count); + + public static native void serialFlush(byte port); + + public static native void serialClear(byte port); + + public static native void serialClose(byte port); +}