diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/AddressableLEDSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/AddressableLEDSim.java new file mode 100644 index 0000000000..cc6eefa244 --- /dev/null +++ b/hal/src/main/java/edu/wpi/first/hal/sim/AddressableLEDSim.java @@ -0,0 +1,77 @@ +/*----------------------------------------------------------------------------*/ +/* 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. */ +/*----------------------------------------------------------------------------*/ + +package edu.wpi.first.hal.sim; + +import edu.wpi.first.hal.sim.mockdata.AddressableLEDDataJNI; + +public class AddressableLEDSim { + private final int m_index; + + public AddressableLEDSim(int index) { + m_index = index; + } + + public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) { + int uid = AddressableLEDDataJNI.registerInitializedCallback(m_index, callback, initialNotify); + return new CallbackStore(m_index, uid, AddressableLEDDataJNI::cancelInitializedCallback); + } + public boolean getInitialized() { + return AddressableLEDDataJNI.getInitialized(m_index); + } + public void setInitialized(boolean initialized) { + AddressableLEDDataJNI.setInitialized(m_index, initialized); + } + + public CallbackStore registerOutputPortCallback(NotifyCallback callback, boolean initialNotify) { + int uid = AddressableLEDDataJNI.registerOutputPortCallback(m_index, callback, initialNotify); + return new CallbackStore(m_index, uid, AddressableLEDDataJNI::cancelOutputPortCallback); + } + public int getOutputPort() { + return AddressableLEDDataJNI.getOutputPort(m_index); + } + public void setOutputPort(int outputPort) { + AddressableLEDDataJNI.setOutputPort(m_index, outputPort); + } + + public CallbackStore registerLengthCallback(NotifyCallback callback, boolean initialNotify) { + int uid = AddressableLEDDataJNI.registerLengthCallback(m_index, callback, initialNotify); + return new CallbackStore(m_index, uid, AddressableLEDDataJNI::cancelLengthCallback); + } + public int getLength() { + return AddressableLEDDataJNI.getLength(m_index); + } + public void setLength(int length) { + AddressableLEDDataJNI.setLength(m_index, length); + } + + public CallbackStore registerRunningCallback(NotifyCallback callback, boolean initialNotify) { + int uid = AddressableLEDDataJNI.registerRunningCallback(m_index, callback, initialNotify); + return new CallbackStore(m_index, uid, AddressableLEDDataJNI::cancelRunningCallback); + } + public boolean getRunning() { + return AddressableLEDDataJNI.getRunning(m_index); + } + public void setRunning(boolean running) { + AddressableLEDDataJNI.setRunning(m_index, running); + } + + public CallbackStore registerDataCallback(ConstBufferCallback callback) { + int uid = AddressableLEDDataJNI.registerDataCallback(m_index, callback); + return new CallbackStore(m_index, uid, AddressableLEDDataJNI::cancelDataCallback); + } + public byte[] getData() { + return AddressableLEDDataJNI.getData(m_index); + } + public void setData(byte[] data) { + AddressableLEDDataJNI.setData(m_index, data); + } + + public void resetData() { + AddressableLEDDataJNI.resetData(m_index); + } +} diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AddressableLEDDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AddressableLEDDataJNI.java new file mode 100644 index 0000000000..8098e6813a --- /dev/null +++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AddressableLEDDataJNI.java @@ -0,0 +1,41 @@ +/*----------------------------------------------------------------------------*/ +/* 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. */ +/*----------------------------------------------------------------------------*/ + +package edu.wpi.first.hal.sim.mockdata; + +import edu.wpi.first.hal.sim.ConstBufferCallback; +import edu.wpi.first.hal.sim.NotifyCallback; +import edu.wpi.first.hal.JNIWrapper; + +public class AddressableLEDDataJNI extends JNIWrapper { + public static native int registerInitializedCallback(int index, NotifyCallback callback, boolean initialNotify); + public static native void cancelInitializedCallback(int index, int uid); + public static native boolean getInitialized(int index); + public static native void setInitialized(int index, boolean initialized); + + public static native int registerOutputPortCallback(int index, NotifyCallback callback, boolean initialNotify); + public static native void cancelOutputPortCallback(int index, int uid); + public static native int getOutputPort(int index); + public static native void setOutputPort(int index, int outputPort); + + public static native int registerLengthCallback(int index, NotifyCallback callback, boolean initialNotify); + public static native void cancelLengthCallback(int index, int uid); + public static native int getLength(int index); + public static native void setLength(int index, int length); + + public static native int registerRunningCallback(int index, NotifyCallback callback, boolean initialNotify); + public static native void cancelRunningCallback(int index, int uid); + public static native boolean getRunning(int index); + public static native void setRunning(int index, boolean running); + + public static native int registerDataCallback(int index, ConstBufferCallback callback); + public static native void cancelDataCallback(int index, int uid); + public static native byte[] getData(int index); + public static native void setData(int index, byte[] data); + + public static native void resetData(int index); +} diff --git a/hal/src/main/native/athena/AddressableLED.cpp b/hal/src/main/native/athena/AddressableLED.cpp index 44e16b183a..f1d94974b2 100644 --- a/hal/src/main/native/athena/AddressableLED.cpp +++ b/hal/src/main/native/athena/AddressableLED.cpp @@ -20,8 +20,6 @@ using namespace hal; -constexpr int32_t kMaxStringSize = 5460; - extern "C" { NiFpga_Status NiFpga_ClientFunctionCall(NiFpga_Session session, uint32_t group, uint32_t functionId, @@ -180,7 +178,7 @@ void HAL_SetAddressableLEDLength(HAL_AddressableLEDHandle handle, return; } - if (length > kMaxStringSize) { + if (length > HAL_kAddressableLEDMaxLength) { *status = PARAMETER_OUT_OF_RANGE; return; } diff --git a/hal/src/main/native/athena/Ports.cpp b/hal/src/main/native/athena/Ports.cpp index 525acac91d..47bd400658 100644 --- a/hal/src/main/native/athena/Ports.cpp +++ b/hal/src/main/native/athena/Ports.cpp @@ -38,5 +38,6 @@ int32_t HAL_GetNumSolenoidChannels(void) { return kNumSolenoidChannels; } int32_t HAL_GetNumPDPModules(void) { return kNumPDPModules; } int32_t HAL_GetNumPDPChannels(void) { return kNumPDPChannels; } int32_t HAL_GetNumDutyCycles(void) { return kNumDutyCycles; } +int32_t HAL_GetNumAddressableLEDs(void) { return kNumAddressableLEDs; } } // extern "C" diff --git a/hal/src/main/native/cpp/jni/AddressableLEDJNI.cpp b/hal/src/main/native/cpp/jni/AddressableLEDJNI.cpp index 2ca0e4b291..3f76e6a88c 100644 --- a/hal/src/main/native/cpp/jni/AddressableLEDJNI.cpp +++ b/hal/src/main/native/cpp/jni/AddressableLEDJNI.cpp @@ -16,6 +16,8 @@ using namespace frc; using namespace wpi::java; +static_assert(sizeof(jbyte) * 4 == sizeof(HAL_AddressableLEDData)); + extern "C" { /* * Class: edu_wpi_first_hal_AddressableLEDJNI diff --git a/hal/src/main/native/include/hal/AddressableLEDTypes.h b/hal/src/main/native/include/hal/AddressableLEDTypes.h index f1fb4fcc0e..bdcd742719 100644 --- a/hal/src/main/native/include/hal/AddressableLEDTypes.h +++ b/hal/src/main/native/include/hal/AddressableLEDTypes.h @@ -9,6 +9,8 @@ #include +#define HAL_kAddressableLEDMaxLength 5460 + struct HAL_AddressableLEDData { uint8_t b; uint8_t g; diff --git a/hal/src/main/native/include/hal/Ports.h b/hal/src/main/native/include/hal/Ports.h index 1992cdb31c..584bc4f4db 100644 --- a/hal/src/main/native/include/hal/Ports.h +++ b/hal/src/main/native/include/hal/Ports.h @@ -151,6 +151,13 @@ int32_t HAL_GetNumPDPChannels(void); * @return the number of Duty Cycle inputs */ int32_t HAL_GetNumDutyCycles(void); + +/** + * Gets the number of addressable LED generators in the current system. + * + * @return the number of Addressable LED generators + */ +int32_t HAL_GetNumAddressableLEDs(void); #ifdef __cplusplus } // extern "C" #endif diff --git a/hal/src/main/native/include/mockdata/AddressableLEDData.h b/hal/src/main/native/include/mockdata/AddressableLEDData.h new file mode 100644 index 0000000000..0d8f3f32da --- /dev/null +++ b/hal/src/main/native/include/mockdata/AddressableLEDData.h @@ -0,0 +1,65 @@ +/*----------------------------------------------------------------------------*/ +/* 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. */ +/*----------------------------------------------------------------------------*/ + +#pragma once + +#include "NotifyListener.h" +#include "hal/AddressableLEDTypes.h" +#include "hal/Types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void HALSIM_ResetAddressableLEDData(int32_t index); + +int32_t HALSIM_RegisterAddressableLEDInitializedCallback( + int32_t index, HAL_NotifyCallback callback, void* param, + HAL_Bool initialNotify); +void HALSIM_CancelAddressableLEDInitializedCallback(int32_t index, int32_t uid); +HAL_Bool HALSIM_GetAddressableLEDInitialized(int32_t index); +void HALSIM_SetAddressableLEDInitialized(int32_t index, HAL_Bool initialized); + +int32_t HALSIM_RegisterAddressableLEDOutputPortCallback( + int32_t index, HAL_NotifyCallback callback, void* param, + HAL_Bool initialNotify); +void HALSIM_CancelAddressableLEDOutputPortCallback(int32_t index, int32_t uid); +int32_t HALSIM_GetAddressableLEDOutputPort(int32_t index); +void HALSIM_SetAddressableLEDOutputPort(int32_t index, int32_t outputPort); + +int32_t HALSIM_RegisterAddressableLEDLengthCallback(int32_t index, + HAL_NotifyCallback callback, + void* param, + HAL_Bool initialNotify); +void HALSIM_CancelAddressableLEDLengthCallback(int32_t index, int32_t uid); +int32_t HALSIM_GetAddressableLEDLength(int32_t index); +void HALSIM_SetAddressableLEDLength(int32_t index, int32_t length); + +int32_t HALSIM_RegisterAddressableLEDRunningCallback( + int32_t index, HAL_NotifyCallback callback, void* param, + HAL_Bool initialNotify); +void HALSIM_CancelAddressableLEDRunningCallback(int32_t index, int32_t uid); +HAL_Bool HALSIM_GetAddressableLEDRunning(int32_t index); +void HALSIM_SetAddressableLEDRunning(int32_t index, HAL_Bool running); + +int32_t HALSIM_RegisterAddressableLEDDataCallback( + int32_t index, HAL_ConstBufferCallback callback, void* param); +void HALSIM_CancelAddressableLEDDataCallback(int32_t index, int32_t uid); +int32_t HALSIM_GetAddressableLEDData(int32_t index, + struct HAL_AddressableLEDData* data); +void HALSIM_SetAddressableLEDData(int32_t index, + const struct HAL_AddressableLEDData* data, + int32_t length); + +void HALSIM_RegisterAddressableLEDAllCallbacks(int32_t index, + HAL_NotifyCallback callback, + void* param, + HAL_Bool initialNotify); + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/hal/src/main/native/sim/AddressableLED.cpp b/hal/src/main/native/sim/AddressableLED.cpp index 63d23d9929..90dee86841 100644 --- a/hal/src/main/native/sim/AddressableLED.cpp +++ b/hal/src/main/native/sim/AddressableLED.cpp @@ -7,24 +7,119 @@ #include "hal/AddressableLED.h" +#include "DigitalInternal.h" +#include "HALInitializer.h" +#include "PortsInternal.h" +#include "hal/Errors.h" +#include "hal/handles/HandlesInternal.h" +#include "hal/handles/LimitedHandleResource.h" +#include "mockdata/AddressableLEDDataInternal.h" + +using namespace hal; + +namespace { +struct AddressableLED { + uint8_t index; +}; +} // namespace + +static LimitedHandleResource* ledHandles; + +namespace hal { +namespace init { +void InitializeAddressableLED() { + static LimitedHandleResource + dcH; + ledHandles = &dcH; +} +} // namespace init +} // namespace hal + extern "C" { HAL_AddressableLEDHandle HAL_InitializeAddressableLED( HAL_DigitalHandle outputPort, int32_t* status) { - return HAL_kInvalidHandle; + hal::init::CheckInit(); + + HAL_AddressableLEDHandle handle = ledHandles->Allocate(); + if (handle == HAL_kInvalidHandle) { + *status = NO_AVAILABLE_RESOURCES; + return HAL_kInvalidHandle; + } + + auto led = ledHandles->Get(handle); + if (!led) { // would only occur on thread issue + *status = HAL_HANDLE_ERROR; + return HAL_kInvalidHandle; + } + + int16_t index = getHandleIndex(handle); + if (auto port = digitalChannelHandles->Get(outputPort, HAL_HandleEnum::PWM)) { + SimAddressableLEDData[index].outputPort = port->channel; + } else { + SimAddressableLEDData[index].outputPort = -1; + } + SimAddressableLEDData[index].length = 1; + SimAddressableLEDData[index].running = false; + SimAddressableLEDData[index].initialized = true; + led->index = index; + return handle; } -void HAL_FreeAddressableLED(HAL_AddressableLEDHandle handle) {} +void HAL_FreeAddressableLED(HAL_AddressableLEDHandle handle) { + auto led = ledHandles->Get(handle); + ledHandles->Free(handle); + if (!led) return; + SimAddressableLEDData[led->index].running = false; + SimAddressableLEDData[led->index].initialized = false; +} void HAL_SetAddressableLEDOutputPort(HAL_AddressableLEDHandle handle, HAL_DigitalHandle outputPort, - int32_t* status) {} + int32_t* status) { + auto led = ledHandles->Get(handle); + if (!led) { + *status = HAL_HANDLE_ERROR; + return; + } + if (auto port = digitalChannelHandles->Get(outputPort, HAL_HandleEnum::PWM)) { + SimAddressableLEDData[led->index].outputPort = port->channel; + } else { + SimAddressableLEDData[led->index].outputPort = -1; + } +} void HAL_SetAddressableLEDLength(HAL_AddressableLEDHandle handle, - int32_t length, int32_t* status) {} + int32_t length, int32_t* status) { + auto led = ledHandles->Get(handle); + if (!led) { + *status = HAL_HANDLE_ERROR; + return; + } + if (length > HAL_kAddressableLEDMaxLength) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } + SimAddressableLEDData[led->index].length = length; +} void HAL_WriteAddressableLEDData(HAL_AddressableLEDHandle handle, const struct HAL_AddressableLEDData* data, - int32_t length, int32_t* status) {} + int32_t length, int32_t* status) { + auto led = ledHandles->Get(handle); + if (!led) { + *status = HAL_HANDLE_ERROR; + return; + } + if (length > SimAddressableLEDData[led->index].length) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } + SimAddressableLEDData[led->index].SetData(data, length); +} void HAL_SetAddressableLEDBitTiming(HAL_AddressableLEDHandle handle, int32_t lowTime0NanoSeconds, @@ -38,8 +133,22 @@ void HAL_SetAddressableLEDSyncTime(HAL_AddressableLEDHandle handle, int32_t* status) {} void HAL_StartAddressableLEDOutput(HAL_AddressableLEDHandle handle, - int32_t* status) {} + int32_t* status) { + auto led = ledHandles->Get(handle); + if (!led) { + *status = HAL_HANDLE_ERROR; + return; + } + SimAddressableLEDData[led->index].running = true; +} void HAL_StopAddressableLEDOutput(HAL_AddressableLEDHandle handle, - int32_t* status) {} + int32_t* status) { + auto led = ledHandles->Get(handle); + if (!led) { + *status = HAL_HANDLE_ERROR; + return; + } + SimAddressableLEDData[led->index].running = false; +} } // extern "C" diff --git a/hal/src/main/native/sim/HAL.cpp b/hal/src/main/native/sim/HAL.cpp index 9e41251edc..6bb43f5b88 100644 --- a/hal/src/main/native/sim/HAL.cpp +++ b/hal/src/main/native/sim/HAL.cpp @@ -25,6 +25,7 @@ namespace hal { namespace init { void InitializeHAL() { InitializeAccelerometerData(); + InitializeAddressableLEDData(); InitializeAnalogGyroData(); InitializeAnalogInData(); InitializeAnalogOutData(); @@ -46,6 +47,7 @@ void InitializeHAL() { InitializeSPIAccelerometerData(); InitializeSPIData(); InitializeAccelerometer(); + InitializeAddressableLED(); InitializeAnalogAccumulator(); InitializeAnalogGyro(); InitializeAnalogInput(); diff --git a/hal/src/main/native/sim/HALInitializer.h b/hal/src/main/native/sim/HALInitializer.h index 8e68ac3911..c08df7398a 100644 --- a/hal/src/main/native/sim/HALInitializer.h +++ b/hal/src/main/native/sim/HALInitializer.h @@ -19,6 +19,7 @@ static inline void CheckInit() { } extern void InitializeAccelerometerData(); +extern void InitializeAddressableLEDData(); extern void InitializeAnalogGyroData(); extern void InitializeAnalogInData(); extern void InitializeAnalogOutData(); @@ -41,6 +42,7 @@ extern void InitializeSimDeviceData(); extern void InitializeSPIAccelerometerData(); extern void InitializeSPIData(); extern void InitializeAccelerometer(); +extern void InitializeAddressableLED(); extern void InitializeAnalogAccumulator(); extern void InitializeAnalogGyro(); extern void InitializeAnalogInput(); diff --git a/hal/src/main/native/sim/Ports.cpp b/hal/src/main/native/sim/Ports.cpp index a21eeb3626..2f670b36f4 100644 --- a/hal/src/main/native/sim/Ports.cpp +++ b/hal/src/main/native/sim/Ports.cpp @@ -37,4 +37,5 @@ int32_t HAL_GetNumSolenoidChannels(void) { return kNumSolenoidChannels; } int32_t HAL_GetNumPDPModules(void) { return kNumPDPModules; } int32_t HAL_GetNumPDPChannels(void) { return kNumPDPChannels; } int32_t HAL_GetNumDutyCycles(void) { return kNumDutyCycles; } +int32_t HAL_GetNumAddressableLEDs(void) { return kNumAddressableLEDs; } } // extern "C" diff --git a/hal/src/main/native/sim/PortsInternal.h b/hal/src/main/native/sim/PortsInternal.h index c830af01f6..cfbf1e7c2d 100644 --- a/hal/src/main/native/sim/PortsInternal.h +++ b/hal/src/main/native/sim/PortsInternal.h @@ -29,4 +29,5 @@ constexpr int32_t kNumSolenoidChannels = 8; constexpr int32_t kNumPDPModules = 63; constexpr int32_t kNumPDPChannels = 16; constexpr int32_t kNumDutyCycles = 8; +constexpr int32_t kNumAddressableLEDs = 1; } // namespace hal diff --git a/hal/src/main/native/sim/jni/AddressableLEDDataJNI.cpp b/hal/src/main/native/sim/jni/AddressableLEDDataJNI.cpp new file mode 100644 index 0000000000..530eae2e6f --- /dev/null +++ b/hal/src/main/native/sim/jni/AddressableLEDDataJNI.cpp @@ -0,0 +1,293 @@ +/*----------------------------------------------------------------------------*/ +/* 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. */ +/*----------------------------------------------------------------------------*/ + +#include + +#include "CallbackStore.h" +#include "ConstBufferCallbackStore.h" +#include "edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI.h" +#include "mockdata/AddressableLEDData.h" + +static_assert(sizeof(jbyte) * 4 == sizeof(HAL_AddressableLEDData)); + +using namespace wpi::java; + +extern "C" { + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: registerInitializedCallback + * Signature: (ILjava/lang/Object;Z)I + */ +JNIEXPORT jint JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_registerInitializedCallback + (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify) +{ + return sim::AllocateCallback( + env, index, callback, initialNotify, + &HALSIM_RegisterAddressableLEDInitializedCallback); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: cancelInitializedCallback + * Signature: (II)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_cancelInitializedCallback + (JNIEnv* env, jclass, jint index, jint handle) +{ + return sim::FreeCallback(env, handle, index, + &HALSIM_CancelAddressableLEDInitializedCallback); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: getInitialized + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_getInitialized + (JNIEnv*, jclass, jint index) +{ + return HALSIM_GetAddressableLEDInitialized(index); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: setInitialized + * Signature: (IZ)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_setInitialized + (JNIEnv*, jclass, jint index, jboolean value) +{ + HALSIM_SetAddressableLEDInitialized(index, value); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: registerOutputPortCallback + * Signature: (ILjava/lang/Object;Z)I + */ +JNIEXPORT jint JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_registerOutputPortCallback + (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify) +{ + return sim::AllocateCallback( + env, index, callback, initialNotify, + &HALSIM_RegisterAddressableLEDOutputPortCallback); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: cancelOutputPortCallback + * Signature: (II)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_cancelOutputPortCallback + (JNIEnv* env, jclass, jint index, jint handle) +{ + return sim::FreeCallback(env, handle, index, + &HALSIM_CancelAddressableLEDOutputPortCallback); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: getOutputPort + * Signature: (I)I + */ +JNIEXPORT jint JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_getOutputPort + (JNIEnv*, jclass, jint index) +{ + return HALSIM_GetAddressableLEDOutputPort(index); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: setOutputPort + * Signature: (II)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_setOutputPort + (JNIEnv*, jclass, jint index, jint value) +{ + HALSIM_SetAddressableLEDOutputPort(index, value); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: registerLengthCallback + * Signature: (ILjava/lang/Object;Z)I + */ +JNIEXPORT jint JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_registerLengthCallback + (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify) +{ + return sim::AllocateCallback(env, index, callback, initialNotify, + &HALSIM_RegisterAddressableLEDLengthCallback); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: cancelLengthCallback + * Signature: (II)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_cancelLengthCallback + (JNIEnv* env, jclass, jint index, jint handle) +{ + return sim::FreeCallback(env, handle, index, + &HALSIM_CancelAddressableLEDLengthCallback); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: getLength + * Signature: (I)I + */ +JNIEXPORT jint JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_getLength + (JNIEnv*, jclass, jint index) +{ + return HALSIM_GetAddressableLEDLength(index); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: setLength + * Signature: (II)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_setLength + (JNIEnv*, jclass, jint index, jint value) +{ + HALSIM_SetAddressableLEDLength(index, value); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: registerRunningCallback + * Signature: (ILjava/lang/Object;Z)I + */ +JNIEXPORT jint JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_registerRunningCallback + (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify) +{ + return sim::AllocateCallback(env, index, callback, initialNotify, + &HALSIM_RegisterAddressableLEDRunningCallback); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: cancelRunningCallback + * Signature: (II)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_cancelRunningCallback + (JNIEnv* env, jclass, jint index, jint handle) +{ + return sim::FreeCallback(env, handle, index, + &HALSIM_CancelAddressableLEDRunningCallback); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: getRunning + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_getRunning + (JNIEnv*, jclass, jint index) +{ + return HALSIM_GetAddressableLEDRunning(index); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: setRunning + * Signature: (IZ)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_setRunning + (JNIEnv*, jclass, jint index, jboolean value) +{ + HALSIM_SetAddressableLEDRunning(index, value); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: registerDataCallback + * Signature: (ILjava/lang/Object;)I + */ +JNIEXPORT jint JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_registerDataCallback + (JNIEnv* env, jclass, jint index, jobject callback) +{ + return sim::AllocateConstBufferCallback( + env, index, callback, &HALSIM_RegisterAddressableLEDDataCallback); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: cancelDataCallback + * Signature: (II)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_cancelDataCallback + (JNIEnv* env, jclass, jint index, jint handle) +{ + sim::FreeConstBufferCallback(env, handle, index, + &HALSIM_CancelAddressableLEDDataCallback); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: getData + * Signature: (I)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_getData + (JNIEnv* env, jclass, jint index) +{ + auto data = + std::make_unique(HAL_kAddressableLEDMaxLength); + int32_t length = HALSIM_GetAddressableLEDData(index, data.get()); + return MakeJByteArray( + env, wpi::ArrayRef(reinterpret_cast(data.get()), length * 4)); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: setData + * Signature: (I[B)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_setData + (JNIEnv* env, jclass, jint index, jbyteArray arr) +{ + JByteArrayRef jArrRef{env, arr}; + auto arrRef = jArrRef.array(); + HALSIM_SetAddressableLEDData( + index, reinterpret_cast(arrRef.data()), + arrRef.size() / 4); +} + +/* + * Class: edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI + * Method: resetData + * Signature: (I)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_sim_mockdata_AddressableLEDDataJNI_resetData + (JNIEnv*, jclass, jint index) +{ + HALSIM_ResetAddressableLEDData(index); +} + +} // extern "C" diff --git a/hal/src/main/native/sim/mockdata/AddressableLEDData.cpp b/hal/src/main/native/sim/mockdata/AddressableLEDData.cpp new file mode 100644 index 0000000000..5b44eaf53b --- /dev/null +++ b/hal/src/main/native/sim/mockdata/AddressableLEDData.cpp @@ -0,0 +1,96 @@ +/*----------------------------------------------------------------------------*/ +/* 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. */ +/*----------------------------------------------------------------------------*/ + +#include +#include + +#include "../PortsInternal.h" +#include "AddressableLEDDataInternal.h" + +using namespace hal; + +namespace hal { +namespace init { +void InitializeAddressableLEDData() { + static AddressableLEDData sad[kNumAddressableLEDs]; + ::hal::SimAddressableLEDData = sad; +} +} // namespace init +} // namespace hal + +AddressableLEDData* hal::SimAddressableLEDData; + +void AddressableLEDData::ResetData() { + initialized.Reset(false); + outputPort.Reset(-1); + length.Reset(1); + running.Reset(false); + data.Reset(); +} + +void AddressableLEDData::SetData(const HAL_AddressableLEDData* d, int32_t len) { + len = (std::min)(HAL_kAddressableLEDMaxLength, len); + { + std::scoped_lock lock(m_dataMutex); + std::memcpy(m_data, d, len * sizeof(d[0])); + } + data(reinterpret_cast(d), len * sizeof(d[0])); +} + +int32_t AddressableLEDData::GetData(HAL_AddressableLEDData* d) { + std::scoped_lock lock(m_dataMutex); + int32_t len = length; + if (d) std::memcpy(d, m_data, len * sizeof(d[0])); + return len; +} + +extern "C" { +void HALSIM_ResetAddressableLEDData(int32_t index) { + SimAddressableLEDData[index].ResetData(); +} + +int32_t HALSIM_GetAddressableLEDData(int32_t index, + struct HAL_AddressableLEDData* data) { + return SimAddressableLEDData[index].GetData(data); +} + +void HALSIM_SetAddressableLEDData(int32_t index, + const struct HAL_AddressableLEDData* data, + int32_t length) { + SimAddressableLEDData[index].SetData(data, length); +} + +#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \ + HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, AddressableLED##CAPINAME, \ + SimAddressableLEDData, LOWERNAME) + +DEFINE_CAPI(HAL_Bool, Initialized, initialized) +DEFINE_CAPI(int32_t, OutputPort, outputPort) +DEFINE_CAPI(int32_t, Length, length) +DEFINE_CAPI(HAL_Bool, Running, running) + +#undef DEFINE_CAPI +#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \ + HAL_SIMCALLBACKREGISTRY_DEFINE_CAPI(TYPE, HALSIM, AddressableLED##CAPINAME, \ + SimAddressableLEDData, LOWERNAME) + +DEFINE_CAPI(HAL_ConstBufferCallback, Data, data) + +#define REGISTER(NAME) \ + SimAddressableLEDData[index].NAME.RegisterCallback(callback, param, \ + initialNotify) + +void HALSIM_RegisterAddressableLEDAllCallbacks(int32_t index, + HAL_NotifyCallback callback, + void* param, + HAL_Bool initialNotify) { + REGISTER(initialized); + REGISTER(outputPort); + REGISTER(length); + REGISTER(running); +} +} // extern "C" diff --git a/hal/src/main/native/sim/mockdata/AddressableLEDDataInternal.h b/hal/src/main/native/sim/mockdata/AddressableLEDDataInternal.h new file mode 100644 index 0000000000..9d6e215e93 --- /dev/null +++ b/hal/src/main/native/sim/mockdata/AddressableLEDDataInternal.h @@ -0,0 +1,43 @@ +/*----------------------------------------------------------------------------*/ +/* 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. */ +/*----------------------------------------------------------------------------*/ + +#pragma once + +#include + +#include + +#include "mockdata/AddressableLEDData.h" +#include "mockdata/SimCallbackRegistry.h" +#include "mockdata/SimDataValue.h" + +namespace hal { +class AddressableLEDData { + HAL_SIMDATAVALUE_DEFINE_NAME(Initialized) + HAL_SIMDATAVALUE_DEFINE_NAME(OutputPort) + HAL_SIMDATAVALUE_DEFINE_NAME(Length) + HAL_SIMDATAVALUE_DEFINE_NAME(Running) + HAL_SIMDATAVALUE_DEFINE_NAME(Data) + + wpi::recursive_spinlock m_dataMutex; + HAL_AddressableLEDData m_data[HAL_kAddressableLEDMaxLength]; + + public: + void SetData(const HAL_AddressableLEDData* d, int32_t len); + int32_t GetData(HAL_AddressableLEDData* d); + + SimDataValue initialized{ + false}; + SimDataValue outputPort{-1}; + SimDataValue length{1}; + SimDataValue running{false}; + SimCallbackRegistry data; + + void ResetData(); +}; +extern AddressableLEDData* SimAddressableLEDData; +} // namespace hal