mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
[hal, wpilib] Rewrite CAN APIs (#7798)
This commit is contained in:
@@ -19,29 +19,20 @@ using namespace wpi::java;
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_CANAPIJNI
|
||||
* Method: getCANPacketBaseTime
|
||||
* Signature: ()J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_edu_wpi_first_hal_CANAPIJNI_getCANPacketBaseTime
|
||||
(JNIEnv*, jclass)
|
||||
{
|
||||
return HAL_GetCANPacketBaseTime();
|
||||
}
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_CANAPIJNI
|
||||
* Method: initializeCAN
|
||||
* Signature: (III)I
|
||||
* Signature: (IIII)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_CANAPIJNI_initializeCAN
|
||||
(JNIEnv* env, jclass, jint manufacturer, jint deviceId, jint deviceType)
|
||||
(JNIEnv* env, jclass, jint busId, jint manufacturer, jint deviceId,
|
||||
jint deviceType)
|
||||
{
|
||||
int32_t status = 0;
|
||||
auto handle =
|
||||
HAL_InitializeCAN(static_cast<HAL_CANManufacturer>(manufacturer),
|
||||
HAL_InitializeCAN(static_cast<int32_t>(busId),
|
||||
static_cast<HAL_CANManufacturer>(manufacturer),
|
||||
static_cast<int32_t>(deviceId),
|
||||
static_cast<HAL_CANDeviceType>(deviceType), &status);
|
||||
|
||||
@@ -63,105 +54,189 @@ Java_edu_wpi_first_hal_CANAPIJNI_cleanCAN
|
||||
}
|
||||
}
|
||||
|
||||
static bool PackCANMessage(JNIEnv* env, jbyteArray data, jint dataLength,
|
||||
jint flags, HAL_CANMessage* message) {
|
||||
if (data == nullptr) {
|
||||
ThrowNullPointerException(env, "data array cannot be null");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto arrLen = env->GetArrayLength(data);
|
||||
if (arrLen < dataLength) {
|
||||
ThrowIllegalArgumentException(env, "array length less than data length");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((flags & HAL_CAN_FD_DATALENGTH) && dataLength > 64) {
|
||||
ThrowIllegalArgumentException(env, "FD frame has max length of 64 bytes");
|
||||
return false;
|
||||
} else if (!(flags & HAL_CAN_FD_DATALENGTH) && dataLength > 8) {
|
||||
ThrowIllegalArgumentException(env,
|
||||
"Non FD frame has max length of 8 bytes");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::memset(message, 0, sizeof(*message));
|
||||
message->dataSize = dataLength;
|
||||
message->flags = flags;
|
||||
JSpan<const jbyte> arr{env, data, static_cast<size_t>(dataLength)};
|
||||
std::memcpy(message->data, arr.data(), dataLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_CANAPIJNI
|
||||
* Method: writeCANPacket
|
||||
* Signature: (I[BI)V
|
||||
* Signature: (II[BII)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_CANAPIJNI_writeCANPacket
|
||||
(JNIEnv* env, jclass, jint handle, jbyteArray data, jint apiId)
|
||||
(JNIEnv* env, jclass, jint handle, jint apiId, jbyteArray data,
|
||||
jint dataLength, jint flags)
|
||||
{
|
||||
auto halHandle = static_cast<HAL_CANHandle>(handle);
|
||||
JSpan<const jbyte> arr{env, data};
|
||||
HAL_CANMessage message;
|
||||
if (!PackCANMessage(env, data, dataLength, flags, &message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t status = 0;
|
||||
HAL_WriteCANPacket(halHandle, reinterpret_cast<const uint8_t*>(arr.data()),
|
||||
arr.size(), apiId, &status);
|
||||
HAL_WriteCANPacket(static_cast<HAL_CANHandle>(handle), apiId, &message,
|
||||
&status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_CANAPIJNI
|
||||
* Method: writeCANPacketRepeating
|
||||
* Signature: (I[BII)V
|
||||
* Signature: (II[BIII)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_CANAPIJNI_writeCANPacketRepeating
|
||||
(JNIEnv* env, jclass, jint handle, jbyteArray data, jint apiId,
|
||||
jint timeoutMs)
|
||||
(JNIEnv* env, jclass, jint handle, jint apiId, jbyteArray data,
|
||||
jint dataLength, jint flags, jint repeatMs)
|
||||
{
|
||||
auto halHandle = static_cast<HAL_CANHandle>(handle);
|
||||
JSpan<const jbyte> arr{env, data};
|
||||
HAL_CANMessage message;
|
||||
if (!PackCANMessage(env, data, dataLength, flags, &message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t status = 0;
|
||||
HAL_WriteCANPacketRepeating(halHandle,
|
||||
reinterpret_cast<const uint8_t*>(arr.data()),
|
||||
arr.size(), apiId, timeoutMs, &status);
|
||||
HAL_WriteCANPacketRepeating(static_cast<HAL_CANHandle>(handle), apiId,
|
||||
&message, repeatMs, &status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_CANAPIJNI
|
||||
* Method: writeCANRTRFrame
|
||||
* Signature: (III)V
|
||||
* Signature: (II[BII)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_CANAPIJNI_writeCANRTRFrame
|
||||
(JNIEnv* env, jclass, jint handle, jint length, jint apiId)
|
||||
(JNIEnv* env, jclass, jint handle, jint apiId, jbyteArray data,
|
||||
jint dataLength, jint flags)
|
||||
{
|
||||
auto halHandle = static_cast<HAL_CANHandle>(handle);
|
||||
HAL_CANMessage message;
|
||||
|
||||
if (data == nullptr) {
|
||||
// We will allow RTR frames to have a null data array
|
||||
if ((flags & HAL_CAN_FD_DATALENGTH) && dataLength > 64) {
|
||||
ThrowIllegalArgumentException(env, "FD frame has max length of 64 bytes");
|
||||
return;
|
||||
} else if (!(flags & HAL_CAN_FD_DATALENGTH) && dataLength > 8) {
|
||||
ThrowIllegalArgumentException(env,
|
||||
"Non FD frame has max length of 8 bytes");
|
||||
return;
|
||||
}
|
||||
|
||||
std::memset(&message, 0, sizeof(message));
|
||||
message.flags = flags;
|
||||
message.dataSize = dataLength;
|
||||
} else if (!PackCANMessage(env, data, dataLength, flags, &message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t status = 0;
|
||||
HAL_WriteCANRTRFrame(halHandle, static_cast<int32_t>(length), apiId, &status);
|
||||
HAL_WriteCANRTRFrame(static_cast<HAL_CANHandle>(handle), apiId, &message,
|
||||
&status);
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_CANAPIJNI
|
||||
* Method: writeCANPacketNoThrow
|
||||
* Signature: (I[BI)I
|
||||
* Signature: (II[BII)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_CANAPIJNI_writeCANPacketNoThrow
|
||||
(JNIEnv* env, jclass, jint handle, jbyteArray data, jint apiId)
|
||||
(JNIEnv* env, jclass, jint handle, jint apiId, jbyteArray data,
|
||||
jint dataLength, jint flags)
|
||||
{
|
||||
auto halHandle = static_cast<HAL_CANHandle>(handle);
|
||||
JSpan<const jbyte> arr{env, data};
|
||||
HAL_CANMessage message;
|
||||
if (!PackCANMessage(env, data, dataLength, flags, &message)) {
|
||||
return PARAMETER_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
int32_t status = 0;
|
||||
HAL_WriteCANPacket(halHandle, reinterpret_cast<const uint8_t*>(arr.data()),
|
||||
arr.size(), apiId, &status);
|
||||
HAL_WriteCANPacket(static_cast<HAL_CANHandle>(handle), apiId, &message,
|
||||
&status);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_CANAPIJNI
|
||||
* Method: writeCANPacketRepeatingNoThrow
|
||||
* Signature: (I[BII)I
|
||||
* Signature: (II[BIII)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_CANAPIJNI_writeCANPacketRepeatingNoThrow
|
||||
(JNIEnv* env, jclass, jint handle, jbyteArray data, jint apiId,
|
||||
jint timeoutMs)
|
||||
(JNIEnv* env, jclass, jint handle, jint apiId, jbyteArray data,
|
||||
jint dataLength, jint flags, jint repeatMs)
|
||||
{
|
||||
auto halHandle = static_cast<HAL_CANHandle>(handle);
|
||||
JSpan<const jbyte> arr{env, data};
|
||||
HAL_CANMessage message;
|
||||
if (!PackCANMessage(env, data, dataLength, flags, &message)) {
|
||||
return PARAMETER_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
int32_t status = 0;
|
||||
HAL_WriteCANPacketRepeating(halHandle,
|
||||
reinterpret_cast<const uint8_t*>(arr.data()),
|
||||
arr.size(), apiId, timeoutMs, &status);
|
||||
HAL_WriteCANPacketRepeating(static_cast<HAL_CANHandle>(handle), apiId,
|
||||
&message, repeatMs, &status);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_CANAPIJNI
|
||||
* Method: writeCANRTRFrameNoThrow
|
||||
* Signature: (III)I
|
||||
* Signature: (II[BII)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_CANAPIJNI_writeCANRTRFrameNoThrow
|
||||
(JNIEnv* env, jclass, jint handle, jint length, jint apiId)
|
||||
(JNIEnv* env, jclass, jint handle, jint apiId, jbyteArray data,
|
||||
jint dataLength, jint flags)
|
||||
{
|
||||
auto halHandle = static_cast<HAL_CANHandle>(handle);
|
||||
HAL_CANMessage message;
|
||||
|
||||
if (data == nullptr) {
|
||||
// We will allow RTR frames to have a null data array
|
||||
if ((flags & HAL_CAN_FD_DATALENGTH) && dataLength > 64) {
|
||||
ThrowIllegalArgumentException(env, "FD frame has max length of 64 bytes");
|
||||
return PARAMETER_OUT_OF_RANGE;
|
||||
} else if (!(flags & HAL_CAN_FD_DATALENGTH) && dataLength > 8) {
|
||||
ThrowIllegalArgumentException(env,
|
||||
"Non FD frame has max length of 8 bytes");
|
||||
return PARAMETER_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
std::memset(&message, 0, sizeof(message));
|
||||
message.flags = flags;
|
||||
message.dataSize = dataLength;
|
||||
} else if (!PackCANMessage(env, data, dataLength, flags, &message)) {
|
||||
return PARAMETER_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
int32_t status = 0;
|
||||
HAL_WriteCANRTRFrame(halHandle, static_cast<int32_t>(length), apiId, &status);
|
||||
HAL_WriteCANRTRFrame(static_cast<HAL_CANHandle>(handle), apiId, &message,
|
||||
&status);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -190,29 +265,28 @@ Java_edu_wpi_first_hal_CANAPIJNI_readCANPacketNew
|
||||
(JNIEnv* env, jclass, jint handle, jint apiId, jobject data)
|
||||
{
|
||||
auto halHandle = static_cast<HAL_CANHandle>(handle);
|
||||
uint8_t dataTemp[8];
|
||||
int32_t dataLength = 0;
|
||||
uint64_t timestamp = 0;
|
||||
HAL_CANReceiveMessage message;
|
||||
std::memset(&message, 0, sizeof(message));
|
||||
int32_t status = 0;
|
||||
HAL_ReadCANPacketNew(halHandle, apiId, dataTemp, &dataLength, ×tamp,
|
||||
&status);
|
||||
HAL_ReadCANPacketNew(halHandle, apiId, &message, &status);
|
||||
if (status == HAL_ERR_CANSessionMux_MessageNotFound) {
|
||||
return false;
|
||||
}
|
||||
if (!CheckStatus(env, status)) {
|
||||
return false;
|
||||
}
|
||||
if (dataLength > 8) {
|
||||
dataLength = 8;
|
||||
}
|
||||
|
||||
jbyteArray toSetArray = SetCANDataObject(env, data, dataLength, timestamp);
|
||||
jbyteArray toSetArray =
|
||||
SetCANReceiveMessageObject(env, data, message.message.dataSize,
|
||||
message.message.flags, message.timeStamp);
|
||||
auto javaLen = env->GetArrayLength(toSetArray);
|
||||
if (javaLen < dataLength) {
|
||||
dataLength = javaLen;
|
||||
if (javaLen < message.message.dataSize) {
|
||||
ThrowIllegalArgumentException(env,
|
||||
"Message buffer not long enough for message");
|
||||
return false;
|
||||
}
|
||||
env->SetByteArrayRegion(toSetArray, 0, dataLength,
|
||||
reinterpret_cast<jbyte*>(dataTemp));
|
||||
env->SetByteArrayRegion(toSetArray, 0, message.message.dataSize,
|
||||
reinterpret_cast<jbyte*>(message.message.data));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -226,48 +300,45 @@ Java_edu_wpi_first_hal_CANAPIJNI_readCANPacketLatest
|
||||
(JNIEnv* env, jclass, jint handle, jint apiId, jobject data)
|
||||
{
|
||||
auto halHandle = static_cast<HAL_CANHandle>(handle);
|
||||
uint8_t dataTemp[8];
|
||||
int32_t dataLength = 0;
|
||||
uint64_t timestamp = 0;
|
||||
HAL_CANReceiveMessage message;
|
||||
std::memset(&message, 0, sizeof(message));
|
||||
int32_t status = 0;
|
||||
HAL_ReadCANPacketLatest(halHandle, apiId, dataTemp, &dataLength, ×tamp,
|
||||
&status);
|
||||
HAL_ReadCANPacketLatest(halHandle, apiId, &message, &status);
|
||||
if (status == HAL_ERR_CANSessionMux_MessageNotFound) {
|
||||
return false;
|
||||
}
|
||||
if (!CheckStatus(env, status)) {
|
||||
return false;
|
||||
}
|
||||
if (dataLength > 8) {
|
||||
dataLength = 8;
|
||||
}
|
||||
|
||||
jbyteArray toSetArray = SetCANDataObject(env, data, dataLength, timestamp);
|
||||
jbyteArray toSetArray =
|
||||
SetCANReceiveMessageObject(env, data, message.message.dataSize,
|
||||
message.message.flags, message.timeStamp);
|
||||
auto javaLen = env->GetArrayLength(toSetArray);
|
||||
if (javaLen < dataLength) {
|
||||
dataLength = javaLen;
|
||||
if (javaLen < message.message.dataSize) {
|
||||
ThrowIllegalArgumentException(env,
|
||||
"Message buffer not long enough for message");
|
||||
return false;
|
||||
}
|
||||
env->SetByteArrayRegion(toSetArray, 0, dataLength,
|
||||
reinterpret_cast<jbyte*>(dataTemp));
|
||||
env->SetByteArrayRegion(toSetArray, 0, message.message.dataSize,
|
||||
reinterpret_cast<jbyte*>(message.message.data));
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_CANAPIJNI
|
||||
* Method: readCANPacketTimeout
|
||||
* Signature: (IIILjava/lang/Object;)Z
|
||||
* Signature: (IILjava/lang/Object;I)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_edu_wpi_first_hal_CANAPIJNI_readCANPacketTimeout
|
||||
(JNIEnv* env, jclass, jint handle, jint apiId, jint timeoutMs, jobject data)
|
||||
(JNIEnv* env, jclass, jint handle, jint apiId, jobject data, jint timeoutMs)
|
||||
{
|
||||
auto halHandle = static_cast<HAL_CANHandle>(handle);
|
||||
uint8_t dataTemp[8];
|
||||
int32_t dataLength = 0;
|
||||
uint64_t timestamp = 0;
|
||||
HAL_CANReceiveMessage message;
|
||||
std::memset(&message, 0, sizeof(message));
|
||||
int32_t status = 0;
|
||||
HAL_ReadCANPacketTimeout(halHandle, apiId, dataTemp, &dataLength, ×tamp,
|
||||
timeoutMs, &status);
|
||||
HAL_ReadCANPacketTimeout(halHandle, apiId, &message, timeoutMs, &status);
|
||||
if (status == HAL_CAN_TIMEOUT ||
|
||||
status == HAL_ERR_CANSessionMux_MessageNotFound) {
|
||||
return false;
|
||||
@@ -275,17 +346,18 @@ Java_edu_wpi_first_hal_CANAPIJNI_readCANPacketTimeout
|
||||
if (!CheckStatus(env, status)) {
|
||||
return false;
|
||||
}
|
||||
if (dataLength > 8) {
|
||||
dataLength = 8;
|
||||
}
|
||||
|
||||
jbyteArray toSetArray = SetCANDataObject(env, data, dataLength, timestamp);
|
||||
jbyteArray toSetArray =
|
||||
SetCANReceiveMessageObject(env, data, message.message.dataSize,
|
||||
message.message.flags, message.timeStamp);
|
||||
auto javaLen = env->GetArrayLength(toSetArray);
|
||||
if (javaLen < dataLength) {
|
||||
dataLength = javaLen;
|
||||
if (javaLen < message.message.dataSize) {
|
||||
ThrowIllegalArgumentException(env,
|
||||
"Message buffer not long enough for message");
|
||||
return false;
|
||||
}
|
||||
env->SetByteArrayRegion(toSetArray, 0, dataLength,
|
||||
reinterpret_cast<jbyte*>(dataTemp));
|
||||
env->SetByteArrayRegion(toSetArray, 0, message.message.dataSize,
|
||||
reinterpret_cast<jbyte*>(message.message.data));
|
||||
return true;
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
@@ -11,68 +11,98 @@
|
||||
#include "HALUtil.h"
|
||||
#include "edu_wpi_first_hal_can_CANJNI.h"
|
||||
#include "hal/CAN.h"
|
||||
#include "hal/Errors.h"
|
||||
|
||||
using namespace hal;
|
||||
using namespace wpi::java;
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_can_CANJNI
|
||||
* Method: FRCNetCommCANSessionMuxSendMessage
|
||||
* Signature: (I[BI)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_can_CANJNI_FRCNetCommCANSessionMuxSendMessage
|
||||
(JNIEnv* env, jclass, jint messageID, jbyteArray data, jint periodMs)
|
||||
{
|
||||
JSpan<const jbyte> dataArray{env, data};
|
||||
static bool PackCANMessage(JNIEnv* env, jbyteArray data, jint dataLength,
|
||||
jint flags, HAL_CANMessage* message) {
|
||||
if (data == nullptr) {
|
||||
ThrowNullPointerException(env, "data array cannot be null");
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t* dataBuffer =
|
||||
reinterpret_cast<const uint8_t*>(dataArray.data());
|
||||
uint8_t dataSize = dataArray.size();
|
||||
auto arrLen = env->GetArrayLength(data);
|
||||
if (arrLen < dataLength) {
|
||||
ThrowIllegalArgumentException(env, "array length less than data length");
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t status = 0;
|
||||
HAL_CAN_SendMessage(messageID, dataBuffer, dataSize, periodMs, &status);
|
||||
CheckCANStatus(env, status, messageID);
|
||||
if ((flags & HAL_CAN_FD_DATALENGTH) && dataLength > 64) {
|
||||
ThrowIllegalArgumentException(env, "FD frame has max length of 64 bytes");
|
||||
return false;
|
||||
} else if (!(flags & HAL_CAN_FD_DATALENGTH) && dataLength > 8) {
|
||||
ThrowIllegalArgumentException(env,
|
||||
"Non FD frame has max length of 8 bytes");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::memset(message, 0, sizeof(*message));
|
||||
message->dataSize = dataLength;
|
||||
message->flags = flags;
|
||||
JSpan<const jbyte> arr{env, data, static_cast<size_t>(dataLength)};
|
||||
std::memcpy(message->data, arr.data(), dataLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_can_CANJNI
|
||||
* Method: FRCNetCommCANSessionMuxReceiveMessage
|
||||
* Signature: (Ljava/lang/Object;ILjava/lang/Object;)[B
|
||||
* Method: sendMessage
|
||||
* Signature: (II[BIII)I
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL
|
||||
Java_edu_wpi_first_hal_can_CANJNI_FRCNetCommCANSessionMuxReceiveMessage
|
||||
(JNIEnv* env, jclass, jobject messageID, jint messageIDMask,
|
||||
jobject timeStamp)
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_can_CANJNI_sendMessage
|
||||
(JNIEnv* env, jclass, jint busId, jint messageId, jbyteArray data,
|
||||
jint dataLength, jint flags, jint periodMs)
|
||||
{
|
||||
uint32_t* messageIDPtr =
|
||||
reinterpret_cast<uint32_t*>(env->GetDirectBufferAddress(messageID));
|
||||
uint32_t* timeStampPtr =
|
||||
reinterpret_cast<uint32_t*>(env->GetDirectBufferAddress(timeStamp));
|
||||
|
||||
uint8_t dataSize = 0;
|
||||
uint8_t buffer[8];
|
||||
HAL_CANMessage message;
|
||||
if (!PackCANMessage(env, data, dataLength, flags, &message)) {
|
||||
return PARAMETER_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
int32_t status = 0;
|
||||
HAL_CAN_ReceiveMessage(messageIDPtr, messageIDMask, buffer, &dataSize,
|
||||
timeStampPtr, &status);
|
||||
HAL_CAN_SendMessage(busId, messageId, &message, periodMs, &status);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!CheckCANStatus(env, status, *messageIDPtr)) {
|
||||
return nullptr;
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_can_CANJNI
|
||||
* Method: receiveMessage
|
||||
* Signature: (IILjava/lang/Object;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_can_CANJNI_receiveMessage
|
||||
(JNIEnv* env, jclass, jint busId, jint messageId, jobject data)
|
||||
{
|
||||
HAL_CANReceiveMessage message;
|
||||
std::memset(&message, 0, sizeof(message));
|
||||
int32_t status = 0;
|
||||
HAL_CAN_ReceiveMessage(busId, messageId, &message, &status);
|
||||
jbyteArray toSetArray =
|
||||
SetCANReceiveMessageObject(env, data, message.message.dataSize,
|
||||
message.message.flags, message.timeStamp);
|
||||
auto javaLen = env->GetArrayLength(toSetArray);
|
||||
if (javaLen < message.message.dataSize) {
|
||||
ThrowIllegalArgumentException(env,
|
||||
"Message buffer not long enough for message");
|
||||
return status;
|
||||
}
|
||||
return MakeJByteArray(env, {buffer, static_cast<size_t>(dataSize)});
|
||||
env->SetByteArrayRegion(toSetArray, 0, message.message.dataSize,
|
||||
reinterpret_cast<jbyte*>(message.message.data));
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_can_CANJNI
|
||||
* Method: getCANStatus
|
||||
* Signature: (Ljava/lang/Object;)V
|
||||
* Signature: (ILjava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_can_CANJNI_getCANStatus
|
||||
(JNIEnv* env, jclass, jobject canStatus)
|
||||
(JNIEnv* env, jclass, jint busId, jobject canStatus)
|
||||
{
|
||||
float percentBusUtilization = 0;
|
||||
uint32_t busOffCount = 0;
|
||||
@@ -80,8 +110,9 @@ Java_edu_wpi_first_hal_can_CANJNI_getCANStatus
|
||||
uint32_t receiveErrorCount = 0;
|
||||
uint32_t transmitErrorCount = 0;
|
||||
int32_t status = 0;
|
||||
HAL_CAN_GetCANStatus(&percentBusUtilization, &busOffCount, &txFullCount,
|
||||
&receiveErrorCount, &transmitErrorCount, &status);
|
||||
HAL_CAN_GetCANStatus(busId, &percentBusUtilization, &busOffCount,
|
||||
&txFullCount, &receiveErrorCount, &transmitErrorCount,
|
||||
&status);
|
||||
|
||||
if (!CheckStatus(env, status)) {
|
||||
return;
|
||||
@@ -94,17 +125,18 @@ Java_edu_wpi_first_hal_can_CANJNI_getCANStatus
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_can_CANJNI
|
||||
* Method: openCANStreamSession
|
||||
* Signature: (III)I
|
||||
* Signature: (IIII)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_can_CANJNI_openCANStreamSession
|
||||
(JNIEnv* env, jclass, jint messageID, jint messageIDMask, jint maxMessages)
|
||||
(JNIEnv* env, jclass, jint busId, jint messageId, jint messageIDMask,
|
||||
jint maxMessages)
|
||||
{
|
||||
uint32_t handle = 0;
|
||||
int32_t status = 0;
|
||||
HAL_CAN_OpenStreamSession(&handle, static_cast<uint32_t>(messageID),
|
||||
static_cast<uint32_t>(messageIDMask),
|
||||
static_cast<uint32_t>(maxMessages), &status);
|
||||
HAL_CANStreamHandle handle =
|
||||
HAL_CAN_OpenStreamSession(busId, static_cast<uint32_t>(messageId),
|
||||
static_cast<uint32_t>(messageIDMask),
|
||||
static_cast<uint32_t>(maxMessages), &status);
|
||||
|
||||
if (!CheckStatus(env, status)) {
|
||||
return static_cast<jint>(0);
|
||||
@@ -182,14 +214,17 @@ Java_edu_wpi_first_hal_can_CANJNI_readCANStreamSession
|
||||
}
|
||||
}
|
||||
JLocal<jbyteArray> toSetArray{
|
||||
env, SetCANStreamObject(env, elem, msg->dataSize, msg->messageID,
|
||||
msg->timeStamp)};
|
||||
env, SetCANStreamObject(env, elem, msg->message.message.dataSize,
|
||||
msg->messageId, msg->message.timeStamp)};
|
||||
auto javaLen = env->GetArrayLength(toSetArray);
|
||||
if (javaLen < msg->dataSize) {
|
||||
msg->dataSize = javaLen;
|
||||
if (javaLen < msg->message.message.dataSize) {
|
||||
ThrowIllegalArgumentException(
|
||||
env, "Message buffer not long enough for message");
|
||||
return PARAMETER_OUT_OF_RANGE;
|
||||
}
|
||||
env->SetByteArrayRegion(toSetArray, 0, msg->dataSize,
|
||||
reinterpret_cast<jbyte*>(msg->data));
|
||||
env->SetByteArrayRegion(
|
||||
toSetArray, 0, msg->message.message.dataSize,
|
||||
reinterpret_cast<jbyte*>(msg->message.message.data));
|
||||
}
|
||||
|
||||
if (status == HAL_ERR_CANSessionMux_SessionOverrun) {
|
||||
|
||||
@@ -19,15 +19,15 @@ extern "C" {
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_CTREPCMJNI
|
||||
* Method: initialize
|
||||
* Signature: (I)I
|
||||
* Signature: (II)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_CTREPCMJNI_initialize
|
||||
(JNIEnv* env, jclass, jint module)
|
||||
(JNIEnv* env, jclass, jint busId, jint module)
|
||||
{
|
||||
int32_t status = 0;
|
||||
auto stack = wpi::java::GetJavaStackTrace(env, "edu.wpi.first");
|
||||
auto handle = HAL_InitializeCTREPCM(module, stack.c_str(), &status);
|
||||
auto handle = HAL_InitializeCTREPCM(busId, module, stack.c_str(), &status);
|
||||
CheckStatusForceThrow(env, status);
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -41,17 +41,13 @@ static JException illegalArgExCls;
|
||||
static JException boundaryExCls;
|
||||
static JException allocationExCls;
|
||||
static JException halHandleExCls;
|
||||
static JException canInvalidBufferExCls;
|
||||
static JException canMessageNotFoundExCls;
|
||||
static JException canMessageNotAllowedExCls;
|
||||
static JException canNotInitializedExCls;
|
||||
static JException uncleanStatusExCls;
|
||||
static JException nullPointerEx;
|
||||
static JClass powerDistributionVersionCls;
|
||||
static JClass pwmConfigDataResultCls;
|
||||
static JClass canStatusCls;
|
||||
static JClass matchInfoDataCls;
|
||||
static JClass canDataCls;
|
||||
static JClass canReceiveMessageCls;
|
||||
static JClass canStreamMessageCls;
|
||||
static JClass halValueCls;
|
||||
static JClass revPHVersionCls;
|
||||
@@ -63,8 +59,8 @@ static const JClassInit classes[] = {
|
||||
{"edu/wpi/first/hal/PWMConfigDataResult", &pwmConfigDataResultCls},
|
||||
{"edu/wpi/first/hal/can/CANStatus", &canStatusCls},
|
||||
{"edu/wpi/first/hal/MatchInfoData", &matchInfoDataCls},
|
||||
{"edu/wpi/first/hal/CANData", &canDataCls},
|
||||
{"edu/wpi/first/hal/CANStreamMessage", &canStreamMessageCls},
|
||||
{"edu/wpi/first/hal/can/CANReceiveMessage", &canReceiveMessageCls},
|
||||
{"edu/wpi/first/hal/can/CANStreamMessage", &canStreamMessageCls},
|
||||
{"edu/wpi/first/hal/HALValue", &halValueCls},
|
||||
{"edu/wpi/first/hal/REVPHVersion", &revPHVersionCls},
|
||||
{"edu/wpi/first/hal/can/CANStreamOverflowException",
|
||||
@@ -75,13 +71,6 @@ static const JExceptionInit exceptions[] = {
|
||||
{"edu/wpi/first/hal/util/BoundaryException", &boundaryExCls},
|
||||
{"edu/wpi/first/hal/util/AllocationException", &allocationExCls},
|
||||
{"edu/wpi/first/hal/util/HalHandleException", &halHandleExCls},
|
||||
{"edu/wpi/first/hal/can/CANInvalidBufferException", &canInvalidBufferExCls},
|
||||
{"edu/wpi/first/hal/can/CANMessageNotFoundException",
|
||||
&canMessageNotFoundExCls},
|
||||
{"edu/wpi/first/hal/can/CANMessageNotAllowedException",
|
||||
&canMessageNotAllowedExCls},
|
||||
{"edu/wpi/first/hal/can/CANNotInitializedException",
|
||||
&canNotInitializedExCls},
|
||||
{"edu/wpi/first/hal/util/UncleanStatusException", &uncleanStatusExCls},
|
||||
{"java/lang/NullPointerException", &nullPointerEx}};
|
||||
|
||||
@@ -152,64 +141,6 @@ void ThrowError(JNIEnv* env, int32_t status, int32_t minRange, int32_t maxRange,
|
||||
env, fmt::format(" Code: {}. {}", status, lastError).c_str(), status);
|
||||
}
|
||||
|
||||
void ReportCANError(JNIEnv* env, int32_t status, int message_id) {
|
||||
if (status >= 0) {
|
||||
return;
|
||||
}
|
||||
switch (status) {
|
||||
case kRioStatusSuccess:
|
||||
// Everything is ok... don't throw.
|
||||
break;
|
||||
case HAL_ERR_CANSessionMux_InvalidBuffer:
|
||||
case kRIOStatusBufferInvalidSize: {
|
||||
static jmethodID invalidBufConstruct = nullptr;
|
||||
if (!invalidBufConstruct) {
|
||||
invalidBufConstruct =
|
||||
env->GetMethodID(canInvalidBufferExCls, "<init>", "()V");
|
||||
}
|
||||
jobject exception =
|
||||
env->NewObject(canInvalidBufferExCls, invalidBufConstruct);
|
||||
env->Throw(static_cast<jthrowable>(exception));
|
||||
break;
|
||||
}
|
||||
case HAL_ERR_CANSessionMux_MessageNotFound:
|
||||
case kRIOStatusOperationTimedOut: {
|
||||
static jmethodID messageNotFoundConstruct = nullptr;
|
||||
if (!messageNotFoundConstruct) {
|
||||
messageNotFoundConstruct =
|
||||
env->GetMethodID(canMessageNotFoundExCls, "<init>", "()V");
|
||||
}
|
||||
jobject exception =
|
||||
env->NewObject(canMessageNotFoundExCls, messageNotFoundConstruct);
|
||||
env->Throw(static_cast<jthrowable>(exception));
|
||||
break;
|
||||
}
|
||||
case HAL_ERR_CANSessionMux_NotAllowed:
|
||||
case kRIOStatusFeatureNotSupported: {
|
||||
canMessageNotAllowedExCls.Throw(
|
||||
env, fmt::format("MessageID = {}", message_id).c_str());
|
||||
break;
|
||||
}
|
||||
case HAL_ERR_CANSessionMux_NotInitialized:
|
||||
case kRIOStatusResourceNotInitialized: {
|
||||
static jmethodID notInitConstruct = nullptr;
|
||||
if (!notInitConstruct) {
|
||||
notInitConstruct =
|
||||
env->GetMethodID(canNotInitializedExCls, "<init>", "()V");
|
||||
}
|
||||
jobject exception =
|
||||
env->NewObject(canNotInitializedExCls, notInitConstruct);
|
||||
env->Throw(static_cast<jthrowable>(exception));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
uncleanStatusExCls.Throw(
|
||||
env, fmt::format("Fatal status code detected: {}", status).c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThrowNullPointerException(JNIEnv* env, std::string_view msg) {
|
||||
nullPointerEx.Throw(env, msg);
|
||||
}
|
||||
@@ -302,24 +233,27 @@ void SetMatchInfoObject(JNIEnv* env, jobject matchStatus,
|
||||
static_cast<jint>(matchInfo.matchType));
|
||||
}
|
||||
|
||||
jbyteArray SetCANDataObject(JNIEnv* env, jobject canData, int32_t length,
|
||||
uint64_t timestamp) {
|
||||
static jmethodID func = env->GetMethodID(canDataCls, "setData", "(IJ)[B");
|
||||
jbyteArray SetCANReceiveMessageObject(JNIEnv* env, jobject canData,
|
||||
int32_t length, int32_t flags,
|
||||
uint64_t timestamp) {
|
||||
static jmethodID func =
|
||||
env->GetMethodID(canReceiveMessageCls, "setReceiveData", "(IIJ)[B");
|
||||
|
||||
jbyteArray retVal = static_cast<jbyteArray>(env->CallObjectMethod(
|
||||
canData, func, static_cast<jint>(length), static_cast<jlong>(timestamp)));
|
||||
canData, func, static_cast<jint>(length), static_cast<jint>(flags),
|
||||
static_cast<jlong>(timestamp)));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
jbyteArray SetCANStreamObject(JNIEnv* env, jobject canStreamData,
|
||||
int32_t length, uint32_t messageID,
|
||||
int32_t length, uint32_t messageId,
|
||||
uint64_t timestamp) {
|
||||
static jmethodID func =
|
||||
env->GetMethodID(canStreamMessageCls, "setStreamData", "(IIJ)[B");
|
||||
|
||||
jbyteArray retVal = static_cast<jbyteArray>(env->CallObjectMethod(
|
||||
canStreamData, func, static_cast<jint>(length),
|
||||
static_cast<jint>(messageID), static_cast<jlong>(timestamp)));
|
||||
static_cast<jint>(messageId), static_cast<jlong>(timestamp)));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,15 +42,6 @@ inline bool CheckStatusForceThrow(JNIEnv* env, int32_t status) {
|
||||
return status == 0;
|
||||
}
|
||||
|
||||
void ReportCANError(JNIEnv* env, int32_t status, int32_t message_id);
|
||||
|
||||
inline bool CheckCANStatus(JNIEnv* env, int32_t status, int32_t message_id) {
|
||||
if (status != 0) {
|
||||
ReportCANError(env, status, message_id);
|
||||
}
|
||||
return status == 0;
|
||||
}
|
||||
|
||||
void ThrowNullPointerException(JNIEnv* env, std::string_view msg);
|
||||
void ThrowCANStreamOverflowException(JNIEnv* env, jobjectArray messages,
|
||||
jint length);
|
||||
@@ -75,11 +66,12 @@ void SetCanStatusObject(JNIEnv* env, jobject canStatus,
|
||||
void SetMatchInfoObject(JNIEnv* env, jobject matchStatus,
|
||||
const HAL_MatchInfo& matchInfo);
|
||||
|
||||
jbyteArray SetCANDataObject(JNIEnv* env, jobject canData, int32_t length,
|
||||
uint64_t timestamp);
|
||||
jbyteArray SetCANReceiveMessageObject(JNIEnv* env, jobject canData,
|
||||
int32_t length, int32_t flags,
|
||||
uint64_t timestamp);
|
||||
|
||||
jbyteArray SetCANStreamObject(JNIEnv* env, jobject canStreamData,
|
||||
int32_t length, uint32_t messageID,
|
||||
int32_t length, uint32_t messageId,
|
||||
uint64_t timestamp);
|
||||
|
||||
jobject CreateHALValue(JNIEnv* env, const HAL_Value& value);
|
||||
|
||||
@@ -13,6 +13,19 @@
|
||||
using namespace hal;
|
||||
|
||||
extern "C" {
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_PortsJNI
|
||||
* Method: getNumCanBuses
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_PortsJNI_getNumCanBuses
|
||||
(JNIEnv*, jclass)
|
||||
{
|
||||
jint value = HAL_GetNumCanBuses();
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_PortsJNI
|
||||
* Method: getNumAnalogInputs
|
||||
|
||||
@@ -27,17 +27,17 @@ extern "C" {
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_PowerDistributionJNI
|
||||
* Method: initialize
|
||||
* Signature: (II)I
|
||||
* Signature: (III)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_PowerDistributionJNI_initialize
|
||||
(JNIEnv* env, jclass, jint module, jint type)
|
||||
(JNIEnv* env, jclass, jint busId, jint module, jint type)
|
||||
{
|
||||
int32_t status = 0;
|
||||
auto stack = wpi::java::GetJavaStackTrace(env, "edu.wpi.first");
|
||||
auto handle = HAL_InitializePowerDistribution(
|
||||
module, static_cast<HAL_PowerDistributionType>(type), stack.c_str(),
|
||||
&status);
|
||||
busId, module, static_cast<HAL_PowerDistributionType>(type),
|
||||
stack.c_str(), &status);
|
||||
CheckStatusForceThrow(env, status);
|
||||
return static_cast<jint>(handle);
|
||||
}
|
||||
|
||||
@@ -32,15 +32,15 @@ extern "C" {
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_REVPHJNI
|
||||
* Method: initialize
|
||||
* Signature: (I)I
|
||||
* Signature: (II)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_REVPHJNI_initialize
|
||||
(JNIEnv* env, jclass, jint module)
|
||||
(JNIEnv* env, jclass, jint busId, jint module)
|
||||
{
|
||||
int32_t status = 0;
|
||||
auto stack = wpi::java::GetJavaStackTrace(env, "edu.wpi.first");
|
||||
auto handle = HAL_InitializeREVPH(module, stack.c_str(), &status);
|
||||
auto handle = HAL_InitializeREVPH(busId, module, stack.c_str(), &status);
|
||||
CheckStatusForceThrow(env, status);
|
||||
return handle;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user