Rename our allwpilib (which is now 2020) to not have 2019 in the name
Change-Id: I3c07f85ed32ab8b97db765a9b43f2a6ce7da964a
diff --git a/hal/src/main/native/sim/Accelerometer.cpp b/hal/src/main/native/sim/Accelerometer.cpp
new file mode 100644
index 0000000..1435fd5
--- /dev/null
+++ b/hal/src/main/native/sim/Accelerometer.cpp
@@ -0,0 +1,31 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "hal/Accelerometer.h"
+
+#include "mockdata/AccelerometerDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeAccelerometer() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+void HAL_SetAccelerometerActive(HAL_Bool active) {
+ SimAccelerometerData[0].active = active;
+}
+
+void HAL_SetAccelerometerRange(HAL_AccelerometerRange range) {
+ SimAccelerometerData[0].range = range;
+}
+double HAL_GetAccelerometerX(void) { return SimAccelerometerData[0].x; }
+double HAL_GetAccelerometerY(void) { return SimAccelerometerData[0].y; }
+double HAL_GetAccelerometerZ(void) { return SimAccelerometerData[0].z; }
+} // extern "C"
diff --git a/hal/src/main/native/sim/AddressableLED.cpp b/hal/src/main/native/sim/AddressableLED.cpp
new file mode 100644
index 0000000..70d3f6f
--- /dev/null
+++ b/hal/src/main/native/sim/AddressableLED.cpp
@@ -0,0 +1,168 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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<HAL_AddressableLEDHandle, AddressableLED,
+ kNumAddressableLEDs,
+ HAL_HandleEnum::AddressableLED>* ledHandles;
+
+namespace hal {
+namespace init {
+void InitializeAddressableLED() {
+ static LimitedHandleResource<HAL_AddressableLEDHandle, AddressableLED,
+ kNumAddressableLEDs,
+ HAL_HandleEnum::AddressableLED>
+ dcH;
+ ledHandles = &dcH;
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_AddressableLEDHandle HAL_InitializeAddressableLED(
+ HAL_DigitalHandle outputPort, int32_t* status) {
+ hal::init::CheckInit();
+
+ auto digitalPort =
+ hal::digitalChannelHandles->Get(outputPort, hal::HAL_HandleEnum::PWM);
+
+ if (!digitalPort) {
+ // If DIO was passed, channel error, else generic error
+ if (getHandleType(outputPort) == hal::HAL_HandleEnum::DIO) {
+ *status = HAL_LED_CHANNEL_ERROR;
+ } else {
+ *status = HAL_HANDLE_ERROR;
+ }
+ return HAL_kInvalidHandle;
+ }
+
+ if (digitalPort->channel >= kNumPWMHeaders) {
+ *status = HAL_LED_CHANNEL_ERROR;
+ return HAL_kInvalidHandle;
+ }
+
+ 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);
+ SimAddressableLEDData[index].outputPort = digitalPort->channel;
+ SimAddressableLEDData[index].length = 1;
+ SimAddressableLEDData[index].running = false;
+ SimAddressableLEDData[index].initialized = true;
+ led->index = index;
+ return 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) {
+ 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) {
+ 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) {
+ 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,
+ int32_t highTime0NanoSeconds,
+ int32_t lowTime1NanoSeconds,
+ int32_t highTime1NanoSeconds,
+ int32_t* status) {}
+
+void HAL_SetAddressableLEDSyncTime(HAL_AddressableLEDHandle handle,
+ int32_t syncTimeMicroSeconds,
+ int32_t* status) {}
+
+void HAL_StartAddressableLEDOutput(HAL_AddressableLEDHandle handle,
+ 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) {
+ 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/AnalogAccumulator.cpp b/hal/src/main/native/sim/AnalogAccumulator.cpp
new file mode 100644
index 0000000..537aa15
--- /dev/null
+++ b/hal/src/main/native/sim/AnalogAccumulator.cpp
@@ -0,0 +1,112 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "hal/AnalogAccumulator.h"
+
+#include "AnalogInternal.h"
+#include "mockdata/AnalogInDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeAnalogAccumulator() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_Bool HAL_IsAccumulatorChannel(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ for (int32_t i = 0; i < kNumAccumulators; i++) {
+ if (port->channel == kAccumulatorChannels[i]) return true;
+ }
+ return false;
+}
+void HAL_InitAccumulator(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ if (!HAL_IsAccumulatorChannel(analogPortHandle, status)) {
+ *status = HAL_INVALID_ACCUMULATOR_CHANNEL;
+ return;
+ }
+
+ SimAnalogInData[port->channel].accumulatorInitialized = true;
+}
+void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimAnalogInData[port->channel].accumulatorCenter = 0;
+ SimAnalogInData[port->channel].accumulatorCount = 0;
+ SimAnalogInData[port->channel].accumulatorValue = 0;
+}
+void HAL_SetAccumulatorCenter(HAL_AnalogInputHandle analogPortHandle,
+ int32_t center, int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimAnalogInData[port->channel].accumulatorCenter = center;
+}
+void HAL_SetAccumulatorDeadband(HAL_AnalogInputHandle analogPortHandle,
+ int32_t deadband, int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimAnalogInData[port->channel].accumulatorDeadband = deadband;
+}
+int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimAnalogInData[port->channel].accumulatorValue;
+}
+int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimAnalogInData[port->channel].accumulatorCount;
+}
+void HAL_GetAccumulatorOutput(HAL_AnalogInputHandle analogPortHandle,
+ int64_t* value, int64_t* count, int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ *count = SimAnalogInData[port->channel].accumulatorCount;
+ *value = SimAnalogInData[port->channel].accumulatorValue;
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/AnalogGyro.cpp b/hal/src/main/native/sim/AnalogGyro.cpp
new file mode 100644
index 0000000..b7d84d9
--- /dev/null
+++ b/hal/src/main/native/sim/AnalogGyro.cpp
@@ -0,0 +1,147 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 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 "hal/AnalogGyro.h"
+
+#include <chrono>
+#include <thread>
+
+#include "AnalogInternal.h"
+#include "HALInitializer.h"
+#include "hal/AnalogAccumulator.h"
+#include "hal/AnalogInput.h"
+#include "hal/handles/IndexedHandleResource.h"
+#include "mockdata/AnalogGyroDataInternal.h"
+
+namespace {
+struct AnalogGyro {
+ HAL_AnalogInputHandle handle;
+ uint8_t index;
+};
+} // namespace
+
+using namespace hal;
+
+static IndexedHandleResource<HAL_GyroHandle, AnalogGyro, kNumAccumulators,
+ HAL_HandleEnum::AnalogGyro>* analogGyroHandles;
+
+namespace hal {
+namespace init {
+void InitializeAnalogGyro() {
+ static IndexedHandleResource<HAL_GyroHandle, AnalogGyro, kNumAccumulators,
+ HAL_HandleEnum::AnalogGyro>
+ agH;
+ analogGyroHandles = &agH;
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_GyroHandle HAL_InitializeAnalogGyro(HAL_AnalogInputHandle analogHandle,
+ int32_t* status) {
+ hal::init::CheckInit();
+ if (!HAL_IsAccumulatorChannel(analogHandle, status)) {
+ if (*status == 0) {
+ *status = HAL_INVALID_ACCUMULATOR_CHANNEL;
+ }
+ return HAL_kInvalidHandle;
+ }
+
+ // handle known to be correct, so no need to type check
+ int16_t channel = getHandleIndex(analogHandle);
+
+ auto handle = analogGyroHandles->Allocate(channel, status);
+
+ if (*status != 0)
+ return HAL_kInvalidHandle; // failed to allocate. Pass error back.
+
+ // Initialize port structure
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) { // would only error on thread issue
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+
+ gyro->handle = analogHandle;
+ gyro->index = channel;
+
+ SimAnalogGyroData[channel].initialized = true;
+
+ return handle;
+}
+
+void HAL_SetupAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
+ // No op
+}
+
+void HAL_FreeAnalogGyro(HAL_GyroHandle handle) {
+ auto gyro = analogGyroHandles->Get(handle);
+ analogGyroHandles->Free(handle);
+ if (gyro == nullptr) return;
+ SimAnalogGyroData[gyro->index].initialized = false;
+}
+
+void HAL_SetAnalogGyroParameters(HAL_GyroHandle handle,
+ double voltsPerDegreePerSecond, double offset,
+ int32_t center, int32_t* status) {
+ // No op
+}
+
+void HAL_SetAnalogGyroVoltsPerDegreePerSecond(HAL_GyroHandle handle,
+ double voltsPerDegreePerSecond,
+ int32_t* status) {
+ // No op
+}
+
+void HAL_ResetAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimAnalogGyroData[gyro->index].angle = 0.0;
+}
+
+void HAL_CalibrateAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
+ // Just do a reset
+ HAL_ResetAnalogGyro(handle, status);
+}
+
+void HAL_SetAnalogGyroDeadband(HAL_GyroHandle handle, double volts,
+ int32_t* status) {
+ // No op
+}
+
+double HAL_GetAnalogGyroAngle(HAL_GyroHandle handle, int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimAnalogGyroData[gyro->index].angle;
+}
+
+double HAL_GetAnalogGyroRate(HAL_GyroHandle handle, int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimAnalogGyroData[gyro->index].rate;
+}
+
+double HAL_GetAnalogGyroOffset(HAL_GyroHandle handle, int32_t* status) {
+ return 0.0;
+}
+
+int32_t HAL_GetAnalogGyroCenter(HAL_GyroHandle handle, int32_t* status) {
+ return 0;
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/AnalogInput.cpp b/hal/src/main/native/sim/AnalogInput.cpp
new file mode 100644
index 0000000..8ecde74
--- /dev/null
+++ b/hal/src/main/native/sim/AnalogInput.cpp
@@ -0,0 +1,196 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/AnalogInput.h"
+
+#include "AnalogInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/AnalogAccumulator.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/AnalogInDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeAnalogInput() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
+ int32_t* status) {
+ hal::init::CheckInit();
+ int16_t channel = getPortHandleChannel(portHandle);
+ if (channel == InvalidHandleIndex) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+
+ HAL_AnalogInputHandle handle = analogInputHandles->Allocate(channel, status);
+
+ if (*status != 0)
+ return HAL_kInvalidHandle; // failed to allocate. Pass error back.
+
+ // Initialize port structure
+ auto analog_port = analogInputHandles->Get(handle);
+ if (analog_port == nullptr) { // would only error on thread issue
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+
+ analog_port->channel = static_cast<uint8_t>(channel);
+ if (HAL_IsAccumulatorChannel(handle, status)) {
+ analog_port->isAccumulator = true;
+ } else {
+ analog_port->isAccumulator = false;
+ }
+
+ SimAnalogInData[channel].initialized = true;
+ SimAnalogInData[channel].accumulatorInitialized = false;
+ SimAnalogInData[channel].simDevice = 0;
+
+ return handle;
+}
+void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analogPortHandle) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ // no status, so no need to check for a proper free.
+ analogInputHandles->Free(analogPortHandle);
+ if (port == nullptr) return;
+ SimAnalogInData[port->channel].initialized = false;
+ SimAnalogInData[port->channel].accumulatorInitialized = false;
+}
+
+HAL_Bool HAL_CheckAnalogModule(int32_t module) { return module == 1; }
+
+HAL_Bool HAL_CheckAnalogInputChannel(int32_t channel) {
+ return channel < kNumAnalogInputs && channel >= 0;
+}
+
+void HAL_SetAnalogInputSimDevice(HAL_AnalogInputHandle handle,
+ HAL_SimDeviceHandle device) {
+ auto port = analogInputHandles->Get(handle);
+ if (port == nullptr) return;
+ SimAnalogInData[port->channel].simDevice = device;
+}
+
+void HAL_SetAnalogSampleRate(double samplesPerSecond, int32_t* status) {
+ // No op
+}
+double HAL_GetAnalogSampleRate(int32_t* status) { return kDefaultSampleRate; }
+void HAL_SetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
+ int32_t bits, int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimAnalogInData[port->channel].averageBits = bits;
+}
+int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimAnalogInData[port->channel].averageBits;
+}
+void HAL_SetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
+ int32_t bits, int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimAnalogInData[port->channel].oversampleBits = bits;
+}
+int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimAnalogInData[port->channel].oversampleBits;
+}
+int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ double voltage = SimAnalogInData[port->channel].voltage;
+ return HAL_GetAnalogVoltsToValue(analogPortHandle, voltage, status);
+}
+int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ // No averaging supported
+ return HAL_GetAnalogValue(analogPortHandle, status);
+}
+int32_t HAL_GetAnalogVoltsToValue(HAL_AnalogInputHandle analogPortHandle,
+ double voltage, int32_t* status) {
+ if (voltage > 5.0) {
+ voltage = 5.0;
+ *status = VOLTAGE_OUT_OF_RANGE;
+ }
+ if (voltage < 0.0) {
+ voltage = 0.0;
+ *status = VOLTAGE_OUT_OF_RANGE;
+ }
+ int32_t LSBWeight = HAL_GetAnalogLSBWeight(analogPortHandle, status);
+ int32_t offset = HAL_GetAnalogOffset(analogPortHandle, status);
+ int32_t value =
+ static_cast<int32_t>((voltage + offset * 1.0e-9) / (LSBWeight * 1.0e-9));
+ return value;
+}
+double HAL_GetAnalogVoltage(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0.0;
+ }
+
+ return SimAnalogInData[port->channel].voltage;
+}
+
+double HAL_GetAnalogValueToVolts(HAL_AnalogInputHandle analogPortHandle,
+ int32_t rawValue, int32_t* status) {
+ int32_t LSBWeight = HAL_GetAnalogLSBWeight(analogPortHandle, status);
+ int32_t offset = HAL_GetAnalogOffset(analogPortHandle, status);
+ double voltage = LSBWeight * 1.0e-9 * rawValue - offset * 1.0e-9;
+ return voltage;
+}
+
+double HAL_GetAnalogAverageVoltage(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0.0;
+ }
+
+ // No averaging supported
+ return SimAnalogInData[port->channel].voltage;
+}
+int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ return 1220703;
+}
+int32_t HAL_GetAnalogOffset(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ return 0;
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/AnalogInternal.cpp b/hal/src/main/native/sim/AnalogInternal.cpp
new file mode 100644
index 0000000..1e6a755
--- /dev/null
+++ b/hal/src/main/native/sim/AnalogInternal.cpp
@@ -0,0 +1,27 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 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 "AnalogInternal.h"
+
+#include "PortsInternal.h"
+#include "hal/AnalogInput.h"
+
+namespace hal {
+IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort, kNumAnalogInputs,
+ HAL_HandleEnum::AnalogInput>* analogInputHandles;
+} // namespace hal
+
+namespace hal {
+namespace init {
+void InitializeAnalogInternal() {
+ static IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort,
+ kNumAnalogInputs, HAL_HandleEnum::AnalogInput>
+ aiH;
+ analogInputHandles = &aiH;
+}
+} // namespace init
+} // namespace hal
diff --git a/hal/src/main/native/sim/AnalogInternal.h b/hal/src/main/native/sim/AnalogInternal.h
new file mode 100644
index 0000000..bcc5c95
--- /dev/null
+++ b/hal/src/main/native/sim/AnalogInternal.h
@@ -0,0 +1,36 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 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 <stdint.h>
+
+#include <memory>
+
+#include "PortsInternal.h"
+#include "hal/Ports.h"
+#include "hal/handles/IndexedHandleResource.h"
+
+namespace hal {
+constexpr int32_t kTimebase = 40000000; ///< 40 MHz clock
+constexpr int32_t kDefaultOversampleBits = 0;
+constexpr int32_t kDefaultAverageBits = 7;
+constexpr double kDefaultSampleRate = 50000.0;
+static constexpr uint32_t kAccumulatorChannels[] = {0, 1};
+
+struct AnalogPort {
+ uint8_t channel;
+ bool isAccumulator;
+};
+
+extern IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort,
+ kNumAnalogInputs, HAL_HandleEnum::AnalogInput>*
+ analogInputHandles;
+
+int32_t GetAnalogTriggerInputIndex(HAL_AnalogTriggerHandle handle,
+ int32_t* status);
+} // namespace hal
diff --git a/hal/src/main/native/sim/AnalogOutput.cpp b/hal/src/main/native/sim/AnalogOutput.cpp
new file mode 100644
index 0000000..2e3a348
--- /dev/null
+++ b/hal/src/main/native/sim/AnalogOutput.cpp
@@ -0,0 +1,102 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "hal/AnalogOutput.h"
+
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/Errors.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/IndexedHandleResource.h"
+#include "mockdata/AnalogOutDataInternal.h"
+
+using namespace hal;
+
+namespace {
+struct AnalogOutput {
+ uint8_t channel;
+};
+} // namespace
+
+static IndexedHandleResource<HAL_AnalogOutputHandle, AnalogOutput,
+ kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>*
+ analogOutputHandles;
+
+namespace hal {
+namespace init {
+void InitializeAnalogOutput() {
+ static IndexedHandleResource<HAL_AnalogOutputHandle, AnalogOutput,
+ kNumAnalogOutputs, HAL_HandleEnum::AnalogOutput>
+ aoH;
+ analogOutputHandles = &aoH;
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
+ int32_t* status) {
+ hal::init::CheckInit();
+ int16_t channel = getPortHandleChannel(portHandle);
+ if (channel == InvalidHandleIndex) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+
+ HAL_AnalogOutputHandle handle =
+ analogOutputHandles->Allocate(channel, status);
+
+ if (*status != 0)
+ return HAL_kInvalidHandle; // failed to allocate. Pass error back.
+
+ auto port = analogOutputHandles->Get(handle);
+ if (port == nullptr) { // would only error on thread issue
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+
+ port->channel = static_cast<uint8_t>(channel);
+
+ // Initialize sim analog input
+ SimAnalogOutData[channel].initialized = true;
+ return handle;
+}
+
+void HAL_FreeAnalogOutputPort(HAL_AnalogOutputHandle analogOutputHandle) {
+ // no status, so no need to check for a proper free.
+ auto port = analogOutputHandles->Get(analogOutputHandle);
+ if (port == nullptr) return;
+ analogOutputHandles->Free(analogOutputHandle);
+ SimAnalogOutData[port->channel].initialized = false;
+}
+
+HAL_Bool HAL_CheckAnalogOutputChannel(int32_t channel) {
+ return channel < kNumAnalogOutputs && channel >= 0;
+}
+
+void HAL_SetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
+ double voltage, int32_t* status) {
+ auto port = analogOutputHandles->Get(analogOutputHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimAnalogOutData[port->channel].voltage = voltage;
+}
+
+double HAL_GetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
+ int32_t* status) {
+ auto port = analogOutputHandles->Get(analogOutputHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0.0;
+ }
+
+ return SimAnalogOutData[port->channel].voltage;
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/AnalogTrigger.cpp b/hal/src/main/native/sim/AnalogTrigger.cpp
new file mode 100644
index 0000000..3ddacee
--- /dev/null
+++ b/hal/src/main/native/sim/AnalogTrigger.cpp
@@ -0,0 +1,285 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/AnalogTrigger.h"
+
+#include "AnalogInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/AnalogInput.h"
+#include "hal/Errors.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/LimitedHandleResource.h"
+#include "mockdata/AnalogInDataInternal.h"
+#include "mockdata/AnalogTriggerDataInternal.h"
+
+namespace {
+struct AnalogTrigger {
+ HAL_AnalogInputHandle analogHandle;
+ uint8_t index;
+ HAL_Bool trigState;
+};
+} // namespace
+
+using namespace hal;
+
+static LimitedHandleResource<HAL_AnalogTriggerHandle, AnalogTrigger,
+ kNumAnalogTriggers, HAL_HandleEnum::AnalogTrigger>*
+ analogTriggerHandles;
+
+namespace hal {
+namespace init {
+void InitializeAnalogTrigger() {
+ static LimitedHandleResource<HAL_AnalogTriggerHandle, AnalogTrigger,
+ kNumAnalogTriggers,
+ HAL_HandleEnum::AnalogTrigger>
+ atH;
+ analogTriggerHandles = &atH;
+}
+} // namespace init
+} // namespace hal
+
+int32_t hal::GetAnalogTriggerInputIndex(HAL_AnalogTriggerHandle handle,
+ int32_t* status) {
+ auto trigger = analogTriggerHandles->Get(handle);
+ if (trigger == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return -1;
+ }
+
+ auto analog_port = analogInputHandles->Get(trigger->analogHandle);
+ if (analog_port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return -1;
+ }
+
+ return analog_port->channel;
+}
+
+extern "C" {
+
+HAL_AnalogTriggerHandle HAL_InitializeAnalogTrigger(
+ HAL_AnalogInputHandle portHandle, int32_t* status) {
+ hal::init::CheckInit();
+ // ensure we are given a valid and active AnalogInput handle
+ auto analog_port = analogInputHandles->Get(portHandle);
+ if (analog_port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+ HAL_AnalogTriggerHandle handle = analogTriggerHandles->Allocate();
+ if (handle == HAL_kInvalidHandle) {
+ *status = NO_AVAILABLE_RESOURCES;
+ return HAL_kInvalidHandle;
+ }
+ auto trigger = analogTriggerHandles->Get(handle);
+ if (trigger == nullptr) { // would only occur on thread issue
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+ trigger->analogHandle = portHandle;
+ trigger->index = static_cast<uint8_t>(getHandleIndex(handle));
+
+ SimAnalogTriggerData[trigger->index].initialized = true;
+
+ trigger->trigState = false;
+
+ return handle;
+}
+
+HAL_AnalogTriggerHandle HAL_InitializeAnalogTriggerDutyCycle(
+ HAL_DutyCycleHandle dutyCycleHandle, int32_t* status) {
+ *status = HAL_SIM_NOT_SUPPORTED;
+ return HAL_kInvalidHandle;
+}
+
+void HAL_CleanAnalogTrigger(HAL_AnalogTriggerHandle analogTriggerHandle,
+ int32_t* status) {
+ auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
+ analogTriggerHandles->Free(analogTriggerHandle);
+ if (trigger == nullptr) return;
+ SimAnalogTriggerData[trigger->index].initialized = false;
+ // caller owns the analog input handle.
+}
+
+static double GetAnalogValueToVoltage(
+ HAL_AnalogTriggerHandle analogTriggerHandle, int32_t value,
+ int32_t* status) {
+ int32_t LSBWeight = HAL_GetAnalogLSBWeight(analogTriggerHandle, status);
+ int32_t offset = HAL_GetAnalogOffset(analogTriggerHandle, status);
+
+ double voltage = LSBWeight * 1.0e-9 * value - offset * 1.0e-9;
+ return voltage;
+}
+
+void HAL_SetAnalogTriggerLimitsRaw(HAL_AnalogTriggerHandle analogTriggerHandle,
+ int32_t lower, int32_t upper,
+ int32_t* status) {
+ auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
+ if (trigger == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ if (lower > upper) {
+ *status = ANALOG_TRIGGER_LIMIT_ORDER_ERROR;
+ }
+
+ double trigLower =
+ GetAnalogValueToVoltage(trigger->analogHandle, lower, status);
+ if (status != 0) return;
+ double trigUpper =
+ GetAnalogValueToVoltage(trigger->analogHandle, upper, status);
+ if (status != 0) return;
+
+ SimAnalogTriggerData[trigger->index].triggerUpperBound = trigUpper;
+ SimAnalogTriggerData[trigger->index].triggerLowerBound = trigLower;
+}
+
+void HAL_SetAnalogTriggerLimitsDutyCycle(
+ HAL_AnalogTriggerHandle analogTriggerHandle, double lower, double upper,
+ int32_t* status) {
+ *status = HAL_SIM_NOT_SUPPORTED;
+}
+
+void HAL_SetAnalogTriggerLimitsVoltage(
+ HAL_AnalogTriggerHandle analogTriggerHandle, double lower, double upper,
+ int32_t* status) {
+ auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
+ if (trigger == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ if (lower > upper) {
+ *status = ANALOG_TRIGGER_LIMIT_ORDER_ERROR;
+ }
+
+ SimAnalogTriggerData[trigger->index].triggerUpperBound = upper;
+ SimAnalogTriggerData[trigger->index].triggerLowerBound = lower;
+}
+void HAL_SetAnalogTriggerAveraged(HAL_AnalogTriggerHandle analogTriggerHandle,
+ HAL_Bool useAveragedValue, int32_t* status) {
+ auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
+ if (trigger == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ AnalogTriggerData* triggerData = &SimAnalogTriggerData[trigger->index];
+
+ if (triggerData->triggerMode.Get() != HALSIM_AnalogTriggerUnassigned) {
+ *status = INCOMPATIBLE_STATE;
+ return;
+ }
+
+ auto setVal = useAveragedValue ? HALSIM_AnalogTriggerAveraged
+ : HALSIM_AnalogTriggerUnassigned;
+ triggerData->triggerMode = setVal;
+}
+
+void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
+ HAL_Bool useFilteredValue, int32_t* status) {
+ auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
+ if (trigger == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ AnalogTriggerData* triggerData = &SimAnalogTriggerData[trigger->index];
+
+ if (triggerData->triggerMode.Get() != HALSIM_AnalogTriggerUnassigned) {
+ *status = INCOMPATIBLE_STATE;
+ return;
+ }
+
+ auto setVal = useFilteredValue ? HALSIM_AnalogTriggerFiltered
+ : HALSIM_AnalogTriggerUnassigned;
+ triggerData->triggerMode = setVal;
+}
+
+static double GetTriggerValue(AnalogTrigger* trigger, int32_t* status) {
+ auto analogIn = analogInputHandles->Get(trigger->analogHandle);
+ if (analogIn == nullptr) {
+ // Returning HAL Handle Error, but going to ignore lower down
+ *status = HAL_HANDLE_ERROR;
+ return 0.0;
+ }
+
+ return SimAnalogInData[analogIn->channel].voltage;
+}
+
+HAL_Bool HAL_GetAnalogTriggerInWindow(
+ HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
+ auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
+ if (trigger == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+
+ double voltage = GetTriggerValue(trigger.get(), status);
+ if (*status == HAL_HANDLE_ERROR) {
+ // Don't error if analog has been destroyed
+ *status = 0;
+ return false;
+ }
+
+ double trigUpper = SimAnalogTriggerData[trigger->index].triggerUpperBound;
+ double trigLower = SimAnalogTriggerData[trigger->index].triggerLowerBound;
+
+ return voltage >= trigLower && voltage <= trigUpper;
+}
+HAL_Bool HAL_GetAnalogTriggerTriggerState(
+ HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
+ auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
+ if (trigger == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+
+ double voltage = GetTriggerValue(trigger.get(), status);
+ if (*status == HAL_HANDLE_ERROR) {
+ // Don't error if analog has been destroyed
+ *status = 0;
+ return false;
+ }
+
+ double trigUpper = SimAnalogTriggerData[trigger->index].triggerUpperBound;
+ double trigLower = SimAnalogTriggerData[trigger->index].triggerLowerBound;
+
+ if (voltage < trigLower) {
+ trigger->trigState = false;
+ return false;
+ }
+ if (voltage > trigUpper) {
+ trigger->trigState = true;
+ return true;
+ }
+ return trigger->trigState;
+}
+HAL_Bool HAL_GetAnalogTriggerOutput(HAL_AnalogTriggerHandle analogTriggerHandle,
+ HAL_AnalogTriggerType type,
+ int32_t* status) {
+ if (type == HAL_Trigger_kInWindow) {
+ return HAL_GetAnalogTriggerInWindow(analogTriggerHandle, status);
+ } else if (type == HAL_Trigger_kState) {
+ return HAL_GetAnalogTriggerTriggerState(analogTriggerHandle, status);
+ } else {
+ *status = ANALOG_TRIGGER_PULSE_OUTPUT_ERROR;
+ return false;
+ }
+}
+
+int32_t HAL_GetAnalogTriggerFPGAIndex(
+ HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
+ auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
+ if (trigger == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return -1;
+ }
+ return trigger->index;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/CAN.cpp b/hal/src/main/native/sim/CAN.cpp
new file mode 100644
index 0000000..1e7af73
--- /dev/null
+++ b/hal/src/main/native/sim/CAN.cpp
@@ -0,0 +1,63 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/CAN.h"
+
+#include "mockdata/CanDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeCAN() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+void HAL_CAN_SendMessage(uint32_t messageID, const uint8_t* data,
+ uint8_t dataSize, int32_t periodMs, int32_t* status) {
+ SimCanData->sendMessage(messageID, data, dataSize, periodMs, status);
+}
+void HAL_CAN_ReceiveMessage(uint32_t* messageID, uint32_t messageIDMask,
+ uint8_t* data, uint8_t* dataSize,
+ uint32_t* timeStamp, int32_t* status) {
+ // Use a data size of 42 as call check. Difficult to add check to invoke
+ // handler
+ *dataSize = 42;
+ auto tmpStatus = *status;
+ SimCanData->receiveMessage(messageID, messageIDMask, data, dataSize,
+ timeStamp, status);
+ // If no handler invoked, return message not found
+ if (*dataSize == 42 && *status == tmpStatus) {
+ *status = HAL_ERR_CANSessionMux_MessageNotFound;
+ }
+}
+void HAL_CAN_OpenStreamSession(uint32_t* sessionHandle, uint32_t messageID,
+ uint32_t messageIDMask, uint32_t maxMessages,
+ int32_t* status) {
+ SimCanData->openStreamSession(sessionHandle, messageID, messageIDMask,
+ maxMessages, status);
+}
+void HAL_CAN_CloseStreamSession(uint32_t sessionHandle) {
+ SimCanData->closeStreamSession(sessionHandle);
+}
+void HAL_CAN_ReadStreamSession(uint32_t sessionHandle,
+ struct HAL_CANStreamMessage* messages,
+ uint32_t messagesToRead, uint32_t* messagesRead,
+ int32_t* status) {
+ SimCanData->readStreamSession(sessionHandle, messages, messagesToRead,
+ messagesRead, status);
+}
+void HAL_CAN_GetCANStatus(float* percentBusUtilization, uint32_t* busOffCount,
+ uint32_t* txFullCount, uint32_t* receiveErrorCount,
+ uint32_t* transmitErrorCount, int32_t* status) {
+ SimCanData->getCANStatus(percentBusUtilization, busOffCount, txFullCount,
+ receiveErrorCount, transmitErrorCount, status);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/CANAPI.cpp b/hal/src/main/native/sim/CANAPI.cpp
new file mode 100644
index 0000000..08b0989
--- /dev/null
+++ b/hal/src/main/native/sim/CANAPI.cpp
@@ -0,0 +1,356 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-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 "hal/CANAPI.h"
+
+#include <atomic>
+#include <ctime>
+
+#include <wpi/DenseMap.h>
+
+#include "CANAPIInternal.h"
+#include "HALInitializer.h"
+#include "hal/CAN.h"
+#include "hal/Errors.h"
+#include "hal/HAL.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+
+using namespace hal;
+
+namespace {
+struct Receives {
+ uint64_t lastTimeStamp;
+ uint8_t data[8];
+ uint8_t length;
+};
+
+struct CANStorage {
+ HAL_CANManufacturer manufacturer;
+ HAL_CANDeviceType deviceType;
+ uint8_t deviceId;
+ wpi::mutex mapMutex;
+ wpi::SmallDenseMap<int32_t, int32_t> periodicSends;
+ wpi::SmallDenseMap<int32_t, Receives> receives;
+};
+} // namespace
+
+static UnlimitedHandleResource<HAL_CANHandle, CANStorage, HAL_HandleEnum::CAN>*
+ canHandles;
+
+static uint32_t GetPacketBaseTime() {
+ int status = 0;
+ auto basetime = HAL_GetFPGATime(&status);
+ // us to ms
+ return (basetime / 1000ull) & 0xFFFFFFFF;
+}
+
+namespace hal {
+namespace init {
+void InitializeCANAPI() {
+ static UnlimitedHandleResource<HAL_CANHandle, CANStorage, HAL_HandleEnum::CAN>
+ cH;
+ canHandles = &cH;
+}
+} // namespace init
+namespace can {
+int32_t GetCANModuleFromHandle(HAL_CANHandle handle, int32_t* status) {
+ auto can = canHandles->Get(handle);
+ if (!can) {
+ *status = HAL_HANDLE_ERROR;
+ return -1;
+ }
+ return can->deviceId;
+}
+} // namespace can
+} // namespace hal
+
+static int32_t CreateCANId(CANStorage* storage, int32_t apiId) {
+ int32_t createdId = 0;
+ createdId |= (static_cast<int32_t>(storage->deviceType) & 0x1F) << 24;
+ createdId |= (static_cast<int32_t>(storage->manufacturer) & 0xFF) << 16;
+ createdId |= (apiId & 0x3FF) << 6;
+ createdId |= (storage->deviceId & 0x3F);
+ return createdId;
+}
+
+HAL_CANHandle HAL_InitializeCAN(HAL_CANManufacturer manufacturer,
+ int32_t deviceId, HAL_CANDeviceType deviceType,
+ int32_t* status) {
+ hal::init::CheckInit();
+ auto can = std::make_shared<CANStorage>();
+
+ auto handle = canHandles->Allocate(can);
+
+ if (handle == HAL_kInvalidHandle) {
+ *status = NO_AVAILABLE_RESOURCES;
+ return HAL_kInvalidHandle;
+ }
+
+ can->deviceId = deviceId;
+ can->deviceType = deviceType;
+ can->manufacturer = manufacturer;
+
+ return handle;
+}
+
+void HAL_CleanCAN(HAL_CANHandle handle) {
+ auto data = canHandles->Free(handle);
+
+ std::scoped_lock lock(data->mapMutex);
+
+ for (auto&& i : data->periodicSends) {
+ int32_t s = 0;
+ auto id = CreateCANId(data.get(), i.first);
+ HAL_CAN_SendMessage(id, nullptr, 0, HAL_CAN_SEND_PERIOD_STOP_REPEATING, &s);
+ i.second = -1;
+ }
+}
+
+void HAL_WriteCANPacket(HAL_CANHandle handle, const uint8_t* data,
+ int32_t length, int32_t apiId, int32_t* status) {
+ auto can = canHandles->Get(handle);
+ if (!can) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ auto id = CreateCANId(can.get(), apiId);
+
+ HAL_CAN_SendMessage(id, data, length, HAL_CAN_SEND_PERIOD_NO_REPEAT, status);
+
+ if (*status != 0) {
+ return;
+ }
+ std::scoped_lock lock(can->mapMutex);
+ can->periodicSends[apiId] = -1;
+}
+
+void HAL_WriteCANPacketRepeating(HAL_CANHandle handle, const uint8_t* data,
+ int32_t length, int32_t apiId,
+ int32_t repeatMs, int32_t* status) {
+ auto can = canHandles->Get(handle);
+ if (!can) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ auto id = CreateCANId(can.get(), apiId);
+
+ HAL_CAN_SendMessage(id, data, length, repeatMs, status);
+
+ if (*status != 0) {
+ return;
+ }
+ std::scoped_lock lock(can->mapMutex);
+ can->periodicSends[apiId] = repeatMs;
+}
+
+void HAL_WriteCANRTRFrame(HAL_CANHandle handle, int32_t length, int32_t apiId,
+ int32_t* status) {
+ auto can = canHandles->Get(handle);
+ if (!can) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ auto id = CreateCANId(can.get(), apiId);
+ id |= HAL_CAN_IS_FRAME_REMOTE;
+ uint8_t data[8];
+ std::memset(data, 0, sizeof(data));
+
+ HAL_CAN_SendMessage(id, data, length, HAL_CAN_SEND_PERIOD_NO_REPEAT, status);
+
+ if (*status != 0) {
+ return;
+ }
+ std::scoped_lock lock(can->mapMutex);
+ can->periodicSends[apiId] = -1;
+}
+
+void HAL_StopCANPacketRepeating(HAL_CANHandle handle, int32_t apiId,
+ int32_t* status) {
+ auto can = canHandles->Get(handle);
+ if (!can) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ auto id = CreateCANId(can.get(), apiId);
+
+ HAL_CAN_SendMessage(id, nullptr, 0, HAL_CAN_SEND_PERIOD_STOP_REPEATING,
+ status);
+
+ if (*status != 0) {
+ return;
+ }
+ std::scoped_lock lock(can->mapMutex);
+ can->periodicSends[apiId] = -1;
+}
+
+void HAL_ReadCANPacketNew(HAL_CANHandle handle, int32_t apiId, uint8_t* data,
+ int32_t* length, uint64_t* receivedTimestamp,
+ int32_t* status) {
+ auto can = canHandles->Get(handle);
+ if (!can) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ uint32_t messageId = CreateCANId(can.get(), apiId);
+ uint8_t dataSize = 0;
+ uint32_t ts = 0;
+ HAL_CAN_ReceiveMessage(&messageId, 0x1FFFFFFF, data, &dataSize, &ts, status);
+
+ if (*status == 0) {
+ std::scoped_lock lock(can->mapMutex);
+ auto& msg = can->receives[messageId];
+ msg.length = dataSize;
+ msg.lastTimeStamp = ts;
+ // The NetComm call placed in data, copy into the msg
+ std::memcpy(msg.data, data, dataSize);
+ }
+ *length = dataSize;
+ *receivedTimestamp = ts;
+}
+
+void HAL_ReadCANPacketLatest(HAL_CANHandle handle, int32_t apiId, uint8_t* data,
+ int32_t* length, uint64_t* receivedTimestamp,
+ int32_t* status) {
+ auto can = canHandles->Get(handle);
+ if (!can) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ uint32_t messageId = CreateCANId(can.get(), apiId);
+ uint8_t dataSize = 0;
+ uint32_t ts = 0;
+ HAL_CAN_ReceiveMessage(&messageId, 0x1FFFFFFF, data, &dataSize, &ts, status);
+
+ std::scoped_lock lock(can->mapMutex);
+ if (*status == 0) {
+ // fresh update
+ auto& msg = can->receives[messageId];
+ msg.length = dataSize;
+ *length = dataSize;
+ msg.lastTimeStamp = ts;
+ *receivedTimestamp = ts;
+ // The NetComm call placed in data, copy into the msg
+ std::memcpy(msg.data, data, dataSize);
+ } else {
+ auto i = can->receives.find(messageId);
+ if (i != can->receives.end()) {
+ // Read the data from the stored message into the output
+ std::memcpy(data, i->second.data, i->second.length);
+ *length = i->second.length;
+ *receivedTimestamp = i->second.lastTimeStamp;
+ *status = 0;
+ }
+ }
+}
+
+void HAL_ReadCANPacketTimeout(HAL_CANHandle handle, int32_t apiId,
+ uint8_t* data, int32_t* length,
+ uint64_t* receivedTimestamp, int32_t timeoutMs,
+ int32_t* status) {
+ auto can = canHandles->Get(handle);
+ if (!can) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ uint32_t messageId = CreateCANId(can.get(), apiId);
+ uint8_t dataSize = 0;
+ uint32_t ts = 0;
+ HAL_CAN_ReceiveMessage(&messageId, 0x1FFFFFFF, data, &dataSize, &ts, status);
+
+ std::scoped_lock lock(can->mapMutex);
+ if (*status == 0) {
+ // fresh update
+ auto& msg = can->receives[messageId];
+ msg.length = dataSize;
+ *length = dataSize;
+ msg.lastTimeStamp = ts;
+ *receivedTimestamp = ts;
+ // The NetComm call placed in data, copy into the msg
+ std::memcpy(msg.data, data, dataSize);
+ } else {
+ auto i = can->receives.find(messageId);
+ if (i != can->receives.end()) {
+ // Found, check if new enough
+ uint32_t now = GetPacketBaseTime();
+ if (now - i->second.lastTimeStamp > static_cast<uint32_t>(timeoutMs)) {
+ // Timeout, return bad status
+ *status = HAL_CAN_TIMEOUT;
+ return;
+ }
+ // Read the data from the stored message into the output
+ std::memcpy(data, i->second.data, i->second.length);
+ *length = i->second.length;
+ *receivedTimestamp = i->second.lastTimeStamp;
+ *status = 0;
+ }
+ }
+}
+
+void HAL_ReadCANPeriodicPacket(HAL_CANHandle handle, int32_t apiId,
+ uint8_t* data, int32_t* length,
+ uint64_t* receivedTimestamp, int32_t timeoutMs,
+ int32_t periodMs, int32_t* status) {
+ auto can = canHandles->Get(handle);
+ if (!can) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ uint32_t messageId = CreateCANId(can.get(), apiId);
+
+ {
+ std::scoped_lock lock(can->mapMutex);
+ auto i = can->receives.find(messageId);
+ if (i != can->receives.end()) {
+ // Found, check if new enough
+ uint32_t now = GetPacketBaseTime();
+ if (now - i->second.lastTimeStamp < static_cast<uint32_t>(periodMs)) {
+ *status = 0;
+ // Read the data from the stored message into the output
+ std::memcpy(data, i->second.data, i->second.length);
+ *length = i->second.length;
+ *receivedTimestamp = i->second.lastTimeStamp;
+ return;
+ }
+ }
+ }
+
+ uint8_t dataSize = 0;
+ uint32_t ts = 0;
+ HAL_CAN_ReceiveMessage(&messageId, 0x1FFFFFFF, data, &dataSize, &ts, status);
+
+ std::scoped_lock lock(can->mapMutex);
+ if (*status == 0) {
+ // fresh update
+ auto& msg = can->receives[messageId];
+ msg.length = dataSize;
+ *length = dataSize;
+ msg.lastTimeStamp = ts;
+ *receivedTimestamp = ts;
+ // The NetComm call placed in data, copy into the msg
+ std::memcpy(msg.data, data, dataSize);
+ } else {
+ auto i = can->receives.find(messageId);
+ if (i != can->receives.end()) {
+ // Found, check if new enough
+ uint32_t now = GetPacketBaseTime();
+ if (now - i->second.lastTimeStamp > static_cast<uint32_t>(timeoutMs)) {
+ // Timeout, return bad status
+ *status = HAL_CAN_TIMEOUT;
+ return;
+ }
+ // Read the data from the stored message into the output
+ std::memcpy(data, i->second.data, i->second.length);
+ *length = i->second.length;
+ *receivedTimestamp = i->second.lastTimeStamp;
+ *status = 0;
+ }
+ }
+}
diff --git a/hal/src/main/native/sim/CANAPIInternal.h b/hal/src/main/native/sim/CANAPIInternal.h
new file mode 100644
index 0000000..074f682
--- /dev/null
+++ b/hal/src/main/native/sim/CANAPIInternal.h
@@ -0,0 +1,16 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 "hal/Types.h"
+
+namespace hal {
+namespace can {
+int32_t GetCANModuleFromHandle(HAL_CANHandle handle, int32_t* status);
+} // namespace can
+} // namespace hal
diff --git a/hal/src/main/native/sim/CallbackStore.cpp b/hal/src/main/native/sim/CallbackStore.cpp
new file mode 100644
index 0000000..d278b93
--- /dev/null
+++ b/hal/src/main/native/sim/CallbackStore.cpp
@@ -0,0 +1,13 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 "simulation/CallbackStore.h"
+
+void frc::sim::CallbackStoreThunk(const char* name, void* param,
+ const HAL_Value* value) {
+ reinterpret_cast<CallbackStore*>(param)->callback(name, value);
+}
diff --git a/hal/src/main/native/sim/Compressor.cpp b/hal/src/main/native/sim/Compressor.cpp
new file mode 100644
index 0000000..b5c5867
--- /dev/null
+++ b/hal/src/main/native/sim/Compressor.cpp
@@ -0,0 +1,123 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 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 "hal/Compressor.h"
+
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/Errors.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/PCMDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeCompressor() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+HAL_CompressorHandle HAL_InitializeCompressor(int32_t module, int32_t* status) {
+ hal::init::CheckInit();
+ // As compressors can have unlimited objects, just create a
+ // handle with the module number as the index.
+
+ SimPCMData[module].compressorInitialized = true;
+ return (HAL_CompressorHandle)createHandle(static_cast<int16_t>(module),
+ HAL_HandleEnum::Compressor, 0);
+}
+
+HAL_Bool HAL_CheckCompressorModule(int32_t module) {
+ return module < kNumPCMModules && module >= 0;
+}
+
+HAL_Bool HAL_GetCompressor(HAL_CompressorHandle compressorHandle,
+ int32_t* status) {
+ int16_t index =
+ getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
+ if (index == InvalidHandleIndex) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+
+ return SimPCMData[index].compressorOn;
+}
+
+void HAL_SetCompressorClosedLoopControl(HAL_CompressorHandle compressorHandle,
+ HAL_Bool value, int32_t* status) {
+ int16_t index =
+ getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
+ if (index == InvalidHandleIndex) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimPCMData[index].closedLoopEnabled = value;
+}
+
+HAL_Bool HAL_GetCompressorClosedLoopControl(
+ HAL_CompressorHandle compressorHandle, int32_t* status) {
+ int16_t index =
+ getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
+ if (index == InvalidHandleIndex) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+
+ return SimPCMData[index].closedLoopEnabled;
+}
+
+HAL_Bool HAL_GetCompressorPressureSwitch(HAL_CompressorHandle compressorHandle,
+ int32_t* status) {
+ int16_t index =
+ getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
+ if (index == InvalidHandleIndex) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+
+ return SimPCMData[index].pressureSwitch;
+}
+
+double HAL_GetCompressorCurrent(HAL_CompressorHandle compressorHandle,
+ int32_t* status) {
+ int16_t index =
+ getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
+ if (index == InvalidHandleIndex) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimPCMData[index].compressorCurrent;
+}
+HAL_Bool HAL_GetCompressorCurrentTooHighFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status) {
+ return false;
+}
+HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status) {
+ return false;
+}
+HAL_Bool HAL_GetCompressorShortedStickyFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status) {
+ return false;
+}
+HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressorHandle,
+ int32_t* status) {
+ return false;
+}
+HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status) {
+ return false;
+}
+HAL_Bool HAL_GetCompressorNotConnectedFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status) {
+ return false;
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/Constants.cpp b/hal/src/main/native/sim/Constants.cpp
new file mode 100644
index 0000000..64cb52b
--- /dev/null
+++ b/hal/src/main/native/sim/Constants.cpp
@@ -0,0 +1,24 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 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 "hal/Constants.h"
+
+#include "ConstantsInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeConstants() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+int32_t HAL_GetSystemClockTicksPerMicrosecond(void) {
+ return kSystemClockTicksPerMicrosecond;
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/ConstantsInternal.h b/hal/src/main/native/sim/ConstantsInternal.h
new file mode 100644
index 0000000..c3a6e8f
--- /dev/null
+++ b/hal/src/main/native/sim/ConstantsInternal.h
@@ -0,0 +1,14 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 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 <stdint.h>
+
+namespace hal {
+constexpr int32_t kSystemClockTicksPerMicrosecond = 40;
+} // namespace hal
diff --git a/hal/src/main/native/sim/Counter.cpp b/hal/src/main/native/sim/Counter.cpp
new file mode 100644
index 0000000..37454d0
--- /dev/null
+++ b/hal/src/main/native/sim/Counter.cpp
@@ -0,0 +1,98 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "hal/Counter.h"
+
+#include "CounterInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/Errors.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/LimitedHandleResource.h"
+
+namespace hal {
+
+LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
+ HAL_HandleEnum::Counter>* counterHandles;
+} // namespace hal
+
+namespace hal {
+namespace init {
+void InitializeCounter() {
+ static LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
+ HAL_HandleEnum::Counter>
+ cH;
+ counterHandles = &cH;
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index,
+ int32_t* status) {
+ hal::init::CheckInit();
+ return 0;
+}
+void HAL_FreeCounter(HAL_CounterHandle counterHandle, int32_t* status) {}
+void HAL_SetCounterAverageSize(HAL_CounterHandle counterHandle, int32_t size,
+ int32_t* status) {}
+void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ int32_t* status) {}
+void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
+ HAL_Bool risingEdge, HAL_Bool fallingEdge,
+ int32_t* status) {}
+void HAL_ClearCounterUpSource(HAL_CounterHandle counterHandle,
+ int32_t* status) {}
+void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ int32_t* status) {}
+void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
+ HAL_Bool risingEdge, HAL_Bool fallingEdge,
+ int32_t* status) {}
+void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
+ int32_t* status) {}
+void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle,
+ int32_t* status) {}
+void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
+ int32_t* status) {}
+void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
+ HAL_Bool highSemiPeriod, int32_t* status) {}
+void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
+ double threshold, int32_t* status) {}
+int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
+ int32_t* status) {
+ return 0;
+}
+void HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
+ int32_t samplesToAverage, int32_t* status) {
+}
+void HAL_ResetCounter(HAL_CounterHandle counterHandle, int32_t* status) {}
+int32_t HAL_GetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
+ return 0;
+}
+double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status) {
+ return 0.0;
+}
+void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
+ int32_t* status) {}
+void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
+ HAL_Bool enabled, int32_t* status) {}
+HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
+ int32_t* status) {
+ return false;
+}
+HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
+ int32_t* status) {
+ return false;
+}
+void HAL_SetCounterReverseDirection(HAL_CounterHandle counterHandle,
+ HAL_Bool reverseDirection,
+ int32_t* status) {}
+} // extern "C"
diff --git a/hal/src/main/native/sim/CounterInternal.h b/hal/src/main/native/sim/CounterInternal.h
new file mode 100644
index 0000000..70fbe54
--- /dev/null
+++ b/hal/src/main/native/sim/CounterInternal.h
@@ -0,0 +1,23 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "PortsInternal.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/LimitedHandleResource.h"
+
+namespace hal {
+
+struct Counter {
+ uint8_t index;
+};
+
+extern LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
+ HAL_HandleEnum::Counter>* counterHandles;
+
+} // namespace hal
diff --git a/hal/src/main/native/sim/DIO.cpp b/hal/src/main/native/sim/DIO.cpp
new file mode 100644
index 0000000..2158136
--- /dev/null
+++ b/hal/src/main/native/sim/DIO.cpp
@@ -0,0 +1,253 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/DIO.h"
+
+#include <cmath>
+
+#include "DigitalInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/LimitedHandleResource.h"
+#include "mockdata/DIODataInternal.h"
+#include "mockdata/DigitalPWMDataInternal.h"
+
+using namespace hal;
+
+static LimitedHandleResource<HAL_DigitalPWMHandle, uint8_t,
+ kNumDigitalPWMOutputs, HAL_HandleEnum::DigitalPWM>*
+ digitalPWMHandles;
+
+namespace hal {
+namespace init {
+void InitializeDIO() {
+ static LimitedHandleResource<HAL_DigitalPWMHandle, uint8_t,
+ kNumDigitalPWMOutputs,
+ HAL_HandleEnum::DigitalPWM>
+ dpH;
+ digitalPWMHandles = &dpH;
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
+ HAL_Bool input, int32_t* status) {
+ hal::init::CheckInit();
+ if (*status != 0) return HAL_kInvalidHandle;
+
+ int16_t channel = getPortHandleChannel(portHandle);
+ if (channel == InvalidHandleIndex) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+
+ auto handle =
+ digitalChannelHandles->Allocate(channel, HAL_HandleEnum::DIO, status);
+
+ if (*status != 0)
+ return HAL_kInvalidHandle; // failed to allocate. Pass error back.
+
+ auto port = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
+ if (port == nullptr) { // would only occur on thread issue.
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+
+ port->channel = static_cast<uint8_t>(channel);
+
+ SimDIOData[channel].initialized = true;
+ SimDIOData[channel].isInput = input;
+ SimDIOData[channel].simDevice = 0;
+
+ return handle;
+}
+
+HAL_Bool HAL_CheckDIOChannel(int32_t channel) {
+ return channel < kNumDigitalChannels && channel >= 0;
+}
+
+void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) {
+ auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
+ // no status, so no need to check for a proper free.
+ digitalChannelHandles->Free(dioPortHandle, HAL_HandleEnum::DIO);
+ if (port == nullptr) return;
+ SimDIOData[port->channel].initialized = false;
+}
+
+void HAL_SetDIOSimDevice(HAL_DigitalHandle handle, HAL_SimDeviceHandle device) {
+ auto port = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
+ if (port == nullptr) return;
+ SimDIOData[port->channel].simDevice = device;
+}
+
+HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status) {
+ auto handle = digitalPWMHandles->Allocate();
+ if (handle == HAL_kInvalidHandle) {
+ *status = NO_AVAILABLE_RESOURCES;
+ return HAL_kInvalidHandle;
+ }
+
+ auto id = digitalPWMHandles->Get(handle);
+ if (id == nullptr) { // would only occur on thread issue.
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+ *id = static_cast<uint8_t>(getHandleIndex(handle));
+
+ SimDigitalPWMData[*id].initialized = true;
+
+ return handle;
+}
+
+void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status) {
+ auto port = digitalPWMHandles->Get(pwmGenerator);
+ digitalPWMHandles->Free(pwmGenerator);
+ if (port == nullptr) return;
+ int32_t id = *port;
+ SimDigitalPWMData[id].initialized = false;
+}
+
+void HAL_SetDigitalPWMRate(double rate, int32_t* status) {
+ // Currently rounding in the log rate domain... heavy weight toward picking a
+ // higher freq.
+ // TODO: Round in the linear rate domain.
+ // uint8_t pwmPeriodPower = static_cast<uint8_t>(
+ // std::log(1.0 / (kExpectedLoopTiming * 0.25E-6 * rate)) /
+ // std::log(2.0) +
+ // 0.5);
+ // TODO(THAD) : Add a case to set this in the simulator
+ // digitalSystem->writePWMPeriodPower(pwmPeriodPower, status);
+}
+
+void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
+ double dutyCycle, int32_t* status) {
+ auto port = digitalPWMHandles->Get(pwmGenerator);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ int32_t id = *port;
+ if (dutyCycle > 1.0) dutyCycle = 1.0;
+ if (dutyCycle < 0.0) dutyCycle = 0.0;
+ SimDigitalPWMData[id].dutyCycle = dutyCycle;
+}
+
+void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
+ int32_t channel, int32_t* status) {
+ auto port = digitalPWMHandles->Get(pwmGenerator);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ int32_t id = *port;
+ SimDigitalPWMData[id].pin = channel;
+}
+
+void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
+ int32_t* status) {
+ auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ if (value != 0 && value != 1) {
+ if (value != 0) value = 1;
+ }
+ SimDIOData[port->channel].value = value;
+}
+
+void HAL_SetDIODirection(HAL_DigitalHandle dioPortHandle, HAL_Bool input,
+ int32_t* status) {
+ auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimDIOData[port->channel].isInput = input;
+}
+
+HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status) {
+ auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ HAL_Bool value = SimDIOData[port->channel].value;
+ if (value > 1) value = 1;
+ if (value < 0) value = 0;
+ return value;
+}
+
+HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status) {
+ auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ HAL_Bool value = SimDIOData[port->channel].isInput;
+ if (value > 1) value = 1;
+ if (value < 0) value = 0;
+ return value;
+}
+
+void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
+ int32_t* status) {
+ auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ // TODO (Thad) Add this
+}
+
+HAL_Bool HAL_IsPulsing(HAL_DigitalHandle dioPortHandle, int32_t* status) {
+ auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ return false;
+ // TODO (Thad) Add this
+}
+
+HAL_Bool HAL_IsAnyPulsing(int32_t* status) {
+ return false; // TODO(Thad) Figure this out
+}
+
+void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
+ int32_t* status) {
+ auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ // TODO(Thad) Figure this out
+}
+
+int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) {
+ auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return 0;
+ // TODO(Thad) Figure this out
+}
+
+void HAL_SetFilterPeriod(int32_t filterIndex, int64_t value, int32_t* status) {
+ // TODO(Thad) figure this out
+}
+
+int64_t HAL_GetFilterPeriod(int32_t filterIndex, int32_t* status) {
+ return 0; // TODO(Thad) figure this out
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/DMA.cpp b/hal/src/main/native/sim/DMA.cpp
new file mode 100644
index 0000000..cea5a29
--- /dev/null
+++ b/hal/src/main/native/sim/DMA.cpp
@@ -0,0 +1,124 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/DMA.h"
+
+extern "C" {
+HAL_DMAHandle HAL_InitializeDMA(int32_t* status) { return HAL_kInvalidHandle; }
+void HAL_FreeDMA(HAL_DMAHandle handle) {}
+
+void HAL_SetDMAPause(HAL_DMAHandle handle, HAL_Bool pause, int32_t* status) {}
+void HAL_SetDMARate(HAL_DMAHandle handle, int32_t cycles, int32_t* status) {}
+
+void HAL_AddDMAEncoder(HAL_DMAHandle handle, HAL_EncoderHandle encoderHandle,
+ int32_t* status) {}
+void HAL_AddDMAEncoderPeriod(HAL_DMAHandle handle,
+ HAL_EncoderHandle encoderHandle, int32_t* status) {
+}
+void HAL_AddDMACounter(HAL_DMAHandle handle, HAL_CounterHandle counterHandle,
+ int32_t* status) {}
+void HAL_AddDMACounterPeriod(HAL_DMAHandle handle,
+ HAL_CounterHandle counterHandle, int32_t* status) {
+}
+void HAL_AddDMADigitalSource(HAL_DMAHandle handle,
+ HAL_Handle digitalSourceHandle, int32_t* status) {}
+void HAL_AddDMAAnalogInput(HAL_DMAHandle handle,
+ HAL_AnalogInputHandle aInHandle, int32_t* status) {}
+
+void HAL_AddDMAAveragedAnalogInput(HAL_DMAHandle handle,
+ HAL_AnalogInputHandle aInHandle,
+ int32_t* status) {}
+
+void HAL_AddDMAAnalogAccumulator(HAL_DMAHandle handle,
+ HAL_AnalogInputHandle aInHandle,
+ int32_t* status) {}
+
+void HAL_AddDMADutyCycle(HAL_DMAHandle handle,
+ HAL_DutyCycleHandle dutyCycleHandle, int32_t* status) {
+}
+
+void HAL_SetDMAExternalTrigger(HAL_DMAHandle handle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ HAL_Bool rising, HAL_Bool falling,
+ int32_t* status) {}
+
+void HAL_StartDMA(HAL_DMAHandle handle, int32_t queueDepth, int32_t* status) {}
+void HAL_StopDMA(HAL_DMAHandle handle, int32_t* status) {}
+
+void* HAL_GetDMADirectPointer(HAL_DMAHandle handle) { return nullptr; }
+
+enum HAL_DMAReadStatus HAL_ReadDMADirect(void* dmaPointer,
+ HAL_DMASample* dmaSample,
+ int32_t timeoutMs,
+ int32_t* remainingOut,
+ int32_t* status) {
+ return HAL_DMA_ERROR;
+}
+
+enum HAL_DMAReadStatus HAL_ReadDMA(HAL_DMAHandle handle,
+ HAL_DMASample* dmaSample, int32_t timeoutMs,
+ int32_t* remainingOut, int32_t* status) {
+ return HAL_DMA_ERROR;
+}
+
+// Sampling Code
+uint64_t HAL_GetDMASampleTime(const HAL_DMASample* dmaSample, int32_t* status) {
+ return 0;
+}
+
+int32_t HAL_GetDMASampleEncoderRaw(const HAL_DMASample* dmaSample,
+ HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ return 0;
+}
+
+int32_t HAL_GetDMASampleCounter(const HAL_DMASample* dmaSample,
+ HAL_CounterHandle counterHandle,
+ int32_t* status) {
+ return 0;
+}
+
+int32_t HAL_GetDMASampleEncoderPeriodRaw(const HAL_DMASample* dmaSample,
+ HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ return 0;
+}
+
+int32_t HAL_GetDMASampleCounterPeriod(const HAL_DMASample* dmaSample,
+ HAL_CounterHandle counterHandle,
+ int32_t* status) {
+ return 0;
+}
+HAL_Bool HAL_GetDMASampleDigitalSource(const HAL_DMASample* dmaSample,
+ HAL_Handle dSourceHandle,
+ int32_t* status) {
+ return 0;
+}
+int32_t HAL_GetDMASampleAnalogInputRaw(const HAL_DMASample* dmaSample,
+ HAL_AnalogInputHandle aInHandle,
+ int32_t* status) {
+ return 0;
+}
+
+int32_t HAL_GetDMASampleAveragedAnalogInputRaw(const HAL_DMASample* dmaSample,
+ HAL_AnalogInputHandle aInHandle,
+ int32_t* status) {
+ return 0;
+}
+
+void HAL_GetDMASampleAnalogAccumulator(const HAL_DMASample* dmaSample,
+ HAL_AnalogInputHandle aInHandle,
+ int64_t* count, int64_t* value,
+ int32_t* status) {}
+
+int32_t HAL_GetDMASampleDutyCycleOutputRaw(const HAL_DMASample* dmaSample,
+ HAL_DutyCycleHandle dutyCycleHandle,
+ int32_t* status) {
+ return 0;
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/DigitalInternal.cpp b/hal/src/main/native/sim/DigitalInternal.cpp
new file mode 100644
index 0000000..070754a
--- /dev/null
+++ b/hal/src/main/native/sim/DigitalInternal.cpp
@@ -0,0 +1,77 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 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 "DigitalInternal.h"
+
+#include "ConstantsInternal.h"
+#include "PortsInternal.h"
+#include "hal/AnalogTrigger.h"
+#include "hal/HAL.h"
+#include "hal/Ports.h"
+
+namespace hal {
+
+DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
+ kNumDigitalChannels + kNumPWMHeaders>*
+ digitalChannelHandles;
+
+namespace init {
+void InitializeDigitalInternal() {
+ static DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
+ kNumDigitalChannels + kNumPWMHeaders>
+ dcH;
+ digitalChannelHandles = &dcH;
+}
+} // namespace init
+
+bool remapDigitalSource(HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ uint8_t& channel, uint8_t& module,
+ bool& analogTrigger) {
+ if (isHandleType(digitalSourceHandle, HAL_HandleEnum::AnalogTrigger)) {
+ // If handle passed, index is not negative
+ int32_t index = getHandleIndex(digitalSourceHandle);
+ channel = (index << 2) + analogTriggerType;
+ module = channel >> 4;
+ analogTrigger = true;
+ return true;
+ } else if (isHandleType(digitalSourceHandle, HAL_HandleEnum::DIO)) {
+ int32_t index = getHandleIndex(digitalSourceHandle);
+ if (index >= kNumDigitalHeaders) {
+ channel = remapMXPChannel(index);
+ module = 1;
+ } else {
+ channel = index;
+ module = 0;
+ }
+ analogTrigger = false;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+int32_t remapMXPChannel(int32_t channel) { return channel - 10; }
+
+int32_t remapMXPPWMChannel(int32_t channel) {
+ if (channel < 14) {
+ return channel - 10; // first block of 4 pwms (MXP 0-3)
+ } else {
+ return channel - 6; // block of PWMs after SPI
+ }
+}
+
+int32_t GetDigitalInputChannel(HAL_DigitalHandle handle, int32_t* status) {
+ auto digital = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
+ if (digital == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return -1;
+ }
+
+ return digital->channel;
+}
+} // namespace hal
diff --git a/hal/src/main/native/sim/DigitalInternal.h b/hal/src/main/native/sim/DigitalInternal.h
new file mode 100644
index 0000000..9df4c51
--- /dev/null
+++ b/hal/src/main/native/sim/DigitalInternal.h
@@ -0,0 +1,93 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "PortsInternal.h"
+#include "hal/AnalogTrigger.h"
+#include "hal/Ports.h"
+#include "hal/Types.h"
+#include "hal/handles/DigitalHandleResource.h"
+#include "hal/handles/HandlesInternal.h"
+
+namespace hal {
+/**
+ * MXP channels when used as digital output PWM are offset from actual value
+ */
+constexpr int32_t kMXPDigitalPWMOffset = 6;
+
+constexpr int32_t kExpectedLoopTiming = 40;
+
+/**
+ * kDefaultPwmPeriod is in ms
+ *
+ * - 20ms periods (50 Hz) are the "safest" setting in that this works for all
+ * devices
+ * - 20ms periods seem to be desirable for Vex Motors
+ * - 20ms periods are the specified period for HS-322HD servos, but work
+ * reliably down to 10.0 ms; starting at about 8.5ms, the servo sometimes hums
+ * and get hot; by 5.0ms the hum is nearly continuous
+ * - 10ms periods work well for Victor 884
+ * - 5ms periods allows higher update rates for Luminary Micro Jaguar speed
+ * controllers. Due to the shipping firmware on the Jaguar, we can't run the
+ * update period less than 5.05 ms.
+ *
+ * kDefaultPwmPeriod is the 1x period (5.05 ms). In hardware, the period
+ * scaling is implemented as an output squelch to get longer periods for old
+ * devices.
+ */
+constexpr float kDefaultPwmPeriod = 5.05f;
+/**
+ * kDefaultPwmCenter is the PWM range center in ms
+ */
+constexpr float kDefaultPwmCenter = 1.5f;
+/**
+ * kDefaultPWMStepsDown is the number of PWM steps below the centerpoint
+ */
+constexpr int32_t kDefaultPwmStepsDown = 1000;
+constexpr int32_t kPwmDisabled = 0;
+
+struct DigitalPort {
+ uint8_t channel;
+ bool configSet = false;
+ bool eliminateDeadband = false;
+ int32_t maxPwm = 0;
+ int32_t deadbandMaxPwm = 0;
+ int32_t centerPwm = 0;
+ int32_t deadbandMinPwm = 0;
+ int32_t minPwm = 0;
+};
+
+extern DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
+ kNumDigitalChannels + kNumPWMHeaders>*
+ digitalChannelHandles;
+
+/**
+ * Remap the digital source channel and set the module.
+ *
+ * If it's an analog trigger, determine the module from the high order routing
+ * channel else do normal digital input remapping based on channel number
+ * (MXP).
+ */
+bool remapDigitalSource(HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ uint8_t& channel, uint8_t& module, bool& analogTrigger);
+
+/**
+ * Map DIO channel numbers from their physical number (10 to 26) to their
+ * position in the bit field.
+ */
+int32_t remapMXPChannel(int32_t channel);
+
+int32_t remapMXPPWMChannel(int32_t channel);
+
+int32_t GetDigitalInputChannel(HAL_DigitalHandle handle, int32_t* status);
+} // namespace hal
diff --git a/hal/src/main/native/sim/DriverStation.cpp b/hal/src/main/native/sim/DriverStation.cpp
new file mode 100644
index 0000000..e8404cf
--- /dev/null
+++ b/hal/src/main/native/sim/DriverStation.cpp
@@ -0,0 +1,335 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/DriverStation.h"
+
+#ifdef __APPLE__
+#include <pthread.h>
+#endif
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <string>
+
+#include <wpi/condition_variable.h>
+#include <wpi/mutex.h>
+
+#include "HALInitializer.h"
+#include "mockdata/DriverStationDataInternal.h"
+#include "mockdata/MockHooks.h"
+
+static wpi::mutex msgMutex;
+static wpi::condition_variable* newDSDataAvailableCond;
+static wpi::mutex newDSDataAvailableMutex;
+static int newDSDataAvailableCounter{0};
+static std::atomic_bool isFinalized{false};
+static std::atomic<HALSIM_SendErrorHandler> sendErrorHandler{nullptr};
+
+namespace hal {
+namespace init {
+void InitializeDriverStation() {
+ static wpi::condition_variable nddaC;
+ newDSDataAvailableCond = &nddaC;
+}
+} // namespace init
+} // namespace hal
+
+using namespace hal;
+
+extern "C" {
+
+void HALSIM_SetSendError(HALSIM_SendErrorHandler handler) {
+ sendErrorHandler.store(handler);
+}
+
+int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
+ const char* details, const char* location,
+ const char* callStack, HAL_Bool printMsg) {
+ auto errorHandler = sendErrorHandler.load();
+ if (errorHandler)
+ return errorHandler(isError, errorCode, isLVCode, details, location,
+ callStack, printMsg);
+ // Avoid flooding console by keeping track of previous 5 error
+ // messages and only printing again if they're longer than 1 second old.
+ static constexpr int KEEP_MSGS = 5;
+ std::scoped_lock lock(msgMutex);
+ static std::string prevMsg[KEEP_MSGS];
+ static std::chrono::time_point<std::chrono::steady_clock>
+ prevMsgTime[KEEP_MSGS];
+ static bool initialized = false;
+ if (!initialized) {
+ for (int i = 0; i < KEEP_MSGS; i++) {
+ prevMsgTime[i] =
+ std::chrono::steady_clock::now() - std::chrono::seconds(2);
+ }
+ initialized = true;
+ }
+
+ auto curTime = std::chrono::steady_clock::now();
+ int i;
+ for (i = 0; i < KEEP_MSGS; ++i) {
+ if (prevMsg[i] == details) break;
+ }
+ int retval = 0;
+ if (i == KEEP_MSGS || (curTime - prevMsgTime[i]) >= std::chrono::seconds(1)) {
+ printMsg = true;
+ if (printMsg) {
+ if (location && location[0] != '\0') {
+ std::fprintf(stderr, "%s at %s: ", isError ? "Error" : "Warning",
+ location);
+ }
+ std::fprintf(stderr, "%s\n", details);
+ if (callStack && callStack[0] != '\0') {
+ std::fprintf(stderr, "%s\n", callStack);
+ }
+ }
+ if (i == KEEP_MSGS) {
+ // replace the oldest one
+ i = 0;
+ auto first = prevMsgTime[0];
+ for (int j = 1; j < KEEP_MSGS; ++j) {
+ if (prevMsgTime[j] < first) {
+ first = prevMsgTime[j];
+ i = j;
+ }
+ }
+ prevMsg[i] = details;
+ }
+ prevMsgTime[i] = curTime;
+ }
+ return retval;
+}
+
+int32_t HAL_GetControlWord(HAL_ControlWord* controlWord) {
+ controlWord->enabled = SimDriverStationData->enabled;
+ controlWord->autonomous = SimDriverStationData->autonomous;
+ controlWord->test = SimDriverStationData->test;
+ controlWord->eStop = SimDriverStationData->eStop;
+ controlWord->fmsAttached = SimDriverStationData->fmsAttached;
+ controlWord->dsAttached = SimDriverStationData->dsAttached;
+ return 0;
+}
+
+HAL_AllianceStationID HAL_GetAllianceStation(int32_t* status) {
+ *status = 0;
+ return SimDriverStationData->allianceStationId;
+}
+
+int32_t HAL_GetJoystickAxes(int32_t joystickNum, HAL_JoystickAxes* axes) {
+ SimDriverStationData->GetJoystickAxes(joystickNum, axes);
+ return 0;
+}
+
+int32_t HAL_GetJoystickPOVs(int32_t joystickNum, HAL_JoystickPOVs* povs) {
+ SimDriverStationData->GetJoystickPOVs(joystickNum, povs);
+ return 0;
+}
+
+int32_t HAL_GetJoystickButtons(int32_t joystickNum,
+ HAL_JoystickButtons* buttons) {
+ SimDriverStationData->GetJoystickButtons(joystickNum, buttons);
+ return 0;
+}
+
+int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
+ HAL_JoystickDescriptor* desc) {
+ SimDriverStationData->GetJoystickDescriptor(joystickNum, desc);
+ return 0;
+}
+
+HAL_Bool HAL_GetJoystickIsXbox(int32_t joystickNum) {
+ HAL_JoystickDescriptor desc;
+ SimDriverStationData->GetJoystickDescriptor(joystickNum, &desc);
+ return desc.isXbox;
+}
+
+int32_t HAL_GetJoystickType(int32_t joystickNum) {
+ HAL_JoystickDescriptor desc;
+ SimDriverStationData->GetJoystickDescriptor(joystickNum, &desc);
+ return desc.type;
+}
+
+char* HAL_GetJoystickName(int32_t joystickNum) {
+ HAL_JoystickDescriptor desc;
+ SimDriverStationData->GetJoystickDescriptor(joystickNum, &desc);
+ size_t len = std::strlen(desc.name);
+ char* name = static_cast<char*>(std::malloc(len + 1));
+ std::memcpy(name, desc.name, len + 1);
+ return name;
+}
+
+void HAL_FreeJoystickName(char* name) { std::free(name); }
+
+int32_t HAL_GetJoystickAxisType(int32_t joystickNum, int32_t axis) { return 0; }
+
+int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
+ int32_t leftRumble, int32_t rightRumble) {
+ SimDriverStationData->SetJoystickOutputs(joystickNum, outputs, leftRumble,
+ rightRumble);
+ return 0;
+}
+
+double HAL_GetMatchTime(int32_t* status) {
+ return SimDriverStationData->matchTime;
+}
+
+int32_t HAL_GetMatchInfo(HAL_MatchInfo* info) {
+ SimDriverStationData->GetMatchInfo(info);
+ return 0;
+}
+
+void HAL_ObserveUserProgramStarting(void) { HALSIM_SetProgramStarted(); }
+
+void HAL_ObserveUserProgramDisabled(void) {
+ // TODO
+}
+
+void HAL_ObserveUserProgramAutonomous(void) {
+ // TODO
+}
+
+void HAL_ObserveUserProgramTeleop(void) {
+ // TODO
+}
+
+void HAL_ObserveUserProgramTest(void) {
+ // TODO
+}
+
+#ifdef __APPLE__
+static pthread_key_t lastCountKey;
+static pthread_once_t lastCountKeyOnce = PTHREAD_ONCE_INIT;
+
+static void InitLastCountKey(void) {
+ pthread_key_create(&lastCountKey, std::free);
+}
+#endif
+
+static int& GetThreadLocalLastCount() {
+ // There is a rollover error condition here. At Packet# = n * (uintmax), this
+ // will return false when instead it should return true. However, this at a
+ // 20ms rate occurs once every 2.7 years of DS connected runtime, so not
+ // worth the cycles to check.
+#ifdef __APPLE__
+ pthread_once(&lastCountKeyOnce, InitLastCountKey);
+ int* lastCountPtr = static_cast<int*>(pthread_getspecific(lastCountKey));
+ if (!lastCountPtr) {
+ lastCountPtr = static_cast<int*>(std::malloc(sizeof(int)));
+ *lastCountPtr = -1;
+ pthread_setspecific(lastCountKey, lastCountPtr);
+ }
+ int& lastCount = *lastCountPtr;
+#else
+ thread_local int lastCount{-1};
+#endif
+ return lastCount;
+}
+
+HAL_Bool HAL_WaitForCachedControlDataTimeout(double timeout) {
+ int& lastCount = GetThreadLocalLastCount();
+ std::unique_lock lock(newDSDataAvailableMutex);
+ int currentCount = newDSDataAvailableCounter;
+ if (lastCount != currentCount) {
+ lastCount = currentCount;
+ return true;
+ }
+
+ if (isFinalized.load()) {
+ return false;
+ }
+
+ auto timeoutTime =
+ std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
+
+ while (newDSDataAvailableCounter == currentCount) {
+ if (timeout > 0) {
+ auto timedOut = newDSDataAvailableCond->wait_until(lock, timeoutTime);
+ if (timedOut == std::cv_status::timeout) {
+ return false;
+ }
+ } else {
+ newDSDataAvailableCond->wait(lock);
+ }
+ }
+ return true;
+}
+
+HAL_Bool HAL_IsNewControlData(void) {
+ int& lastCount = GetThreadLocalLastCount();
+ int currentCount = 0;
+ {
+ std::scoped_lock lock(newDSDataAvailableMutex);
+ currentCount = newDSDataAvailableCounter;
+ }
+ if (lastCount == currentCount) return false;
+ lastCount = currentCount;
+ return true;
+}
+
+void HAL_WaitForDSData(void) { HAL_WaitForDSDataTimeout(0); }
+
+HAL_Bool HAL_WaitForDSDataTimeout(double timeout) {
+ if (isFinalized.load()) {
+ return false;
+ }
+ auto timeoutTime =
+ std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
+
+ std::unique_lock lock(newDSDataAvailableMutex);
+ int currentCount = newDSDataAvailableCounter;
+ while (newDSDataAvailableCounter == currentCount) {
+ if (timeout > 0) {
+ auto timedOut = newDSDataAvailableCond->wait_until(lock, timeoutTime);
+ if (timedOut == std::cv_status::timeout) {
+ return false;
+ }
+ } else {
+ newDSDataAvailableCond->wait(lock);
+ }
+ }
+ return true;
+}
+
+// Constant number to be used for our occur handle
+constexpr int32_t refNumber = 42;
+
+static int32_t newDataOccur(uint32_t refNum) {
+ // Since we could get other values, require our specific handle
+ // to signal our threads
+ if (refNum != refNumber) return 0;
+ std::scoped_lock lock(newDSDataAvailableMutex);
+ // Nofify all threads
+ newDSDataAvailableCounter++;
+ newDSDataAvailableCond->notify_all();
+ return 0;
+}
+
+void HAL_InitializeDriverStation(void) {
+ hal::init::CheckInit();
+ static std::atomic_bool initialized{false};
+ static wpi::mutex initializeMutex;
+ // Initial check, as if it's true initialization has finished
+ if (initialized) return;
+
+ std::scoped_lock lock(initializeMutex);
+ // Second check in case another thread was waiting
+ if (initialized) return;
+
+ SimDriverStationData->ResetData();
+
+ std::atexit([]() {
+ isFinalized.store(true);
+ HAL_ReleaseDSMutex();
+ });
+
+ initialized = true;
+}
+
+void HAL_ReleaseDSMutex(void) { newDataOccur(refNumber); }
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/DutyCycle.cpp b/hal/src/main/native/sim/DutyCycle.cpp
new file mode 100644
index 0000000..0e14eeb
--- /dev/null
+++ b/hal/src/main/native/sim/DutyCycle.cpp
@@ -0,0 +1,120 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/DutyCycle.h"
+
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/Errors.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/LimitedHandleResource.h"
+#include "mockdata/DutyCycleDataInternal.h"
+
+using namespace hal;
+
+namespace {
+struct DutyCycle {
+ uint8_t index;
+};
+struct Empty {};
+} // namespace
+
+static LimitedHandleResource<HAL_DutyCycleHandle, DutyCycle, kNumDutyCycles,
+ HAL_HandleEnum::DutyCycle>* dutyCycleHandles;
+
+namespace hal {
+namespace init {
+void InitializeDutyCycle() {
+ static LimitedHandleResource<HAL_DutyCycleHandle, DutyCycle, kNumDutyCycles,
+ HAL_HandleEnum::DutyCycle>
+ dcH;
+ dutyCycleHandles = &dcH;
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType triggerType,
+ int32_t* status) {
+ hal::init::CheckInit();
+
+ HAL_DutyCycleHandle handle = dutyCycleHandles->Allocate();
+ if (handle == HAL_kInvalidHandle) {
+ *status = NO_AVAILABLE_RESOURCES;
+ return HAL_kInvalidHandle;
+ }
+
+ auto dutyCycle = dutyCycleHandles->Get(handle);
+ if (dutyCycle == nullptr) { // would only occur on thread issue
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+
+ int16_t index = getHandleIndex(handle);
+ SimDutyCycleData[index].digitalChannel = getHandleIndex(digitalSourceHandle);
+ SimDutyCycleData[index].initialized = true;
+ SimDutyCycleData[index].simDevice = 0;
+ dutyCycle->index = index;
+ return handle;
+}
+void HAL_FreeDutyCycle(HAL_DutyCycleHandle dutyCycleHandle) {
+ auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
+ dutyCycleHandles->Free(dutyCycleHandle);
+ if (dutyCycle == nullptr) return;
+ SimDutyCycleData[dutyCycle->index].initialized = false;
+}
+
+void HAL_SetDutyCycleSimDevice(HAL_EncoderHandle handle,
+ HAL_SimDeviceHandle device) {
+ auto dutyCycle = dutyCycleHandles->Get(handle);
+ if (dutyCycle == nullptr) return;
+ SimDutyCycleData[dutyCycle->index].simDevice = device;
+}
+
+int32_t HAL_GetDutyCycleFrequency(HAL_DutyCycleHandle dutyCycleHandle,
+ int32_t* status) {
+ auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
+ if (dutyCycle == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return SimDutyCycleData[dutyCycle->index].frequency;
+}
+double HAL_GetDutyCycleOutput(HAL_DutyCycleHandle dutyCycleHandle,
+ int32_t* status) {
+ auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
+ if (dutyCycle == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return SimDutyCycleData[dutyCycle->index].output;
+}
+int32_t HAL_GetDutyCycleOutputRaw(HAL_DutyCycleHandle dutyCycleHandle,
+ int32_t* status) {
+ auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
+ if (dutyCycle == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return SimDutyCycleData[dutyCycle->index].output *
+ HAL_GetDutyCycleOutputScaleFactor(dutyCycleHandle, status);
+}
+int32_t HAL_GetDutyCycleOutputScaleFactor(HAL_DutyCycleHandle dutyCycleHandle,
+ int32_t* status) {
+ return 4e7 - 1;
+}
+int32_t HAL_GetDutyCycleFPGAIndex(HAL_DutyCycleHandle dutyCycleHandle,
+ int32_t* status) {
+ auto dutyCycle = dutyCycleHandles->Get(dutyCycleHandle);
+ if (dutyCycle == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return -1;
+ }
+ return dutyCycle->index;
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/Encoder.cpp b/hal/src/main/native/sim/Encoder.cpp
new file mode 100644
index 0000000..36122bf
--- /dev/null
+++ b/hal/src/main/native/sim/Encoder.cpp
@@ -0,0 +1,354 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/Encoder.h"
+
+#include "CounterInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/Counter.h"
+#include "hal/Errors.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/LimitedHandleResource.h"
+#include "mockdata/EncoderDataInternal.h"
+
+using namespace hal;
+
+namespace {
+struct Encoder {
+ HAL_Handle nativeHandle;
+ HAL_EncoderEncodingType encodingType;
+ double distancePerPulse;
+ uint8_t index;
+};
+struct Empty {};
+} // namespace
+
+static LimitedHandleResource<HAL_EncoderHandle, Encoder,
+ kNumEncoders + kNumCounters,
+ HAL_HandleEnum::Encoder>* encoderHandles;
+
+static LimitedHandleResource<HAL_FPGAEncoderHandle, Empty, kNumEncoders,
+ HAL_HandleEnum::FPGAEncoder>* fpgaEncoderHandles;
+
+namespace hal {
+namespace init {
+void InitializeEncoder() {
+ static LimitedHandleResource<HAL_FPGAEncoderHandle, Empty, kNumEncoders,
+ HAL_HandleEnum::FPGAEncoder>
+ feH;
+ fpgaEncoderHandles = &feH;
+ static LimitedHandleResource<HAL_EncoderHandle, Encoder,
+ kNumEncoders + kNumCounters,
+ HAL_HandleEnum::Encoder>
+ eH;
+ encoderHandles = &eH;
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_EncoderHandle HAL_InitializeEncoder(
+ HAL_Handle digitalSourceHandleA, HAL_AnalogTriggerType analogTriggerTypeA,
+ HAL_Handle digitalSourceHandleB, HAL_AnalogTriggerType analogTriggerTypeB,
+ HAL_Bool reverseDirection, HAL_EncoderEncodingType encodingType,
+ int32_t* status) {
+ hal::init::CheckInit();
+ HAL_Handle nativeHandle = HAL_kInvalidHandle;
+ if (encodingType == HAL_EncoderEncodingType::HAL_Encoder_k4X) {
+ // k4x, allocate encoder
+ nativeHandle = fpgaEncoderHandles->Allocate();
+ } else {
+ // k2x or k1x, allocate counter
+ nativeHandle = counterHandles->Allocate();
+ }
+ if (nativeHandle == HAL_kInvalidHandle) {
+ *status = NO_AVAILABLE_RESOURCES;
+ return HAL_kInvalidHandle;
+ }
+ auto handle = encoderHandles->Allocate();
+ if (handle == HAL_kInvalidHandle) {
+ *status = NO_AVAILABLE_RESOURCES;
+ return HAL_kInvalidHandle;
+ }
+ auto encoder = encoderHandles->Get(handle);
+ if (encoder == nullptr) { // would only occur on thread issue
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+ int16_t index = getHandleIndex(handle);
+ SimEncoderData[index].digitalChannelA = getHandleIndex(digitalSourceHandleA);
+ SimEncoderData[index].digitalChannelB = getHandleIndex(digitalSourceHandleB);
+ SimEncoderData[index].initialized = true;
+ SimEncoderData[index].reverseDirection = reverseDirection;
+ SimEncoderData[index].simDevice = 0;
+ // TODO: Add encoding type to Sim data
+ encoder->index = index;
+ encoder->nativeHandle = nativeHandle;
+ encoder->encodingType = encodingType;
+ encoder->distancePerPulse = 1.0;
+ return handle;
+}
+
+void HAL_FreeEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ encoderHandles->Free(encoderHandle);
+ if (encoder == nullptr) return;
+ if (isHandleType(encoder->nativeHandle, HAL_HandleEnum::FPGAEncoder)) {
+ fpgaEncoderHandles->Free(encoder->nativeHandle);
+ } else if (isHandleType(encoder->nativeHandle, HAL_HandleEnum::Counter)) {
+ counterHandles->Free(encoder->nativeHandle);
+ }
+ SimEncoderData[encoder->index].initialized = false;
+}
+
+void HAL_SetEncoderSimDevice(HAL_EncoderHandle handle,
+ HAL_SimDeviceHandle device) {
+ auto encoder = encoderHandles->Get(handle);
+ if (encoder == nullptr) return;
+ SimEncoderData[encoder->index].simDevice = device;
+}
+
+static inline int EncodingScaleFactor(Encoder* encoder) {
+ switch (encoder->encodingType) {
+ case HAL_Encoder_k1X:
+ return 1;
+ case HAL_Encoder_k2X:
+ return 2;
+ case HAL_Encoder_k4X:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
+static inline double DecodingScaleFactor(Encoder* encoder) {
+ switch (encoder->encodingType) {
+ case HAL_Encoder_k1X:
+ return 1.0;
+ case HAL_Encoder_k2X:
+ return 0.5;
+ case HAL_Encoder_k4X:
+ return 0.25;
+ default:
+ return 0.0;
+ }
+}
+
+int32_t HAL_GetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimEncoderData[encoder->index].count;
+}
+int32_t HAL_GetEncoderRaw(HAL_EncoderHandle encoderHandle, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimEncoderData[encoder->index].count /
+ DecodingScaleFactor(encoder.get());
+}
+int32_t HAL_GetEncoderEncodingScale(HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return EncodingScaleFactor(encoder.get());
+}
+void HAL_ResetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimEncoderData[encoder->index].count = 0;
+ SimEncoderData[encoder->index].period = std::numeric_limits<double>::max();
+ SimEncoderData[encoder->index].reset = true;
+}
+double HAL_GetEncoderPeriod(HAL_EncoderHandle encoderHandle, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimEncoderData[encoder->index].period;
+}
+void HAL_SetEncoderMaxPeriod(HAL_EncoderHandle encoderHandle, double maxPeriod,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimEncoderData[encoder->index].maxPeriod = maxPeriod;
+}
+HAL_Bool HAL_GetEncoderStopped(HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimEncoderData[encoder->index].period >
+ SimEncoderData[encoder->index].maxPeriod;
+}
+HAL_Bool HAL_GetEncoderDirection(HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimEncoderData[encoder->index].direction;
+}
+double HAL_GetEncoderDistance(HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimEncoderData[encoder->index].count * encoder->distancePerPulse;
+}
+double HAL_GetEncoderRate(HAL_EncoderHandle encoderHandle, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return encoder->distancePerPulse / SimEncoderData[encoder->index].period;
+}
+void HAL_SetEncoderMinRate(HAL_EncoderHandle encoderHandle, double minRate,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ if (minRate == 0.0) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return;
+ }
+
+ SimEncoderData[encoder->index].maxPeriod =
+ encoder->distancePerPulse / minRate;
+}
+void HAL_SetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
+ double distancePerPulse, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ if (distancePerPulse == 0.0) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return;
+ }
+ encoder->distancePerPulse = distancePerPulse;
+ SimEncoderData[encoder->index].distancePerPulse = distancePerPulse;
+}
+void HAL_SetEncoderReverseDirection(HAL_EncoderHandle encoderHandle,
+ HAL_Bool reverseDirection,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimEncoderData[encoder->index].reverseDirection = reverseDirection;
+}
+void HAL_SetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
+ int32_t samplesToAverage, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimEncoderData[encoder->index].samplesToAverage = samplesToAverage;
+}
+int32_t HAL_GetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimEncoderData[encoder->index].samplesToAverage;
+}
+
+void HAL_SetEncoderIndexSource(HAL_EncoderHandle encoderHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ HAL_EncoderIndexingType type, int32_t* status) {
+ // Not implemented yet
+}
+
+int32_t HAL_GetEncoderFPGAIndex(HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return encoder->index;
+}
+
+double HAL_GetEncoderDecodingScaleFactor(HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0.0;
+ }
+
+ return DecodingScaleFactor(encoder.get());
+}
+
+double HAL_GetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0.0;
+ }
+
+ return encoder->distancePerPulse;
+}
+
+HAL_EncoderEncodingType HAL_GetEncoderEncodingType(
+ HAL_EncoderHandle encoderHandle, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return HAL_Encoder_k4X; // default to k4x
+ }
+
+ return encoder->encodingType;
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/ErrorsInternal.h b/hal/src/main/native/sim/ErrorsInternal.h
new file mode 100644
index 0000000..55372d8
--- /dev/null
+++ b/hal/src/main/native/sim/ErrorsInternal.h
@@ -0,0 +1,448 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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
+
+typedef enum {
+ CTR_OKAY, // No Error - Function executed as expected
+ CTR_RxTimeout, // CAN frame has not been received within specified period of
+ // time.
+ CTR_TxTimeout, // Not used.
+ CTR_InvalidParamValue, // Caller passed an invalid param
+ CTR_UnexpectedArbId, // Specified CAN Id is invalid.
+ CTR_TxFailed, // Could not transmit the CAN frame.
+ CTR_SigNotUpdated, // Have not received an value response for signal.
+ CTR_BufferFull, // Caller attempted to insert data into a buffer that is
+ // full.
+} CTR_Code;
+
+// VISA Error
+#define _VI_ERROR (-2147483647L - 1)
+#define VI_ERROR_SYSTEM_ERROR (_VI_ERROR + 0x3FFF0000L)
+#define VI_ERROR_INV_OBJECT (_VI_ERROR + 0x3FFF000EL)
+#define VI_ERROR_RSRC_LOCKED (_VI_ERROR + 0x3FFF000FL)
+#define VI_ERROR_INV_EXPR (_VI_ERROR + 0x3FFF0010L)
+#define VI_ERROR_RSRC_NFOUND (_VI_ERROR + 0x3FFF0011L)
+#define VI_ERROR_INV_RSRC_NAME (_VI_ERROR + 0x3FFF0012L)
+#define VI_ERROR_INV_ACC_MODE (_VI_ERROR + 0x3FFF0013L)
+#define VI_ERROR_TMO (_VI_ERROR + 0x3FFF0015L)
+#define VI_ERROR_CLOSING_FAILED (_VI_ERROR + 0x3FFF0016L)
+#define VI_ERROR_INV_DEGREE (_VI_ERROR + 0x3FFF001BL)
+#define VI_ERROR_INV_JOB_ID (_VI_ERROR + 0x3FFF001CL)
+#define VI_ERROR_NSUP_ATTR (_VI_ERROR + 0x3FFF001DL)
+#define VI_ERROR_NSUP_ATTR_STATE (_VI_ERROR + 0x3FFF001EL)
+#define VI_ERROR_ATTR_READONLY (_VI_ERROR + 0x3FFF001FL)
+#define VI_ERROR_INV_LOCK_TYPE (_VI_ERROR + 0x3FFF0020L)
+#define VI_ERROR_INV_ACCESS_KEY (_VI_ERROR + 0x3FFF0021L)
+#define VI_ERROR_INV_EVENT (_VI_ERROR + 0x3FFF0026L)
+#define VI_ERROR_INV_MECH (_VI_ERROR + 0x3FFF0027L)
+#define VI_ERROR_HNDLR_NINSTALLED (_VI_ERROR + 0x3FFF0028L)
+#define VI_ERROR_INV_HNDLR_REF (_VI_ERROR + 0x3FFF0029L)
+#define VI_ERROR_INV_CONTEXT (_VI_ERROR + 0x3FFF002AL)
+#define VI_ERROR_QUEUE_OVERFLOW (_VI_ERROR + 0x3FFF002DL)
+#define VI_ERROR_NENABLED (_VI_ERROR + 0x3FFF002FL)
+#define VI_ERROR_ABORT (_VI_ERROR + 0x3FFF0030L)
+#define VI_ERROR_RAW_WR_PROT_VIOL (_VI_ERROR + 0x3FFF0034L)
+#define VI_ERROR_RAW_RD_PROT_VIOL (_VI_ERROR + 0x3FFF0035L)
+#define VI_ERROR_OUTP_PROT_VIOL (_VI_ERROR + 0x3FFF0036L)
+#define VI_ERROR_INP_PROT_VIOL (_VI_ERROR + 0x3FFF0037L)
+#define VI_ERROR_BERR (_VI_ERROR + 0x3FFF0038L)
+#define VI_ERROR_IN_PROGRESS (_VI_ERROR + 0x3FFF0039L)
+#define VI_ERROR_INV_SETUP (_VI_ERROR + 0x3FFF003AL)
+#define VI_ERROR_QUEUE_ERROR (_VI_ERROR + 0x3FFF003BL)
+#define VI_ERROR_ALLOC (_VI_ERROR + 0x3FFF003CL)
+#define VI_ERROR_INV_MASK (_VI_ERROR + 0x3FFF003DL)
+#define VI_ERROR_IO (_VI_ERROR + 0x3FFF003EL)
+#define VI_ERROR_INV_FMT (_VI_ERROR + 0x3FFF003FL)
+#define VI_ERROR_NSUP_FMT (_VI_ERROR + 0x3FFF0041L)
+#define VI_ERROR_LINE_IN_USE (_VI_ERROR + 0x3FFF0042L)
+#define VI_ERROR_NSUP_MODE (_VI_ERROR + 0x3FFF0046L)
+#define VI_ERROR_SRQ_NOCCURRED (_VI_ERROR + 0x3FFF004AL)
+#define VI_ERROR_INV_SPACE (_VI_ERROR + 0x3FFF004EL)
+#define VI_ERROR_INV_OFFSET (_VI_ERROR + 0x3FFF0051L)
+#define VI_ERROR_INV_WIDTH (_VI_ERROR + 0x3FFF0052L)
+#define VI_ERROR_NSUP_OFFSET (_VI_ERROR + 0x3FFF0054L)
+#define VI_ERROR_NSUP_VAR_WIDTH (_VI_ERROR + 0x3FFF0055L)
+#define VI_ERROR_WINDOW_NMAPPED (_VI_ERROR + 0x3FFF0057L)
+#define VI_ERROR_RESP_PENDING (_VI_ERROR + 0x3FFF0059L)
+#define VI_ERROR_NLISTENERS (_VI_ERROR + 0x3FFF005FL)
+#define VI_ERROR_NCIC (_VI_ERROR + 0x3FFF0060L)
+#define VI_ERROR_NSYS_CNTLR (_VI_ERROR + 0x3FFF0061L)
+#define VI_ERROR_NSUP_OPER (_VI_ERROR + 0x3FFF0067L)
+#define VI_ERROR_INTR_PENDING (_VI_ERROR + 0x3FFF0068L)
+#define VI_ERROR_ASRL_PARITY (_VI_ERROR + 0x3FFF006AL)
+#define VI_ERROR_ASRL_FRAMING (_VI_ERROR + 0x3FFF006BL)
+#define VI_ERROR_ASRL_OVERRUN (_VI_ERROR + 0x3FFF006CL)
+#define VI_ERROR_TRIG_NMAPPED (_VI_ERROR + 0x3FFF006EL)
+#define VI_ERROR_NSUP_ALIGN_OFFSET (_VI_ERROR + 0x3FFF0070L)
+#define VI_ERROR_USER_BUF (_VI_ERROR + 0x3FFF0071L)
+#define VI_ERROR_RSRC_BUSY (_VI_ERROR + 0x3FFF0072L)
+#define VI_ERROR_NSUP_WIDTH (_VI_ERROR + 0x3FFF0076L)
+#define VI_ERROR_INV_PARAMETER (_VI_ERROR + 0x3FFF0078L)
+#define VI_ERROR_INV_PROT (_VI_ERROR + 0x3FFF0079L)
+#define VI_ERROR_INV_SIZE (_VI_ERROR + 0x3FFF007BL)
+#define VI_ERROR_WINDOW_MAPPED (_VI_ERROR + 0x3FFF0080L)
+#define VI_ERROR_NIMPL_OPER (_VI_ERROR + 0x3FFF0081L)
+#define VI_ERROR_INV_LENGTH (_VI_ERROR + 0x3FFF0083L)
+#define VI_ERROR_INV_MODE (_VI_ERROR + 0x3FFF0091L)
+#define VI_ERROR_SESN_NLOCKED (_VI_ERROR + 0x3FFF009CL)
+#define VI_ERROR_MEM_NSHARED (_VI_ERROR + 0x3FFF009DL)
+#define VI_ERROR_LIBRARY_NFOUND (_VI_ERROR + 0x3FFF009EL)
+#define VI_ERROR_NSUP_INTR (_VI_ERROR + 0x3FFF009FL)
+#define VI_ERROR_INV_LINE (_VI_ERROR + 0x3FFF00A0L)
+#define VI_ERROR_FILE_ACCESS (_VI_ERROR + 0x3FFF00A1L)
+#define VI_ERROR_FILE_IO (_VI_ERROR + 0x3FFF00A2L)
+#define VI_ERROR_NSUP_LINE (_VI_ERROR + 0x3FFF00A3L)
+#define VI_ERROR_NSUP_MECH (_VI_ERROR + 0x3FFF00A4L)
+#define VI_ERROR_INTF_NUM_NCONFIG (_VI_ERROR + 0x3FFF00A5L)
+#define VI_ERROR_CONN_LOST (_VI_ERROR + 0x3FFF00A6L)
+#define VI_ERROR_MACHINE_NAVAIL (_VI_ERROR + 0x3FFF00A7L)
+#define VI_ERROR_NPERMISSION (_VI_ERROR + 0x3FFF00A8L)
+
+// FPGA Errors
+
+/**
+ * Represents the resulting status of a function call through its return value.
+ * 0 is success, negative values are errors, and positive values are warnings.
+ */
+typedef int32_t NiFpga_Status;
+
+/**
+ * No errors or warnings.
+ */
+static const NiFpga_Status NiFpga_Status_Success = 0;
+
+/**
+ * The timeout expired before the FIFO operation could complete.
+ */
+static const NiFpga_Status NiFpga_Status_FifoTimeout = -50400;
+
+/**
+ * No transfer is in progress because the transfer was aborted by the client.
+ * The operation could not be completed as specified.
+ */
+static const NiFpga_Status NiFpga_Status_TransferAborted = -50405;
+
+/**
+ * A memory allocation failed. Try again after rebooting.
+ */
+static const NiFpga_Status NiFpga_Status_MemoryFull = -52000;
+
+/**
+ * An unexpected software error occurred.
+ */
+static const NiFpga_Status NiFpga_Status_SoftwareFault = -52003;
+
+/**
+ * A parameter to a function was not valid. This could be a NULL pointer, a bad
+ * value, etc.
+ */
+static const NiFpga_Status NiFpga_Status_InvalidParameter = -52005;
+
+/**
+ * A required resource was not found. The NiFpga.* library, the RIO resource, or
+ * some other resource may be missing.
+ */
+static const NiFpga_Status NiFpga_Status_ResourceNotFound = -52006;
+
+/**
+ * A required resource was not properly initialized. This could occur if
+ * NiFpga_Initialize was not called or a required NiFpga_IrqContext was not
+ * reserved.
+ */
+static const NiFpga_Status NiFpga_Status_ResourceNotInitialized = -52010;
+
+/**
+ * A hardware failure has occurred. The operation could not be completed as
+ * specified.
+ */
+static const NiFpga_Status NiFpga_Status_HardwareFault = -52018;
+
+/**
+ * The FPGA is already running.
+ */
+static const NiFpga_Status NiFpga_Status_FpgaAlreadyRunning = -61003;
+
+/**
+ * An error occurred downloading the VI to the FPGA device. Verify that
+ * the target is connected and powered and that the resource of the target
+ * is properly configured.
+ */
+static const NiFpga_Status NiFpga_Status_DownloadError = -61018;
+
+/**
+ * The bitfile was not compiled for the specified resource's device type.
+ */
+static const NiFpga_Status NiFpga_Status_DeviceTypeMismatch = -61024;
+
+/**
+ * An error was detected in the communication between the host computer and the
+ * FPGA target.
+ */
+static const NiFpga_Status NiFpga_Status_CommunicationTimeout = -61046;
+
+/**
+ * The timeout expired before any of the IRQs were asserted.
+ */
+static const NiFpga_Status NiFpga_Status_IrqTimeout = -61060;
+
+/**
+ * The specified bitfile is invalid or corrupt.
+ */
+static const NiFpga_Status NiFpga_Status_CorruptBitfile = -61070;
+
+/**
+ * The requested FIFO depth is invalid. It is either 0 or an amount not
+ * supported by the hardware.
+ */
+static const NiFpga_Status NiFpga_Status_BadDepth = -61072;
+
+/**
+ * The number of FIFO elements is invalid. Either the number is greater than the
+ * depth of the host memory DMA FIFO, or more elements were requested for
+ * release than had been acquired.
+ */
+static const NiFpga_Status NiFpga_Status_BadReadWriteCount = -61073;
+
+/**
+ * A hardware clocking error occurred. A derived clock lost lock with its base
+ * clock during the execution of the LabVIEW FPGA VI. If any base clocks with
+ * derived clocks are referencing an external source, make sure that the
+ * external source is connected and within the supported frequency, jitter,
+ * accuracy, duty cycle, and voltage specifications. Also verify that the
+ * characteristics of the base clock match the configuration specified in the
+ * FPGA Base Clock Properties. If all base clocks with derived clocks are
+ * generated from free-running, on-board sources, please contact National
+ * Instruments technical support at ni.com/support.
+ */
+static const NiFpga_Status NiFpga_Status_ClockLostLock = -61083;
+
+/**
+ * The operation could not be performed because the FPGA is busy. Stop all
+ * activities on the FPGA before requesting this operation. If the target is in
+ * Scan Interface programming mode, put it in FPGA Interface programming mode.
+ */
+static const NiFpga_Status NiFpga_Status_FpgaBusy = -61141;
+
+/**
+ * The operation could not be performed because the FPGA is busy operating in
+ * FPGA Interface C API mode. Stop all activities on the FPGA before requesting
+ * this operation.
+ */
+static const NiFpga_Status NiFpga_Status_FpgaBusyFpgaInterfaceCApi = -61200;
+
+/**
+ * The chassis is in Scan Interface programming mode. In order to run FPGA VIs,
+ * you must go to the chassis properties page, select FPGA programming mode, and
+ * deploy settings.
+ */
+static const NiFpga_Status NiFpga_Status_FpgaBusyScanInterface = -61201;
+
+/**
+ * The operation could not be performed because the FPGA is busy operating in
+ * FPGA Interface mode. Stop all activities on the FPGA before requesting this
+ * operation.
+ */
+static const NiFpga_Status NiFpga_Status_FpgaBusyFpgaInterface = -61202;
+
+/**
+ * The operation could not be performed because the FPGA is busy operating in
+ * Interactive mode. Stop all activities on the FPGA before requesting this
+ * operation.
+ */
+static const NiFpga_Status NiFpga_Status_FpgaBusyInteractive = -61203;
+
+/**
+ * The operation could not be performed because the FPGA is busy operating in
+ * Emulation mode. Stop all activities on the FPGA before requesting this
+ * operation.
+ */
+static const NiFpga_Status NiFpga_Status_FpgaBusyEmulation = -61204;
+
+/**
+ * LabVIEW FPGA does not support the Reset method for bitfiles that allow
+ * removal of implicit enable signals in single-cycle Timed Loops.
+ */
+static const NiFpga_Status NiFpga_Status_ResetCalledWithImplicitEnableRemoval =
+ -61211;
+
+/**
+ * LabVIEW FPGA does not support the Abort method for bitfiles that allow
+ * removal of implicit enable signals in single-cycle Timed Loops.
+ */
+static const NiFpga_Status NiFpga_Status_AbortCalledWithImplicitEnableRemoval =
+ -61212;
+
+/**
+ * LabVIEW FPGA does not support Close and Reset if Last Reference for bitfiles
+ * that allow removal of implicit enable signals in single-cycle Timed Loops.
+ * Pass the NiFpga_CloseAttribute_NoResetIfLastSession attribute to NiFpga_Close
+ * instead of 0.
+ */
+static const NiFpga_Status
+ NiFpga_Status_CloseAndResetCalledWithImplicitEnableRemoval = -61213;
+
+/**
+ * For bitfiles that allow removal of implicit enable signals in single-cycle
+ * Timed Loops, LabVIEW FPGA does not support this method prior to running the
+ * bitfile.
+ */
+static const NiFpga_Status NiFpga_Status_ImplicitEnableRemovalButNotYetRun =
+ -61214;
+
+/**
+ * Bitfiles that allow removal of implicit enable signals in single-cycle Timed
+ * Loops can run only once. Download the bitfile again before re-running the VI.
+ */
+static const NiFpga_Status
+ NiFpga_Status_RunAfterStoppedCalledWithImplicitEnableRemoval = -61215;
+
+/**
+ * A gated clock has violated the handshaking protocol. If you are using
+ * external gated clocks, ensure that they follow the required clock gating
+ * protocol. If you are generating your clocks internally, please contact
+ * National Instruments Technical Support.
+ */
+static const NiFpga_Status NiFpga_Status_GatedClockHandshakingViolation =
+ -61216;
+
+/**
+ * The number of elements requested must be less than or equal to the number of
+ * unacquired elements left in the host memory DMA FIFO. There are currently
+ * fewer unacquired elements left in the FIFO than are being requested. Release
+ * some acquired elements before acquiring more elements.
+ */
+static const NiFpga_Status NiFpga_Status_ElementsNotPermissibleToBeAcquired =
+ -61219;
+
+/**
+ * The operation could not be performed because the FPGA is in configuration or
+ * discovery mode. Wait for configuration or discovery to complete and retry
+ * your operation.
+ */
+static const NiFpga_Status NiFpga_Status_FpgaBusyConfiguration = -61252;
+
+/**
+ * An unexpected internal error occurred.
+ */
+static const NiFpga_Status NiFpga_Status_InternalError = -61499;
+
+/**
+ * The NI-RIO driver was unable to allocate memory for a FIFO. This can happen
+ * when the combined depth of all DMA FIFOs exceeds the maximum depth for the
+ * controller, or when the controller runs out of system memory. You may be able
+ * to reconfigure the controller with a greater maximum FIFO depth. For more
+ * information, refer to the NI KnowledgeBase article 65OF2ERQ.
+ */
+static const NiFpga_Status NiFpga_Status_TotalDmaFifoDepthExceeded = -63003;
+
+/**
+ * Access to the remote system was denied. Use MAX to check the Remote Device
+ * Access settings under Software>>NI-RIO>>NI-RIO Settings on the remote system.
+ */
+static const NiFpga_Status NiFpga_Status_AccessDenied = -63033;
+
+/**
+ * The NI-RIO software on the host is not compatible with the software on the
+ * target. Upgrade the NI-RIO software on the host in order to connect to this
+ * target.
+ */
+static const NiFpga_Status NiFpga_Status_HostVersionMismatch = -63038;
+
+/**
+ * A connection could not be established to the specified remote device. Ensure
+ * that the device is on and accessible over the network, that NI-RIO software
+ * is installed, and that the RIO server is running and properly configured.
+ */
+static const NiFpga_Status NiFpga_Status_RpcConnectionError = -63040;
+
+/**
+ * The RPC session is invalid. The target may have reset or been rebooted. Check
+ * the network connection and retry the operation.
+ */
+static const NiFpga_Status NiFpga_Status_RpcSessionError = -63043;
+
+/**
+ * The operation could not complete because another session is accessing the
+ * FIFO. Close the other session and retry.
+ */
+static const NiFpga_Status NiFpga_Status_FifoReserved = -63082;
+
+/**
+ * A Configure FIFO, Stop FIFO, Read FIFO, or Write FIFO function was called
+ * while the host had acquired elements of the FIFO. Release all acquired
+ * elements before configuring, stopping, reading, or writing.
+ */
+static const NiFpga_Status NiFpga_Status_FifoElementsCurrentlyAcquired = -63083;
+
+/**
+ * A function was called using a misaligned address. The address must be a
+ * multiple of the size of the datatype.
+ */
+static const NiFpga_Status NiFpga_Status_MisalignedAccess = -63084;
+
+/**
+ * The FPGA Read/Write Control Function is accessing a control or indicator
+ * with data that exceeds the maximum size supported on the current target.
+ * Refer to the hardware documentation for the limitations on data types for
+ * this target.
+ */
+static const NiFpga_Status NiFpga_Status_ControlOrIndicatorTooLarge = -63085;
+
+/**
+ * A valid .lvbitx bitfile is required. If you are using a valid .lvbitx
+ * bitfile, the bitfile may not be compatible with the software you are using.
+ * Determine which version of LabVIEW was used to make the bitfile, update your
+ * software to that version or later, and try again.
+ */
+static const NiFpga_Status NiFpga_Status_BitfileReadError = -63101;
+
+/**
+ * The specified signature does not match the signature of the bitfile. If the
+ * bitfile has been recompiled, regenerate the C API and rebuild the
+ * application.
+ */
+static const NiFpga_Status NiFpga_Status_SignatureMismatch = -63106;
+
+/**
+ * The bitfile you are trying to use is incompatible with the version
+ * of NI-RIO installed on the target and/or host. Update the version
+ * of NI-RIO on the target and/or host to the same version (or later)
+ * used to compile the bitfile. Alternatively, recompile the bitfile
+ * with the same version of NI-RIO that is currently installed on the
+ * target and/or host.
+ */
+static const NiFpga_Status NiFpga_Status_IncompatibleBitfile = -63107;
+
+/**
+ * Either the supplied resource name is invalid as a RIO resource name, or the
+ * device was not found. Use MAX to find the proper resource name for the
+ * intended device.
+ */
+static const NiFpga_Status NiFpga_Status_InvalidResourceName = -63192;
+
+/**
+ * The requested feature is not supported.
+ */
+static const NiFpga_Status NiFpga_Status_FeatureNotSupported = -63193;
+
+/**
+ * The NI-RIO software on the target system is not compatible with this
+ * software. Upgrade the NI-RIO software on the target system.
+ */
+static const NiFpga_Status NiFpga_Status_VersionMismatch = -63194;
+
+/**
+ * The session is invalid or has been closed.
+ */
+static const NiFpga_Status NiFpga_Status_InvalidSession = -63195;
+
+/**
+ * The maximum number of open FPGA sessions has been reached. Close some open
+ * sessions.
+ */
+static const NiFpga_Status NiFpga_Status_OutOfHandles = -63198;
diff --git a/hal/src/main/native/sim/Extensions.cpp b/hal/src/main/native/sim/Extensions.cpp
new file mode 100644
index 0000000..951ad10
--- /dev/null
+++ b/hal/src/main/native/sim/Extensions.cpp
@@ -0,0 +1,119 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/Extensions.h"
+
+#include <wpi/Path.h>
+#include <wpi/SmallString.h>
+#include <wpi/StringRef.h>
+#include <wpi/raw_ostream.h>
+
+#include "hal/HAL.h"
+
+#if defined(WIN32) || defined(_WIN32)
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif
+
+#if defined(WIN32) || defined(_WIN32)
+#define DELIM ';'
+#define HTYPE HMODULE
+#define DLOPEN(a) LoadLibrary(a)
+#define DLSYM GetProcAddress
+#define DLCLOSE FreeLibrary
+#else
+#define DELIM ':'
+#define HTYPE void*
+#define PREFIX "lib"
+#define DLOPEN(a) dlopen(a, RTLD_LAZY)
+#define DLSYM dlsym
+#define DLCLOSE dlclose
+#endif
+
+namespace hal {
+namespace init {
+void InitializeExtensions() {}
+} // namespace init
+} // namespace hal
+
+static bool& GetShowNotFoundMessage() {
+ static bool showMsg = true;
+ return showMsg;
+}
+
+extern "C" {
+
+int HAL_LoadOneExtension(const char* library) {
+ int rc = 1; // It is expected and reasonable not to find an extra simulation
+ wpi::outs() << "HAL Extensions: Attempting to load: "
+ << wpi::sys::path::stem(library) << "\n";
+ wpi::outs().flush();
+ HTYPE handle = DLOPEN(library);
+#if !defined(WIN32) && !defined(_WIN32)
+ if (!handle) {
+ wpi::SmallString<128> libraryName("lib");
+ libraryName += library;
+#if defined(__APPLE__)
+ libraryName += ".dylib";
+#else
+ libraryName += ".so";
+#endif
+ wpi::outs() << "HAL Extensions: Trying modified name: "
+ << wpi::sys::path::stem(libraryName);
+ wpi::outs().flush();
+ handle = DLOPEN(libraryName.c_str());
+ }
+#endif
+ if (!handle) {
+ wpi::outs() << "HAL Extensions: Failed to load library\n";
+ wpi::outs().flush();
+ return rc;
+ }
+
+ auto init = reinterpret_cast<halsim_extension_init_func_t*>(
+ DLSYM(handle, "HALSIM_InitExtension"));
+
+ if (init) rc = (*init)();
+
+ if (rc != 0) {
+ wpi::outs() << "HAL Extensions: Failed to load extension\n";
+ wpi::outs().flush();
+ DLCLOSE(handle);
+ } else {
+ wpi::outs() << "HAL Extensions: Successfully loaded extension\n";
+ wpi::outs().flush();
+ }
+ return rc;
+}
+
+int HAL_LoadExtensions(void) {
+ int rc = 1;
+ wpi::SmallVector<wpi::StringRef, 2> libraries;
+ const char* e = std::getenv("HALSIM_EXTENSIONS");
+ if (!e) {
+ if (GetShowNotFoundMessage()) {
+ wpi::outs() << "HAL Extensions: No extensions found\n";
+ wpi::outs().flush();
+ }
+ return rc;
+ }
+ wpi::StringRef env{e};
+ env.split(libraries, DELIM, -1, false);
+ for (auto& libref : libraries) {
+ wpi::SmallString<128> library(libref);
+ rc = HAL_LoadOneExtension(library.c_str());
+ if (rc < 0) break;
+ }
+ return rc;
+}
+
+void HAL_SetShowExtensionsNotFoundMessages(HAL_Bool showMessage) {
+ GetShowNotFoundMessage() = showMessage;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/HAL.cpp b/hal/src/main/native/sim/HAL.cpp
new file mode 100644
index 0000000..0dda617
--- /dev/null
+++ b/hal/src/main/native/sim/HAL.cpp
@@ -0,0 +1,291 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/HAL.h"
+
+#include <wpi/mutex.h>
+#include <wpi/raw_ostream.h>
+
+#include "ErrorsInternal.h"
+#include "HALInitializer.h"
+#include "MockHooksInternal.h"
+#include "hal/DriverStation.h"
+#include "hal/Errors.h"
+#include "hal/Extensions.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/RoboRioDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeHAL() {
+ InitializeAccelerometerData();
+ InitializeAddressableLEDData();
+ InitializeAnalogGyroData();
+ InitializeAnalogInData();
+ InitializeAnalogOutData();
+ InitializeAnalogTriggerData();
+ InitializeCanData();
+ InitializeCANAPI();
+ InitializeDigitalPWMData();
+ InitializeDutyCycleData();
+ InitializeDIOData();
+ InitializeDriverStationData();
+ InitializeEncoderData();
+ InitializeI2CData();
+ InitializePCMData();
+ InitializePDPData();
+ InitializePWMData();
+ InitializeRelayData();
+ InitializeRoboRioData();
+ InitializeSimDeviceData();
+ InitializeSPIAccelerometerData();
+ InitializeSPIData();
+ InitializeAccelerometer();
+ InitializeAddressableLED();
+ InitializeAnalogAccumulator();
+ InitializeAnalogGyro();
+ InitializeAnalogInput();
+ InitializeAnalogInternal();
+ InitializeAnalogOutput();
+ InitializeCAN();
+ InitializeCompressor();
+ InitializeConstants();
+ InitializeCounter();
+ InitializeDigitalInternal();
+ InitializeDIO();
+ InitializeDutyCycle();
+ InitializeDriverStation();
+ InitializeEncoder();
+ InitializeExtensions();
+ InitializeI2C();
+ InitializeInterrupts();
+ InitializeMain();
+ InitializeMockHooks();
+ InitializeNotifier();
+ InitializePDP();
+ InitializePorts();
+ InitializePower();
+ InitializePWM();
+ InitializeRelay();
+ InitializeSerialPort();
+ InitializeSimDevice();
+ InitializeSolenoid();
+ InitializeSPI();
+ InitializeThreads();
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+HAL_PortHandle HAL_GetPort(int32_t channel) {
+ // Dont allow a number that wouldn't fit in a uint8_t
+ if (channel < 0 || channel >= 255) return HAL_kInvalidHandle;
+ return createPortHandle(channel, 1);
+}
+
+HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel) {
+ // Dont allow a number that wouldn't fit in a uint8_t
+ if (channel < 0 || channel >= 255) return HAL_kInvalidHandle;
+ if (module < 0 || module >= 255) return HAL_kInvalidHandle;
+ return createPortHandle(channel, module);
+}
+
+const char* HAL_GetErrorMessage(int32_t code) {
+ switch (code) {
+ case 0:
+ return "";
+ case CTR_RxTimeout:
+ return CTR_RxTimeout_MESSAGE;
+ case CTR_TxTimeout:
+ return CTR_TxTimeout_MESSAGE;
+ case CTR_InvalidParamValue:
+ return CTR_InvalidParamValue_MESSAGE;
+ case CTR_UnexpectedArbId:
+ return CTR_UnexpectedArbId_MESSAGE;
+ case CTR_TxFailed:
+ return CTR_TxFailed_MESSAGE;
+ case CTR_SigNotUpdated:
+ return CTR_SigNotUpdated_MESSAGE;
+ case NiFpga_Status_FifoTimeout:
+ return NiFpga_Status_FifoTimeout_MESSAGE;
+ case NiFpga_Status_TransferAborted:
+ return NiFpga_Status_TransferAborted_MESSAGE;
+ case NiFpga_Status_MemoryFull:
+ return NiFpga_Status_MemoryFull_MESSAGE;
+ case NiFpga_Status_SoftwareFault:
+ return NiFpga_Status_SoftwareFault_MESSAGE;
+ case NiFpga_Status_InvalidParameter:
+ return NiFpga_Status_InvalidParameter_MESSAGE;
+ case NiFpga_Status_ResourceNotFound:
+ return NiFpga_Status_ResourceNotFound_MESSAGE;
+ case NiFpga_Status_ResourceNotInitialized:
+ return NiFpga_Status_ResourceNotInitialized_MESSAGE;
+ case NiFpga_Status_HardwareFault:
+ return NiFpga_Status_HardwareFault_MESSAGE;
+ case NiFpga_Status_IrqTimeout:
+ return NiFpga_Status_IrqTimeout_MESSAGE;
+ case SAMPLE_RATE_TOO_HIGH:
+ return SAMPLE_RATE_TOO_HIGH_MESSAGE;
+ case VOLTAGE_OUT_OF_RANGE:
+ return VOLTAGE_OUT_OF_RANGE_MESSAGE;
+ case LOOP_TIMING_ERROR:
+ return LOOP_TIMING_ERROR_MESSAGE;
+ case SPI_WRITE_NO_MOSI:
+ return SPI_WRITE_NO_MOSI_MESSAGE;
+ case SPI_READ_NO_MISO:
+ return SPI_READ_NO_MISO_MESSAGE;
+ case SPI_READ_NO_DATA:
+ return SPI_READ_NO_DATA_MESSAGE;
+ case INCOMPATIBLE_STATE:
+ return INCOMPATIBLE_STATE_MESSAGE;
+ case NO_AVAILABLE_RESOURCES:
+ return NO_AVAILABLE_RESOURCES_MESSAGE;
+ case RESOURCE_IS_ALLOCATED:
+ return RESOURCE_IS_ALLOCATED_MESSAGE;
+ case RESOURCE_OUT_OF_RANGE:
+ return RESOURCE_OUT_OF_RANGE_MESSAGE;
+ case HAL_INVALID_ACCUMULATOR_CHANNEL:
+ return HAL_INVALID_ACCUMULATOR_CHANNEL_MESSAGE;
+ case HAL_HANDLE_ERROR:
+ return HAL_HANDLE_ERROR_MESSAGE;
+ case NULL_PARAMETER:
+ return NULL_PARAMETER_MESSAGE;
+ case ANALOG_TRIGGER_LIMIT_ORDER_ERROR:
+ return ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE;
+ case ANALOG_TRIGGER_PULSE_OUTPUT_ERROR:
+ return ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE;
+ case PARAMETER_OUT_OF_RANGE:
+ return PARAMETER_OUT_OF_RANGE_MESSAGE;
+ case HAL_COUNTER_NOT_SUPPORTED:
+ return HAL_COUNTER_NOT_SUPPORTED_MESSAGE;
+ case HAL_ERR_CANSessionMux_InvalidBuffer:
+ return ERR_CANSessionMux_InvalidBuffer_MESSAGE;
+ case HAL_ERR_CANSessionMux_MessageNotFound:
+ return ERR_CANSessionMux_MessageNotFound_MESSAGE;
+ case HAL_WARN_CANSessionMux_NoToken:
+ return WARN_CANSessionMux_NoToken_MESSAGE;
+ case HAL_ERR_CANSessionMux_NotAllowed:
+ return ERR_CANSessionMux_NotAllowed_MESSAGE;
+ case HAL_ERR_CANSessionMux_NotInitialized:
+ return ERR_CANSessionMux_NotInitialized_MESSAGE;
+ case VI_ERROR_SYSTEM_ERROR:
+ return VI_ERROR_SYSTEM_ERROR_MESSAGE;
+ case VI_ERROR_INV_OBJECT:
+ return VI_ERROR_INV_OBJECT_MESSAGE;
+ case VI_ERROR_RSRC_LOCKED:
+ return VI_ERROR_RSRC_LOCKED_MESSAGE;
+ case VI_ERROR_RSRC_NFOUND:
+ return VI_ERROR_RSRC_NFOUND_MESSAGE;
+ case VI_ERROR_INV_RSRC_NAME:
+ return VI_ERROR_INV_RSRC_NAME_MESSAGE;
+ case VI_ERROR_QUEUE_OVERFLOW:
+ return VI_ERROR_QUEUE_OVERFLOW_MESSAGE;
+ case VI_ERROR_IO:
+ return VI_ERROR_IO_MESSAGE;
+ case VI_ERROR_ASRL_PARITY:
+ return VI_ERROR_ASRL_PARITY_MESSAGE;
+ case VI_ERROR_ASRL_FRAMING:
+ return VI_ERROR_ASRL_FRAMING_MESSAGE;
+ case VI_ERROR_ASRL_OVERRUN:
+ return VI_ERROR_ASRL_OVERRUN_MESSAGE;
+ case VI_ERROR_RSRC_BUSY:
+ return VI_ERROR_RSRC_BUSY_MESSAGE;
+ case VI_ERROR_INV_PARAMETER:
+ return VI_ERROR_INV_PARAMETER_MESSAGE;
+ case HAL_PWM_SCALE_ERROR:
+ return HAL_PWM_SCALE_ERROR_MESSAGE;
+ case HAL_CAN_TIMEOUT:
+ return HAL_CAN_TIMEOUT_MESSAGE;
+ case HAL_SIM_NOT_SUPPORTED:
+ return HAL_SIM_NOT_SUPPORTED_MESSAGE;
+ case HAL_CAN_BUFFER_OVERRUN:
+ return HAL_CAN_BUFFER_OVERRUN_MESSAGE;
+ case HAL_LED_CHANNEL_ERROR:
+ return HAL_LED_CHANNEL_ERROR_MESSAGE;
+ default:
+ return "Unknown error status";
+ }
+}
+
+HAL_RuntimeType HAL_GetRuntimeType(void) { return HAL_Mock; }
+
+int32_t HAL_GetFPGAVersion(int32_t* status) {
+ return 2018; // Automatically script this at some point
+}
+
+int64_t HAL_GetFPGARevision(int32_t* status) {
+ return 0; // TODO: Find a better number to return;
+}
+
+uint64_t HAL_GetFPGATime(int32_t* status) { return hal::GetFPGATime(); }
+
+uint64_t HAL_ExpandFPGATime(uint32_t unexpanded_lower, int32_t* status) {
+ // Capture the current FPGA time. This will give us the upper half of the
+ // clock.
+ uint64_t fpga_time = HAL_GetFPGATime(status);
+ if (*status != 0) return 0;
+
+ // Now, we need to detect the case where the lower bits rolled over after we
+ // sampled. In that case, the upper bits will be 1 bigger than they should
+ // be.
+
+ // Break it into lower and upper portions.
+ uint32_t lower = fpga_time & 0xffffffffull;
+ uint64_t upper = (fpga_time >> 32) & 0xffffffff;
+
+ // The time was sampled *before* the current time, so roll it back.
+ if (lower < unexpanded_lower) {
+ --upper;
+ }
+
+ return (upper << 32) + static_cast<uint64_t>(unexpanded_lower);
+}
+
+HAL_Bool HAL_GetFPGAButton(int32_t* status) {
+ return SimRoboRioData[0].fpgaButton;
+}
+
+HAL_Bool HAL_GetSystemActive(int32_t* status) {
+ return true; // Figure out if we need to handle this
+}
+
+HAL_Bool HAL_GetBrownedOut(int32_t* status) {
+ return false; // Figure out if we need to detect a brownout condition
+}
+
+HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
+ static std::atomic_bool initialized{false};
+ static wpi::mutex initializeMutex;
+ // Initial check, as if it's true initialization has finished
+ if (initialized) return true;
+
+ std::scoped_lock lock(initializeMutex);
+ // Second check in case another thread was waiting
+ if (initialized) return true;
+
+ hal::init::InitializeHAL();
+
+ hal::init::HAL_IsInitialized.store(true);
+
+ wpi::outs().SetUnbuffered();
+ if (HAL_LoadExtensions() < 0) return false;
+ hal::RestartTiming();
+ HAL_InitializeDriverStation();
+
+ initialized = true;
+ return true; // Add initialization if we need to at a later point
+}
+
+int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
+ const char* feature) {
+ return 0; // Do nothing for now
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/HALInitializer.cpp b/hal/src/main/native/sim/HALInitializer.cpp
new file mode 100644
index 0000000..a0456d4
--- /dev/null
+++ b/hal/src/main/native/sim/HALInitializer.cpp
@@ -0,0 +1,17 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 "HALInitializer.h"
+
+#include "hal/HAL.h"
+
+namespace hal {
+namespace init {
+std::atomic_bool HAL_IsInitialized{false};
+void RunInitialize() { HAL_Initialize(500, 0); }
+} // namespace init
+} // namespace hal
diff --git a/hal/src/main/native/sim/HALInitializer.h b/hal/src/main/native/sim/HALInitializer.h
new file mode 100644
index 0000000..c08df73
--- /dev/null
+++ b/hal/src/main/native/sim/HALInitializer.h
@@ -0,0 +1,78 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <atomic>
+
+namespace hal {
+namespace init {
+extern std::atomic_bool HAL_IsInitialized;
+extern void RunInitialize();
+static inline void CheckInit() {
+ if (HAL_IsInitialized.load(std::memory_order_relaxed)) return;
+ RunInitialize();
+}
+
+extern void InitializeAccelerometerData();
+extern void InitializeAddressableLEDData();
+extern void InitializeAnalogGyroData();
+extern void InitializeAnalogInData();
+extern void InitializeAnalogOutData();
+extern void InitializeAnalogTriggerData();
+extern void InitializeCanData();
+extern void InitializeCANAPI();
+extern void InitializeDigitalPWMData();
+extern void InitializeDutyCycleData();
+extern void InitializeDIOData();
+extern void InitializeDutyCycle();
+extern void InitializeDriverStationData();
+extern void InitializeEncoderData();
+extern void InitializeI2CData();
+extern void InitializePCMData();
+extern void InitializePDPData();
+extern void InitializePWMData();
+extern void InitializeRelayData();
+extern void InitializeRoboRioData();
+extern void InitializeSimDeviceData();
+extern void InitializeSPIAccelerometerData();
+extern void InitializeSPIData();
+extern void InitializeAccelerometer();
+extern void InitializeAddressableLED();
+extern void InitializeAnalogAccumulator();
+extern void InitializeAnalogGyro();
+extern void InitializeAnalogInput();
+extern void InitializeAnalogInternal();
+extern void InitializeAnalogOutput();
+extern void InitializeCAN();
+extern void InitializeCompressor();
+extern void InitializeConstants();
+extern void InitializeCounter();
+extern void InitializeDigitalInternal();
+extern void InitializeDIO();
+extern void InitializeDriverStation();
+extern void InitializeEncoder();
+extern void InitializeExtensions();
+extern void InitializeHAL();
+extern void InitializeI2C();
+extern void InitializeInterrupts();
+extern void InitializeMain();
+extern void InitializeMockHooks();
+extern void InitializeNotifier();
+extern void InitializePDP();
+extern void InitializePorts();
+extern void InitializePower();
+extern void InitializePWM();
+extern void InitializeRelay();
+extern void InitializeSerialPort();
+extern void InitializeSimDevice();
+extern void InitializeSolenoid();
+extern void InitializeSPI();
+extern void InitializeThreads();
+
+} // namespace init
+} // namespace hal
diff --git a/hal/src/main/native/sim/I2C.cpp b/hal/src/main/native/sim/I2C.cpp
new file mode 100644
index 0000000..fe4952f
--- /dev/null
+++ b/hal/src/main/native/sim/I2C.cpp
@@ -0,0 +1,44 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "hal/I2C.h"
+
+#include "HALInitializer.h"
+#include "mockdata/I2CDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeI2C() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
+ hal::init::CheckInit();
+ SimI2CData[port].initialized = true;
+}
+int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
+ const uint8_t* dataToSend, int32_t sendSize,
+ uint8_t* dataReceived, int32_t receiveSize) {
+ SimI2CData[port].Write(deviceAddress, dataToSend, sendSize);
+ SimI2CData[port].Read(deviceAddress, dataReceived, receiveSize);
+ return 0;
+}
+int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress,
+ const uint8_t* dataToSend, int32_t sendSize) {
+ SimI2CData[port].Write(deviceAddress, dataToSend, sendSize);
+ return 0;
+}
+int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer,
+ int32_t count) {
+ SimI2CData[port].Read(deviceAddress, buffer, count);
+ return 0;
+}
+void HAL_CloseI2C(HAL_I2CPort port) { SimI2CData[port].initialized = false; }
+} // extern "C"
diff --git a/hal/src/main/native/sim/Interrupts.cpp b/hal/src/main/native/sim/Interrupts.cpp
new file mode 100644
index 0000000..a7dd285
--- /dev/null
+++ b/hal/src/main/native/sim/Interrupts.cpp
@@ -0,0 +1,569 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/Interrupts.h"
+
+#include <memory>
+
+#include <wpi/condition_variable.h>
+
+#include "AnalogInternal.h"
+#include "DigitalInternal.h"
+#include "ErrorsInternal.h"
+#include "HALInitializer.h"
+#include "MockHooksInternal.h"
+#include "PortsInternal.h"
+#include "hal/AnalogTrigger.h"
+#include "hal/Errors.h"
+#include "hal/Value.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/LimitedHandleResource.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/AnalogInDataInternal.h"
+#include "mockdata/DIODataInternal.h"
+
+#ifdef _WIN32
+#pragma warning(disable : 4996 4018 6297 26451 4334)
+#endif
+
+using namespace hal;
+
+enum WaitResult {
+ Timeout = 0x0,
+ RisingEdge = 0x1,
+ FallingEdge = 0x100,
+ Both = 0x101,
+};
+
+namespace {
+struct Interrupt {
+ bool isAnalog;
+ HAL_Handle portHandle;
+ uint8_t index;
+ HAL_AnalogTriggerType trigType;
+ bool watcher;
+ int64_t risingTimestamp;
+ int64_t fallingTimestamp;
+ bool previousState;
+ bool fireOnUp;
+ bool fireOnDown;
+ int32_t callbackId;
+
+ void* callbackParam;
+ HAL_InterruptHandlerFunction callbackFunction;
+};
+
+struct SynchronousWaitData {
+ HAL_InterruptHandle interruptHandle{HAL_kInvalidHandle};
+ wpi::condition_variable waitCond;
+ HAL_Bool waitPredicate{false};
+};
+} // namespace
+
+static LimitedHandleResource<HAL_InterruptHandle, Interrupt, kNumInterrupts,
+ HAL_HandleEnum::Interrupt>* interruptHandles;
+
+typedef HAL_Handle SynchronousWaitDataHandle;
+static UnlimitedHandleResource<SynchronousWaitDataHandle, SynchronousWaitData,
+ HAL_HandleEnum::Vendor>*
+ synchronousInterruptHandles;
+
+namespace hal {
+namespace init {
+void InitializeInterrupts() {
+ static LimitedHandleResource<HAL_InterruptHandle, Interrupt, kNumInterrupts,
+ HAL_HandleEnum::Interrupt>
+ iH;
+ interruptHandles = &iH;
+ static UnlimitedHandleResource<SynchronousWaitDataHandle, SynchronousWaitData,
+ HAL_HandleEnum::Vendor>
+ siH;
+ synchronousInterruptHandles = &siH;
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_InterruptHandle HAL_InitializeInterrupts(HAL_Bool watcher,
+ int32_t* status) {
+ hal::init::CheckInit();
+ HAL_InterruptHandle handle = interruptHandles->Allocate();
+ if (handle == HAL_kInvalidHandle) {
+ *status = NO_AVAILABLE_RESOURCES;
+ return HAL_kInvalidHandle;
+ }
+ auto anInterrupt = interruptHandles->Get(handle);
+ if (anInterrupt == nullptr) { // would only occur on thread issue.
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+
+ anInterrupt->index = getHandleIndex(handle);
+ anInterrupt->callbackId = -1;
+
+ anInterrupt->watcher = watcher;
+
+ return handle;
+}
+void* HAL_CleanInterrupts(HAL_InterruptHandle interruptHandle,
+ int32_t* status) {
+ HAL_DisableInterrupts(interruptHandle, status);
+ auto anInterrupt = interruptHandles->Get(interruptHandle);
+ interruptHandles->Free(interruptHandle);
+ if (anInterrupt == nullptr) {
+ return nullptr;
+ }
+ return anInterrupt->callbackParam;
+}
+
+static void ProcessInterruptDigitalSynchronous(const char* name, void* param,
+ const struct HAL_Value* value) {
+ // void* is a SynchronousWaitDataHandle.
+ // convert to uintptr_t first, then to handle
+ uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
+ SynchronousWaitDataHandle handle =
+ static_cast<SynchronousWaitDataHandle>(handleTmp);
+ auto interruptData = synchronousInterruptHandles->Get(handle);
+ if (interruptData == nullptr) return;
+ auto interrupt = interruptHandles->Get(interruptData->interruptHandle);
+ if (interrupt == nullptr) return;
+ // Have a valid interrupt
+ if (value->type != HAL_Type::HAL_BOOLEAN) return;
+ bool retVal = value->data.v_boolean;
+ // If no change in interrupt, return;
+ if (retVal == interrupt->previousState) return;
+ // If its a falling change, and we dont fire on falling return
+ if (interrupt->previousState && !interrupt->fireOnDown) return;
+ // If its a rising change, and we dont fire on rising return.
+ if (!interrupt->previousState && !interrupt->fireOnUp) return;
+
+ interruptData->waitPredicate = true;
+
+ // Pulse interrupt
+ interruptData->waitCond.notify_all();
+}
+
+static double GetAnalogTriggerValue(HAL_Handle triggerHandle,
+ HAL_AnalogTriggerType type,
+ int32_t* status) {
+ return HAL_GetAnalogTriggerOutput(triggerHandle, type, status);
+}
+
+static void ProcessInterruptAnalogSynchronous(const char* name, void* param,
+ const struct HAL_Value* value) {
+ // void* is a SynchronousWaitDataHandle.
+ // convert to uintptr_t first, then to handle
+ uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
+ SynchronousWaitDataHandle handle =
+ static_cast<SynchronousWaitDataHandle>(handleTmp);
+ auto interruptData = synchronousInterruptHandles->Get(handle);
+ if (interruptData == nullptr) return;
+ auto interrupt = interruptHandles->Get(interruptData->interruptHandle);
+ if (interrupt == nullptr) return;
+ // Have a valid interrupt
+ if (value->type != HAL_Type::HAL_DOUBLE) return;
+ int32_t status = 0;
+ bool retVal = GetAnalogTriggerValue(interrupt->portHandle,
+ interrupt->trigType, &status);
+ if (status != 0) {
+ // Interrupt and Cancel
+ interruptData->waitPredicate = true;
+ // Pulse interrupt
+ interruptData->waitCond.notify_all();
+ }
+ // If no change in interrupt, return;
+ if (retVal == interrupt->previousState) return;
+ // If its a falling change, and we dont fire on falling return
+ if (interrupt->previousState && !interrupt->fireOnDown) return;
+ // If its a rising change, and we dont fire on rising return.
+ if (!interrupt->previousState && !interrupt->fireOnUp) return;
+
+ interruptData->waitPredicate = true;
+
+ // Pulse interrupt
+ interruptData->waitCond.notify_all();
+}
+
+static int64_t WaitForInterruptDigital(HAL_InterruptHandle handle,
+ Interrupt* interrupt, double timeout,
+ bool ignorePrevious) {
+ auto data = std::make_shared<SynchronousWaitData>();
+
+ auto dataHandle = synchronousInterruptHandles->Allocate(data);
+ if (dataHandle == HAL_kInvalidHandle) {
+ // Error allocating data
+ return WaitResult::Timeout;
+ }
+
+ // auto data = synchronousInterruptHandles->Get(dataHandle);
+ data->waitPredicate = false;
+ data->interruptHandle = handle;
+
+ int32_t status = 0;
+
+ int32_t digitalIndex = GetDigitalInputChannel(interrupt->portHandle, &status);
+
+ if (status != 0) return WaitResult::Timeout;
+
+ interrupt->previousState = SimDIOData[digitalIndex].value;
+
+ int32_t uid = SimDIOData[digitalIndex].value.RegisterCallback(
+ &ProcessInterruptDigitalSynchronous,
+ reinterpret_cast<void*>(static_cast<uintptr_t>(dataHandle)), false);
+
+ bool timedOut = false;
+
+ wpi::mutex waitMutex;
+
+ auto timeoutTime =
+ std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
+
+ {
+ std::unique_lock lock(waitMutex);
+ while (!data->waitPredicate) {
+ if (data->waitCond.wait_until(lock, timeoutTime) ==
+ std::cv_status::timeout) {
+ timedOut = true;
+ break;
+ }
+ }
+ }
+
+ // Cancel our callback
+ SimDIOData[digitalIndex].value.CancelCallback(uid);
+ (void)synchronousInterruptHandles->Free(dataHandle);
+
+ // Check for what to return
+ if (timedOut) return WaitResult::Timeout;
+ // True => false, Falling
+ if (interrupt->previousState) {
+ // Set our return value and our timestamps
+ interrupt->fallingTimestamp = hal::GetFPGATime();
+ return 1 << (8 + interrupt->index);
+ } else {
+ interrupt->risingTimestamp = hal::GetFPGATime();
+ return 1 << (interrupt->index);
+ }
+}
+
+static int64_t WaitForInterruptAnalog(HAL_InterruptHandle handle,
+ Interrupt* interrupt, double timeout,
+ bool ignorePrevious) {
+ auto data = std::make_shared<SynchronousWaitData>();
+
+ auto dataHandle = synchronousInterruptHandles->Allocate(data);
+ if (dataHandle == HAL_kInvalidHandle) {
+ // Error allocating data
+ return WaitResult::Timeout;
+ }
+
+ data->waitPredicate = false;
+ data->interruptHandle = handle;
+
+ int32_t status = 0;
+ interrupt->previousState = GetAnalogTriggerValue(
+ interrupt->portHandle, interrupt->trigType, &status);
+
+ if (status != 0) return WaitResult::Timeout;
+
+ int32_t analogIndex =
+ GetAnalogTriggerInputIndex(interrupt->portHandle, &status);
+
+ if (status != 0) return WaitResult::Timeout;
+
+ int32_t uid = SimAnalogInData[analogIndex].voltage.RegisterCallback(
+ &ProcessInterruptAnalogSynchronous,
+ reinterpret_cast<void*>(static_cast<uintptr_t>(dataHandle)), false);
+
+ bool timedOut = false;
+
+ wpi::mutex waitMutex;
+
+ auto timeoutTime =
+ std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
+
+ {
+ std::unique_lock lock(waitMutex);
+ while (!data->waitPredicate) {
+ if (data->waitCond.wait_until(lock, timeoutTime) ==
+ std::cv_status::timeout) {
+ timedOut = true;
+ break;
+ }
+ }
+ }
+
+ // Cancel our callback
+ SimAnalogInData[analogIndex].voltage.CancelCallback(uid);
+ (void)synchronousInterruptHandles->Free(dataHandle);
+
+ // Check for what to return
+ if (timedOut) return WaitResult::Timeout;
+ // True => false, Falling
+ if (interrupt->previousState) {
+ // Set our return value and our timestamps
+ interrupt->fallingTimestamp = hal::GetFPGATime();
+ return 1 << (8 + interrupt->index);
+ } else {
+ interrupt->risingTimestamp = hal::GetFPGATime();
+ return 1 << (interrupt->index);
+ }
+}
+
+int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
+ double timeout, HAL_Bool ignorePrevious,
+ int32_t* status) {
+ auto interrupt = interruptHandles->Get(interruptHandle);
+ if (interrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return WaitResult::Timeout;
+ }
+
+ // Check to make sure we are actually an interrupt in synchronous mode
+ if (!interrupt->watcher) {
+ *status = NiFpga_Status_InvalidParameter;
+ return WaitResult::Timeout;
+ }
+
+ if (interrupt->isAnalog) {
+ return WaitForInterruptAnalog(interruptHandle, interrupt.get(), timeout,
+ ignorePrevious);
+ } else {
+ return WaitForInterruptDigital(interruptHandle, interrupt.get(), timeout,
+ ignorePrevious);
+ }
+}
+
+static void ProcessInterruptDigitalAsynchronous(const char* name, void* param,
+ const struct HAL_Value* value) {
+ // void* is a HAL handle
+ // convert to uintptr_t first, then to handle
+ uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
+ HAL_InterruptHandle handle = static_cast<HAL_InterruptHandle>(handleTmp);
+ auto interrupt = interruptHandles->Get(handle);
+ if (interrupt == nullptr) return;
+ // Have a valid interrupt
+ if (value->type != HAL_Type::HAL_BOOLEAN) return;
+ bool retVal = value->data.v_boolean;
+ // If no change in interrupt, return;
+ if (retVal == interrupt->previousState) return;
+ int32_t mask = 0;
+ if (interrupt->previousState) {
+ interrupt->previousState = retVal;
+ interrupt->fallingTimestamp = hal::GetFPGATime();
+ mask = 1 << (8 + interrupt->index);
+ if (!interrupt->fireOnDown) return;
+ } else {
+ interrupt->previousState = retVal;
+ interrupt->risingTimestamp = hal::GetFPGATime();
+ mask = 1 << (interrupt->index);
+ if (!interrupt->fireOnUp) return;
+ }
+
+ // run callback
+ auto callback = interrupt->callbackFunction;
+ if (callback == nullptr) return;
+ callback(mask, interrupt->callbackParam);
+}
+
+static void ProcessInterruptAnalogAsynchronous(const char* name, void* param,
+ const struct HAL_Value* value) {
+ // void* is a HAL handle
+ // convert to intptr_t first, then to handle
+ uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
+ HAL_InterruptHandle handle = static_cast<HAL_InterruptHandle>(handleTmp);
+ auto interrupt = interruptHandles->Get(handle);
+ if (interrupt == nullptr) return;
+ // Have a valid interrupt
+ if (value->type != HAL_Type::HAL_DOUBLE) return;
+ int32_t status = 0;
+ bool retVal = GetAnalogTriggerValue(interrupt->portHandle,
+ interrupt->trigType, &status);
+ if (status != 0) return;
+ // If no change in interrupt, return;
+ if (retVal == interrupt->previousState) return;
+ int mask = 0;
+ if (interrupt->previousState) {
+ interrupt->previousState = retVal;
+ interrupt->fallingTimestamp = hal::GetFPGATime();
+ if (!interrupt->fireOnDown) return;
+ mask = 1 << (8 + interrupt->index);
+ } else {
+ interrupt->previousState = retVal;
+ interrupt->risingTimestamp = hal::GetFPGATime();
+ if (!interrupt->fireOnUp) return;
+ mask = 1 << (interrupt->index);
+ }
+
+ // run callback
+ auto callback = interrupt->callbackFunction;
+ if (callback == nullptr) return;
+ callback(mask, interrupt->callbackParam);
+}
+
+static void EnableInterruptsDigital(HAL_InterruptHandle handle,
+ Interrupt* interrupt) {
+ int32_t status = 0;
+ int32_t digitalIndex = GetDigitalInputChannel(interrupt->portHandle, &status);
+ if (status != 0) return;
+
+ interrupt->previousState = SimDIOData[digitalIndex].value;
+
+ int32_t uid = SimDIOData[digitalIndex].value.RegisterCallback(
+ &ProcessInterruptDigitalAsynchronous,
+ reinterpret_cast<void*>(static_cast<uintptr_t>(handle)), false);
+ interrupt->callbackId = uid;
+}
+
+static void EnableInterruptsAnalog(HAL_InterruptHandle handle,
+ Interrupt* interrupt) {
+ int32_t status = 0;
+ int32_t analogIndex =
+ GetAnalogTriggerInputIndex(interrupt->portHandle, &status);
+ if (status != 0) return;
+
+ status = 0;
+ interrupt->previousState = GetAnalogTriggerValue(
+ interrupt->portHandle, interrupt->trigType, &status);
+ if (status != 0) return;
+
+ int32_t uid = SimAnalogInData[analogIndex].voltage.RegisterCallback(
+ &ProcessInterruptAnalogAsynchronous,
+ reinterpret_cast<void*>(static_cast<uintptr_t>(handle)), false);
+ interrupt->callbackId = uid;
+}
+
+void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle,
+ int32_t* status) {
+ auto interrupt = interruptHandles->Get(interruptHandle);
+ if (interrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ // If we have not had a callback set, error out
+ if (interrupt->callbackFunction == nullptr) {
+ *status = INCOMPATIBLE_STATE;
+ return;
+ }
+
+ // EnableInterrupts has already been called
+ if (interrupt->callbackId >= 0) {
+ // We can double enable safely.
+ return;
+ }
+
+ if (interrupt->isAnalog) {
+ EnableInterruptsAnalog(interruptHandle, interrupt.get());
+ } else {
+ EnableInterruptsDigital(interruptHandle, interrupt.get());
+ }
+}
+void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
+ int32_t* status) {
+ auto interrupt = interruptHandles->Get(interruptHandle);
+ if (interrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ // No need to disable if we are already disabled
+ if (interrupt->callbackId < 0) return;
+
+ if (interrupt->isAnalog) {
+ // Do analog
+ int32_t status = 0;
+ int32_t analogIndex =
+ GetAnalogTriggerInputIndex(interrupt->portHandle, &status);
+ if (status != 0) return;
+ SimAnalogInData[analogIndex].voltage.CancelCallback(interrupt->callbackId);
+ } else {
+ int32_t status = 0;
+ int32_t digitalIndex =
+ GetDigitalInputChannel(interrupt->portHandle, &status);
+ if (status != 0) return;
+ SimDIOData[digitalIndex].value.CancelCallback(interrupt->callbackId);
+ }
+ interrupt->callbackId = -1;
+}
+int64_t HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
+ int32_t* status) {
+ auto interrupt = interruptHandles->Get(interruptHandle);
+ if (interrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return interrupt->risingTimestamp;
+}
+int64_t HAL_ReadInterruptFallingTimestamp(HAL_InterruptHandle interruptHandle,
+ int32_t* status) {
+ auto interrupt = interruptHandles->Get(interruptHandle);
+ if (interrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return interrupt->fallingTimestamp;
+}
+void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ int32_t* status) {
+ auto interrupt = interruptHandles->Get(interruptHandle);
+ if (interrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ bool routingAnalogTrigger = false;
+ uint8_t routingChannel = 0;
+ uint8_t routingModule = 0;
+ bool success =
+ remapDigitalSource(digitalSourceHandle, analogTriggerType, routingChannel,
+ routingModule, routingAnalogTrigger);
+ if (!success) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ interrupt->isAnalog = routingAnalogTrigger;
+ interrupt->trigType = analogTriggerType;
+ interrupt->portHandle = digitalSourceHandle;
+}
+void HAL_AttachInterruptHandler(HAL_InterruptHandle interruptHandle,
+ HAL_InterruptHandlerFunction handler,
+ void* param, int32_t* status) {
+ auto interrupt = interruptHandles->Get(interruptHandle);
+ if (interrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ interrupt->callbackFunction = handler;
+ interrupt->callbackParam = param;
+}
+
+void HAL_AttachInterruptHandlerThreaded(HAL_InterruptHandle interruptHandle,
+ HAL_InterruptHandlerFunction handler,
+ void* param, int32_t* status) {
+ HAL_AttachInterruptHandler(interruptHandle, handler, param, status);
+}
+
+void HAL_SetInterruptUpSourceEdge(HAL_InterruptHandle interruptHandle,
+ HAL_Bool risingEdge, HAL_Bool fallingEdge,
+ int32_t* status) {
+ auto interrupt = interruptHandles->Get(interruptHandle);
+ if (interrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ interrupt->fireOnDown = fallingEdge;
+ interrupt->fireOnUp = risingEdge;
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/MockHooks.cpp b/hal/src/main/native/sim/MockHooks.cpp
new file mode 100644
index 0000000..59086ae
--- /dev/null
+++ b/hal/src/main/native/sim/MockHooks.cpp
@@ -0,0 +1,98 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include <atomic>
+#include <chrono>
+#include <cstdio>
+#include <thread>
+
+#include <wpi/timestamp.h>
+
+#include "MockHooksInternal.h"
+#include "NotifierInternal.h"
+
+static std::atomic<bool> programStarted{false};
+
+static std::atomic<uint64_t> programStartTime{0};
+static std::atomic<uint64_t> programPauseTime{0};
+
+namespace hal {
+namespace init {
+void InitializeMockHooks() {}
+} // namespace init
+} // namespace hal
+
+namespace hal {
+void RestartTiming() {
+ programStartTime = wpi::Now();
+ if (programPauseTime != 0) programPauseTime = programStartTime.load();
+}
+
+void PauseTiming() {
+ if (programPauseTime == 0) programPauseTime = wpi::Now();
+}
+
+void ResumeTiming() {
+ if (programPauseTime != 0) {
+ programStartTime += wpi::Now() - programPauseTime;
+ programPauseTime = 0;
+ }
+}
+
+bool IsTimingPaused() { return programPauseTime != 0; }
+
+void StepTiming(uint64_t delta) {
+ if (programPauseTime != 0) programPauseTime += delta;
+}
+
+int64_t GetFPGATime() {
+ uint64_t curTime = programPauseTime;
+ if (curTime == 0) curTime = wpi::Now();
+ return curTime - programStartTime;
+}
+
+double GetFPGATimestamp() { return GetFPGATime() * 1.0e-6; }
+
+void SetProgramStarted() { programStarted = true; }
+bool GetProgramStarted() { return programStarted; }
+} // namespace hal
+
+using namespace hal;
+
+extern "C" {
+void HALSIM_WaitForProgramStart(void) {
+ int count = 0;
+ while (!programStarted) {
+ count++;
+ std::printf("Waiting for program start signal: %d\n", count);
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ }
+}
+
+void HALSIM_SetProgramStarted(void) { SetProgramStarted(); }
+
+HAL_Bool HALSIM_GetProgramStarted(void) { return GetProgramStarted(); }
+
+void HALSIM_RestartTiming(void) { RestartTiming(); }
+
+void HALSIM_PauseTiming(void) {
+ PauseTiming();
+ PauseNotifiers();
+}
+
+void HALSIM_ResumeTiming(void) {
+ ResumeTiming();
+ ResumeNotifiers();
+}
+
+HAL_Bool HALSIM_IsTimingPaused(void) { return IsTimingPaused(); }
+
+void HALSIM_StepTiming(uint64_t delta) {
+ StepTiming(delta);
+ WakeupNotifiers();
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/MockHooksInternal.h b/hal/src/main/native/sim/MockHooksInternal.h
new file mode 100644
index 0000000..a69e9bf
--- /dev/null
+++ b/hal/src/main/native/sim/MockHooksInternal.h
@@ -0,0 +1,30 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <stdint.h>
+
+#include "mockdata/MockHooks.h"
+
+namespace hal {
+void RestartTiming();
+
+void PauseTiming();
+
+void ResumeTiming();
+
+bool IsTimingPaused();
+
+void StepTiming(uint64_t delta);
+
+int64_t GetFPGATime();
+
+double GetFPGATimestamp();
+
+void SetProgramStarted();
+} // namespace hal
diff --git a/hal/src/main/native/sim/Notifier.cpp b/hal/src/main/native/sim/Notifier.cpp
new file mode 100644
index 0000000..211f7b2
--- /dev/null
+++ b/hal/src/main/native/sim/Notifier.cpp
@@ -0,0 +1,223 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/Notifier.h"
+
+#include <atomic>
+#include <chrono>
+#include <cstdio>
+#include <cstring>
+#include <string>
+
+#include <wpi/condition_variable.h>
+#include <wpi/mutex.h>
+#include <wpi/timestamp.h>
+
+#include "HALInitializer.h"
+#include "NotifierInternal.h"
+#include "hal/HAL.h"
+#include "hal/cpp/fpga_clock.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/NotifierData.h"
+
+namespace {
+struct Notifier {
+ std::string name;
+ uint64_t waitTime;
+ bool active = true;
+ bool running = false;
+ wpi::mutex mutex;
+ wpi::condition_variable cond;
+};
+} // namespace
+
+using namespace hal;
+
+class NotifierHandleContainer
+ : public UnlimitedHandleResource<HAL_NotifierHandle, Notifier,
+ HAL_HandleEnum::Notifier> {
+ public:
+ ~NotifierHandleContainer() {
+ ForEach([](HAL_NotifierHandle handle, Notifier* notifier) {
+ {
+ std::scoped_lock lock(notifier->mutex);
+ notifier->active = false;
+ notifier->running = false;
+ }
+ notifier->cond.notify_all(); // wake up any waiting threads
+ });
+ }
+};
+
+static NotifierHandleContainer* notifierHandles;
+static std::atomic<bool> notifiersPaused{false};
+
+namespace hal {
+namespace init {
+void InitializeNotifier() {
+ static NotifierHandleContainer nH;
+ notifierHandles = &nH;
+}
+} // namespace init
+
+void PauseNotifiers() { notifiersPaused = true; }
+
+void ResumeNotifiers() {
+ notifiersPaused = false;
+ WakeupNotifiers();
+}
+
+void WakeupNotifiers() {
+ notifierHandles->ForEach([](HAL_NotifierHandle handle, Notifier* notifier) {
+ notifier->cond.notify_all();
+ });
+}
+} // namespace hal
+
+extern "C" {
+
+HAL_NotifierHandle HAL_InitializeNotifier(int32_t* status) {
+ hal::init::CheckInit();
+ std::shared_ptr<Notifier> notifier = std::make_shared<Notifier>();
+ HAL_NotifierHandle handle = notifierHandles->Allocate(notifier);
+ if (handle == HAL_kInvalidHandle) {
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+ return handle;
+}
+
+void HAL_SetNotifierName(HAL_NotifierHandle notifierHandle, const char* name,
+ int32_t* status) {
+ auto notifier = notifierHandles->Get(notifierHandle);
+ if (!notifier) return;
+ std::scoped_lock lock(notifier->mutex);
+ notifier->name = name;
+}
+
+void HAL_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) {
+ auto notifier = notifierHandles->Get(notifierHandle);
+ if (!notifier) return;
+
+ {
+ std::scoped_lock lock(notifier->mutex);
+ notifier->active = false;
+ notifier->running = false;
+ }
+ notifier->cond.notify_all();
+}
+
+void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) {
+ auto notifier = notifierHandles->Free(notifierHandle);
+ if (!notifier) return;
+
+ // Just in case HAL_StopNotifier() wasn't called...
+ {
+ std::scoped_lock lock(notifier->mutex);
+ notifier->active = false;
+ notifier->running = false;
+ }
+ notifier->cond.notify_all();
+}
+
+void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
+ uint64_t triggerTime, int32_t* status) {
+ auto notifier = notifierHandles->Get(notifierHandle);
+ if (!notifier) return;
+
+ {
+ std::scoped_lock lock(notifier->mutex);
+ notifier->waitTime = triggerTime;
+ notifier->running = true;
+ }
+
+ // We wake up any waiters to change how long they're sleeping for
+ notifier->cond.notify_all();
+}
+
+void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
+ int32_t* status) {
+ auto notifier = notifierHandles->Get(notifierHandle);
+ if (!notifier) return;
+
+ {
+ std::scoped_lock lock(notifier->mutex);
+ notifier->running = false;
+ }
+}
+
+uint64_t HAL_WaitForNotifierAlarm(HAL_NotifierHandle notifierHandle,
+ int32_t* status) {
+ auto notifier = notifierHandles->Get(notifierHandle);
+ if (!notifier) return 0;
+
+ std::unique_lock lock(notifier->mutex);
+ while (notifier->active) {
+ double waitTime;
+ if (!notifier->running || notifiersPaused) {
+ waitTime = (HAL_GetFPGATime(status) * 1e-6) + 1000.0;
+ // If not running, wait 1000 seconds
+ } else {
+ waitTime = notifier->waitTime * 1e-6;
+ }
+
+ auto timeoutTime =
+ hal::fpga_clock::epoch() + std::chrono::duration<double>(waitTime);
+ notifier->cond.wait_until(lock, timeoutTime);
+ if (!notifier->running) continue;
+ if (!notifier->active) break;
+ uint64_t curTime = HAL_GetFPGATime(status);
+ if (curTime < notifier->waitTime) continue;
+ notifier->running = false;
+ return curTime;
+ }
+ return 0;
+}
+
+uint64_t HALSIM_GetNextNotifierTimeout(void) {
+ uint64_t timeout = UINT64_MAX;
+ notifierHandles->ForEach([&](HAL_NotifierHandle, Notifier* notifier) {
+ std::scoped_lock lock(notifier->mutex);
+ if (notifier->active && notifier->running && timeout > notifier->waitTime)
+ timeout = notifier->waitTime;
+ });
+ return timeout;
+}
+
+int32_t HALSIM_GetNumNotifiers(void) {
+ int32_t count = 0;
+ notifierHandles->ForEach([&](HAL_NotifierHandle, Notifier* notifier) {
+ std::scoped_lock lock(notifier->mutex);
+ if (notifier->active) ++count;
+ });
+ return count;
+}
+
+int32_t HALSIM_GetNotifierInfo(struct HALSIM_NotifierInfo* arr, int32_t size) {
+ int32_t num = 0;
+ notifierHandles->ForEach([&](HAL_NotifierHandle handle, Notifier* notifier) {
+ std::scoped_lock lock(notifier->mutex);
+ if (!notifier->active) return;
+ if (num < size) {
+ arr[num].handle = handle;
+ if (notifier->name.empty()) {
+ std::snprintf(arr[num].name, sizeof(arr[num].name), "Notifier%d",
+ static_cast<int>(getHandleIndex(handle)));
+ } else {
+ std::strncpy(arr[num].name, notifier->name.c_str(),
+ sizeof(arr[num].name));
+ arr[num].name[sizeof(arr[num].name) - 1] = '\0';
+ }
+ arr[num].timeout = notifier->waitTime;
+ arr[num].running = notifier->running;
+ }
+ ++num;
+ });
+ return num;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/NotifierInternal.h b/hal/src/main/native/sim/NotifierInternal.h
new file mode 100644
index 0000000..84232d2
--- /dev/null
+++ b/hal/src/main/native/sim/NotifierInternal.h
@@ -0,0 +1,14 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+namespace hal {
+void PauseNotifiers();
+void ResumeNotifiers();
+void WakeupNotifiers();
+} // namespace hal
diff --git a/hal/src/main/native/sim/PDP.cpp b/hal/src/main/native/sim/PDP.cpp
new file mode 100644
index 0000000..dbe09d4
--- /dev/null
+++ b/hal/src/main/native/sim/PDP.cpp
@@ -0,0 +1,104 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/PDP.h"
+
+#include "CANAPIInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/CANAPI.h"
+#include "hal/handles/IndexedHandleResource.h"
+#include "mockdata/PDPDataInternal.h"
+
+using namespace hal;
+
+static constexpr HAL_CANManufacturer manufacturer =
+ HAL_CANManufacturer::HAL_CAN_Man_kCTRE;
+
+static constexpr HAL_CANDeviceType deviceType =
+ HAL_CANDeviceType::HAL_CAN_Dev_kPowerDistribution;
+
+namespace hal {
+namespace init {
+void InitializePDP() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_PDPHandle HAL_InitializePDP(int32_t module, int32_t* status) {
+ if (!HAL_CheckPDPModule(module)) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+ hal::init::CheckInit();
+ SimPDPData[module].initialized = true;
+ auto handle = HAL_InitializeCAN(manufacturer, module, deviceType, status);
+
+ if (*status != 0) {
+ HAL_CleanCAN(handle);
+ return HAL_kInvalidHandle;
+ }
+
+ return handle;
+}
+
+HAL_Bool HAL_CheckPDPModule(int32_t module) {
+ return module < kNumPDPModules && module >= 0;
+}
+
+HAL_Bool HAL_CheckPDPChannel(int32_t channel) {
+ return channel < kNumPDPChannels && channel >= 0;
+}
+
+void HAL_CleanPDP(HAL_PDPHandle handle) { HAL_CleanCAN(handle); }
+
+double HAL_GetPDPTemperature(HAL_PDPHandle handle, int32_t* status) {
+ auto module = hal::can::GetCANModuleFromHandle(handle, status);
+ if (*status != 0) {
+ return 0.0;
+ }
+ return SimPDPData[module].temperature;
+}
+double HAL_GetPDPVoltage(HAL_PDPHandle handle, int32_t* status) {
+ auto module = hal::can::GetCANModuleFromHandle(handle, status);
+ if (*status != 0) {
+ return 0.0;
+ }
+ return SimPDPData[module].voltage;
+}
+double HAL_GetPDPChannelCurrent(HAL_PDPHandle handle, int32_t channel,
+ int32_t* status) {
+ auto module = hal::can::GetCANModuleFromHandle(handle, status);
+ if (*status != 0) {
+ return 0.0;
+ }
+ return SimPDPData[module].current[channel];
+}
+void HAL_GetPDPAllChannelCurrents(HAL_PDPHandle handle, double* currents,
+ int32_t* status) {
+ auto module = hal::can::GetCANModuleFromHandle(handle, status);
+ if (*status != 0) {
+ return;
+ }
+
+ auto& data = SimPDPData[module];
+ for (int i = 0; i < kNumPDPChannels; i++) {
+ currents[i] = data.current[i];
+ }
+}
+double HAL_GetPDPTotalCurrent(HAL_PDPHandle handle, int32_t* status) {
+ return 0.0;
+}
+double HAL_GetPDPTotalPower(HAL_PDPHandle handle, int32_t* status) {
+ return 0.0;
+}
+double HAL_GetPDPTotalEnergy(HAL_PDPHandle handle, int32_t* status) {
+ return 0.0;
+}
+void HAL_ResetPDPTotalEnergy(HAL_PDPHandle handle, int32_t* status) {}
+void HAL_ClearPDPStickyFaults(HAL_PDPHandle handle, int32_t* status) {}
+} // extern "C"
diff --git a/hal/src/main/native/sim/PWM.cpp b/hal/src/main/native/sim/PWM.cpp
new file mode 100644
index 0000000..228b540
--- /dev/null
+++ b/hal/src/main/native/sim/PWM.cpp
@@ -0,0 +1,302 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 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 "hal/PWM.h"
+
+#include "ConstantsInternal.h"
+#include "DigitalInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/PWMDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializePWM() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+HAL_DigitalHandle HAL_InitializePWMPort(HAL_PortHandle portHandle,
+ int32_t* status) {
+ hal::init::CheckInit();
+ if (*status != 0) return HAL_kInvalidHandle;
+
+ int16_t channel = getPortHandleChannel(portHandle);
+ if (channel == InvalidHandleIndex) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+
+ uint8_t origChannel = static_cast<uint8_t>(channel);
+
+ if (origChannel < kNumPWMHeaders) {
+ channel += kNumDigitalChannels; // remap Headers to end of allocations
+ } else {
+ channel = remapMXPPWMChannel(channel) + 10; // remap MXP to proper channel
+ }
+
+ auto handle =
+ digitalChannelHandles->Allocate(channel, HAL_HandleEnum::PWM, status);
+
+ if (*status != 0)
+ return HAL_kInvalidHandle; // failed to allocate. Pass error back.
+
+ auto port = digitalChannelHandles->Get(handle, HAL_HandleEnum::PWM);
+ if (port == nullptr) { // would only occur on thread issue.
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+
+ port->channel = origChannel;
+
+ SimPWMData[origChannel].initialized = true;
+
+ // Defaults to allow an always valid config.
+ HAL_SetPWMConfig(handle, 2.0, 1.501, 1.5, 1.499, 1.0, status);
+
+ return handle;
+}
+void HAL_FreePWMPort(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimPWMData[port->channel].initialized = false;
+
+ digitalChannelHandles->Free(pwmPortHandle, HAL_HandleEnum::PWM);
+}
+
+HAL_Bool HAL_CheckPWMChannel(int32_t channel) {
+ return channel < kNumPWMChannels && channel >= 0;
+}
+
+void HAL_SetPWMConfig(HAL_DigitalHandle pwmPortHandle, double max,
+ double deadbandMax, double center, double deadbandMin,
+ double min, int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ // calculate the loop time in milliseconds
+ double loopTime =
+ HAL_GetPWMLoopTiming(status) / (kSystemClockTicksPerMicrosecond * 1e3);
+ if (*status != 0) return;
+
+ int32_t maxPwm = static_cast<int32_t>((max - kDefaultPwmCenter) / loopTime +
+ kDefaultPwmStepsDown - 1);
+ int32_t deadbandMaxPwm = static_cast<int32_t>(
+ (deadbandMax - kDefaultPwmCenter) / loopTime + kDefaultPwmStepsDown - 1);
+ int32_t centerPwm = static_cast<int32_t>(
+ (center - kDefaultPwmCenter) / loopTime + kDefaultPwmStepsDown - 1);
+ int32_t deadbandMinPwm = static_cast<int32_t>(
+ (deadbandMin - kDefaultPwmCenter) / loopTime + kDefaultPwmStepsDown - 1);
+ int32_t minPwm = static_cast<int32_t>((min - kDefaultPwmCenter) / loopTime +
+ kDefaultPwmStepsDown - 1);
+
+ port->maxPwm = maxPwm;
+ port->deadbandMaxPwm = deadbandMaxPwm;
+ port->deadbandMinPwm = deadbandMinPwm;
+ port->centerPwm = centerPwm;
+ port->minPwm = minPwm;
+ port->configSet = true;
+}
+
+void HAL_SetPWMConfigRaw(HAL_DigitalHandle pwmPortHandle, int32_t maxPwm,
+ int32_t deadbandMaxPwm, int32_t centerPwm,
+ int32_t deadbandMinPwm, int32_t minPwm,
+ int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ port->maxPwm = maxPwm;
+ port->deadbandMaxPwm = deadbandMaxPwm;
+ port->deadbandMinPwm = deadbandMinPwm;
+ port->centerPwm = centerPwm;
+ port->minPwm = minPwm;
+}
+
+void HAL_GetPWMConfigRaw(HAL_DigitalHandle pwmPortHandle, int32_t* maxPwm,
+ int32_t* deadbandMaxPwm, int32_t* centerPwm,
+ int32_t* deadbandMinPwm, int32_t* minPwm,
+ int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ *maxPwm = port->maxPwm;
+ *deadbandMaxPwm = port->deadbandMaxPwm;
+ *deadbandMinPwm = port->deadbandMinPwm;
+ *centerPwm = port->centerPwm;
+ *minPwm = port->minPwm;
+}
+
+void HAL_SetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
+ HAL_Bool eliminateDeadband, int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ port->eliminateDeadband = eliminateDeadband;
+}
+
+HAL_Bool HAL_GetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
+ int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ return port->eliminateDeadband;
+}
+
+void HAL_SetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t value,
+ int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimPWMData[port->channel].rawValue = value;
+}
+
+void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
+ int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ if (!port->configSet) {
+ *status = INCOMPATIBLE_STATE;
+ return;
+ }
+
+ if (speed < -1.0) {
+ speed = -1.0;
+ } else if (speed > 1.0) {
+ speed = 1.0;
+ }
+
+ SimPWMData[port->channel].speed = speed;
+}
+
+void HAL_SetPWMPosition(HAL_DigitalHandle pwmPortHandle, double pos,
+ int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ if (!port->configSet) {
+ *status = INCOMPATIBLE_STATE;
+ return;
+ }
+
+ if (pos < 0.0) {
+ pos = 0.0;
+ } else if (pos > 1.0) {
+ pos = 1.0;
+ }
+
+ SimPWMData[port->channel].position = pos;
+}
+
+void HAL_SetPWMDisabled(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ SimPWMData[port->channel].rawValue = 0;
+ SimPWMData[port->channel].position = 0;
+ SimPWMData[port->channel].speed = 0;
+}
+
+int32_t HAL_GetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return SimPWMData[port->channel].rawValue;
+}
+
+double HAL_GetPWMSpeed(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ if (!port->configSet) {
+ *status = INCOMPATIBLE_STATE;
+ return 0;
+ }
+
+ double speed = SimPWMData[port->channel].speed;
+ if (speed > 1) speed = 1;
+ if (speed < -1) speed = -1;
+ return speed;
+}
+
+double HAL_GetPWMPosition(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ if (!port->configSet) {
+ *status = INCOMPATIBLE_STATE;
+ return 0;
+ }
+
+ double position = SimPWMData[port->channel].position;
+ if (position > 1) position = 1;
+ if (position < 0) position = 0;
+ return position;
+}
+
+void HAL_LatchPWMZero(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimPWMData[port->channel].zeroLatch = true;
+ SimPWMData[port->channel].zeroLatch = false;
+}
+
+void HAL_SetPWMPeriodScale(HAL_DigitalHandle pwmPortHandle, int32_t squelchMask,
+ int32_t* status) {
+ auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ SimPWMData[port->channel].periodScale = squelchMask;
+}
+
+int32_t HAL_GetPWMLoopTiming(int32_t* status) { return kExpectedLoopTiming; }
+
+uint64_t HAL_GetPWMCycleStartTime(int32_t* status) { return 0; }
+} // extern "C"
diff --git a/hal/src/main/native/sim/Ports.cpp b/hal/src/main/native/sim/Ports.cpp
new file mode 100644
index 0000000..2f670b3
--- /dev/null
+++ b/hal/src/main/native/sim/Ports.cpp
@@ -0,0 +1,41 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/Ports.h"
+
+#include "PortsInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializePorts() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+int32_t HAL_GetNumAccumulators(void) { return kNumAccumulators; }
+int32_t HAL_GetNumAnalogTriggers(void) { return kNumAnalogTriggers; }
+int32_t HAL_GetNumAnalogInputs(void) { return kNumAnalogInputs; }
+int32_t HAL_GetNumAnalogOutputs(void) { return kNumAnalogOutputs; }
+int32_t HAL_GetNumCounters(void) { return kNumCounters; }
+int32_t HAL_GetNumDigitalHeaders(void) { return kNumDigitalHeaders; }
+int32_t HAL_GetNumPWMHeaders(void) { return kNumPWMHeaders; }
+int32_t HAL_GetNumDigitalChannels(void) { return kNumDigitalChannels; }
+int32_t HAL_GetNumPWMChannels(void) { return kNumPWMChannels; }
+int32_t HAL_GetNumDigitalPWMOutputs(void) { return kNumDigitalPWMOutputs; }
+int32_t HAL_GetNumEncoders(void) { return kNumEncoders; }
+int32_t HAL_GetNumInterrupts(void) { return kNumInterrupts; }
+int32_t HAL_GetNumRelayChannels(void) { return kNumRelayChannels; }
+int32_t HAL_GetNumRelayHeaders(void) { return kNumRelayHeaders; }
+int32_t HAL_GetNumPCMModules(void) { return kNumPCMModules; }
+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
new file mode 100644
index 0000000..cfbf1e7
--- /dev/null
+++ b/hal/src/main/native/sim/PortsInternal.h
@@ -0,0 +1,33 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <stdint.h>
+
+namespace hal {
+constexpr int32_t kNumAccumulators = 2;
+constexpr int32_t kNumAnalogTriggers = 8;
+constexpr int32_t kNumAnalogInputs = 8;
+constexpr int32_t kNumAnalogOutputs = 2;
+constexpr int32_t kNumCounters = 8;
+constexpr int32_t kNumDigitalHeaders = 10;
+constexpr int32_t kNumPWMHeaders = 10;
+constexpr int32_t kNumDigitalChannels = 26;
+constexpr int32_t kNumPWMChannels = 20;
+constexpr int32_t kNumDigitalPWMOutputs = 6;
+constexpr int32_t kNumEncoders = 8;
+constexpr int32_t kNumInterrupts = 8;
+constexpr int32_t kNumRelayChannels = 8;
+constexpr int32_t kNumRelayHeaders = kNumRelayChannels / 2;
+constexpr int32_t kNumPCMModules = 63;
+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/Power.cpp b/hal/src/main/native/sim/Power.cpp
new file mode 100644
index 0000000..95bb3dd
--- /dev/null
+++ b/hal/src/main/native/sim/Power.cpp
@@ -0,0 +1,64 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "hal/Power.h"
+
+#include "mockdata/RoboRioDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializePower() {}
+} // namespace init
+} // namespace hal
+
+// TODO: Fix the naming in here
+extern "C" {
+double HAL_GetVinVoltage(int32_t* status) {
+ return SimRoboRioData[0].vInVoltage;
+}
+double HAL_GetVinCurrent(int32_t* status) {
+ return SimRoboRioData[0].vInCurrent;
+}
+double HAL_GetUserVoltage6V(int32_t* status) {
+ return SimRoboRioData[0].userVoltage6V;
+}
+double HAL_GetUserCurrent6V(int32_t* status) {
+ return SimRoboRioData[0].userCurrent6V;
+}
+HAL_Bool HAL_GetUserActive6V(int32_t* status) {
+ return SimRoboRioData[0].userActive6V;
+}
+int32_t HAL_GetUserCurrentFaults6V(int32_t* status) {
+ return SimRoboRioData[0].userFaults6V;
+}
+double HAL_GetUserVoltage5V(int32_t* status) {
+ return SimRoboRioData[0].userVoltage5V;
+}
+double HAL_GetUserCurrent5V(int32_t* status) {
+ return SimRoboRioData[0].userCurrent5V;
+}
+HAL_Bool HAL_GetUserActive5V(int32_t* status) {
+ return SimRoboRioData[0].userActive5V;
+}
+int32_t HAL_GetUserCurrentFaults5V(int32_t* status) {
+ return SimRoboRioData[0].userFaults5V;
+}
+double HAL_GetUserVoltage3V3(int32_t* status) {
+ return SimRoboRioData[0].userVoltage3V3;
+}
+double HAL_GetUserCurrent3V3(int32_t* status) {
+ return SimRoboRioData[0].userCurrent3V3;
+}
+HAL_Bool HAL_GetUserActive3V3(int32_t* status) {
+ return SimRoboRioData[0].userActive3V3;
+}
+int32_t HAL_GetUserCurrentFaults3V3(int32_t* status) {
+ return SimRoboRioData[0].userFaults3V3;
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/Relay.cpp b/hal/src/main/native/sim/Relay.cpp
new file mode 100644
index 0000000..bd1c8a8
--- /dev/null
+++ b/hal/src/main/native/sim/Relay.cpp
@@ -0,0 +1,121 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2018 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 "hal/Relay.h"
+
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/handles/IndexedHandleResource.h"
+#include "mockdata/RelayDataInternal.h"
+
+using namespace hal;
+
+namespace {
+struct Relay {
+ uint8_t channel;
+ bool fwd;
+};
+} // namespace
+
+static IndexedHandleResource<HAL_RelayHandle, Relay, kNumRelayChannels,
+ HAL_HandleEnum::Relay>* relayHandles;
+
+namespace hal {
+namespace init {
+void InitializeRelay() {
+ static IndexedHandleResource<HAL_RelayHandle, Relay, kNumRelayChannels,
+ HAL_HandleEnum::Relay>
+ rH;
+ relayHandles = &rH;
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_RelayHandle HAL_InitializeRelayPort(HAL_PortHandle portHandle, HAL_Bool fwd,
+ int32_t* status) {
+ hal::init::CheckInit();
+ if (*status != 0) return HAL_kInvalidHandle;
+
+ int16_t channel = getPortHandleChannel(portHandle);
+ if (channel == InvalidHandleIndex) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+
+ if (!fwd) channel += kNumRelayHeaders; // add 4 to reverse channels
+
+ auto handle = relayHandles->Allocate(channel, status);
+
+ if (*status != 0)
+ return HAL_kInvalidHandle; // failed to allocate. Pass error back.
+
+ auto port = relayHandles->Get(handle);
+ if (port == nullptr) { // would only occur on thread issue.
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+
+ if (!fwd) {
+ // Subtract number of headers to put channel in range
+ channel -= kNumRelayHeaders;
+
+ port->fwd = false; // set to reverse
+
+ SimRelayData[channel].initializedReverse = true;
+ } else {
+ port->fwd = true; // set to forward
+ SimRelayData[channel].initializedForward = true;
+ }
+
+ port->channel = static_cast<uint8_t>(channel);
+
+ return handle;
+}
+
+void HAL_FreeRelayPort(HAL_RelayHandle relayPortHandle) {
+ auto port = relayHandles->Get(relayPortHandle);
+ relayHandles->Free(relayPortHandle);
+ if (port == nullptr) return;
+ if (port->fwd)
+ SimRelayData[port->channel].initializedForward = false;
+ else
+ SimRelayData[port->channel].initializedReverse = false;
+}
+
+HAL_Bool HAL_CheckRelayChannel(int32_t channel) {
+ // roboRIO only has 4 headers, and the FPGA has
+ // seperate functions for forward and reverse,
+ // instead of seperate channel IDs
+ return channel < kNumRelayHeaders && channel >= 0;
+}
+
+void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
+ int32_t* status) {
+ auto port = relayHandles->Get(relayPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ if (port->fwd)
+ SimRelayData[port->channel].forward = on;
+ else
+ SimRelayData[port->channel].reverse = on;
+}
+
+HAL_Bool HAL_GetRelay(HAL_RelayHandle relayPortHandle, int32_t* status) {
+ auto port = relayHandles->Get(relayPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ if (port->fwd)
+ return SimRelayData[port->channel].forward;
+ else
+ return SimRelayData[port->channel].reverse;
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/SPI.cpp b/hal/src/main/native/sim/SPI.cpp
new file mode 100644
index 0000000..1c90a98
--- /dev/null
+++ b/hal/src/main/native/sim/SPI.cpp
@@ -0,0 +1,73 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/SPI.h"
+
+#include "HALInitializer.h"
+#include "mockdata/SPIDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeSPI() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status) {
+ hal::init::CheckInit();
+ SimSPIData[port].initialized = true;
+}
+int32_t HAL_TransactionSPI(HAL_SPIPort port, const uint8_t* dataToSend,
+ uint8_t* dataReceived, int32_t size) {
+ return SimSPIData[port].Transaction(dataToSend, dataReceived, size);
+}
+int32_t HAL_WriteSPI(HAL_SPIPort port, const uint8_t* dataToSend,
+ int32_t sendSize) {
+ return SimSPIData[port].Write(dataToSend, sendSize);
+}
+int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count) {
+ return SimSPIData[port].Read(buffer, count);
+}
+void HAL_CloseSPI(HAL_SPIPort port) { SimSPIData[port].initialized = false; }
+void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed) {}
+void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
+ HAL_Bool sampleOnTrailing, HAL_Bool clkIdleHigh) {}
+void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) {}
+void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status) {}
+int32_t HAL_GetSPIHandle(HAL_SPIPort port) { return 0; }
+void HAL_SetSPIHandle(HAL_SPIPort port, int32_t handle) {}
+
+void HAL_InitSPIAuto(HAL_SPIPort port, int32_t bufferSize, int32_t* status) {}
+void HAL_FreeSPIAuto(HAL_SPIPort port, int32_t* status) {}
+void HAL_StartSPIAutoRate(HAL_SPIPort port, double period, int32_t* status) {}
+void HAL_StartSPIAutoTrigger(HAL_SPIPort port, HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ HAL_Bool triggerRising, HAL_Bool triggerFalling,
+ int32_t* status) {}
+void HAL_StopSPIAuto(HAL_SPIPort port, int32_t* status) {}
+void HAL_SetSPIAutoTransmitData(HAL_SPIPort port, const uint8_t* dataToSend,
+ int32_t dataSize, int32_t zeroSize,
+ int32_t* status) {}
+void HAL_ForceSPIAutoRead(HAL_SPIPort port, int32_t* status) {}
+int32_t HAL_ReadSPIAutoReceivedData(HAL_SPIPort port, uint32_t* buffer,
+ int32_t numToRead, double timeout,
+ int32_t* status) {
+ return SimSPIData[port].ReadAutoReceivedData(buffer, numToRead, timeout,
+ status);
+}
+int32_t HAL_GetSPIAutoDroppedCount(HAL_SPIPort port, int32_t* status) {
+ return 0;
+}
+
+void HAL_ConfigureSPIAutoStall(HAL_SPIPort port, int32_t csToSclkTicks,
+ int32_t stallTicks, int32_t pow2BytesPerRead,
+ int32_t* status) {}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/SerialPort.cpp b/hal/src/main/native/sim/SerialPort.cpp
new file mode 100644
index 0000000..2df2ebe
--- /dev/null
+++ b/hal/src/main/native/sim/SerialPort.cpp
@@ -0,0 +1,87 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/SerialPort.h"
+
+#include "HALInitializer.h"
+
+namespace hal {
+namespace init {
+void InitializeSerialPort() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_SerialPortHandle HAL_InitializeSerialPort(HAL_SerialPort port,
+ int32_t* status) {
+ hal::init::CheckInit();
+ return HAL_kInvalidHandle;
+}
+
+HAL_SerialPortHandle HAL_InitializeSerialPortDirect(HAL_SerialPort port,
+ const char* portName,
+ int32_t* status) {
+ hal::init::CheckInit();
+ return HAL_kInvalidHandle;
+}
+
+int HAL_GetSerialFD(HAL_SerialPortHandle handle, int32_t* status) { return -1; }
+
+void HAL_SetSerialBaudRate(HAL_SerialPortHandle handle, int32_t baud,
+ int32_t* status) {}
+
+void HAL_SetSerialDataBits(HAL_SerialPortHandle handle, int32_t bits,
+ int32_t* status) {}
+
+void HAL_SetSerialParity(HAL_SerialPortHandle handle, int32_t parity,
+ int32_t* status) {}
+
+void HAL_SetSerialStopBits(HAL_SerialPortHandle handle, int32_t stopBits,
+ int32_t* status) {}
+
+void HAL_SetSerialWriteMode(HAL_SerialPortHandle handle, int32_t mode,
+ int32_t* status) {}
+
+void HAL_SetSerialFlowControl(HAL_SerialPortHandle handle, int32_t flow,
+ int32_t* status) {}
+
+void HAL_SetSerialTimeout(HAL_SerialPortHandle handle, double timeout,
+ int32_t* status) {}
+
+void HAL_EnableSerialTermination(HAL_SerialPortHandle handle, char terminator,
+ int32_t* status) {}
+
+void HAL_DisableSerialTermination(HAL_SerialPortHandle handle,
+ int32_t* status) {}
+
+void HAL_SetSerialReadBufferSize(HAL_SerialPortHandle handle, int32_t size,
+ int32_t* status) {}
+
+void HAL_SetSerialWriteBufferSize(HAL_SerialPortHandle handle, int32_t size,
+ int32_t* status) {}
+
+int32_t HAL_GetSerialBytesReceived(HAL_SerialPortHandle handle,
+ int32_t* status) {
+ return 0;
+}
+
+int32_t HAL_ReadSerial(HAL_SerialPortHandle handle, char* buffer, int32_t count,
+ int32_t* status) {
+ return 0;
+}
+
+int32_t HAL_WriteSerial(HAL_SerialPortHandle handle, const char* buffer,
+ int32_t count, int32_t* status) {
+ return 0;
+}
+
+void HAL_FlushSerial(HAL_SerialPortHandle handle, int32_t* status) {}
+
+void HAL_ClearSerial(HAL_SerialPortHandle handle, int32_t* status) {}
+
+void HAL_CloseSerial(HAL_SerialPortHandle handle, int32_t* status) {}
+} // extern "C"
diff --git a/hal/src/main/native/sim/SimDevice.cpp b/hal/src/main/native/sim/SimDevice.cpp
new file mode 100644
index 0000000..a8f8f80
--- /dev/null
+++ b/hal/src/main/native/sim/SimDevice.cpp
@@ -0,0 +1,75 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/SimDevice.h"
+
+#include <wpi/SmallString.h>
+#include <wpi/raw_ostream.h>
+
+#include "HALInitializer.h"
+#include "mockdata/SimDeviceDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeSimDevice() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+HAL_SimDeviceHandle HAL_CreateSimDevice(const char* name) {
+ hal::init::CheckInit();
+ return SimSimDeviceData->CreateDevice(name);
+}
+
+void HAL_FreeSimDevice(HAL_SimDeviceHandle handle) {
+ SimSimDeviceData->FreeDevice(handle);
+}
+
+HAL_SimValueHandle HAL_CreateSimValue(HAL_SimDeviceHandle device,
+ const char* name, HAL_Bool readonly,
+ const struct HAL_Value* initialValue) {
+ return SimSimDeviceData->CreateValue(device, name, readonly, 0, nullptr,
+ *initialValue);
+}
+
+HAL_SimValueHandle HAL_CreateSimValueEnum(HAL_SimDeviceHandle device,
+ const char* name, HAL_Bool readonly,
+ int32_t numOptions,
+ const char** options,
+ int32_t initialValue) {
+ return SimSimDeviceData->CreateValue(device, name, readonly, numOptions,
+ options, HAL_MakeEnum(initialValue));
+}
+
+void HAL_GetSimValue(HAL_SimValueHandle handle, struct HAL_Value* value) {
+ *value = SimSimDeviceData->GetValue(handle);
+}
+
+void HAL_SetSimValue(HAL_SimValueHandle handle, const struct HAL_Value* value) {
+ SimSimDeviceData->SetValue(handle, *value);
+}
+
+hal::SimDevice::SimDevice(const char* name, int index) {
+ wpi::SmallString<128> fullname;
+ wpi::raw_svector_ostream os(fullname);
+ os << name << '[' << index << ']';
+
+ m_handle = HAL_CreateSimDevice(fullname.c_str());
+}
+
+hal::SimDevice::SimDevice(const char* name, int index, int channel) {
+ wpi::SmallString<128> fullname;
+ wpi::raw_svector_ostream os(fullname);
+ os << name << '[' << index << ',' << channel << ']';
+
+ m_handle = HAL_CreateSimDevice(fullname.c_str());
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/Solenoid.cpp b/hal/src/main/native/sim/Solenoid.cpp
new file mode 100644
index 0000000..46bd285
--- /dev/null
+++ b/hal/src/main/native/sim/Solenoid.cpp
@@ -0,0 +1,145 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "hal/Solenoid.h"
+
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/Errors.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/IndexedHandleResource.h"
+#include "mockdata/PCMDataInternal.h"
+
+namespace {
+struct Solenoid {
+ uint8_t module;
+ uint8_t channel;
+};
+} // namespace
+
+using namespace hal;
+
+static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
+ kNumPCMModules * kNumSolenoidChannels,
+ HAL_HandleEnum::Solenoid>* solenoidHandles;
+
+namespace hal {
+namespace init {
+void InitializeSolenoid() {
+ static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
+ kNumPCMModules * kNumSolenoidChannels,
+ HAL_HandleEnum::Solenoid>
+ sH;
+ solenoidHandles = &sH;
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
+ int32_t* status) {
+ hal::init::CheckInit();
+ int16_t channel = getPortHandleChannel(portHandle);
+ int16_t module = getPortHandleModule(portHandle);
+ if (channel == InvalidHandleIndex) {
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+
+ if (!HAL_CheckSolenoidChannel(channel)) {
+ *status = RESOURCE_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+
+ if (!HAL_CheckSolenoidModule(module)) {
+ *status = RESOURCE_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+
+ auto handle = solenoidHandles->Allocate(
+ module * kNumSolenoidChannels + channel, status);
+ if (handle == HAL_kInvalidHandle) { // out of resources
+ *status = NO_AVAILABLE_RESOURCES;
+ return HAL_kInvalidHandle;
+ }
+ auto solenoidPort = solenoidHandles->Get(handle);
+ if (solenoidPort == nullptr) { // would only occur on thread issues
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+ solenoidPort->module = static_cast<uint8_t>(module);
+ solenoidPort->channel = static_cast<uint8_t>(channel);
+
+ HALSIM_SetPCMSolenoidInitialized(module, channel, true);
+
+ return handle;
+}
+void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle) {
+ auto port = solenoidHandles->Get(solenoidPortHandle);
+ if (port == nullptr) return;
+ solenoidHandles->Free(solenoidPortHandle);
+ HALSIM_SetPCMSolenoidInitialized(port->module, port->channel, false);
+}
+HAL_Bool HAL_CheckSolenoidModule(int32_t module) {
+ return module < kNumPCMModules && module >= 0;
+}
+
+HAL_Bool HAL_CheckSolenoidChannel(int32_t channel) {
+ return channel < kNumSolenoidChannels && channel >= 0;
+}
+HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
+ int32_t* status) {
+ auto port = solenoidHandles->Get(solenoidPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+
+ return HALSIM_GetPCMSolenoidOutput(port->module, port->channel);
+}
+int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status) {
+ int32_t total = 0;
+ for (int i = 0; i < kNumSolenoidChannels; i++) {
+ int32_t channel = HALSIM_GetPCMSolenoidOutput(module, i) ? 1 : 0;
+ total = total + (channel << i);
+ }
+
+ return total;
+}
+void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
+ int32_t* status) {
+ auto port = solenoidHandles->Get(solenoidPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ HALSIM_SetPCMSolenoidOutput(port->module, port->channel, value);
+}
+
+void HAL_SetAllSolenoids(int32_t module, int32_t state, int32_t* status) {
+ for (int i = 0; i < kNumSolenoidChannels; i++) {
+ int set = state & 1;
+ HALSIM_SetPCMSolenoidOutput(module, i, set);
+ state >>= 1;
+ }
+}
+
+int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status) {
+ return 0;
+}
+HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status) {
+ return 0;
+}
+HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status) {
+ return 0;
+}
+void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status) {}
+void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
+ int32_t durMS, int32_t* status) {}
+void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status) {}
+} // extern "C"
diff --git a/hal/src/main/native/sim/Threads.cpp b/hal/src/main/native/sim/Threads.cpp
new file mode 100644
index 0000000..2aa2c4b
--- /dev/null
+++ b/hal/src/main/native/sim/Threads.cpp
@@ -0,0 +1,30 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "hal/Threads.h"
+
+namespace hal {
+namespace init {
+void InitializeThreads() {}
+} // namespace init
+} // namespace hal
+
+int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
+ int32_t* status) {
+ return 0;
+}
+int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status) {
+ return 0;
+}
+HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
+ int32_t priority, int32_t* status) {
+ return true;
+}
+HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority,
+ int32_t* status) {
+ return true;
+}
diff --git a/hal/src/main/native/sim/jni/AccelerometerDataJNI.cpp b/hal/src/main/native/sim/jni/AccelerometerDataJNI.cpp
new file mode 100644
index 0000000..8964a41
--- /dev/null
+++ b/hal/src/main/native/sim/jni/AccelerometerDataJNI.cpp
@@ -0,0 +1,279 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI.h"
+#include "mockdata/AccelerometerData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: registerActiveCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_registerActiveCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAccelerometerActiveCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: cancelActiveCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_cancelActiveCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAccelerometerActiveCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: getActive
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_getActive
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAccelerometerActive(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: setActive
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_setActive
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetAccelerometerActive(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: registerRangeCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_registerRangeCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAccelerometerRangeCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: cancelRangeCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_cancelRangeCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAccelerometerRangeCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: getRange
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_getRange
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAccelerometerRange(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: setRange
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_setRange
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetAccelerometerRange(index,
+ static_cast<HAL_AccelerometerRange>(value));
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: registerXCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_registerXCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAccelerometerXCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: cancelXCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_cancelXCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAccelerometerXCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: getX
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_getX
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAccelerometerX(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: setX
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_setX
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetAccelerometerX(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: registerYCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_registerYCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAccelerometerYCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: cancelYCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_cancelYCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAccelerometerYCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: getY
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_getY
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAccelerometerY(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: setY
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_setY
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetAccelerometerY(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: registerZCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_registerZCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAccelerometerZCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: cancelZCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_cancelZCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAccelerometerZCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: getZ
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_getZ
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAccelerometerZ(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: setZ
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_setZ
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetAccelerometerZ(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AccelerometerDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetAccelerometerData(index);
+}
+
+} // extern "C"
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 0000000..530eae2
--- /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 <jni.h>
+
+#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_AddressableLEDData[]>(HAL_kAddressableLEDMaxLength);
+ int32_t length = HALSIM_GetAddressableLEDData(index, data.get());
+ return MakeJByteArray(
+ env, wpi::ArrayRef(reinterpret_cast<jbyte*>(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<const HAL_AddressableLEDData*>(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/jni/AnalogGyroDataJNI.cpp b/hal/src/main/native/sim/jni/AnalogGyroDataJNI.cpp
new file mode 100644
index 0000000..08d18de
--- /dev/null
+++ b/hal/src/main/native/sim/jni/AnalogGyroDataJNI.cpp
@@ -0,0 +1,178 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI.h"
+#include "mockdata/AnalogGyroData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: registerAngleCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_registerAngleCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogGyroAngleCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: cancelAngleCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_cancelAngleCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogGyroAngleCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: getAngle
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_getAngle
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogGyroAngle(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: setAngle
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_setAngle
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetAnalogGyroAngle(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: registerRateCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_registerRateCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogGyroRateCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: cancelRateCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_cancelRateCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogGyroRateCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: getRate
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_getRate
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogGyroRate(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: setRate
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_setRate
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetAnalogGyroRate(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: registerInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_registerInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogGyroInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: cancelInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_cancelInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogGyroInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: getInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_getInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogGyroInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: setInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_setInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetAnalogGyroInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogGyroDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetAnalogGyroData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/AnalogInDataJNI.cpp b/hal/src/main/native/sim/jni/AnalogInDataJNI.cpp
new file mode 100644
index 0000000..c6cee7b
--- /dev/null
+++ b/hal/src/main/native/sim/jni/AnalogInDataJNI.cpp
@@ -0,0 +1,483 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI.h"
+#include "mockdata/AnalogInData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: registerInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_registerInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogInInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: cancelInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_cancelInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogInInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: getInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_getInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogInInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: setInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_setInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetAnalogInInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: registerAverageBitsCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_registerAverageBitsCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogInAverageBitsCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: cancelAverageBitsCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_cancelAverageBitsCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogInAverageBitsCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: getAverageBits
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_getAverageBits
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogInAverageBits(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: setAverageBits
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_setAverageBits
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetAnalogInAverageBits(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: registerOversampleBitsCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_registerOversampleBitsCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogInOversampleBitsCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: cancelOversampleBitsCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_cancelOversampleBitsCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogInOversampleBitsCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: getOversampleBits
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_getOversampleBits
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogInOversampleBits(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: setOversampleBits
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_setOversampleBits
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetAnalogInOversampleBits(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: registerVoltageCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_registerVoltageCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogInVoltageCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: cancelVoltageCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_cancelVoltageCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogInVoltageCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: getVoltage
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_getVoltage
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogInVoltage(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: setVoltage
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_setVoltage
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetAnalogInVoltage(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: registerAccumulatorInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_registerAccumulatorInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(
+ env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogInAccumulatorInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: cancelAccumulatorInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_cancelAccumulatorInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(
+ env, handle, index, &HALSIM_CancelAnalogInAccumulatorInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: getAccumulatorInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_getAccumulatorInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogInAccumulatorInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: setAccumulatorInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_setAccumulatorInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetAnalogInAccumulatorInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: registerAccumulatorValueCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_registerAccumulatorValueCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(
+ env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogInAccumulatorValueCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: cancelAccumulatorValueCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_cancelAccumulatorValueCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogInAccumulatorValueCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: getAccumulatorValue
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_getAccumulatorValue
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogInAccumulatorValue(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: setAccumulatorValue
+ * Signature: (IJ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_setAccumulatorValue
+ (JNIEnv*, jclass, jint index, jlong value)
+{
+ HALSIM_SetAnalogInAccumulatorValue(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: registerAccumulatorCountCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_registerAccumulatorCountCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(
+ env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogInAccumulatorCountCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: cancelAccumulatorCountCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_cancelAccumulatorCountCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogInAccumulatorCountCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: getAccumulatorCount
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_getAccumulatorCount
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogInAccumulatorCount(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: setAccumulatorCount
+ * Signature: (IJ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_setAccumulatorCount
+ (JNIEnv*, jclass, jint index, jlong value)
+{
+ HALSIM_SetAnalogInAccumulatorCount(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: registerAccumulatorCenterCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_registerAccumulatorCenterCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(
+ env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogInAccumulatorCenterCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: cancelAccumulatorCenterCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_cancelAccumulatorCenterCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogInAccumulatorCenterCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: getAccumulatorCenter
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_getAccumulatorCenter
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogInAccumulatorCenter(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: setAccumulatorCenter
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_setAccumulatorCenter
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetAnalogInAccumulatorCenter(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: registerAccumulatorDeadbandCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_registerAccumulatorDeadbandCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(
+ env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogInAccumulatorDeadbandCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: cancelAccumulatorDeadbandCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_cancelAccumulatorDeadbandCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogInAccumulatorDeadbandCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: getAccumulatorDeadband
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_getAccumulatorDeadband
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogInAccumulatorDeadband(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: setAccumulatorDeadband
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_setAccumulatorDeadband
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetAnalogInAccumulatorDeadband(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogInDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetAnalogInData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/AnalogOutDataJNI.cpp b/hal/src/main/native/sim/jni/AnalogOutDataJNI.cpp
new file mode 100644
index 0000000..af9d6d6
--- /dev/null
+++ b/hal/src/main/native/sim/jni/AnalogOutDataJNI.cpp
@@ -0,0 +1,128 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI.h"
+#include "mockdata/AnalogOutData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI
+ * Method: registerVoltageCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI_registerVoltageCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogOutVoltageCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI
+ * Method: cancelVoltageCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI_cancelVoltageCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogOutVoltageCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI
+ * Method: getVoltage
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI_getVoltage
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogOutVoltage(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI
+ * Method: setVoltage
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI_setVoltage
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetAnalogOutVoltage(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI
+ * Method: registerInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI_registerInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogOutInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI
+ * Method: cancelInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI_cancelInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogOutInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI
+ * Method: getInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI_getInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogOutInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI
+ * Method: setInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI_setInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetAnalogOutInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogOutDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetAnalogOutData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/AnalogTriggerDataJNI.cpp b/hal/src/main/native/sim/jni/AnalogTriggerDataJNI.cpp
new file mode 100644
index 0000000..66af737
--- /dev/null
+++ b/hal/src/main/native/sim/jni/AnalogTriggerDataJNI.cpp
@@ -0,0 +1,181 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI.h"
+#include "mockdata/AnalogTriggerData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: registerInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_registerInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(
+ env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogTriggerInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: cancelInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_cancelInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelAnalogTriggerInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: getInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_getInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogTriggerInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: setInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_setInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetAnalogTriggerInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: registerTriggerLowerBoundCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_registerTriggerLowerBoundCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(
+ env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogTriggerTriggerLowerBoundCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: cancelTriggerLowerBoundCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_cancelTriggerLowerBoundCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(
+ env, handle, index, &HALSIM_CancelAnalogTriggerTriggerLowerBoundCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: getTriggerLowerBound
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_getTriggerLowerBound
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogTriggerTriggerLowerBound(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: setTriggerLowerBound
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_setTriggerLowerBound
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetAnalogTriggerTriggerLowerBound(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: registerTriggerUpperBoundCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_registerTriggerUpperBoundCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(
+ env, index, callback, initialNotify,
+ &HALSIM_RegisterAnalogTriggerTriggerUpperBoundCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: cancelTriggerUpperBoundCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_cancelTriggerUpperBoundCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(
+ env, handle, index, &HALSIM_CancelAnalogTriggerTriggerUpperBoundCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: getTriggerUpperBound
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_getTriggerUpperBound
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetAnalogTriggerTriggerUpperBound(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: setTriggerUpperBound
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_setTriggerUpperBound
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetAnalogTriggerTriggerUpperBound(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_AnalogTriggerDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetAnalogTriggerData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/BufferCallbackStore.cpp b/hal/src/main/native/sim/jni/BufferCallbackStore.cpp
new file mode 100644
index 0000000..3c9941e
--- /dev/null
+++ b/hal/src/main/native/sim/jni/BufferCallbackStore.cpp
@@ -0,0 +1,125 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-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 "BufferCallbackStore.h"
+
+#include <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/Value.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/NotifyListener.h"
+
+using namespace wpi::java;
+using namespace sim;
+
+static hal::UnlimitedHandleResource<SIM_JniHandle, BufferCallbackStore,
+ hal::HAL_HandleEnum::SimulationJni>*
+ callbackHandles;
+
+namespace sim {
+void InitializeBufferStore() {
+ static hal::UnlimitedHandleResource<SIM_JniHandle, BufferCallbackStore,
+ hal::HAL_HandleEnum::SimulationJni>
+ cb;
+ callbackHandles = &cb;
+}
+} // namespace sim
+
+void BufferCallbackStore::create(JNIEnv* env, jobject obj) {
+ m_call = JGlobal<jobject>(env, obj);
+}
+
+void BufferCallbackStore::performCallback(const char* name, uint8_t* buffer,
+ uint32_t length) {
+ JNIEnv* env;
+ JavaVM* vm = sim::GetJVM();
+ bool didAttachThread = false;
+ int tryGetEnv = vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
+ if (tryGetEnv == JNI_EDETACHED) {
+ // Thread not attached
+ didAttachThread = true;
+ if (vm->AttachCurrentThread(reinterpret_cast<void**>(&env), nullptr) != 0) {
+ // Failed to attach, log and return
+ wpi::outs() << "Failed to attach\n";
+ wpi::outs().flush();
+ return;
+ }
+ } else if (tryGetEnv == JNI_EVERSION) {
+ wpi::outs() << "Invalid JVM Version requested\n";
+ wpi::outs().flush();
+ }
+
+ auto toCallbackArr =
+ MakeJByteArray(env, wpi::StringRef{reinterpret_cast<const char*>(buffer),
+ static_cast<size_t>(length)});
+
+ env->CallVoidMethod(m_call, sim::GetBufferCallback(), MakeJString(env, name),
+ toCallbackArr, (jint)length);
+
+ jbyte* fromCallbackArr = reinterpret_cast<jbyte*>(
+ env->GetPrimitiveArrayCritical(toCallbackArr, nullptr));
+
+ for (size_t i = 0; i < length; i++) {
+ buffer[i] = fromCallbackArr[i];
+ }
+
+ env->ReleasePrimitiveArrayCritical(toCallbackArr, fromCallbackArr, JNI_ABORT);
+
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ }
+
+ if (didAttachThread) {
+ vm->DetachCurrentThread();
+ }
+}
+
+void BufferCallbackStore::free(JNIEnv* env) { m_call.free(env); }
+
+SIM_JniHandle sim::AllocateBufferCallback(
+ JNIEnv* env, jint index, jobject callback,
+ RegisterBufferCallbackFunc createCallback) {
+ auto callbackStore = std::make_shared<BufferCallbackStore>();
+
+ auto handle = callbackHandles->Allocate(callbackStore);
+
+ if (handle == HAL_kInvalidHandle) {
+ return -1;
+ }
+
+ uintptr_t handleAsPtr = static_cast<uintptr_t>(handle);
+ void* handleAsVoidPtr = reinterpret_cast<void*>(handleAsPtr);
+
+ callbackStore->create(env, callback);
+
+ auto callbackFunc = [](const char* name, void* param, uint8_t* buffer,
+ uint32_t length) {
+ uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
+ SIM_JniHandle handle = static_cast<SIM_JniHandle>(handleTmp);
+ auto data = callbackHandles->Get(handle);
+ if (!data) return;
+
+ data->performCallback(name, buffer, length);
+ };
+
+ auto id = createCallback(index, callbackFunc, handleAsVoidPtr);
+
+ callbackStore->setCallbackId(id);
+
+ return handle;
+}
+
+void sim::FreeBufferCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
+ FreeBufferCallbackFunc freeCallback) {
+ auto callback = callbackHandles->Free(handle);
+ freeCallback(index, callback->getCallbackId());
+ callback->free(env);
+}
diff --git a/hal/src/main/native/sim/jni/BufferCallbackStore.h b/hal/src/main/native/sim/jni/BufferCallbackStore.h
new file mode 100644
index 0000000..6b472ac
--- /dev/null
+++ b/hal/src/main/native/sim/jni/BufferCallbackStore.h
@@ -0,0 +1,45 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-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 <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/Value.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/NotifyListener.h"
+
+namespace sim {
+class BufferCallbackStore {
+ public:
+ void create(JNIEnv* env, jobject obj);
+ void performCallback(const char* name, uint8_t* buffer, uint32_t length);
+ void free(JNIEnv* env);
+ void setCallbackId(int32_t id) { callbackId = id; }
+ int32_t getCallbackId() { return callbackId; }
+
+ private:
+ wpi::java::JGlobal<jobject> m_call;
+ int32_t callbackId;
+};
+
+void InitializeBufferStore();
+
+typedef int32_t (*RegisterBufferCallbackFunc)(int32_t index,
+ HAL_BufferCallback callback,
+ void* param);
+typedef void (*FreeBufferCallbackFunc)(int32_t index, int32_t uid);
+
+SIM_JniHandle AllocateBufferCallback(JNIEnv* env, jint index, jobject callback,
+ RegisterBufferCallbackFunc createCallback);
+void FreeBufferCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
+ FreeBufferCallbackFunc freeCallback);
+} // namespace sim
diff --git a/hal/src/main/native/sim/jni/CallbackStore.cpp b/hal/src/main/native/sim/jni/CallbackStore.cpp
new file mode 100644
index 0000000..318ab1e
--- /dev/null
+++ b/hal/src/main/native/sim/jni/CallbackStore.cpp
@@ -0,0 +1,194 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-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 "CallbackStore.h"
+
+#include <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/Value.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/NotifyListener.h"
+
+using namespace wpi::java;
+using namespace sim;
+
+static hal::UnlimitedHandleResource<SIM_JniHandle, CallbackStore,
+ hal::HAL_HandleEnum::SimulationJni>*
+ callbackHandles;
+
+namespace sim {
+void InitializeStore() {
+ static hal::UnlimitedHandleResource<SIM_JniHandle, CallbackStore,
+ hal::HAL_HandleEnum::SimulationJni>
+ cb;
+ callbackHandles = &cb;
+}
+} // namespace sim
+
+void CallbackStore::create(JNIEnv* env, jobject obj) {
+ m_call = JGlobal<jobject>(env, obj);
+}
+
+void CallbackStore::performCallback(const char* name, const HAL_Value* value) {
+ JNIEnv* env;
+ JavaVM* vm = sim::GetJVM();
+ bool didAttachThread = false;
+ int tryGetEnv = vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
+ if (tryGetEnv == JNI_EDETACHED) {
+ // Thread not attached
+ didAttachThread = true;
+ if (vm->AttachCurrentThread(reinterpret_cast<void**>(&env), nullptr) != 0) {
+ // Failed to attach, log and return
+ wpi::outs() << "Failed to attach\n";
+ wpi::outs().flush();
+ return;
+ }
+ } else if (tryGetEnv == JNI_EVERSION) {
+ wpi::outs() << "Invalid JVM Version requested\n";
+ wpi::outs().flush();
+ }
+
+ env->CallVoidMethod(m_call, sim::GetNotifyCallback(), MakeJString(env, name),
+ (jint)value->type, (jlong)value->data.v_long,
+ (jdouble)value->data.v_double);
+
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ }
+
+ if (didAttachThread) {
+ vm->DetachCurrentThread();
+ }
+}
+
+void CallbackStore::free(JNIEnv* env) { m_call.free(env); }
+
+SIM_JniHandle sim::AllocateCallback(JNIEnv* env, jint index, jobject callback,
+ jboolean initialNotify,
+ RegisterCallbackFunc createCallback) {
+ auto callbackStore = std::make_shared<CallbackStore>();
+
+ auto handle = callbackHandles->Allocate(callbackStore);
+
+ if (handle == HAL_kInvalidHandle) {
+ return -1;
+ }
+
+ uintptr_t handleAsPtr = static_cast<uintptr_t>(handle);
+ void* handleAsVoidPtr = reinterpret_cast<void*>(handleAsPtr);
+
+ callbackStore->create(env, callback);
+
+ auto callbackFunc = [](const char* name, void* param,
+ const HAL_Value* value) {
+ uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
+ SIM_JniHandle handle = static_cast<SIM_JniHandle>(handleTmp);
+ auto data = callbackHandles->Get(handle);
+ if (!data) return;
+
+ data->performCallback(name, value);
+ };
+
+ auto id = createCallback(index, callbackFunc, handleAsVoidPtr, initialNotify);
+
+ callbackStore->setCallbackId(id);
+
+ return handle;
+}
+
+void sim::FreeCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
+ FreeCallbackFunc freeCallback) {
+ auto callback = callbackHandles->Free(handle);
+ freeCallback(index, callback->getCallbackId());
+ callback->free(env);
+}
+
+SIM_JniHandle sim::AllocateChannelCallback(
+ JNIEnv* env, jint index, jint channel, jobject callback,
+ jboolean initialNotify, RegisterChannelCallbackFunc createCallback) {
+ auto callbackStore = std::make_shared<CallbackStore>();
+
+ auto handle = callbackHandles->Allocate(callbackStore);
+
+ if (handle == HAL_kInvalidHandle) {
+ return -1;
+ }
+
+ uintptr_t handleAsPtr = static_cast<uintptr_t>(handle);
+ void* handleAsVoidPtr = reinterpret_cast<void*>(handleAsPtr);
+
+ callbackStore->create(env, callback);
+
+ auto callbackFunc = [](const char* name, void* param,
+ const HAL_Value* value) {
+ uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
+ SIM_JniHandle handle = static_cast<SIM_JniHandle>(handleTmp);
+ auto data = callbackHandles->Get(handle);
+ if (!data) return;
+
+ data->performCallback(name, value);
+ };
+
+ auto id = createCallback(index, channel, callbackFunc, handleAsVoidPtr,
+ initialNotify);
+
+ callbackStore->setCallbackId(id);
+
+ return handle;
+}
+
+void sim::FreeChannelCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
+ jint channel,
+ FreeChannelCallbackFunc freeCallback) {
+ auto callback = callbackHandles->Free(handle);
+ freeCallback(index, channel, callback->getCallbackId());
+ callback->free(env);
+}
+
+SIM_JniHandle sim::AllocateCallbackNoIndex(
+ JNIEnv* env, jobject callback, jboolean initialNotify,
+ RegisterCallbackNoIndexFunc createCallback) {
+ auto callbackStore = std::make_shared<CallbackStore>();
+
+ auto handle = callbackHandles->Allocate(callbackStore);
+
+ if (handle == HAL_kInvalidHandle) {
+ return -1;
+ }
+
+ uintptr_t handleAsPtr = static_cast<uintptr_t>(handle);
+ void* handleAsVoidPtr = reinterpret_cast<void*>(handleAsPtr);
+
+ callbackStore->create(env, callback);
+
+ auto callbackFunc = [](const char* name, void* param,
+ const HAL_Value* value) {
+ uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
+ SIM_JniHandle handle = static_cast<SIM_JniHandle>(handleTmp);
+ auto data = callbackHandles->Get(handle);
+ if (!data) return;
+
+ data->performCallback(name, value);
+ };
+
+ auto id = createCallback(callbackFunc, handleAsVoidPtr, initialNotify);
+
+ callbackStore->setCallbackId(id);
+
+ return handle;
+}
+
+void sim::FreeCallbackNoIndex(JNIEnv* env, SIM_JniHandle handle,
+ FreeCallbackNoIndexFunc freeCallback) {
+ auto callback = callbackHandles->Free(handle);
+ freeCallback(callback->getCallbackId());
+ callback->free(env);
+}
diff --git a/hal/src/main/native/sim/jni/CallbackStore.h b/hal/src/main/native/sim/jni/CallbackStore.h
new file mode 100644
index 0000000..eacf314
--- /dev/null
+++ b/hal/src/main/native/sim/jni/CallbackStore.h
@@ -0,0 +1,66 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-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 <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/Value.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/NotifyListener.h"
+
+namespace sim {
+class CallbackStore {
+ public:
+ void create(JNIEnv* env, jobject obj);
+ void performCallback(const char* name, const HAL_Value* value);
+ void free(JNIEnv* env);
+ void setCallbackId(int32_t id) { callbackId = id; }
+ int32_t getCallbackId() { return callbackId; }
+
+ private:
+ wpi::java::JGlobal<jobject> m_call;
+ int32_t callbackId;
+};
+
+void InitializeStore();
+
+typedef int32_t (*RegisterCallbackFunc)(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+typedef void (*FreeCallbackFunc)(int32_t index, int32_t uid);
+typedef int32_t (*RegisterChannelCallbackFunc)(int32_t index, int32_t channel,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+typedef void (*FreeChannelCallbackFunc)(int32_t index, int32_t channel,
+ int32_t uid);
+typedef int32_t (*RegisterCallbackNoIndexFunc)(HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+typedef void (*FreeCallbackNoIndexFunc)(int32_t uid);
+
+SIM_JniHandle AllocateCallback(JNIEnv* env, jint index, jobject callback,
+ jboolean initialNotify,
+ RegisterCallbackFunc createCallback);
+SIM_JniHandle AllocateChannelCallback(
+ JNIEnv* env, jint index, jint channel, jobject callback,
+ jboolean initialNotify, RegisterChannelCallbackFunc createCallback);
+SIM_JniHandle AllocateCallbackNoIndex(
+ JNIEnv* env, jobject callback, jboolean initialNotify,
+ RegisterCallbackNoIndexFunc createCallback);
+void FreeCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
+ FreeCallbackFunc freeCallback);
+void FreeChannelCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
+ jint channel, FreeChannelCallbackFunc freeCallback);
+void FreeCallbackNoIndex(JNIEnv* env, SIM_JniHandle handle,
+ FreeCallbackNoIndexFunc freeCallback);
+} // namespace sim
diff --git a/hal/src/main/native/sim/jni/ConstBufferCallbackStore.cpp b/hal/src/main/native/sim/jni/ConstBufferCallbackStore.cpp
new file mode 100644
index 0000000..d681983
--- /dev/null
+++ b/hal/src/main/native/sim/jni/ConstBufferCallbackStore.cpp
@@ -0,0 +1,117 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-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 "ConstBufferCallbackStore.h"
+
+#include <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/Value.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/NotifyListener.h"
+
+using namespace wpi::java;
+using namespace sim;
+
+static hal::UnlimitedHandleResource<SIM_JniHandle, ConstBufferCallbackStore,
+ hal::HAL_HandleEnum::SimulationJni>*
+ callbackHandles;
+
+namespace sim {
+void InitializeConstBufferStore() {
+ static hal::UnlimitedHandleResource<SIM_JniHandle, ConstBufferCallbackStore,
+ hal::HAL_HandleEnum::SimulationJni>
+ cb;
+ callbackHandles = &cb;
+}
+} // namespace sim
+
+void ConstBufferCallbackStore::create(JNIEnv* env, jobject obj) {
+ m_call = JGlobal<jobject>(env, obj);
+}
+
+void ConstBufferCallbackStore::performCallback(const char* name,
+ const uint8_t* buffer,
+ uint32_t length) {
+ JNIEnv* env;
+ JavaVM* vm = sim::GetJVM();
+ bool didAttachThread = false;
+ int tryGetEnv = vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
+ if (tryGetEnv == JNI_EDETACHED) {
+ // Thread not attached
+ didAttachThread = true;
+ if (vm->AttachCurrentThread(reinterpret_cast<void**>(&env), nullptr) != 0) {
+ // Failed to attach, log and return
+ wpi::outs() << "Failed to attach\n";
+ wpi::outs().flush();
+ return;
+ }
+ } else if (tryGetEnv == JNI_EVERSION) {
+ wpi::outs() << "Invalid JVM Version requested\n";
+ wpi::outs().flush();
+ }
+
+ auto toCallbackArr =
+ MakeJByteArray(env, wpi::StringRef{reinterpret_cast<const char*>(buffer),
+ static_cast<size_t>(length)});
+
+ env->CallVoidMethod(m_call, sim::GetConstBufferCallback(),
+ MakeJString(env, name), toCallbackArr, (jint)length);
+
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ }
+
+ if (didAttachThread) {
+ vm->DetachCurrentThread();
+ }
+}
+
+void ConstBufferCallbackStore::free(JNIEnv* env) { m_call.free(env); }
+
+SIM_JniHandle sim::AllocateConstBufferCallback(
+ JNIEnv* env, jint index, jobject callback,
+ RegisterConstBufferCallbackFunc createCallback) {
+ auto callbackStore = std::make_shared<ConstBufferCallbackStore>();
+
+ auto handle = callbackHandles->Allocate(callbackStore);
+
+ if (handle == HAL_kInvalidHandle) {
+ return -1;
+ }
+
+ uintptr_t handleAsPtr = static_cast<uintptr_t>(handle);
+ void* handleAsVoidPtr = reinterpret_cast<void*>(handleAsPtr);
+
+ callbackStore->create(env, callback);
+
+ auto callbackFunc = [](const char* name, void* param, const uint8_t* buffer,
+ uint32_t length) {
+ uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
+ SIM_JniHandle handle = static_cast<SIM_JniHandle>(handleTmp);
+ auto data = callbackHandles->Get(handle);
+ if (!data) return;
+
+ data->performCallback(name, buffer, length);
+ };
+
+ auto id = createCallback(index, callbackFunc, handleAsVoidPtr);
+
+ callbackStore->setCallbackId(id);
+
+ return handle;
+}
+
+void sim::FreeConstBufferCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
+ FreeConstBufferCallbackFunc freeCallback) {
+ auto callback = callbackHandles->Free(handle);
+ freeCallback(index, callback->getCallbackId());
+ callback->free(env);
+}
diff --git a/hal/src/main/native/sim/jni/ConstBufferCallbackStore.h b/hal/src/main/native/sim/jni/ConstBufferCallbackStore.h
new file mode 100644
index 0000000..2164a74
--- /dev/null
+++ b/hal/src/main/native/sim/jni/ConstBufferCallbackStore.h
@@ -0,0 +1,46 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-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 <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/Value.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/NotifyListener.h"
+
+namespace sim {
+class ConstBufferCallbackStore {
+ public:
+ void create(JNIEnv* env, jobject obj);
+ void performCallback(const char* name, const uint8_t* buffer,
+ uint32_t length);
+ void free(JNIEnv* env);
+ void setCallbackId(int32_t id) { callbackId = id; }
+ int32_t getCallbackId() { return callbackId; }
+
+ private:
+ wpi::java::JGlobal<jobject> m_call;
+ int32_t callbackId;
+};
+
+void InitializeConstBufferStore();
+
+typedef int32_t (*RegisterConstBufferCallbackFunc)(
+ int32_t index, HAL_ConstBufferCallback callback, void* param);
+typedef void (*FreeConstBufferCallbackFunc)(int32_t index, int32_t uid);
+
+SIM_JniHandle AllocateConstBufferCallback(
+ JNIEnv* env, jint index, jobject callback,
+ RegisterConstBufferCallbackFunc createCallback);
+void FreeConstBufferCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
+ FreeConstBufferCallbackFunc freeCallback);
+} // namespace sim
diff --git a/hal/src/main/native/sim/jni/DIODataJNI.cpp b/hal/src/main/native/sim/jni/DIODataJNI.cpp
new file mode 100644
index 0000000..2ad55f9
--- /dev/null
+++ b/hal/src/main/native/sim/jni/DIODataJNI.cpp
@@ -0,0 +1,277 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_DIODataJNI.h"
+#include "mockdata/DIOData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: registerInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_registerInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterDIOInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: cancelInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_cancelInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelDIOInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: getInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_getInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetDIOInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: setInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_setInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetDIOInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: registerValueCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_registerValueCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterDIOValueCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: cancelValueCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_cancelValueCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index, &HALSIM_CancelDIOValueCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: getValue
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_getValue
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetDIOValue(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: setValue
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_setValue
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetDIOValue(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: registerPulseLengthCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_registerPulseLengthCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterDIOPulseLengthCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: cancelPulseLengthCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_cancelPulseLengthCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelDIOPulseLengthCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: getPulseLength
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_getPulseLength
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetDIOPulseLength(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: setPulseLength
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_setPulseLength
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetDIOPulseLength(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: registerIsInputCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_registerIsInputCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterDIOIsInputCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: cancelIsInputCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_cancelIsInputCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelDIOIsInputCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: getIsInput
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_getIsInput
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetDIOIsInput(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: setIsInput
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_setIsInput
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetDIOIsInput(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: registerFilterIndexCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_registerFilterIndexCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterDIOFilterIndexCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: cancelFilterIndexCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_cancelFilterIndexCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelDIOFilterIndexCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: getFilterIndex
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_getFilterIndex
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetDIOFilterIndex(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: setFilterIndex
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_setFilterIndex
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetDIOFilterIndex(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DIODataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DIODataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetDIOData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/DigitalPWMDataJNI.cpp b/hal/src/main/native/sim/jni/DigitalPWMDataJNI.cpp
new file mode 100644
index 0000000..0800917
--- /dev/null
+++ b/hal/src/main/native/sim/jni/DigitalPWMDataJNI.cpp
@@ -0,0 +1,178 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI.h"
+#include "mockdata/DigitalPWMData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: registerInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_registerInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterDigitalPWMInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: cancelInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_cancelInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelDigitalPWMInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: getInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_getInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetDigitalPWMInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: setInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_setInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetDigitalPWMInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: registerDutyCycleCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_registerDutyCycleCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterDigitalPWMDutyCycleCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: cancelDutyCycleCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_cancelDutyCycleCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelDigitalPWMDutyCycleCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: getDutyCycle
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_getDutyCycle
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetDigitalPWMDutyCycle(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: setDutyCycle
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_setDutyCycle
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetDigitalPWMDutyCycle(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: registerPinCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_registerPinCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterDigitalPWMPinCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: cancelPinCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_cancelPinCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelDigitalPWMPinCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: getPin
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_getPin
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetDigitalPWMPin(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: setPin
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_setPin
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetDigitalPWMPin(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DigitalPWMDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetDigitalPWMData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/DriverStationDataJNI.cpp b/hal/src/main/native/sim/jni/DriverStationDataJNI.cpp
new file mode 100644
index 0000000..82433b3
--- /dev/null
+++ b/hal/src/main/native/sim/jni/DriverStationDataJNI.cpp
@@ -0,0 +1,481 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-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 <jni.h>
+
+#include <cstring>
+
+#include <wpi/jni_util.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI.h"
+#include "mockdata/DriverStationData.h"
+#include "mockdata/MockHooks.h"
+
+using namespace wpi::java;
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: registerEnabledCallback
+ * Signature: (Ljava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_registerEnabledCallback
+ (JNIEnv* env, jclass, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallbackNoIndex(
+ env, callback, initialNotify,
+ &HALSIM_RegisterDriverStationEnabledCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: cancelEnabledCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_cancelEnabledCallback
+ (JNIEnv* env, jclass, jint handle)
+{
+ return sim::FreeCallbackNoIndex(env, handle,
+ &HALSIM_CancelDriverStationEnabledCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: getEnabled
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_getEnabled
+ (JNIEnv*, jclass)
+{
+ return HALSIM_GetDriverStationEnabled();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: setEnabled
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_setEnabled
+ (JNIEnv*, jclass, jboolean value)
+{
+ HALSIM_SetDriverStationEnabled(value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: registerAutonomousCallback
+ * Signature: (Ljava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_registerAutonomousCallback
+ (JNIEnv* env, jclass, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallbackNoIndex(
+ env, callback, initialNotify,
+ &HALSIM_RegisterDriverStationAutonomousCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: cancelAutonomousCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_cancelAutonomousCallback
+ (JNIEnv* env, jclass, jint handle)
+{
+ return sim::FreeCallbackNoIndex(
+ env, handle, &HALSIM_CancelDriverStationAutonomousCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: getAutonomous
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_getAutonomous
+ (JNIEnv*, jclass)
+{
+ return HALSIM_GetDriverStationAutonomous();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: setAutonomous
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_setAutonomous
+ (JNIEnv*, jclass, jboolean value)
+{
+ HALSIM_SetDriverStationAutonomous(value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: registerTestCallback
+ * Signature: (Ljava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_registerTestCallback
+ (JNIEnv* env, jclass, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallbackNoIndex(
+ env, callback, initialNotify, &HALSIM_RegisterDriverStationTestCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: cancelTestCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_cancelTestCallback
+ (JNIEnv* env, jclass, jint handle)
+{
+ return sim::FreeCallbackNoIndex(env, handle,
+ &HALSIM_CancelDriverStationTestCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: getTest
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_getTest
+ (JNIEnv*, jclass)
+{
+ return HALSIM_GetDriverStationTest();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: setTest
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_setTest
+ (JNIEnv*, jclass, jboolean value)
+{
+ HALSIM_SetDriverStationTest(value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: registerEStopCallback
+ * Signature: (Ljava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_registerEStopCallback
+ (JNIEnv* env, jclass, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallbackNoIndex(
+ env, callback, initialNotify, &HALSIM_RegisterDriverStationEStopCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: cancelEStopCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_cancelEStopCallback
+ (JNIEnv* env, jclass, jint handle)
+{
+ return sim::FreeCallbackNoIndex(env, handle,
+ &HALSIM_CancelDriverStationEStopCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: getEStop
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_getEStop
+ (JNIEnv*, jclass)
+{
+ return HALSIM_GetDriverStationEStop();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: setEStop
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_setEStop
+ (JNIEnv*, jclass, jboolean value)
+{
+ HALSIM_SetDriverStationEStop(value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: registerFmsAttachedCallback
+ * Signature: (Ljava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_registerFmsAttachedCallback
+ (JNIEnv* env, jclass, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallbackNoIndex(
+ env, callback, initialNotify,
+ &HALSIM_RegisterDriverStationFmsAttachedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: cancelFmsAttachedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_cancelFmsAttachedCallback
+ (JNIEnv* env, jclass, jint handle)
+{
+ return sim::FreeCallbackNoIndex(
+ env, handle, &HALSIM_CancelDriverStationFmsAttachedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: getFmsAttached
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_getFmsAttached
+ (JNIEnv*, jclass)
+{
+ return HALSIM_GetDriverStationFmsAttached();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: setFmsAttached
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_setFmsAttached
+ (JNIEnv*, jclass, jboolean value)
+{
+ HALSIM_SetDriverStationFmsAttached(value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: registerDsAttachedCallback
+ * Signature: (Ljava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_registerDsAttachedCallback
+ (JNIEnv* env, jclass, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallbackNoIndex(
+ env, callback, initialNotify,
+ &HALSIM_RegisterDriverStationDsAttachedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: cancelDsAttachedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_cancelDsAttachedCallback
+ (JNIEnv* env, jclass, jint handle)
+{
+ return sim::FreeCallbackNoIndex(
+ env, handle, &HALSIM_CancelDriverStationDsAttachedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: getDsAttached
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_getDsAttached
+ (JNIEnv*, jclass)
+{
+ return HALSIM_GetDriverStationDsAttached();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: setDsAttached
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_setDsAttached
+ (JNIEnv*, jclass, jboolean value)
+{
+ HALSIM_SetDriverStationDsAttached(value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: setJoystickAxes
+ * Signature: (B[F)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_setJoystickAxes
+ (JNIEnv* env, jclass, jbyte joystickNum, jfloatArray axesArray)
+{
+ HAL_JoystickAxes axes;
+ {
+ wpi::java::JFloatArrayRef jArrayRef(env, axesArray);
+ auto arrayRef = jArrayRef.array();
+ auto arraySize = arrayRef.size();
+ int maxCount =
+ arraySize < HAL_kMaxJoystickAxes ? arraySize : HAL_kMaxJoystickAxes;
+ axes.count = maxCount;
+ for (int i = 0; i < maxCount; i++) {
+ axes.axes[i] = arrayRef[i];
+ }
+ }
+ HALSIM_SetJoystickAxes(joystickNum, &axes);
+ return;
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: setJoystickPOVs
+ * Signature: (B[S)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_setJoystickPOVs
+ (JNIEnv* env, jclass, jbyte joystickNum, jshortArray povsArray)
+{
+ HAL_JoystickPOVs povs;
+ {
+ wpi::java::JShortArrayRef jArrayRef(env, povsArray);
+ auto arrayRef = jArrayRef.array();
+ auto arraySize = arrayRef.size();
+ int maxCount =
+ arraySize < HAL_kMaxJoystickPOVs ? arraySize : HAL_kMaxJoystickPOVs;
+ povs.count = maxCount;
+ for (int i = 0; i < maxCount; i++) {
+ povs.povs[i] = arrayRef[i];
+ }
+ }
+ HALSIM_SetJoystickPOVs(joystickNum, &povs);
+ return;
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: setJoystickButtons
+ * Signature: (BII)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_setJoystickButtons
+ (JNIEnv* env, jclass, jbyte joystickNum, jint buttons, jint count)
+{
+ if (count > 32) {
+ count = 32;
+ }
+ HAL_JoystickButtons joystickButtons;
+ joystickButtons.count = count;
+ joystickButtons.buttons = buttons;
+ HALSIM_SetJoystickButtons(joystickNum, &joystickButtons);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: setMatchInfo
+ * Signature: (Ljava/lang/String;Ljava/lang/String;III)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_setMatchInfo
+ (JNIEnv* env, jclass, jstring eventName, jstring gameSpecificMessage,
+ jint matchNumber, jint replayNumber, jint matchType)
+{
+ JStringRef eventNameRef{env, eventName};
+ JStringRef gameSpecificMessageRef{env, gameSpecificMessage};
+
+ HAL_MatchInfo halMatchInfo;
+ std::snprintf(halMatchInfo.eventName, sizeof(halMatchInfo.eventName), "%s",
+ eventNameRef.c_str());
+ std::snprintf(reinterpret_cast<char*>(halMatchInfo.gameSpecificMessage),
+ sizeof(halMatchInfo.gameSpecificMessage), "%s",
+ gameSpecificMessageRef.c_str());
+ halMatchInfo.gameSpecificMessageSize = gameSpecificMessageRef.size();
+ halMatchInfo.matchType = (HAL_MatchType)matchType;
+ halMatchInfo.matchNumber = matchNumber;
+ halMatchInfo.replayNumber = replayNumber;
+ HALSIM_SetMatchInfo(&halMatchInfo);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: registerAllCallbacks
+ * Signature: (Ljava/lang/Object;Z)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_registerAllCallbacks
+ (JNIEnv* env, jclass, jobject callback, jboolean initialNotify)
+{
+ sim::AllocateCallbackNoIndex(
+ env, callback, initialNotify,
+ [](HAL_NotifyCallback cb, void* param, HAL_Bool in) {
+ HALSIM_RegisterDriverStationAllCallbacks(cb, param, in);
+ return 0;
+ });
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: notifyNewData
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_notifyNewData
+ (JNIEnv*, jclass)
+{
+ HALSIM_NotifyDriverStationNewData();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: setSendError
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_setSendError
+ (JNIEnv*, jclass, jboolean shouldSend)
+{
+ if (shouldSend) {
+ HALSIM_SetSendError(nullptr);
+ } else {
+ HALSIM_SetSendError([](HAL_Bool isError, int32_t errorCode,
+ HAL_Bool isLVCode, const char* details,
+ const char* location, const char* callStack,
+ HAL_Bool printMsg) { return 1; });
+ }
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI
+ * Method: resetData
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI_resetData
+ (JNIEnv*, jclass)
+{
+ HALSIM_ResetDriverStationData();
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/DutyCycleDataJNI.cpp b/hal/src/main/native/sim/jni/DutyCycleDataJNI.cpp
new file mode 100644
index 0000000..d746ce1
--- /dev/null
+++ b/hal/src/main/native/sim/jni/DutyCycleDataJNI.cpp
@@ -0,0 +1,178 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI.h"
+#include "mockdata/DutyCycleData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: registerInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_registerInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterDutyCycleInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: cancelInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_cancelInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelDutyCycleInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: getInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_getInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetDutyCycleInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: setInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_setInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetDutyCycleInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: registerFrequencyCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_registerFrequencyCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterDutyCycleFrequencyCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: cancelFrequencyCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_cancelFrequencyCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelDutyCycleFrequencyCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: getFrequency
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_getFrequency
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetDutyCycleFrequency(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: setFrequency
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_setFrequency
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetDutyCycleFrequency(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: registerOutputCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_registerOutputCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterDutyCycleOutputCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: cancelOutputCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_cancelOutputCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelDutyCycleOutputCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: getOutput
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_getOutput
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetDutyCycleOutput(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: setOutput
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_setOutput
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetDutyCycleOutput(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_DutyCycleDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetDutyCycleData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/EncoderDataJNI.cpp b/hal/src/main/native/sim/jni/EncoderDataJNI.cpp
new file mode 100644
index 0000000..8992b0c
--- /dev/null
+++ b/hal/src/main/native/sim/jni/EncoderDataJNI.cpp
@@ -0,0 +1,428 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_EncoderDataJNI.h"
+#include "mockdata/EncoderData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: registerInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_registerInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterEncoderInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: cancelInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_cancelInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelEncoderInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: getInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_getInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetEncoderInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: setInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_setInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetEncoderInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: registerCountCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_registerCountCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterEncoderCountCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: cancelCountCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_cancelCountCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelEncoderCountCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: getCount
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_getCount
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetEncoderCount(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: setCount
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_setCount
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetEncoderCount(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: registerPeriodCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_registerPeriodCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterEncoderPeriodCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: cancelPeriodCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_cancelPeriodCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelEncoderPeriodCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: getPeriod
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_getPeriod
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetEncoderPeriod(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: setPeriod
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_setPeriod
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetEncoderPeriod(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: registerResetCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_registerResetCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterEncoderResetCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: cancelResetCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_cancelResetCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelEncoderResetCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: getReset
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_getReset
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetEncoderReset(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: setReset
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_setReset
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetEncoderReset(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: registerMaxPeriodCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_registerMaxPeriodCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterEncoderMaxPeriodCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: cancelMaxPeriodCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_cancelMaxPeriodCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelEncoderMaxPeriodCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: getMaxPeriod
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_getMaxPeriod
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetEncoderMaxPeriod(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: setMaxPeriod
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_setMaxPeriod
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetEncoderMaxPeriod(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: registerDirectionCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_registerDirectionCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterEncoderDirectionCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: cancelDirectionCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_cancelDirectionCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelEncoderDirectionCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: getDirection
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_getDirection
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetEncoderDirection(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: setDirection
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_setDirection
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetEncoderDirection(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: registerReverseDirectionCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_registerReverseDirectionCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterEncoderReverseDirectionCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: cancelReverseDirectionCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_cancelReverseDirectionCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelEncoderReverseDirectionCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: getReverseDirection
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_getReverseDirection
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetEncoderReverseDirection(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: setReverseDirection
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_setReverseDirection
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetEncoderReverseDirection(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: registerSamplesToAverageCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_registerSamplesToAverageCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterEncoderSamplesToAverageCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: cancelSamplesToAverageCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_cancelSamplesToAverageCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelEncoderSamplesToAverageCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: getSamplesToAverage
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_getSamplesToAverage
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetEncoderSamplesToAverage(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: setSamplesToAverage
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_setSamplesToAverage
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetEncoderSamplesToAverage(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_EncoderDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_EncoderDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetEncoderData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/I2CDataJNI.cpp b/hal/src/main/native/sim/jni/I2CDataJNI.cpp
new file mode 100644
index 0000000..14b3292
--- /dev/null
+++ b/hal/src/main/native/sim/jni/I2CDataJNI.cpp
@@ -0,0 +1,131 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "BufferCallbackStore.h"
+#include "CallbackStore.h"
+#include "ConstBufferCallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_I2CDataJNI.h"
+#include "mockdata/I2CData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_I2CDataJNI
+ * Method: registerInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_I2CDataJNI_registerInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterI2CInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_I2CDataJNI
+ * Method: cancelInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_I2CDataJNI_cancelInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelI2CInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_I2CDataJNI
+ * Method: getInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_I2CDataJNI_getInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetI2CInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_I2CDataJNI
+ * Method: setInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_I2CDataJNI_setInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetI2CInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_I2CDataJNI
+ * Method: registerReadCallback
+ * Signature: (ILjava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_I2CDataJNI_registerReadCallback
+ (JNIEnv* env, jclass, jint index, jobject callback)
+{
+ return sim::AllocateBufferCallback(env, index, callback,
+ &HALSIM_RegisterI2CReadCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_I2CDataJNI
+ * Method: cancelReadCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_I2CDataJNI_cancelReadCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ sim::FreeBufferCallback(env, handle, index, &HALSIM_CancelI2CReadCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_I2CDataJNI
+ * Method: registerWriteCallback
+ * Signature: (ILjava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_I2CDataJNI_registerWriteCallback
+ (JNIEnv* env, jclass, jint index, jobject callback)
+{
+ return sim::AllocateConstBufferCallback(env, index, callback,
+ &HALSIM_RegisterI2CWriteCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_I2CDataJNI
+ * Method: cancelWriteCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_I2CDataJNI_cancelWriteCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ sim::FreeConstBufferCallback(env, handle, index,
+ &HALSIM_CancelI2CWriteCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_I2CDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_I2CDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetI2CData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/NotifierDataJNI.cpp b/hal/src/main/native/sim/jni/NotifierDataJNI.cpp
new file mode 100644
index 0000000..b59b6e0
--- /dev/null
+++ b/hal/src/main/native/sim/jni/NotifierDataJNI.cpp
@@ -0,0 +1,37 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "edu_wpi_first_hal_sim_mockdata_NotifierDataJNI.h"
+#include "mockdata/NotifierData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_NotifierDataJNI
+ * Method: getNextTimeout
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_NotifierDataJNI_getNextTimeout
+ (JNIEnv*, jclass)
+{
+ return HALSIM_GetNextNotifierTimeout();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_NotifierDataJNI
+ * Method: getNumNotifiers
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_NotifierDataJNI_getNumNotifiers
+ (JNIEnv*, jclass)
+{
+ return HALSIM_GetNumNotifiers();
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/PCMDataJNI.cpp b/hal/src/main/native/sim/jni/PCMDataJNI.cpp
new file mode 100644
index 0000000..de6f738
--- /dev/null
+++ b/hal/src/main/native/sim/jni/PCMDataJNI.cpp
@@ -0,0 +1,419 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_PCMDataJNI.h"
+#include "mockdata/PCMData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: registerSolenoidInitializedCallback
+ * Signature: (IILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_registerSolenoidInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint channel, jobject callback,
+ jboolean initialNotify)
+{
+ return sim::AllocateChannelCallback(
+ env, index, channel, callback, initialNotify,
+ &HALSIM_RegisterPCMSolenoidInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: cancelSolenoidInitializedCallback
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_cancelSolenoidInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint channel, jint handle)
+{
+ return sim::FreeChannelCallback(env, handle, index, channel,
+ &HALSIM_CancelPCMSolenoidInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: getSolenoidInitialized
+ * Signature: (II)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_getSolenoidInitialized
+ (JNIEnv*, jclass, jint index, jint channel)
+{
+ return HALSIM_GetPCMSolenoidInitialized(index, channel);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: setSolenoidInitialized
+ * Signature: (IIZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_setSolenoidInitialized
+ (JNIEnv*, jclass, jint index, jint channel, jboolean value)
+{
+ HALSIM_SetPCMSolenoidInitialized(index, channel, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: registerSolenoidOutputCallback
+ * Signature: (IILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_registerSolenoidOutputCallback
+ (JNIEnv* env, jclass, jint index, jint channel, jobject callback,
+ jboolean initialNotify)
+{
+ return sim::AllocateChannelCallback(
+ env, index, channel, callback, initialNotify,
+ &HALSIM_RegisterPCMSolenoidOutputCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: cancelSolenoidOutputCallback
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_cancelSolenoidOutputCallback
+ (JNIEnv* env, jclass, jint index, jint channel, jint handle)
+{
+ return sim::FreeChannelCallback(env, handle, index, channel,
+ &HALSIM_CancelPCMSolenoidOutputCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: getSolenoidOutput
+ * Signature: (II)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_getSolenoidOutput
+ (JNIEnv*, jclass, jint index, jint channel)
+{
+ return HALSIM_GetPCMSolenoidOutput(index, channel);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: setSolenoidOutput
+ * Signature: (IIZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_setSolenoidOutput
+ (JNIEnv*, jclass, jint index, jint channel, jboolean value)
+{
+ HALSIM_SetPCMSolenoidOutput(index, channel, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: registerCompressorInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_registerCompressorInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(
+ env, index, callback, initialNotify,
+ &HALSIM_RegisterPCMCompressorInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: cancelCompressorInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_cancelCompressorInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPCMCompressorInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: getCompressorInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_getCompressorInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPCMCompressorInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: setCompressorInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_setCompressorInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetPCMCompressorInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: registerCompressorOnCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_registerCompressorOnCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPCMCompressorOnCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: cancelCompressorOnCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_cancelCompressorOnCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPCMCompressorOnCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: getCompressorOn
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_getCompressorOn
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPCMCompressorOn(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: setCompressorOn
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_setCompressorOn
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetPCMCompressorOn(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: registerClosedLoopEnabledCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_registerClosedLoopEnabledCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPCMClosedLoopEnabledCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: cancelClosedLoopEnabledCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_cancelClosedLoopEnabledCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPCMClosedLoopEnabledCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: getClosedLoopEnabled
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_getClosedLoopEnabled
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPCMClosedLoopEnabled(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: setClosedLoopEnabled
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_setClosedLoopEnabled
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetPCMClosedLoopEnabled(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: registerPressureSwitchCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_registerPressureSwitchCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPCMPressureSwitchCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: cancelPressureSwitchCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_cancelPressureSwitchCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPCMPressureSwitchCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: getPressureSwitch
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_getPressureSwitch
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPCMPressureSwitch(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: setPressureSwitch
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_setPressureSwitch
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetPCMPressureSwitch(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: registerCompressorCurrentCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_registerCompressorCurrentCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPCMCompressorCurrentCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: cancelCompressorCurrentCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_cancelCompressorCurrentCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPCMCompressorCurrentCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: getCompressorCurrent
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_getCompressorCurrent
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPCMCompressorCurrent(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: setCompressorCurrent
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_setCompressorCurrent
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetPCMCompressorCurrent(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: registerAllNonSolenoidCallbacks
+ * Signature: (ILjava/lang/Object;Z)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_registerAllNonSolenoidCallbacks
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ sim::AllocateCallback(
+ env, index, callback, initialNotify,
+ [](int32_t index, HAL_NotifyCallback cb, void* param, HAL_Bool in) {
+ HALSIM_RegisterPCMAllNonSolenoidCallbacks(index, cb, param, in);
+ return 0;
+ });
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: registerAllSolenoidCallbacks
+ * Signature: (IILjava/lang/Object;Z)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_registerAllSolenoidCallbacks
+ (JNIEnv* env, jclass, jint index, jint channel, jobject callback,
+ jboolean initialNotify)
+{
+ sim::AllocateChannelCallback(
+ env, index, channel, callback, initialNotify,
+ [](int32_t index, int32_t channel, HAL_NotifyCallback cb, void* param,
+ HAL_Bool in) {
+ HALSIM_RegisterPCMAllSolenoidCallbacks(index, channel, cb, param, in);
+ return 0;
+ });
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PCMDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PCMDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetPCMData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/PDPDataJNI.cpp b/hal/src/main/native/sim/jni/PDPDataJNI.cpp
new file mode 100644
index 0000000..5d39e87
--- /dev/null
+++ b/hal/src/main/native/sim/jni/PDPDataJNI.cpp
@@ -0,0 +1,230 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_PDPDataJNI.h"
+#include "mockdata/PDPData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: registerInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_registerInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPDPInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: cancelInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_cancelInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPDPInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: getInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_getInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPDPInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: setInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_setInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetPDPInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: registerTemperatureCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_registerTemperatureCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPDPTemperatureCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: cancelTemperatureCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_cancelTemperatureCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPDPTemperatureCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: getTemperature
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_getTemperature
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPDPTemperature(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: setTemperature
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_setTemperature
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetPDPTemperature(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: registerVoltageCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_registerVoltageCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPDPVoltageCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: cancelVoltageCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_cancelVoltageCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPDPVoltageCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: getVoltage
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_getVoltage
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPDPVoltage(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: setVoltage
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_setVoltage
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetPDPVoltage(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: registerCurrentCallback
+ * Signature: (IILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_registerCurrentCallback
+ (JNIEnv* env, jclass, jint index, jint channel, jobject callback,
+ jboolean initialNotify)
+{
+ return sim::AllocateChannelCallback(env, index, channel, callback,
+ initialNotify,
+ &HALSIM_RegisterPDPCurrentCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: cancelCurrentCallback
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_cancelCurrentCallback
+ (JNIEnv* env, jclass, jint index, jint channel, jint handle)
+{
+ return sim::FreeChannelCallback(env, handle, index, channel,
+ &HALSIM_CancelPDPCurrentCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: getCurrent
+ * Signature: (II)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_getCurrent
+ (JNIEnv*, jclass, jint index, jint channel)
+{
+ return HALSIM_GetPDPCurrent(index, channel);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: setCurrent
+ * Signature: (IID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_setCurrent
+ (JNIEnv*, jclass, jint index, jint channel, jdouble value)
+{
+ HALSIM_SetPDPCurrent(index, channel, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PDPDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PDPDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetPDPData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/PWMDataJNI.cpp b/hal/src/main/native/sim/jni/PWMDataJNI.cpp
new file mode 100644
index 0000000..b8a7c41
--- /dev/null
+++ b/hal/src/main/native/sim/jni/PWMDataJNI.cpp
@@ -0,0 +1,327 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_PWMDataJNI.h"
+#include "mockdata/PWMData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: registerInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_registerInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPWMInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: cancelInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_cancelInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPWMInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: getInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_getInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPWMInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: setInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_setInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetPWMInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: registerRawValueCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_registerRawValueCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPWMRawValueCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: cancelRawValueCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_cancelRawValueCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPWMRawValueCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: getRawValue
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_getRawValue
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPWMRawValue(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: setRawValue
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_setRawValue
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetPWMRawValue(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: registerSpeedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_registerSpeedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPWMSpeedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: cancelSpeedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_cancelSpeedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index, &HALSIM_CancelPWMSpeedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: getSpeed
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_getSpeed
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPWMSpeed(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: setSpeed
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_setSpeed
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetPWMSpeed(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: registerPositionCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_registerPositionCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPWMPositionCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: cancelPositionCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_cancelPositionCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPWMPositionCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: getPosition
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_getPosition
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPWMPosition(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: setPosition
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_setPosition
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetPWMPosition(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: registerPeriodScaleCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_registerPeriodScaleCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPWMPeriodScaleCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: cancelPeriodScaleCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_cancelPeriodScaleCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPWMPeriodScaleCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: getPeriodScale
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_getPeriodScale
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPWMPeriodScale(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: setPeriodScale
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_setPeriodScale
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetPWMPeriodScale(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: registerZeroLatchCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_registerZeroLatchCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterPWMZeroLatchCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: cancelZeroLatchCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_cancelZeroLatchCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelPWMZeroLatchCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: getZeroLatch
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_getZeroLatch
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetPWMZeroLatch(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: setZeroLatch
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_setZeroLatch
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetPWMZeroLatch(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_PWMDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_PWMDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetPWMData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/RelayDataJNI.cpp b/hal/src/main/native/sim/jni/RelayDataJNI.cpp
new file mode 100644
index 0000000..bf85407
--- /dev/null
+++ b/hal/src/main/native/sim/jni/RelayDataJNI.cpp
@@ -0,0 +1,228 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_RelayDataJNI.h"
+#include "mockdata/RelayData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: registerInitializedForwardCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_registerInitializedForwardCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRelayInitializedForwardCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: cancelInitializedForwardCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_cancelInitializedForwardCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRelayInitializedForwardCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: getInitializedForward
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_getInitializedForward
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRelayInitializedForward(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: setInitializedForward
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_setInitializedForward
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetRelayInitializedForward(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: registerInitializedReverseCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_registerInitializedReverseCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRelayInitializedReverseCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: cancelInitializedReverseCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_cancelInitializedReverseCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRelayInitializedReverseCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: getInitializedReverse
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_getInitializedReverse
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRelayInitializedReverse(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: setInitializedReverse
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_setInitializedReverse
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetRelayInitializedReverse(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: registerForwardCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_registerForwardCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRelayForwardCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: cancelForwardCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_cancelForwardCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRelayForwardCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: getForward
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_getForward
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRelayForward(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: setForward
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_setForward
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetRelayForward(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: registerReverseCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_registerReverseCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRelayReverseCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: cancelReverseCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_cancelReverseCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRelayReverseCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: getReverse
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_getReverse
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRelayReverse(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: setReverse
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_setReverse
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetRelayReverse(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RelayDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RelayDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetRelayData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/RoboRioDataJNI.cpp b/hal/src/main/native/sim/jni/RoboRioDataJNI.cpp
new file mode 100644
index 0000000..d69e895
--- /dev/null
+++ b/hal/src/main/native/sim/jni/RoboRioDataJNI.cpp
@@ -0,0 +1,778 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI.h"
+#include "mockdata/RoboRioData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerFPGAButtonCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerFPGAButtonCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioFPGAButtonCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelFPGAButtonCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelFPGAButtonCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioFPGAButtonCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getFPGAButton
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getFPGAButton
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioFPGAButton(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setFPGAButton
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setFPGAButton
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetRoboRioFPGAButton(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerVInVoltageCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerVInVoltageCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioVInVoltageCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelVInVoltageCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelVInVoltageCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioVInVoltageCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getVInVoltage
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getVInVoltage
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioVInVoltage(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setVInVoltage
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setVInVoltage
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetRoboRioVInVoltage(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerVInCurrentCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerVInCurrentCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioVInCurrentCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelVInCurrentCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelVInCurrentCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioVInCurrentCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getVInCurrent
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getVInCurrent
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioVInCurrent(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setVInCurrent
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setVInCurrent
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetRoboRioVInCurrent(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerUserVoltage6VCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerUserVoltage6VCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioUserVoltage6VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelUserVoltage6VCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelUserVoltage6VCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioUserVoltage6VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getUserVoltage6V
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getUserVoltage6V
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioUserVoltage6V(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setUserVoltage6V
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setUserVoltage6V
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetRoboRioUserVoltage6V(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerUserCurrent6VCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerUserCurrent6VCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioUserCurrent6VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelUserCurrent6VCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelUserCurrent6VCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioUserCurrent6VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getUserCurrent6V
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getUserCurrent6V
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioUserCurrent6V(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setUserCurrent6V
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setUserCurrent6V
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetRoboRioUserCurrent6V(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerUserActive6VCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerUserActive6VCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioUserActive6VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelUserActive6VCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelUserActive6VCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioUserActive6VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getUserActive6V
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getUserActive6V
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioUserActive6V(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setUserActive6V
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setUserActive6V
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetRoboRioUserActive6V(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerUserVoltage5VCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerUserVoltage5VCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioUserVoltage5VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelUserVoltage5VCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelUserVoltage5VCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioUserVoltage5VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getUserVoltage5V
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getUserVoltage5V
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioUserVoltage5V(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setUserVoltage5V
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setUserVoltage5V
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetRoboRioUserVoltage5V(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerUserCurrent5VCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerUserCurrent5VCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioUserCurrent5VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelUserCurrent5VCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelUserCurrent5VCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioUserCurrent5VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getUserCurrent5V
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getUserCurrent5V
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioUserCurrent5V(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setUserCurrent5V
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setUserCurrent5V
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetRoboRioUserCurrent5V(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerUserActive5VCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerUserActive5VCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioUserActive5VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelUserActive5VCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelUserActive5VCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioUserActive5VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getUserActive5V
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getUserActive5V
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioUserActive5V(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setUserActive5V
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setUserActive5V
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetRoboRioUserActive5V(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerUserVoltage3V3Callback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerUserVoltage3V3Callback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioUserVoltage3V3Callback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelUserVoltage3V3Callback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelUserVoltage3V3Callback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioUserVoltage3V3Callback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getUserVoltage3V3
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getUserVoltage3V3
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioUserVoltage3V3(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setUserVoltage3V3
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setUserVoltage3V3
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetRoboRioUserVoltage3V3(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerUserCurrent3V3Callback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerUserCurrent3V3Callback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioUserCurrent3V3Callback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelUserCurrent3V3Callback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelUserCurrent3V3Callback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioUserCurrent3V3Callback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getUserCurrent3V3
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getUserCurrent3V3
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioUserCurrent3V3(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setUserCurrent3V3
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setUserCurrent3V3
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetRoboRioUserCurrent3V3(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerUserActive3V3Callback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerUserActive3V3Callback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioUserActive3V3Callback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelUserActive3V3Callback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelUserActive3V3Callback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioUserActive3V3Callback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getUserActive3V3
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getUserActive3V3
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioUserActive3V3(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setUserActive3V3
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setUserActive3V3
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetRoboRioUserActive3V3(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerUserFaults6VCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerUserFaults6VCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioUserFaults6VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelUserFaults6VCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelUserFaults6VCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioUserFaults6VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getUserFaults6V
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getUserFaults6V
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioUserFaults6V(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setUserFaults6V
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setUserFaults6V
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetRoboRioUserFaults6V(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerUserFaults5VCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerUserFaults5VCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioUserFaults5VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelUserFaults5VCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelUserFaults5VCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioUserFaults5VCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getUserFaults5V
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getUserFaults5V
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioUserFaults5V(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setUserFaults5V
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setUserFaults5V
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetRoboRioUserFaults5V(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: registerUserFaults3V3Callback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_registerUserFaults3V3Callback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterRoboRioUserFaults3V3Callback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: cancelUserFaults3V3Callback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_cancelUserFaults3V3Callback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelRoboRioUserFaults3V3Callback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: getUserFaults3V3
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_getUserFaults3V3
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetRoboRioUserFaults3V3(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: setUserFaults3V3
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_setUserFaults3V3
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetRoboRioUserFaults3V3(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_RoboRioDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetRoboRioData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/SPIAccelerometerDataJNI.cpp b/hal/src/main/native/sim/jni/SPIAccelerometerDataJNI.cpp
new file mode 100644
index 0000000..ca12f79
--- /dev/null
+++ b/hal/src/main/native/sim/jni/SPIAccelerometerDataJNI.cpp
@@ -0,0 +1,278 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI.h"
+#include "mockdata/SPIAccelerometerData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: registerActiveCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_registerActiveCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterSPIAccelerometerActiveCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: cancelActiveCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_cancelActiveCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelSPIAccelerometerActiveCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: getActive
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_getActive
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetSPIAccelerometerActive(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: setActive
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_setActive
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetSPIAccelerometerActive(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: registerRangeCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_registerRangeCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterSPIAccelerometerRangeCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: cancelRangeCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_cancelRangeCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelSPIAccelerometerRangeCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: getRange
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_getRange
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetSPIAccelerometerRange(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: setRange
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_setRange
+ (JNIEnv*, jclass, jint index, jint value)
+{
+ HALSIM_SetSPIAccelerometerRange(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: registerXCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_registerXCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterSPIAccelerometerXCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: cancelXCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_cancelXCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelSPIAccelerometerXCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: getX
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_getX
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetSPIAccelerometerX(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: setX
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_setX
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetSPIAccelerometerX(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: registerYCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_registerYCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterSPIAccelerometerYCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: cancelYCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_cancelYCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelSPIAccelerometerYCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: getY
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_getY
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetSPIAccelerometerY(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: setY
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_setY
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetSPIAccelerometerY(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: registerZCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_registerZCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterSPIAccelerometerZCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: cancelZCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_cancelZCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelSPIAccelerometerZCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: getZ
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_getZ
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetSPIAccelerometerZ(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: setZ
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_setZ
+ (JNIEnv*, jclass, jint index, jdouble value)
+{
+ HALSIM_SetSPIAccelerometerZ(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIAccelerometerDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetSPIAccelerometerData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/SPIDataJNI.cpp b/hal/src/main/native/sim/jni/SPIDataJNI.cpp
new file mode 100644
index 0000000..4eb342c
--- /dev/null
+++ b/hal/src/main/native/sim/jni/SPIDataJNI.cpp
@@ -0,0 +1,158 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 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 <jni.h>
+
+#include "BufferCallbackStore.h"
+#include "CallbackStore.h"
+#include "ConstBufferCallbackStore.h"
+#include "SpiReadAutoReceiveBufferCallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_SPIDataJNI.h"
+#include "mockdata/SPIData.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIDataJNI
+ * Method: registerInitializedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIDataJNI_registerInitializedCallback
+ (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
+{
+ return sim::AllocateCallback(env, index, callback, initialNotify,
+ &HALSIM_RegisterSPIInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIDataJNI
+ * Method: cancelInitializedCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIDataJNI_cancelInitializedCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ return sim::FreeCallback(env, handle, index,
+ &HALSIM_CancelSPIInitializedCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIDataJNI
+ * Method: getInitialized
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIDataJNI_getInitialized
+ (JNIEnv*, jclass, jint index)
+{
+ return HALSIM_GetSPIInitialized(index);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIDataJNI
+ * Method: setInitialized
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIDataJNI_setInitialized
+ (JNIEnv*, jclass, jint index, jboolean value)
+{
+ HALSIM_SetSPIInitialized(index, value);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIDataJNI
+ * Method: registerReadCallback
+ * Signature: (ILjava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIDataJNI_registerReadCallback
+ (JNIEnv* env, jclass, jint index, jobject callback)
+{
+ return sim::AllocateBufferCallback(env, index, callback,
+ &HALSIM_RegisterSPIReadCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIDataJNI
+ * Method: cancelReadCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIDataJNI_cancelReadCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ sim::FreeBufferCallback(env, handle, index, &HALSIM_CancelSPIReadCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIDataJNI
+ * Method: registerWriteCallback
+ * Signature: (ILjava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIDataJNI_registerWriteCallback
+ (JNIEnv* env, jclass, jint index, jobject callback)
+{
+ return sim::AllocateConstBufferCallback(env, index, callback,
+ &HALSIM_RegisterSPIWriteCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIDataJNI
+ * Method: cancelWriteCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIDataJNI_cancelWriteCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ sim::FreeConstBufferCallback(env, handle, index,
+ &HALSIM_CancelSPIWriteCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIDataJNI
+ * Method: registerReadAutoReceiveBufferCallback
+ * Signature: (ILjava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIDataJNI_registerReadAutoReceiveBufferCallback
+ (JNIEnv* env, jclass, jint index, jobject callback)
+{
+ return sim::AllocateSpiBufferCallback(
+ env, index, callback, &HALSIM_RegisterSPIReadAutoReceivedDataCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIDataJNI
+ * Method: cancelReadAutoReceiveBufferCallback
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIDataJNI_cancelReadAutoReceiveBufferCallback
+ (JNIEnv* env, jclass, jint index, jint handle)
+{
+ sim::FreeSpiBufferCallback(env, handle, index,
+ &HALSIM_CancelSPIReadAutoReceivedDataCallback);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SPIDataJNI
+ * Method: resetData
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SPIDataJNI_resetData
+ (JNIEnv*, jclass, jint index)
+{
+ HALSIM_ResetSPIData(index);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/SimDeviceDataJNI.cpp b/hal/src/main/native/sim/jni/SimDeviceDataJNI.cpp
new file mode 100644
index 0000000..f6cd05e
--- /dev/null
+++ b/hal/src/main/native/sim/jni/SimDeviceDataJNI.cpp
@@ -0,0 +1,573 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "SimDeviceDataJNI.h"
+
+#include <jni.h>
+
+#include <functional>
+#include <string>
+#include <utility>
+
+#include <wpi/UidVector.h>
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI.h"
+#include "mockdata/SimDeviceData.h"
+
+using namespace wpi::java;
+
+static JClass simDeviceInfoCls;
+static JClass simValueInfoCls;
+static JClass simDeviceCallbackCls;
+static JClass simValueCallbackCls;
+static jmethodID simDeviceCallbackCallback;
+static jmethodID simValueCallbackCallback;
+
+namespace {
+
+struct DeviceInfo {
+ DeviceInfo(const char* name_, HAL_SimDeviceHandle handle_)
+ : name{name_}, handle{handle_} {}
+ std::string name;
+ HAL_SimValueHandle handle;
+
+ jobject MakeJava(JNIEnv* env) const;
+ void CallJava(JNIEnv* env, jobject callobj) const;
+};
+
+struct ValueInfo {
+ ValueInfo(const char* name_, HAL_SimValueHandle handle_, bool readonly_,
+ const HAL_Value& value_)
+ : name{name_}, handle{handle_}, readonly{readonly_}, value{value_} {}
+ std::string name;
+ HAL_SimValueHandle handle;
+ bool readonly;
+ HAL_Value value;
+
+ jobject MakeJava(JNIEnv* env) const;
+ void CallJava(JNIEnv* env, jobject callobj) const;
+
+ private:
+ std::pair<jlong, jdouble> ToValue12() const;
+};
+
+} // namespace
+
+jobject DeviceInfo::MakeJava(JNIEnv* env) const {
+ static jmethodID func =
+ env->GetMethodID(simDeviceInfoCls, "<init>", "(Ljava/lang/String;I)V");
+ return env->NewObject(simDeviceInfoCls, func, MakeJString(env, name),
+ (jint)handle);
+}
+
+void DeviceInfo::CallJava(JNIEnv* env, jobject callobj) const {
+ env->CallVoidMethod(callobj, simDeviceCallbackCallback,
+ MakeJString(env, name), (jint)handle);
+}
+
+std::pair<jlong, jdouble> ValueInfo::ToValue12() const {
+ jlong value1 = 0;
+ jdouble value2 = 0.0;
+ switch (value.type) {
+ case HAL_BOOLEAN:
+ value1 = value.data.v_boolean;
+ break;
+ case HAL_DOUBLE:
+ value2 = value.data.v_double;
+ break;
+ case HAL_ENUM:
+ value1 = value.data.v_enum;
+ break;
+ case HAL_INT:
+ value1 = value.data.v_int;
+ break;
+ case HAL_LONG:
+ value1 = value.data.v_long;
+ break;
+ default:
+ break;
+ }
+ return std::pair(value1, value2);
+}
+
+jobject ValueInfo::MakeJava(JNIEnv* env) const {
+ static jmethodID func =
+ env->GetMethodID(simValueInfoCls, "<init>", "(Ljava/lang/String;IZIJD)V");
+ auto [value1, value2] = ToValue12();
+ return env->NewObject(simValueInfoCls, func, MakeJString(env, name),
+ (jint)handle, (jboolean)readonly, (jint)value.type,
+ value1, value2);
+}
+
+void ValueInfo::CallJava(JNIEnv* env, jobject callobj) const {
+ auto [value1, value2] = ToValue12();
+ env->CallVoidMethod(callobj, simValueCallbackCallback, MakeJString(env, name),
+ (jint)handle, (jboolean)readonly, (jint)value.type,
+ value1, value2);
+}
+
+namespace {
+
+class CallbackStore {
+ public:
+ explicit CallbackStore(JNIEnv* env, jobject obj) : m_call{env, obj} {}
+ ~CallbackStore() {
+ if (m_cancelCallback) m_cancelCallback();
+ }
+
+ void SetCancel(std::function<void()> cancelCallback) {
+ m_cancelCallback = std::move(cancelCallback);
+ }
+ void Free(JNIEnv* env) { m_call.free(env); }
+ jobject Get() const { return m_call; }
+
+ private:
+ wpi::java::JGlobal<jobject> m_call;
+ std::function<void()> m_cancelCallback;
+};
+
+class CallbackThreadJNI : public wpi::SafeThread {
+ public:
+ void Main();
+
+ using DeviceCalls =
+ std::vector<std::pair<std::weak_ptr<CallbackStore>, DeviceInfo>>;
+ DeviceCalls m_deviceCalls;
+ using ValueCalls =
+ std::vector<std::pair<std::weak_ptr<CallbackStore>, ValueInfo>>;
+ ValueCalls m_valueCalls;
+
+ wpi::UidVector<std::shared_ptr<CallbackStore>, 4> m_callbacks;
+};
+
+class CallbackJNI {
+ public:
+ static CallbackJNI& GetInstance() {
+ static CallbackJNI inst;
+ return inst;
+ }
+ void SendDevice(int32_t callback, DeviceInfo info);
+ void SendValue(int32_t callback, ValueInfo info);
+
+ std::pair<int32_t, std::shared_ptr<CallbackStore>> AllocateCallback(
+ JNIEnv* env, jobject obj);
+
+ void FreeCallback(JNIEnv* env, int32_t uid);
+
+ private:
+ CallbackJNI() { m_owner.Start(); }
+
+ wpi::SafeThreadOwner<CallbackThreadJNI> m_owner;
+};
+
+} // namespace
+
+void CallbackThreadJNI::Main() {
+ JNIEnv* env;
+ JavaVMAttachArgs args;
+ args.version = JNI_VERSION_1_2;
+ args.name = const_cast<char*>("SimDeviceCallback");
+ args.group = nullptr;
+ jint rs = sim::GetJVM()->AttachCurrentThreadAsDaemon(
+ reinterpret_cast<void**>(&env), &args);
+ if (rs != JNI_OK) return;
+
+ DeviceCalls deviceCalls;
+ ValueCalls valueCalls;
+
+ std::unique_lock lock(m_mutex);
+ while (m_active) {
+ m_cond.wait(lock, [&] { return !m_active; });
+ if (!m_active) break;
+
+ deviceCalls.swap(m_deviceCalls);
+ valueCalls.swap(m_valueCalls);
+
+ lock.unlock(); // don't hold mutex during callback execution
+
+ for (auto&& call : deviceCalls) {
+ if (auto store = call.first.lock()) {
+ if (jobject callobj = store->Get()) {
+ call.second.CallJava(env, callobj);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ }
+ }
+ }
+
+ for (auto&& call : valueCalls) {
+ if (auto store = call.first.lock()) {
+ if (jobject callobj = store->Get()) {
+ call.second.CallJava(env, callobj);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ }
+ }
+ }
+
+ deviceCalls.clear();
+ valueCalls.clear();
+
+ lock.lock();
+ }
+
+ // free global references
+ for (auto&& callback : m_callbacks) callback->Free(env);
+
+ sim::GetJVM()->DetachCurrentThread();
+}
+
+void CallbackJNI::SendDevice(int32_t callback, DeviceInfo info) {
+ auto thr = m_owner.GetThread();
+ if (!thr) return;
+ thr->m_deviceCalls.emplace_back(thr->m_callbacks[callback], std::move(info));
+ thr->m_cond.notify_one();
+}
+
+void CallbackJNI::SendValue(int32_t callback, ValueInfo info) {
+ auto thr = m_owner.GetThread();
+ if (!thr) return;
+ thr->m_valueCalls.emplace_back(thr->m_callbacks[callback], std::move(info));
+ thr->m_cond.notify_one();
+}
+
+std::pair<int32_t, std::shared_ptr<CallbackStore>>
+CallbackJNI::AllocateCallback(JNIEnv* env, jobject obj) {
+ auto thr = m_owner.GetThread();
+ if (!thr) return std::pair(0, nullptr);
+ auto store = std::make_shared<CallbackStore>(env, obj);
+ return std::pair(thr->m_callbacks.emplace_back(store) + 1, store);
+}
+
+void CallbackJNI::FreeCallback(JNIEnv* env, int32_t uid) {
+ auto thr = m_owner.GetThread();
+ if (!thr) return;
+ if (uid <= 0 || static_cast<uint32_t>(uid) >= thr->m_callbacks.size()) return;
+ --uid;
+ auto store = std::move(thr->m_callbacks[uid]);
+ thr->m_callbacks.erase(uid);
+ store->Free(env);
+}
+
+namespace sim {
+
+bool InitializeSimDeviceDataJNI(JNIEnv* env) {
+ simDeviceInfoCls = JClass(
+ env, "edu/wpi/first/hal/sim/mockdata/SimDeviceDataJNI$SimDeviceInfo");
+ if (!simDeviceInfoCls) return false;
+
+ simValueInfoCls = JClass(
+ env, "edu/wpi/first/hal/sim/mockdata/SimDeviceDataJNI$SimValueInfo");
+ if (!simValueInfoCls) return false;
+
+ simDeviceCallbackCls = JClass(env, "edu/wpi/first/hal/sim/SimDeviceCallback");
+ if (!simDeviceCallbackCls) return false;
+
+ simDeviceCallbackCallback = env->GetMethodID(simDeviceCallbackCls, "callback",
+ "(Ljava/lang/String;I)V");
+ if (!simDeviceCallbackCallback) return false;
+
+ simValueCallbackCls = JClass(env, "edu/wpi/first/hal/sim/SimValueCallback");
+ if (!simValueCallbackCls) return false;
+
+ simValueCallbackCallback = env->GetMethodID(
+ simValueCallbackCls, "callbackNative", "(Ljava/lang/String;IZIJD)V");
+ if (!simValueCallbackCallback) return false;
+
+ return true;
+}
+
+void FreeSimDeviceDataJNI(JNIEnv* env) {
+ simDeviceInfoCls.free(env);
+ simValueInfoCls.free(env);
+ simDeviceCallbackCls.free(env);
+ simValueCallbackCls.free(env);
+}
+
+} // namespace sim
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: registerSimDeviceCreatedCallback
+ * Signature: (Ljava/lang/String;Ljava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_registerSimDeviceCreatedCallback
+ (JNIEnv* env, jclass, jstring prefix, jobject callback,
+ jboolean initialNotify)
+{
+ auto [uid, store] =
+ CallbackJNI::GetInstance().AllocateCallback(env, callback);
+ int32_t cuid = HALSIM_RegisterSimDeviceCreatedCallback(
+ JStringRef{env, prefix}.c_str(),
+ reinterpret_cast<void*>(static_cast<intptr_t>(uid)),
+ [](const char* name, void* param, HAL_SimDeviceHandle handle) {
+ int32_t uid = reinterpret_cast<intptr_t>(param);
+ CallbackJNI::GetInstance().SendDevice(uid, DeviceInfo{name, handle});
+ },
+ initialNotify);
+ store->SetCancel([cuid] { HALSIM_CancelSimDeviceCreatedCallback(cuid); });
+ return uid;
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: cancelSimDeviceCreatedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_cancelSimDeviceCreatedCallback
+ (JNIEnv* env, jclass, jint uid)
+{
+ CallbackJNI::GetInstance().FreeCallback(env, uid);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: registerSimDeviceFreedCallback
+ * Signature: (Ljava/lang/String;Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_registerSimDeviceFreedCallback
+ (JNIEnv* env, jclass, jstring prefix, jobject callback)
+{
+ auto [uid, store] =
+ CallbackJNI::GetInstance().AllocateCallback(env, callback);
+ int32_t cuid = HALSIM_RegisterSimDeviceFreedCallback(
+ JStringRef{env, prefix}.c_str(),
+ reinterpret_cast<void*>(static_cast<intptr_t>(uid)),
+ [](const char* name, void* param, HAL_SimDeviceHandle handle) {
+ int32_t uid = reinterpret_cast<intptr_t>(param);
+ CallbackJNI::GetInstance().SendDevice(uid, DeviceInfo{name, handle});
+ });
+ store->SetCancel([cuid] { HALSIM_CancelSimDeviceFreedCallback(cuid); });
+ return uid;
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: cancelSimDeviceFreedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_cancelSimDeviceFreedCallback
+ (JNIEnv* env, jclass, jint uid)
+{
+ CallbackJNI::GetInstance().FreeCallback(env, uid);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: getSimDeviceHandle
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_getSimDeviceHandle
+ (JNIEnv* env, jclass, jstring name)
+{
+ return HALSIM_GetSimDeviceHandle(JStringRef{env, name}.c_str());
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: getSimValueDeviceHandle
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_getSimValueDeviceHandle
+ (JNIEnv*, jclass, jint handle)
+{
+ return HALSIM_GetSimValueDeviceHandle(handle);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: enumerateSimDevices
+ * Signature: (Ljava/lang/String;)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_enumerateSimDevices
+ (JNIEnv* env, jclass, jstring prefix)
+{
+ // get values
+ std::vector<DeviceInfo> arr;
+ HALSIM_EnumerateSimDevices(
+ JStringRef{env, prefix}.c_str(), &arr,
+ [](const char* name, void* param, HAL_SimDeviceHandle handle) {
+ auto arr = static_cast<std::vector<DeviceInfo>*>(param);
+ arr->emplace_back(name, handle);
+ });
+
+ // convert to java
+ size_t numElems = arr.size();
+ jobjectArray jarr =
+ env->NewObjectArray(arr.size(), simDeviceInfoCls, nullptr);
+ if (!jarr) return nullptr;
+ for (size_t i = 0; i < numElems; ++i) {
+ JLocal<jobject> elem{env, arr[i].MakeJava(env)};
+ env->SetObjectArrayElement(jarr, i, elem.obj());
+ }
+ return jarr;
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: registerSimValueCreatedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_registerSimValueCreatedCallback
+ (JNIEnv* env, jclass, jint device, jobject callback, jboolean initialNotify)
+{
+ auto [uid, store] =
+ CallbackJNI::GetInstance().AllocateCallback(env, callback);
+ int32_t cuid = HALSIM_RegisterSimValueCreatedCallback(
+ device, reinterpret_cast<void*>(static_cast<intptr_t>(uid)),
+ [](const char* name, void* param, HAL_SimValueHandle handle,
+ HAL_Bool readonly, const HAL_Value* value) {
+ int32_t uid = reinterpret_cast<intptr_t>(param);
+ CallbackJNI::GetInstance().SendValue(
+ uid, ValueInfo{name, handle, static_cast<bool>(readonly), *value});
+ },
+ initialNotify);
+ store->SetCancel([cuid] { HALSIM_CancelSimValueCreatedCallback(cuid); });
+ return uid;
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: cancelSimValueCreatedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_cancelSimValueCreatedCallback
+ (JNIEnv* env, jclass, jint uid)
+{
+ CallbackJNI::GetInstance().FreeCallback(env, uid);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: registerSimValueChangedCallback
+ * Signature: (ILjava/lang/Object;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_registerSimValueChangedCallback
+ (JNIEnv* env, jclass, jint handle, jobject callback, jboolean initialNotify)
+{
+ auto [uid, store] =
+ CallbackJNI::GetInstance().AllocateCallback(env, callback);
+ int32_t cuid = HALSIM_RegisterSimValueChangedCallback(
+ handle, reinterpret_cast<void*>(static_cast<intptr_t>(uid)),
+ [](const char* name, void* param, HAL_SimValueHandle handle,
+ HAL_Bool readonly, const HAL_Value* value) {
+ int32_t uid = reinterpret_cast<intptr_t>(param);
+ CallbackJNI::GetInstance().SendValue(
+ uid, ValueInfo{name, handle, static_cast<bool>(readonly), *value});
+ },
+ initialNotify);
+ store->SetCancel([cuid] { HALSIM_CancelSimValueChangedCallback(cuid); });
+ return uid;
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: cancelSimValueChangedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_cancelSimValueChangedCallback
+ (JNIEnv* env, jclass, jint uid)
+{
+ CallbackJNI::GetInstance().FreeCallback(env, uid);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: getSimValueHandle
+ * Signature: (ILjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_getSimValueHandle
+ (JNIEnv* env, jclass, jint device, jstring name)
+{
+ return HALSIM_GetSimValueHandle(device, JStringRef{env, name}.c_str());
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: enumerateSimValues
+ * Signature: (I)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_enumerateSimValues
+ (JNIEnv* env, jclass, jint device)
+{
+ // get values
+ std::vector<ValueInfo> arr;
+ HALSIM_EnumerateSimValues(
+ device, &arr,
+ [](const char* name, void* param, HAL_SimValueHandle handle,
+ HAL_Bool readonly, const HAL_Value* value) {
+ auto arr = static_cast<std::vector<ValueInfo>*>(param);
+ arr->emplace_back(name, handle, readonly, *value);
+ });
+
+ // convert to java
+ size_t numElems = arr.size();
+ jobjectArray jarr = env->NewObjectArray(arr.size(), simValueInfoCls, nullptr);
+ if (!jarr) return nullptr;
+ for (size_t i = 0; i < numElems; ++i) {
+ JLocal<jobject> elem{env, arr[i].MakeJava(env)};
+ env->SetObjectArrayElement(jarr, i, elem.obj());
+ }
+ return jarr;
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: getSimValueEnumOptions
+ * Signature: (I)[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_getSimValueEnumOptions
+ (JNIEnv* env, jclass, jint handle)
+{
+ static JClass stringCls{env, "java/lang/String"};
+ if (!stringCls) return nullptr;
+ int32_t numElems = 0;
+ const char** elems = HALSIM_GetSimValueEnumOptions(handle, &numElems);
+ jobjectArray jarr = env->NewObjectArray(numElems, stringCls, nullptr);
+ if (!jarr) return nullptr;
+ for (int32_t i = 0; i < numElems; ++i) {
+ JLocal<jstring> elem{env, MakeJString(env, elems[i])};
+ env->SetObjectArrayElement(jarr, i, elem.obj());
+ }
+ return jarr;
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI
+ * Method: resetSimDeviceData
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimDeviceDataJNI_resetSimDeviceData
+ (JNIEnv*, jclass)
+{
+ HALSIM_ResetSimDeviceData();
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/SimDeviceDataJNI.h b/hal/src/main/native/sim/jni/SimDeviceDataJNI.h
new file mode 100644
index 0000000..56f6d9b
--- /dev/null
+++ b/hal/src/main/native/sim/jni/SimDeviceDataJNI.h
@@ -0,0 +1,15 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+namespace sim {
+bool InitializeSimDeviceDataJNI(JNIEnv* env);
+void FreeSimDeviceDataJNI(JNIEnv* env);
+} // namespace sim
diff --git a/hal/src/main/native/sim/jni/SimulatorJNI.cpp b/hal/src/main/native/sim/jni/SimulatorJNI.cpp
new file mode 100644
index 0000000..9226f91
--- /dev/null
+++ b/hal/src/main/native/sim/jni/SimulatorJNI.cpp
@@ -0,0 +1,204 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-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 "SimulatorJNI.h"
+
+#include <wpi/jni_util.h>
+
+#include "BufferCallbackStore.h"
+#include "CallbackStore.h"
+#include "ConstBufferCallbackStore.h"
+#include "SimDeviceDataJNI.h"
+#include "SpiReadAutoReceiveBufferCallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_SimulatorJNI.h"
+#include "hal/HAL.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/MockHooks.h"
+
+using namespace wpi::java;
+
+static JavaVM* jvm = nullptr;
+static JClass notifyCallbackCls;
+static JClass bufferCallbackCls;
+static JClass constBufferCallbackCls;
+static JClass spiReadAutoReceiveBufferCallbackCls;
+static jmethodID notifyCallbackCallback;
+static jmethodID bufferCallbackCallback;
+static jmethodID constBufferCallbackCallback;
+static jmethodID spiReadAutoReceiveBufferCallbackCallback;
+
+namespace sim {
+jint SimOnLoad(JavaVM* vm, void* reserved) {
+ jvm = vm;
+
+ JNIEnv* env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
+ return JNI_ERR;
+
+ notifyCallbackCls = JClass(env, "edu/wpi/first/hal/sim/NotifyCallback");
+ if (!notifyCallbackCls) return JNI_ERR;
+
+ notifyCallbackCallback = env->GetMethodID(notifyCallbackCls, "callbackNative",
+ "(Ljava/lang/String;IJD)V");
+ if (!notifyCallbackCallback) return JNI_ERR;
+
+ bufferCallbackCls = JClass(env, "edu/wpi/first/hal/sim/BufferCallback");
+ if (!bufferCallbackCls) return JNI_ERR;
+
+ bufferCallbackCallback = env->GetMethodID(bufferCallbackCls, "callback",
+ "(Ljava/lang/String;[BI)V");
+ if (!bufferCallbackCallback) return JNI_ERR;
+
+ constBufferCallbackCls =
+ JClass(env, "edu/wpi/first/hal/sim/ConstBufferCallback");
+ if (!constBufferCallbackCls) return JNI_ERR;
+
+ constBufferCallbackCallback = env->GetMethodID(
+ constBufferCallbackCls, "callback", "(Ljava/lang/String;[BI)V");
+ if (!constBufferCallbackCallback) return JNI_ERR;
+
+ spiReadAutoReceiveBufferCallbackCls =
+ JClass(env, "edu/wpi/first/hal/sim/SpiReadAutoReceiveBufferCallback");
+ if (!spiReadAutoReceiveBufferCallbackCls) return JNI_ERR;
+
+ spiReadAutoReceiveBufferCallbackCallback =
+ env->GetMethodID(spiReadAutoReceiveBufferCallbackCls, "callback",
+ "(Ljava/lang/String;[II)I");
+ if (!spiReadAutoReceiveBufferCallbackCallback) return JNI_ERR;
+
+ InitializeStore();
+ InitializeBufferStore();
+ InitializeConstBufferStore();
+ InitializeSpiBufferStore();
+ if (!InitializeSimDeviceDataJNI(env)) return JNI_ERR;
+
+ return JNI_VERSION_1_6;
+}
+
+void SimOnUnload(JavaVM* vm, void* reserved) {
+ JNIEnv* env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
+ return;
+
+ notifyCallbackCls.free(env);
+ bufferCallbackCls.free(env);
+ constBufferCallbackCls.free(env);
+ spiReadAutoReceiveBufferCallbackCls.free(env);
+ FreeSimDeviceDataJNI(env);
+ jvm = nullptr;
+}
+
+JavaVM* GetJVM() { return jvm; }
+
+jmethodID GetNotifyCallback() { return notifyCallbackCallback; }
+
+jmethodID GetBufferCallback() { return bufferCallbackCallback; }
+
+jmethodID GetConstBufferCallback() { return constBufferCallbackCallback; }
+
+jmethodID GetSpiReadAutoReceiveBufferCallback() {
+ return spiReadAutoReceiveBufferCallbackCallback;
+}
+} // namespace sim
+
+extern "C" {
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimulatorJNI
+ * Method: waitForProgramStart
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimulatorJNI_waitForProgramStart
+ (JNIEnv*, jclass)
+{
+ HALSIM_WaitForProgramStart();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimulatorJNI
+ * Method: setProgramStarted
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimulatorJNI_setProgramStarted
+ (JNIEnv*, jclass)
+{
+ HALSIM_SetProgramStarted();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimulatorJNI
+ * Method: restartTiming
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimulatorJNI_restartTiming
+ (JNIEnv*, jclass)
+{
+ HALSIM_RestartTiming();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimulatorJNI
+ * Method: pauseTiming
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimulatorJNI_pauseTiming
+ (JNIEnv*, jclass)
+{
+ HALSIM_PauseTiming();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimulatorJNI
+ * Method: resumeTiming
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimulatorJNI_resumeTiming
+ (JNIEnv*, jclass)
+{
+ HALSIM_ResumeTiming();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimulatorJNI
+ * Method: isTimingPaused
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimulatorJNI_isTimingPaused
+ (JNIEnv*, jclass)
+{
+ return HALSIM_IsTimingPaused();
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimulatorJNI
+ * Method: stepTiming
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimulatorJNI_stepTiming
+ (JNIEnv*, jclass, jlong delta)
+{
+ HALSIM_StepTiming(delta);
+}
+
+/*
+ * Class: edu_wpi_first_hal_sim_mockdata_SimulatorJNI
+ * Method: resetHandles
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_sim_mockdata_SimulatorJNI_resetHandles
+ (JNIEnv*, jclass)
+{
+ hal::HandleBase::ResetGlobalHandles();
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/jni/SimulatorJNI.h b/hal/src/main/native/sim/jni/SimulatorJNI.h
new file mode 100644
index 0000000..8680396
--- /dev/null
+++ b/hal/src/main/native/sim/jni/SimulatorJNI.h
@@ -0,0 +1,22 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-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 "hal/Types.h"
+#include "jni.h"
+
+typedef HAL_Handle SIM_JniHandle;
+
+namespace sim {
+JavaVM* GetJVM();
+
+jmethodID GetNotifyCallback();
+jmethodID GetBufferCallback();
+jmethodID GetConstBufferCallback();
+jmethodID GetSpiReadAutoReceiveBufferCallback();
+} // namespace sim
diff --git a/hal/src/main/native/sim/jni/SpiReadAutoReceiveBufferCallbackStore.cpp b/hal/src/main/native/sim/jni/SpiReadAutoReceiveBufferCallbackStore.cpp
new file mode 100644
index 0000000..b75bb1e
--- /dev/null
+++ b/hal/src/main/native/sim/jni/SpiReadAutoReceiveBufferCallbackStore.cpp
@@ -0,0 +1,130 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-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 "SpiReadAutoReceiveBufferCallbackStore.h"
+
+#include <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/Value.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/NotifyListener.h"
+
+using namespace wpi::java;
+using namespace sim;
+
+static hal::UnlimitedHandleResource<
+ SIM_JniHandle, SpiReadAutoReceiveBufferCallbackStore,
+ hal::HAL_HandleEnum::SimulationJni>* callbackHandles;
+
+namespace sim {
+void InitializeSpiBufferStore() {
+ static hal::UnlimitedHandleResource<SIM_JniHandle,
+ SpiReadAutoReceiveBufferCallbackStore,
+ hal::HAL_HandleEnum::SimulationJni>
+ cb;
+ callbackHandles = &cb;
+}
+} // namespace sim
+
+void SpiReadAutoReceiveBufferCallbackStore::create(JNIEnv* env, jobject obj) {
+ m_call = JGlobal<jobject>(env, obj);
+}
+
+int32_t SpiReadAutoReceiveBufferCallbackStore::performCallback(
+ const char* name, uint32_t* buffer, int32_t numToRead) {
+ JNIEnv* env;
+ JavaVM* vm = sim::GetJVM();
+ bool didAttachThread = false;
+ int tryGetEnv = vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
+ if (tryGetEnv == JNI_EDETACHED) {
+ // Thread not attached
+ didAttachThread = true;
+ if (vm->AttachCurrentThread(reinterpret_cast<void**>(&env), nullptr) != 0) {
+ // Failed to attach, log and return
+ wpi::outs() << "Failed to attach\n";
+ wpi::outs().flush();
+ return -1;
+ }
+ } else if (tryGetEnv == JNI_EVERSION) {
+ wpi::outs() << "Invalid JVM Version requested\n";
+ wpi::outs().flush();
+ }
+
+ auto toCallbackArr = MakeJIntArray(
+ env, wpi::ArrayRef<uint32_t>{buffer, static_cast<size_t>(numToRead)});
+
+ jint ret = env->CallIntMethod(m_call, sim::GetBufferCallback(),
+ MakeJString(env, name), toCallbackArr,
+ (jint)numToRead);
+
+ jint* fromCallbackArr = reinterpret_cast<jint*>(
+ env->GetPrimitiveArrayCritical(toCallbackArr, nullptr));
+
+ for (int i = 0; i < ret; i++) {
+ buffer[i] = fromCallbackArr[i];
+ }
+
+ env->ReleasePrimitiveArrayCritical(toCallbackArr, fromCallbackArr, JNI_ABORT);
+
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ }
+
+ if (didAttachThread) {
+ vm->DetachCurrentThread();
+ }
+ return ret;
+}
+
+void SpiReadAutoReceiveBufferCallbackStore::free(JNIEnv* env) {
+ m_call.free(env);
+}
+
+SIM_JniHandle sim::AllocateSpiBufferCallback(
+ JNIEnv* env, jint index, jobject callback,
+ RegisterSpiBufferCallbackFunc createCallback) {
+ auto callbackStore =
+ std::make_shared<SpiReadAutoReceiveBufferCallbackStore>();
+
+ auto handle = callbackHandles->Allocate(callbackStore);
+
+ if (handle == HAL_kInvalidHandle) {
+ return -1;
+ }
+
+ uintptr_t handleAsPtr = static_cast<uintptr_t>(handle);
+ void* handleAsVoidPtr = reinterpret_cast<void*>(handleAsPtr);
+
+ callbackStore->create(env, callback);
+
+ auto callbackFunc = [](const char* name, void* param, uint32_t* buffer,
+ int32_t numToRead, int32_t* outputCount) {
+ uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
+ SIM_JniHandle handle = static_cast<SIM_JniHandle>(handleTmp);
+ auto data = callbackHandles->Get(handle);
+ if (!data) return;
+
+ *outputCount = data->performCallback(name, buffer, numToRead);
+ };
+
+ auto id = createCallback(index, callbackFunc, handleAsVoidPtr);
+
+ callbackStore->setCallbackId(id);
+
+ return handle;
+}
+
+void sim::FreeSpiBufferCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
+ FreeSpiBufferCallbackFunc freeCallback) {
+ auto callback = callbackHandles->Free(handle);
+ freeCallback(index, callback->getCallbackId());
+ callback->free(env);
+}
diff --git a/hal/src/main/native/sim/jni/SpiReadAutoReceiveBufferCallbackStore.h b/hal/src/main/native/sim/jni/SpiReadAutoReceiveBufferCallbackStore.h
new file mode 100644
index 0000000..1a03f59
--- /dev/null
+++ b/hal/src/main/native/sim/jni/SpiReadAutoReceiveBufferCallbackStore.h
@@ -0,0 +1,47 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-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 <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/Value.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/NotifyListener.h"
+#include "mockdata/SPIData.h"
+
+namespace sim {
+class SpiReadAutoReceiveBufferCallbackStore {
+ public:
+ void create(JNIEnv* env, jobject obj);
+ int32_t performCallback(const char* name, uint32_t* buffer,
+ int32_t numToRead);
+ void free(JNIEnv* env);
+ void setCallbackId(int32_t id) { callbackId = id; }
+ int32_t getCallbackId() { return callbackId; }
+
+ private:
+ wpi::java::JGlobal<jobject> m_call;
+ int32_t callbackId;
+};
+
+void InitializeSpiBufferStore();
+
+typedef int32_t (*RegisterSpiBufferCallbackFunc)(
+ int32_t index, HAL_SpiReadAutoReceiveBufferCallback callback, void* param);
+typedef void (*FreeSpiBufferCallbackFunc)(int32_t index, int32_t uid);
+
+SIM_JniHandle AllocateSpiBufferCallback(
+ JNIEnv* env, jint index, jobject callback,
+ RegisterSpiBufferCallbackFunc createCallback);
+void FreeSpiBufferCallback(JNIEnv* env, SIM_JniHandle handle, jint index,
+ FreeSpiBufferCallbackFunc freeCallback);
+} // namespace sim
diff --git a/hal/src/main/native/sim/mockdata/AccelerometerData.cpp b/hal/src/main/native/sim/mockdata/AccelerometerData.cpp
new file mode 100644
index 0000000..66e129a
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AccelerometerData.cpp
@@ -0,0 +1,60 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "../PortsInternal.h"
+#include "AccelerometerDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeAccelerometerData() {
+ static AccelerometerData sad[1];
+ ::hal::SimAccelerometerData = sad;
+}
+} // namespace init
+} // namespace hal
+
+AccelerometerData* hal::SimAccelerometerData;
+void AccelerometerData::ResetData() {
+ active.Reset(false);
+ range.Reset(static_cast<HAL_AccelerometerRange>(0));
+ x.Reset(0.0);
+ y.Reset(0.0);
+ z.Reset(0.0);
+}
+
+extern "C" {
+void HALSIM_ResetAccelerometerData(int32_t index) {
+ SimAccelerometerData[index].ResetData();
+}
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, Accelerometer##CAPINAME, \
+ SimAccelerometerData, LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Active, active)
+DEFINE_CAPI(HAL_AccelerometerRange, Range, range)
+DEFINE_CAPI(double, X, x)
+DEFINE_CAPI(double, Y, y)
+DEFINE_CAPI(double, Z, z)
+
+#define REGISTER(NAME) \
+ SimAccelerometerData[index].NAME.RegisterCallback(callback, param, \
+ initialNotify)
+
+void HALSIM_RegisterAccelerometerAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify) {
+ REGISTER(active);
+ REGISTER(range);
+ REGISTER(x);
+ REGISTER(y);
+ REGISTER(z);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/AccelerometerDataInternal.h b/hal/src/main/native/sim/mockdata/AccelerometerDataInternal.h
new file mode 100644
index 0000000..9db0875
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AccelerometerDataInternal.h
@@ -0,0 +1,36 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/AccelerometerData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class AccelerometerData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Active)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Range)
+ HAL_SIMDATAVALUE_DEFINE_NAME(X)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Y)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Z)
+
+ static inline HAL_Value MakeRangeValue(HAL_AccelerometerRange value) {
+ return HAL_MakeEnum(value);
+ }
+
+ public:
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetActiveName> active{false};
+ SimDataValue<HAL_AccelerometerRange, MakeRangeValue, GetRangeName> range{
+ static_cast<HAL_AccelerometerRange>(0)};
+ SimDataValue<double, HAL_MakeDouble, GetXName> x{0.0};
+ SimDataValue<double, HAL_MakeDouble, GetYName> y{0.0};
+ SimDataValue<double, HAL_MakeDouble, GetZName> z{0.0};
+
+ virtual void ResetData();
+};
+extern AccelerometerData* SimAccelerometerData;
+} // namespace hal
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 0000000..5b44eaf
--- /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 <algorithm>
+#include <cstring>
+
+#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<const uint8_t*>(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 0000000..9d6e215
--- /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 <vector>
+
+#include <wpi/spinlock.h>
+
+#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<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{
+ false};
+ SimDataValue<int32_t, HAL_MakeInt, GetOutputPortName> outputPort{-1};
+ SimDataValue<int32_t, HAL_MakeInt, GetLengthName> length{1};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetRunningName> running{false};
+ SimCallbackRegistry<HAL_ConstBufferCallback, GetDataName> data;
+
+ void ResetData();
+};
+extern AddressableLEDData* SimAddressableLEDData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/AnalogGyroData.cpp b/hal/src/main/native/sim/mockdata/AnalogGyroData.cpp
new file mode 100644
index 0000000..2508d9b
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogGyroData.cpp
@@ -0,0 +1,53 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "../PortsInternal.h"
+#include "AnalogGyroDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeAnalogGyroData() {
+ static AnalogGyroData agd[kNumAccumulators];
+ ::hal::SimAnalogGyroData = agd;
+}
+} // namespace init
+} // namespace hal
+
+AnalogGyroData* hal::SimAnalogGyroData;
+void AnalogGyroData::ResetData() {
+ angle.Reset(0.0);
+ rate.Reset(0.0);
+ initialized.Reset(false);
+}
+
+extern "C" {
+void HALSIM_ResetAnalogGyroData(int32_t index) {
+ SimAnalogGyroData[index].ResetData();
+}
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, AnalogGyro##CAPINAME, \
+ SimAnalogGyroData, LOWERNAME)
+
+DEFINE_CAPI(double, Angle, angle)
+DEFINE_CAPI(double, Rate, rate)
+DEFINE_CAPI(HAL_Bool, Initialized, initialized)
+
+#define REGISTER(NAME) \
+ SimAnalogGyroData[index].NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterAnalogGyroAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify) {
+ REGISTER(angle);
+ REGISTER(rate);
+ REGISTER(initialized);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/AnalogGyroDataInternal.h b/hal/src/main/native/sim/mockdata/AnalogGyroDataInternal.h
new file mode 100644
index 0000000..427d2fb
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogGyroDataInternal.h
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/AnalogGyroData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class AnalogGyroData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Angle)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Rate)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+
+ public:
+ SimDataValue<double, HAL_MakeDouble, GetAngleName> angle{0.0};
+ SimDataValue<double, HAL_MakeDouble, GetRateName> rate{0.0};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{
+ false};
+
+ virtual void ResetData();
+};
+extern AnalogGyroData* SimAnalogGyroData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/AnalogInData.cpp b/hal/src/main/native/sim/mockdata/AnalogInData.cpp
new file mode 100644
index 0000000..a2a871c
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogInData.cpp
@@ -0,0 +1,75 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "../PortsInternal.h"
+#include "AnalogInDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeAnalogInData() {
+ static AnalogInData sind[kNumAnalogInputs];
+ ::hal::SimAnalogInData = sind;
+}
+} // namespace init
+} // namespace hal
+
+AnalogInData* hal::SimAnalogInData;
+void AnalogInData::ResetData() {
+ initialized.Reset(false);
+ simDevice = 0;
+ averageBits.Reset(7);
+ oversampleBits.Reset(0);
+ voltage.Reset(0.0);
+ accumulatorInitialized.Reset(false);
+ accumulatorValue.Reset(0);
+ accumulatorCount.Reset(0);
+ accumulatorCenter.Reset(0);
+ accumulatorDeadband.Reset(0);
+}
+
+extern "C" {
+void HALSIM_ResetAnalogInData(int32_t index) {
+ SimAnalogInData[index].ResetData();
+}
+
+HAL_SimDeviceHandle HALSIM_GetAnalogInSimDevice(int32_t index) {
+ return SimAnalogInData[index].simDevice;
+}
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, AnalogIn##CAPINAME, \
+ SimAnalogInData, LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Initialized, initialized)
+DEFINE_CAPI(int32_t, AverageBits, averageBits)
+DEFINE_CAPI(int32_t, OversampleBits, oversampleBits)
+DEFINE_CAPI(double, Voltage, voltage)
+DEFINE_CAPI(HAL_Bool, AccumulatorInitialized, accumulatorInitialized)
+DEFINE_CAPI(int64_t, AccumulatorValue, accumulatorValue)
+DEFINE_CAPI(int64_t, AccumulatorCount, accumulatorCount)
+DEFINE_CAPI(int32_t, AccumulatorCenter, accumulatorCenter)
+DEFINE_CAPI(int32_t, AccumulatorDeadband, accumulatorDeadband)
+
+#define REGISTER(NAME) \
+ SimAnalogInData[index].NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterAnalogInAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify) {
+ REGISTER(initialized);
+ REGISTER(averageBits);
+ REGISTER(oversampleBits);
+ REGISTER(voltage);
+ REGISTER(accumulatorInitialized);
+ REGISTER(accumulatorValue);
+ REGISTER(accumulatorCount);
+ REGISTER(accumulatorCenter);
+ REGISTER(accumulatorDeadband);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/AnalogInDataInternal.h b/hal/src/main/native/sim/mockdata/AnalogInDataInternal.h
new file mode 100644
index 0000000..cd8348d
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogInDataInternal.h
@@ -0,0 +1,46 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/AnalogInData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class AnalogInData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+ HAL_SIMDATAVALUE_DEFINE_NAME(AverageBits)
+ HAL_SIMDATAVALUE_DEFINE_NAME(OversampleBits)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Voltage)
+ HAL_SIMDATAVALUE_DEFINE_NAME(AccumulatorInitialized)
+ HAL_SIMDATAVALUE_DEFINE_NAME(AccumulatorValue)
+ HAL_SIMDATAVALUE_DEFINE_NAME(AccumulatorCount)
+ HAL_SIMDATAVALUE_DEFINE_NAME(AccumulatorCenter)
+ HAL_SIMDATAVALUE_DEFINE_NAME(AccumulatorDeadband)
+
+ public:
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{
+ false};
+ std::atomic<HAL_SimDeviceHandle> simDevice;
+ SimDataValue<int32_t, HAL_MakeInt, GetAverageBitsName> averageBits{7};
+ SimDataValue<int32_t, HAL_MakeInt, GetOversampleBitsName> oversampleBits{0};
+ SimDataValue<double, HAL_MakeDouble, GetVoltageName> voltage{0.0};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetAccumulatorInitializedName>
+ accumulatorInitialized{false};
+ SimDataValue<int64_t, HAL_MakeLong, GetAccumulatorValueName> accumulatorValue{
+ 0};
+ SimDataValue<int64_t, HAL_MakeLong, GetAccumulatorCountName> accumulatorCount{
+ 0};
+ SimDataValue<int32_t, HAL_MakeInt, GetAccumulatorCenterName>
+ accumulatorCenter{0};
+ SimDataValue<int32_t, HAL_MakeInt, GetAccumulatorDeadbandName>
+ accumulatorDeadband{0};
+
+ virtual void ResetData();
+};
+extern AnalogInData* SimAnalogInData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/AnalogOutData.cpp b/hal/src/main/native/sim/mockdata/AnalogOutData.cpp
new file mode 100644
index 0000000..d4b9116
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogOutData.cpp
@@ -0,0 +1,49 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "../PortsInternal.h"
+#include "AnalogOutDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeAnalogOutData() {
+ static AnalogOutData siod[kNumAnalogOutputs];
+ ::hal::SimAnalogOutData = siod;
+}
+} // namespace init
+} // namespace hal
+
+AnalogOutData* hal::SimAnalogOutData;
+void AnalogOutData::ResetData() {
+ voltage.Reset(0.0);
+ initialized.Reset(0);
+}
+
+extern "C" {
+void HALSIM_ResetAnalogOutData(int32_t index) {
+ SimAnalogOutData[index].ResetData();
+}
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, AnalogOut##CAPINAME, \
+ SimAnalogOutData, LOWERNAME)
+
+DEFINE_CAPI(double, Voltage, voltage)
+DEFINE_CAPI(HAL_Bool, Initialized, initialized)
+
+#define REGISTER(NAME) \
+ SimAnalogOutData[index].NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterAnalogOutAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify) {
+ REGISTER(voltage);
+ REGISTER(initialized);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/AnalogOutDataInternal.h b/hal/src/main/native/sim/mockdata/AnalogOutDataInternal.h
new file mode 100644
index 0000000..da7d49f
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogOutDataInternal.h
@@ -0,0 +1,25 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/AnalogOutData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class AnalogOutData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Voltage)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+
+ public:
+ SimDataValue<double, HAL_MakeDouble, GetVoltageName> voltage{0.0};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{0};
+
+ virtual void ResetData();
+};
+extern AnalogOutData* SimAnalogOutData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/AnalogTriggerData.cpp b/hal/src/main/native/sim/mockdata/AnalogTriggerData.cpp
new file mode 100644
index 0000000..64d1a97
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogTriggerData.cpp
@@ -0,0 +1,57 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "../PortsInternal.h"
+#include "AnalogTriggerDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeAnalogTriggerData() {
+ static AnalogTriggerData satd[kNumAnalogTriggers];
+ ::hal::SimAnalogTriggerData = satd;
+}
+} // namespace init
+} // namespace hal
+
+AnalogTriggerData* hal::SimAnalogTriggerData;
+void AnalogTriggerData::ResetData() {
+ initialized.Reset(0);
+ triggerLowerBound.Reset(0);
+ triggerUpperBound.Reset(0);
+ triggerMode.Reset(static_cast<HALSIM_AnalogTriggerMode>(0));
+}
+
+extern "C" {
+void HALSIM_ResetAnalogTriggerData(int32_t index) {
+ SimAnalogTriggerData[index].ResetData();
+}
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, AnalogTrigger##CAPINAME, \
+ SimAnalogTriggerData, LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Initialized, initialized)
+DEFINE_CAPI(double, TriggerLowerBound, triggerLowerBound)
+DEFINE_CAPI(double, TriggerUpperBound, triggerUpperBound)
+DEFINE_CAPI(HALSIM_AnalogTriggerMode, TriggerMode, triggerMode)
+
+#define REGISTER(NAME) \
+ SimAnalogTriggerData[index].NAME.RegisterCallback(callback, param, \
+ initialNotify)
+
+void HALSIM_RegisterAnalogTriggerAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify) {
+ REGISTER(initialized);
+ REGISTER(triggerLowerBound);
+ REGISTER(triggerUpperBound);
+ REGISTER(triggerMode);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/AnalogTriggerDataInternal.h b/hal/src/main/native/sim/mockdata/AnalogTriggerDataInternal.h
new file mode 100644
index 0000000..61b3c19
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogTriggerDataInternal.h
@@ -0,0 +1,38 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/AnalogTriggerData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class AnalogTriggerData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+ HAL_SIMDATAVALUE_DEFINE_NAME(TriggerLowerBound)
+ HAL_SIMDATAVALUE_DEFINE_NAME(TriggerUpperBound)
+ HAL_SIMDATAVALUE_DEFINE_NAME(TriggerMode)
+
+ static LLVM_ATTRIBUTE_ALWAYS_INLINE HAL_Value
+ MakeTriggerModeValue(HALSIM_AnalogTriggerMode value) {
+ return HAL_MakeEnum(value);
+ }
+
+ public:
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{0};
+ SimDataValue<double, HAL_MakeDouble, GetTriggerLowerBoundName>
+ triggerLowerBound{0};
+ SimDataValue<double, HAL_MakeDouble, GetTriggerUpperBoundName>
+ triggerUpperBound{0};
+ SimDataValue<HALSIM_AnalogTriggerMode, MakeTriggerModeValue,
+ GetTriggerModeName>
+ triggerMode{static_cast<HALSIM_AnalogTriggerMode>(0)};
+
+ virtual void ResetData();
+};
+extern AnalogTriggerData* SimAnalogTriggerData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/CanDataInternal.cpp b/hal/src/main/native/sim/mockdata/CanDataInternal.cpp
new file mode 100644
index 0000000..e37d865
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/CanDataInternal.cpp
@@ -0,0 +1,47 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "CanDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeCanData() {
+ static CanData scd;
+ ::hal::SimCanData = &scd;
+}
+} // namespace init
+} // namespace hal
+
+CanData* hal::SimCanData;
+
+void CanData::ResetData() {
+ sendMessage.Reset();
+ receiveMessage.Reset();
+ openStreamSession.Reset();
+ closeStreamSession.Reset();
+ readStreamSession.Reset();
+ getCANStatus.Reset();
+}
+
+extern "C" {
+
+void HALSIM_ResetCanData(void) { SimCanData->ResetData(); }
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMCALLBACKREGISTRY_DEFINE_CAPI_NOINDEX(TYPE, HALSIM, Can##CAPINAME, \
+ SimCanData, LOWERNAME)
+
+DEFINE_CAPI(HAL_CAN_SendMessageCallback, SendMessage, sendMessage)
+DEFINE_CAPI(HAL_CAN_ReceiveMessageCallback, ReceiveMessage, receiveMessage)
+DEFINE_CAPI(HAL_CAN_OpenStreamSessionCallback, OpenStream, openStreamSession)
+DEFINE_CAPI(HAL_CAN_CloseStreamSessionCallback, CloseStream, closeStreamSession)
+DEFINE_CAPI(HAL_CAN_ReadStreamSessionCallback, ReadStream, readStreamSession)
+DEFINE_CAPI(HAL_CAN_GetCANStatusCallback, GetCANStatus, getCANStatus)
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/CanDataInternal.h b/hal/src/main/native/sim/mockdata/CanDataInternal.h
new file mode 100644
index 0000000..ffdd351
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/CanDataInternal.h
@@ -0,0 +1,42 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "mockdata/CanData.h"
+#include "mockdata/SimCallbackRegistry.h"
+
+namespace hal {
+
+class CanData {
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(SendMessage)
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(ReceiveMessage)
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(OpenStream)
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(CloseStream)
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(ReadStream)
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(GetCanStatus)
+
+ public:
+ SimCallbackRegistry<HAL_CAN_SendMessageCallback, GetSendMessageName>
+ sendMessage;
+ SimCallbackRegistry<HAL_CAN_ReceiveMessageCallback, GetReceiveMessageName>
+ receiveMessage;
+ SimCallbackRegistry<HAL_CAN_OpenStreamSessionCallback, GetOpenStreamName>
+ openStreamSession;
+ SimCallbackRegistry<HAL_CAN_CloseStreamSessionCallback, GetCloseStreamName>
+ closeStreamSession;
+ SimCallbackRegistry<HAL_CAN_ReadStreamSessionCallback, GetReadStreamName>
+ readStreamSession;
+ SimCallbackRegistry<HAL_CAN_GetCANStatusCallback, GetGetCanStatusName>
+ getCANStatus;
+
+ void ResetData();
+};
+
+extern CanData* SimCanData;
+
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/DIOData.cpp b/hal/src/main/native/sim/mockdata/DIOData.cpp
new file mode 100644
index 0000000..a9c61fd
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DIOData.cpp
@@ -0,0 +1,60 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "../PortsInternal.h"
+#include "DIODataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeDIOData() {
+ static DIOData sdd[kNumDigitalChannels];
+ ::hal::SimDIOData = sdd;
+}
+} // namespace init
+} // namespace hal
+
+DIOData* hal::SimDIOData;
+void DIOData::ResetData() {
+ initialized.Reset(false);
+ simDevice = 0;
+ value.Reset(true);
+ pulseLength.Reset(0.0);
+ isInput.Reset(true);
+ filterIndex.Reset(-1);
+}
+
+extern "C" {
+void HALSIM_ResetDIOData(int32_t index) { SimDIOData[index].ResetData(); }
+
+HAL_SimDeviceHandle HALSIM_GetDIOSimDevice(int32_t index) {
+ return SimDIOData[index].simDevice;
+}
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, DIO##CAPINAME, SimDIOData, \
+ LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Initialized, initialized)
+DEFINE_CAPI(HAL_Bool, Value, value)
+DEFINE_CAPI(double, PulseLength, pulseLength)
+DEFINE_CAPI(HAL_Bool, IsInput, isInput)
+DEFINE_CAPI(int32_t, FilterIndex, filterIndex)
+
+#define REGISTER(NAME) \
+ SimDIOData[index].NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterDIOAllCallbacks(int32_t index, HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify) {
+ REGISTER(initialized);
+ REGISTER(value);
+ REGISTER(pulseLength);
+ REGISTER(isInput);
+ REGISTER(filterIndex);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/DIODataInternal.h b/hal/src/main/native/sim/mockdata/DIODataInternal.h
new file mode 100644
index 0000000..49e0f75
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DIODataInternal.h
@@ -0,0 +1,33 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/DIOData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class DIOData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Value)
+ HAL_SIMDATAVALUE_DEFINE_NAME(PulseLength)
+ HAL_SIMDATAVALUE_DEFINE_NAME(IsInput)
+ HAL_SIMDATAVALUE_DEFINE_NAME(FilterIndex)
+
+ public:
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{
+ false};
+ std::atomic<HAL_SimDeviceHandle> simDevice;
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetValueName> value{true};
+ SimDataValue<double, HAL_MakeDouble, GetPulseLengthName> pulseLength{0.0};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetIsInputName> isInput{true};
+ SimDataValue<int32_t, HAL_MakeInt, GetFilterIndexName> filterIndex{-1};
+
+ virtual void ResetData();
+};
+extern DIOData* SimDIOData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/DigitalPWMData.cpp b/hal/src/main/native/sim/mockdata/DigitalPWMData.cpp
new file mode 100644
index 0000000..78ee749
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DigitalPWMData.cpp
@@ -0,0 +1,53 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "../PortsInternal.h"
+#include "DigitalPWMDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeDigitalPWMData() {
+ static DigitalPWMData sdpd[kNumDigitalPWMOutputs];
+ ::hal::SimDigitalPWMData = sdpd;
+}
+} // namespace init
+} // namespace hal
+
+DigitalPWMData* hal::SimDigitalPWMData;
+void DigitalPWMData::ResetData() {
+ initialized.Reset(false);
+ dutyCycle.Reset(0.0);
+ pin.Reset(0);
+}
+
+extern "C" {
+void HALSIM_ResetDigitalPWMData(int32_t index) {
+ SimDigitalPWMData[index].ResetData();
+}
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, DigitalPWM##CAPINAME, \
+ SimDigitalPWMData, LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Initialized, initialized)
+DEFINE_CAPI(double, DutyCycle, dutyCycle)
+DEFINE_CAPI(int32_t, Pin, pin)
+
+#define REGISTER(NAME) \
+ SimDigitalPWMData[index].NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterDigitalPWMAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify) {
+ REGISTER(initialized);
+ REGISTER(dutyCycle);
+ REGISTER(pin);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/DigitalPWMDataInternal.h b/hal/src/main/native/sim/mockdata/DigitalPWMDataInternal.h
new file mode 100644
index 0000000..09d5903
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DigitalPWMDataInternal.h
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/DigitalPWMData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class DigitalPWMData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+ HAL_SIMDATAVALUE_DEFINE_NAME(DutyCycle)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Pin)
+
+ public:
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{
+ false};
+ SimDataValue<double, HAL_MakeDouble, GetDutyCycleName> dutyCycle{0.0};
+ SimDataValue<int32_t, HAL_MakeInt, GetPinName> pin{0};
+
+ virtual void ResetData();
+};
+extern DigitalPWMData* SimDigitalPWMData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/DriverStationData.cpp b/hal/src/main/native/sim/mockdata/DriverStationData.cpp
new file mode 100644
index 0000000..ece98c8
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DriverStationData.cpp
@@ -0,0 +1,209 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include <cstdlib>
+#include <cstring>
+#include <string>
+
+#include "DriverStationDataInternal.h"
+#include "hal/DriverStation.h"
+
+namespace hal {
+struct JoystickOutputStore {
+ int64_t outputs = 0;
+ int32_t leftRumble = 0;
+ int32_t rightRumble = 0;
+};
+} // namespace hal
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeDriverStationData() {
+ static DriverStationData dsd;
+ ::hal::SimDriverStationData = &dsd;
+}
+} // namespace init
+} // namespace hal
+
+DriverStationData* hal::SimDriverStationData;
+
+DriverStationData::DriverStationData() { ResetData(); }
+
+void DriverStationData::ResetData() {
+ enabled.Reset(false);
+ autonomous.Reset(false);
+ test.Reset(false);
+ eStop.Reset(false);
+ fmsAttached.Reset(false);
+ dsAttached.Reset(true);
+ allianceStationId.Reset(static_cast<HAL_AllianceStationID>(0));
+ matchTime.Reset(0.0);
+
+ {
+ std::scoped_lock lock(m_joystickDataMutex);
+ m_joystickAxes = std::make_unique<HAL_JoystickAxes[]>(6);
+ m_joystickPOVs = std::make_unique<HAL_JoystickPOVs[]>(6);
+ m_joystickButtons = std::make_unique<HAL_JoystickButtons[]>(6);
+ m_joystickOutputs = std::make_unique<JoystickOutputStore[]>(6);
+ m_joystickDescriptor = std::make_unique<HAL_JoystickDescriptor[]>(6);
+
+ for (int i = 0; i < 6; i++) {
+ m_joystickAxes[i].count = 0;
+ m_joystickPOVs[i].count = 0;
+ m_joystickButtons[i].count = 0;
+ m_joystickDescriptor[i].isXbox = 0;
+ m_joystickDescriptor[i].type = -1;
+ m_joystickDescriptor[i].name[0] = '\0';
+ }
+ }
+ {
+ std::scoped_lock lock(m_matchInfoMutex);
+
+ m_matchInfo = std::make_unique<HAL_MatchInfo>();
+ }
+}
+
+void DriverStationData::GetJoystickAxes(int32_t joystickNum,
+ HAL_JoystickAxes* axes) {
+ std::scoped_lock lock(m_joystickDataMutex);
+ *axes = m_joystickAxes[joystickNum];
+}
+void DriverStationData::GetJoystickPOVs(int32_t joystickNum,
+ HAL_JoystickPOVs* povs) {
+ std::scoped_lock lock(m_joystickDataMutex);
+ *povs = m_joystickPOVs[joystickNum];
+}
+void DriverStationData::GetJoystickButtons(int32_t joystickNum,
+ HAL_JoystickButtons* buttons) {
+ std::scoped_lock lock(m_joystickDataMutex);
+ *buttons = m_joystickButtons[joystickNum];
+}
+void DriverStationData::GetJoystickDescriptor(
+ int32_t joystickNum, HAL_JoystickDescriptor* descriptor) {
+ std::scoped_lock lock(m_joystickDataMutex);
+ *descriptor = m_joystickDescriptor[joystickNum];
+ // Always ensure name is null terminated
+ descriptor->name[255] = '\0';
+}
+void DriverStationData::GetJoystickOutputs(int32_t joystickNum,
+ int64_t* outputs,
+ int32_t* leftRumble,
+ int32_t* rightRumble) {
+ std::scoped_lock lock(m_joystickDataMutex);
+ *leftRumble = m_joystickOutputs[joystickNum].leftRumble;
+ *outputs = m_joystickOutputs[joystickNum].outputs;
+ *rightRumble = m_joystickOutputs[joystickNum].rightRumble;
+}
+void DriverStationData::GetMatchInfo(HAL_MatchInfo* info) {
+ std::scoped_lock lock(m_matchInfoMutex);
+ *info = *m_matchInfo;
+}
+
+void DriverStationData::SetJoystickAxes(int32_t joystickNum,
+ const HAL_JoystickAxes* axes) {
+ std::scoped_lock lock(m_joystickDataMutex);
+ m_joystickAxes[joystickNum] = *axes;
+}
+void DriverStationData::SetJoystickPOVs(int32_t joystickNum,
+ const HAL_JoystickPOVs* povs) {
+ std::scoped_lock lock(m_joystickDataMutex);
+ m_joystickPOVs[joystickNum] = *povs;
+}
+void DriverStationData::SetJoystickButtons(int32_t joystickNum,
+ const HAL_JoystickButtons* buttons) {
+ std::scoped_lock lock(m_joystickDataMutex);
+ m_joystickButtons[joystickNum] = *buttons;
+}
+
+void DriverStationData::SetJoystickDescriptor(
+ int32_t joystickNum, const HAL_JoystickDescriptor* descriptor) {
+ std::scoped_lock lock(m_joystickDataMutex);
+ m_joystickDescriptor[joystickNum] = *descriptor;
+}
+
+void DriverStationData::SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
+ int32_t leftRumble,
+ int32_t rightRumble) {
+ std::scoped_lock lock(m_joystickDataMutex);
+ m_joystickOutputs[joystickNum].leftRumble = leftRumble;
+ m_joystickOutputs[joystickNum].outputs = outputs;
+ m_joystickOutputs[joystickNum].rightRumble = rightRumble;
+}
+
+void DriverStationData::SetMatchInfo(const HAL_MatchInfo* info) {
+ std::scoped_lock lock(m_matchInfoMutex);
+ *m_matchInfo = *info;
+ *(std::end(m_matchInfo->eventName) - 1) = '\0';
+}
+
+void DriverStationData::NotifyNewData() { HAL_ReleaseDSMutex(); }
+
+extern "C" {
+void HALSIM_ResetDriverStationData(void) { SimDriverStationData->ResetData(); }
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI_NOINDEX(TYPE, HALSIM, DriverStation##CAPINAME, \
+ SimDriverStationData, LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Enabled, enabled)
+DEFINE_CAPI(HAL_Bool, Autonomous, autonomous)
+DEFINE_CAPI(HAL_Bool, Test, test)
+DEFINE_CAPI(HAL_Bool, EStop, eStop)
+DEFINE_CAPI(HAL_Bool, FmsAttached, fmsAttached)
+DEFINE_CAPI(HAL_Bool, DsAttached, dsAttached)
+DEFINE_CAPI(HAL_AllianceStationID, AllianceStationId, allianceStationId)
+DEFINE_CAPI(double, MatchTime, matchTime)
+
+void HALSIM_SetJoystickAxes(int32_t joystickNum, const HAL_JoystickAxes* axes) {
+ SimDriverStationData->SetJoystickAxes(joystickNum, axes);
+}
+
+void HALSIM_SetJoystickPOVs(int32_t joystickNum, const HAL_JoystickPOVs* povs) {
+ SimDriverStationData->SetJoystickPOVs(joystickNum, povs);
+}
+
+void HALSIM_SetJoystickButtons(int32_t joystickNum,
+ const HAL_JoystickButtons* buttons) {
+ SimDriverStationData->SetJoystickButtons(joystickNum, buttons);
+}
+void HALSIM_SetJoystickDescriptor(int32_t joystickNum,
+ const HAL_JoystickDescriptor* descriptor) {
+ SimDriverStationData->SetJoystickDescriptor(joystickNum, descriptor);
+}
+
+void HALSIM_GetJoystickOutputs(int32_t joystickNum, int64_t* outputs,
+ int32_t* leftRumble, int32_t* rightRumble) {
+ SimDriverStationData->GetJoystickOutputs(joystickNum, outputs, leftRumble,
+ rightRumble);
+}
+
+void HALSIM_SetMatchInfo(const HAL_MatchInfo* info) {
+ SimDriverStationData->SetMatchInfo(info);
+}
+
+void HALSIM_NotifyDriverStationNewData(void) {
+ SimDriverStationData->NotifyNewData();
+}
+
+#define REGISTER(NAME) \
+ SimDriverStationData->NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterDriverStationAllCallbacks(HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify) {
+ REGISTER(enabled);
+ REGISTER(autonomous);
+ REGISTER(test);
+ REGISTER(eStop);
+ REGISTER(fmsAttached);
+ REGISTER(dsAttached);
+ REGISTER(allianceStationId);
+ REGISTER(matchTime);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/DriverStationDataInternal.h b/hal/src/main/native/sim/mockdata/DriverStationDataInternal.h
new file mode 100644
index 0000000..fdeb3c6
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DriverStationDataInternal.h
@@ -0,0 +1,86 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <memory>
+
+#include <wpi/spinlock.h>
+
+#include "mockdata/DriverStationData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+struct JoystickOutputStore;
+
+class DriverStationData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Enabled)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Autonomous)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Test)
+ HAL_SIMDATAVALUE_DEFINE_NAME(EStop)
+ HAL_SIMDATAVALUE_DEFINE_NAME(FmsAttached)
+ HAL_SIMDATAVALUE_DEFINE_NAME(DsAttached)
+ HAL_SIMDATAVALUE_DEFINE_NAME(AllianceStationId)
+ HAL_SIMDATAVALUE_DEFINE_NAME(MatchTime)
+
+ static LLVM_ATTRIBUTE_ALWAYS_INLINE HAL_Value
+ MakeAllianceStationIdValue(HAL_AllianceStationID value) {
+ return HAL_MakeEnum(value);
+ }
+
+ public:
+ DriverStationData();
+ void ResetData();
+
+ void GetJoystickAxes(int32_t joystickNum, HAL_JoystickAxes* axes);
+ void GetJoystickPOVs(int32_t joystickNum, HAL_JoystickPOVs* povs);
+ void GetJoystickButtons(int32_t joystickNum, HAL_JoystickButtons* buttons);
+ void GetJoystickDescriptor(int32_t joystickNum,
+ HAL_JoystickDescriptor* descriptor);
+ void GetJoystickOutputs(int32_t joystickNum, int64_t* outputs,
+ int32_t* leftRumble, int32_t* rightRumble);
+ void GetMatchInfo(HAL_MatchInfo* info);
+ void FreeMatchInfo(const HAL_MatchInfo* info);
+
+ void SetJoystickAxes(int32_t joystickNum, const HAL_JoystickAxes* axes);
+ void SetJoystickPOVs(int32_t joystickNum, const HAL_JoystickPOVs* povs);
+ void SetJoystickButtons(int32_t joystickNum,
+ const HAL_JoystickButtons* buttons);
+ void SetJoystickDescriptor(int32_t joystickNum,
+ const HAL_JoystickDescriptor* descriptor);
+ void SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
+ int32_t leftRumble, int32_t rightRumble);
+ void SetMatchInfo(const HAL_MatchInfo* info);
+
+ void NotifyNewData();
+
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetEnabledName> enabled{false};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetAutonomousName> autonomous{false};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetTestName> test{false};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetEStopName> eStop{false};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetFmsAttachedName> fmsAttached{
+ false};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetDsAttachedName> dsAttached{true};
+ SimDataValue<HAL_AllianceStationID, MakeAllianceStationIdValue,
+ GetAllianceStationIdName>
+ allianceStationId{static_cast<HAL_AllianceStationID>(0)};
+ SimDataValue<double, HAL_MakeDouble, GetMatchTimeName> matchTime{0.0};
+
+ private:
+ wpi::spinlock m_joystickDataMutex;
+ wpi::spinlock m_matchInfoMutex;
+
+ std::unique_ptr<HAL_JoystickAxes[]> m_joystickAxes;
+ std::unique_ptr<HAL_JoystickPOVs[]> m_joystickPOVs;
+ std::unique_ptr<HAL_JoystickButtons[]> m_joystickButtons;
+
+ std::unique_ptr<JoystickOutputStore[]> m_joystickOutputs;
+ std::unique_ptr<HAL_JoystickDescriptor[]> m_joystickDescriptor;
+ std::unique_ptr<HAL_MatchInfo> m_matchInfo;
+};
+extern DriverStationData* SimDriverStationData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/DutyCycleData.cpp b/hal/src/main/native/sim/mockdata/DutyCycleData.cpp
new file mode 100644
index 0000000..04806e0
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DutyCycleData.cpp
@@ -0,0 +1,63 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "../PortsInternal.h"
+#include "DutyCycleDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeDutyCycleData() {
+ static DutyCycleData sed[kNumDutyCycles];
+ ::hal::SimDutyCycleData = sed;
+}
+} // namespace init
+} // namespace hal
+
+DutyCycleData* hal::SimDutyCycleData;
+
+void DutyCycleData::ResetData() {
+ digitalChannel = 0;
+ initialized.Reset(false);
+ simDevice = 0;
+ frequency.Reset(0);
+ output.Reset(0);
+}
+
+extern "C" {
+void HALSIM_ResetDutyCycleData(int32_t index) {
+ SimDutyCycleData[index].ResetData();
+}
+int32_t HALSIM_GetDutyCycleDigitalChannel(int32_t index) {
+ return SimDutyCycleData[index].digitalChannel;
+}
+
+HAL_SimDeviceHandle HALSIM_GetDutyCycleSimDevice(int32_t index) {
+ return SimDutyCycleData[index].simDevice;
+}
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, DutyCycle##CAPINAME, \
+ SimDutyCycleData, LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Initialized, initialized)
+DEFINE_CAPI(int32_t, Frequency, frequency)
+DEFINE_CAPI(double, Output, output)
+
+#define REGISTER(NAME) \
+ SimDutyCycleData[index].NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterDutyCycleAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify) {
+ REGISTER(initialized);
+ REGISTER(frequency);
+ REGISTER(output);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/DutyCycleDataInternal.h b/hal/src/main/native/sim/mockdata/DutyCycleDataInternal.h
new file mode 100644
index 0000000..2f98b07
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DutyCycleDataInternal.h
@@ -0,0 +1,33 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <atomic>
+#include <limits>
+
+#include "mockdata/DutyCycleData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class DutyCycleData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Output)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Frequency)
+
+ public:
+ std::atomic<int32_t> digitalChannel{0};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{
+ false};
+ std::atomic<HAL_SimDeviceHandle> simDevice;
+ SimDataValue<int32_t, HAL_MakeInt, GetFrequencyName> frequency{0};
+ SimDataValue<double, HAL_MakeDouble, GetOutputName> output{0};
+
+ virtual void ResetData();
+};
+extern DutyCycleData* SimDutyCycleData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/EncoderData.cpp b/hal/src/main/native/sim/mockdata/EncoderData.cpp
new file mode 100644
index 0000000..33bd073
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/EncoderData.cpp
@@ -0,0 +1,85 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "../PortsInternal.h"
+#include "EncoderDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeEncoderData() {
+ static EncoderData sed[kNumEncoders];
+ ::hal::SimEncoderData = sed;
+}
+} // namespace init
+} // namespace hal
+
+EncoderData* hal::SimEncoderData;
+void EncoderData::ResetData() {
+ digitalChannelA = 0;
+ digitalChannelB = 0;
+ initialized.Reset(false);
+ simDevice = 0;
+ count.Reset(0);
+ period.Reset(std::numeric_limits<double>::max());
+ reset.Reset(false);
+ maxPeriod.Reset(0);
+ direction.Reset(false);
+ reverseDirection.Reset(false);
+ samplesToAverage.Reset(0);
+ distancePerPulse.Reset(1);
+}
+
+extern "C" {
+void HALSIM_ResetEncoderData(int32_t index) {
+ SimEncoderData[index].ResetData();
+}
+
+int32_t HALSIM_GetEncoderDigitalChannelA(int32_t index) {
+ return SimEncoderData[index].digitalChannelA;
+}
+
+int32_t HALSIM_GetEncoderDigitalChannelB(int32_t index) {
+ return SimEncoderData[index].digitalChannelB;
+}
+
+HAL_SimDeviceHandle HALSIM_GetEncoderSimDevice(int32_t index) {
+ return SimEncoderData[index].simDevice;
+}
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, Encoder##CAPINAME, \
+ SimEncoderData, LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Initialized, initialized)
+DEFINE_CAPI(int32_t, Count, count)
+DEFINE_CAPI(double, Period, period)
+DEFINE_CAPI(HAL_Bool, Reset, reset)
+DEFINE_CAPI(double, MaxPeriod, maxPeriod)
+DEFINE_CAPI(HAL_Bool, Direction, direction)
+DEFINE_CAPI(HAL_Bool, ReverseDirection, reverseDirection)
+DEFINE_CAPI(int32_t, SamplesToAverage, samplesToAverage)
+DEFINE_CAPI(double, DistancePerPulse, distancePerPulse)
+
+#define REGISTER(NAME) \
+ SimEncoderData[index].NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterEncoderAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify) {
+ REGISTER(initialized);
+ REGISTER(count);
+ REGISTER(period);
+ REGISTER(reset);
+ REGISTER(maxPeriod);
+ REGISTER(direction);
+ REGISTER(reverseDirection);
+ REGISTER(samplesToAverage);
+ REGISTER(distancePerPulse);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/EncoderDataInternal.h b/hal/src/main/native/sim/mockdata/EncoderDataInternal.h
new file mode 100644
index 0000000..389289c
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/EncoderDataInternal.h
@@ -0,0 +1,50 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <atomic>
+#include <limits>
+
+#include "mockdata/EncoderData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class EncoderData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Count)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Period)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Reset)
+ HAL_SIMDATAVALUE_DEFINE_NAME(MaxPeriod)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Direction)
+ HAL_SIMDATAVALUE_DEFINE_NAME(ReverseDirection)
+ HAL_SIMDATAVALUE_DEFINE_NAME(SamplesToAverage)
+ HAL_SIMDATAVALUE_DEFINE_NAME(DistancePerPulse)
+
+ public:
+ std::atomic<int32_t> digitalChannelA{0};
+ std::atomic<int32_t> digitalChannelB{0};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{
+ false};
+ std::atomic<HAL_SimDeviceHandle> simDevice;
+ SimDataValue<int32_t, HAL_MakeInt, GetCountName> count{0};
+ SimDataValue<double, HAL_MakeDouble, GetPeriodName> period{
+ (std::numeric_limits<double>::max)()};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetResetName> reset{false};
+ SimDataValue<double, HAL_MakeDouble, GetMaxPeriodName> maxPeriod{0};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetDirectionName> direction{false};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetReverseDirectionName>
+ reverseDirection{false};
+ SimDataValue<int32_t, HAL_MakeInt, GetSamplesToAverageName> samplesToAverage{
+ 0};
+ SimDataValue<double, HAL_MakeDouble, GetDistancePerPulseName>
+ distancePerPulse{1};
+
+ virtual void ResetData();
+};
+extern EncoderData* SimEncoderData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/I2CData.cpp b/hal/src/main/native/sim/mockdata/I2CData.cpp
new file mode 100644
index 0000000..b228c3b
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/I2CData.cpp
@@ -0,0 +1,58 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 <iostream>
+
+#include "../PortsInternal.h"
+#include "I2CDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeI2CData() {
+ static I2CData sid[2];
+ ::hal::SimI2CData = sid;
+}
+} // namespace init
+} // namespace hal
+
+I2CData* hal::SimI2CData;
+
+void I2CData::ResetData() {
+ initialized.Reset(false);
+ read.Reset();
+ write.Reset();
+}
+
+void I2CData::Write(int32_t deviceAddress, const uint8_t* dataToSend,
+ int32_t sendSize) {
+ write(dataToSend, sendSize);
+}
+
+void I2CData::Read(int32_t deviceAddress, uint8_t* buffer, int32_t count) {
+ read(buffer, count);
+}
+
+extern "C" {
+void HALSIM_ResetI2CData(int32_t index) { SimI2CData[index].ResetData(); }
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, I2C##CAPINAME, SimI2CData, \
+ LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Initialized, initialized)
+
+#undef DEFINE_CAPI
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMCALLBACKREGISTRY_DEFINE_CAPI(TYPE, HALSIM, I2C##CAPINAME, SimI2CData, \
+ LOWERNAME)
+
+DEFINE_CAPI(HAL_BufferCallback, Read, read)
+DEFINE_CAPI(HAL_ConstBufferCallback, Write, write)
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/I2CDataInternal.h b/hal/src/main/native/sim/mockdata/I2CDataInternal.h
new file mode 100644
index 0000000..c799bb7
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/I2CDataInternal.h
@@ -0,0 +1,33 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/I2CData.h"
+#include "mockdata/SimCallbackRegistry.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class I2CData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(Read)
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(Write)
+
+ public:
+ void Write(int32_t deviceAddress, const uint8_t* dataToSend,
+ int32_t sendSize);
+ void Read(int32_t deviceAddress, uint8_t* buffer, int32_t count);
+
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{
+ false};
+ SimCallbackRegistry<HAL_BufferCallback, GetReadName> read;
+ SimCallbackRegistry<HAL_ConstBufferCallback, GetWriteName> write;
+
+ void ResetData();
+};
+extern I2CData* SimI2CData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/PCMData.cpp b/hal/src/main/native/sim/mockdata/PCMData.cpp
new file mode 100644
index 0000000..6193b05
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/PCMData.cpp
@@ -0,0 +1,90 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "../PortsInternal.h"
+#include "PCMDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializePCMData() {
+ static PCMData spd[kNumPCMModules];
+ ::hal::SimPCMData = spd;
+}
+} // namespace init
+} // namespace hal
+
+PCMData* hal::SimPCMData;
+void PCMData::ResetData() {
+ for (int i = 0; i < kNumSolenoidChannels; i++) {
+ solenoidInitialized[i].Reset(false);
+ solenoidOutput[i].Reset(false);
+ }
+ compressorInitialized.Reset(false);
+ compressorOn.Reset(false);
+ closedLoopEnabled.Reset(true);
+ pressureSwitch.Reset(false);
+ compressorCurrent.Reset(0.0);
+}
+
+extern "C" {
+void HALSIM_ResetPCMData(int32_t index) { SimPCMData[index].ResetData(); }
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, PCM##CAPINAME, SimPCMData, \
+ LOWERNAME)
+
+HAL_SIMDATAVALUE_DEFINE_CAPI_CHANNEL(HAL_Bool, HALSIM, PCMSolenoidInitialized,
+ SimPCMData, solenoidInitialized)
+HAL_SIMDATAVALUE_DEFINE_CAPI_CHANNEL(HAL_Bool, HALSIM, PCMSolenoidOutput,
+ SimPCMData, solenoidOutput)
+DEFINE_CAPI(HAL_Bool, CompressorInitialized, compressorInitialized)
+DEFINE_CAPI(HAL_Bool, CompressorOn, compressorOn)
+DEFINE_CAPI(HAL_Bool, ClosedLoopEnabled, closedLoopEnabled)
+DEFINE_CAPI(HAL_Bool, PressureSwitch, pressureSwitch)
+DEFINE_CAPI(double, CompressorCurrent, compressorCurrent)
+
+void HALSIM_GetPCMAllSolenoids(int32_t index, uint8_t* values) {
+ auto& data = SimPCMData[index].solenoidOutput;
+ uint8_t ret = 0;
+ for (int i = 0; i < kNumSolenoidChannels; i++) {
+ ret |= (data[i] << i);
+ }
+ *values = ret;
+}
+
+void HALSIM_SetPCMAllSolenoids(int32_t index, uint8_t values) {
+ auto& data = SimPCMData[index].solenoidOutput;
+ for (int i = 0; i < kNumSolenoidChannels; i++) {
+ data[i] = (values & 0x1) != 0;
+ values >>= 1;
+ }
+}
+
+#define REGISTER(NAME) \
+ SimPCMData[index].NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterPCMAllNonSolenoidCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify) {
+ REGISTER(compressorInitialized);
+ REGISTER(compressorOn);
+ REGISTER(closedLoopEnabled);
+ REGISTER(pressureSwitch);
+ REGISTER(compressorCurrent);
+}
+
+void HALSIM_RegisterPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify) {
+ REGISTER(solenoidInitialized[channel]);
+ REGISTER(solenoidOutput[channel]);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/PCMDataInternal.h b/hal/src/main/native/sim/mockdata/PCMDataInternal.h
new file mode 100644
index 0000000..0c7b99b
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/PCMDataInternal.h
@@ -0,0 +1,54 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "../PortsInternal.h"
+#include "mockdata/PCMData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class PCMData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(SolenoidInitialized)
+ HAL_SIMDATAVALUE_DEFINE_NAME(SolenoidOutput)
+ HAL_SIMDATAVALUE_DEFINE_NAME(CompressorInitialized)
+ HAL_SIMDATAVALUE_DEFINE_NAME(CompressorOn)
+ HAL_SIMDATAVALUE_DEFINE_NAME(ClosedLoopEnabled)
+ HAL_SIMDATAVALUE_DEFINE_NAME(PressureSwitch)
+ HAL_SIMDATAVALUE_DEFINE_NAME(CompressorCurrent)
+
+ static LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr HAL_Bool
+ GetSolenoidInitializedDefault() {
+ return false;
+ }
+ static LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr HAL_Bool
+ GetSolenoidOutputDefault() {
+ return false;
+ }
+
+ public:
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetSolenoidInitializedName,
+ GetSolenoidInitializedDefault>
+ solenoidInitialized[kNumSolenoidChannels];
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetSolenoidOutputName,
+ GetSolenoidOutputDefault>
+ solenoidOutput[kNumSolenoidChannels];
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetCompressorInitializedName>
+ compressorInitialized{false};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetCompressorOnName> compressorOn{
+ false};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetClosedLoopEnabledName>
+ closedLoopEnabled{true};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetPressureSwitchName> pressureSwitch{
+ false};
+ SimDataValue<double, HAL_MakeDouble, GetCompressorCurrentName>
+ compressorCurrent{0.0};
+
+ virtual void ResetData();
+};
+extern PCMData* SimPCMData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/PDPData.cpp b/hal/src/main/native/sim/mockdata/PDPData.cpp
new file mode 100644
index 0000000..1c150bb
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/PDPData.cpp
@@ -0,0 +1,70 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "../PortsInternal.h"
+#include "PDPDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializePDPData() {
+ static PDPData spd[kNumPDPModules];
+ ::hal::SimPDPData = spd;
+}
+} // namespace init
+} // namespace hal
+
+PDPData* hal::SimPDPData;
+void PDPData::ResetData() {
+ initialized.Reset(false);
+ temperature.Reset(0.0);
+ voltage.Reset(12.0);
+ for (int i = 0; i < kNumPDPChannels; i++) {
+ current[i].Reset(0.0);
+ }
+}
+
+extern "C" {
+void HALSIM_ResetPDPData(int32_t index) { SimPDPData[index].ResetData(); }
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, PDP##CAPINAME, SimPDPData, \
+ LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Initialized, initialized)
+DEFINE_CAPI(double, Temperature, temperature)
+DEFINE_CAPI(double, Voltage, voltage)
+HAL_SIMDATAVALUE_DEFINE_CAPI_CHANNEL(double, HALSIM, PDPCurrent, SimPDPData,
+ current)
+
+void HALSIM_GetPDPAllCurrents(int32_t index, double* currents) {
+ auto& data = SimPDPData[index].current;
+ for (int i = 0; i < kNumPDPChannels; i++) {
+ currents[i] = data[i];
+ }
+}
+
+void HALSIM_SetPDPAllCurrents(int32_t index, const double* currents) {
+ auto& data = SimPDPData[index].current;
+ for (int i = 0; i < kNumPDPChannels; i++) {
+ data[i] = currents[i];
+ }
+}
+
+#define REGISTER(NAME) \
+ SimPDPData[index].NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterPDPAllNonCurrentCallbacks(int32_t index, int32_t channel,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify) {
+ REGISTER(initialized);
+ REGISTER(temperature);
+ REGISTER(voltage);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/PDPDataInternal.h b/hal/src/main/native/sim/mockdata/PDPDataInternal.h
new file mode 100644
index 0000000..8d45416
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/PDPDataInternal.h
@@ -0,0 +1,36 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "../PortsInternal.h"
+#include "mockdata/PDPData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class PDPData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Temperature)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Voltage)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Current)
+
+ static LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr double GetCurrentDefault() {
+ return 0.0;
+ }
+
+ public:
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{
+ false};
+ SimDataValue<double, HAL_MakeDouble, GetTemperatureName> temperature{0.0};
+ SimDataValue<double, HAL_MakeDouble, GetVoltageName> voltage{12.0};
+ SimDataValue<double, HAL_MakeDouble, GetCurrentName, GetCurrentDefault>
+ current[kNumPDPChannels];
+
+ virtual void ResetData();
+};
+extern PDPData* SimPDPData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/PWMData.cpp b/hal/src/main/native/sim/mockdata/PWMData.cpp
new file mode 100644
index 0000000..4d2121d
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/PWMData.cpp
@@ -0,0 +1,58 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "../PortsInternal.h"
+#include "PWMDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializePWMData() {
+ static PWMData spd[kNumPWMChannels];
+ ::hal::SimPWMData = spd;
+}
+} // namespace init
+} // namespace hal
+
+PWMData* hal::SimPWMData;
+void PWMData::ResetData() {
+ initialized.Reset(false);
+ rawValue.Reset(0);
+ speed.Reset(0);
+ position.Reset(0);
+ periodScale.Reset(0);
+ zeroLatch.Reset(false);
+}
+
+extern "C" {
+void HALSIM_ResetPWMData(int32_t index) { SimPWMData[index].ResetData(); }
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, PWM##CAPINAME, SimPWMData, \
+ LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Initialized, initialized)
+DEFINE_CAPI(int32_t, RawValue, rawValue)
+DEFINE_CAPI(double, Speed, speed)
+DEFINE_CAPI(double, Position, position)
+DEFINE_CAPI(int32_t, PeriodScale, periodScale)
+DEFINE_CAPI(HAL_Bool, ZeroLatch, zeroLatch)
+
+#define REGISTER(NAME) \
+ SimPWMData[index].NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterPWMAllCallbacks(int32_t index, HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify) {
+ REGISTER(initialized);
+ REGISTER(rawValue);
+ REGISTER(speed);
+ REGISTER(position);
+ REGISTER(periodScale);
+ REGISTER(zeroLatch);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/PWMDataInternal.h b/hal/src/main/native/sim/mockdata/PWMDataInternal.h
new file mode 100644
index 0000000..248b7b3
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/PWMDataInternal.h
@@ -0,0 +1,34 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/PWMData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class PWMData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+ HAL_SIMDATAVALUE_DEFINE_NAME(RawValue)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Speed)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Position)
+ HAL_SIMDATAVALUE_DEFINE_NAME(PeriodScale)
+ HAL_SIMDATAVALUE_DEFINE_NAME(ZeroLatch)
+
+ public:
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{
+ false};
+ SimDataValue<int32_t, HAL_MakeInt, GetRawValueName> rawValue{0};
+ SimDataValue<double, HAL_MakeDouble, GetSpeedName> speed{0};
+ SimDataValue<double, HAL_MakeDouble, GetPositionName> position{0};
+ SimDataValue<int32_t, HAL_MakeInt, GetPeriodScaleName> periodScale{0};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetZeroLatchName> zeroLatch{false};
+
+ virtual void ResetData();
+};
+extern PWMData* SimPWMData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/RelayData.cpp b/hal/src/main/native/sim/mockdata/RelayData.cpp
new file mode 100644
index 0000000..4623203
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/RelayData.cpp
@@ -0,0 +1,53 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "../PortsInternal.h"
+#include "RelayDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeRelayData() {
+ static RelayData srd[kNumRelayHeaders];
+ ::hal::SimRelayData = srd;
+}
+} // namespace init
+} // namespace hal
+
+RelayData* hal::SimRelayData;
+void RelayData::ResetData() {
+ initializedForward.Reset(false);
+ initializedReverse.Reset(false);
+ forward.Reset(false);
+ reverse.Reset(false);
+}
+
+extern "C" {
+void HALSIM_ResetRelayData(int32_t index) { SimRelayData[index].ResetData(); }
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, Relay##CAPINAME, SimRelayData, \
+ LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, InitializedForward, initializedForward)
+DEFINE_CAPI(HAL_Bool, InitializedReverse, initializedReverse)
+DEFINE_CAPI(HAL_Bool, Forward, forward)
+DEFINE_CAPI(HAL_Bool, Reverse, reverse)
+
+#define REGISTER(NAME) \
+ SimRelayData[index].NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterRelayAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify) {
+ REGISTER(initializedForward);
+ REGISTER(initializedReverse);
+ REGISTER(forward);
+ REGISTER(reverse);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/RelayDataInternal.h b/hal/src/main/native/sim/mockdata/RelayDataInternal.h
new file mode 100644
index 0000000..cb38388
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/RelayDataInternal.h
@@ -0,0 +1,31 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/RelayData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class RelayData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(InitializedForward)
+ HAL_SIMDATAVALUE_DEFINE_NAME(InitializedReverse)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Forward)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Reverse)
+
+ public:
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedForwardName>
+ initializedForward{false};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedReverseName>
+ initializedReverse{false};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetForwardName> forward{false};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetReverseName> reverse{false};
+
+ virtual void ResetData();
+};
+extern RelayData* SimRelayData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/RoboRioData.cpp b/hal/src/main/native/sim/mockdata/RoboRioData.cpp
new file mode 100644
index 0000000..5cff1d9
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/RoboRioData.cpp
@@ -0,0 +1,88 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "../PortsInternal.h"
+#include "RoboRioDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeRoboRioData() {
+ static RoboRioData srrd[1];
+ ::hal::SimRoboRioData = srrd;
+}
+} // namespace init
+} // namespace hal
+
+RoboRioData* hal::SimRoboRioData;
+void RoboRioData::ResetData() {
+ fpgaButton.Reset(false);
+ vInVoltage.Reset(0.0);
+ vInCurrent.Reset(0.0);
+ userVoltage6V.Reset(6.0);
+ userCurrent6V.Reset(0.0);
+ userActive6V.Reset(false);
+ userVoltage5V.Reset(5.0);
+ userCurrent5V.Reset(0.0);
+ userActive5V.Reset(false);
+ userVoltage3V3.Reset(3.3);
+ userCurrent3V3.Reset(0.0);
+ userActive3V3.Reset(false);
+ userFaults6V.Reset(0);
+ userFaults5V.Reset(0);
+ userFaults3V3.Reset(0);
+}
+
+extern "C" {
+void HALSIM_ResetRoboRioData(int32_t index) {
+ SimRoboRioData[index].ResetData();
+}
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, RoboRio##CAPINAME, \
+ SimRoboRioData, LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, FPGAButton, fpgaButton)
+DEFINE_CAPI(double, VInVoltage, vInVoltage)
+DEFINE_CAPI(double, VInCurrent, vInCurrent)
+DEFINE_CAPI(double, UserVoltage6V, userVoltage6V)
+DEFINE_CAPI(double, UserCurrent6V, userCurrent6V)
+DEFINE_CAPI(HAL_Bool, UserActive6V, userActive6V)
+DEFINE_CAPI(double, UserVoltage5V, userVoltage5V)
+DEFINE_CAPI(double, UserCurrent5V, userCurrent5V)
+DEFINE_CAPI(HAL_Bool, UserActive5V, userActive5V)
+DEFINE_CAPI(double, UserVoltage3V3, userVoltage3V3)
+DEFINE_CAPI(double, UserCurrent3V3, userCurrent3V3)
+DEFINE_CAPI(HAL_Bool, UserActive3V3, userActive3V3)
+DEFINE_CAPI(int32_t, UserFaults6V, userFaults6V)
+DEFINE_CAPI(int32_t, UserFaults5V, userFaults5V)
+DEFINE_CAPI(int32_t, UserFaults3V3, userFaults3V3)
+
+#define REGISTER(NAME) \
+ SimRoboRioData[index].NAME.RegisterCallback(callback, param, initialNotify)
+
+void HALSIM_RegisterRoboRioAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify) {
+ REGISTER(fpgaButton);
+ REGISTER(vInVoltage);
+ REGISTER(vInCurrent);
+ REGISTER(userVoltage6V);
+ REGISTER(userCurrent6V);
+ REGISTER(userActive6V);
+ REGISTER(userVoltage5V);
+ REGISTER(userCurrent5V);
+ REGISTER(userActive5V);
+ REGISTER(userVoltage3V3);
+ REGISTER(userCurrent3V3);
+ REGISTER(userActive3V3);
+ REGISTER(userFaults6V);
+ REGISTER(userFaults5V);
+ REGISTER(userFaults3V3);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/RoboRioDataInternal.h b/hal/src/main/native/sim/mockdata/RoboRioDataInternal.h
new file mode 100644
index 0000000..cc74fa2
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/RoboRioDataInternal.h
@@ -0,0 +1,56 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/RoboRioData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class RoboRioData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(FPGAButton)
+ HAL_SIMDATAVALUE_DEFINE_NAME(VInVoltage)
+ HAL_SIMDATAVALUE_DEFINE_NAME(VInCurrent)
+ HAL_SIMDATAVALUE_DEFINE_NAME(UserVoltage6V)
+ HAL_SIMDATAVALUE_DEFINE_NAME(UserCurrent6V)
+ HAL_SIMDATAVALUE_DEFINE_NAME(UserActive6V)
+ HAL_SIMDATAVALUE_DEFINE_NAME(UserVoltage5V)
+ HAL_SIMDATAVALUE_DEFINE_NAME(UserCurrent5V)
+ HAL_SIMDATAVALUE_DEFINE_NAME(UserActive5V)
+ HAL_SIMDATAVALUE_DEFINE_NAME(UserVoltage3V3)
+ HAL_SIMDATAVALUE_DEFINE_NAME(UserCurrent3V3)
+ HAL_SIMDATAVALUE_DEFINE_NAME(UserActive3V3)
+ HAL_SIMDATAVALUE_DEFINE_NAME(UserFaults6V)
+ HAL_SIMDATAVALUE_DEFINE_NAME(UserFaults5V)
+ HAL_SIMDATAVALUE_DEFINE_NAME(UserFaults3V3)
+
+ public:
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetFPGAButtonName> fpgaButton{false};
+ SimDataValue<double, HAL_MakeDouble, GetVInVoltageName> vInVoltage{0.0};
+ SimDataValue<double, HAL_MakeDouble, GetVInCurrentName> vInCurrent{0.0};
+ SimDataValue<double, HAL_MakeDouble, GetUserVoltage6VName> userVoltage6V{6.0};
+ SimDataValue<double, HAL_MakeDouble, GetUserCurrent6VName> userCurrent6V{0.0};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetUserActive6VName> userActive6V{
+ false};
+ SimDataValue<double, HAL_MakeDouble, GetUserVoltage5VName> userVoltage5V{5.0};
+ SimDataValue<double, HAL_MakeDouble, GetUserCurrent5VName> userCurrent5V{0.0};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetUserActive5VName> userActive5V{
+ false};
+ SimDataValue<double, HAL_MakeDouble, GetUserVoltage3V3Name> userVoltage3V3{
+ 3.3};
+ SimDataValue<double, HAL_MakeDouble, GetUserCurrent3V3Name> userCurrent3V3{
+ 0.0};
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetUserActive3V3Name> userActive3V3{
+ false};
+ SimDataValue<int32_t, HAL_MakeInt, GetUserFaults6VName> userFaults6V{0};
+ SimDataValue<int32_t, HAL_MakeInt, GetUserFaults5VName> userFaults5V{0};
+ SimDataValue<int32_t, HAL_MakeInt, GetUserFaults3V3Name> userFaults3V3{0};
+
+ virtual void ResetData();
+};
+extern RoboRioData* SimRoboRioData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/SPIAccelerometerData.cpp b/hal/src/main/native/sim/mockdata/SPIAccelerometerData.cpp
new file mode 100644
index 0000000..db7dc1d
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/SPIAccelerometerData.cpp
@@ -0,0 +1,60 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 "../PortsInternal.h"
+#include "SPIAccelerometerDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeSPIAccelerometerData() {
+ static SPIAccelerometerData ssad[5];
+ ::hal::SimSPIAccelerometerData = ssad;
+}
+} // namespace init
+} // namespace hal
+
+SPIAccelerometerData* hal::SimSPIAccelerometerData;
+void SPIAccelerometerData::ResetData() {
+ active.Reset(false);
+ range.Reset(0);
+ x.Reset(0.0);
+ y.Reset(0.0);
+ z.Reset(0.0);
+}
+
+extern "C" {
+void HALSIM_ResetSPIAccelerometerData(int32_t index) {
+ SimSPIAccelerometerData[index].ResetData();
+}
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, SPIAccelerometer##CAPINAME, \
+ SimSPIAccelerometerData, LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Active, active)
+DEFINE_CAPI(int32_t, Range, range)
+DEFINE_CAPI(double, X, x)
+DEFINE_CAPI(double, Y, y)
+DEFINE_CAPI(double, Z, z)
+
+#define REGISTER(NAME) \
+ SimSPIAccelerometerData[index].NAME.RegisterCallback(callback, param, \
+ initialNotify)
+
+void HALSIM_RegisterSPIAccelerometerAllCallbcaks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify) {
+ REGISTER(active);
+ REGISTER(range);
+ REGISTER(x);
+ REGISTER(y);
+ REGISTER(z);
+}
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/SPIAccelerometerDataInternal.h b/hal/src/main/native/sim/mockdata/SPIAccelerometerDataInternal.h
new file mode 100644
index 0000000..661e01b
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/SPIAccelerometerDataInternal.h
@@ -0,0 +1,31 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/SPIAccelerometerData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class SPIAccelerometerData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Active)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Range)
+ HAL_SIMDATAVALUE_DEFINE_NAME(X)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Y)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Z)
+
+ public:
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetActiveName> active{false};
+ SimDataValue<int32_t, HAL_MakeInt, GetRangeName> range{0};
+ SimDataValue<double, HAL_MakeDouble, GetXName> x{0.0};
+ SimDataValue<double, HAL_MakeDouble, GetYName> y{0.0};
+ SimDataValue<double, HAL_MakeDouble, GetZName> z{0.0};
+
+ virtual void ResetData();
+};
+extern SPIAccelerometerData* SimSPIAccelerometerData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/SPIData.cpp b/hal/src/main/native/sim/mockdata/SPIData.cpp
new file mode 100644
index 0000000..3afc606
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/SPIData.cpp
@@ -0,0 +1,75 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2018 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 <iostream>
+
+#include "../PortsInternal.h"
+#include "SPIDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeSPIData() {
+ static SPIData ssd[5];
+ ::hal::SimSPIData = ssd;
+}
+} // namespace init
+} // namespace hal
+
+SPIData* hal::SimSPIData;
+void SPIData::ResetData() {
+ initialized.Reset(false);
+ read.Reset();
+ write.Reset();
+ autoReceivedData.Reset();
+}
+
+int32_t SPIData::Read(uint8_t* buffer, int32_t count) {
+ read(buffer, count);
+ return count;
+}
+
+int32_t SPIData::Write(const uint8_t* dataToSend, int32_t sendSize) {
+ write(dataToSend, sendSize);
+ return sendSize;
+}
+
+int32_t SPIData::Transaction(const uint8_t* dataToSend, uint8_t* dataReceived,
+ int32_t size) {
+ write(dataToSend, size);
+ read(dataReceived, size);
+ return size;
+}
+
+int32_t SPIData::ReadAutoReceivedData(uint32_t* buffer, int32_t numToRead,
+ double timeout, int32_t* status) {
+ int32_t outputCount = 0;
+ autoReceivedData(buffer, numToRead, &outputCount);
+ return outputCount;
+}
+
+extern "C" {
+void HALSIM_ResetSPIData(int32_t index) { SimSPIData[index].ResetData(); }
+
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, SPI##CAPINAME, SimSPIData, \
+ LOWERNAME)
+
+DEFINE_CAPI(HAL_Bool, Initialized, initialized)
+
+#undef DEFINE_CAPI
+#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
+ HAL_SIMCALLBACKREGISTRY_DEFINE_CAPI(TYPE, HALSIM, SPI##CAPINAME, SimSPIData, \
+ LOWERNAME)
+
+DEFINE_CAPI(HAL_BufferCallback, Read, read)
+DEFINE_CAPI(HAL_ConstBufferCallback, Write, write)
+DEFINE_CAPI(HAL_SpiReadAutoReceiveBufferCallback, ReadAutoReceivedData,
+ autoReceivedData)
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/SPIDataInternal.h b/hal/src/main/native/sim/mockdata/SPIDataInternal.h
new file mode 100644
index 0000000..44868d2
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/SPIDataInternal.h
@@ -0,0 +1,40 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include "mockdata/SPIData.h"
+#include "mockdata/SimCallbackRegistry.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+
+class SPIData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(Read)
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(Write)
+ HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(AutoReceive)
+
+ public:
+ int32_t Read(uint8_t* buffer, int32_t count);
+ int32_t Write(const uint8_t* dataToSend, int32_t sendSize);
+ int32_t Transaction(const uint8_t* dataToSend, uint8_t* dataReceived,
+ int32_t size);
+ int32_t ReadAutoReceivedData(uint32_t* buffer, int32_t numToRead,
+ double timeout, int32_t* status);
+
+ SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{
+ false};
+ SimCallbackRegistry<HAL_BufferCallback, GetReadName> read;
+ SimCallbackRegistry<HAL_ConstBufferCallback, GetWriteName> write;
+ SimCallbackRegistry<HAL_SpiReadAutoReceiveBufferCallback, GetAutoReceiveName>
+ autoReceivedData;
+
+ void ResetData();
+};
+extern SPIData* SimSPIData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/SimDeviceData.cpp b/hal/src/main/native/sim/mockdata/SimDeviceData.cpp
new file mode 100644
index 0000000..a703257
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/SimDeviceData.cpp
@@ -0,0 +1,414 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "mockdata/SimDeviceData.h" // NOLINT(build/include_order)
+
+#include <algorithm>
+
+#include "SimDeviceDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeSimDeviceData() {
+ static SimDeviceData sdd;
+ ::hal::SimSimDeviceData = &sdd;
+}
+} // namespace init
+} // namespace hal
+
+SimDeviceData* hal::SimSimDeviceData;
+
+SimDeviceData::Device* SimDeviceData::LookupDevice(HAL_SimDeviceHandle handle) {
+ if (handle <= 0) return nullptr;
+ --handle;
+ if (static_cast<uint32_t>(handle) >= m_devices.size() || !m_devices[handle])
+ return nullptr;
+ return m_devices[handle].get();
+}
+
+SimDeviceData::Value* SimDeviceData::LookupValue(HAL_SimValueHandle handle) {
+ if (handle <= 0) return nullptr;
+
+ // look up device
+ Device* deviceImpl = LookupDevice(handle >> 16);
+ if (!deviceImpl) return nullptr;
+
+ // look up value
+ handle &= 0xffff;
+ --handle;
+ if (static_cast<uint32_t>(handle) >= deviceImpl->values.size() ||
+ !deviceImpl->values[handle])
+ return nullptr;
+
+ return deviceImpl->values[handle].get();
+}
+
+HAL_SimDeviceHandle SimDeviceData::CreateDevice(const char* name) {
+ std::scoped_lock lock(m_mutex);
+
+ // check for duplicates and don't overwrite them
+ auto it = m_deviceMap.find(name);
+ if (it != m_deviceMap.end()) return 0;
+
+ // don't allow more than 4096 devices (limit driven by 12-bit allocation in
+ // value changed callback uid)
+ if (m_devices.size() >= 4095) return 0;
+
+ // create and save
+ auto deviceImpl = std::make_shared<Device>(name);
+ HAL_SimDeviceHandle deviceHandle = m_devices.emplace_back(deviceImpl) + 1;
+ deviceImpl->handle = deviceHandle;
+ m_deviceMap[name] = deviceImpl;
+
+ // notify callbacks
+ m_deviceCreated(name, deviceHandle);
+
+ return deviceHandle;
+}
+
+void SimDeviceData::FreeDevice(HAL_SimDeviceHandle handle) {
+ std::scoped_lock lock(m_mutex);
+ --handle;
+
+ // see if it exists
+ if (handle < 0 || static_cast<uint32_t>(handle) >= m_devices.size()) return;
+ auto deviceImpl = std::move(m_devices[handle]);
+ if (!deviceImpl) return;
+
+ // remove from map
+ m_deviceMap.erase(deviceImpl->name);
+
+ // remove from vector
+ m_devices.erase(handle);
+
+ // notify callbacks
+ m_deviceFreed(deviceImpl->name.c_str(), handle + 1);
+}
+
+HAL_SimValueHandle SimDeviceData::CreateValue(HAL_SimDeviceHandle device,
+ const char* name, bool readonly,
+ int32_t numOptions,
+ const char** options,
+ const HAL_Value& initialValue) {
+ std::scoped_lock lock(m_mutex);
+
+ // look up device
+ Device* deviceImpl = LookupDevice(device);
+ if (!deviceImpl) return 0;
+
+ // check for duplicates and don't overwrite them
+ auto it = deviceImpl->valueMap.find(name);
+ if (it != deviceImpl->valueMap.end()) return 0;
+
+ // don't allow more than 4096 values per device (limit driven by 12-bit
+ // allocation in value changed callback uid)
+ if (deviceImpl->values.size() >= 4095) return 0;
+
+ // create and save; encode device into handle
+ auto valueImplPtr = std::make_unique<Value>(name, readonly, initialValue);
+ Value* valueImpl = valueImplPtr.get();
+ HAL_SimValueHandle valueHandle =
+ (device << 16) |
+ (deviceImpl->values.emplace_back(std::move(valueImplPtr)) + 1);
+ valueImpl->handle = valueHandle;
+ // copy options (if any provided)
+ if (numOptions > 0 && options) {
+ valueImpl->enumOptions.reserve(numOptions);
+ valueImpl->cstrEnumOptions.reserve(numOptions);
+ for (int32_t i = 0; i < numOptions; ++i) {
+ valueImpl->enumOptions.emplace_back(options[i]);
+ // point to our copy of the string, not the passed-in one
+ valueImpl->cstrEnumOptions.emplace_back(
+ valueImpl->enumOptions.back().c_str());
+ }
+ }
+ deviceImpl->valueMap[name] = valueImpl;
+
+ // notify callbacks
+ deviceImpl->valueCreated(name, valueHandle, readonly, &initialValue);
+
+ return valueHandle;
+}
+
+HAL_Value SimDeviceData::GetValue(HAL_SimValueHandle handle) {
+ std::scoped_lock lock(m_mutex);
+ Value* valueImpl = LookupValue(handle);
+
+ if (!valueImpl) {
+ HAL_Value value;
+ value.data.v_int = 0;
+ value.type = HAL_UNASSIGNED;
+ return value;
+ }
+
+ return valueImpl->value;
+}
+
+void SimDeviceData::SetValue(HAL_SimValueHandle handle,
+ const HAL_Value& value) {
+ std::scoped_lock lock(m_mutex);
+ Value* valueImpl = LookupValue(handle);
+ if (!valueImpl) return;
+
+ valueImpl->value = value;
+
+ // notify callbacks
+ valueImpl->changed(valueImpl->name.c_str(), valueImpl->handle,
+ valueImpl->readonly, &value);
+}
+
+int32_t SimDeviceData::RegisterDeviceCreatedCallback(
+ const char* prefix, void* param, HALSIM_SimDeviceCallback callback,
+ bool initialNotify) {
+ std::scoped_lock lock(m_mutex);
+
+ // register callback
+ int32_t index = m_deviceCreated.Register(prefix, param, callback);
+
+ // initial notifications
+ if (initialNotify) {
+ for (auto&& device : m_devices)
+ callback(device->name.c_str(), param, device->handle);
+ }
+
+ return index;
+}
+
+void SimDeviceData::CancelDeviceCreatedCallback(int32_t uid) {
+ if (uid <= 0) return;
+ std::scoped_lock lock(m_mutex);
+ m_deviceCreated.Cancel(uid);
+}
+
+int32_t SimDeviceData::RegisterDeviceFreedCallback(
+ const char* prefix, void* param, HALSIM_SimDeviceCallback callback) {
+ std::scoped_lock lock(m_mutex);
+ return m_deviceFreed.Register(prefix, param, callback);
+}
+
+void SimDeviceData::CancelDeviceFreedCallback(int32_t uid) {
+ if (uid <= 0) return;
+ std::scoped_lock lock(m_mutex);
+ m_deviceFreed.Cancel(uid);
+}
+
+HAL_SimDeviceHandle SimDeviceData::GetDeviceHandle(const char* name) {
+ std::scoped_lock lock(m_mutex);
+ auto it = m_deviceMap.find(name);
+ if (it == m_deviceMap.end()) return 0;
+ if (auto deviceImpl = it->getValue().lock())
+ return deviceImpl->handle;
+ else
+ return 0;
+}
+
+const char* SimDeviceData::GetDeviceName(HAL_SimDeviceHandle handle) {
+ std::scoped_lock lock(m_mutex);
+
+ // look up device
+ Device* deviceImpl = LookupDevice(handle);
+ if (!deviceImpl) return nullptr;
+
+ return deviceImpl->name.c_str();
+}
+
+void SimDeviceData::EnumerateDevices(const char* prefix, void* param,
+ HALSIM_SimDeviceCallback callback) {
+ std::scoped_lock lock(m_mutex);
+ for (auto&& device : m_devices) {
+ if (wpi::StringRef{device->name}.startswith(prefix))
+ callback(device->name.c_str(), param, device->handle);
+ }
+}
+
+int32_t SimDeviceData::RegisterValueCreatedCallback(
+ HAL_SimDeviceHandle device, void* param, HALSIM_SimValueCallback callback,
+ bool initialNotify) {
+ std::scoped_lock lock(m_mutex);
+ Device* deviceImpl = LookupDevice(device);
+ if (!deviceImpl) return -1;
+
+ // register callback
+ int32_t index = deviceImpl->valueCreated.Register(callback, param);
+
+ // initial notifications
+ if (initialNotify) {
+ for (auto&& value : deviceImpl->values)
+ callback(value->name.c_str(), param, value->handle, value->readonly,
+ &value->value);
+ }
+
+ // encode device into uid
+ return (device << 16) | (index & 0xffff);
+}
+
+void SimDeviceData::CancelValueCreatedCallback(int32_t uid) {
+ if (uid <= 0) return;
+ std::scoped_lock lock(m_mutex);
+ Device* deviceImpl = LookupDevice(uid >> 16);
+ if (!deviceImpl) return;
+ deviceImpl->valueCreated.Cancel(uid & 0xffff);
+}
+
+int32_t SimDeviceData::RegisterValueChangedCallback(
+ HAL_SimValueHandle handle, void* param, HALSIM_SimValueCallback callback,
+ bool initialNotify) {
+ std::scoped_lock lock(m_mutex);
+ Value* valueImpl = LookupValue(handle);
+ if (!valueImpl) return -1;
+
+ // register callback
+ int32_t index = valueImpl->changed.Register(callback, param);
+
+ // initial notification
+ if (initialNotify)
+ callback(valueImpl->name.c_str(), param, valueImpl->handle,
+ valueImpl->readonly, &valueImpl->value);
+
+ // encode device and value into uid
+ return (((handle >> 16) & 0xfff) << 19) | ((handle & 0xfff) << 7) |
+ (index & 0x7f);
+}
+
+void SimDeviceData::CancelValueChangedCallback(int32_t uid) {
+ if (uid <= 0) return;
+ std::scoped_lock lock(m_mutex);
+ Value* valueImpl = LookupValue(((uid >> 19) << 16) | ((uid >> 7) & 0xfff));
+ if (!valueImpl) return;
+ valueImpl->changed.Cancel(uid & 0x7f);
+}
+
+HAL_SimValueHandle SimDeviceData::GetValueHandle(HAL_SimDeviceHandle device,
+ const char* name) {
+ std::scoped_lock lock(m_mutex);
+ Device* deviceImpl = LookupDevice(device);
+ if (!deviceImpl) return 0;
+
+ // lookup value
+ auto it = deviceImpl->valueMap.find(name);
+ if (it == deviceImpl->valueMap.end()) return 0;
+ if (!it->getValue()) return 0;
+ return it->getValue()->handle;
+}
+
+void SimDeviceData::EnumerateValues(HAL_SimDeviceHandle device, void* param,
+ HALSIM_SimValueCallback callback) {
+ std::scoped_lock lock(m_mutex);
+ Device* deviceImpl = LookupDevice(device);
+ if (!deviceImpl) return;
+
+ for (auto&& value : deviceImpl->values)
+ callback(value->name.c_str(), param, value->handle, value->readonly,
+ &value->value);
+}
+
+const char** SimDeviceData::GetValueEnumOptions(HAL_SimValueHandle handle,
+ int32_t* numOptions) {
+ *numOptions = 0;
+
+ std::scoped_lock lock(m_mutex);
+ Value* valueImpl = LookupValue(handle);
+ if (!valueImpl) return nullptr;
+
+ // get list of options (safe to return as they never change)
+ auto& options = valueImpl->cstrEnumOptions;
+ *numOptions = options.size();
+ return options.data();
+}
+
+void SimDeviceData::ResetData() {
+ std::scoped_lock lock(m_mutex);
+ m_devices.clear();
+ m_deviceMap.clear();
+ m_deviceCreated.Reset();
+ m_deviceFreed.Reset();
+}
+
+extern "C" {
+
+int32_t HALSIM_RegisterSimDeviceCreatedCallback(
+ const char* prefix, void* param, HALSIM_SimDeviceCallback callback,
+ HAL_Bool initialNotify) {
+ return SimSimDeviceData->RegisterDeviceCreatedCallback(
+ prefix, param, callback, initialNotify);
+}
+
+void HALSIM_CancelSimDeviceCreatedCallback(int32_t uid) {
+ SimSimDeviceData->CancelDeviceCreatedCallback(uid);
+}
+
+int32_t HALSIM_RegisterSimDeviceFreedCallback(
+ const char* prefix, void* param, HALSIM_SimDeviceCallback callback) {
+ return SimSimDeviceData->RegisterDeviceFreedCallback(prefix, param, callback);
+}
+
+void HALSIM_CancelSimDeviceFreedCallback(int32_t uid) {
+ SimSimDeviceData->CancelDeviceFreedCallback(uid);
+}
+
+HAL_SimDeviceHandle HALSIM_GetSimDeviceHandle(const char* name) {
+ return SimSimDeviceData->GetDeviceHandle(name);
+}
+
+const char* HALSIM_GetSimDeviceName(HAL_SimDeviceHandle handle) {
+ return SimSimDeviceData->GetDeviceName(handle);
+}
+
+HAL_SimDeviceHandle HALSIM_GetSimValueDeviceHandle(HAL_SimValueHandle handle) {
+ if (handle <= 0) return 0;
+ return handle >> 16;
+}
+
+void HALSIM_EnumerateSimDevices(const char* prefix, void* param,
+ HALSIM_SimDeviceCallback callback) {
+ SimSimDeviceData->EnumerateDevices(prefix, param, callback);
+}
+
+int32_t HALSIM_RegisterSimValueCreatedCallback(HAL_SimDeviceHandle device,
+ void* param,
+ HALSIM_SimValueCallback callback,
+ HAL_Bool initialNotify) {
+ return SimSimDeviceData->RegisterValueCreatedCallback(device, param, callback,
+ initialNotify);
+}
+
+void HALSIM_CancelSimValueCreatedCallback(int32_t uid) {
+ SimSimDeviceData->CancelValueCreatedCallback(uid);
+}
+
+int32_t HALSIM_RegisterSimValueChangedCallback(HAL_SimValueHandle handle,
+ void* param,
+ HALSIM_SimValueCallback callback,
+ HAL_Bool initialNotify) {
+ return SimSimDeviceData->RegisterValueChangedCallback(handle, param, callback,
+ initialNotify);
+}
+
+void HALSIM_CancelSimValueChangedCallback(int32_t uid) {
+ SimSimDeviceData->CancelValueChangedCallback(uid);
+}
+
+HAL_SimValueHandle HALSIM_GetSimValueHandle(HAL_SimDeviceHandle device,
+ const char* name) {
+ return SimSimDeviceData->GetValueHandle(device, name);
+}
+
+void HALSIM_EnumerateSimValues(HAL_SimDeviceHandle device, void* param,
+ HALSIM_SimValueCallback callback) {
+ SimSimDeviceData->EnumerateValues(device, param, callback);
+}
+
+const char** HALSIM_GetSimValueEnumOptions(HAL_SimValueHandle handle,
+ int32_t* numOptions) {
+ return SimSimDeviceData->GetValueEnumOptions(handle, numOptions);
+}
+
+void HALSIM_ResetSimDeviceData(void) { SimSimDeviceData->ResetData(); }
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/mockdata/SimDeviceDataInternal.h b/hal/src/main/native/sim/mockdata/SimDeviceDataInternal.h
new file mode 100644
index 0000000..2582eca
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/SimDeviceDataInternal.h
@@ -0,0 +1,214 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <stdint.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <wpi/StringMap.h>
+#include <wpi/UidVector.h>
+#include <wpi/spinlock.h>
+
+#include "hal/Value.h"
+#include "mockdata/SimCallbackRegistry.h"
+#include "mockdata/SimDeviceData.h"
+
+namespace hal {
+
+namespace impl {
+
+template <typename CallbackFunction>
+class SimUnnamedCallbackRegistry {
+ public:
+ using RawFunctor = void (*)();
+
+ protected:
+ using CallbackVector = wpi::UidVector<HalCallbackListener<RawFunctor>, 4>;
+
+ public:
+ void Cancel(int32_t uid) {
+ if (m_callbacks) m_callbacks->erase(uid - 1);
+ }
+
+ void Reset() {
+ if (m_callbacks) m_callbacks->clear();
+ }
+
+ int32_t Register(CallbackFunction callback, void* param) {
+ // Must return -1 on a null callback for error handling
+ if (callback == nullptr) return -1;
+ if (!m_callbacks) m_callbacks = std::make_unique<CallbackVector>();
+ return m_callbacks->emplace_back(param,
+ reinterpret_cast<RawFunctor>(callback)) +
+ 1;
+ }
+
+ template <typename... U>
+ void Invoke(const char* name, U&&... u) const {
+ if (m_callbacks) {
+ for (auto&& cb : *m_callbacks) {
+ reinterpret_cast<CallbackFunction>(cb.callback)(name, cb.param,
+ std::forward<U>(u)...);
+ }
+ }
+ }
+
+ template <typename... U>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE void operator()(U&&... u) const {
+ return Invoke(std::forward<U>(u)...);
+ }
+
+ private:
+ std::unique_ptr<CallbackVector> m_callbacks;
+};
+
+template <typename CallbackFunction>
+class SimPrefixCallbackRegistry {
+ struct CallbackData {
+ CallbackData() = default;
+ CallbackData(const char* prefix_, void* param_, CallbackFunction callback_)
+ : prefix{prefix_}, callback{callback_}, param{param_} {}
+ std::string prefix;
+ CallbackFunction callback;
+ void* param;
+
+ explicit operator bool() const { return callback != nullptr; }
+ };
+ using CallbackVector = wpi::UidVector<CallbackData, 4>;
+
+ public:
+ void Cancel(int32_t uid) {
+ if (m_callbacks) m_callbacks->erase(uid - 1);
+ }
+
+ void Reset() {
+ if (m_callbacks) m_callbacks->clear();
+ }
+
+ int32_t Register(const char* prefix, void* param, CallbackFunction callback) {
+ // Must return -1 on a null callback for error handling
+ if (callback == nullptr) return -1;
+ if (!m_callbacks) m_callbacks = std::make_unique<CallbackVector>();
+ return m_callbacks->emplace_back(prefix, param, callback) + 1;
+ }
+
+ template <typename... U>
+ void Invoke(const char* name, U&&... u) const {
+ if (m_callbacks) {
+ for (auto&& cb : *m_callbacks) {
+ if (wpi::StringRef{name}.startswith(cb.prefix)) {
+ cb.callback(name, cb.param, std::forward<U>(u)...);
+ }
+ }
+ }
+ }
+
+ template <typename... U>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE void operator()(U&&... u) const {
+ return Invoke(std::forward<U>(u)...);
+ }
+
+ private:
+ std::unique_ptr<CallbackVector> m_callbacks;
+};
+
+} // namespace impl
+
+class SimDeviceData {
+ private:
+ struct Value {
+ Value(const char* name_, bool readonly_, const HAL_Value& value_)
+ : name{name_}, readonly{readonly_}, value{value_} {}
+
+ HAL_SimValueHandle handle{0};
+ std::string name;
+ bool readonly;
+ HAL_Value value;
+ std::vector<std::string> enumOptions;
+ std::vector<const char*> cstrEnumOptions;
+ impl::SimUnnamedCallbackRegistry<HALSIM_SimValueCallback> changed;
+ };
+
+ struct Device {
+ explicit Device(const char* name_) : name{name_} {}
+
+ HAL_SimDeviceHandle handle{0};
+ std::string name;
+ wpi::UidVector<std::unique_ptr<Value>, 16> values;
+ wpi::StringMap<Value*> valueMap;
+ impl::SimUnnamedCallbackRegistry<HALSIM_SimValueCallback> valueCreated;
+ };
+
+ wpi::UidVector<std::shared_ptr<Device>, 4> m_devices;
+ wpi::StringMap<std::weak_ptr<Device>> m_deviceMap;
+
+ wpi::recursive_spinlock m_mutex;
+
+ impl::SimPrefixCallbackRegistry<HALSIM_SimDeviceCallback> m_deviceCreated;
+ impl::SimPrefixCallbackRegistry<HALSIM_SimDeviceCallback> m_deviceFreed;
+
+ // call with lock held, returns null if does not exist
+ Device* LookupDevice(HAL_SimDeviceHandle handle);
+ Value* LookupValue(HAL_SimValueHandle handle);
+
+ public:
+ HAL_SimDeviceHandle CreateDevice(const char* name);
+ void FreeDevice(HAL_SimDeviceHandle handle);
+ HAL_SimValueHandle CreateValue(HAL_SimDeviceHandle device, const char* name,
+ bool readonly, int32_t numOptions,
+ const char** options,
+ const HAL_Value& initialValue);
+ HAL_Value GetValue(HAL_SimValueHandle handle);
+ void SetValue(HAL_SimValueHandle handle, const HAL_Value& value);
+
+ int32_t RegisterDeviceCreatedCallback(const char* prefix, void* param,
+ HALSIM_SimDeviceCallback callback,
+ bool initialNotify);
+
+ void CancelDeviceCreatedCallback(int32_t uid);
+
+ int32_t RegisterDeviceFreedCallback(const char* prefix, void* param,
+ HALSIM_SimDeviceCallback callback);
+
+ void CancelDeviceFreedCallback(int32_t uid);
+
+ HAL_SimDeviceHandle GetDeviceHandle(const char* name);
+ const char* GetDeviceName(HAL_SimDeviceHandle handle);
+
+ void EnumerateDevices(const char* prefix, void* param,
+ HALSIM_SimDeviceCallback callback);
+
+ int32_t RegisterValueCreatedCallback(HAL_SimDeviceHandle device, void* param,
+ HALSIM_SimValueCallback callback,
+ bool initialNotify);
+
+ void CancelValueCreatedCallback(int32_t uid);
+
+ int32_t RegisterValueChangedCallback(HAL_SimValueHandle handle, void* param,
+ HALSIM_SimValueCallback callback,
+ bool initialNotify);
+
+ void CancelValueChangedCallback(int32_t uid);
+
+ HAL_SimValueHandle GetValueHandle(HAL_SimDeviceHandle device,
+ const char* name);
+
+ void EnumerateValues(HAL_SimDeviceHandle device, void* param,
+ HALSIM_SimValueCallback callback);
+
+ const char** GetValueEnumOptions(HAL_SimValueHandle handle,
+ int32_t* numOptions);
+
+ void ResetData();
+};
+extern SimDeviceData* SimSimDeviceData;
+} // namespace hal