From ed18693345594d1373591ef71c53639ade6635c0 Mon Sep 17 00:00:00 2001 From: Thad House Date: Sat, 29 Aug 2020 23:07:22 -0700 Subject: [PATCH] [hal] Add no throw/error version of CAN Write methods (#2063) --- .../java/edu/wpi/first/hal/CANAPIJNI.java | 7 +++ hal/src/main/native/cpp/jni/CANAPIJNI.cpp | 53 +++++++++++++++++++ wpilibc/src/main/native/cpp/CAN.cpp | 21 +++++++- wpilibc/src/main/native/include/frc/CAN.h | 32 +++++++++++ .../main/java/edu/wpi/first/wpilibj/CAN.java | 36 ++++++++++++- 5 files changed, 147 insertions(+), 2 deletions(-) diff --git a/hal/src/main/java/edu/wpi/first/hal/CANAPIJNI.java b/hal/src/main/java/edu/wpi/first/hal/CANAPIJNI.java index 029cc6d5e9..e07839bf20 100644 --- a/hal/src/main/java/edu/wpi/first/hal/CANAPIJNI.java +++ b/hal/src/main/java/edu/wpi/first/hal/CANAPIJNI.java @@ -20,6 +20,13 @@ public class CANAPIJNI extends JNIWrapper { public static native void writeCANRTRFrame(int handle, int length, int apiId); + public static native int writeCANPacketNoThrow(int handle, byte[] data, int apiId); + + public static native int writeCANPacketRepeatingNoThrow(int handle, byte[] data, int apiId, + int repeatMs); + + public static native int writeCANRTRFrameNoThrow(int handle, int length, int apiId); + public static native void stopCANPacketRepeating(int handle, int apiId); public static native boolean readCANPacketNew(int handle, int apiId, CANData data); diff --git a/hal/src/main/native/cpp/jni/CANAPIJNI.cpp b/hal/src/main/native/cpp/jni/CANAPIJNI.cpp index bf28b54915..f42cc2f98a 100644 --- a/hal/src/main/native/cpp/jni/CANAPIJNI.cpp +++ b/hal/src/main/native/cpp/jni/CANAPIJNI.cpp @@ -107,6 +107,59 @@ Java_edu_wpi_first_hal_CANAPIJNI_writeCANRTRFrame CheckStatus(env, status); } +/* + * Class: edu_wpi_first_hal_CANAPIJNI + * Method: writeCANPacketNoThrow + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL +Java_edu_wpi_first_hal_CANAPIJNI_writeCANPacketNoThrow + (JNIEnv* env, jclass, jint handle, jbyteArray data, jint apiId) +{ + auto halHandle = static_cast(handle); + JByteArrayRef arr{env, data}; + auto arrRef = arr.array(); + int32_t status = 0; + HAL_WriteCANPacket(halHandle, reinterpret_cast(arrRef.data()), + arrRef.size(), apiId, &status); + return status; +} + +/* + * Class: edu_wpi_first_hal_CANAPIJNI + * Method: writeCANPacketRepeatingNoThrow + * Signature: (I[BII)I + */ +JNIEXPORT jint JNICALL +Java_edu_wpi_first_hal_CANAPIJNI_writeCANPacketRepeatingNoThrow + (JNIEnv* env, jclass, jint handle, jbyteArray data, jint apiId, + jint timeoutMs) +{ + auto halHandle = static_cast(handle); + JByteArrayRef arr{env, data}; + auto arrRef = arr.array(); + int32_t status = 0; + HAL_WriteCANPacketRepeating(halHandle, + reinterpret_cast(arrRef.data()), + arrRef.size(), apiId, timeoutMs, &status); + return status; +} + +/* + * Class: edu_wpi_first_hal_CANAPIJNI + * Method: writeCANRTRFrameNoThrow + * Signature: (III)I + */ +JNIEXPORT jint JNICALL +Java_edu_wpi_first_hal_CANAPIJNI_writeCANRTRFrameNoThrow + (JNIEnv* env, jclass, jint handle, jint length, jint apiId) +{ + auto halHandle = static_cast(handle); + int32_t status = 0; + HAL_WriteCANRTRFrame(halHandle, static_cast(length), apiId, &status); + return status; +} + /* * Class: edu_wpi_first_hal_CANAPIJNI * Method: stopCANPacketRepeating diff --git a/wpilibc/src/main/native/cpp/CAN.cpp b/wpilibc/src/main/native/cpp/CAN.cpp index 797b9ff4e3..e56e435514 100644 --- a/wpilibc/src/main/native/cpp/CAN.cpp +++ b/wpilibc/src/main/native/cpp/CAN.cpp @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */ +/* Copyright (c) 2018-2020 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. */ @@ -70,6 +70,25 @@ void CAN::WriteRTRFrame(int length, int apiId) { wpi_setHALError(status); } +int CAN::WritePacketNoError(const uint8_t* data, int length, int apiId) { + int32_t status = 0; + HAL_WriteCANPacket(m_handle, data, length, apiId, &status); + return status; +} + +int CAN::WritePacketRepeatingNoError(const uint8_t* data, int length, int apiId, + int repeatMs) { + int32_t status = 0; + HAL_WriteCANPacketRepeating(m_handle, data, length, apiId, repeatMs, &status); + return status; +} + +int CAN::WriteRTRFrameNoError(int length, int apiId) { + int32_t status = 0; + HAL_WriteCANRTRFrame(m_handle, length, apiId, &status); + return status; +} + void CAN::StopPacketRepeating(int apiId) { int32_t status = 0; HAL_StopCANPacketRepeating(m_handle, apiId, &status); diff --git a/wpilibc/src/main/native/include/frc/CAN.h b/wpilibc/src/main/native/include/frc/CAN.h index ed861fb4a7..a01f3a5955 100644 --- a/wpilibc/src/main/native/include/frc/CAN.h +++ b/wpilibc/src/main/native/include/frc/CAN.h @@ -93,6 +93,38 @@ class CAN : public ErrorBase { */ void WriteRTRFrame(int length, int apiId); + /** + * Write a packet to the CAN device with a specific ID. This ID is 10 bits. + * + * @param data The data to write (8 bytes max) + * @param length The data length to write + * @param apiId The API ID to write. + */ + int WritePacketNoError(const uint8_t* data, int length, int apiId); + + /** + * Write a repeating packet to the CAN device with a specific ID. This ID is + * 10 bits. The RoboRIO will automatically repeat the packet at the specified + * interval + * + * @param data The data to write (8 bytes max) + * @param length The data length to write + * @param apiId The API ID to write. + * @param repeatMs The period to repeat the packet at. + */ + int WritePacketRepeatingNoError(const uint8_t* data, int length, int apiId, + int repeatMs); + + /** + * Write an RTR frame to the CAN device with a specific ID. This ID is 10 + * bits. The length by spec must match what is returned by the responding + * device + * + * @param length The length to request (0 to 8) + * @param apiId The API ID to write. + */ + int WriteRTRFrameNoError(int length, int apiId); + /** * Stop a repeating packet with a specific ID. This ID is 10 bits. * diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/CAN.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/CAN.java index 7b188e552f..d24fcc23a9 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/CAN.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/CAN.java @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */ +/* Copyright (c) 2018-2020 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. */ @@ -25,6 +25,7 @@ import edu.wpi.first.hal.HAL; * read methods and the byte[] passed into the write methods need to not * be modified for the duration of their respective calls. */ +@SuppressWarnings("PMD.TooManyMethods") public class CAN implements Closeable { public static final int kTeamManufacturer = 8; public static final int kTeamDeviceType = 10; @@ -100,6 +101,39 @@ public class CAN implements Closeable { CANAPIJNI.writeCANRTRFrame(m_handle, length, apiId); } + /** + * Write a packet to the CAN device with a specific ID. This ID is 10 bits. + * + * @param data The data to write (8 bytes max) + * @param apiId The API ID to write. + */ + public int writePacketNoThrow(byte[] data, int apiId) { + return CANAPIJNI.writeCANPacketNoThrow(m_handle, data, apiId); + } + + /** + * Write a repeating packet to the CAN device with a specific ID. This ID is 10 bits. + * The RoboRIO will automatically repeat the packet at the specified interval + * + * @param data The data to write (8 bytes max) + * @param apiId The API ID to write. + * @param repeatMs The period to repeat the packet at. + */ + public int writePacketRepeatingNoThrow(byte[] data, int apiId, int repeatMs) { + return CANAPIJNI.writeCANPacketRepeatingNoThrow(m_handle, data, apiId, repeatMs); + } + + /** + * Write an RTR frame to the CAN device with a specific ID. This ID is 10 bits. + * The length by spec must match what is returned by the responding device + * + * @param length The length to request (0 to 8) + * @param apiId The API ID to write. + */ + public int writeRTRFrameNoThrow(int length, int apiId) { + return CANAPIJNI.writeCANRTRFrameNoThrow(m_handle, length, apiId); + } + /** * Stop a repeating packet with a specific ID. This ID is 10 bits. *