Squashed 'third_party/allwpilib_2019/' content from commit bd05dfa1c
Change-Id: I2b1c2250cdb9b055133780c33593292098c375b7
git-subtree-dir: third_party/allwpilib_2019
git-subtree-split: bd05dfa1c7cca74c4fac451e7b9d6a37e7b53447
diff --git a/hal/src/dev/java/DevMain.java b/hal/src/dev/java/DevMain.java
new file mode 100644
index 0000000..8cdb8ba
--- /dev/null
+++ b/hal/src/dev/java/DevMain.java
@@ -0,0 +1,15 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+public final class DevMain {
+ public static void main(String[] args) {
+
+ }
+
+ private DevMain() {
+ }
+}
diff --git a/hal/src/dev/native/cpp/main.cpp b/hal/src/dev/native/cpp/main.cpp
new file mode 100644
index 0000000..6bfa3df
--- /dev/null
+++ b/hal/src/dev/native/cpp/main.cpp
@@ -0,0 +1,15 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/HAL.h"
+
+int main() {
+ std::cout << "Hello World" << std::endl;
+ std::cout << HAL_GetRuntimeType() << std::endl;
+}
diff --git a/hal/src/generate/FRCNetComm.java.in b/hal/src/generate/FRCNetComm.java.in
new file mode 100644
index 0000000..af49407
--- /dev/null
+++ b/hal/src/generate/FRCNetComm.java.in
@@ -0,0 +1,33 @@
+/*
+ * Autogenerated file! Do not manually edit this file.
+ */
+
+package edu.wpi.first.hal;
+
+/**
+ * JNI wrapper for library <b>FRC_NetworkCommunication</b><br>.
+ */
+@SuppressWarnings({"MethodName", "LineLength"})
+public class FRCNetComm {
+ /**
+ * Resource type from UsageReporting.
+ */
+ @SuppressWarnings({"TypeName", "PMD.ConstantsInInterface"})
+ public static final class tResourceType {
+ private tResourceType() {
+ }
+
+${usage_reporting_types}
+ }
+
+ /**
+ * Instances from UsageReporting.
+ */
+ @SuppressWarnings({"TypeName", "PMD.ConstantsInInterface"})
+ public static final class tInstances {
+ private tInstances() {
+ }
+
+${usage_reporting_instances}
+ }
+}
diff --git a/hal/src/generate/FRCUsageReporting.h.in b/hal/src/generate/FRCUsageReporting.h.in
new file mode 100644
index 0000000..7cf8128
--- /dev/null
+++ b/hal/src/generate/FRCUsageReporting.h.in
@@ -0,0 +1,14 @@
+#pragma once
+
+/*
+ * Autogenerated file! Do not manually edit this file.
+ */
+
+namespace HALUsageReporting {
+ typedef enum {
+${usage_reporting_types_cpp}
+ } tResourceType;
+ typedef enum {
+${usage_reporting_instances_cpp}
+ } tInstances;
+}
diff --git a/hal/src/generate/Instances.txt b/hal/src/generate/Instances.txt
new file mode 100644
index 0000000..25fc463
--- /dev/null
+++ b/hal/src/generate/Instances.txt
@@ -0,0 +1,44 @@
+kLanguage_LabVIEW = 1
+kLanguage_CPlusPlus = 2
+kLanguage_Java = 3
+kLanguage_Python = 4
+kLanguage_DotNet = 5
+kCANPlugin_BlackJagBridge = 1
+kCANPlugin_2CAN = 2
+kFramework_Iterative = 1
+kFramework_Simple = 2
+kFramework_CommandControl = 3
+kFramework_Timed = 4
+kFramework_ROS = 5
+kFramework_RobotBuilder = 6
+kRobotDrive_ArcadeStandard = 1
+kRobotDrive_ArcadeButtonSpin = 2
+kRobotDrive_ArcadeRatioCurve = 3
+kRobotDrive_Tank = 4
+kRobotDrive_MecanumPolar = 5
+kRobotDrive_MecanumCartesian = 6
+kRobotDrive2_DifferentialArcade = 7
+kRobotDrive2_DifferentialTank = 8
+kRobotDrive2_DifferentialCurvature = 9
+kRobotDrive2_MecanumCartesian = 10
+kRobotDrive2_MecanumPolar = 11
+kRobotDrive2_KilloughCartesian = 12
+kRobotDrive2_KilloughPolar = 13
+kDriverStationCIO_Analog = 1
+kDriverStationCIO_DigitalIn = 2
+kDriverStationCIO_DigitalOut = 3
+kDriverStationEIO_Acceleration = 1
+kDriverStationEIO_AnalogIn = 2
+kDriverStationEIO_AnalogOut = 3
+kDriverStationEIO_Button = 4
+kDriverStationEIO_LED = 5
+kDriverStationEIO_DigitalIn = 6
+kDriverStationEIO_DigitalOut = 7
+kDriverStationEIO_FixedDigitalOut = 8
+kDriverStationEIO_PWM = 9
+kDriverStationEIO_Encoder = 10
+kDriverStationEIO_TouchSlider = 11
+kADXL345_SPI = 1
+kADXL345_I2C = 2
+kCommand_Scheduler = 1
+kSmartDashboard_Instance = 1
diff --git a/hal/src/generate/ResourceType.txt b/hal/src/generate/ResourceType.txt
new file mode 100644
index 0000000..b8699b0
--- /dev/null
+++ b/hal/src/generate/ResourceType.txt
@@ -0,0 +1,85 @@
+kResourceType_Controller = 0
+kResourceType_Module = 1
+kResourceType_Language = 2
+kResourceType_CANPlugin = 3
+kResourceType_Accelerometer = 4
+kResourceType_ADXL345 = 5
+kResourceType_AnalogChannel = 6
+kResourceType_AnalogTrigger = 7
+kResourceType_AnalogTriggerOutput = 8
+kResourceType_CANJaguar = 9
+kResourceType_Compressor = 10
+kResourceType_Counter = 11
+kResourceType_Dashboard = 12
+kResourceType_DigitalInput = 13
+kResourceType_DigitalOutput = 14
+kResourceType_DriverStationCIO = 15
+kResourceType_DriverStationEIO = 16
+kResourceType_DriverStationLCD = 17
+kResourceType_Encoder = 18
+kResourceType_GearTooth = 19
+kResourceType_Gyro = 20
+kResourceType_I2C = 21
+kResourceType_Framework = 22
+kResourceType_Jaguar = 23
+kResourceType_Joystick = 24
+kResourceType_Kinect = 25
+kResourceType_KinectStick = 26
+kResourceType_PIDController = 27
+kResourceType_Preferences = 28
+kResourceType_PWM = 29
+kResourceType_Relay = 30
+kResourceType_RobotDrive = 31
+kResourceType_SerialPort = 32
+kResourceType_Servo = 33
+kResourceType_Solenoid = 34
+kResourceType_SPI = 35
+kResourceType_Task = 36
+kResourceType_Ultrasonic = 37
+kResourceType_Victor = 38
+kResourceType_Button = 39
+kResourceType_Command = 40
+kResourceType_AxisCamera = 41
+kResourceType_PCVideoServer = 42
+kResourceType_SmartDashboard = 43
+kResourceType_Talon = 44
+kResourceType_HiTechnicColorSensor = 45
+kResourceType_HiTechnicAccel = 46
+kResourceType_HiTechnicCompass = 47
+kResourceType_SRF08 = 48
+kResourceType_AnalogOutput = 49
+kResourceType_VictorSP = 50
+kResourceType_PWMTalonSRX = 51
+kResourceType_CANTalonSRX = 52
+kResourceType_ADXL362 = 53
+kResourceType_ADXRS450 = 54
+kResourceType_RevSPARK = 55
+kResourceType_MindsensorsSD540 = 56
+kResourceType_DigitalGlitchFilter = 57
+kResourceType_ADIS16448 = 58
+kResourceType_PDP = 59
+kResourceType_PCM = 60
+kResourceType_PigeonIMU = 61
+kResourceType_NidecBrushless = 62
+kResourceType_CANifier = 63
+kResourceType_CTRE_future0 = 64
+kResourceType_CTRE_future1 = 65
+kResourceType_CTRE_future2 = 66
+kResourceType_CTRE_future3 = 67
+kResourceType_CTRE_future4 = 68
+kResourceType_CTRE_future5 = 69
+kResourceType_CTRE_future6 = 70
+kResourceType_LinearFilter = 71
+kResourceType_XboxController = 72
+kResourceType_UsbCamera = 73
+kResourceType_NavX = 74
+kResourceType_Pixy = 75
+kResourceType_Pixy2 = 76
+kResourceType_ScanseSweep = 77
+kResourceType_Shuffleboard = 78
+kResourceType_CAN = 79
+kResourceType_DigilentDMC60 = 80
+kResourceType_PWMVictorSPX = 81
+kResourceType_RevSparkMaxPWM = 82
+kResourceType_RevSparkMaxCAN = 83
+kResourceType_ADIS16470 = 84
diff --git a/hal/src/main/java/edu/wpi/first/hal/AccelerometerJNI.java b/hal/src/main/java/edu/wpi/first/hal/AccelerometerJNI.java
new file mode 100644
index 0000000..e1e3750
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/AccelerometerJNI.java
@@ -0,0 +1,20 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class AccelerometerJNI extends JNIWrapper {
+ public static native void setAccelerometerActive(boolean active);
+
+ public static native void setAccelerometerRange(int range);
+
+ public static native double getAccelerometerX();
+
+ public static native double getAccelerometerY();
+
+ public static native double getAccelerometerZ();
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/AccumulatorResult.java b/hal/src/main/java/edu/wpi/first/hal/AccumulatorResult.java
new file mode 100644
index 0000000..d3aa8c8
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/AccumulatorResult.java
@@ -0,0 +1,32 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+/**
+ * Structure for holding the values stored in an accumulator.
+ */
+public class AccumulatorResult {
+ /**
+ * The total value accumulated.
+ */
+ @SuppressWarnings("MemberName")
+ public long value;
+ /**
+ * The number of sample value was accumulated over.
+ */
+ @SuppressWarnings("MemberName")
+ public long count;
+
+ /**
+ * Set the value and count.
+ */
+ public void set(long value, long count) {
+ this.value = value;
+ this.count = count;
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/AllianceStationID.java b/hal/src/main/java/edu/wpi/first/hal/AllianceStationID.java
new file mode 100644
index 0000000..148dd76
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/AllianceStationID.java
@@ -0,0 +1,12 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public enum AllianceStationID {
+ Red1, Red2, Red3, Blue1, Blue2, Blue3
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/AnalogGyroJNI.java b/hal/src/main/java/edu/wpi/first/hal/AnalogGyroJNI.java
new file mode 100644
index 0000000..332be79
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/AnalogGyroJNI.java
@@ -0,0 +1,37 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class AnalogGyroJNI extends JNIWrapper {
+ public static native int initializeAnalogGyro(int halAnalogInputHandle);
+
+ public static native void setupAnalogGyro(int handle);
+
+ public static native void freeAnalogGyro(int handle);
+
+ public static native void setAnalogGyroParameters(int handle,
+ double voltsPerDegreePerSecond,
+ double offset, int center);
+
+ public static native void setAnalogGyroVoltsPerDegreePerSecond(int handle,
+ double voltsPerDegreePerSecond);
+
+ public static native void resetAnalogGyro(int handle);
+
+ public static native void calibrateAnalogGyro(int handle);
+
+ public static native void setAnalogGyroDeadband(int handle, double volts);
+
+ public static native double getAnalogGyroAngle(int handle);
+
+ public static native double getAnalogGyroRate(int handle);
+
+ public static native double getAnalogGyroOffset(int handle);
+
+ public static native int getAnalogGyroCenter(int handle);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/AnalogJNI.java b/hal/src/main/java/edu/wpi/first/hal/AnalogJNI.java
new file mode 100644
index 0000000..3e78039
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/AnalogJNI.java
@@ -0,0 +1,116 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+import java.nio.IntBuffer;
+
+public class AnalogJNI extends JNIWrapper {
+ /**
+ * <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:58</i><br> enum values
+ */
+ public interface AnalogTriggerType {
+ /**
+ * <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:54</i>
+ */
+ int kInWindow = 0;
+ /**
+ * <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:55</i>
+ */
+ int kState = 1;
+ /**
+ * <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:56</i>
+ */
+ int kRisingPulse = 2;
+ /**
+ * <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:57</i>
+ */
+ int kFallingPulse = 3;
+ }
+
+ public static native int initializeAnalogInputPort(int halPortHandle);
+
+ public static native void freeAnalogInputPort(int portHandle);
+
+ public static native int initializeAnalogOutputPort(int halPortHandle);
+
+ public static native void freeAnalogOutputPort(int portHandle);
+
+ public static native boolean checkAnalogModule(byte module);
+
+ public static native boolean checkAnalogInputChannel(int channel);
+
+ public static native boolean checkAnalogOutputChannel(int channel);
+
+ public static native void setAnalogOutput(int portHandle, double voltage);
+
+ public static native double getAnalogOutput(int portHandle);
+
+ public static native void setAnalogSampleRate(double samplesPerSecond);
+
+ public static native double getAnalogSampleRate();
+
+ public static native void setAnalogAverageBits(int analogPortHandle, int bits);
+
+ public static native int getAnalogAverageBits(int analogPortHandle);
+
+ public static native void setAnalogOversampleBits(int analogPortHandle, int bits);
+
+ public static native int getAnalogOversampleBits(int analogPortHandle);
+
+ public static native short getAnalogValue(int analogPortHandle);
+
+ public static native int getAnalogAverageValue(int analogPortHandle);
+
+ public static native int getAnalogVoltsToValue(int analogPortHandle, double voltage);
+
+ public static native double getAnalogVoltage(int analogPortHandle);
+
+ public static native double getAnalogAverageVoltage(int analogPortHandle);
+
+ public static native int getAnalogLSBWeight(int analogPortHandle);
+
+ public static native int getAnalogOffset(int analogPortHandle);
+
+ public static native boolean isAccumulatorChannel(int analogPortHandle);
+
+ public static native void initAccumulator(int analogPortHandle);
+
+ public static native void resetAccumulator(int analogPortHandle);
+
+ public static native void setAccumulatorCenter(int analogPortHandle, int center);
+
+ public static native void setAccumulatorDeadband(int analogPortHandle, int deadband);
+
+ public static native long getAccumulatorValue(int analogPortHandle);
+
+ public static native int getAccumulatorCount(int analogPortHandle);
+
+ public static native void getAccumulatorOutput(int analogPortHandle, AccumulatorResult result);
+
+ public static native int initializeAnalogTrigger(int analogInputHandle, IntBuffer index);
+
+ public static native void cleanAnalogTrigger(int analogTriggerHandle);
+
+ public static native void setAnalogTriggerLimitsRaw(int analogTriggerHandle, int lower,
+ int upper);
+
+ public static native void setAnalogTriggerLimitsVoltage(int analogTriggerHandle,
+ double lower, double upper);
+
+ public static native void setAnalogTriggerAveraged(int analogTriggerHandle,
+ boolean useAveragedValue);
+
+ public static native void setAnalogTriggerFiltered(int analogTriggerHandle,
+ boolean useFilteredValue);
+
+ public static native boolean getAnalogTriggerInWindow(int analogTriggerHandle);
+
+ public static native boolean getAnalogTriggerTriggerState(int analogTriggerHandle);
+
+ public static native boolean getAnalogTriggerOutput(int analogTriggerHandle, int type);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/CANAPIJNI.java b/hal/src/main/java/edu/wpi/first/hal/CANAPIJNI.java
new file mode 100644
index 0000000..1ac3ca7
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/CANAPIJNI.java
@@ -0,0 +1,32 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+@SuppressWarnings("AbbreviationAsWordInName")
+public class CANAPIJNI extends JNIWrapper {
+ public static native int initializeCAN(int manufacturer, int deviceId, int deviceType);
+
+ public static native void cleanCAN(int handle);
+
+ public static native void writeCANPacket(int handle, byte[] data, int apiId);
+
+ public static native void writeCANPacketRepeating(int handle, byte[] data, int apiId,
+ int repeatMs);
+
+ public static native void stopCANPacketRepeating(int handle, int apiId);
+
+ public static native boolean readCANPacketNew(int handle, int apiId, CANData data);
+
+ public static native boolean readCANPacketLatest(int handle, int apiId, CANData data);
+
+ public static native boolean readCANPacketTimeout(int handle, int apiId, int timeoutMs,
+ CANData data);
+
+ public static native boolean readCANPeriodicPacket(int handle, int apiId, int timeoutMs,
+ int periodMs, CANData data);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/CANData.java b/hal/src/main/java/edu/wpi/first/hal/CANData.java
new file mode 100644
index 0000000..23d37c9
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/CANData.java
@@ -0,0 +1,27 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class CANData {
+ @SuppressWarnings("MemberName")
+ public final byte[] data = new byte[8];
+ @SuppressWarnings("MemberName")
+ public int length;
+ @SuppressWarnings("MemberName")
+ public long timestamp;
+
+ /**
+ * API used from JNI to set the data.
+ */
+ @SuppressWarnings("PMD.MethodReturnsInternalArray")
+ public byte[] setData(int length, long timestamp) {
+ this.length = length;
+ this.timestamp = timestamp;
+ return data;
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/CompressorJNI.java b/hal/src/main/java/edu/wpi/first/hal/CompressorJNI.java
new file mode 100644
index 0000000..64e9e1d
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/CompressorJNI.java
@@ -0,0 +1,38 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class CompressorJNI extends JNIWrapper {
+ public static native int initializeCompressor(byte module);
+
+ public static native boolean checkCompressorModule(byte module);
+
+ public static native boolean getCompressor(int compressorHandle);
+
+ public static native void setCompressorClosedLoopControl(int compressorHandle, boolean value);
+
+ public static native boolean getCompressorClosedLoopControl(int compressorHandle);
+
+ public static native boolean getCompressorPressureSwitch(int compressorHandle);
+
+ public static native double getCompressorCurrent(int compressorHandle);
+
+ public static native boolean getCompressorCurrentTooHighFault(int compressorHandle);
+
+ public static native boolean getCompressorCurrentTooHighStickyFault(int compressorHandle);
+
+ public static native boolean getCompressorShortedStickyFault(int compressorHandle);
+
+ public static native boolean getCompressorShortedFault(int compressorHandle);
+
+ public static native boolean getCompressorNotConnectedStickyFault(int compressorHandle);
+
+ public static native boolean getCompressorNotConnectedFault(int compressorHandle);
+
+ public static native void clearAllPCMStickyFaults(byte compressorModule);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/ConstantsJNI.java b/hal/src/main/java/edu/wpi/first/hal/ConstantsJNI.java
new file mode 100644
index 0000000..3db75f5
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/ConstantsJNI.java
@@ -0,0 +1,12 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class ConstantsJNI extends JNIWrapper {
+ public static native int getSystemClockTicksPerMicrosecond();
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/ControlWord.java b/hal/src/main/java/edu/wpi/first/hal/ControlWord.java
new file mode 100644
index 0000000..8353606
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/ControlWord.java
@@ -0,0 +1,54 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+/**
+ * A wrapper for the HALControlWord bitfield.
+ */
+public class ControlWord {
+ private boolean m_enabled;
+ private boolean m_autonomous;
+ private boolean m_test;
+ private boolean m_emergencyStop;
+ private boolean m_fmsAttached;
+ private boolean m_dsAttached;
+
+ void update(boolean enabled, boolean autonomous, boolean test, boolean emergencyStop,
+ boolean fmsAttached, boolean dsAttached) {
+ m_enabled = enabled;
+ m_autonomous = autonomous;
+ m_test = test;
+ m_emergencyStop = emergencyStop;
+ m_fmsAttached = fmsAttached;
+ m_dsAttached = dsAttached;
+ }
+
+ public boolean getEnabled() {
+ return m_enabled;
+ }
+
+ public boolean getAutonomous() {
+ return m_autonomous;
+ }
+
+ public boolean getTest() {
+ return m_test;
+ }
+
+ public boolean getEStop() {
+ return m_emergencyStop;
+ }
+
+ public boolean getFMSAttached() {
+ return m_fmsAttached;
+ }
+
+ public boolean getDSAttached() {
+ return m_dsAttached;
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/CounterJNI.java b/hal/src/main/java/edu/wpi/first/hal/CounterJNI.java
new file mode 100644
index 0000000..b7935d6
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/CounterJNI.java
@@ -0,0 +1,65 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+import java.nio.IntBuffer;
+
+public class CounterJNI extends JNIWrapper {
+ public static native int initializeCounter(int mode, IntBuffer index);
+
+ public static native void freeCounter(int counterHandle);
+
+ public static native void setCounterAverageSize(int counterHandle, int size);
+
+ public static native void setCounterUpSource(int counterHandle, int digitalSourceHandle,
+ int analogTriggerType);
+
+ public static native void setCounterUpSourceEdge(int counterHandle, boolean risingEdge,
+ boolean fallingEdge);
+
+ public static native void clearCounterUpSource(int counterHandle);
+
+ public static native void setCounterDownSource(int counterHandle, int digitalSourceHandle,
+ int analogTriggerType);
+
+ public static native void setCounterDownSourceEdge(int counterHandle, boolean risingEdge,
+ boolean fallingEdge);
+
+ public static native void clearCounterDownSource(int counterHandle);
+
+ public static native void setCounterUpDownMode(int counterHandle);
+
+ public static native void setCounterExternalDirectionMode(int counterHandle);
+
+ public static native void setCounterSemiPeriodMode(int counterHandle,
+ boolean highSemiPeriod);
+
+ public static native void setCounterPulseLengthMode(int counterHandle, double threshold);
+
+ public static native int getCounterSamplesToAverage(int counterHandle);
+
+ public static native void setCounterSamplesToAverage(int counterHandle,
+ int samplesToAverage);
+
+ public static native void resetCounter(int counterHandle);
+
+ public static native int getCounter(int counterHandle);
+
+ public static native double getCounterPeriod(int counterHandle);
+
+ public static native void setCounterMaxPeriod(int counterHandle, double maxPeriod);
+
+ public static native void setCounterUpdateWhenEmpty(int counterHandle, boolean enabled);
+
+ public static native boolean getCounterStopped(int counterHandle);
+
+ public static native boolean getCounterDirection(int counterHandle);
+
+ public static native void setCounterReverseDirection(int counterHandle,
+ boolean reverseDirection);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/DIOJNI.java b/hal/src/main/java/edu/wpi/first/hal/DIOJNI.java
new file mode 100644
index 0000000..b9c11a5
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/DIOJNI.java
@@ -0,0 +1,44 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+@SuppressWarnings("AbbreviationAsWordInName")
+public class DIOJNI extends JNIWrapper {
+ public static native int initializeDIOPort(int halPortHandle, boolean input);
+
+ public static native boolean checkDIOChannel(int channel);
+
+ public static native void freeDIOPort(int dioPortHandle);
+
+ // TODO(Thad): Switch this to use boolean
+ public static native void setDIO(int dioPortHandle, short value);
+
+ public static native void setDIODirection(int dioPortHandle, boolean input);
+
+ public static native boolean getDIO(int dioPortHandle);
+
+ public static native boolean getDIODirection(int dioPortHandle);
+
+ public static native void pulse(int dioPortHandle, double pulseLength);
+
+ public static native boolean isPulsing(int dioPortHandle);
+
+ public static native boolean isAnyPulsing();
+
+ public static native short getLoopTiming();
+
+ public static native int allocateDigitalPWM();
+
+ public static native void freeDigitalPWM(int pwmGenerator);
+
+ public static native void setDigitalPWMRate(double rate);
+
+ public static native void setDigitalPWMDutyCycle(int pwmGenerator, double dutyCycle);
+
+ public static native void setDigitalPWMOutputChannel(int pwmGenerator, int channel);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/DigitalGlitchFilterJNI.java b/hal/src/main/java/edu/wpi/first/hal/DigitalGlitchFilterJNI.java
new file mode 100644
index 0000000..aa818cf
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/DigitalGlitchFilterJNI.java
@@ -0,0 +1,18 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class DigitalGlitchFilterJNI extends JNIWrapper {
+ public static native void setFilterSelect(int digitalPortHandle, int filterIndex);
+
+ public static native int getFilterSelect(int digitalPortHandle);
+
+ public static native void setFilterPeriod(int filterIndex, int fpgaCycles);
+
+ public static native int getFilterPeriod(int filterIndex);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/EncoderJNI.java b/hal/src/main/java/edu/wpi/first/hal/EncoderJNI.java
new file mode 100644
index 0000000..082b6d9
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/EncoderJNI.java
@@ -0,0 +1,62 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class EncoderJNI extends JNIWrapper {
+ public static native int initializeEncoder(int digitalSourceHandleA, int analogTriggerTypeA,
+ int digitalSourceHandleB, int analogTriggerTypeB,
+ boolean reverseDirection, int encodingType);
+
+ public static native void freeEncoder(int encoderHandle);
+
+ public static native int getEncoder(int encoderHandle);
+
+ public static native int getEncoderRaw(int encoderHandle);
+
+ public static native int getEncodingScaleFactor(int encoderHandle);
+
+ public static native void resetEncoder(int encoderHandle);
+
+ public static native double getEncoderPeriod(int encoderHandle);
+
+ public static native void setEncoderMaxPeriod(int encoderHandle, double maxPeriod);
+
+ public static native boolean getEncoderStopped(int encoderHandle);
+
+ public static native boolean getEncoderDirection(int encoderHandle);
+
+ public static native double getEncoderDistance(int encoderHandle);
+
+ public static native double getEncoderRate(int encoderHandle);
+
+ public static native void setEncoderMinRate(int encoderHandle, double minRate);
+
+ public static native void setEncoderDistancePerPulse(int encoderHandle, double distancePerPulse);
+
+ public static native void setEncoderReverseDirection(int encoderHandle,
+ boolean reverseDirection);
+
+ public static native void setEncoderSamplesToAverage(int encoderHandle,
+ int samplesToAverage);
+
+ public static native int getEncoderSamplesToAverage(int encoderHandle);
+
+ public static native void setEncoderIndexSource(int encoderHandle, int digitalSourceHandle,
+ int analogTriggerType, int indexingType);
+
+ @SuppressWarnings("AbbreviationAsWordInName")
+ public static native int getEncoderFPGAIndex(int encoderHandle);
+
+ public static native int getEncoderEncodingScale(int encoderHandle);
+
+ public static native double getEncoderDecodingScaleFactor(int encoderHandle);
+
+ public static native double getEncoderDistancePerPulse(int encoderHandle);
+
+ public static native int getEncoderEncodingType(int encoderHandle);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/HAL.java b/hal/src/main/java/edu/wpi/first/hal/HAL.java
new file mode 100644
index 0000000..a298ff6
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/HAL.java
@@ -0,0 +1,134 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+import java.nio.ByteBuffer;
+
+/**
+ * JNI Wrapper for HAL<br>.
+ */
+@SuppressWarnings({"AbbreviationAsWordInName", "MethodName", "PMD.TooManyMethods"})
+public final class HAL extends JNIWrapper {
+ public static native void waitForDSData();
+
+ public static native boolean initialize(int timeout, int mode);
+
+ public static native void observeUserProgramStarting();
+
+ public static native void observeUserProgramDisabled();
+
+ public static native void observeUserProgramAutonomous();
+
+ public static native void observeUserProgramTeleop();
+
+ public static native void observeUserProgramTest();
+
+ public static void report(int resource, int instanceNumber) {
+ report(resource, instanceNumber, 0, "");
+ }
+
+ public static void report(int resource, int instanceNumber, int context) {
+ report(resource, instanceNumber, context, "");
+ }
+
+ /**
+ * Report the usage of a resource of interest. <br>
+ *
+ * <p>Original signature: <code>uint32_t report(tResourceType, uint8_t, uint8_t, const
+ * char*)</code>
+ *
+ * @param resource one of the values in the tResourceType above (max value 51). <br>
+ * @param instanceNumber an index that identifies the resource instance. <br>
+ * @param context an optional additional context number for some cases (such as module
+ * number). Set to 0 to omit. <br>
+ * @param feature a string to be included describing features in use on a specific
+ * resource. Setting the same resource more than once allows you to change
+ * the feature string.
+ */
+ public static native int report(int resource, int instanceNumber, int context, String feature);
+
+ public static native int nativeGetControlWord();
+
+ @SuppressWarnings("JavadocMethod")
+ public static void getControlWord(ControlWord controlWord) {
+ int word = nativeGetControlWord();
+ controlWord.update((word & 1) != 0, ((word >> 1) & 1) != 0, ((word >> 2) & 1) != 0,
+ ((word >> 3) & 1) != 0, ((word >> 4) & 1) != 0, ((word >> 5) & 1) != 0);
+ }
+
+ private static native int nativeGetAllianceStation();
+
+ @SuppressWarnings("JavadocMethod")
+ public static AllianceStationID getAllianceStation() {
+ switch (nativeGetAllianceStation()) {
+ case 0:
+ return AllianceStationID.Red1;
+ case 1:
+ return AllianceStationID.Red2;
+ case 2:
+ return AllianceStationID.Red3;
+ case 3:
+ return AllianceStationID.Blue1;
+ case 4:
+ return AllianceStationID.Blue2;
+ case 5:
+ return AllianceStationID.Blue3;
+ default:
+ return null;
+ }
+ }
+
+ @SuppressWarnings("JavadocMethod")
+ public static native boolean isNewControlData();
+
+ @SuppressWarnings("JavadocMethod")
+ public static native void releaseDSMutex();
+
+ @SuppressWarnings("JavadocMethod")
+ public static native boolean waitForDSDataTimeout(double timeout);
+
+ public static int kMaxJoystickAxes = 12;
+ public static int kMaxJoystickPOVs = 12;
+
+ public static native short getJoystickAxes(byte joystickNum, float[] axesArray);
+
+ public static native short getJoystickPOVs(byte joystickNum, short[] povsArray);
+
+ public static native int getJoystickButtons(byte joystickNum, ByteBuffer count);
+
+ public static native int setJoystickOutputs(byte joystickNum, int outputs, short leftRumble,
+ short rightRumble);
+
+ public static native int getJoystickIsXbox(byte joystickNum);
+
+ public static native int getJoystickType(byte joystickNum);
+
+ public static native String getJoystickName(byte joystickNum);
+
+ public static native int getJoystickAxisType(byte joystickNum, byte axis);
+
+ public static native double getMatchTime();
+
+ public static native boolean getSystemActive();
+
+ public static native boolean getBrownedOut();
+
+ public static native int getMatchInfo(MatchInfoData info);
+
+ public static native int sendError(boolean isError, int errorCode, boolean isLVCode,
+ String details, String location, String callStack,
+ boolean printMsg);
+
+ public static native int getPortWithModule(byte module, byte channel);
+
+ public static native int getPort(byte channel);
+
+ private HAL() {
+
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/HALUtil.java b/hal/src/main/java/edu/wpi/first/hal/HALUtil.java
new file mode 100644
index 0000000..0e5fe21
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/HALUtil.java
@@ -0,0 +1,44 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+@SuppressWarnings("AbbreviationAsWordInName")
+public final class HALUtil extends JNIWrapper {
+ public static final int NULL_PARAMETER = -1005;
+ public static final int SAMPLE_RATE_TOO_HIGH = 1001;
+ public static final int VOLTAGE_OUT_OF_RANGE = 1002;
+ public static final int LOOP_TIMING_ERROR = 1004;
+ public static final int INCOMPATIBLE_STATE = 1015;
+ public static final int ANALOG_TRIGGER_PULSE_OUTPUT_ERROR = -1011;
+ public static final int NO_AVAILABLE_RESOURCES = -104;
+ public static final int PARAMETER_OUT_OF_RANGE = -1028;
+
+ public static native short getFPGAVersion();
+
+ public static native int getFPGARevision();
+
+ public static native long getFPGATime();
+
+ public static native int getHALRuntimeType();
+
+ public static native boolean getFPGAButton();
+
+ public static native String getHALErrorMessage(int code);
+
+ public static native int getHALErrno();
+
+ public static native String getHALstrerror(int errno);
+
+ public static String getHALstrerror() {
+ return getHALstrerror(getHALErrno());
+ }
+
+ private HALUtil() {
+
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/I2CJNI.java b/hal/src/main/java/edu/wpi/first/hal/I2CJNI.java
new file mode 100644
index 0000000..12a9af0
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/I2CJNI.java
@@ -0,0 +1,33 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+import java.nio.ByteBuffer;
+
+@SuppressWarnings("AbbreviationAsWordInName")
+public class I2CJNI extends JNIWrapper {
+ public static native void i2CInitialize(int port);
+
+ public static native int i2CTransaction(int port, byte address, ByteBuffer dataToSend,
+ byte sendSize, ByteBuffer dataReceived, byte receiveSize);
+
+ public static native int i2CTransactionB(int port, byte address, byte[] dataToSend,
+ byte sendSize, byte[] dataReceived, byte receiveSize);
+
+ public static native int i2CWrite(int port, byte address, ByteBuffer dataToSend, byte sendSize);
+
+ public static native int i2CWriteB(int port, byte address, byte[] dataToSend, byte sendSize);
+
+ public static native int i2CRead(int port, byte address, ByteBuffer dataReceived,
+ byte receiveSize);
+
+ public static native int i2CReadB(int port, byte address, byte[] dataReceived,
+ byte receiveSize);
+
+ public static native void i2CClose(int port);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/InterruptJNI.java b/hal/src/main/java/edu/wpi/first/hal/InterruptJNI.java
new file mode 100644
index 0000000..8574a25
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/InterruptJNI.java
@@ -0,0 +1,41 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class InterruptJNI extends JNIWrapper {
+ public static final int HalInvalidHandle = 0;
+
+ public interface InterruptJNIHandlerFunction {
+ void apply(int interruptAssertedMask, Object param);
+ }
+
+ public static native int initializeInterrupts(boolean watcher);
+
+ public static native void cleanInterrupts(int interruptHandle);
+
+ public static native int waitForInterrupt(int interruptHandle, double timeout,
+ boolean ignorePrevious);
+
+ public static native void enableInterrupts(int interruptHandle);
+
+ public static native void disableInterrupts(int interruptHandle);
+
+ public static native long readInterruptRisingTimestamp(int interruptHandle);
+
+ public static native long readInterruptFallingTimestamp(int interruptHandle);
+
+ public static native void requestInterrupts(int interruptHandle, int digitalSourceHandle,
+ int analogTriggerType);
+
+ public static native void attachInterruptHandler(int interruptHandle,
+ InterruptJNIHandlerFunction handler,
+ Object param);
+
+ public static native void setInterruptUpSourceEdge(int interruptHandle, boolean risingEdge,
+ boolean fallingEdge);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/JNIWrapper.java b/hal/src/main/java/edu/wpi/first/hal/JNIWrapper.java
new file mode 100644
index 0000000..21342bc
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/JNIWrapper.java
@@ -0,0 +1,34 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+import java.io.IOException;
+
+import edu.wpi.first.wpiutil.RuntimeLoader;
+
+/**
+ * Base class for all JNI wrappers.
+ */
+public class JNIWrapper {
+ static boolean libraryLoaded = false;
+ static RuntimeLoader<JNIWrapper> loader = null;
+
+ static {
+ if (!libraryLoaded) {
+ try {
+ loader = new RuntimeLoader<>("wpiHaljni", RuntimeLoader.getDefaultExtractionRoot(), JNIWrapper.class);
+ loader.loadLibrary();
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ System.exit(1);
+ }
+ libraryLoaded = true;
+ libraryLoaded = true;
+ }
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/MatchInfoData.java b/hal/src/main/java/edu/wpi/first/hal/MatchInfoData.java
new file mode 100644
index 0000000..2f11515
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/MatchInfoData.java
@@ -0,0 +1,56 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+/**
+ * Structure for holding the match info data request.
+ */
+public class MatchInfoData {
+ /**
+ * Stores the event name.
+ */
+ @SuppressWarnings("MemberName")
+ public String eventName = "";
+
+ /**
+ * Stores the game specific message.
+ */
+ @SuppressWarnings("MemberName")
+ public String gameSpecificMessage = "";
+
+ /**
+ * Stores the match number.
+ */
+ @SuppressWarnings("MemberName")
+ public int matchNumber;
+
+ /**
+ * Stores the replay number.
+ */
+ @SuppressWarnings("MemberName")
+ public int replayNumber;
+
+ /**
+ * Stores the match type.
+ */
+ @SuppressWarnings("MemberName")
+ public int matchType;
+
+ /**
+ * Called from JNI to set the structure data.
+ */
+ @SuppressWarnings("JavadocMethod")
+ public void setData(String eventName, String gameSpecificMessage,
+ int matchNumber, int replayNumber, int matchType) {
+ this.eventName = eventName;
+ this.gameSpecificMessage = gameSpecificMessage;
+ this.matchNumber = matchNumber;
+ this.replayNumber = replayNumber;
+ this.matchType = matchType;
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/NotifierJNI.java b/hal/src/main/java/edu/wpi/first/hal/NotifierJNI.java
new file mode 100644
index 0000000..bf92c37
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/NotifierJNI.java
@@ -0,0 +1,49 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+/**
+ * The NotifierJNI class directly wraps the C++ HAL Notifier.
+ *
+ * <p>This class is not meant for direct use by teams. Instead, the edu.wpi.first.wpilibj.Notifier
+ * class, which corresponds to the C++ Notifier class, should be used.
+ */
+public class NotifierJNI extends JNIWrapper {
+ /**
+ * Initializes the notifier.
+ */
+ public static native int initializeNotifier();
+
+ /**
+ * Wakes up the waiter with time=0. Note: after this function is called, all
+ * calls to waitForNotifierAlarm() will immediately start returning 0.
+ */
+ public static native void stopNotifier(int notifierHandle);
+
+ /**
+ * Deletes the notifier object when we are done with it.
+ */
+ public static native void cleanNotifier(int notifierHandle);
+
+ /**
+ * Sets the notifier to wakeup the waiter in another triggerTime microseconds.
+ */
+ public static native void updateNotifierAlarm(int notifierHandle, long triggerTime);
+
+ /**
+ * Cancels any pending wakeups set by updateNotifierAlarm(). Does NOT wake
+ * up any waiters.
+ */
+ public static native void cancelNotifierAlarm(int notifierHandle);
+
+ /**
+ * Block until woken up by an alarm (or stop).
+ * @return Time when woken up.
+ */
+ public static native long waitForNotifierAlarm(int notifierHandle);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/PDPJNI.java b/hal/src/main/java/edu/wpi/first/hal/PDPJNI.java
new file mode 100644
index 0000000..c45a053
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/PDPJNI.java
@@ -0,0 +1,33 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+@SuppressWarnings("AbbreviationAsWordInName")
+public class PDPJNI extends JNIWrapper {
+ public static native int initializePDP(int module);
+
+ public static native boolean checkPDPModule(int module);
+
+ public static native boolean checkPDPChannel(int channel);
+
+ public static native double getPDPTemperature(int handle);
+
+ public static native double getPDPVoltage(int handle);
+
+ public static native double getPDPChannelCurrent(byte channel, int handle);
+
+ public static native double getPDPTotalCurrent(int handle);
+
+ public static native double getPDPTotalPower(int handle);
+
+ public static native double getPDPTotalEnergy(int handle);
+
+ public static native void resetPDPTotalEnergy(int handle);
+
+ public static native void clearPDPStickyFaults(int handle);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/PWMConfigDataResult.java b/hal/src/main/java/edu/wpi/first/hal/PWMConfigDataResult.java
new file mode 100644
index 0000000..d29b0df
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/PWMConfigDataResult.java
@@ -0,0 +1,51 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+/**
+ * Structure for holding the config data result for PWM.
+ */
+public class PWMConfigDataResult {
+ PWMConfigDataResult(int max, int deadbandMax, int center, int deadbandMin, int min) {
+ this.max = max;
+ this.deadbandMax = deadbandMax;
+ this.center = center;
+ this.deadbandMin = deadbandMin;
+ this.min = min;
+ }
+
+ /**
+ * The maximum PWM value.
+ */
+ @SuppressWarnings("MemberName")
+ public int max;
+
+ /**
+ * The deadband maximum PWM value.
+ */
+ @SuppressWarnings("MemberName")
+ public int deadbandMax;
+
+ /**
+ * The center PWM value.
+ */
+ @SuppressWarnings("MemberName")
+ public int center;
+
+ /**
+ * The deadband minimum PWM value.
+ */
+ @SuppressWarnings("MemberName")
+ public int deadbandMin;
+
+ /**
+ * The minimum PWM value.
+ */
+ @SuppressWarnings("MemberName")
+ public int min;
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/PWMJNI.java b/hal/src/main/java/edu/wpi/first/hal/PWMJNI.java
new file mode 100644
index 0000000..3af6f96
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/PWMJNI.java
@@ -0,0 +1,49 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+@SuppressWarnings("AbbreviationAsWordInName")
+public class PWMJNI extends DIOJNI {
+ public static native int initializePWMPort(int halPortHandle);
+
+ public static native boolean checkPWMChannel(int channel);
+
+ public static native void freePWMPort(int pwmPortHandle);
+
+ public static native void setPWMConfigRaw(int pwmPortHandle, int maxPwm,
+ int deadbandMaxPwm, int centerPwm,
+ int deadbandMinPwm, int minPwm);
+
+ public static native void setPWMConfig(int pwmPortHandle, double maxPwm,
+ double deadbandMaxPwm, double centerPwm,
+ double deadbandMinPwm, double minPwm);
+
+ public static native PWMConfigDataResult getPWMConfigRaw(int pwmPortHandle);
+
+ public static native void setPWMEliminateDeadband(int pwmPortHandle, boolean eliminateDeadband);
+
+ public static native boolean getPWMEliminateDeadband(int pwmPortHandle);
+
+ public static native void setPWMRaw(int pwmPortHandle, short value);
+
+ public static native void setPWMSpeed(int pwmPortHandle, double speed);
+
+ public static native void setPWMPosition(int pwmPortHandle, double position);
+
+ public static native short getPWMRaw(int pwmPortHandle);
+
+ public static native double getPWMSpeed(int pwmPortHandle);
+
+ public static native double getPWMPosition(int pwmPortHandle);
+
+ public static native void setPWMDisabled(int pwmPortHandle);
+
+ public static native void latchPWMZero(int pwmPortHandle);
+
+ public static native void setPWMPeriodScale(int pwmPortHandle, int squelchMask);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/PortsJNI.java b/hal/src/main/java/edu/wpi/first/hal/PortsJNI.java
new file mode 100644
index 0000000..a2ac60b
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/PortsJNI.java
@@ -0,0 +1,46 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class PortsJNI extends JNIWrapper {
+ public static native int getNumAccumulators();
+
+ public static native int getNumAnalogTriggers();
+
+ public static native int getNumAnalogInputs();
+
+ public static native int getNumAnalogOutputs();
+
+ public static native int getNumCounters();
+
+ public static native int getNumDigitalHeaders();
+
+ public static native int getNumPWMHeaders();
+
+ public static native int getNumDigitalChannels();
+
+ public static native int getNumPWMChannels();
+
+ public static native int getNumDigitalPWMOutputs();
+
+ public static native int getNumEncoders();
+
+ public static native int getNumInterrupts();
+
+ public static native int getNumRelayChannels();
+
+ public static native int getNumRelayHeaders();
+
+ public static native int getNumPCMModules();
+
+ public static native int getNumSolenoidChannels();
+
+ public static native int getNumPDPModules();
+
+ public static native int getNumPDPChannels();
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/PowerJNI.java b/hal/src/main/java/edu/wpi/first/hal/PowerJNI.java
new file mode 100644
index 0000000..7a0a376
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/PowerJNI.java
@@ -0,0 +1,38 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class PowerJNI extends JNIWrapper {
+ public static native double getVinVoltage();
+
+ public static native double getVinCurrent();
+
+ public static native double getUserVoltage6V();
+
+ public static native double getUserCurrent6V();
+
+ public static native boolean getUserActive6V();
+
+ public static native int getUserCurrentFaults6V();
+
+ public static native double getUserVoltage5V();
+
+ public static native double getUserCurrent5V();
+
+ public static native boolean getUserActive5V();
+
+ public static native int getUserCurrentFaults5V();
+
+ public static native double getUserVoltage3V3();
+
+ public static native double getUserCurrent3V3();
+
+ public static native boolean getUserActive3V3();
+
+ public static native int getUserCurrentFaults3V3();
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/RelayJNI.java b/hal/src/main/java/edu/wpi/first/hal/RelayJNI.java
new file mode 100644
index 0000000..1b507dc
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/RelayJNI.java
@@ -0,0 +1,20 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class RelayJNI extends DIOJNI {
+ public static native int initializeRelayPort(int halPortHandle, boolean forward);
+
+ public static native void freeRelayPort(int relayPortHandle);
+
+ public static native boolean checkRelayChannel(int channel);
+
+ public static native void setRelay(int relayPortHandle, boolean on);
+
+ public static native boolean getRelay(int relayPortHandle);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/SPIJNI.java b/hal/src/main/java/edu/wpi/first/hal/SPIJNI.java
new file mode 100644
index 0000000..c473181
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/SPIJNI.java
@@ -0,0 +1,64 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+import java.nio.ByteBuffer;
+
+@SuppressWarnings("AbbreviationAsWordInName")
+public class SPIJNI extends JNIWrapper {
+ public static native void spiInitialize(int port);
+
+ public static native int spiTransaction(int port, ByteBuffer dataToSend,
+ ByteBuffer dataReceived, byte size);
+
+ public static native int spiTransactionB(int port, byte[] dataToSend,
+ byte[] dataReceived, byte size);
+
+ public static native int spiWrite(int port, ByteBuffer dataToSend, byte sendSize);
+
+ public static native int spiWriteB(int port, byte[] dataToSend, byte sendSize);
+
+ public static native int spiRead(int port, boolean initiate, ByteBuffer dataReceived, byte size);
+
+ public static native int spiReadB(int port, boolean initiate, byte[] dataReceived, byte size);
+
+ public static native void spiClose(int port);
+
+ public static native void spiSetSpeed(int port, int speed);
+
+ public static native void spiSetOpts(int port, int msbFirst, int sampleOnTrailing,
+ int clkIdleHigh);
+
+ public static native void spiSetChipSelectActiveHigh(int port);
+
+ public static native void spiSetChipSelectActiveLow(int port);
+
+ public static native void spiInitAuto(int port, int bufferSize);
+
+ public static native void spiFreeAuto(int port);
+
+ public static native void spiStartAutoRate(int port, double period);
+
+ public static native void spiStartAutoTrigger(int port, int digitalSourceHandle,
+ int analogTriggerType, boolean triggerRising,
+ boolean triggerFalling);
+
+ public static native void spiStopAuto(int port);
+
+ public static native void spiSetAutoTransmitData(int port, byte[] dataToSend, int zeroSize);
+
+ public static native void spiForceAutoRead(int port);
+
+ public static native int spiReadAutoReceivedData(int port, ByteBuffer buffer, int numToRead,
+ double timeout);
+
+ public static native int spiReadAutoReceivedData(int port, int[] buffer, int numToRead,
+ double timeout);
+
+ public static native int spiGetAutoDroppedCount(int port);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/SerialPortJNI.java b/hal/src/main/java/edu/wpi/first/hal/SerialPortJNI.java
new file mode 100644
index 0000000..db98b9c
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/SerialPortJNI.java
@@ -0,0 +1,48 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class SerialPortJNI extends JNIWrapper {
+ public static native void serialInitializePort(byte port);
+
+ public static native void serialInitializePortDirect(byte port, String portName);
+
+ public static native void serialSetBaudRate(byte port, int baud);
+
+ public static native void serialSetDataBits(byte port, byte bits);
+
+ public static native void serialSetParity(byte port, byte parity);
+
+ public static native void serialSetStopBits(byte port, byte stopBits);
+
+ public static native void serialSetWriteMode(byte port, byte mode);
+
+ public static native void serialSetFlowControl(byte port, byte flow);
+
+ public static native void serialSetTimeout(byte port, double timeout);
+
+ public static native void serialEnableTermination(byte port, char terminator);
+
+ public static native void serialDisableTermination(byte port);
+
+ public static native void serialSetReadBufferSize(byte port, int size);
+
+ public static native void serialSetWriteBufferSize(byte port, int size);
+
+ public static native int serialGetBytesReceived(byte port);
+
+ public static native int serialRead(byte port, byte[] buffer, int count);
+
+ public static native int serialWrite(byte port, byte[] buffer, int count);
+
+ public static native void serialFlush(byte port);
+
+ public static native void serialClear(byte port);
+
+ public static native void serialClose(byte port);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/SolenoidJNI.java b/hal/src/main/java/edu/wpi/first/hal/SolenoidJNI.java
new file mode 100644
index 0000000..66acbea
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/SolenoidJNI.java
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class SolenoidJNI extends JNIWrapper {
+ public static native int initializeSolenoidPort(int halPortHandle);
+
+ public static native boolean checkSolenoidModule(int module);
+
+ public static native boolean checkSolenoidChannel(int channel);
+
+ public static native void freeSolenoidPort(int portHandle);
+
+ public static native void setSolenoid(int portHandle, boolean on);
+
+ public static native boolean getSolenoid(int portHandle);
+
+ public static native int getAllSolenoids(int module);
+
+ public static native int getPCMSolenoidBlackList(int module);
+
+ public static native boolean getPCMSolenoidVoltageStickyFault(int module);
+
+ public static native boolean getPCMSolenoidVoltageFault(int module);
+
+ public static native void clearAllPCMStickyFaults(int module);
+
+ public static native void setOneShotDuration(int portHandle, long durationMS);
+
+ public static native void fireOneShot(int portHandle);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/ThreadsJNI.java b/hal/src/main/java/edu/wpi/first/hal/ThreadsJNI.java
new file mode 100644
index 0000000..e320eb5
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/ThreadsJNI.java
@@ -0,0 +1,16 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal;
+
+public class ThreadsJNI extends JNIWrapper {
+ public static native int getCurrentThreadPriority();
+
+ public static native boolean getCurrentThreadIsRealTime();
+
+ public static native boolean setCurrentThreadPriority(boolean realTime, int priority);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/can/CANExceptionFactory.java b/hal/src/main/java/edu/wpi/first/hal/can/CANExceptionFactory.java
new file mode 100644
index 0000000..132dae1
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/can/CANExceptionFactory.java
@@ -0,0 +1,48 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.can;
+
+import edu.wpi.first.hal.communication.NIRioStatus;
+import edu.wpi.first.hal.util.UncleanStatusException;
+
+public final class CANExceptionFactory {
+ // FRC Error codes
+ static final int ERR_CANSessionMux_InvalidBuffer = -44086;
+ static final int ERR_CANSessionMux_MessageNotFound = -44087;
+ static final int ERR_CANSessionMux_NotAllowed = -44088;
+ static final int ERR_CANSessionMux_NotInitialized = -44089;
+
+ @SuppressWarnings({"JavadocMethod", "PMD.CyclomaticComplexity"})
+ public static void checkStatus(int status, int messageID) throws CANInvalidBufferException,
+ CANMessageNotAllowedException, CANNotInitializedException, UncleanStatusException {
+ switch (status) {
+ case NIRioStatus.kRioStatusSuccess:
+ // Everything is ok... don't throw.
+ return;
+ case ERR_CANSessionMux_InvalidBuffer:
+ case NIRioStatus.kRIOStatusBufferInvalidSize:
+ throw new CANInvalidBufferException();
+ case ERR_CANSessionMux_MessageNotFound:
+ case NIRioStatus.kRIOStatusOperationTimedOut:
+ throw new CANMessageNotFoundException();
+ case ERR_CANSessionMux_NotAllowed:
+ case NIRioStatus.kRIOStatusFeatureNotSupported:
+ throw new CANMessageNotAllowedException("MessageID = " + Integer.toString(messageID));
+ case ERR_CANSessionMux_NotInitialized:
+ case NIRioStatus.kRIOStatusResourceNotInitialized:
+ throw new CANNotInitializedException();
+ default:
+ throw new UncleanStatusException("Fatal status code detected: " + Integer.toString(
+ status));
+ }
+ }
+
+ private CANExceptionFactory() {
+
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/can/CANInvalidBufferException.java b/hal/src/main/java/edu/wpi/first/hal/can/CANInvalidBufferException.java
new file mode 100644
index 0000000..8ea718b
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/can/CANInvalidBufferException.java
@@ -0,0 +1,24 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.can;
+
+/**
+ * Exception indicating that a CAN driver library entry-point was passed an invalid buffer.
+ * Typically, this is due to a buffer being too small to include the needed safety token.
+ */
+public class CANInvalidBufferException extends RuntimeException {
+ private static final long serialVersionUID = -7993785672956997939L;
+
+ public CANInvalidBufferException() {
+ super();
+ }
+
+ public CANInvalidBufferException(String msg) {
+ super(msg);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/can/CANJNI.java b/hal/src/main/java/edu/wpi/first/hal/can/CANJNI.java
new file mode 100644
index 0000000..754157b
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/can/CANJNI.java
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.can;
+
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+import edu.wpi.first.hal.JNIWrapper;
+
+@SuppressWarnings("AbbreviationAsWordInName")
+public class CANJNI extends JNIWrapper {
+ public static final int CAN_SEND_PERIOD_NO_REPEAT = 0;
+ public static final int CAN_SEND_PERIOD_STOP_REPEATING = -1;
+
+ /* Flags in the upper bits of the messageID */
+ public static final int CAN_IS_FRAME_REMOTE = 0x80000000;
+ public static final int CAN_IS_FRAME_11BIT = 0x40000000;
+
+ @SuppressWarnings("MethodName")
+ public static native void FRCNetCommCANSessionMuxSendMessage(int messageID,
+ byte[] data,
+ int periodMs);
+
+ @SuppressWarnings("MethodName")
+ public static native byte[] FRCNetCommCANSessionMuxReceiveMessage(
+ IntBuffer messageID, int messageIDMask, ByteBuffer timeStamp);
+
+
+ @SuppressWarnings("MethodName")
+ public static native void GetCANStatus(CANStatus status);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/can/CANMessageNotAllowedException.java b/hal/src/main/java/edu/wpi/first/hal/can/CANMessageNotAllowedException.java
new file mode 100644
index 0000000..f4ba6a8
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/can/CANMessageNotAllowedException.java
@@ -0,0 +1,20 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.can;
+
+/**
+ * Exception indicating that the Jaguar CAN Driver layer refused to send a restricted message ID to
+ * the CAN bus.
+ */
+public class CANMessageNotAllowedException extends RuntimeException {
+ private static final long serialVersionUID = -638450112427013494L;
+
+ public CANMessageNotAllowedException(String msg) {
+ super(msg);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/can/CANMessageNotFoundException.java b/hal/src/main/java/edu/wpi/first/hal/can/CANMessageNotFoundException.java
new file mode 100644
index 0000000..0838691
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/can/CANMessageNotFoundException.java
@@ -0,0 +1,24 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.can;
+
+/**
+ * Exception indicating that a can message is not available from Network Communications. This
+ * usually just means we already have the most recent value cached locally.
+ */
+public class CANMessageNotFoundException extends RuntimeException {
+ private static final long serialVersionUID = 8249780881928189975L;
+
+ public CANMessageNotFoundException() {
+ super();
+ }
+
+ public CANMessageNotFoundException(String msg) {
+ super(msg);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/can/CANNotInitializedException.java b/hal/src/main/java/edu/wpi/first/hal/can/CANNotInitializedException.java
new file mode 100644
index 0000000..119b59d
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/can/CANNotInitializedException.java
@@ -0,0 +1,24 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.can;
+
+/**
+ * Exception indicating that the CAN driver layer has not been initialized. This happens when an
+ * entry-point is called before a CAN driver plugin has been installed.
+ */
+public class CANNotInitializedException extends RuntimeException {
+ private static final long serialVersionUID = -5982895147092686594L;
+
+ public CANNotInitializedException() {
+ super();
+ }
+
+ public CANNotInitializedException(String msg) {
+ super(msg);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/can/CANStatus.java b/hal/src/main/java/edu/wpi/first/hal/can/CANStatus.java
new file mode 100644
index 0000000..492d999
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/can/CANStatus.java
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.can;
+
+/**
+ * Structure for holding the result of a CAN Status request.
+ */
+public class CANStatus {
+ /**
+ * The utilization of the CAN Bus.
+ */
+ @SuppressWarnings("MemberName")
+ public double percentBusUtilization;
+
+ /**
+ * The CAN Bus off count.
+ */
+ @SuppressWarnings("MemberName")
+ public int busOffCount;
+
+ /**
+ * The CAN Bus TX full count.
+ */
+ @SuppressWarnings("MemberName")
+ public int txFullCount;
+
+ /**
+ * The CAN Bus receive error count.
+ */
+ @SuppressWarnings("MemberName")
+ public int receiveErrorCount;
+
+ /**
+ * The CAN Bus transmit error count.
+ */
+ @SuppressWarnings("MemberName")
+ public int transmitErrorCount;
+
+ @SuppressWarnings("JavadocMethod")
+ public void setStatus(double percentBusUtilization, int busOffCount, int txFullCount,
+ int receiveErrorCount, int transmitErrorCount) {
+ this.percentBusUtilization = percentBusUtilization;
+ this.busOffCount = busOffCount;
+ this.txFullCount = txFullCount;
+ this.receiveErrorCount = receiveErrorCount;
+ this.transmitErrorCount = transmitErrorCount;
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/communication/NIRioStatus.java b/hal/src/main/java/edu/wpi/first/hal/communication/NIRioStatus.java
new file mode 100644
index 0000000..f49f34e
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/communication/NIRioStatus.java
@@ -0,0 +1,18 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.communication;
+
+public class NIRioStatus {
+ public static final int kRioStatusOffset = -63000;
+
+ public static final int kRioStatusSuccess = 0;
+ public static final int kRIOStatusBufferInvalidSize = kRioStatusOffset - 80;
+ public static final int kRIOStatusOperationTimedOut = -52007;
+ public static final int kRIOStatusFeatureNotSupported = kRioStatusOffset - 193;
+ public static final int kRIOStatusResourceNotInitialized = -52010;
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/AccelerometerSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/AccelerometerSim.java
new file mode 100644
index 0000000..d9c95af
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/AccelerometerSim.java
@@ -0,0 +1,77 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.AccelerometerDataJNI;
+
+public class AccelerometerSim {
+ private final int m_index;
+
+ public AccelerometerSim() {
+ m_index = 0;
+ }
+
+ public CallbackStore registerActiveCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AccelerometerDataJNI.registerActiveCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AccelerometerDataJNI::cancelActiveCallback);
+ }
+ public boolean getActive() {
+ return AccelerometerDataJNI.getActive(m_index);
+ }
+ public void setActive(boolean active) {
+ AccelerometerDataJNI.setActive(m_index, active);
+ }
+
+ public CallbackStore registerRangeCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AccelerometerDataJNI.registerRangeCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AccelerometerDataJNI::cancelRangeCallback);
+ }
+ public int getRange() {
+ return AccelerometerDataJNI.getRange(m_index);
+ }
+ public void setRange(int range) {
+ AccelerometerDataJNI.setRange(m_index, range);
+ }
+
+ public CallbackStore registerXCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AccelerometerDataJNI.registerXCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AccelerometerDataJNI::cancelXCallback);
+ }
+ public double getX() {
+ return AccelerometerDataJNI.getX(m_index);
+ }
+ public void setX(double x) {
+ AccelerometerDataJNI.setX(m_index, x);
+ }
+
+ public CallbackStore registerYCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AccelerometerDataJNI.registerYCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AccelerometerDataJNI::cancelYCallback);
+ }
+ public double getY() {
+ return AccelerometerDataJNI.getY(m_index);
+ }
+ public void setY(double y) {
+ AccelerometerDataJNI.setY(m_index, y);
+ }
+
+ public CallbackStore registerZCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AccelerometerDataJNI.registerZCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AccelerometerDataJNI::cancelZCallback);
+ }
+ public double getZ() {
+ return AccelerometerDataJNI.getZ(m_index);
+ }
+ public void setZ(double z) {
+ AccelerometerDataJNI.setZ(m_index, z);
+ }
+
+ public void resetData() {
+ AccelerometerDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/AnalogGyroSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/AnalogGyroSim.java
new file mode 100644
index 0000000..ddaa0ce
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/AnalogGyroSim.java
@@ -0,0 +1,55 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.AnalogGyroDataJNI;
+
+public class AnalogGyroSim {
+ private final int m_index;
+
+ public AnalogGyroSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerAngleCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogGyroDataJNI.registerAngleCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogGyroDataJNI::cancelAngleCallback);
+ }
+ public double getAngle() {
+ return AnalogGyroDataJNI.getAngle(m_index);
+ }
+ public void setAngle(double angle) {
+ AnalogGyroDataJNI.setAngle(m_index, angle);
+ }
+
+ public CallbackStore registerRateCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogGyroDataJNI.registerRateCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogGyroDataJNI::cancelRateCallback);
+ }
+ public double getRate() {
+ return AnalogGyroDataJNI.getRate(m_index);
+ }
+ public void setRate(double rate) {
+ AnalogGyroDataJNI.setRate(m_index, rate);
+ }
+
+ public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogGyroDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogGyroDataJNI::cancelInitializedCallback);
+ }
+ public boolean getInitialized() {
+ return AnalogGyroDataJNI.getInitialized(m_index);
+ }
+ public void setInitialized(boolean initialized) {
+ AnalogGyroDataJNI.setInitialized(m_index, initialized);
+ }
+
+ public void resetData() {
+ AnalogGyroDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/AnalogInSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/AnalogInSim.java
new file mode 100644
index 0000000..f7f86bb
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/AnalogInSim.java
@@ -0,0 +1,121 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.AnalogInDataJNI;
+
+public class AnalogInSim {
+ private final int m_index;
+
+ public AnalogInSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogInDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogInDataJNI::cancelInitializedCallback);
+ }
+ public boolean getInitialized() {
+ return AnalogInDataJNI.getInitialized(m_index);
+ }
+ public void setInitialized(boolean initialized) {
+ AnalogInDataJNI.setInitialized(m_index, initialized);
+ }
+
+ public CallbackStore registerAverageBitsCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogInDataJNI.registerAverageBitsCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogInDataJNI::cancelAverageBitsCallback);
+ }
+ public int getAverageBits() {
+ return AnalogInDataJNI.getAverageBits(m_index);
+ }
+ public void setAverageBits(int averageBits) {
+ AnalogInDataJNI.setAverageBits(m_index, averageBits);
+ }
+
+ public CallbackStore registerOversampleBitsCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogInDataJNI.registerOversampleBitsCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogInDataJNI::cancelOversampleBitsCallback);
+ }
+ public int getOversampleBits() {
+ return AnalogInDataJNI.getOversampleBits(m_index);
+ }
+ public void setOversampleBits(int oversampleBits) {
+ AnalogInDataJNI.setOversampleBits(m_index, oversampleBits);
+ }
+
+ public CallbackStore registerVoltageCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogInDataJNI.registerVoltageCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogInDataJNI::cancelVoltageCallback);
+ }
+ public double getVoltage() {
+ return AnalogInDataJNI.getVoltage(m_index);
+ }
+ public void setVoltage(double voltage) {
+ AnalogInDataJNI.setVoltage(m_index, voltage);
+ }
+
+ public CallbackStore registerAccumulatorInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogInDataJNI.registerAccumulatorInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogInDataJNI::cancelAccumulatorInitializedCallback);
+ }
+ public boolean getAccumulatorInitialized() {
+ return AnalogInDataJNI.getAccumulatorInitialized(m_index);
+ }
+ public void setAccumulatorInitialized(boolean accumulatorInitialized) {
+ AnalogInDataJNI.setAccumulatorInitialized(m_index, accumulatorInitialized);
+ }
+
+ public CallbackStore registerAccumulatorValueCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogInDataJNI.registerAccumulatorValueCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogInDataJNI::cancelAccumulatorValueCallback);
+ }
+ public long getAccumulatorValue() {
+ return AnalogInDataJNI.getAccumulatorValue(m_index);
+ }
+ public void setAccumulatorValue(long accumulatorValue) {
+ AnalogInDataJNI.setAccumulatorValue(m_index, accumulatorValue);
+ }
+
+ public CallbackStore registerAccumulatorCountCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogInDataJNI.registerAccumulatorCountCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogInDataJNI::cancelAccumulatorCountCallback);
+ }
+ public long getAccumulatorCount() {
+ return AnalogInDataJNI.getAccumulatorCount(m_index);
+ }
+ public void setAccumulatorCount(long accumulatorCount) {
+ AnalogInDataJNI.setAccumulatorCount(m_index, accumulatorCount);
+ }
+
+ public CallbackStore registerAccumulatorCenterCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogInDataJNI.registerAccumulatorCenterCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogInDataJNI::cancelAccumulatorCenterCallback);
+ }
+ public int getAccumulatorCenter() {
+ return AnalogInDataJNI.getAccumulatorCenter(m_index);
+ }
+ public void setAccumulatorCenter(int accumulatorCenter) {
+ AnalogInDataJNI.setAccumulatorCenter(m_index, accumulatorCenter);
+ }
+
+ public CallbackStore registerAccumulatorDeadbandCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogInDataJNI.registerAccumulatorDeadbandCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogInDataJNI::cancelAccumulatorDeadbandCallback);
+ }
+ public int getAccumulatorDeadband() {
+ return AnalogInDataJNI.getAccumulatorDeadband(m_index);
+ }
+ public void setAccumulatorDeadband(int accumulatorDeadband) {
+ AnalogInDataJNI.setAccumulatorDeadband(m_index, accumulatorDeadband);
+ }
+
+ public void resetData() {
+ AnalogInDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/AnalogOutSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/AnalogOutSim.java
new file mode 100644
index 0000000..4731b11
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/AnalogOutSim.java
@@ -0,0 +1,44 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.AnalogOutDataJNI;
+
+public class AnalogOutSim {
+ private final int m_index;
+
+ public AnalogOutSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerVoltageCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogOutDataJNI.registerVoltageCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogOutDataJNI::cancelVoltageCallback);
+ }
+ public double getVoltage() {
+ return AnalogOutDataJNI.getVoltage(m_index);
+ }
+ public void setVoltage(double voltage) {
+ AnalogOutDataJNI.setVoltage(m_index, voltage);
+ }
+
+ public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogOutDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogOutDataJNI::cancelInitializedCallback);
+ }
+ public boolean getInitialized() {
+ return AnalogOutDataJNI.getInitialized(m_index);
+ }
+ public void setInitialized(boolean initialized) {
+ AnalogOutDataJNI.setInitialized(m_index, initialized);
+ }
+
+ public void resetData() {
+ AnalogOutDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/AnalogTriggerSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/AnalogTriggerSim.java
new file mode 100644
index 0000000..fd88d5f
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/AnalogTriggerSim.java
@@ -0,0 +1,55 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.AnalogTriggerDataJNI;
+
+public class AnalogTriggerSim {
+ private final int m_index;
+
+ public AnalogTriggerSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogTriggerDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogTriggerDataJNI::cancelInitializedCallback);
+ }
+ public boolean getInitialized() {
+ return AnalogTriggerDataJNI.getInitialized(m_index);
+ }
+ public void setInitialized(boolean initialized) {
+ AnalogTriggerDataJNI.setInitialized(m_index, initialized);
+ }
+
+ public CallbackStore registerTriggerLowerBoundCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogTriggerDataJNI.registerTriggerLowerBoundCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogTriggerDataJNI::cancelTriggerLowerBoundCallback);
+ }
+ public double getTriggerLowerBound() {
+ return AnalogTriggerDataJNI.getTriggerLowerBound(m_index);
+ }
+ public void setTriggerLowerBound(double triggerLowerBound) {
+ AnalogTriggerDataJNI.setTriggerLowerBound(m_index, triggerLowerBound);
+ }
+
+ public CallbackStore registerTriggerUpperBoundCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = AnalogTriggerDataJNI.registerTriggerUpperBoundCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, AnalogTriggerDataJNI::cancelTriggerUpperBoundCallback);
+ }
+ public double getTriggerUpperBound() {
+ return AnalogTriggerDataJNI.getTriggerUpperBound(m_index);
+ }
+ public void setTriggerUpperBound(double triggerUpperBound) {
+ AnalogTriggerDataJNI.setTriggerUpperBound(m_index, triggerUpperBound);
+ }
+
+ public void resetData() {
+ AnalogTriggerDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/BufferCallback.java b/hal/src/main/java/edu/wpi/first/hal/sim/BufferCallback.java
new file mode 100644
index 0000000..0f7b2d9
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/BufferCallback.java
@@ -0,0 +1,12 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+public interface BufferCallback {
+ void callback(String name, byte[] buffer, int count);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/CallbackStore.java b/hal/src/main/java/edu/wpi/first/hal/sim/CallbackStore.java
new file mode 100644
index 0000000..7564104
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/CallbackStore.java
@@ -0,0 +1,84 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+public class CallbackStore implements AutoCloseable {
+ interface CancelCallbackFunc {
+ void cancel(int index, int uid);
+ }
+
+ interface CancelCallbackChannelFunc {
+ void cancel(int index, int channel, int uid);
+ }
+
+ interface CancelCallbackNoIndexFunc {
+ void cancel(int uid);
+ }
+
+ public CallbackStore(int index, int uid, CancelCallbackFunc ccf) {
+ this.m_cancelType = kNormalCancel;
+ this.m_index = index;
+ this.m_uid = uid;
+ this.m_cancelCallback = ccf;
+ }
+
+ public CallbackStore(int index, int channel, int uid, CancelCallbackChannelFunc ccf) {
+ this.m_cancelType = kChannelCancel;
+ this.m_index = index;
+ this.m_uid = uid;
+ this.m_channel = channel;
+ this.m_cancelCallbackChannel = ccf;
+ }
+
+ public CallbackStore(int uid, CancelCallbackNoIndexFunc ccf) {
+ this.m_cancelType = kNoIndexCancel;
+ this.m_uid = uid;
+ this.m_cancelCallbackNoIndex = ccf;
+ }
+
+ private int m_index;
+ private int m_channel;
+ private final int m_uid;
+ private CancelCallbackFunc m_cancelCallback;
+ private CancelCallbackChannelFunc m_cancelCallbackChannel;
+ private CancelCallbackNoIndexFunc m_cancelCallbackNoIndex;
+ private static final int kNormalCancel = 0;
+ private static final int kChannelCancel = 1;
+ private static final int kNoIndexCancel = 2;
+ private int m_cancelType;
+
+ @Override
+ public void close() {
+ switch (m_cancelType) {
+ case kNormalCancel:
+ m_cancelCallback.cancel(m_index, m_uid);
+ break;
+ case kChannelCancel:
+ m_cancelCallbackChannel.cancel(m_index, m_channel, m_uid);
+ break;
+ case kNoIndexCancel:
+ m_cancelCallbackNoIndex.cancel(m_uid);
+ break;
+ default:
+ assert false;
+ break;
+ }
+ m_cancelType = -1;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ if (m_cancelType >= 0) {
+ close(); // close open files
+ }
+ } finally {
+ super.finalize();
+ }
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/ConstBufferCallback.java b/hal/src/main/java/edu/wpi/first/hal/sim/ConstBufferCallback.java
new file mode 100644
index 0000000..a4251c2
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/ConstBufferCallback.java
@@ -0,0 +1,12 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+public interface ConstBufferCallback {
+ void callback(String name, byte[] buffer, int count);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/DIOSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/DIOSim.java
new file mode 100644
index 0000000..cd75822
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/DIOSim.java
@@ -0,0 +1,77 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.DIODataJNI;
+
+public class DIOSim {
+ private final int m_index;
+
+ public DIOSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DIODataJNI.registerInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, DIODataJNI::cancelInitializedCallback);
+ }
+ public boolean getInitialized() {
+ return DIODataJNI.getInitialized(m_index);
+ }
+ public void setInitialized(boolean initialized) {
+ DIODataJNI.setInitialized(m_index, initialized);
+ }
+
+ public CallbackStore registerValueCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DIODataJNI.registerValueCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, DIODataJNI::cancelValueCallback);
+ }
+ public boolean getValue() {
+ return DIODataJNI.getValue(m_index);
+ }
+ public void setValue(boolean value) {
+ DIODataJNI.setValue(m_index, value);
+ }
+
+ public CallbackStore registerPulseLengthCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DIODataJNI.registerPulseLengthCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, DIODataJNI::cancelPulseLengthCallback);
+ }
+ public double getPulseLength() {
+ return DIODataJNI.getPulseLength(m_index);
+ }
+ public void setPulseLength(double pulseLength) {
+ DIODataJNI.setPulseLength(m_index, pulseLength);
+ }
+
+ public CallbackStore registerIsInputCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DIODataJNI.registerIsInputCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, DIODataJNI::cancelIsInputCallback);
+ }
+ public boolean getIsInput() {
+ return DIODataJNI.getIsInput(m_index);
+ }
+ public void setIsInput(boolean isInput) {
+ DIODataJNI.setIsInput(m_index, isInput);
+ }
+
+ public CallbackStore registerFilterIndexCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DIODataJNI.registerFilterIndexCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, DIODataJNI::cancelFilterIndexCallback);
+ }
+ public int getFilterIndex() {
+ return DIODataJNI.getFilterIndex(m_index);
+ }
+ public void setFilterIndex(int filterIndex) {
+ DIODataJNI.setFilterIndex(m_index, filterIndex);
+ }
+
+ public void resetData() {
+ DIODataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/DigitalPWMSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/DigitalPWMSim.java
new file mode 100644
index 0000000..314d994
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/DigitalPWMSim.java
@@ -0,0 +1,55 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.DigitalPWMDataJNI;
+
+public class DigitalPWMSim {
+ private final int m_index;
+
+ public DigitalPWMSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DigitalPWMDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, DigitalPWMDataJNI::cancelInitializedCallback);
+ }
+ public boolean getInitialized() {
+ return DigitalPWMDataJNI.getInitialized(m_index);
+ }
+ public void setInitialized(boolean initialized) {
+ DigitalPWMDataJNI.setInitialized(m_index, initialized);
+ }
+
+ public CallbackStore registerDutyCycleCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DigitalPWMDataJNI.registerDutyCycleCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, DigitalPWMDataJNI::cancelDutyCycleCallback);
+ }
+ public double getDutyCycle() {
+ return DigitalPWMDataJNI.getDutyCycle(m_index);
+ }
+ public void setDutyCycle(double dutyCycle) {
+ DigitalPWMDataJNI.setDutyCycle(m_index, dutyCycle);
+ }
+
+ public CallbackStore registerPinCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DigitalPWMDataJNI.registerPinCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, DigitalPWMDataJNI::cancelPinCallback);
+ }
+ public int getPin() {
+ return DigitalPWMDataJNI.getPin(m_index);
+ }
+ public void setPin(int pin) {
+ DigitalPWMDataJNI.setPin(m_index, pin);
+ }
+
+ public void resetData() {
+ DigitalPWMDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/DriverStationSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/DriverStationSim.java
new file mode 100644
index 0000000..20fed0d
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/DriverStationSim.java
@@ -0,0 +1,85 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.DriverStationDataJNI;
+
+public class DriverStationSim {
+ public CallbackStore registerEnabledCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DriverStationDataJNI.registerEnabledCallback(callback, initialNotify);
+ return new CallbackStore(uid, DriverStationDataJNI::cancelEnabledCallback);
+ }
+ public boolean getEnabled() {
+ return DriverStationDataJNI.getEnabled();
+ }
+ public void setEnabled(boolean enabled) {
+ DriverStationDataJNI.setEnabled(enabled);
+ }
+
+ public CallbackStore registerAutonomousCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DriverStationDataJNI.registerAutonomousCallback(callback, initialNotify);
+ return new CallbackStore(uid, DriverStationDataJNI::cancelAutonomousCallback);
+ }
+ public boolean getAutonomous() {
+ return DriverStationDataJNI.getAutonomous();
+ }
+ public void setAutonomous(boolean autonomous) {
+ DriverStationDataJNI.setAutonomous(autonomous);
+ }
+
+ public CallbackStore registerTestCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DriverStationDataJNI.registerTestCallback(callback, initialNotify);
+ return new CallbackStore(uid, DriverStationDataJNI::cancelTestCallback);
+ }
+ public boolean getTest() {
+ return DriverStationDataJNI.getTest();
+ }
+ public void setTest(boolean test) {
+ DriverStationDataJNI.setTest(test);
+ }
+
+ public CallbackStore registerEStopCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DriverStationDataJNI.registerEStopCallback(callback, initialNotify);
+ return new CallbackStore(uid, DriverStationDataJNI::cancelEStopCallback);
+ }
+ public boolean getEStop() {
+ return DriverStationDataJNI.getEStop();
+ }
+ public void setEStop(boolean eStop) {
+ DriverStationDataJNI.setEStop(eStop);
+ }
+
+ public CallbackStore registerFmsAttachedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DriverStationDataJNI.registerFmsAttachedCallback(callback, initialNotify);
+ return new CallbackStore(uid, DriverStationDataJNI::cancelFmsAttachedCallback);
+ }
+ public boolean getFmsAttached() {
+ return DriverStationDataJNI.getFmsAttached();
+ }
+ public void setFmsAttached(boolean fmsAttached) {
+ DriverStationDataJNI.setFmsAttached(fmsAttached);
+ }
+
+ public CallbackStore registerDsAttachedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = DriverStationDataJNI.registerDsAttachedCallback(callback, initialNotify);
+ return new CallbackStore(uid, DriverStationDataJNI::cancelDsAttachedCallback);
+ }
+ public boolean getDsAttached() {
+ return DriverStationDataJNI.getDsAttached();
+ }
+ public void setDsAttached(boolean dsAttached) {
+ DriverStationDataJNI.setDsAttached(dsAttached);
+ }
+ public void notifyNewData() {
+ DriverStationDataJNI.notifyNewData();
+ }
+
+ public void resetData() {
+ DriverStationDataJNI.resetData();
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/EncoderSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/EncoderSim.java
new file mode 100644
index 0000000..408ca84
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/EncoderSim.java
@@ -0,0 +1,110 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.EncoderDataJNI;
+
+public class EncoderSim {
+ private final int m_index;
+
+ public EncoderSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = EncoderDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, EncoderDataJNI::cancelInitializedCallback);
+ }
+ public boolean getInitialized() {
+ return EncoderDataJNI.getInitialized(m_index);
+ }
+ public void setInitialized(boolean initialized) {
+ EncoderDataJNI.setInitialized(m_index, initialized);
+ }
+
+ public CallbackStore registerCountCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = EncoderDataJNI.registerCountCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, EncoderDataJNI::cancelCountCallback);
+ }
+ public int getCount() {
+ return EncoderDataJNI.getCount(m_index);
+ }
+ public void setCount(int count) {
+ EncoderDataJNI.setCount(m_index, count);
+ }
+
+ public CallbackStore registerPeriodCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = EncoderDataJNI.registerPeriodCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, EncoderDataJNI::cancelPeriodCallback);
+ }
+ public double getPeriod() {
+ return EncoderDataJNI.getPeriod(m_index);
+ }
+ public void setPeriod(double period) {
+ EncoderDataJNI.setPeriod(m_index, period);
+ }
+
+ public CallbackStore registerResetCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = EncoderDataJNI.registerResetCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, EncoderDataJNI::cancelResetCallback);
+ }
+ public boolean getReset() {
+ return EncoderDataJNI.getReset(m_index);
+ }
+ public void setReset(boolean reset) {
+ EncoderDataJNI.setReset(m_index, reset);
+ }
+
+ public CallbackStore registerMaxPeriodCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = EncoderDataJNI.registerMaxPeriodCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, EncoderDataJNI::cancelMaxPeriodCallback);
+ }
+ public double getMaxPeriod() {
+ return EncoderDataJNI.getMaxPeriod(m_index);
+ }
+ public void setMaxPeriod(double maxPeriod) {
+ EncoderDataJNI.setMaxPeriod(m_index, maxPeriod);
+ }
+
+ public CallbackStore registerDirectionCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = EncoderDataJNI.registerDirectionCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, EncoderDataJNI::cancelDirectionCallback);
+ }
+ public boolean getDirection() {
+ return EncoderDataJNI.getDirection(m_index);
+ }
+ public void setDirection(boolean direction) {
+ EncoderDataJNI.setDirection(m_index, direction);
+ }
+
+ public CallbackStore registerReverseDirectionCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = EncoderDataJNI.registerReverseDirectionCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, EncoderDataJNI::cancelReverseDirectionCallback);
+ }
+ public boolean getReverseDirection() {
+ return EncoderDataJNI.getReverseDirection(m_index);
+ }
+ public void setReverseDirection(boolean reverseDirection) {
+ EncoderDataJNI.setReverseDirection(m_index, reverseDirection);
+ }
+
+ public CallbackStore registerSamplesToAverageCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = EncoderDataJNI.registerSamplesToAverageCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, EncoderDataJNI::cancelSamplesToAverageCallback);
+ }
+ public int getSamplesToAverage() {
+ return EncoderDataJNI.getSamplesToAverage(m_index);
+ }
+ public void setSamplesToAverage(int samplesToAverage) {
+ EncoderDataJNI.setSamplesToAverage(m_index, samplesToAverage);
+ }
+
+ public void resetData() {
+ EncoderDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/I2CSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/I2CSim.java
new file mode 100644
index 0000000..3a9aa02
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/I2CSim.java
@@ -0,0 +1,43 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.I2CDataJNI;
+
+public class I2CSim {
+ private final int m_index;
+
+ public I2CSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = I2CDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, I2CDataJNI::cancelInitializedCallback);
+ }
+ public boolean getInitialized() {
+ return I2CDataJNI.getInitialized(m_index);
+ }
+ public void setInitialized(boolean initialized) {
+ I2CDataJNI.setInitialized(m_index, initialized);
+ }
+
+ public CallbackStore registerReadCallback(BufferCallback callback) {
+ int uid = I2CDataJNI.registerReadCallback(m_index, callback);
+ return new CallbackStore(m_index, uid, I2CDataJNI::cancelReadCallback);
+ }
+
+ public CallbackStore registerWriteCallback(ConstBufferCallback callback) {
+ int uid = I2CDataJNI.registerWriteCallback(m_index, callback);
+ return new CallbackStore(m_index, uid, I2CDataJNI::cancelWriteCallback);
+ }
+
+ public void resetData() {
+ I2CDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/NotifyCallback.java b/hal/src/main/java/edu/wpi/first/hal/sim/NotifyCallback.java
new file mode 100644
index 0000000..8781f75
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/NotifyCallback.java
@@ -0,0 +1,35 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+public interface NotifyCallback {
+ void callback(String name, SimValue value);
+
+ default void callbackNative(String name, int type, long value1, double value2) {
+ switch (type) {
+ case 0x01:
+ callback(name, SimValue.makeBoolean(value1 != 0));
+ break;
+ case 0x02:
+ callback(name, SimValue.makeDouble(value2));
+ break;
+ case 0x16:
+ callback(name, SimValue.makeEnum((int) value1));
+ break;
+ case 0x32:
+ callback(name, SimValue.makeInt((int) value1));
+ break;
+ case 0x64:
+ callback(name, SimValue.makeLong(value1));
+ break;
+ default:
+ callback(name, SimValue.makeUnassigned());
+ break;
+ }
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/PCMSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/PCMSim.java
new file mode 100644
index 0000000..f8cc327
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/PCMSim.java
@@ -0,0 +1,99 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.PCMDataJNI;
+
+public class PCMSim {
+ private final int m_index;
+
+ public PCMSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerSolenoidInitializedCallback(int channel, NotifyCallback callback, boolean initialNotify) {
+ int uid = PCMDataJNI.registerSolenoidInitializedCallback(m_index, channel, callback, initialNotify);
+ return new CallbackStore(m_index, channel, uid, PCMDataJNI::cancelSolenoidInitializedCallback);
+ }
+ public boolean getSolenoidInitialized(int channel) {
+ return PCMDataJNI.getSolenoidInitialized(m_index, channel);
+ }
+ public void setSolenoidInitialized(int channel, boolean solenoidInitialized) {
+ PCMDataJNI.setSolenoidInitialized(m_index, channel, solenoidInitialized);
+ }
+
+ public CallbackStore registerSolenoidOutputCallback(int channel, NotifyCallback callback, boolean initialNotify) {
+ int uid = PCMDataJNI.registerSolenoidOutputCallback(m_index, channel, callback, initialNotify);
+ return new CallbackStore(m_index, channel, uid, PCMDataJNI::cancelSolenoidOutputCallback);
+ }
+ public boolean getSolenoidOutput(int channel) {
+ return PCMDataJNI.getSolenoidOutput(m_index, channel);
+ }
+ public void setSolenoidOutput(int channel, boolean solenoidOutput) {
+ PCMDataJNI.setSolenoidOutput(m_index, channel, solenoidOutput);
+ }
+
+ public CallbackStore registerCompressorInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PCMDataJNI.registerCompressorInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PCMDataJNI::cancelCompressorInitializedCallback);
+ }
+ public boolean getCompressorInitialized() {
+ return PCMDataJNI.getCompressorInitialized(m_index);
+ }
+ public void setCompressorInitialized(boolean compressorInitialized) {
+ PCMDataJNI.setCompressorInitialized(m_index, compressorInitialized);
+ }
+
+ public CallbackStore registerCompressorOnCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PCMDataJNI.registerCompressorOnCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PCMDataJNI::cancelCompressorOnCallback);
+ }
+ public boolean getCompressorOn() {
+ return PCMDataJNI.getCompressorOn(m_index);
+ }
+ public void setCompressorOn(boolean compressorOn) {
+ PCMDataJNI.setCompressorOn(m_index, compressorOn);
+ }
+
+ public CallbackStore registerClosedLoopEnabledCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PCMDataJNI.registerClosedLoopEnabledCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PCMDataJNI::cancelClosedLoopEnabledCallback);
+ }
+ public boolean getClosedLoopEnabled() {
+ return PCMDataJNI.getClosedLoopEnabled(m_index);
+ }
+ public void setClosedLoopEnabled(boolean closedLoopEnabled) {
+ PCMDataJNI.setClosedLoopEnabled(m_index, closedLoopEnabled);
+ }
+
+ public CallbackStore registerPressureSwitchCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PCMDataJNI.registerPressureSwitchCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PCMDataJNI::cancelPressureSwitchCallback);
+ }
+ public boolean getPressureSwitch() {
+ return PCMDataJNI.getPressureSwitch(m_index);
+ }
+ public void setPressureSwitch(boolean pressureSwitch) {
+ PCMDataJNI.setPressureSwitch(m_index, pressureSwitch);
+ }
+
+ public CallbackStore registerCompressorCurrentCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PCMDataJNI.registerCompressorCurrentCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PCMDataJNI::cancelCompressorCurrentCallback);
+ }
+ public double getCompressorCurrent() {
+ return PCMDataJNI.getCompressorCurrent(m_index);
+ }
+ public void setCompressorCurrent(double compressorCurrent) {
+ PCMDataJNI.setCompressorCurrent(m_index, compressorCurrent);
+ }
+
+ public void resetData() {
+ PCMDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/PDPSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/PDPSim.java
new file mode 100644
index 0000000..d44cf3a
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/PDPSim.java
@@ -0,0 +1,66 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.PDPDataJNI;
+
+public class PDPSim {
+ private final int m_index;
+
+ public PDPSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PDPDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PDPDataJNI::cancelInitializedCallback);
+ }
+ public boolean getInitialized() {
+ return PDPDataJNI.getInitialized(m_index);
+ }
+ public void setInitialized(boolean initialized) {
+ PDPDataJNI.setInitialized(m_index, initialized);
+ }
+
+ public CallbackStore registerTemperatureCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PDPDataJNI.registerTemperatureCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PDPDataJNI::cancelTemperatureCallback);
+ }
+ public double getTemperature() {
+ return PDPDataJNI.getTemperature(m_index);
+ }
+ public void setTemperature(double temperature) {
+ PDPDataJNI.setTemperature(m_index, temperature);
+ }
+
+ public CallbackStore registerVoltageCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PDPDataJNI.registerVoltageCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PDPDataJNI::cancelVoltageCallback);
+ }
+ public double getVoltage() {
+ return PDPDataJNI.getVoltage(m_index);
+ }
+ public void setVoltage(double voltage) {
+ PDPDataJNI.setVoltage(m_index, voltage);
+ }
+
+ public CallbackStore registerCurrentCallback(int channel, NotifyCallback callback, boolean initialNotify) {
+ int uid = PDPDataJNI.registerCurrentCallback(m_index, channel, callback, initialNotify);
+ return new CallbackStore(m_index, channel, uid, PDPDataJNI::cancelCurrentCallback);
+ }
+ public double getCurrent(int channel) {
+ return PDPDataJNI.getCurrent(m_index, channel);
+ }
+ public void setCurrent(int channel, double current) {
+ PDPDataJNI.setCurrent(m_index, channel, current);
+ }
+
+ public void resetData() {
+ PDPDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/PWMSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/PWMSim.java
new file mode 100644
index 0000000..dde38a4
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/PWMSim.java
@@ -0,0 +1,88 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.PWMDataJNI;
+
+public class PWMSim {
+ private final int m_index;
+
+ public PWMSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PWMDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PWMDataJNI::cancelInitializedCallback);
+ }
+ public boolean getInitialized() {
+ return PWMDataJNI.getInitialized(m_index);
+ }
+ public void setInitialized(boolean initialized) {
+ PWMDataJNI.setInitialized(m_index, initialized);
+ }
+
+ public CallbackStore registerRawValueCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PWMDataJNI.registerRawValueCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PWMDataJNI::cancelRawValueCallback);
+ }
+ public int getRawValue() {
+ return PWMDataJNI.getRawValue(m_index);
+ }
+ public void setRawValue(int rawValue) {
+ PWMDataJNI.setRawValue(m_index, rawValue);
+ }
+
+ public CallbackStore registerSpeedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PWMDataJNI.registerSpeedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PWMDataJNI::cancelSpeedCallback);
+ }
+ public double getSpeed() {
+ return PWMDataJNI.getSpeed(m_index);
+ }
+ public void setSpeed(double speed) {
+ PWMDataJNI.setSpeed(m_index, speed);
+ }
+
+ public CallbackStore registerPositionCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PWMDataJNI.registerPositionCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PWMDataJNI::cancelPositionCallback);
+ }
+ public double getPosition() {
+ return PWMDataJNI.getPosition(m_index);
+ }
+ public void setPosition(double position) {
+ PWMDataJNI.setPosition(m_index, position);
+ }
+
+ public CallbackStore registerPeriodScaleCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PWMDataJNI.registerPeriodScaleCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PWMDataJNI::cancelPeriodScaleCallback);
+ }
+ public int getPeriodScale() {
+ return PWMDataJNI.getPeriodScale(m_index);
+ }
+ public void setPeriodScale(int periodScale) {
+ PWMDataJNI.setPeriodScale(m_index, periodScale);
+ }
+
+ public CallbackStore registerZeroLatchCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = PWMDataJNI.registerZeroLatchCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, PWMDataJNI::cancelZeroLatchCallback);
+ }
+ public boolean getZeroLatch() {
+ return PWMDataJNI.getZeroLatch(m_index);
+ }
+ public void setZeroLatch(boolean zeroLatch) {
+ PWMDataJNI.setZeroLatch(m_index, zeroLatch);
+ }
+
+ public void resetData() {
+ PWMDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/RelaySim.java b/hal/src/main/java/edu/wpi/first/hal/sim/RelaySim.java
new file mode 100644
index 0000000..84059e8
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/RelaySim.java
@@ -0,0 +1,66 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.RelayDataJNI;
+
+public class RelaySim {
+ private final int m_index;
+
+ public RelaySim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerInitializedForwardCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RelayDataJNI.registerInitializedForwardCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RelayDataJNI::cancelInitializedForwardCallback);
+ }
+ public boolean getInitializedForward() {
+ return RelayDataJNI.getInitializedForward(m_index);
+ }
+ public void setInitializedForward(boolean initializedForward) {
+ RelayDataJNI.setInitializedForward(m_index, initializedForward);
+ }
+
+ public CallbackStore registerInitializedReverseCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RelayDataJNI.registerInitializedReverseCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RelayDataJNI::cancelInitializedReverseCallback);
+ }
+ public boolean getInitializedReverse() {
+ return RelayDataJNI.getInitializedReverse(m_index);
+ }
+ public void setInitializedReverse(boolean initializedReverse) {
+ RelayDataJNI.setInitializedReverse(m_index, initializedReverse);
+ }
+
+ public CallbackStore registerForwardCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RelayDataJNI.registerForwardCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RelayDataJNI::cancelForwardCallback);
+ }
+ public boolean getForward() {
+ return RelayDataJNI.getForward(m_index);
+ }
+ public void setForward(boolean forward) {
+ RelayDataJNI.setForward(m_index, forward);
+ }
+
+ public CallbackStore registerReverseCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RelayDataJNI.registerReverseCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RelayDataJNI::cancelReverseCallback);
+ }
+ public boolean getReverse() {
+ return RelayDataJNI.getReverse(m_index);
+ }
+ public void setReverse(boolean reverse) {
+ RelayDataJNI.setReverse(m_index, reverse);
+ }
+
+ public void resetData() {
+ RelayDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/RoboRioSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/RoboRioSim.java
new file mode 100644
index 0000000..082f712
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/RoboRioSim.java
@@ -0,0 +1,188 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.RoboRioDataJNI;
+
+@SuppressWarnings({"PMD.ExcessivePublicCount", "PMD.TooManyMethods"})
+public class RoboRioSim {
+ private final int m_index;
+
+ public RoboRioSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerFPGAButtonCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerFPGAButtonCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelFPGAButtonCallback);
+ }
+ public boolean getFPGAButton() {
+ return RoboRioDataJNI.getFPGAButton(m_index);
+ }
+ public void setFPGAButton(boolean fPGAButton) {
+ RoboRioDataJNI.setFPGAButton(m_index, fPGAButton);
+ }
+
+ public CallbackStore registerVInVoltageCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerVInVoltageCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelVInVoltageCallback);
+ }
+ public double getVInVoltage() {
+ return RoboRioDataJNI.getVInVoltage(m_index);
+ }
+ public void setVInVoltage(double vInVoltage) {
+ RoboRioDataJNI.setVInVoltage(m_index, vInVoltage);
+ }
+
+ public CallbackStore registerVInCurrentCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerVInCurrentCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelVInCurrentCallback);
+ }
+ public double getVInCurrent() {
+ return RoboRioDataJNI.getVInCurrent(m_index);
+ }
+ public void setVInCurrent(double vInCurrent) {
+ RoboRioDataJNI.setVInCurrent(m_index, vInCurrent);
+ }
+
+ public CallbackStore registerUserVoltage6VCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerUserVoltage6VCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelUserVoltage6VCallback);
+ }
+ public double getUserVoltage6V() {
+ return RoboRioDataJNI.getUserVoltage6V(m_index);
+ }
+ public void setUserVoltage6V(double userVoltage6V) {
+ RoboRioDataJNI.setUserVoltage6V(m_index, userVoltage6V);
+ }
+
+ public CallbackStore registerUserCurrent6VCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerUserCurrent6VCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelUserCurrent6VCallback);
+ }
+ public double getUserCurrent6V() {
+ return RoboRioDataJNI.getUserCurrent6V(m_index);
+ }
+ public void setUserCurrent6V(double userCurrent6V) {
+ RoboRioDataJNI.setUserCurrent6V(m_index, userCurrent6V);
+ }
+
+ public CallbackStore registerUserActive6VCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerUserActive6VCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelUserActive6VCallback);
+ }
+ public boolean getUserActive6V() {
+ return RoboRioDataJNI.getUserActive6V(m_index);
+ }
+ public void setUserActive6V(boolean userActive6V) {
+ RoboRioDataJNI.setUserActive6V(m_index, userActive6V);
+ }
+
+ public CallbackStore registerUserVoltage5VCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerUserVoltage5VCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelUserVoltage5VCallback);
+ }
+ public double getUserVoltage5V() {
+ return RoboRioDataJNI.getUserVoltage5V(m_index);
+ }
+ public void setUserVoltage5V(double userVoltage5V) {
+ RoboRioDataJNI.setUserVoltage5V(m_index, userVoltage5V);
+ }
+
+ public CallbackStore registerUserCurrent5VCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerUserCurrent5VCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelUserCurrent5VCallback);
+ }
+ public double getUserCurrent5V() {
+ return RoboRioDataJNI.getUserCurrent5V(m_index);
+ }
+ public void setUserCurrent5V(double userCurrent5V) {
+ RoboRioDataJNI.setUserCurrent5V(m_index, userCurrent5V);
+ }
+
+ public CallbackStore registerUserActive5VCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerUserActive5VCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelUserActive5VCallback);
+ }
+ public boolean getUserActive5V() {
+ return RoboRioDataJNI.getUserActive5V(m_index);
+ }
+ public void setUserActive5V(boolean userActive5V) {
+ RoboRioDataJNI.setUserActive5V(m_index, userActive5V);
+ }
+
+ public CallbackStore registerUserVoltage3V3Callback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerUserVoltage3V3Callback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelUserVoltage3V3Callback);
+ }
+ public double getUserVoltage3V3() {
+ return RoboRioDataJNI.getUserVoltage3V3(m_index);
+ }
+ public void setUserVoltage3V3(double userVoltage3V3) {
+ RoboRioDataJNI.setUserVoltage3V3(m_index, userVoltage3V3);
+ }
+
+ public CallbackStore registerUserCurrent3V3Callback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerUserCurrent3V3Callback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelUserCurrent3V3Callback);
+ }
+ public double getUserCurrent3V3() {
+ return RoboRioDataJNI.getUserCurrent3V3(m_index);
+ }
+ public void setUserCurrent3V3(double userCurrent3V3) {
+ RoboRioDataJNI.setUserCurrent3V3(m_index, userCurrent3V3);
+ }
+
+ public CallbackStore registerUserActive3V3Callback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerUserActive3V3Callback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelUserActive3V3Callback);
+ }
+ public boolean getUserActive3V3() {
+ return RoboRioDataJNI.getUserActive3V3(m_index);
+ }
+ public void setUserActive3V3(boolean userActive3V3) {
+ RoboRioDataJNI.setUserActive3V3(m_index, userActive3V3);
+ }
+
+ public CallbackStore registerUserFaults6VCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerUserFaults6VCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelUserFaults6VCallback);
+ }
+ public int getUserFaults6V() {
+ return RoboRioDataJNI.getUserFaults6V(m_index);
+ }
+ public void setUserFaults6V(int userFaults6V) {
+ RoboRioDataJNI.setUserFaults6V(m_index, userFaults6V);
+ }
+
+ public CallbackStore registerUserFaults5VCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerUserFaults5VCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelUserFaults5VCallback);
+ }
+ public int getUserFaults5V() {
+ return RoboRioDataJNI.getUserFaults5V(m_index);
+ }
+ public void setUserFaults5V(int userFaults5V) {
+ RoboRioDataJNI.setUserFaults5V(m_index, userFaults5V);
+ }
+
+ public CallbackStore registerUserFaults3V3Callback(NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerUserFaults3V3Callback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, RoboRioDataJNI::cancelUserFaults3V3Callback);
+ }
+ public int getUserFaults3V3() {
+ return RoboRioDataJNI.getUserFaults3V3(m_index);
+ }
+ public void setUserFaults3V3(int userFaults3V3) {
+ RoboRioDataJNI.setUserFaults3V3(m_index, userFaults3V3);
+ }
+
+ public void resetData() {
+ RoboRioDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/SPIAccelerometerSim.java b/hal/src/main/java/edu/wpi/first/hal/sim/SPIAccelerometerSim.java
new file mode 100644
index 0000000..94577bd
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/SPIAccelerometerSim.java
@@ -0,0 +1,77 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.SPIAccelerometerDataJNI;
+
+public class SPIAccelerometerSim {
+ private final int m_index;
+
+ public SPIAccelerometerSim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerActiveCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = SPIAccelerometerDataJNI.registerActiveCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, SPIAccelerometerDataJNI::cancelActiveCallback);
+ }
+ public boolean getActive() {
+ return SPIAccelerometerDataJNI.getActive(m_index);
+ }
+ public void setActive(boolean active) {
+ SPIAccelerometerDataJNI.setActive(m_index, active);
+ }
+
+ public CallbackStore registerRangeCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = SPIAccelerometerDataJNI.registerRangeCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, SPIAccelerometerDataJNI::cancelRangeCallback);
+ }
+ public int getRange() {
+ return SPIAccelerometerDataJNI.getRange(m_index);
+ }
+ public void setRange(int range) {
+ SPIAccelerometerDataJNI.setRange(m_index, range);
+ }
+
+ public CallbackStore registerXCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = SPIAccelerometerDataJNI.registerXCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, SPIAccelerometerDataJNI::cancelXCallback);
+ }
+ public double getX() {
+ return SPIAccelerometerDataJNI.getX(m_index);
+ }
+ public void setX(double x) {
+ SPIAccelerometerDataJNI.setX(m_index, x);
+ }
+
+ public CallbackStore registerYCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = SPIAccelerometerDataJNI.registerYCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, SPIAccelerometerDataJNI::cancelYCallback);
+ }
+ public double getY() {
+ return SPIAccelerometerDataJNI.getY(m_index);
+ }
+ public void setY(double y) {
+ SPIAccelerometerDataJNI.setY(m_index, y);
+ }
+
+ public CallbackStore registerZCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = SPIAccelerometerDataJNI.registerZCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, SPIAccelerometerDataJNI::cancelZCallback);
+ }
+ public double getZ() {
+ return SPIAccelerometerDataJNI.getZ(m_index);
+ }
+ public void setZ(double z) {
+ SPIAccelerometerDataJNI.setZ(m_index, z);
+ }
+
+ public void resetData() {
+ SPIAccelerometerDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/SPISim.java b/hal/src/main/java/edu/wpi/first/hal/sim/SPISim.java
new file mode 100644
index 0000000..5f43bca
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/SPISim.java
@@ -0,0 +1,48 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.SPIDataJNI;
+
+public class SPISim {
+ private final int m_index;
+
+ public SPISim(int index) {
+ m_index = index;
+ }
+
+ public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
+ int uid = SPIDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
+ return new CallbackStore(m_index, uid, SPIDataJNI::cancelInitializedCallback);
+ }
+ public boolean getInitialized() {
+ return SPIDataJNI.getInitialized(m_index);
+ }
+ public void setInitialized(boolean initialized) {
+ SPIDataJNI.setInitialized(m_index, initialized);
+ }
+
+ public CallbackStore registerReadCallback(BufferCallback callback) {
+ int uid = SPIDataJNI.registerReadCallback(m_index, callback);
+ return new CallbackStore(m_index, uid, SPIDataJNI::cancelReadCallback);
+ }
+
+ public CallbackStore registerWriteCallback(ConstBufferCallback callback) {
+ int uid = SPIDataJNI.registerWriteCallback(m_index, callback);
+ return new CallbackStore(m_index, uid, SPIDataJNI::cancelWriteCallback);
+ }
+
+ public CallbackStore registerReadAutoReceiveBufferCallback(SpiReadAutoReceiveBufferCallback callback) {
+ int uid = SPIDataJNI.registerReadAutoReceiveBufferCallback(m_index, callback);
+ return new CallbackStore(m_index, uid, SPIDataJNI::cancelReadAutoReceiveBufferCallback);
+ }
+
+ public void resetData() {
+ SPIDataJNI.resetData(m_index);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/SimHooks.java b/hal/src/main/java/edu/wpi/first/hal/sim/SimHooks.java
new file mode 100644
index 0000000..6c46111
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/SimHooks.java
@@ -0,0 +1,27 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import edu.wpi.first.hal.sim.mockdata.SimulatorJNI;
+
+public final class SimHooks {
+ private SimHooks() {
+ }
+
+ public static void waitForProgramStart() {
+ SimulatorJNI.waitForProgramStart();
+ }
+
+ public static void setProgramStarted() {
+ SimulatorJNI.setProgramStarted();
+ }
+
+ public static void restartTiming() {
+ SimulatorJNI.restartTiming();
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/SimValue.java b/hal/src/main/java/edu/wpi/first/hal/sim/SimValue.java
new file mode 100644
index 0000000..3dbb7c9
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/SimValue.java
@@ -0,0 +1,66 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+public final class SimValue {
+ private boolean m_boolean;
+ private long m_long;
+ private double m_double;
+
+ private SimValue(boolean b) {
+ m_boolean = b;
+ }
+
+ private SimValue(double v) {
+ m_double = v;
+ }
+
+ private SimValue(long v) {
+ m_long = v;
+ }
+
+ private SimValue() {
+
+ }
+
+ public boolean getBoolean() {
+ return m_boolean;
+ }
+
+ public long getLong() {
+ return m_long;
+ }
+
+ public double getDouble() {
+ return m_double;
+ }
+
+ public static SimValue makeBoolean(boolean value) {
+ return new SimValue(value);
+ }
+
+ public static SimValue makeEnum(int value) {
+ return new SimValue(value);
+ }
+
+ public static SimValue makeInt(int value) {
+ return new SimValue(value);
+ }
+
+ public static SimValue makeLong(long value) {
+ return new SimValue(value);
+ }
+
+ public static SimValue makeDouble(double value) {
+ return new SimValue(value);
+ }
+
+ public static SimValue makeUnassigned() {
+ return new SimValue();
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/SpiReadAutoReceiveBufferCallback.java b/hal/src/main/java/edu/wpi/first/hal/sim/SpiReadAutoReceiveBufferCallback.java
new file mode 100644
index 0000000..5083fab
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/SpiReadAutoReceiveBufferCallback.java
@@ -0,0 +1,12 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+public interface SpiReadAutoReceiveBufferCallback {
+ int callback(String name, int[] buffer, int numToRead);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AccelerometerDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AccelerometerDataJNI.java
new file mode 100644
index 0000000..22276d4
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AccelerometerDataJNI.java
@@ -0,0 +1,40 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class AccelerometerDataJNI extends JNIWrapper {
+ public static native int registerActiveCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelActiveCallback(int index, int uid);
+ public static native boolean getActive(int index);
+ public static native void setActive(int index, boolean active);
+
+ public static native int registerRangeCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelRangeCallback(int index, int uid);
+ public static native int getRange(int index);
+ public static native void setRange(int index, int range);
+
+ public static native int registerXCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelXCallback(int index, int uid);
+ public static native double getX(int index);
+ public static native void setX(int index, double x);
+
+ public static native int registerYCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelYCallback(int index, int uid);
+ public static native double getY(int index);
+ public static native void setY(int index, double y);
+
+ public static native int registerZCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelZCallback(int index, int uid);
+ public static native double getZ(int index);
+ public static native void setZ(int index, double z);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AnalogGyroDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AnalogGyroDataJNI.java
new file mode 100644
index 0000000..4995df2
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AnalogGyroDataJNI.java
@@ -0,0 +1,30 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class AnalogGyroDataJNI extends JNIWrapper {
+ public static native int registerAngleCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelAngleCallback(int index, int uid);
+ public static native double getAngle(int index);
+ public static native void setAngle(int index, double angle);
+
+ public static native int registerRateCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelRateCallback(int index, int uid);
+ public static native double getRate(int index);
+ public static native void setRate(int index, double rate);
+
+ public static native int registerInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedCallback(int index, int uid);
+ public static native boolean getInitialized(int index);
+ public static native void setInitialized(int index, boolean initialized);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AnalogInDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AnalogInDataJNI.java
new file mode 100644
index 0000000..ed4fbac
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AnalogInDataJNI.java
@@ -0,0 +1,60 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class AnalogInDataJNI extends JNIWrapper {
+ public static native int registerInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedCallback(int index, int uid);
+ public static native boolean getInitialized(int index);
+ public static native void setInitialized(int index, boolean initialized);
+
+ public static native int registerAverageBitsCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelAverageBitsCallback(int index, int uid);
+ public static native int getAverageBits(int index);
+ public static native void setAverageBits(int index, int averageBits);
+
+ public static native int registerOversampleBitsCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelOversampleBitsCallback(int index, int uid);
+ public static native int getOversampleBits(int index);
+ public static native void setOversampleBits(int index, int oversampleBits);
+
+ public static native int registerVoltageCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelVoltageCallback(int index, int uid);
+ public static native double getVoltage(int index);
+ public static native void setVoltage(int index, double voltage);
+
+ public static native int registerAccumulatorInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelAccumulatorInitializedCallback(int index, int uid);
+ public static native boolean getAccumulatorInitialized(int index);
+ public static native void setAccumulatorInitialized(int index, boolean accumulatorInitialized);
+
+ public static native int registerAccumulatorValueCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelAccumulatorValueCallback(int index, int uid);
+ public static native long getAccumulatorValue(int index);
+ public static native void setAccumulatorValue(int index, long accumulatorValue);
+
+ public static native int registerAccumulatorCountCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelAccumulatorCountCallback(int index, int uid);
+ public static native long getAccumulatorCount(int index);
+ public static native void setAccumulatorCount(int index, long accumulatorCount);
+
+ public static native int registerAccumulatorCenterCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelAccumulatorCenterCallback(int index, int uid);
+ public static native int getAccumulatorCenter(int index);
+ public static native void setAccumulatorCenter(int index, int AccumulatorCenter);
+
+ public static native int registerAccumulatorDeadbandCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelAccumulatorDeadbandCallback(int index, int uid);
+ public static native int getAccumulatorDeadband(int index);
+ public static native void setAccumulatorDeadband(int index, int AccumulatorDeadband);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AnalogOutDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AnalogOutDataJNI.java
new file mode 100644
index 0000000..2f7596c
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AnalogOutDataJNI.java
@@ -0,0 +1,25 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class AnalogOutDataJNI extends JNIWrapper {
+ public static native int registerVoltageCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelVoltageCallback(int index, int uid);
+ public static native double getVoltage(int index);
+ public static native void setVoltage(int index, double voltage);
+
+ public static native int registerInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedCallback(int index, int uid);
+ public static native boolean getInitialized(int index);
+ public static native void setInitialized(int index, boolean initialized);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AnalogTriggerDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AnalogTriggerDataJNI.java
new file mode 100644
index 0000000..cf4187f
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/AnalogTriggerDataJNI.java
@@ -0,0 +1,30 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class AnalogTriggerDataJNI extends JNIWrapper {
+ public static native int registerInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedCallback(int index, int uid);
+ public static native boolean getInitialized(int index);
+ public static native void setInitialized(int index, boolean initialized);
+
+ public static native int registerTriggerLowerBoundCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelTriggerLowerBoundCallback(int index, int uid);
+ public static native double getTriggerLowerBound(int index);
+ public static native void setTriggerLowerBound(int index, double triggerLowerBound);
+
+ public static native int registerTriggerUpperBoundCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelTriggerUpperBoundCallback(int index, int uid);
+ public static native double getTriggerUpperBound(int index);
+ public static native void setTriggerUpperBound(int index, double triggerUpperBound);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/DIODataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/DIODataJNI.java
new file mode 100644
index 0000000..55de7de
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/DIODataJNI.java
@@ -0,0 +1,40 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class DIODataJNI extends JNIWrapper {
+ public static native int registerInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedCallback(int index, int uid);
+ public static native boolean getInitialized(int index);
+ public static native void setInitialized(int index, boolean initialized);
+
+ public static native int registerValueCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelValueCallback(int index, int uid);
+ public static native boolean getValue(int index);
+ public static native void setValue(int index, boolean value);
+
+ public static native int registerPulseLengthCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelPulseLengthCallback(int index, int uid);
+ public static native double getPulseLength(int index);
+ public static native void setPulseLength(int index, double pulseLength);
+
+ public static native int registerIsInputCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelIsInputCallback(int index, int uid);
+ public static native boolean getIsInput(int index);
+ public static native void setIsInput(int index, boolean isInput);
+
+ public static native int registerFilterIndexCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelFilterIndexCallback(int index, int uid);
+ public static native int getFilterIndex(int index);
+ public static native void setFilterIndex(int index, int filterIndex);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/DigitalPWMDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/DigitalPWMDataJNI.java
new file mode 100644
index 0000000..69bee07
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/DigitalPWMDataJNI.java
@@ -0,0 +1,30 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class DigitalPWMDataJNI extends JNIWrapper {
+ public static native int registerInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedCallback(int index, int uid);
+ public static native boolean getInitialized(int index);
+ public static native void setInitialized(int index, boolean initialized);
+
+ public static native int registerDutyCycleCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelDutyCycleCallback(int index, int uid);
+ public static native double getDutyCycle(int index);
+ public static native void setDutyCycle(int index, double dutyCycle);
+
+ public static native int registerPinCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelPinCallback(int index, int uid);
+ public static native int getPin(int index);
+ public static native void setPin(int index, int pin);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/DriverStationDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/DriverStationDataJNI.java
new file mode 100644
index 0000000..2d41ca7
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/DriverStationDataJNI.java
@@ -0,0 +1,53 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.JNIWrapper;
+import edu.wpi.first.hal.sim.NotifyCallback;
+
+public class DriverStationDataJNI extends JNIWrapper {
+ public static native int registerEnabledCallback(NotifyCallback callback, boolean initialNotify);
+ public static native void cancelEnabledCallback(int uid);
+ public static native boolean getEnabled();
+ public static native void setEnabled(boolean enabled);
+
+ public static native int registerAutonomousCallback(NotifyCallback callback, boolean initialNotify);
+ public static native void cancelAutonomousCallback(int uid);
+ public static native boolean getAutonomous();
+ public static native void setAutonomous(boolean autonomous);
+
+ public static native int registerTestCallback(NotifyCallback callback, boolean initialNotify);
+ public static native void cancelTestCallback(int uid);
+ public static native boolean getTest();
+ public static native void setTest(boolean test);
+
+ public static native int registerEStopCallback(NotifyCallback callback, boolean initialNotify);
+ public static native void cancelEStopCallback(int uid);
+ public static native boolean getEStop();
+ public static native void setEStop(boolean eStop);
+
+ public static native int registerFmsAttachedCallback(NotifyCallback callback, boolean initialNotify);
+ public static native void cancelFmsAttachedCallback(int uid);
+ public static native boolean getFmsAttached();
+ public static native void setFmsAttached(boolean fmsAttached);
+
+ public static native int registerDsAttachedCallback(NotifyCallback callback, boolean initialNotify);
+ public static native void cancelDsAttachedCallback(int uid);
+ public static native boolean getDsAttached();
+ public static native void setDsAttached(boolean dsAttached);
+
+ public static native void setJoystickAxes(byte joystickNum, float[] axesArray);
+ public static native void setJoystickPOVs(byte joystickNum, short[] povsArray);
+ public static native void setJoystickButtons(byte joystickNum, int buttons, int count);
+
+ public static native void setMatchInfo(String eventName, String gameSpecificMessage, int matchNumber, int replayNumber, int matchType);
+ public static native void registerAllCallbacks(NotifyCallback callback, boolean initialNotify);
+ public static native void notifyNewData();
+
+ public static native void resetData();
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/EncoderDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/EncoderDataJNI.java
new file mode 100644
index 0000000..17e242e
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/EncoderDataJNI.java
@@ -0,0 +1,55 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class EncoderDataJNI extends JNIWrapper {
+ public static native int registerInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedCallback(int index, int uid);
+ public static native boolean getInitialized(int index);
+ public static native void setInitialized(int index, boolean initialized);
+
+ public static native int registerCountCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelCountCallback(int index, int uid);
+ public static native int getCount(int index);
+ public static native void setCount(int index, int count);
+
+ public static native int registerPeriodCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelPeriodCallback(int index, int uid);
+ public static native double getPeriod(int index);
+ public static native void setPeriod(int index, double period);
+
+ public static native int registerResetCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelResetCallback(int index, int uid);
+ public static native boolean getReset(int index);
+ public static native void setReset(int index, boolean reset);
+
+ public static native int registerMaxPeriodCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelMaxPeriodCallback(int index, int uid);
+ public static native double getMaxPeriod(int index);
+ public static native void setMaxPeriod(int index, double maxPeriod);
+
+ public static native int registerDirectionCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelDirectionCallback(int index, int uid);
+ public static native boolean getDirection(int index);
+ public static native void setDirection(int index, boolean direction);
+
+ public static native int registerReverseDirectionCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelReverseDirectionCallback(int index, int uid);
+ public static native boolean getReverseDirection(int index);
+ public static native void setReverseDirection(int index, boolean reverseDirection);
+
+ public static native int registerSamplesToAverageCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelSamplesToAverageCallback(int index, int uid);
+ public static native int getSamplesToAverage(int index);
+ public static native void setSamplesToAverage(int index, int samplesToAverage);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/I2CDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/I2CDataJNI.java
new file mode 100644
index 0000000..33d78f8
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/I2CDataJNI.java
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.BufferCallback;
+import edu.wpi.first.hal.sim.ConstBufferCallback;
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class I2CDataJNI extends JNIWrapper {
+ public static native int registerInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedCallback(int index, int uid);
+ public static native boolean getInitialized(int index);
+ public static native void setInitialized(int index, boolean initialized);
+
+ public static native int registerReadCallback(int index, BufferCallback callback);
+ public static native void cancelReadCallback(int index, int uid);
+
+ public static native int registerWriteCallback(int index, ConstBufferCallback callback);
+ public static native void cancelWriteCallback(int index, int uid);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/PCMDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/PCMDataJNI.java
new file mode 100644
index 0000000..c5de287
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/PCMDataJNI.java
@@ -0,0 +1,53 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class PCMDataJNI extends JNIWrapper {
+ public static native int registerSolenoidInitializedCallback(int index, int channel, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelSolenoidInitializedCallback(int index, int channel, int uid);
+ public static native boolean getSolenoidInitialized(int index, int channel);
+ public static native void setSolenoidInitialized(int index, int channel, boolean solenoidInitialized);
+
+ public static native int registerSolenoidOutputCallback(int index, int channel, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelSolenoidOutputCallback(int index, int channel, int uid);
+ public static native boolean getSolenoidOutput(int index, int channel);
+ public static native void setSolenoidOutput(int index, int channel, boolean solenoidOutput);
+
+ public static native int registerCompressorInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelCompressorInitializedCallback(int index, int uid);
+ public static native boolean getCompressorInitialized(int index);
+ public static native void setCompressorInitialized(int index, boolean compressorInitialized);
+
+ public static native int registerCompressorOnCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelCompressorOnCallback(int index, int uid);
+ public static native boolean getCompressorOn(int index);
+ public static native void setCompressorOn(int index, boolean compressorOn);
+
+ public static native int registerClosedLoopEnabledCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelClosedLoopEnabledCallback(int index, int uid);
+ public static native boolean getClosedLoopEnabled(int index);
+ public static native void setClosedLoopEnabled(int index, boolean closeLoopEnabled);
+
+ public static native int registerPressureSwitchCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelPressureSwitchCallback(int index, int uid);
+ public static native boolean getPressureSwitch(int index);
+ public static native void setPressureSwitch(int index, boolean pressureSwitch);
+
+ public static native int registerCompressorCurrentCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelCompressorCurrentCallback(int index, int uid);
+ public static native double getCompressorCurrent(int index);
+ public static native void setCompressorCurrent(int index, double compressorCurrent);
+
+ public static native void registerAllNonSolenoidCallbacks(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void registerAllSolenoidCallbacks(int index, int channel, NotifyCallback callback, boolean initialNotify);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/PDPDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/PDPDataJNI.java
new file mode 100644
index 0000000..581a727
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/PDPDataJNI.java
@@ -0,0 +1,36 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class PDPDataJNI extends JNIWrapper {
+ public static native int registerInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedCallback(int index, int uid);
+ public static native boolean getInitialized(int index);
+ public static native void setInitialized(int index, boolean initialized);
+
+ public static native int registerTemperatureCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelTemperatureCallback(int index, int uid);
+ public static native double getTemperature(int index);
+ public static native void setTemperature(int index, double temperature);
+
+ public static native int registerVoltageCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelVoltageCallback(int index, int uid);
+ public static native double getVoltage(int index);
+ public static native void setVoltage(int index, double voltage);
+
+
+ public static native int registerCurrentCallback(int index, int channel, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelCurrentCallback(int index, int channel, int uid);
+ public static native double getCurrent(int index, int channel);
+ public static native void setCurrent(int index, int channel, double current);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/PWMDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/PWMDataJNI.java
new file mode 100644
index 0000000..e36990e
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/PWMDataJNI.java
@@ -0,0 +1,45 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class PWMDataJNI extends JNIWrapper {
+ public static native int registerInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedCallback(int index, int uid);
+ public static native boolean getInitialized(int index);
+ public static native void setInitialized(int index, boolean initialized);
+
+ public static native int registerRawValueCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelRawValueCallback(int index, int uid);
+ public static native int getRawValue(int index);
+ public static native void setRawValue(int index, int rawValue);
+
+ public static native int registerSpeedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelSpeedCallback(int index, int uid);
+ public static native double getSpeed(int index);
+ public static native void setSpeed(int index, double speed);
+
+ public static native int registerPositionCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelPositionCallback(int index, int uid);
+ public static native double getPosition(int index);
+ public static native void setPosition(int index, double position);
+
+ public static native int registerPeriodScaleCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelPeriodScaleCallback(int index, int uid);
+ public static native int getPeriodScale(int index);
+ public static native void setPeriodScale(int index, int periodScale);
+
+ public static native int registerZeroLatchCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelZeroLatchCallback(int index, int uid);
+ public static native boolean getZeroLatch(int index);
+ public static native void setZeroLatch(int index, boolean zeroLatch);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/RelayDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/RelayDataJNI.java
new file mode 100644
index 0000000..320a86d
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/RelayDataJNI.java
@@ -0,0 +1,35 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class RelayDataJNI extends JNIWrapper {
+ public static native int registerInitializedForwardCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedForwardCallback(int index, int uid);
+ public static native boolean getInitializedForward(int index);
+ public static native void setInitializedForward(int index, boolean initializedForward);
+
+ public static native int registerInitializedReverseCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedReverseCallback(int index, int uid);
+ public static native boolean getInitializedReverse(int index);
+ public static native void setInitializedReverse(int index, boolean initializedReverse);
+
+ public static native int registerForwardCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelForwardCallback(int index, int uid);
+ public static native boolean getForward(int index);
+ public static native void setForward(int index, boolean forward);
+
+ public static native int registerReverseCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelReverseCallback(int index, int uid);
+ public static native boolean getReverse(int index);
+ public static native void setReverse(int index, boolean reverse);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/RoboRioDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/RoboRioDataJNI.java
new file mode 100644
index 0000000..a13845c
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/RoboRioDataJNI.java
@@ -0,0 +1,90 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class RoboRioDataJNI extends JNIWrapper {
+ public static native int registerFPGAButtonCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelFPGAButtonCallback(int index, int uid);
+ public static native boolean getFPGAButton(int index);
+ public static native void setFPGAButton(int index, boolean fPGAButton);
+
+ public static native int registerVInVoltageCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelVInVoltageCallback(int index, int uid);
+ public static native double getVInVoltage(int index);
+ public static native void setVInVoltage(int index, double vInVoltage);
+
+ public static native int registerVInCurrentCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelVInCurrentCallback(int index, int uid);
+ public static native double getVInCurrent(int index);
+ public static native void setVInCurrent(int index, double vInCurrent);
+
+ public static native int registerUserVoltage6VCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelUserVoltage6VCallback(int index, int uid);
+ public static native double getUserVoltage6V(int index);
+ public static native void setUserVoltage6V(int index, double userVoltage6V);
+
+ public static native int registerUserCurrent6VCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelUserCurrent6VCallback(int index, int uid);
+ public static native double getUserCurrent6V(int index);
+ public static native void setUserCurrent6V(int index, double userCurrent6V);
+
+ public static native int registerUserActive6VCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelUserActive6VCallback(int index, int uid);
+ public static native boolean getUserActive6V(int index);
+ public static native void setUserActive6V(int index, boolean userActive6V);
+
+ public static native int registerUserVoltage5VCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelUserVoltage5VCallback(int index, int uid);
+ public static native double getUserVoltage5V(int index);
+ public static native void setUserVoltage5V(int index, double userVoltage5V);
+
+ public static native int registerUserCurrent5VCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelUserCurrent5VCallback(int index, int uid);
+ public static native double getUserCurrent5V(int index);
+ public static native void setUserCurrent5V(int index, double userCurrent5V);
+
+ public static native int registerUserActive5VCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelUserActive5VCallback(int index, int uid);
+ public static native boolean getUserActive5V(int index);
+ public static native void setUserActive5V(int index, boolean userActive5V);
+
+ public static native int registerUserVoltage3V3Callback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelUserVoltage3V3Callback(int index, int uid);
+ public static native double getUserVoltage3V3(int index);
+ public static native void setUserVoltage3V3(int index, double userVoltage3V3);
+
+ public static native int registerUserCurrent3V3Callback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelUserCurrent3V3Callback(int index, int uid);
+ public static native double getUserCurrent3V3(int index);
+ public static native void setUserCurrent3V3(int index, double userCurrent3V3);
+
+ public static native int registerUserActive3V3Callback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelUserActive3V3Callback(int index, int uid);
+ public static native boolean getUserActive3V3(int index);
+ public static native void setUserActive3V3(int index, boolean userActive3V3);
+
+ public static native int registerUserFaults6VCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelUserFaults6VCallback(int index, int uid);
+ public static native int getUserFaults6V(int index);
+ public static native void setUserFaults6V(int index, int userFaults6V);
+
+ public static native int registerUserFaults5VCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelUserFaults5VCallback(int index, int uid);
+ public static native int getUserFaults5V(int index);
+ public static native void setUserFaults5V(int index, int userFaults5V);
+
+ public static native int registerUserFaults3V3Callback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelUserFaults3V3Callback(int index, int uid);
+ public static native int getUserFaults3V3(int index);
+ public static native void setUserFaults3V3(int index, int userFaults3V3);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/SPIAccelerometerDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/SPIAccelerometerDataJNI.java
new file mode 100644
index 0000000..d8e7353
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/SPIAccelerometerDataJNI.java
@@ -0,0 +1,40 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class SPIAccelerometerDataJNI extends JNIWrapper {
+ public static native int registerActiveCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelActiveCallback(int index, int uid);
+ public static native boolean getActive(int index);
+ public static native void setActive(int index, boolean active);
+
+ public static native int registerRangeCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelRangeCallback(int index, int uid);
+ public static native int getRange(int index);
+ public static native void setRange(int index, int range);
+
+ public static native int registerXCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelXCallback(int index, int uid);
+ public static native double getX(int index);
+ public static native void setX(int index, double x);
+
+ public static native int registerYCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelYCallback(int index, int uid);
+ public static native double getY(int index);
+ public static native void setY(int index, double y);
+
+ public static native int registerZCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelZCallback(int index, int uid);
+ public static native double getZ(int index);
+ public static native void setZ(int index, double z);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/SPIDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/SPIDataJNI.java
new file mode 100644
index 0000000..a12ec66
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/SPIDataJNI.java
@@ -0,0 +1,32 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.sim.BufferCallback;
+import edu.wpi.first.hal.sim.ConstBufferCallback;
+import edu.wpi.first.hal.sim.NotifyCallback;
+import edu.wpi.first.hal.sim.SpiReadAutoReceiveBufferCallback;
+import edu.wpi.first.hal.JNIWrapper;
+
+public class SPIDataJNI extends JNIWrapper {
+ public static native int registerInitializedCallback(int index, NotifyCallback callback, boolean initialNotify);
+ public static native void cancelInitializedCallback(int index, int uid);
+ public static native boolean getInitialized(int index);
+ public static native void setInitialized(int index, boolean initialized);
+
+ public static native int registerReadCallback(int index, BufferCallback callback);
+ public static native void cancelReadCallback(int index, int uid);
+
+ public static native int registerWriteCallback(int index, ConstBufferCallback callback);
+ public static native void cancelWriteCallback(int index, int uid);
+
+ public static native int registerReadAutoReceiveBufferCallback(int index, SpiReadAutoReceiveBufferCallback callback);
+ public static native void cancelReadAutoReceiveBufferCallback(int index, int uid);
+
+ public static native void resetData(int index);
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/SimulatorJNI.java b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/SimulatorJNI.java
new file mode 100644
index 0000000..bb86005
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/sim/mockdata/SimulatorJNI.java
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim.mockdata;
+
+import edu.wpi.first.hal.JNIWrapper;
+
+public class SimulatorJNI extends JNIWrapper {
+ public static native void waitForProgramStart();
+ public static native void setProgramStarted();
+ public static native void restartTiming();
+ public static native void resetHandles();
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/util/AllocationException.java b/hal/src/main/java/edu/wpi/first/hal/util/AllocationException.java
new file mode 100644
index 0000000..6f789d8
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/util/AllocationException.java
@@ -0,0 +1,22 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.util;
+
+/**
+ * Exception indicating that the resource is already allocated.
+ */
+public class AllocationException extends RuntimeException {
+ /**
+ * Create a new AllocationException.
+ *
+ * @param msg the message to attach to the exception
+ */
+ public AllocationException(String msg) {
+ super(msg);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/util/BoundaryException.java b/hal/src/main/java/edu/wpi/first/hal/util/BoundaryException.java
new file mode 100644
index 0000000..8f21e60
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/util/BoundaryException.java
@@ -0,0 +1,50 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.util;
+
+/**
+ * This exception represents an error in which a lower limit was set as higher than an upper limit.
+ */
+public class BoundaryException extends RuntimeException {
+ /**
+ * Create a new exception with the given message.
+ *
+ * @param message the message to attach to the exception
+ */
+ public BoundaryException(String message) {
+ super(message);
+ }
+
+ /**
+ * Make sure that the given value is between the upper and lower bounds, and throw an exception if
+ * they are not.
+ *
+ * @param value The value to check.
+ * @param lower The minimum acceptable value.
+ * @param upper The maximum acceptable value.
+ */
+ public static void assertWithinBounds(double value, double lower, double upper) {
+ if (value < lower || value > upper) {
+ throw new BoundaryException("Value must be between " + lower + " and " + upper + ", " + value
+ + " given");
+ }
+ }
+
+ /**
+ * Returns the message for a boundary exception. Used to keep the message consistent across all
+ * boundary exceptions.
+ *
+ * @param value The given value
+ * @param lower The lower limit
+ * @param upper The upper limit
+ * @return the message for a boundary exception
+ */
+ public static String getMessage(double value, double lower, double upper) {
+ return "Value must be between " + lower + " and " + upper + ", " + value + " given";
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/util/CheckedAllocationException.java b/hal/src/main/java/edu/wpi/first/hal/util/CheckedAllocationException.java
new file mode 100644
index 0000000..f17e381
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/util/CheckedAllocationException.java
@@ -0,0 +1,23 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.util;
+
+/**
+ * Exception indicating that the resource is already allocated This is meant to be thrown by the
+ * resource class.
+ */
+public class CheckedAllocationException extends Exception {
+ /**
+ * Create a new CheckedAllocationException.
+ *
+ * @param msg the message to attach to the exception
+ */
+ public CheckedAllocationException(String msg) {
+ super(msg);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/util/HalHandleException.java b/hal/src/main/java/edu/wpi/first/hal/util/HalHandleException.java
new file mode 100644
index 0000000..874b07a
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/util/HalHandleException.java
@@ -0,0 +1,22 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.util;
+
+/**
+ * Exception indicating that an error has occured with a HAL Handle.
+ */
+public class HalHandleException extends RuntimeException {
+ /**
+ * Create a new HalHandleException.
+ *
+ * @param msg the message to attach to the exception
+ */
+ public HalHandleException(String msg) {
+ super(msg);
+ }
+}
diff --git a/hal/src/main/java/edu/wpi/first/hal/util/UncleanStatusException.java b/hal/src/main/java/edu/wpi/first/hal/util/UncleanStatusException.java
new file mode 100644
index 0000000..3a3e217
--- /dev/null
+++ b/hal/src/main/java/edu/wpi/first/hal/util/UncleanStatusException.java
@@ -0,0 +1,60 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.util;
+
+/**
+ * Exception for bad status codes from the chip object.
+ */
+public final class UncleanStatusException extends IllegalStateException {
+ private final int m_statusCode;
+
+ /**
+ * Create a new UncleanStatusException.
+ *
+ * @param status the status code that caused the exception
+ * @param message A message describing the exception
+ */
+ public UncleanStatusException(int status, String message) {
+ super(message);
+ m_statusCode = status;
+ }
+
+ /**
+ * Create a new UncleanStatusException.
+ *
+ * @param status the status code that caused the exception
+ */
+ public UncleanStatusException(int status) {
+ this(status, "Status code was non-zero");
+ }
+
+ /**
+ * Create a new UncleanStatusException.
+ *
+ * @param message a message describing the exception
+ */
+ public UncleanStatusException(String message) {
+ this(-1, message);
+ }
+
+ /**
+ * Create a new UncleanStatusException.
+ */
+ public UncleanStatusException() {
+ this(-1, "Status code was non-zero");
+ }
+
+ /**
+ * Create a new UncleanStatusException.
+ *
+ * @return the status code that caused the exception
+ */
+ public int getStatus() {
+ return m_statusCode;
+ }
+}
diff --git a/hal/src/main/native/athena/Accelerometer.cpp b/hal/src/main/native/athena/Accelerometer.cpp
new file mode 100644
index 0000000..f83c06e
--- /dev/null
+++ b/hal/src/main/native/athena/Accelerometer.cpp
@@ -0,0 +1,243 @@
+/*----------------------------------------------------------------------------*/
+/* 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/Accelerometer.h"
+
+#include <stdint.h>
+
+#include <cassert>
+#include <cstdio>
+#include <memory>
+
+#include "HALInitializer.h"
+#include "hal/ChipObject.h"
+#include "hal/HAL.h"
+
+using namespace hal;
+
+// The 7-bit I2C address with a 0 "send" bit
+static constexpr uint8_t kSendAddress = (0x1c << 1) | 0;
+
+// The 7-bit I2C address with a 1 "receive" bit
+static constexpr uint8_t kReceiveAddress = (0x1c << 1) | 1;
+
+static constexpr uint8_t kControlTxRx = 1;
+static constexpr uint8_t kControlStart = 2;
+static constexpr uint8_t kControlStop = 4;
+
+static std::unique_ptr<tAccel> accel;
+static HAL_AccelerometerRange accelerometerRange;
+
+// Register addresses
+enum Register {
+ kReg_Status = 0x00,
+ kReg_OutXMSB = 0x01,
+ kReg_OutXLSB = 0x02,
+ kReg_OutYMSB = 0x03,
+ kReg_OutYLSB = 0x04,
+ kReg_OutZMSB = 0x05,
+ kReg_OutZLSB = 0x06,
+ kReg_Sysmod = 0x0B,
+ kReg_IntSource = 0x0C,
+ kReg_WhoAmI = 0x0D,
+ kReg_XYZDataCfg = 0x0E,
+ kReg_HPFilterCutoff = 0x0F,
+ kReg_PLStatus = 0x10,
+ kReg_PLCfg = 0x11,
+ kReg_PLCount = 0x12,
+ kReg_PLBfZcomp = 0x13,
+ kReg_PLThsReg = 0x14,
+ kReg_FFMtCfg = 0x15,
+ kReg_FFMtSrc = 0x16,
+ kReg_FFMtThs = 0x17,
+ kReg_FFMtCount = 0x18,
+ kReg_TransientCfg = 0x1D,
+ kReg_TransientSrc = 0x1E,
+ kReg_TransientThs = 0x1F,
+ kReg_TransientCount = 0x20,
+ kReg_PulseCfg = 0x21,
+ kReg_PulseSrc = 0x22,
+ kReg_PulseThsx = 0x23,
+ kReg_PulseThsy = 0x24,
+ kReg_PulseThsz = 0x25,
+ kReg_PulseTmlt = 0x26,
+ kReg_PulseLtcy = 0x27,
+ kReg_PulseWind = 0x28,
+ kReg_ASlpCount = 0x29,
+ kReg_CtrlReg1 = 0x2A,
+ kReg_CtrlReg2 = 0x2B,
+ kReg_CtrlReg3 = 0x2C,
+ kReg_CtrlReg4 = 0x2D,
+ kReg_CtrlReg5 = 0x2E,
+ kReg_OffX = 0x2F,
+ kReg_OffY = 0x30,
+ kReg_OffZ = 0x31
+};
+
+namespace hal {
+namespace init {
+void InitializeAccelerometer() {}
+} // namespace init
+} // namespace hal
+
+namespace hal {
+
+static void writeRegister(Register reg, uint8_t data);
+static uint8_t readRegister(Register reg);
+
+/**
+ * Initialize the accelerometer.
+ */
+static void initializeAccelerometer() {
+ hal::init::CheckInit();
+ int32_t status;
+
+ if (!accel) {
+ accel.reset(tAccel::create(&status));
+
+ accelerometerRange = HAL_AccelerometerRange::HAL_AccelerometerRange_k2G;
+
+ // Enable I2C
+ accel->writeCNFG(1, &status);
+
+ // Set the counter to 100 kbps
+ accel->writeCNTR(213, &status);
+
+ // The device identification number should be 0x2a
+ assert(readRegister(kReg_WhoAmI) == 0x2a);
+ }
+}
+
+static void writeRegister(Register reg, uint8_t data) {
+ int32_t status = 0;
+ uint64_t initialTime;
+
+ accel->writeADDR(kSendAddress, &status);
+
+ // Send a start transmit/receive message with the register address
+ accel->writeCNTL(kControlStart | kControlTxRx, &status);
+ accel->writeDATO(reg, &status);
+ accel->strobeGO(&status);
+
+ // Execute and wait until it's done (up to a millisecond)
+ initialTime = HAL_GetFPGATime(&status);
+ while (accel->readSTAT(&status) & 1) {
+ if (HAL_GetFPGATime(&status) > initialTime + 1000) break;
+ }
+
+ // Send a stop transmit/receive message with the data
+ accel->writeCNTL(kControlStop | kControlTxRx, &status);
+ accel->writeDATO(data, &status);
+ accel->strobeGO(&status);
+
+ // Execute and wait until it's done (up to a millisecond)
+ initialTime = HAL_GetFPGATime(&status);
+ while (accel->readSTAT(&status) & 1) {
+ if (HAL_GetFPGATime(&status) > initialTime + 1000) break;
+ }
+}
+
+static uint8_t readRegister(Register reg) {
+ int32_t status = 0;
+ uint64_t initialTime;
+
+ // Send a start transmit/receive message with the register address
+ accel->writeADDR(kSendAddress, &status);
+ accel->writeCNTL(kControlStart | kControlTxRx, &status);
+ accel->writeDATO(reg, &status);
+ accel->strobeGO(&status);
+
+ // Execute and wait until it's done (up to a millisecond)
+ initialTime = HAL_GetFPGATime(&status);
+ while (accel->readSTAT(&status) & 1) {
+ if (HAL_GetFPGATime(&status) > initialTime + 1000) break;
+ }
+
+ // Receive a message with the data and stop
+ accel->writeADDR(kReceiveAddress, &status);
+ accel->writeCNTL(kControlStart | kControlStop | kControlTxRx, &status);
+ accel->strobeGO(&status);
+
+ // Execute and wait until it's done (up to a millisecond)
+ initialTime = HAL_GetFPGATime(&status);
+ while (accel->readSTAT(&status) & 1) {
+ if (HAL_GetFPGATime(&status) > initialTime + 1000) break;
+ }
+
+ return accel->readDATI(&status);
+}
+
+/**
+ * Convert a 12-bit raw acceleration value into a scaled double in units of
+ * 1 g-force, taking into account the accelerometer range.
+ */
+static double unpackAxis(int16_t raw) {
+ // The raw value is actually 12 bits, not 16, so we need to propogate the
+ // 2's complement sign bit to the unused 4 bits for this to work with
+ // negative numbers.
+ raw <<= 4;
+ raw >>= 4;
+
+ switch (accelerometerRange) {
+ case HAL_AccelerometerRange_k2G:
+ return raw / 1024.0;
+ case HAL_AccelerometerRange_k4G:
+ return raw / 512.0;
+ case HAL_AccelerometerRange_k8G:
+ return raw / 256.0;
+ default:
+ return 0.0;
+ }
+}
+
+} // namespace hal
+
+extern "C" {
+
+void HAL_SetAccelerometerActive(HAL_Bool active) {
+ initializeAccelerometer();
+
+ uint8_t ctrlReg1 = readRegister(kReg_CtrlReg1);
+ ctrlReg1 &= ~1; // Clear the existing active bit
+ writeRegister(kReg_CtrlReg1, ctrlReg1 | (active ? 1 : 0));
+}
+
+void HAL_SetAccelerometerRange(HAL_AccelerometerRange range) {
+ initializeAccelerometer();
+
+ accelerometerRange = range;
+
+ uint8_t xyzDataCfg = readRegister(kReg_XYZDataCfg);
+ xyzDataCfg &= ~3; // Clear the existing two range bits
+ writeRegister(kReg_XYZDataCfg, xyzDataCfg | range);
+}
+
+double HAL_GetAccelerometerX(void) {
+ initializeAccelerometer();
+
+ int32_t raw =
+ (readRegister(kReg_OutXMSB) << 4) | (readRegister(kReg_OutXLSB) >> 4);
+ return unpackAxis(raw);
+}
+
+double HAL_GetAccelerometerY(void) {
+ initializeAccelerometer();
+
+ int32_t raw =
+ (readRegister(kReg_OutYMSB) << 4) | (readRegister(kReg_OutYLSB) >> 4);
+ return unpackAxis(raw);
+}
+
+double HAL_GetAccelerometerZ(void) {
+ initializeAccelerometer();
+
+ int32_t raw =
+ (readRegister(kReg_OutZMSB) << 4) | (readRegister(kReg_OutZLSB) >> 4);
+ return unpackAxis(raw);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/AnalogAccumulator.cpp b/hal/src/main/native/athena/AnalogAccumulator.cpp
new file mode 100644
index 0000000..6664c52
--- /dev/null
+++ b/hal/src/main/native/athena/AnalogAccumulator.cpp
@@ -0,0 +1,139 @@
+/*----------------------------------------------------------------------------*/
+/* 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/AnalogAccumulator.h"
+
+#include "AnalogInternal.h"
+#include "hal/HAL.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) {
+ if (!HAL_IsAccumulatorChannel(analogPortHandle, status)) {
+ *status = HAL_INVALID_ACCUMULATOR_CHANNEL;
+ return;
+ }
+ HAL_SetAccumulatorCenter(analogPortHandle, 0, status);
+ HAL_ResetAccumulator(analogPortHandle, status);
+}
+
+void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ if (port->accumulator == nullptr) {
+ *status = NULL_PARAMETER;
+ return;
+ }
+ port->accumulator->strobeReset(status);
+}
+
+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;
+ }
+ if (port->accumulator == nullptr) {
+ *status = NULL_PARAMETER;
+ return;
+ }
+ port->accumulator->writeCenter(center, status);
+}
+
+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;
+ }
+ if (port->accumulator == nullptr) {
+ *status = NULL_PARAMETER;
+ return;
+ }
+ port->accumulator->writeDeadband(deadband, status);
+}
+
+int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ if (port->accumulator == nullptr) {
+ *status = NULL_PARAMETER;
+ return 0;
+ }
+ int64_t value = port->accumulator->readOutput_Value(status);
+ return value;
+}
+
+int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ if (port->accumulator == nullptr) {
+ *status = NULL_PARAMETER;
+ return 0;
+ }
+ return port->accumulator->readOutput_Count(status);
+}
+
+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;
+ }
+ if (port->accumulator == nullptr) {
+ *status = NULL_PARAMETER;
+ return;
+ }
+ if (value == nullptr || count == nullptr) {
+ *status = NULL_PARAMETER;
+ return;
+ }
+
+ tAccumulator::tOutput output = port->accumulator->readOutput(status);
+
+ *value = output.Value;
+ *count = output.Count;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/AnalogGyro.cpp b/hal/src/main/native/athena/AnalogGyro.cpp
new file mode 100644
index 0000000..56b6f28
--- /dev/null
+++ b/hal/src/main/native/athena/AnalogGyro.cpp
@@ -0,0 +1,261 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <thread>
+
+#include <wpi/raw_ostream.h>
+
+#include "AnalogInternal.h"
+#include "HALInitializer.h"
+#include "hal/AnalogAccumulator.h"
+#include "hal/AnalogInput.h"
+#include "hal/handles/IndexedHandleResource.h"
+
+namespace {
+
+struct AnalogGyro {
+ HAL_AnalogInputHandle handle;
+ double voltsPerDegreePerSecond;
+ double offset;
+ int32_t center;
+};
+
+} // namespace
+
+static constexpr uint32_t kOversampleBits = 10;
+static constexpr uint32_t kAverageBits = 0;
+static constexpr double kSamplesPerSecond = 50.0;
+static constexpr double kCalibrationSampleTime = 5.0;
+static constexpr double kDefaultVoltsPerDegreePerSecond = 0.007;
+
+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>
+ agHandles;
+ analogGyroHandles = &agHandles;
+}
+} // namespace init
+} // namespace hal
+
+static void Wait(double seconds) {
+ if (seconds < 0.0) return;
+ std::this_thread::sleep_for(std::chrono::duration<double>(seconds));
+}
+
+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->voltsPerDegreePerSecond = 0;
+ gyro->offset = 0;
+ gyro->center = 0;
+
+ return handle;
+}
+
+void HAL_SetupAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ gyro->voltsPerDegreePerSecond = kDefaultVoltsPerDegreePerSecond;
+
+ HAL_SetAnalogAverageBits(gyro->handle, kAverageBits, status);
+ if (*status != 0) return;
+ HAL_SetAnalogOversampleBits(gyro->handle, kOversampleBits, status);
+ if (*status != 0) return;
+ double sampleRate =
+ kSamplesPerSecond * (1 << (kAverageBits + kOversampleBits));
+ HAL_SetAnalogSampleRate(sampleRate, status);
+ if (*status != 0) return;
+ Wait(0.1);
+
+ HAL_SetAnalogGyroDeadband(handle, 0.0, status);
+ if (*status != 0) return;
+}
+
+void HAL_FreeAnalogGyro(HAL_GyroHandle handle) {
+ analogGyroHandles->Free(handle);
+}
+
+void HAL_SetAnalogGyroParameters(HAL_GyroHandle handle,
+ double voltsPerDegreePerSecond, double offset,
+ int32_t center, int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ gyro->voltsPerDegreePerSecond = voltsPerDegreePerSecond;
+ gyro->offset = offset;
+ gyro->center = center;
+ HAL_SetAccumulatorCenter(gyro->handle, center, status);
+}
+
+void HAL_SetAnalogGyroVoltsPerDegreePerSecond(HAL_GyroHandle handle,
+ double voltsPerDegreePerSecond,
+ int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ gyro->voltsPerDegreePerSecond = voltsPerDegreePerSecond;
+}
+
+void HAL_ResetAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ HAL_ResetAccumulator(gyro->handle, status);
+ if (*status != 0) return;
+
+ const double sampleTime = 1.0 / HAL_GetAnalogSampleRate(status);
+ const double overSamples =
+ 1 << HAL_GetAnalogOversampleBits(gyro->handle, status);
+ const double averageSamples =
+ 1 << HAL_GetAnalogAverageBits(gyro->handle, status);
+ if (*status != 0) return;
+ Wait(sampleTime * overSamples * averageSamples);
+}
+
+void HAL_CalibrateAnalogGyro(HAL_GyroHandle handle, int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ HAL_InitAccumulator(gyro->handle, status);
+ if (*status != 0) return;
+ wpi::outs() << "Calibrating analog gyro for " << kCalibrationSampleTime
+ << " seconds." << '\n';
+ Wait(kCalibrationSampleTime);
+
+ int64_t value;
+ int64_t count;
+ HAL_GetAccumulatorOutput(gyro->handle, &value, &count, status);
+ if (*status != 0) return;
+
+ gyro->center = static_cast<int32_t>(
+ static_cast<double>(value) / static_cast<double>(count) + .5);
+
+ gyro->offset = static_cast<double>(value) / static_cast<double>(count) -
+ static_cast<double>(gyro->center);
+ HAL_SetAccumulatorCenter(gyro->handle, gyro->center, status);
+ if (*status != 0) return;
+ HAL_ResetAnalogGyro(handle, status);
+}
+
+void HAL_SetAnalogGyroDeadband(HAL_GyroHandle handle, double volts,
+ int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ int32_t deadband = static_cast<int32_t>(
+ volts * 1e9 / HAL_GetAnalogLSBWeight(gyro->handle, status) *
+ (1 << HAL_GetAnalogOversampleBits(gyro->handle, status)));
+ if (*status != 0) return;
+ HAL_SetAccumulatorDeadband(gyro->handle, deadband, status);
+}
+
+double HAL_GetAnalogGyroAngle(HAL_GyroHandle handle, int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ int64_t rawValue = 0;
+ int64_t count = 0;
+ HAL_GetAccumulatorOutput(gyro->handle, &rawValue, &count, status);
+
+ int64_t value = rawValue - static_cast<int64_t>(static_cast<double>(count) *
+ gyro->offset);
+
+ double scaledValue =
+ value * 1e-9 *
+ static_cast<double>(HAL_GetAnalogLSBWeight(gyro->handle, status)) *
+ static_cast<double>(1 << HAL_GetAnalogAverageBits(gyro->handle, status)) /
+ (HAL_GetAnalogSampleRate(status) * gyro->voltsPerDegreePerSecond);
+
+ return scaledValue;
+}
+
+double HAL_GetAnalogGyroRate(HAL_GyroHandle handle, int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ return (HAL_GetAnalogAverageValue(gyro->handle, status) -
+ (static_cast<double>(gyro->center) + gyro->offset)) *
+ 1e-9 * HAL_GetAnalogLSBWeight(gyro->handle, status) /
+ ((1 << HAL_GetAnalogOversampleBits(gyro->handle, status)) *
+ gyro->voltsPerDegreePerSecond);
+}
+
+double HAL_GetAnalogGyroOffset(HAL_GyroHandle handle, int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return gyro->offset;
+}
+
+int32_t HAL_GetAnalogGyroCenter(HAL_GyroHandle handle, int32_t* status) {
+ auto gyro = analogGyroHandles->Get(handle);
+ if (gyro == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return gyro->center;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/AnalogInput.cpp b/hal/src/main/native/athena/AnalogInput.cpp
new file mode 100644
index 0000000..b11280d
--- /dev/null
+++ b/hal/src/main/native/athena/AnalogInput.cpp
@@ -0,0 +1,238 @@
+/*----------------------------------------------------------------------------*/
+/* 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/AnalogInput.h"
+
+#include <FRC_NetworkCommunication/AICalibration.h>
+#include <wpi/mutex.h>
+
+#include "AnalogInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/AnalogAccumulator.h"
+#include "hal/handles/HandlesInternal.h"
+
+namespace hal {
+namespace init {
+void InitializeAnalogInput() {}
+} // namespace init
+} // namespace hal
+
+using namespace hal;
+
+extern "C" {
+
+HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
+ int32_t* status) {
+ hal::init::CheckInit();
+ initializeAnalog(status);
+
+ if (*status != 0) return HAL_kInvalidHandle;
+
+ 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->accumulator.reset(tAccumulator::create(channel, status));
+ } else {
+ analog_port->accumulator = nullptr;
+ }
+
+ // Set default configuration
+ analogInputSystem->writeScanList(channel, channel, status);
+ HAL_SetAnalogAverageBits(handle, kDefaultAverageBits, status);
+ HAL_SetAnalogOversampleBits(handle, kDefaultOversampleBits, status);
+ return handle;
+}
+
+void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analogPortHandle) {
+ // no status, so no need to check for a proper free.
+ analogInputHandles->Free(analogPortHandle);
+}
+
+HAL_Bool HAL_CheckAnalogModule(int32_t module) { return module == 1; }
+
+HAL_Bool HAL_CheckAnalogInputChannel(int32_t channel) {
+ return channel < kNumAnalogInputs && channel >= 0;
+}
+
+void HAL_SetAnalogSampleRate(double samplesPerSecond, int32_t* status) {
+ // TODO: This will change when variable size scan lists are implemented.
+ // TODO: Need double comparison with epsilon.
+ // wpi_assert(!sampleRateSet || GetSampleRate() == samplesPerSecond);
+ initializeAnalog(status);
+ if (*status != 0) return;
+ setAnalogSampleRate(samplesPerSecond, status);
+}
+
+double HAL_GetAnalogSampleRate(int32_t* status) {
+ initializeAnalog(status);
+ if (*status != 0) return 0;
+ uint32_t ticksPerConversion = analogInputSystem->readLoopTiming(status);
+ uint32_t ticksPerSample =
+ ticksPerConversion * getAnalogNumActiveChannels(status);
+ return static_cast<double>(kTimebase) / static_cast<double>(ticksPerSample);
+}
+
+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;
+ }
+ analogInputSystem->writeAverageBits(port->channel, static_cast<uint8_t>(bits),
+ status);
+}
+
+int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return kDefaultAverageBits;
+ }
+ uint8_t result = analogInputSystem->readAverageBits(port->channel, status);
+ return result;
+}
+
+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;
+ }
+ analogInputSystem->writeOversampleBits(port->channel,
+ static_cast<uint8_t>(bits), status);
+}
+
+int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return kDefaultOversampleBits;
+ }
+ uint8_t result = analogInputSystem->readOversampleBits(port->channel, status);
+ return result;
+}
+
+int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ tAI::tReadSelect readSelect;
+ readSelect.Channel = port->channel;
+ readSelect.Averaged = false;
+
+ std::lock_guard<wpi::mutex> lock(analogRegisterWindowMutex);
+ analogInputSystem->writeReadSelect(readSelect, status);
+ analogInputSystem->strobeLatchOutput(status);
+ return static_cast<int16_t>(analogInputSystem->readOutput(status));
+}
+
+int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ tAI::tReadSelect readSelect;
+ readSelect.Channel = port->channel;
+ readSelect.Averaged = true;
+
+ std::lock_guard<wpi::mutex> lock(analogRegisterWindowMutex);
+ analogInputSystem->writeReadSelect(readSelect, status);
+ analogInputSystem->strobeLatchOutput(status);
+ return static_cast<int32_t>(analogInputSystem->readOutput(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) {
+ int32_t value = HAL_GetAnalogValue(analogPortHandle, status);
+ int32_t LSBWeight = HAL_GetAnalogLSBWeight(analogPortHandle, status);
+ int32_t offset = HAL_GetAnalogOffset(analogPortHandle, status);
+ double voltage = LSBWeight * 1.0e-9 * value - offset * 1.0e-9;
+ return voltage;
+}
+
+double HAL_GetAnalogAverageVoltage(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ int32_t value = HAL_GetAnalogAverageValue(analogPortHandle, status);
+ int32_t LSBWeight = HAL_GetAnalogLSBWeight(analogPortHandle, status);
+ int32_t offset = HAL_GetAnalogOffset(analogPortHandle, status);
+ int32_t oversampleBits =
+ HAL_GetAnalogOversampleBits(analogPortHandle, status);
+ double voltage =
+ LSBWeight * 1.0e-9 * value / static_cast<double>(1 << oversampleBits) -
+ offset * 1.0e-9;
+ return voltage;
+}
+
+int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ int32_t lsbWeight = FRC_NetworkCommunication_nAICalibration_getLSBWeight(
+ 0, port->channel, status); // XXX: aiSystemIndex == 0?
+ return lsbWeight;
+}
+
+int32_t HAL_GetAnalogOffset(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status) {
+ auto port = analogInputHandles->Get(analogPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ int32_t offset = FRC_NetworkCommunication_nAICalibration_getOffset(
+ 0, port->channel, status); // XXX: aiSystemIndex == 0?
+ return offset;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/AnalogInternal.cpp b/hal/src/main/native/athena/AnalogInternal.cpp
new file mode 100644
index 0000000..6e02def
--- /dev/null
+++ b/hal/src/main/native/athena/AnalogInternal.cpp
@@ -0,0 +1,100 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <atomic>
+
+#include <wpi/mutex.h>
+
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/AnalogInput.h"
+#include "hal/ChipObject.h"
+
+namespace hal {
+
+wpi::mutex analogRegisterWindowMutex;
+std::unique_ptr<tAI> analogInputSystem;
+std::unique_ptr<tAO> analogOutputSystem;
+
+IndexedHandleResource<HAL_AnalogInputHandle, ::hal::AnalogPort,
+ kNumAnalogInputs, HAL_HandleEnum::AnalogInput>*
+ analogInputHandles;
+
+static int32_t analogNumChannelsToActivate = 0;
+
+static std::atomic<bool> analogSystemInitialized{false};
+
+bool analogSampleRateSet = false;
+
+namespace init {
+void InitializeAnalogInternal() {
+ static IndexedHandleResource<HAL_AnalogInputHandle, ::hal::AnalogPort,
+ kNumAnalogInputs, HAL_HandleEnum::AnalogInput>
+ alH;
+ analogInputHandles = &alH;
+}
+} // namespace init
+
+void initializeAnalog(int32_t* status) {
+ hal::init::CheckInit();
+ if (analogSystemInitialized) return;
+ std::lock_guard<wpi::mutex> lock(analogRegisterWindowMutex);
+ if (analogSystemInitialized) return;
+ analogInputSystem.reset(tAI::create(status));
+ analogOutputSystem.reset(tAO::create(status));
+ setAnalogNumChannelsToActivate(kNumAnalogInputs);
+ setAnalogSampleRate(kDefaultSampleRate, status);
+ analogSystemInitialized = true;
+}
+
+int32_t getAnalogNumActiveChannels(int32_t* status) {
+ int32_t scanSize = analogInputSystem->readConfig_ScanSize(status);
+ if (scanSize == 0) return 8;
+ return scanSize;
+}
+
+void setAnalogNumChannelsToActivate(int32_t channels) {
+ analogNumChannelsToActivate = channels;
+}
+
+int32_t getAnalogNumChannelsToActivate(int32_t* status) {
+ if (analogNumChannelsToActivate == 0)
+ return getAnalogNumActiveChannels(status);
+ return analogNumChannelsToActivate;
+}
+
+void setAnalogSampleRate(double samplesPerSecond, int32_t* status) {
+ // TODO: This will change when variable size scan lists are implemented.
+ // TODO: Need double comparison with epsilon.
+ // wpi_assert(!sampleRateSet || GetSampleRate() == samplesPerSecond);
+ analogSampleRateSet = true;
+
+ // Compute the convert rate
+ uint32_t ticksPerSample =
+ static_cast<uint32_t>(static_cast<double>(kTimebase) / samplesPerSecond);
+ uint32_t ticksPerConversion =
+ ticksPerSample / getAnalogNumChannelsToActivate(status);
+ // ticksPerConversion must be at least 80
+ if (ticksPerConversion < 80) {
+ if ((*status) >= 0) *status = SAMPLE_RATE_TOO_HIGH;
+ ticksPerConversion = 80;
+ }
+
+ // Atomically set the scan size and the convert rate so that the sample rate
+ // is constant
+ tAI::tConfig config;
+ config.ScanSize = getAnalogNumChannelsToActivate(status);
+ config.ConvertRate = ticksPerConversion;
+ analogInputSystem->writeConfig(config, status);
+
+ // Indicate that the scan size has been commited to hardware.
+ setAnalogNumChannelsToActivate(0);
+}
+
+} // namespace hal
diff --git a/hal/src/main/native/athena/AnalogInternal.h b/hal/src/main/native/athena/AnalogInternal.h
new file mode 100644
index 0000000..a74562f
--- /dev/null
+++ b/hal/src/main/native/athena/AnalogInternal.h
@@ -0,0 +1,88 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <wpi/mutex.h>
+
+#include "PortsInternal.h"
+#include "hal/ChipObject.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};
+
+extern std::unique_ptr<tAI> analogInputSystem;
+extern std::unique_ptr<tAO> analogOutputSystem;
+extern wpi::mutex analogRegisterWindowMutex;
+extern bool analogSampleRateSet;
+
+struct AnalogPort {
+ uint8_t channel;
+ std::unique_ptr<tAccumulator> accumulator;
+};
+
+extern IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort,
+ kNumAnalogInputs, HAL_HandleEnum::AnalogInput>*
+ analogInputHandles;
+
+/**
+ * Initialize the analog System.
+ */
+void initializeAnalog(int32_t* status);
+
+/**
+ * Return the number of channels on the module in use.
+ *
+ * @return Active channels.
+ */
+int32_t getAnalogNumActiveChannels(int32_t* status);
+
+/**
+ * Set the number of active channels.
+ *
+ * Store the number of active channels to set. Don't actually commit to
+ * hardware
+ * until SetSampleRate().
+ *
+ * @param channels Number of active channels.
+ */
+void setAnalogNumChannelsToActivate(int32_t channels);
+
+/**
+ * Get the number of active channels.
+ *
+ * This is an internal function to allow the atomic update of both the
+ * number of active channels and the sample rate.
+ *
+ * When the number of channels changes, use the new value. Otherwise,
+ * return the curent value.
+ *
+ * @return Value to write to the active channels field.
+ */
+int32_t getAnalogNumChannelsToActivate(int32_t* status);
+
+/**
+ * Set the sample rate.
+ *
+ * This is a global setting for the Athena and effects all channels.
+ *
+ * @param samplesPerSecond The number of samples per channel per second.
+ */
+void setAnalogSampleRate(double samplesPerSecond, int32_t* status);
+
+} // namespace hal
diff --git a/hal/src/main/native/athena/AnalogOutput.cpp b/hal/src/main/native/athena/AnalogOutput.cpp
new file mode 100644
index 0000000..77f841b
--- /dev/null
+++ b/hal/src/main/native/athena/AnalogOutput.cpp
@@ -0,0 +1,113 @@
+/*----------------------------------------------------------------------------*/
+/* 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/AnalogOutput.h"
+
+#include "AnalogInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/Errors.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/IndexedHandleResource.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();
+ initializeAnalog(status);
+
+ if (*status != 0) return HAL_kInvalidHandle;
+
+ 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);
+ return handle;
+}
+
+void HAL_FreeAnalogOutputPort(HAL_AnalogOutputHandle analogOutputHandle) {
+ // no status, so no need to check for a proper free.
+ analogOutputHandles->Free(analogOutputHandle);
+}
+
+void HAL_SetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
+ double voltage, int32_t* status) {
+ auto port = analogOutputHandles->Get(analogOutputHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ uint16_t rawValue = static_cast<uint16_t>(voltage / 5.0 * 0x1000);
+
+ if (voltage < 0.0)
+ rawValue = 0;
+ else if (voltage > 5.0)
+ rawValue = 0x1000;
+
+ analogOutputSystem->writeMXP(port->channel, rawValue, status);
+}
+
+double HAL_GetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
+ int32_t* status) {
+ auto port = analogOutputHandles->Get(analogOutputHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0.0;
+ }
+
+ uint16_t rawValue = analogOutputSystem->readMXP(port->channel, status);
+
+ return rawValue * 5.0 / 0x1000;
+}
+
+HAL_Bool HAL_CheckAnalogOutputChannel(int32_t channel) {
+ return channel < kNumAnalogOutputs && channel >= 0;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/AnalogTrigger.cpp b/hal/src/main/native/athena/AnalogTrigger.cpp
new file mode 100644
index 0000000..1841c51
--- /dev/null
+++ b/hal/src/main/native/athena/AnalogTrigger.cpp
@@ -0,0 +1,192 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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"
+
+using namespace hal;
+
+namespace {
+
+struct AnalogTrigger {
+ std::unique_ptr<tAnalogTrigger> trigger;
+ HAL_AnalogInputHandle analogHandle;
+ uint8_t index;
+};
+
+} // namespace
+
+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
+
+extern "C" {
+
+HAL_AnalogTriggerHandle HAL_InitializeAnalogTrigger(
+ HAL_AnalogInputHandle portHandle, int32_t* index, 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));
+ *index = trigger->index;
+
+ trigger->trigger.reset(tAnalogTrigger::create(trigger->index, status));
+ trigger->trigger->writeSourceSelect_Channel(analog_port->channel, status);
+ return handle;
+}
+
+void HAL_CleanAnalogTrigger(HAL_AnalogTriggerHandle analogTriggerHandle,
+ int32_t* status) {
+ analogTriggerHandles->Free(analogTriggerHandle);
+ // caller owns the analog input handle.
+}
+
+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;
+ }
+ trigger->trigger->writeLowerLimit(lower, status);
+ trigger->trigger->writeUpperLimit(upper, status);
+}
+
+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;
+ }
+
+ // TODO: This depends on the averaged setting. Only raw values will work as
+ // is.
+ trigger->trigger->writeLowerLimit(
+ HAL_GetAnalogVoltsToValue(trigger->analogHandle, lower, status), status);
+ trigger->trigger->writeUpperLimit(
+ HAL_GetAnalogVoltsToValue(trigger->analogHandle, upper, status), status);
+}
+
+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;
+ }
+ if (trigger->trigger->readSourceSelect_Filter(status) != 0) {
+ *status = INCOMPATIBLE_STATE;
+ // TODO: wpi_setWPIErrorWithContext(IncompatibleMode, "Hardware does not
+ // support average and filtering at the same time.");
+ }
+ trigger->trigger->writeSourceSelect_Averaged(useAveragedValue, status);
+}
+
+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;
+ }
+ if (trigger->trigger->readSourceSelect_Averaged(status) != 0) {
+ *status = INCOMPATIBLE_STATE;
+ // TODO: wpi_setWPIErrorWithContext(IncompatibleMode, "Hardware does not "
+ // "support average and filtering at the same time.");
+ }
+ trigger->trigger->writeSourceSelect_Filter(useFilteredValue, status);
+}
+
+HAL_Bool HAL_GetAnalogTriggerInWindow(
+ HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
+ auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
+ if (trigger == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ return trigger->trigger->readOutput_InHysteresis(trigger->index, status) != 0;
+}
+
+HAL_Bool HAL_GetAnalogTriggerTriggerState(
+ HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
+ auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
+ if (trigger == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ return trigger->trigger->readOutput_OverLimit(trigger->index, status) != 0;
+}
+
+HAL_Bool HAL_GetAnalogTriggerOutput(HAL_AnalogTriggerHandle analogTriggerHandle,
+ HAL_AnalogTriggerType type,
+ int32_t* status) {
+ auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
+ if (trigger == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ bool result = false;
+ switch (type) {
+ case HAL_Trigger_kInWindow:
+ result =
+ trigger->trigger->readOutput_InHysteresis(trigger->index, status);
+ break; // XXX: Backport
+ case HAL_Trigger_kState:
+ result = trigger->trigger->readOutput_OverLimit(trigger->index, status);
+ break; // XXX: Backport
+ case HAL_Trigger_kRisingPulse:
+ case HAL_Trigger_kFallingPulse:
+ *status = ANALOG_TRIGGER_PULSE_OUTPUT_ERROR;
+ return false;
+ }
+ return result;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/CAN.cpp b/hal/src/main/native/athena/CAN.cpp
new file mode 100644
index 0000000..8105358
--- /dev/null
+++ b/hal/src/main/native/athena/CAN.cpp
@@ -0,0 +1,55 @@
+/*----------------------------------------------------------------------------*/
+/* 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/CAN.h"
+
+#include <FRC_NetworkCommunication/CANSessionMux.h>
+
+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) {
+ FRC_NetworkCommunication_CANSessionMux_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) {
+ FRC_NetworkCommunication_CANSessionMux_receiveMessage(
+ messageID, messageIDMask, data, dataSize, timeStamp, status);
+}
+void HAL_CAN_OpenStreamSession(uint32_t* sessionHandle, uint32_t messageID,
+ uint32_t messageIDMask, uint32_t maxMessages,
+ int32_t* status) {
+ FRC_NetworkCommunication_CANSessionMux_openStreamSession(
+ sessionHandle, messageID, messageIDMask, maxMessages, status);
+}
+void HAL_CAN_CloseStreamSession(uint32_t sessionHandle) {
+ FRC_NetworkCommunication_CANSessionMux_closeStreamSession(sessionHandle);
+}
+void HAL_CAN_ReadStreamSession(uint32_t sessionHandle,
+ struct HAL_CANStreamMessage* messages,
+ uint32_t messagesToRead, uint32_t* messagesRead,
+ int32_t* status) {
+ FRC_NetworkCommunication_CANSessionMux_readStreamSession(
+ sessionHandle, reinterpret_cast<tCANStreamMessage*>(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) {
+ FRC_NetworkCommunication_CANSessionMux_getCANStatus(
+ percentBusUtilization, busOffCount, txFullCount, receiveErrorCount,
+ transmitErrorCount, status);
+}
+} // extern "C"
diff --git a/hal/src/main/native/athena/CANAPI.cpp b/hal/src/main/native/athena/CANAPI.cpp
new file mode 100644
index 0000000..01c06bd
--- /dev/null
+++ b/hal/src/main/native/athena/CANAPI.cpp
@@ -0,0 +1,326 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/CANAPI.h"
+
+#include <atomic>
+#include <ctime>
+
+#include <wpi/DenseMap.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 {
+ uint32_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() {
+ timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+
+ // Convert t to milliseconds
+ uint64_t ms = t.tv_sec * 1000ull + t.tv_nsec / 1000000ull;
+ return ms & 0xFFFFFFFF;
+}
+
+namespace hal {
+namespace init {
+void InitializeCANAPI() {
+ static UnlimitedHandleResource<HAL_CANHandle, CANStorage, HAL_HandleEnum::CAN>
+ cH;
+ canHandles = &cH;
+}
+} // namespace init
+} // 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::lock_guard<wpi::mutex> lock(data->mapMutex);
+
+ for (auto&& i : data->periodicSends) {
+ int32_t s = 0;
+ HAL_CAN_SendMessage(i.first, 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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> lock(can->mapMutex);
+ can->periodicSends[apiId] = repeatMs;
+}
+
+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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> 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)) {
+ // 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;
+ return;
+ }
+ }
+ }
+
+ uint8_t dataSize = 0;
+ uint32_t ts = 0;
+ HAL_CAN_ReceiveMessage(&messageId, 0x1FFFFFFF, data, &dataSize, &ts, status);
+
+ std::lock_guard<wpi::mutex> 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/athena/Compressor.cpp b/hal/src/main/native/athena/Compressor.cpp
new file mode 100644
index 0000000..f381305
--- /dev/null
+++ b/hal/src/main/native/athena/Compressor.cpp
@@ -0,0 +1,202 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "PCMInternal.h"
+#include "PortsInternal.h"
+#include "ctre/PCM.h"
+#include "hal/Errors.h"
+#include "hal/handles/HandlesInternal.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();
+ // Use status to check for invalid index
+ initializePCM(module, status);
+ if (*status != 0) {
+ return HAL_kInvalidHandle;
+ }
+
+ // As compressors can have unlimited objects, just create a
+ // handle with the module number as the index.
+
+ 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;
+ }
+ bool value;
+
+ *status = PCM_modules[index]->GetCompressor(value);
+
+ return value;
+}
+
+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;
+ }
+
+ *status = PCM_modules[index]->SetClosedLoopControl(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;
+ }
+ bool value;
+
+ *status = PCM_modules[index]->GetClosedLoopControl(value);
+
+ return value;
+}
+
+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;
+ }
+ bool value;
+
+ *status = PCM_modules[index]->GetPressure(value);
+
+ return value;
+}
+
+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;
+ }
+ float value;
+
+ *status = PCM_modules[index]->GetCompressorCurrent(value);
+
+ return value;
+}
+HAL_Bool HAL_GetCompressorCurrentTooHighFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status) {
+ int16_t index =
+ getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
+ if (index == InvalidHandleIndex) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ bool value;
+
+ *status = PCM_modules[index]->GetCompressorCurrentTooHighFault(value);
+
+ return value;
+}
+HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status) {
+ int16_t index =
+ getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
+ if (index == InvalidHandleIndex) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ bool value;
+
+ *status = PCM_modules[index]->GetCompressorCurrentTooHighStickyFault(value);
+
+ return value;
+}
+HAL_Bool HAL_GetCompressorShortedStickyFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status) {
+ int16_t index =
+ getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
+ if (index == InvalidHandleIndex) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ bool value;
+
+ *status = PCM_modules[index]->GetCompressorShortedStickyFault(value);
+
+ return value;
+}
+HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressorHandle,
+ int32_t* status) {
+ int16_t index =
+ getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
+ if (index == InvalidHandleIndex) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ bool value;
+
+ *status = PCM_modules[index]->GetCompressorShortedFault(value);
+
+ return value;
+}
+HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status) {
+ int16_t index =
+ getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
+ if (index == InvalidHandleIndex) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ bool value;
+
+ *status = PCM_modules[index]->GetCompressorNotConnectedStickyFault(value);
+
+ return value;
+}
+HAL_Bool HAL_GetCompressorNotConnectedFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status) {
+ int16_t index =
+ getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
+ if (index == InvalidHandleIndex) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ bool value;
+
+ *status = PCM_modules[index]->GetCompressorNotConnectedFault(value);
+
+ return value;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/Constants.cpp b/hal/src/main/native/athena/Constants.cpp
new file mode 100644
index 0000000..6af443d
--- /dev/null
+++ b/hal/src/main/native/athena/Constants.cpp
@@ -0,0 +1,26 @@
+/*----------------------------------------------------------------------------*/
+/* 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/athena/ConstantsInternal.h b/hal/src/main/native/athena/ConstantsInternal.h
new file mode 100644
index 0000000..55bbdee
--- /dev/null
+++ b/hal/src/main/native/athena/ConstantsInternal.h
@@ -0,0 +1,16 @@
+/*----------------------------------------------------------------------------*/
+/* 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/athena/Counter.cpp b/hal/src/main/native/athena/Counter.cpp
new file mode 100644
index 0000000..6d7e254
--- /dev/null
+++ b/hal/src/main/native/athena/Counter.cpp
@@ -0,0 +1,372 @@
+/*----------------------------------------------------------------------------*/
+/* 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/Counter.h"
+
+#include "ConstantsInternal.h"
+#include "DigitalInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/HAL.h"
+#include "hal/handles/LimitedHandleResource.h"
+
+using namespace hal;
+
+namespace {
+
+struct Counter {
+ std::unique_ptr<tCounter> counter;
+ uint8_t index;
+};
+
+} // namespace
+
+static LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
+ HAL_HandleEnum::Counter>* counterHandles;
+
+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();
+ auto handle = counterHandles->Allocate();
+ if (handle == HAL_kInvalidHandle) { // out of resources
+ *status = NO_AVAILABLE_RESOURCES;
+ return HAL_kInvalidHandle;
+ }
+ auto counter = counterHandles->Get(handle);
+ if (counter == nullptr) { // would only occur on thread issues
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+ counter->index = static_cast<uint8_t>(getHandleIndex(handle));
+ *index = counter->index;
+
+ counter->counter.reset(tCounter::create(counter->index, status));
+ counter->counter->writeConfig_Mode(mode, status);
+ counter->counter->writeTimerConfig_AverageSize(1, status);
+ return handle;
+}
+
+void HAL_FreeCounter(HAL_CounterHandle counterHandle, int32_t* status) {
+ counterHandles->Free(counterHandle);
+}
+
+void HAL_SetCounterAverageSize(HAL_CounterHandle counterHandle, int32_t size,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ counter->counter->writeTimerConfig_AverageSize(size, status);
+}
+
+void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == 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;
+ }
+
+ counter->counter->writeConfig_UpSource_Module(routingModule, status);
+ counter->counter->writeConfig_UpSource_Channel(routingChannel, status);
+ counter->counter->writeConfig_UpSource_AnalogTrigger(routingAnalogTrigger,
+ status);
+
+ if (counter->counter->readConfig_Mode(status) == HAL_Counter_kTwoPulse ||
+ counter->counter->readConfig_Mode(status) ==
+ HAL_Counter_kExternalDirection) {
+ HAL_SetCounterUpSourceEdge(counterHandle, true, false, status);
+ }
+ counter->counter->strobeReset(status);
+}
+
+void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
+ HAL_Bool risingEdge, HAL_Bool fallingEdge,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ counter->counter->writeConfig_UpRisingEdge(risingEdge, status);
+ counter->counter->writeConfig_UpFallingEdge(fallingEdge, status);
+}
+
+void HAL_ClearCounterUpSource(HAL_CounterHandle counterHandle,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ counter->counter->writeConfig_UpFallingEdge(false, status);
+ counter->counter->writeConfig_UpRisingEdge(false, status);
+ // Index 0 of digital is always 0.
+ counter->counter->writeConfig_UpSource_Channel(0, status);
+ counter->counter->writeConfig_UpSource_AnalogTrigger(false, status);
+}
+
+void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ uint8_t mode = counter->counter->readConfig_Mode(status);
+ if (mode != HAL_Counter_kTwoPulse && mode != HAL_Counter_kExternalDirection) {
+ // TODO: wpi_setWPIErrorWithContext(ParameterOutOfRange, "Counter only
+ // supports DownSource in TwoPulse and ExternalDirection modes.");
+ *status = PARAMETER_OUT_OF_RANGE;
+ 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;
+ }
+
+ counter->counter->writeConfig_DownSource_Module(routingModule, status);
+ counter->counter->writeConfig_DownSource_Channel(routingChannel, status);
+ counter->counter->writeConfig_DownSource_AnalogTrigger(routingAnalogTrigger,
+ status);
+
+ HAL_SetCounterDownSourceEdge(counterHandle, true, false, status);
+ counter->counter->strobeReset(status);
+}
+
+void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
+ HAL_Bool risingEdge, HAL_Bool fallingEdge,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ counter->counter->writeConfig_DownRisingEdge(risingEdge, status);
+ counter->counter->writeConfig_DownFallingEdge(fallingEdge, status);
+}
+
+void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ counter->counter->writeConfig_DownFallingEdge(false, status);
+ counter->counter->writeConfig_DownRisingEdge(false, status);
+ // Index 0 of digital is always 0.
+ counter->counter->writeConfig_DownSource_Channel(0, status);
+ counter->counter->writeConfig_DownSource_AnalogTrigger(false, status);
+}
+
+void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ counter->counter->writeConfig_Mode(HAL_Counter_kTwoPulse, status);
+}
+
+void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ counter->counter->writeConfig_Mode(HAL_Counter_kExternalDirection, status);
+}
+
+void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
+ HAL_Bool highSemiPeriod, int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ counter->counter->writeConfig_Mode(HAL_Counter_kSemiperiod, status);
+ counter->counter->writeConfig_UpRisingEdge(highSemiPeriod, status);
+ HAL_SetCounterUpdateWhenEmpty(counterHandle, false, status);
+}
+
+void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
+ double threshold, int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ counter->counter->writeConfig_Mode(HAL_Counter_kPulseLength, status);
+ counter->counter->writeConfig_PulseLengthThreshold(
+ static_cast<uint32_t>(threshold * 1.0e6) *
+ kSystemClockTicksPerMicrosecond,
+ status);
+}
+
+int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return counter->counter->readTimerConfig_AverageSize(status);
+}
+
+void HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
+ int32_t samplesToAverage, int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ if (samplesToAverage < 1 || samplesToAverage > 127) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ }
+ counter->counter->writeTimerConfig_AverageSize(samplesToAverage, status);
+}
+
+void HAL_ResetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ counter->counter->strobeReset(status);
+}
+
+int32_t HAL_GetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ int32_t value = counter->counter->readOutput_Value(status);
+ return value;
+}
+
+double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0.0;
+ }
+ tCounter::tTimerOutput output = counter->counter->readTimerOutput(status);
+ double period;
+ if (output.Stalled) {
+ // Return infinity
+ double zero = 0.0;
+ period = 1.0 / zero;
+ } else {
+ // output.Period is a fixed point number that counts by 2 (24 bits, 25
+ // integer bits)
+ period = static_cast<double>(output.Period << 1) /
+ static_cast<double>(output.Count);
+ }
+ return static_cast<double>(period *
+ 2.5e-8); // result * timebase (currently 25ns)
+}
+
+void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ counter->counter->writeTimerConfig_StallPeriod(
+ static_cast<uint32_t>(maxPeriod * 4.0e8), status);
+}
+
+void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
+ HAL_Bool enabled, int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ counter->counter->writeTimerConfig_UpdateWhenEmpty(enabled, status);
+}
+
+HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ return counter->counter->readTimerOutput_Stalled(status);
+}
+
+HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ bool value = counter->counter->readOutput_Direction(status);
+ return value;
+}
+
+void HAL_SetCounterReverseDirection(HAL_CounterHandle counterHandle,
+ HAL_Bool reverseDirection,
+ int32_t* status) {
+ auto counter = counterHandles->Get(counterHandle);
+ if (counter == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ if (counter->counter->readConfig_Mode(status) ==
+ HAL_Counter_kExternalDirection) {
+ if (reverseDirection)
+ HAL_SetCounterDownSourceEdge(counterHandle, true, true, status);
+ else
+ HAL_SetCounterDownSourceEdge(counterHandle, false, true, status);
+ }
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/DIO.cpp b/hal/src/main/native/athena/DIO.cpp
new file mode 100644
index 0000000..96eab2b
--- /dev/null
+++ b/hal/src/main/native/athena/DIO.cpp
@@ -0,0 +1,486 @@
+/*----------------------------------------------------------------------------*/
+/* 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/DIO.h"
+
+#include <cmath>
+#include <thread>
+
+#include <wpi/raw_ostream.h>
+
+#include "DigitalInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/cpp/fpga_clock.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/LimitedHandleResource.h"
+
+using namespace hal;
+
+// Create a mutex to protect changes to the DO PWM config
+static wpi::mutex digitalPwmMutex;
+
+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();
+ initializeDigital(status);
+
+ if (*status != 0) return HAL_kInvalidHandle;
+
+ int16_t channel = getPortHandleChannel(portHandle);
+ if (channel == InvalidHandleIndex || channel >= kNumDigitalChannels) {
+ *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);
+
+ std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
+
+ tDIO::tOutputEnable outputEnable = digitalSystem->readOutputEnable(status);
+
+ if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
+ if (!getPortHandleSPIEnable(portHandle)) {
+ // if this flag is not set, we actually want DIO.
+ uint32_t bitToSet = 1u << remapSPIChannel(port->channel);
+
+ uint16_t specialFunctions = spiSystem->readEnableDIO(status);
+ // Set the field to enable SPI DIO
+ spiSystem->writeEnableDIO(specialFunctions | bitToSet, status);
+
+ if (input) {
+ outputEnable.SPIPort =
+ outputEnable.SPIPort & (~bitToSet); // clear the field for read
+ } else {
+ outputEnable.SPIPort =
+ outputEnable.SPIPort | bitToSet; // set the bits for write
+ }
+ }
+ } else if (port->channel < kNumDigitalHeaders) {
+ uint32_t bitToSet = 1u << port->channel;
+ if (input) {
+ outputEnable.Headers =
+ outputEnable.Headers & (~bitToSet); // clear the bit for read
+ } else {
+ outputEnable.Headers =
+ outputEnable.Headers | bitToSet; // set the bit for write
+ }
+ } else {
+ uint32_t bitToSet = 1u << remapMXPChannel(port->channel);
+
+ uint16_t specialFunctions =
+ digitalSystem->readEnableMXPSpecialFunction(status);
+ digitalSystem->writeEnableMXPSpecialFunction(specialFunctions & ~bitToSet,
+ status);
+
+ if (input) {
+ outputEnable.MXP =
+ outputEnable.MXP & (~bitToSet); // clear the bit for read
+ } else {
+ outputEnable.MXP = outputEnable.MXP | bitToSet; // set the bit for write
+ }
+ }
+
+ digitalSystem->writeOutputEnable(outputEnable, status);
+
+ 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.
+ if (port == nullptr) return;
+ digitalChannelHandles->Free(dioPortHandle, HAL_HandleEnum::DIO);
+
+ // Wait for no other object to hold this handle.
+ auto start = hal::fpga_clock::now();
+ while (port.use_count() != 1) {
+ auto current = hal::fpga_clock::now();
+ if (start + std::chrono::seconds(1) < current) {
+ wpi::outs() << "DIO handle free timeout\n";
+ wpi::outs().flush();
+ break;
+ }
+ std::this_thread::yield();
+ }
+
+ int32_t status = 0;
+ std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
+ if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
+ // Unset the SPI flag
+ int32_t bitToUnset = 1 << remapSPIChannel(port->channel);
+ uint16_t specialFunctions = spiSystem->readEnableDIO(&status);
+ spiSystem->writeEnableDIO(specialFunctions & ~bitToUnset, &status);
+ } else if (port->channel >= kNumDigitalHeaders) {
+ // Unset the MXP flag
+ uint32_t bitToUnset = 1u << remapMXPChannel(port->channel);
+
+ uint16_t specialFunctions =
+ digitalSystem->readEnableMXPSpecialFunction(&status);
+ digitalSystem->writeEnableMXPSpecialFunction(specialFunctions | bitToUnset,
+ &status);
+ }
+}
+
+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));
+
+ return handle;
+}
+
+void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status) {
+ digitalPWMHandles->Free(pwmGenerator);
+}
+
+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.
+ initializeDigital(status);
+ if (*status != 0) return;
+ uint16_t pwmPeriodPower = static_cast<uint16_t>(
+ std::log(1.0 / (16 * 1.0E-6 * rate)) / std::log(2.0) + 0.5);
+ 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;
+ double rawDutyCycle = 256.0 * dutyCycle;
+ if (rawDutyCycle > 255.5) rawDutyCycle = 255.5;
+ {
+ std::lock_guard<wpi::mutex> lock(digitalPwmMutex);
+ uint16_t pwmPeriodPower = digitalSystem->readPWMPeriodPower(status);
+ if (pwmPeriodPower < 4) {
+ // The resolution of the duty cycle drops close to the highest
+ // frequencies.
+ rawDutyCycle = rawDutyCycle / std::pow(2.0, 4 - pwmPeriodPower);
+ }
+ if (id < 4)
+ digitalSystem->writePWMDutyCycleA(id, static_cast<uint8_t>(rawDutyCycle),
+ status);
+ else
+ digitalSystem->writePWMDutyCycleB(
+ id - 4, static_cast<uint8_t>(rawDutyCycle), status);
+ }
+}
+
+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;
+ if (channel >= kNumDigitalHeaders &&
+ channel <
+ kNumDigitalHeaders + kNumDigitalMXPChannels) { // If it is on the MXP
+ /* Then to write as a digital PWM channel an offset is needed to write on
+ * the correct channel
+ */
+ channel += kMXPDigitalPWMOffset;
+ }
+ digitalSystem->writePWMOutputSelect(id, channel, status);
+}
+
+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;
+ }
+ {
+ std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
+ tDIO::tDO currentDIO = digitalSystem->readDO(status);
+
+ if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
+ if (value == 0) {
+ currentDIO.SPIPort =
+ currentDIO.SPIPort & ~(1u << remapSPIChannel(port->channel));
+ } else if (value == 1) {
+ currentDIO.SPIPort =
+ currentDIO.SPIPort | (1u << remapSPIChannel(port->channel));
+ }
+ } else if (port->channel < kNumDigitalHeaders) {
+ if (value == 0) {
+ currentDIO.Headers = currentDIO.Headers & ~(1u << port->channel);
+ } else if (value == 1) {
+ currentDIO.Headers = currentDIO.Headers | (1u << port->channel);
+ }
+ } else {
+ if (value == 0) {
+ currentDIO.MXP =
+ currentDIO.MXP & ~(1u << remapMXPChannel(port->channel));
+ } else if (value == 1) {
+ currentDIO.MXP =
+ currentDIO.MXP | (1u << remapMXPChannel(port->channel));
+ }
+ }
+ digitalSystem->writeDO(currentDIO, status);
+ }
+}
+
+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;
+ }
+ {
+ std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
+ tDIO::tOutputEnable currentDIO = digitalSystem->readOutputEnable(status);
+
+ if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
+ if (input) {
+ currentDIO.SPIPort =
+ currentDIO.SPIPort & ~(1u << remapSPIChannel(port->channel));
+ } else {
+ currentDIO.SPIPort =
+ currentDIO.SPIPort | (1u << remapSPIChannel(port->channel));
+ }
+ } else if (port->channel < kNumDigitalHeaders) {
+ if (input) {
+ currentDIO.Headers = currentDIO.Headers & ~(1u << port->channel);
+ } else {
+ currentDIO.Headers = currentDIO.Headers | (1u << port->channel);
+ }
+ } else {
+ if (input) {
+ currentDIO.MXP =
+ currentDIO.MXP & ~(1u << remapMXPChannel(port->channel));
+ } else {
+ currentDIO.MXP =
+ currentDIO.MXP | (1u << remapMXPChannel(port->channel));
+ }
+ }
+ digitalSystem->writeOutputEnable(currentDIO, status);
+ }
+}
+
+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;
+ }
+ tDIO::tDI currentDIO = digitalSystem->readDI(status);
+ // Shift 00000001 over channel-1 places.
+ // AND it against the currentDIO
+ // if it == 0, then return false
+ // else return true
+
+ if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
+ return ((currentDIO.SPIPort >> remapSPIChannel(port->channel)) & 1) != 0;
+ } else if (port->channel < kNumDigitalHeaders) {
+ return ((currentDIO.Headers >> port->channel) & 1) != 0;
+ } else {
+ return ((currentDIO.MXP >> remapMXPChannel(port->channel)) & 1) != 0;
+ }
+}
+
+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;
+ }
+ tDIO::tOutputEnable currentOutputEnable =
+ digitalSystem->readOutputEnable(status);
+ // Shift 00000001 over port->channel-1 places.
+ // AND it against the currentOutputEnable
+ // if it == 0, then return false
+ // else return true
+
+ if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
+ return ((currentOutputEnable.SPIPort >> remapSPIChannel(port->channel)) &
+ 1) != 0;
+ } else if (port->channel < kNumDigitalHeaders) {
+ return ((currentOutputEnable.Headers >> port->channel) & 1) != 0;
+ } else {
+ return ((currentOutputEnable.MXP >> remapMXPChannel(port->channel)) & 1) !=
+ 0;
+ }
+}
+
+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;
+ }
+ tDIO::tPulse pulse;
+
+ if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
+ pulse.SPIPort = 1u << remapSPIChannel(port->channel);
+ } else if (port->channel < kNumDigitalHeaders) {
+ pulse.Headers = 1u << port->channel;
+ } else {
+ pulse.MXP = 1u << remapMXPChannel(port->channel);
+ }
+
+ digitalSystem->writePulseLength(
+ static_cast<uint8_t>(1.0e9 * pulseLength /
+ (pwmSystem->readLoopTiming(status) * 25)),
+ status);
+ digitalSystem->writePulse(pulse, status);
+}
+
+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;
+ }
+ tDIO::tPulse pulseRegister = digitalSystem->readPulse(status);
+
+ if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
+ return (pulseRegister.SPIPort & (1 << remapSPIChannel(port->channel))) != 0;
+ } else if (port->channel < kNumDigitalHeaders) {
+ return (pulseRegister.Headers & (1 << port->channel)) != 0;
+ } else {
+ return (pulseRegister.MXP & (1 << remapMXPChannel(port->channel))) != 0;
+ }
+}
+
+HAL_Bool HAL_IsAnyPulsing(int32_t* status) {
+ initializeDigital(status);
+ if (*status != 0) return false;
+ tDIO::tPulse pulseRegister = digitalSystem->readPulse(status);
+ return pulseRegister.Headers != 0 && pulseRegister.MXP != 0 &&
+ pulseRegister.SPIPort != 0;
+}
+
+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;
+ }
+
+ std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
+ if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
+ // Channels 10-15 are SPI channels, so subtract our MXP channels
+ digitalSystem->writeFilterSelectHdr(port->channel - kNumDigitalMXPChannels,
+ filterIndex, status);
+ } else if (port->channel < kNumDigitalHeaders) {
+ digitalSystem->writeFilterSelectHdr(port->channel, filterIndex, status);
+ } else {
+ digitalSystem->writeFilterSelectMXP(remapMXPChannel(port->channel),
+ filterIndex, status);
+ }
+}
+
+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;
+ }
+
+ std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
+ if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
+ // Channels 10-15 are SPI channels, so subtract our MXP channels
+ return digitalSystem->readFilterSelectHdr(
+ port->channel - kNumDigitalMXPChannels, status);
+ } else if (port->channel < kNumDigitalHeaders) {
+ return digitalSystem->readFilterSelectHdr(port->channel, status);
+ } else {
+ return digitalSystem->readFilterSelectMXP(remapMXPChannel(port->channel),
+ status);
+ }
+}
+
+void HAL_SetFilterPeriod(int32_t filterIndex, int64_t value, int32_t* status) {
+ initializeDigital(status);
+ if (*status != 0) return;
+ std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
+ digitalSystem->writeFilterPeriodHdr(filterIndex, value, status);
+ if (*status == 0) {
+ digitalSystem->writeFilterPeriodMXP(filterIndex, value, status);
+ }
+}
+
+int64_t HAL_GetFilterPeriod(int32_t filterIndex, int32_t* status) {
+ initializeDigital(status);
+ if (*status != 0) return 0;
+ uint32_t hdrPeriod = 0;
+ uint32_t mxpPeriod = 0;
+ {
+ std::lock_guard<wpi::mutex> lock(digitalDIOMutex);
+ hdrPeriod = digitalSystem->readFilterPeriodHdr(filterIndex, status);
+ if (*status == 0) {
+ mxpPeriod = digitalSystem->readFilterPeriodMXP(filterIndex, status);
+ }
+ }
+ if (hdrPeriod != mxpPeriod) {
+ *status = NiFpga_Status_SoftwareFault;
+ return -1;
+ }
+ return hdrPeriod;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/DigitalInternal.cpp b/hal/src/main/native/athena/DigitalInternal.cpp
new file mode 100644
index 0000000..1db6c7e
--- /dev/null
+++ b/hal/src/main/native/athena/DigitalInternal.cpp
@@ -0,0 +1,183 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <atomic>
+#include <thread>
+
+#include <FRC_NetworkCommunication/LoadOut.h>
+#include <wpi/mutex.h>
+
+#include "ConstantsInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/AnalogTrigger.h"
+#include "hal/ChipObject.h"
+#include "hal/HAL.h"
+#include "hal/Ports.h"
+#include "hal/cpp/UnsafeDIO.h"
+
+namespace hal {
+
+std::unique_ptr<tDIO> digitalSystem;
+std::unique_ptr<tRelay> relaySystem;
+std::unique_ptr<tPWM> pwmSystem;
+std::unique_ptr<tSPI> spiSystem;
+
+// Create a mutex to protect changes to the digital output values
+wpi::mutex digitalDIOMutex;
+
+DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
+ kNumDigitalChannels + kNumPWMHeaders>*
+ digitalChannelHandles;
+
+namespace init {
+void InitializeDigitalInternal() {
+ static DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
+ kNumDigitalChannels + kNumPWMHeaders>
+ dcH;
+ digitalChannelHandles = &dcH;
+}
+} // namespace init
+
+namespace detail {
+wpi::mutex& UnsafeGetDIOMutex() { return digitalDIOMutex; }
+tDIO* UnsafeGetDigialSystem() { return digitalSystem.get(); }
+int32_t ComputeDigitalMask(HAL_DigitalHandle handle, int32_t* status) {
+ auto port = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ tDIO::tDO output;
+ output.value = 0;
+ if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) {
+ output.SPIPort = (1u << remapSPIChannel(port->channel));
+ } else if (port->channel < kNumDigitalHeaders) {
+ output.Headers = (1u << port->channel);
+ } else {
+ output.MXP = (1u << remapMXPChannel(port->channel));
+ }
+ return output.value;
+}
+} // namespace detail
+
+void initializeDigital(int32_t* status) {
+ 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::lock_guard<wpi::mutex> lock(initializeMutex);
+ // Second check in case another thread was waiting
+ if (initialized) return;
+
+ digitalSystem.reset(tDIO::create(status));
+
+ // Relay Setup
+ relaySystem.reset(tRelay::create(status));
+
+ // Turn off all relay outputs.
+ relaySystem->writeValue_Forward(0, status);
+ relaySystem->writeValue_Reverse(0, status);
+
+ // PWM Setup
+ pwmSystem.reset(tPWM::create(status));
+
+ // Make sure that the 9403 IONode has had a chance to initialize before
+ // continuing.
+ while (pwmSystem->readLoopTiming(status) == 0) std::this_thread::yield();
+
+ if (pwmSystem->readLoopTiming(status) != kExpectedLoopTiming) {
+ *status = LOOP_TIMING_ERROR; // NOTE: Doesn't display the error
+ }
+
+ // Calculate the length, in ms, of one DIO loop
+ double loopTime = pwmSystem->readLoopTiming(status) /
+ (kSystemClockTicksPerMicrosecond * 1e3);
+
+ pwmSystem->writeConfig_Period(
+ static_cast<uint16_t>(kDefaultPwmPeriod / loopTime + .5), status);
+ uint16_t minHigh = static_cast<uint16_t>(
+ (kDefaultPwmCenter - kDefaultPwmStepsDown * loopTime) / loopTime + .5);
+ pwmSystem->writeConfig_MinHigh(minHigh, status);
+ // Ensure that PWM output values are set to OFF
+ for (uint8_t pwmIndex = 0; pwmIndex < kNumPWMChannels; pwmIndex++) {
+ // Copy of SetPWM
+ if (pwmIndex < tPWM::kNumHdrRegisters) {
+ pwmSystem->writeHdr(pwmIndex, kPwmDisabled, status);
+ } else {
+ pwmSystem->writeMXP(pwmIndex - tPWM::kNumHdrRegisters, kPwmDisabled,
+ status);
+ }
+
+ // Copy of SetPWMPeriodScale, set to 4x by default.
+ if (pwmIndex < tPWM::kNumPeriodScaleHdrElements) {
+ pwmSystem->writePeriodScaleHdr(pwmIndex, 3, status);
+ } else {
+ pwmSystem->writePeriodScaleMXP(
+ pwmIndex - tPWM::kNumPeriodScaleHdrElements, 3, status);
+ }
+ }
+
+ // SPI setup
+ spiSystem.reset(tSPI::create(status));
+
+ initialized = true;
+}
+
+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 + kNumDigitalMXPChannels) {
+ // channels 10-15, so need to add headers to remap index
+ channel = remapSPIChannel(index) + kNumDigitalHeaders;
+ module = 0;
+ } else 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 remapSPIChannel(int32_t channel) { return channel - 26; }
+
+} // namespace hal
+
+// Unused function here to test template compile.
+__attribute__((unused)) static void CompileFunctorTest() {
+ hal::UnsafeManipulateDIO(0, nullptr, [](hal::DIOSetProxy& proxy) {});
+}
diff --git a/hal/src/main/native/athena/DigitalInternal.h b/hal/src/main/native/athena/DigitalInternal.h
new file mode 100644
index 0000000..b486f48
--- /dev/null
+++ b/hal/src/main/native/athena/DigitalInternal.h
@@ -0,0 +1,113 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <wpi/mutex.h>
+
+#include "PortsInternal.h"
+#include "hal/AnalogTrigger.h"
+#include "hal/ChipObject.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 double kDefaultPwmPeriod = 5.05;
+/**
+ * kDefaultPwmCenter is the PWM range center in ms
+ */
+constexpr double kDefaultPwmCenter = 1.5;
+/**
+ * kDefaultPWMStepsDown is the number of PWM steps below the centerpoint
+ */
+constexpr int32_t kDefaultPwmStepsDown = 1000;
+constexpr int32_t kPwmDisabled = 0;
+
+extern std::unique_ptr<tDIO> digitalSystem;
+extern std::unique_ptr<tRelay> relaySystem;
+extern std::unique_ptr<tPWM> pwmSystem;
+extern std::unique_ptr<tSPI> spiSystem;
+
+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;
+
+extern wpi::mutex digitalDIOMutex;
+
+/**
+ * Initialize the digital system.
+ */
+void initializeDigital(int32_t* status);
+
+/**
+ * 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);
+
+/**
+ * Map SPI channel numbers from their physical number (27 to 31) to their
+ * position in the bit field.
+ */
+int32_t remapSPIChannel(int32_t channel);
+
+} // namespace hal
diff --git a/hal/src/main/native/athena/Encoder.cpp b/hal/src/main/native/athena/Encoder.cpp
new file mode 100644
index 0000000..adf70ed
--- /dev/null
+++ b/hal/src/main/native/athena/Encoder.cpp
@@ -0,0 +1,462 @@
+/*----------------------------------------------------------------------------*/
+/* 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/Encoder.h"
+
+#include "EncoderInternal.h"
+#include "FPGAEncoder.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/ChipObject.h"
+#include "hal/Counter.h"
+#include "hal/Errors.h"
+#include "hal/handles/LimitedClassedHandleResource.h"
+
+using namespace hal;
+
+Encoder::Encoder(HAL_Handle digitalSourceHandleA,
+ HAL_AnalogTriggerType analogTriggerTypeA,
+ HAL_Handle digitalSourceHandleB,
+ HAL_AnalogTriggerType analogTriggerTypeB,
+ bool reverseDirection, HAL_EncoderEncodingType encodingType,
+ int32_t* status) {
+ m_encodingType = encodingType;
+ switch (encodingType) {
+ case HAL_Encoder_k4X: {
+ m_encodingScale = 4;
+ m_encoder = HAL_InitializeFPGAEncoder(
+ digitalSourceHandleA, analogTriggerTypeA, digitalSourceHandleB,
+ analogTriggerTypeB, reverseDirection, &m_index, status);
+ if (*status != 0) {
+ return;
+ }
+ m_counter = HAL_kInvalidHandle;
+ SetMaxPeriod(.5, status);
+ break;
+ }
+ case HAL_Encoder_k1X:
+ case HAL_Encoder_k2X: {
+ SetupCounter(digitalSourceHandleA, analogTriggerTypeA,
+ digitalSourceHandleB, analogTriggerTypeB, reverseDirection,
+ encodingType, status);
+
+ m_encodingScale = encodingType == HAL_Encoder_k1X ? 1 : 2;
+ break;
+ }
+ default:
+ *status = PARAMETER_OUT_OF_RANGE;
+ return;
+ }
+}
+
+void Encoder::SetupCounter(HAL_Handle digitalSourceHandleA,
+ HAL_AnalogTriggerType analogTriggerTypeA,
+ HAL_Handle digitalSourceHandleB,
+ HAL_AnalogTriggerType analogTriggerTypeB,
+ bool reverseDirection,
+ HAL_EncoderEncodingType encodingType,
+ int32_t* status) {
+ m_encodingScale = encodingType == HAL_Encoder_k1X ? 1 : 2;
+ m_counter =
+ HAL_InitializeCounter(HAL_Counter_kExternalDirection, &m_index, status);
+ if (*status != 0) return;
+ HAL_SetCounterMaxPeriod(m_counter, 0.5, status);
+ if (*status != 0) return;
+ HAL_SetCounterUpSource(m_counter, digitalSourceHandleA, analogTriggerTypeA,
+ status);
+ if (*status != 0) return;
+ HAL_SetCounterDownSource(m_counter, digitalSourceHandleB, analogTriggerTypeB,
+ status);
+ if (*status != 0) return;
+ if (encodingType == HAL_Encoder_k1X) {
+ HAL_SetCounterUpSourceEdge(m_counter, true, false, status);
+ HAL_SetCounterAverageSize(m_counter, 1, status);
+ } else {
+ HAL_SetCounterUpSourceEdge(m_counter, true, true, status);
+ HAL_SetCounterAverageSize(m_counter, 2, status);
+ }
+ HAL_SetCounterDownSourceEdge(m_counter, reverseDirection, true, status);
+}
+
+Encoder::~Encoder() {
+ if (m_counter != HAL_kInvalidHandle) {
+ int32_t status = 0;
+ HAL_FreeCounter(m_counter, &status);
+ } else {
+ int32_t status = 0;
+ HAL_FreeFPGAEncoder(m_encoder, &status);
+ }
+}
+
+// CounterBase interface
+int32_t Encoder::Get(int32_t* status) const {
+ return static_cast<int32_t>(GetRaw(status) * DecodingScaleFactor());
+}
+
+int32_t Encoder::GetRaw(int32_t* status) const {
+ if (m_counter) {
+ return HAL_GetCounter(m_counter, status);
+ } else {
+ return HAL_GetFPGAEncoder(m_encoder, status);
+ }
+}
+
+int32_t Encoder::GetEncodingScale(int32_t* status) const {
+ return m_encodingScale;
+}
+
+void Encoder::Reset(int32_t* status) {
+ if (m_counter) {
+ HAL_ResetCounter(m_counter, status);
+ } else {
+ HAL_ResetFPGAEncoder(m_encoder, status);
+ }
+}
+
+double Encoder::GetPeriod(int32_t* status) const {
+ if (m_counter) {
+ return HAL_GetCounterPeriod(m_counter, status) / DecodingScaleFactor();
+ } else {
+ return HAL_GetFPGAEncoderPeriod(m_encoder, status);
+ }
+}
+
+void Encoder::SetMaxPeriod(double maxPeriod, int32_t* status) {
+ if (m_counter) {
+ HAL_SetCounterMaxPeriod(m_counter, maxPeriod, status);
+ } else {
+ HAL_SetFPGAEncoderMaxPeriod(m_encoder, maxPeriod, status);
+ }
+}
+
+bool Encoder::GetStopped(int32_t* status) const {
+ if (m_counter) {
+ return HAL_GetCounterStopped(m_counter, status);
+ } else {
+ return HAL_GetFPGAEncoderStopped(m_encoder, status);
+ }
+}
+
+bool Encoder::GetDirection(int32_t* status) const {
+ if (m_counter) {
+ return HAL_GetCounterDirection(m_counter, status);
+ } else {
+ return HAL_GetFPGAEncoderDirection(m_encoder, status);
+ }
+}
+
+double Encoder::GetDistance(int32_t* status) const {
+ return GetRaw(status) * DecodingScaleFactor() * m_distancePerPulse;
+}
+
+double Encoder::GetRate(int32_t* status) const {
+ return m_distancePerPulse / GetPeriod(status);
+}
+
+void Encoder::SetMinRate(double minRate, int32_t* status) {
+ SetMaxPeriod(m_distancePerPulse / minRate, status);
+}
+
+void Encoder::SetDistancePerPulse(double distancePerPulse, int32_t* status) {
+ m_distancePerPulse = distancePerPulse;
+}
+
+void Encoder::SetReverseDirection(bool reverseDirection, int32_t* status) {
+ if (m_counter) {
+ HAL_SetCounterReverseDirection(m_counter, reverseDirection, status);
+ } else {
+ HAL_SetFPGAEncoderReverseDirection(m_encoder, reverseDirection, status);
+ }
+}
+
+void Encoder::SetSamplesToAverage(int32_t samplesToAverage, int32_t* status) {
+ if (samplesToAverage < 1 || samplesToAverage > 127) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return;
+ }
+ if (m_counter) {
+ HAL_SetCounterSamplesToAverage(m_counter, samplesToAverage, status);
+ } else {
+ HAL_SetFPGAEncoderSamplesToAverage(m_encoder, samplesToAverage, status);
+ }
+}
+
+int32_t Encoder::GetSamplesToAverage(int32_t* status) const {
+ if (m_counter) {
+ return HAL_GetCounterSamplesToAverage(m_counter, status);
+ } else {
+ return HAL_GetFPGAEncoderSamplesToAverage(m_encoder, status);
+ }
+}
+
+void Encoder::SetIndexSource(HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ HAL_EncoderIndexingType type, int32_t* status) {
+ if (m_counter) {
+ *status = HAL_COUNTER_NOT_SUPPORTED;
+ return;
+ }
+ bool activeHigh =
+ (type == HAL_kResetWhileHigh) || (type == HAL_kResetOnRisingEdge);
+ bool edgeSensitive =
+ (type == HAL_kResetOnFallingEdge) || (type == HAL_kResetOnRisingEdge);
+ HAL_SetFPGAEncoderIndexSource(m_encoder, digitalSourceHandle,
+ analogTriggerType, activeHigh, edgeSensitive,
+ status);
+}
+
+double Encoder::DecodingScaleFactor() const {
+ switch (m_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;
+ }
+}
+
+static LimitedClassedHandleResource<HAL_EncoderHandle, Encoder,
+ kNumEncoders + kNumCounters,
+ HAL_HandleEnum::Encoder>* encoderHandles;
+
+namespace hal {
+namespace init {
+void InitializeEncoder() {
+ static LimitedClassedHandleResource<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();
+ auto encoder = std::make_shared<Encoder>(
+ digitalSourceHandleA, analogTriggerTypeA, digitalSourceHandleB,
+ analogTriggerTypeB, reverseDirection, encodingType, status);
+ if (*status != 0) return HAL_kInvalidHandle; // return in creation error
+ auto handle = encoderHandles->Allocate(encoder);
+ if (handle == HAL_kInvalidHandle) {
+ *status = NO_AVAILABLE_RESOURCES;
+ return HAL_kInvalidHandle;
+ }
+ return handle;
+}
+
+void HAL_FreeEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
+ encoderHandles->Free(encoderHandle);
+}
+
+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 encoder->Get(status);
+}
+
+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 encoder->GetRaw(status);
+}
+
+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 encoder->GetEncodingScale(status);
+}
+
+void HAL_ResetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ encoder->Reset(status);
+}
+
+double HAL_GetEncoderPeriod(HAL_EncoderHandle encoderHandle, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return encoder->GetPeriod(status);
+}
+
+void HAL_SetEncoderMaxPeriod(HAL_EncoderHandle encoderHandle, double maxPeriod,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ encoder->SetMaxPeriod(maxPeriod, status);
+}
+
+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 encoder->GetStopped(status);
+}
+
+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 encoder->GetDirection(status);
+}
+
+double HAL_GetEncoderDistance(HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return encoder->GetDistance(status);
+}
+
+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->GetRate(status);
+}
+
+void HAL_SetEncoderMinRate(HAL_EncoderHandle encoderHandle, double minRate,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ encoder->SetMinRate(minRate, status);
+}
+
+void HAL_SetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
+ double distancePerPulse, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ encoder->SetDistancePerPulse(distancePerPulse, status);
+}
+
+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;
+ }
+ encoder->SetReverseDirection(reverseDirection, status);
+}
+
+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;
+ }
+ encoder->SetSamplesToAverage(samplesToAverage, status);
+}
+
+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 encoder->GetSamplesToAverage(status);
+}
+
+double HAL_GetEncoderDecodingScaleFactor(HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return encoder->DecodingScaleFactor();
+}
+
+double HAL_GetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
+ int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return encoder->GetDistancePerPulse();
+}
+
+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->GetEncodingType();
+}
+
+void HAL_SetEncoderIndexSource(HAL_EncoderHandle encoderHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ HAL_EncoderIndexingType type, int32_t* status) {
+ auto encoder = encoderHandles->Get(encoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ encoder->SetIndexSource(digitalSourceHandle, analogTriggerType, type, status);
+}
+
+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->GetFPGAIndex();
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/EncoderInternal.h b/hal/src/main/native/athena/EncoderInternal.h
new file mode 100644
index 0000000..1e7ed4d
--- /dev/null
+++ b/hal/src/main/native/athena/EncoderInternal.h
@@ -0,0 +1,78 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Encoder.h"
+
+namespace hal {
+
+class Encoder {
+ public:
+ Encoder(HAL_Handle digitalSourceHandleA,
+ HAL_AnalogTriggerType analogTriggerTypeA,
+ HAL_Handle digitalSourceHandleB,
+ HAL_AnalogTriggerType analogTriggerTypeB, bool reverseDirection,
+ HAL_EncoderEncodingType encodingType, int32_t* status);
+ ~Encoder();
+
+ // CounterBase interface
+ int32_t Get(int32_t* status) const;
+ int32_t GetRaw(int32_t* status) const;
+ int32_t GetEncodingScale(int32_t* status) const;
+ void Reset(int32_t* status);
+ double GetPeriod(int32_t* status) const;
+ void SetMaxPeriod(double maxPeriod, int32_t* status);
+ bool GetStopped(int32_t* status) const;
+ bool GetDirection(int32_t* status) const;
+
+ double GetDistance(int32_t* status) const;
+ double GetRate(int32_t* status) const;
+ void SetMinRate(double minRate, int32_t* status);
+ void SetDistancePerPulse(double distancePerPulse, int32_t* status);
+ void SetReverseDirection(bool reverseDirection, int32_t* status);
+ void SetSamplesToAverage(int32_t samplesToAverage, int32_t* status);
+ int32_t GetSamplesToAverage(int32_t* status) const;
+
+ void SetIndexSource(HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ HAL_EncoderIndexingType type, int32_t* status);
+
+ int32_t GetFPGAIndex() const { return m_index; }
+
+ int32_t GetEncodingScale() const { return m_encodingScale; }
+
+ double DecodingScaleFactor() const;
+
+ double GetDistancePerPulse() const { return m_distancePerPulse; }
+
+ HAL_EncoderEncodingType GetEncodingType() const { return m_encodingType; }
+
+ private:
+ void SetupCounter(HAL_Handle digitalSourceHandleA,
+ HAL_AnalogTriggerType analogTriggerTypeA,
+ HAL_Handle digitalSourceHandleB,
+ HAL_AnalogTriggerType analogTriggerTypeB,
+ bool reverseDirection, HAL_EncoderEncodingType encodingType,
+ int32_t* status);
+
+ HAL_FPGAEncoderHandle m_encoder = HAL_kInvalidHandle;
+
+ HAL_CounterHandle m_counter = HAL_kInvalidHandle;
+
+ int32_t m_index = 0;
+
+ double m_distancePerPulse = 1.0;
+
+ HAL_EncoderEncodingType m_encodingType;
+
+ int32_t m_encodingScale;
+};
+
+} // namespace hal
diff --git a/hal/src/main/native/athena/FPGAEncoder.cpp b/hal/src/main/native/athena/FPGAEncoder.cpp
new file mode 100644
index 0000000..7f2e107
--- /dev/null
+++ b/hal/src/main/native/athena/FPGAEncoder.cpp
@@ -0,0 +1,245 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "FPGAEncoder.h"
+
+#include <memory>
+
+#include "DigitalInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/handles/LimitedHandleResource.h"
+
+using namespace hal;
+
+namespace {
+
+struct Encoder {
+ std::unique_ptr<tEncoder> encoder;
+ uint8_t index;
+};
+
+} // namespace
+
+static constexpr double DECODING_SCALING_FACTOR = 0.25;
+
+static LimitedHandleResource<HAL_FPGAEncoderHandle, Encoder, kNumEncoders,
+ HAL_HandleEnum::FPGAEncoder>* fpgaEncoderHandles;
+
+namespace hal {
+namespace init {
+void InitializeFPGAEncoder() {
+ static LimitedHandleResource<HAL_FPGAEncoderHandle, Encoder, kNumEncoders,
+ HAL_HandleEnum::FPGAEncoder>
+ feH;
+ fpgaEncoderHandles = &feH;
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+HAL_FPGAEncoderHandle HAL_InitializeFPGAEncoder(
+ HAL_Handle digitalSourceHandleA, HAL_AnalogTriggerType analogTriggerTypeA,
+ HAL_Handle digitalSourceHandleB, HAL_AnalogTriggerType analogTriggerTypeB,
+ HAL_Bool reverseDirection, int32_t* index, int32_t* status) {
+ hal::init::CheckInit();
+ bool routingAnalogTriggerA = false;
+ uint8_t routingChannelA = 0;
+ uint8_t routingModuleA = 0;
+ bool successA = remapDigitalSource(digitalSourceHandleA, analogTriggerTypeA,
+ routingChannelA, routingModuleA,
+ routingAnalogTriggerA);
+ bool routingAnalogTriggerB = false;
+ uint8_t routingChannelB = 0;
+ uint8_t routingModuleB = 0;
+ bool successB = remapDigitalSource(digitalSourceHandleB, analogTriggerTypeB,
+ routingChannelB, routingModuleB,
+ routingAnalogTriggerB);
+
+ if (!successA || !successB) {
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+
+ auto handle = fpgaEncoderHandles->Allocate();
+ if (handle == HAL_kInvalidHandle) { // out of resources
+ *status = NO_AVAILABLE_RESOURCES;
+ return HAL_kInvalidHandle;
+ }
+
+ auto encoder = fpgaEncoderHandles->Get(handle);
+ if (encoder == nullptr) { // will only error on thread issue
+ *status = HAL_HANDLE_ERROR;
+ return HAL_kInvalidHandle;
+ }
+
+ encoder->index = static_cast<uint8_t>(getHandleIndex(handle));
+ *index = encoder->index;
+ // TODO: if (index == ~0ul) { CloneError(quadEncoders); return; }
+ encoder->encoder.reset(tEncoder::create(encoder->index, status));
+ encoder->encoder->writeConfig_ASource_Module(routingModuleA, status);
+ encoder->encoder->writeConfig_ASource_Channel(routingChannelA, status);
+ encoder->encoder->writeConfig_ASource_AnalogTrigger(routingAnalogTriggerA,
+ status);
+ encoder->encoder->writeConfig_BSource_Module(routingModuleB, status);
+ encoder->encoder->writeConfig_BSource_Channel(routingChannelB, status);
+ encoder->encoder->writeConfig_BSource_AnalogTrigger(routingAnalogTriggerB,
+ status);
+ encoder->encoder->strobeReset(status);
+ encoder->encoder->writeConfig_Reverse(reverseDirection, status);
+ encoder->encoder->writeTimerConfig_AverageSize(4, status);
+
+ return handle;
+}
+
+void HAL_FreeFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t* status) {
+ fpgaEncoderHandles->Free(fpgaEncoderHandle);
+}
+
+void HAL_ResetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t* status) {
+ auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ encoder->encoder->strobeReset(status);
+}
+
+int32_t HAL_GetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t* status) {
+ auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return encoder->encoder->readOutput_Value(status);
+}
+
+double HAL_GetFPGAEncoderPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t* status) {
+ auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0.0;
+ }
+ tEncoder::tTimerOutput output = encoder->encoder->readTimerOutput(status);
+ double value;
+ if (output.Stalled) {
+ // Return infinity
+ double zero = 0.0;
+ value = 1.0 / zero;
+ } else {
+ // output.Period is a fixed point number that counts by 2 (24 bits, 25
+ // integer bits)
+ value = static_cast<double>(output.Period << 1) /
+ static_cast<double>(output.Count);
+ }
+ double measuredPeriod = value * 2.5e-8;
+ return measuredPeriod / DECODING_SCALING_FACTOR;
+}
+
+void HAL_SetFPGAEncoderMaxPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ double maxPeriod, int32_t* status) {
+ auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ encoder->encoder->writeTimerConfig_StallPeriod(
+ static_cast<uint32_t>(maxPeriod * 4.0e8 * DECODING_SCALING_FACTOR),
+ status);
+}
+
+HAL_Bool HAL_GetFPGAEncoderStopped(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t* status) {
+ auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ return encoder->encoder->readTimerOutput_Stalled(status) != 0;
+}
+
+HAL_Bool HAL_GetFPGAEncoderDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t* status) {
+ auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+ return encoder->encoder->readOutput_Direction(status);
+}
+
+void HAL_SetFPGAEncoderReverseDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ HAL_Bool reverseDirection,
+ int32_t* status) {
+ auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ encoder->encoder->writeConfig_Reverse(reverseDirection, status);
+}
+
+void HAL_SetFPGAEncoderSamplesToAverage(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t samplesToAverage,
+ int32_t* status) {
+ auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ if (samplesToAverage < 1 || samplesToAverage > 127) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ }
+ encoder->encoder->writeTimerConfig_AverageSize(samplesToAverage, status);
+}
+
+int32_t HAL_GetFPGAEncoderSamplesToAverage(
+ HAL_FPGAEncoderHandle fpgaEncoderHandle, int32_t* status) {
+ auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+ if (encoder == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ return encoder->encoder->readTimerConfig_AverageSize(status);
+}
+
+void HAL_SetFPGAEncoderIndexSource(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ HAL_Bool activeHigh, HAL_Bool edgeSensitive,
+ int32_t* status) {
+ auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+ if (encoder == 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;
+ }
+
+ encoder->encoder->writeConfig_IndexSource_Channel(routingChannel, status);
+ encoder->encoder->writeConfig_IndexSource_Module(routingModule, status);
+ encoder->encoder->writeConfig_IndexSource_AnalogTrigger(routingAnalogTrigger,
+ status);
+ encoder->encoder->writeConfig_IndexActiveHigh(activeHigh, status);
+ encoder->encoder->writeConfig_IndexEdgeSensitive(edgeSensitive, status);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/FPGAEncoder.h b/hal/src/main/native/athena/FPGAEncoder.h
new file mode 100644
index 0000000..f29aeae
--- /dev/null
+++ b/hal/src/main/native/athena/FPGAEncoder.h
@@ -0,0 +1,126 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/AnalogTrigger.h"
+#include "hal/Types.h"
+
+extern "C" {
+
+HAL_FPGAEncoderHandle HAL_InitializeFPGAEncoder(
+ HAL_Handle digitalSourceHandleA, HAL_AnalogTriggerType analogTriggerTypeA,
+ HAL_Handle digitalSourceHandleB, HAL_AnalogTriggerType analogTriggerTypeB,
+ HAL_Bool reverseDirection, int32_t* index, int32_t* status);
+void HAL_FreeFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t* status);
+
+/**
+ * Reset the Encoder distance to zero.
+ * Resets the current count to zero on the encoder.
+ */
+void HAL_ResetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t* status);
+
+/**
+ * Gets the fpga value from the encoder.
+ * The fpga value is the actual count unscaled by the 1x, 2x, or 4x scale
+ * factor.
+ * @return Current fpga count from the encoder
+ */
+int32_t HAL_GetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t* status); // Raw value
+
+/**
+ * Returns the period of the most recent pulse.
+ * Returns the period of the most recent Encoder pulse in seconds.
+ * This method compenstates for the decoding type.
+ *
+ * @deprecated Use GetRate() in favor of this method. This returns unscaled
+ * periods and GetRate() scales using value from SetDistancePerPulse().
+ *
+ * @return Period in seconds of the most recent pulse.
+ */
+double HAL_GetFPGAEncoderPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t* status);
+
+/**
+ * Sets the maximum period for stopped detection.
+ * Sets the value that represents the maximum period of the Encoder before it
+ * will assume that the attached device is stopped. This timeout allows users
+ * to determine if the wheels or other shaft has stopped rotating.
+ * This method compensates for the decoding type.
+ *
+ * @deprecated Use SetMinRate() in favor of this method. This takes unscaled
+ * periods and SetMinRate() scales using value from SetDistancePerPulse().
+ *
+ * @param maxPeriod The maximum time between rising and falling edges before the
+ * FPGA will
+ * report the device stopped. This is expressed in seconds.
+ */
+void HAL_SetFPGAEncoderMaxPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ double maxPeriod, int32_t* status);
+
+/**
+ * Determine if the encoder is stopped.
+ * Using the MaxPeriod value, a boolean is returned that is true if the encoder
+ * is considered stopped and false if it is still moving. A stopped encoder is
+ * one where the most recent pulse width exceeds the MaxPeriod.
+ * @return True if the encoder is considered stopped.
+ */
+HAL_Bool HAL_GetFPGAEncoderStopped(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t* status);
+
+/**
+ * The last direction the encoder value changed.
+ * @return The last direction the encoder value changed.
+ */
+HAL_Bool HAL_GetFPGAEncoderDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t* status);
+
+/**
+ * Set the direction sensing for this encoder.
+ * This sets the direction sensing on the encoder so that it could count in the
+ * correct software direction regardless of the mounting.
+ * @param reverseDirection true if the encoder direction should be reversed
+ */
+void HAL_SetFPGAEncoderReverseDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ HAL_Bool reverseDirection,
+ int32_t* status);
+
+/**
+ * Set the Samples to Average which specifies the number of samples of the timer
+ * to average when calculating the period. Perform averaging to account for
+ * mechanical imperfections or as oversampling to increase resolution.
+ * @param samplesToAverage The number of samples to average from 1 to 127.
+ */
+void HAL_SetFPGAEncoderSamplesToAverage(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ int32_t samplesToAverage,
+ int32_t* status);
+
+/**
+ * Get the Samples to Average which specifies the number of samples of the timer
+ * to average when calculating the period. Perform averaging to account for
+ * mechanical imperfections or as oversampling to increase resolution.
+ * @return SamplesToAverage The number of samples being averaged (from 1 to 127)
+ */
+int32_t HAL_GetFPGAEncoderSamplesToAverage(
+ HAL_FPGAEncoderHandle fpgaEncoderHandle, int32_t* status);
+
+/**
+ * Set an index source for an encoder, which is an input that resets the
+ * encoder's count.
+ */
+void HAL_SetFPGAEncoderIndexSource(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ HAL_Bool activeHigh, HAL_Bool edgeSensitive,
+ int32_t* status);
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/FRCDriverStation.cpp b/hal/src/main/native/athena/FRCDriverStation.cpp
new file mode 100644
index 0000000..5409ad0
--- /dev/null
+++ b/hal/src/main/native/athena/FRCDriverStation.cpp
@@ -0,0 +1,536 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <atomic>
+#include <chrono>
+#include <cstdlib>
+#include <cstring>
+#include <limits>
+
+#include <FRC_NetworkCommunication/FRCComm.h>
+#include <FRC_NetworkCommunication/NetCommRPCProxy_Occur.h>
+#include <wpi/SafeThread.h>
+#include <wpi/condition_variable.h>
+#include <wpi/mutex.h>
+#include <wpi/raw_ostream.h>
+
+#include "hal/DriverStation.h"
+
+static_assert(sizeof(int32_t) >= sizeof(int),
+ "FRC_NetworkComm status variable is larger than 32 bits");
+
+struct HAL_JoystickAxesInt {
+ int16_t count;
+ int16_t axes[HAL_kMaxJoystickAxes];
+};
+
+static constexpr int kJoystickPorts = 6;
+
+// Joystick User Data
+static std::unique_ptr<HAL_JoystickAxes[]> m_joystickAxes;
+static std::unique_ptr<HAL_JoystickPOVs[]> m_joystickPOVs;
+static std::unique_ptr<HAL_JoystickButtons[]> m_joystickButtons;
+static std::unique_ptr<HAL_JoystickDescriptor[]> m_joystickDescriptor;
+static std::unique_ptr<HAL_MatchInfo> m_matchInfo;
+
+// Joystick Cached Data
+static std::unique_ptr<HAL_JoystickAxes[]> m_joystickAxesCache;
+static std::unique_ptr<HAL_JoystickPOVs[]> m_joystickPOVsCache;
+static std::unique_ptr<HAL_JoystickButtons[]> m_joystickButtonsCache;
+static std::unique_ptr<HAL_JoystickDescriptor[]> m_joystickDescriptorCache;
+static std::unique_ptr<HAL_MatchInfo> m_matchInfoCache;
+
+static wpi::mutex m_cacheDataMutex;
+
+// Control word variables
+static HAL_ControlWord m_controlWordCache;
+static std::chrono::steady_clock::time_point m_lastControlWordUpdate;
+static wpi::mutex m_controlWordMutex;
+
+// Message and Data variables
+static wpi::mutex msgMutex;
+
+static void InitializeDriverStationCaches() {
+ m_joystickAxes = std::make_unique<HAL_JoystickAxes[]>(kJoystickPorts);
+ m_joystickPOVs = std::make_unique<HAL_JoystickPOVs[]>(kJoystickPorts);
+ m_joystickButtons = std::make_unique<HAL_JoystickButtons[]>(kJoystickPorts);
+ m_joystickDescriptor =
+ std::make_unique<HAL_JoystickDescriptor[]>(kJoystickPorts);
+ m_matchInfo = std::make_unique<HAL_MatchInfo>();
+ m_joystickAxesCache = std::make_unique<HAL_JoystickAxes[]>(kJoystickPorts);
+ m_joystickPOVsCache = std::make_unique<HAL_JoystickPOVs[]>(kJoystickPorts);
+ m_joystickButtonsCache =
+ std::make_unique<HAL_JoystickButtons[]>(kJoystickPorts);
+ m_joystickDescriptorCache =
+ std::make_unique<HAL_JoystickDescriptor[]>(kJoystickPorts);
+ m_matchInfoCache = std::make_unique<HAL_MatchInfo>();
+
+ // All joysticks should default to having zero axes, povs and buttons, so
+ // uninitialized memory doesn't get sent to speed controllers.
+ for (unsigned int i = 0; i < kJoystickPorts; 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';
+
+ m_joystickAxesCache[i].count = 0;
+ m_joystickPOVsCache[i].count = 0;
+ m_joystickButtonsCache[i].count = 0;
+ m_joystickDescriptorCache[i].isXbox = 0;
+ m_joystickDescriptorCache[i].type = -1;
+ m_joystickDescriptorCache[i].name[0] = '\0';
+ }
+}
+
+static int32_t HAL_GetJoystickAxesInternal(int32_t joystickNum,
+ HAL_JoystickAxes* axes) {
+ HAL_JoystickAxesInt axesInt;
+
+ int retVal = FRC_NetworkCommunication_getJoystickAxes(
+ joystickNum, reinterpret_cast<JoystickAxes_t*>(&axesInt),
+ HAL_kMaxJoystickAxes);
+
+ // copy integer values to double values
+ axes->count = axesInt.count;
+ // current scaling is -128 to 127, can easily be patched in the future by
+ // changing this function.
+ for (int32_t i = 0; i < axesInt.count; i++) {
+ int8_t value = axesInt.axes[i];
+ if (value < 0) {
+ axes->axes[i] = value / 128.0;
+ } else {
+ axes->axes[i] = value / 127.0;
+ }
+ }
+
+ return retVal;
+}
+
+static int32_t HAL_GetJoystickPOVsInternal(int32_t joystickNum,
+ HAL_JoystickPOVs* povs) {
+ return FRC_NetworkCommunication_getJoystickPOVs(
+ joystickNum, reinterpret_cast<JoystickPOV_t*>(povs),
+ HAL_kMaxJoystickPOVs);
+}
+
+static int32_t HAL_GetJoystickButtonsInternal(int32_t joystickNum,
+ HAL_JoystickButtons* buttons) {
+ return FRC_NetworkCommunication_getJoystickButtons(
+ joystickNum, &buttons->buttons, &buttons->count);
+}
+/**
+ * Retrieve the Joystick Descriptor for particular slot
+ * @param desc [out] descriptor (data transfer object) to fill in. desc is
+ * filled in regardless of success. In other words, if descriptor is not
+ * available, desc is filled in with default values matching the init-values in
+ * Java and C++ Driverstation for when caller requests a too-large joystick
+ * index.
+ *
+ * @return error code reported from Network Comm back-end. Zero is good,
+ * nonzero is bad.
+ */
+static int32_t HAL_GetJoystickDescriptorInternal(int32_t joystickNum,
+ HAL_JoystickDescriptor* desc) {
+ desc->isXbox = 0;
+ desc->type = std::numeric_limits<uint8_t>::max();
+ desc->name[0] = '\0';
+ desc->axisCount =
+ HAL_kMaxJoystickAxes; /* set to the desc->axisTypes's capacity */
+ desc->buttonCount = 0;
+ desc->povCount = 0;
+ int retval = FRC_NetworkCommunication_getJoystickDesc(
+ joystickNum, &desc->isXbox, &desc->type,
+ reinterpret_cast<char*>(&desc->name), &desc->axisCount,
+ reinterpret_cast<uint8_t*>(&desc->axisTypes), &desc->buttonCount,
+ &desc->povCount);
+ /* check the return, if there is an error and the RIOimage predates FRC2017,
+ * then axisCount needs to be cleared */
+ if (retval != 0) {
+ /* set count to zero so downstream code doesn't decode invalid axisTypes. */
+ desc->axisCount = 0;
+ }
+ return retval;
+}
+
+static int32_t HAL_GetControlWordInternal(HAL_ControlWord* controlWord) {
+ std::memset(controlWord, 0, sizeof(HAL_ControlWord));
+ return FRC_NetworkCommunication_getControlWord(
+ reinterpret_cast<ControlWord_t*>(controlWord));
+}
+
+static int32_t HAL_GetMatchInfoInternal(HAL_MatchInfo* info) {
+ MatchType_t matchType = MatchType_t::kMatchType_none;
+ int status = FRC_NetworkCommunication_getMatchInfo(
+ info->eventName, &matchType, &info->matchNumber, &info->replayNumber,
+ info->gameSpecificMessage, &info->gameSpecificMessageSize);
+
+ info->matchType = static_cast<HAL_MatchType>(matchType);
+
+ *(std::end(info->eventName) - 1) = '\0';
+
+ return status;
+}
+
+static void UpdateDriverStationControlWord(bool force,
+ HAL_ControlWord& controlWord) {
+ auto now = std::chrono::steady_clock::now();
+ std::lock_guard<wpi::mutex> lock(m_controlWordMutex);
+ // Update every 50 ms or on force.
+ if ((now - m_lastControlWordUpdate > std::chrono::milliseconds(50)) ||
+ force) {
+ HAL_GetControlWordInternal(&m_controlWordCache);
+ m_lastControlWordUpdate = now;
+ }
+ controlWord = m_controlWordCache;
+}
+
+static void UpdateDriverStationDataCaches() {
+ // Get the status of all of the joysticks, and save to the cache
+ for (uint8_t stick = 0; stick < kJoystickPorts; stick++) {
+ HAL_GetJoystickAxesInternal(stick, &m_joystickAxesCache[stick]);
+ HAL_GetJoystickPOVsInternal(stick, &m_joystickPOVsCache[stick]);
+ HAL_GetJoystickButtonsInternal(stick, &m_joystickButtonsCache[stick]);
+ HAL_GetJoystickDescriptorInternal(stick, &m_joystickDescriptorCache[stick]);
+ }
+ // Grab match specific data
+ HAL_GetMatchInfoInternal(m_matchInfoCache.get());
+
+ // Force a control word update, to make sure the data is the newest.
+ HAL_ControlWord controlWord;
+ UpdateDriverStationControlWord(true, controlWord);
+
+ {
+ // Obtain a lock on the data, swap the cached data into the main data arrays
+ std::lock_guard<wpi::mutex> lock(m_cacheDataMutex);
+
+ m_joystickAxes.swap(m_joystickAxesCache);
+ m_joystickPOVs.swap(m_joystickPOVsCache);
+ m_joystickButtons.swap(m_joystickButtonsCache);
+ m_joystickDescriptor.swap(m_joystickDescriptorCache);
+ m_matchInfo.swap(m_matchInfoCache);
+ }
+}
+
+class DriverStationThread : public wpi::SafeThread {
+ public:
+ void Main() {
+ std::unique_lock<wpi::mutex> lock(m_mutex);
+ while (m_active) {
+ m_cond.wait(lock, [&] { return !m_active || m_notify; });
+ if (!m_active) break;
+ m_notify = false;
+
+ lock.unlock();
+ UpdateDriverStationDataCaches();
+ lock.lock();
+
+ // Notify all threads
+ newDSDataAvailableCounter++;
+ newDSDataAvailableCond.notify_all();
+ }
+
+ // Notify waiters on thread exit
+ newDSDataAvailableCounter++;
+ newDSDataAvailableCond.notify_all();
+ }
+
+ bool m_notify = false;
+ wpi::condition_variable newDSDataAvailableCond;
+ int newDSDataAvailableCounter{0};
+};
+
+class DriverStationThreadOwner
+ : public wpi::SafeThreadOwner<DriverStationThread> {
+ public:
+ void Notify() {
+ auto thr = GetThread();
+ if (!thr) return;
+ thr->m_notify = true;
+ thr->m_cond.notify_one();
+ }
+};
+
+static std::unique_ptr<DriverStationThreadOwner> dsThread = nullptr;
+
+namespace hal {
+namespace init {
+void InitializeFRCDriverStation() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+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) {
+ // 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::lock_guard<wpi::mutex> 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)) {
+ retval = FRC_NetworkCommunication_sendError(isError, errorCode, isLVCode,
+ details, location, callStack);
+ if (printMsg) {
+ if (location && location[0] != '\0') {
+ wpi::errs() << (isError ? "Error" : "Warning") << " at " << location
+ << ": ";
+ }
+ wpi::errs() << details << "\n";
+ if (callStack && callStack[0] != '\0') {
+ wpi::errs() << callStack << "\n";
+ }
+ }
+ 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) {
+ std::memset(controlWord, 0, sizeof(HAL_ControlWord));
+ UpdateDriverStationControlWord(false, *controlWord);
+ return 0;
+}
+
+int32_t HAL_GetJoystickAxes(int32_t joystickNum, HAL_JoystickAxes* axes) {
+ std::unique_lock<wpi::mutex> lock(m_cacheDataMutex);
+ *axes = m_joystickAxes[joystickNum];
+ return 0;
+}
+
+int32_t HAL_GetJoystickPOVs(int32_t joystickNum, HAL_JoystickPOVs* povs) {
+ std::unique_lock<wpi::mutex> lock(m_cacheDataMutex);
+ *povs = m_joystickPOVs[joystickNum];
+ return 0;
+}
+
+int32_t HAL_GetJoystickButtons(int32_t joystickNum,
+ HAL_JoystickButtons* buttons) {
+ std::unique_lock<wpi::mutex> lock(m_cacheDataMutex);
+ *buttons = m_joystickButtons[joystickNum];
+ return 0;
+}
+
+int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
+ HAL_JoystickDescriptor* desc) {
+ std::unique_lock<wpi::mutex> lock(m_cacheDataMutex);
+ *desc = m_joystickDescriptor[joystickNum];
+ return 0;
+}
+
+int32_t HAL_GetMatchInfo(HAL_MatchInfo* info) {
+ std::unique_lock<wpi::mutex> lock(m_cacheDataMutex);
+ *info = *m_matchInfo;
+ return 0;
+}
+
+HAL_AllianceStationID HAL_GetAllianceStation(int32_t* status) {
+ HAL_AllianceStationID allianceStation;
+ *status = FRC_NetworkCommunication_getAllianceStation(
+ reinterpret_cast<AllianceStationID_t*>(&allianceStation));
+ return allianceStation;
+}
+
+HAL_Bool HAL_GetJoystickIsXbox(int32_t joystickNum) {
+ HAL_JoystickDescriptor joystickDesc;
+ if (HAL_GetJoystickDescriptor(joystickNum, &joystickDesc) < 0) {
+ return 0;
+ } else {
+ return joystickDesc.isXbox;
+ }
+}
+
+int32_t HAL_GetJoystickType(int32_t joystickNum) {
+ HAL_JoystickDescriptor joystickDesc;
+ if (HAL_GetJoystickDescriptor(joystickNum, &joystickDesc) < 0) {
+ return -1;
+ } else {
+ return joystickDesc.type;
+ }
+}
+
+char* HAL_GetJoystickName(int32_t joystickNum) {
+ HAL_JoystickDescriptor joystickDesc;
+ if (HAL_GetJoystickDescriptor(joystickNum, &joystickDesc) < 0) {
+ char* name = static_cast<char*>(std::malloc(1));
+ name[0] = '\0';
+ return name;
+ } else {
+ size_t len = std::strlen(joystickDesc.name);
+ char* name = static_cast<char*>(std::malloc(len + 1));
+ std::strncpy(name, joystickDesc.name, len);
+ name[len] = '\0';
+ return name;
+ }
+}
+
+void HAL_FreeJoystickName(char* name) { std::free(name); }
+
+int32_t HAL_GetJoystickAxisType(int32_t joystickNum, int32_t axis) {
+ HAL_JoystickDescriptor joystickDesc;
+ if (HAL_GetJoystickDescriptor(joystickNum, &joystickDesc) < 0) {
+ return -1;
+ } else {
+ return joystickDesc.axisTypes[axis];
+ }
+}
+
+int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
+ int32_t leftRumble, int32_t rightRumble) {
+ return FRC_NetworkCommunication_setJoystickOutputs(joystickNum, outputs,
+ leftRumble, rightRumble);
+}
+
+double HAL_GetMatchTime(int32_t* status) {
+ float matchTime;
+ *status = FRC_NetworkCommunication_getMatchTime(&matchTime);
+ return matchTime;
+}
+
+void HAL_ObserveUserProgramStarting(void) {
+ FRC_NetworkCommunication_observeUserProgramStarting();
+}
+
+void HAL_ObserveUserProgramDisabled(void) {
+ FRC_NetworkCommunication_observeUserProgramDisabled();
+}
+
+void HAL_ObserveUserProgramAutonomous(void) {
+ FRC_NetworkCommunication_observeUserProgramAutonomous();
+}
+
+void HAL_ObserveUserProgramTeleop(void) {
+ FRC_NetworkCommunication_observeUserProgramTeleop();
+}
+
+void HAL_ObserveUserProgramTest(void) {
+ FRC_NetworkCommunication_observeUserProgramTest();
+}
+
+HAL_Bool HAL_IsNewControlData(void) {
+ // 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.
+ thread_local int lastCount{-1};
+ if (!dsThread) return false;
+ auto thr = dsThread->GetThread();
+ if (!thr) return false;
+ int currentCount = thr->newDSDataAvailableCounter;
+ if (lastCount == currentCount) return false;
+ lastCount = currentCount;
+ return true;
+}
+
+/**
+ * Waits for the newest DS packet to arrive. Note that this is a blocking call.
+ */
+void HAL_WaitForDSData(void) { HAL_WaitForDSDataTimeout(0); }
+
+/**
+ * Waits for the newest DS packet to arrive. If timeout is <= 0, this will wait
+ * forever. Otherwise, it will wait until either a new packet, or the timeout
+ * time has passed. Returns true on new data, false on timeout.
+ */
+HAL_Bool HAL_WaitForDSDataTimeout(double timeout) {
+ auto timeoutTime =
+ std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
+
+ if (!dsThread) return false;
+ auto thr = dsThread->GetThread();
+ if (!thr) return false;
+ int currentCount = thr->newDSDataAvailableCounter;
+ while (thr->newDSDataAvailableCounter == currentCount) {
+ if (timeout > 0) {
+ auto timedOut =
+ thr->newDSDataAvailableCond.wait_until(thr.GetLock(), timeoutTime);
+ if (timedOut == std::cv_status::timeout) {
+ return false;
+ }
+ } else {
+ thr->newDSDataAvailableCond.wait(thr.GetLock());
+ }
+ }
+ return true;
+}
+
+// Constant number to be used for our occur handle
+constexpr int32_t refNumber = 42;
+
+static void newDataOccur(uint32_t refNum) {
+ // Since we could get other values, require our specific handle
+ // to signal our threads
+ if (refNum != refNumber) return;
+ dsThread->Notify();
+}
+
+/*
+ * Call this to initialize the driver station communication. This will properly
+ * handle multiple calls. However note that this CANNOT be called from a library
+ * that interfaces with LabVIEW.
+ */
+void HAL_InitializeDriverStation(void) {
+ static std::atomic_bool initialized{false};
+ static wpi::mutex initializeMutex;
+ // Initial check, as if it's true initialization has finished
+ if (initialized) return;
+
+ std::lock_guard<wpi::mutex> lock(initializeMutex);
+ // Second check in case another thread was waiting
+ if (initialized) return;
+
+ InitializeDriverStationCaches();
+
+ dsThread = std::make_unique<DriverStationThreadOwner>();
+ dsThread->Start();
+
+ // Set up the occur function internally with NetComm
+ NetCommRPCProxy_SetOccurFuncPointer(newDataOccur);
+ // Set up our occur reference number
+ setNewDataOccurRef(refNumber);
+
+ initialized = true;
+}
+
+/*
+ * Releases the DS Mutex to allow proper shutdown of any threads that are
+ * waiting on it.
+ */
+void HAL_ReleaseDSMutex(void) { newDataOccur(refNumber); }
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/HAL.cpp b/hal/src/main/native/athena/HAL.cpp
new file mode 100644
index 0000000..dbdb826
--- /dev/null
+++ b/hal/src/main/native/athena/HAL.cpp
@@ -0,0 +1,410 @@
+/*----------------------------------------------------------------------------*/
+/* 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/HAL.h"
+
+#include <signal.h> // linux for kill
+#include <sys/prctl.h>
+#include <unistd.h>
+
+#include <atomic>
+#include <cstdlib>
+#include <fstream>
+#include <thread>
+
+#include <FRC_NetworkCommunication/FRCComm.h>
+#include <FRC_NetworkCommunication/LoadOut.h>
+#include <FRC_NetworkCommunication/UsageReporting.h>
+#include <wpi/mutex.h>
+#include <wpi/raw_ostream.h>
+#include <wpi/timestamp.h>
+
+#include "HALInitializer.h"
+#include "ctre/ctre.h"
+#include "hal/ChipObject.h"
+#include "hal/DriverStation.h"
+#include "hal/Errors.h"
+#include "hal/Notifier.h"
+#include "hal/handles/HandlesInternal.h"
+#include "visa/visa.h"
+
+using namespace hal;
+
+static std::unique_ptr<tGlobal> global;
+static std::unique_ptr<tSysWatchdog> watchdog;
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeHAL() {
+ InitializeAccelerometer();
+ InitializeAnalogAccumulator();
+ InitializeAnalogGyro();
+ InitializeAnalogInput();
+ InitializeAnalogInternal();
+ InitializeAnalogOutput();
+ InitializeAnalogTrigger();
+ InitializeCAN();
+ InitializeCANAPI();
+ InitializeCompressor();
+ InitializeConstants();
+ InitializeCounter();
+ InitializeDigitalInternal();
+ InitializeDIO();
+ InitializeEncoder();
+ InitializeFPGAEncoder();
+ InitializeFRCDriverStation();
+ InitializeI2C();
+ InitialzeInterrupts();
+ InitializeNotifier();
+ InitializePCMInternal();
+ InitializePDP();
+ InitializePorts();
+ InitializePower();
+ InitializePWM();
+ InitializeRelay();
+ InitializeSerialPort();
+ 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_SERIAL_PORT_NOT_FOUND:
+ return HAL_SERIAL_PORT_NOT_FOUND_MESSAGE;
+ case HAL_THREAD_PRIORITY_ERROR:
+ return HAL_THREAD_PRIORITY_ERROR_MESSAGE;
+ case HAL_THREAD_PRIORITY_RANGE_ERROR:
+ return HAL_THREAD_PRIORITY_RANGE_ERROR_MESSAGE;
+ case HAL_SERIAL_PORT_OPEN_ERROR:
+ return HAL_SERIAL_PORT_OPEN_ERROR_MESSAGE;
+ case HAL_SERIAL_PORT_ERROR:
+ return HAL_SERIAL_PORT_ERROR_MESSAGE;
+ case HAL_CAN_TIMEOUT:
+ return HAL_CAN_TIMEOUT_MESSAGE;
+ case ERR_FRCSystem_NetCommNotResponding:
+ return ERR_FRCSystem_NetCommNotResponding_MESSAGE;
+ case ERR_FRCSystem_NoDSConnection:
+ return ERR_FRCSystem_NoDSConnection_MESSAGE;
+ default:
+ return "Unknown error status";
+ }
+}
+
+HAL_RuntimeType HAL_GetRuntimeType(void) { return HAL_Athena; }
+
+int32_t HAL_GetFPGAVersion(int32_t* status) {
+ if (!global) {
+ *status = NiFpga_Status_ResourceNotInitialized;
+ return 0;
+ }
+ return global->readVersion(status);
+}
+
+int64_t HAL_GetFPGARevision(int32_t* status) {
+ if (!global) {
+ *status = NiFpga_Status_ResourceNotInitialized;
+ return 0;
+ }
+ return global->readRevision(status);
+}
+
+uint64_t HAL_GetFPGATime(int32_t* status) {
+ if (!global) {
+ *status = NiFpga_Status_ResourceNotInitialized;
+ return 0;
+ }
+ *status = 0;
+ uint64_t upper1 = global->readLocalTimeUpper(status);
+ uint32_t lower = global->readLocalTime(status);
+ uint64_t upper2 = global->readLocalTimeUpper(status);
+ if (*status != 0) return 0;
+ if (upper1 != upper2) {
+ // Rolled over between the lower call, reread lower
+ lower = global->readLocalTime(status);
+ if (*status != 0) return 0;
+ }
+ return (upper2 << 32) + lower;
+}
+
+HAL_Bool HAL_GetFPGAButton(int32_t* status) {
+ if (!global) {
+ *status = NiFpga_Status_ResourceNotInitialized;
+ return false;
+ }
+ return global->readUserButton(status);
+}
+
+HAL_Bool HAL_GetSystemActive(int32_t* status) {
+ if (!watchdog) {
+ *status = NiFpga_Status_ResourceNotInitialized;
+ return false;
+ }
+ return watchdog->readStatus_SystemActive(status);
+}
+
+HAL_Bool HAL_GetBrownedOut(int32_t* status) {
+ if (!watchdog) {
+ *status = NiFpga_Status_ResourceNotInitialized;
+ return false;
+ }
+ return !(watchdog->readStatus_PowerAlive(status));
+}
+
+void HAL_BaseInitialize(int32_t* status) {
+ static std::atomic_bool initialized{false};
+ static wpi::mutex initializeMutex;
+ // Initial check, as if it's true initialization has finished
+ if (initialized) return;
+
+ std::lock_guard<wpi::mutex> lock(initializeMutex);
+ // Second check in case another thread was waiting
+ if (initialized) return;
+ // image 4; Fixes errors caused by multiple processes. Talk to NI about this
+ nFPGA::nRoboRIO_FPGANamespace::g_currentTargetClass =
+ nLoadOut::kTargetClass_RoboRIO;
+
+ global.reset(tGlobal::create(status));
+ watchdog.reset(tSysWatchdog::create(status));
+ initialized = true;
+}
+
+static bool killExistingProgram(int timeout, int mode) {
+ // Kill any previous robot programs
+ std::fstream fs;
+ // By making this both in/out, it won't give us an error if it doesnt exist
+ fs.open("/var/lock/frc.pid", std::fstream::in | std::fstream::out);
+ if (fs.bad()) return false;
+
+ pid_t pid = 0;
+ if (!fs.eof() && !fs.fail()) {
+ fs >> pid;
+ // see if the pid is around, but we don't want to mess with init id=1, or
+ // ourselves
+ if (pid >= 2 && kill(pid, 0) == 0 && pid != getpid()) {
+ wpi::outs() << "Killing previously running FRC program...\n";
+ kill(pid, SIGTERM); // try to kill it
+ std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
+ if (kill(pid, 0) == 0) {
+ // still not successfull
+ wpi::outs() << "FRC pid " << pid << " did not die within " << timeout
+ << "ms. Force killing with kill -9\n";
+ // Force kill -9
+ auto forceKill = kill(pid, SIGKILL);
+ if (forceKill != 0) {
+ auto errorMsg = std::strerror(forceKill);
+ wpi::outs() << "Kill -9 error: " << errorMsg << "\n";
+ }
+ // Give a bit of time for the kill to take place
+ std::this_thread::sleep_for(std::chrono::milliseconds(250));
+ }
+ }
+ }
+ fs.close();
+ // we will re-open it write only to truncate the file
+ fs.open("/var/lock/frc.pid", std::fstream::out | std::fstream::trunc);
+ fs.seekp(0);
+ pid = getpid();
+ fs << pid << std::endl;
+ fs.close();
+ return true;
+}
+
+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::lock_guard<wpi::mutex> lock(initializeMutex);
+ // Second check in case another thread was waiting
+ if (initialized) return true;
+
+ hal::init::InitializeHAL();
+
+ hal::init::HAL_IsInitialized.store(true);
+
+ setlinebuf(stdin);
+ setlinebuf(stdout);
+ wpi::outs().SetUnbuffered();
+
+ prctl(PR_SET_PDEATHSIG, SIGTERM);
+
+ // Return false if program failed to kill an existing program
+ if (!killExistingProgram(timeout, mode)) {
+ return false;
+ }
+
+ FRC_NetworkCommunication_Reserve(nullptr);
+
+ std::atexit([]() {
+ // Unregister our new data condition variable.
+ setNewDataSem(nullptr);
+ });
+
+ int32_t status = 0;
+ HAL_BaseInitialize(&status);
+ if (status != 0) return false;
+
+ HAL_InitializeDriverStation();
+
+ // Set WPI_Now to use FPGA timestamp
+ wpi::SetNowImpl([]() -> uint64_t {
+ int32_t status = 0;
+ uint64_t rv = HAL_GetFPGATime(&status);
+ if (status != 0) {
+ wpi::errs()
+ << "Call to HAL_GetFPGATime failed."
+ << "Initialization might have failed. Time will not be correct\n";
+ wpi::errs().flush();
+ return 0u;
+ }
+ return rv;
+ });
+
+ initialized = true;
+ return true;
+}
+
+int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
+ const char* feature) {
+ if (feature == nullptr) {
+ feature = "";
+ }
+
+ return FRC_NetworkCommunication_nUsageReporting_report(
+ resource, instanceNumber, context, feature);
+}
+
+// TODO: HACKS
+// No need for header definitions, as we should not run from user code.
+void NumericArrayResize(void) {}
+void RTSetCleanupProc(void) {}
+void EDVR_CreateReference(void) {}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/HALInitializer.cpp b/hal/src/main/native/athena/HALInitializer.cpp
new file mode 100644
index 0000000..a0456d4
--- /dev/null
+++ b/hal/src/main/native/athena/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/athena/HALInitializer.h b/hal/src/main/native/athena/HALInitializer.h
new file mode 100644
index 0000000..384fe58
--- /dev/null
+++ b/hal/src/main/native/athena/HALInitializer.h
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+#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 InitializeAccelerometer();
+extern void InitializeAnalogAccumulator();
+extern void InitializeAnalogGyro();
+extern void InitializeAnalogInput();
+extern void InitializeAnalogInternal();
+extern void InitializeAnalogOutput();
+extern void InitializeAnalogTrigger();
+extern void InitializeCAN();
+extern void InitializeCANAPI();
+extern void InitializeCompressor();
+extern void InitializeConstants();
+extern void InitializeCounter();
+extern void InitializeDigitalInternal();
+extern void InitializeDIO();
+extern void InitializeEncoder();
+extern void InitializeFPGAEncoder();
+extern void InitializeFRCDriverStation();
+extern void InitializeHAL();
+extern void InitializeI2C();
+extern void InitialzeInterrupts();
+extern void InitializeNotifier();
+extern void InitializePCMInternal();
+extern void InitializePDP();
+extern void InitializePorts();
+extern void InitializePower();
+extern void InitializePWM();
+extern void InitializeRelay();
+extern void InitializeSerialPort();
+extern void InitializeSolenoid();
+extern void InitializeSPI();
+extern void InitializeThreads();
+} // namespace init
+} // namespace hal
diff --git a/hal/src/main/native/athena/I2C.cpp b/hal/src/main/native/athena/I2C.cpp
new file mode 100644
index 0000000..907906e
--- /dev/null
+++ b/hal/src/main/native/athena/I2C.cpp
@@ -0,0 +1,192 @@
+/*----------------------------------------------------------------------------*/
+/* 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/I2C.h"
+
+#include <fcntl.h>
+#include <linux/i2c-dev.h>
+#include <linux/i2c.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <cstring>
+
+#include "DigitalInternal.h"
+#include "HALInitializer.h"
+#include "hal/DIO.h"
+#include "hal/HAL.h"
+
+using namespace hal;
+
+static wpi::mutex digitalI2COnBoardMutex;
+static wpi::mutex digitalI2CMXPMutex;
+
+static uint8_t i2COnboardObjCount{0};
+static uint8_t i2CMXPObjCount{0};
+static int i2COnBoardHandle{-1};
+static int i2CMXPHandle{-1};
+
+static HAL_DigitalHandle i2CMXPDigitalHandle1{HAL_kInvalidHandle};
+static HAL_DigitalHandle i2CMXPDigitalHandle2{HAL_kInvalidHandle};
+
+namespace hal {
+namespace init {
+void InitializeI2C() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
+ hal::init::CheckInit();
+ initializeDigital(status);
+ if (*status != 0) return;
+
+ if (port < 0 || port > 1) {
+ // Set port out of range error here
+ return;
+ }
+
+ if (port == HAL_I2C_kOnboard) {
+ std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
+ i2COnboardObjCount++;
+ if (i2COnboardObjCount > 1) return;
+ int handle = open("/dev/i2c-2", O_RDWR);
+ if (handle < 0) {
+ std::printf("Failed to open onboard i2c bus: %s\n", std::strerror(errno));
+ return;
+ }
+ i2COnBoardHandle = handle;
+ } else {
+ std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
+ i2CMXPObjCount++;
+ if (i2CMXPObjCount > 1) return;
+ if ((i2CMXPDigitalHandle1 = HAL_InitializeDIOPort(
+ HAL_GetPort(24), false, status)) == HAL_kInvalidHandle) {
+ return;
+ }
+ if ((i2CMXPDigitalHandle2 = HAL_InitializeDIOPort(
+ HAL_GetPort(25), false, status)) == HAL_kInvalidHandle) {
+ HAL_FreeDIOPort(i2CMXPDigitalHandle1); // free the first port allocated
+ return;
+ }
+ digitalSystem->writeEnableMXPSpecialFunction(
+ digitalSystem->readEnableMXPSpecialFunction(status) | 0xC000, status);
+ int handle = open("/dev/i2c-1", O_RDWR);
+ if (handle < 0) {
+ std::printf("Failed to open MXP i2c bus: %s\n", std::strerror(errno));
+ return;
+ }
+ i2CMXPHandle = handle;
+ }
+}
+
+int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
+ const uint8_t* dataToSend, int32_t sendSize,
+ uint8_t* dataReceived, int32_t receiveSize) {
+ if (port < 0 || port > 1) {
+ // Set port out of range error here
+ return -1;
+ }
+
+ struct i2c_msg msgs[2];
+ msgs[0].addr = deviceAddress;
+ msgs[0].flags = 0;
+ msgs[0].len = sendSize;
+ msgs[0].buf = const_cast<uint8_t*>(dataToSend);
+ msgs[1].addr = deviceAddress;
+ msgs[1].flags = I2C_M_RD;
+ msgs[1].len = receiveSize;
+ msgs[1].buf = dataReceived;
+
+ struct i2c_rdwr_ioctl_data rdwr;
+ rdwr.msgs = msgs;
+ rdwr.nmsgs = 2;
+
+ if (port == HAL_I2C_kOnboard) {
+ std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
+ return ioctl(i2COnBoardHandle, I2C_RDWR, &rdwr);
+ } else {
+ std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
+ return ioctl(i2CMXPHandle, I2C_RDWR, &rdwr);
+ }
+}
+
+int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress,
+ const uint8_t* dataToSend, int32_t sendSize) {
+ if (port < 0 || port > 1) {
+ // Set port out of range error here
+ return -1;
+ }
+
+ struct i2c_msg msg;
+ msg.addr = deviceAddress;
+ msg.flags = 0;
+ msg.len = sendSize;
+ msg.buf = const_cast<uint8_t*>(dataToSend);
+
+ struct i2c_rdwr_ioctl_data rdwr;
+ rdwr.msgs = &msg;
+ rdwr.nmsgs = 1;
+
+ if (port == HAL_I2C_kOnboard) {
+ std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
+ return ioctl(i2COnBoardHandle, I2C_RDWR, &rdwr);
+ } else {
+ std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
+ return ioctl(i2CMXPHandle, I2C_RDWR, &rdwr);
+ }
+}
+
+int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer,
+ int32_t count) {
+ if (port < 0 || port > 1) {
+ // Set port out of range error here
+ return -1;
+ }
+
+ struct i2c_msg msg;
+ msg.addr = deviceAddress;
+ msg.flags = I2C_M_RD;
+ msg.len = count;
+ msg.buf = buffer;
+
+ struct i2c_rdwr_ioctl_data rdwr;
+ rdwr.msgs = &msg;
+ rdwr.nmsgs = 1;
+
+ if (port == HAL_I2C_kOnboard) {
+ std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
+ return ioctl(i2COnBoardHandle, I2C_RDWR, &rdwr);
+ } else {
+ std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
+ return ioctl(i2CMXPHandle, I2C_RDWR, &rdwr);
+ }
+}
+
+void HAL_CloseI2C(HAL_I2CPort port) {
+ if (port < 0 || port > 1) {
+ // Set port out of range error here
+ return;
+ }
+
+ if (port == HAL_I2C_kOnboard) {
+ std::lock_guard<wpi::mutex> lock(digitalI2COnBoardMutex);
+ if (i2COnboardObjCount-- == 0) {
+ close(i2COnBoardHandle);
+ }
+ } else {
+ std::lock_guard<wpi::mutex> lock(digitalI2CMXPMutex);
+ if (i2CMXPObjCount-- == 0) {
+ close(i2CMXPHandle);
+ }
+ HAL_FreeDIOPort(i2CMXPDigitalHandle1);
+ HAL_FreeDIOPort(i2CMXPDigitalHandle2);
+ }
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/Interrupts.cpp b/hal/src/main/native/athena/Interrupts.cpp
new file mode 100644
index 0000000..c661da4
--- /dev/null
+++ b/hal/src/main/native/athena/Interrupts.cpp
@@ -0,0 +1,262 @@
+/*----------------------------------------------------------------------------*/
+/* 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/Interrupts.h"
+
+#include <memory>
+
+#include <wpi/SafeThread.h>
+
+#include "DigitalInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/ChipObject.h"
+#include "hal/Errors.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/LimitedHandleResource.h"
+
+using namespace hal;
+
+namespace {
+// Safe thread to allow callbacks to run on their own thread
+class InterruptThread : public wpi::SafeThread {
+ public:
+ void Main() {
+ std::unique_lock<wpi::mutex> lock(m_mutex);
+ while (m_active) {
+ m_cond.wait(lock, [&] { return !m_active || m_notify; });
+ if (!m_active) break;
+ m_notify = false;
+ HAL_InterruptHandlerFunction handler = m_handler;
+ uint32_t mask = m_mask;
+ void* param = m_param;
+ lock.unlock(); // don't hold mutex during callback execution
+ handler(mask, param);
+ lock.lock();
+ }
+ }
+
+ bool m_notify = false;
+ HAL_InterruptHandlerFunction m_handler;
+ void* m_param;
+ uint32_t m_mask;
+};
+
+class InterruptThreadOwner : public wpi::SafeThreadOwner<InterruptThread> {
+ public:
+ void SetFunc(HAL_InterruptHandlerFunction handler, void* param) {
+ auto thr = GetThread();
+ if (!thr) return;
+ thr->m_handler = handler;
+ thr->m_param = param;
+ }
+
+ void Notify(uint32_t mask) {
+ auto thr = GetThread();
+ if (!thr) return;
+ thr->m_mask = mask;
+ thr->m_notify = true;
+ thr->m_cond.notify_one();
+ }
+};
+
+} // namespace
+
+static void threadedInterruptHandler(uint32_t mask, void* param) {
+ static_cast<InterruptThreadOwner*>(param)->Notify(mask);
+}
+
+struct Interrupt {
+ std::unique_ptr<tInterrupt> anInterrupt;
+ std::unique_ptr<tInterruptManager> manager;
+ std::unique_ptr<InterruptThreadOwner> threadOwner = nullptr;
+ void* param = nullptr;
+};
+
+static LimitedHandleResource<HAL_InterruptHandle, Interrupt, kNumInterrupts,
+ HAL_HandleEnum::Interrupt>* interruptHandles;
+
+namespace hal {
+namespace init {
+void InitialzeInterrupts() {
+ static LimitedHandleResource<HAL_InterruptHandle, Interrupt, kNumInterrupts,
+ HAL_HandleEnum::Interrupt>
+ iH;
+ interruptHandles = &iH;
+}
+} // 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);
+ uint32_t interruptIndex = static_cast<uint32_t>(getHandleIndex(handle));
+ // Expects the calling leaf class to allocate an interrupt index.
+ anInterrupt->anInterrupt.reset(tInterrupt::create(interruptIndex, status));
+ anInterrupt->anInterrupt->writeConfig_WaitForAck(false, status);
+ anInterrupt->manager = std::make_unique<tInterruptManager>(
+ (1u << interruptIndex) | (1u << (interruptIndex + 8u)), watcher, status);
+ return handle;
+}
+
+void* HAL_CleanInterrupts(HAL_InterruptHandle interruptHandle,
+ int32_t* status) {
+ auto anInterrupt = interruptHandles->Get(interruptHandle);
+ interruptHandles->Free(interruptHandle);
+ if (anInterrupt == nullptr) {
+ return nullptr;
+ }
+ anInterrupt->manager->enable(status);
+ void* param = anInterrupt->param;
+ return param;
+}
+
+int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
+ double timeout, HAL_Bool ignorePrevious,
+ int32_t* status) {
+ uint32_t result;
+ auto anInterrupt = interruptHandles->Get(interruptHandle);
+ if (anInterrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+
+ result = anInterrupt->manager->watch(static_cast<int32_t>(timeout * 1e3),
+ ignorePrevious, status);
+
+ // Don't report a timeout as an error - the return code is enough to tell
+ // that a timeout happened.
+ if (*status == -NiFpga_Status_IrqTimeout) {
+ *status = NiFpga_Status_Success;
+ }
+
+ return result;
+}
+
+void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle,
+ int32_t* status) {
+ auto anInterrupt = interruptHandles->Get(interruptHandle);
+ if (anInterrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ anInterrupt->manager->enable(status);
+}
+
+void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
+ int32_t* status) {
+ auto anInterrupt = interruptHandles->Get(interruptHandle);
+ if (anInterrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ anInterrupt->manager->disable(status);
+}
+
+int64_t HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
+ int32_t* status) {
+ auto anInterrupt = interruptHandles->Get(interruptHandle);
+ if (anInterrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ uint32_t timestamp = anInterrupt->anInterrupt->readRisingTimeStamp(status);
+ return timestamp;
+}
+
+int64_t HAL_ReadInterruptFallingTimestamp(HAL_InterruptHandle interruptHandle,
+ int32_t* status) {
+ auto anInterrupt = interruptHandles->Get(interruptHandle);
+ if (anInterrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return 0;
+ }
+ uint32_t timestamp = anInterrupt->anInterrupt->readFallingTimeStamp(status);
+ return timestamp;
+}
+
+void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ int32_t* status) {
+ auto anInterrupt = interruptHandles->Get(interruptHandle);
+ if (anInterrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ anInterrupt->anInterrupt->writeConfig_WaitForAck(false, status);
+ 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;
+ }
+ anInterrupt->anInterrupt->writeConfig_Source_AnalogTrigger(
+ routingAnalogTrigger, status);
+ anInterrupt->anInterrupt->writeConfig_Source_Channel(routingChannel, status);
+ anInterrupt->anInterrupt->writeConfig_Source_Module(routingModule, status);
+}
+
+void HAL_AttachInterruptHandler(HAL_InterruptHandle interruptHandle,
+ HAL_InterruptHandlerFunction handler,
+ void* param, int32_t* status) {
+ auto anInterrupt = interruptHandles->Get(interruptHandle);
+ if (anInterrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ anInterrupt->manager->registerHandler(handler, param, status);
+ anInterrupt->param = param;
+}
+
+void HAL_AttachInterruptHandlerThreaded(HAL_InterruptHandle interrupt_handle,
+ HAL_InterruptHandlerFunction handler,
+ void* param, int32_t* status) {
+ auto anInterrupt = interruptHandles->Get(interrupt_handle);
+ if (anInterrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ anInterrupt->threadOwner = std::make_unique<InterruptThreadOwner>();
+ anInterrupt->threadOwner->Start();
+ anInterrupt->threadOwner->SetFunc(handler, param);
+
+ HAL_AttachInterruptHandler(interrupt_handle, threadedInterruptHandler,
+ anInterrupt->threadOwner.get(), status);
+
+ if (*status != 0) {
+ anInterrupt->threadOwner = nullptr;
+ }
+ anInterrupt->param = param;
+}
+
+void HAL_SetInterruptUpSourceEdge(HAL_InterruptHandle interruptHandle,
+ HAL_Bool risingEdge, HAL_Bool fallingEdge,
+ int32_t* status) {
+ auto anInterrupt = interruptHandles->Get(interruptHandle);
+ if (anInterrupt == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ anInterrupt->anInterrupt->writeConfig_RisingEdge(risingEdge, status);
+ anInterrupt->anInterrupt->writeConfig_FallingEdge(fallingEdge, status);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/Notifier.cpp b/hal/src/main/native/athena/Notifier.cpp
new file mode 100644
index 0000000..c457cd1
--- /dev/null
+++ b/hal/src/main/native/athena/Notifier.cpp
@@ -0,0 +1,233 @@
+/*----------------------------------------------------------------------------*/
+/* 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/Notifier.h"
+
+#include <atomic>
+#include <cstdlib> // For std::atexit()
+#include <memory>
+
+#include <wpi/condition_variable.h>
+#include <wpi/mutex.h>
+
+#include "HALInitializer.h"
+#include "hal/ChipObject.h"
+#include "hal/Errors.h"
+#include "hal/HAL.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+
+using namespace hal;
+
+static constexpr int32_t kTimerInterruptNumber = 28;
+
+static wpi::mutex notifierMutex;
+static std::unique_ptr<tAlarm> notifierAlarm;
+static std::unique_ptr<tInterruptManager> notifierManager;
+static uint64_t closestTrigger{UINT64_MAX};
+
+namespace {
+
+struct Notifier {
+ uint64_t triggerTime = UINT64_MAX;
+ uint64_t triggeredTime = UINT64_MAX;
+ bool active = true;
+ wpi::mutex mutex;
+ wpi::condition_variable cond;
+};
+
+} // namespace
+
+static std::atomic_flag notifierAtexitRegistered{ATOMIC_FLAG_INIT};
+static std::atomic_int notifierRefCount{0};
+
+using namespace hal;
+
+class NotifierHandleContainer
+ : public UnlimitedHandleResource<HAL_NotifierHandle, Notifier,
+ HAL_HandleEnum::Notifier> {
+ public:
+ ~NotifierHandleContainer() {
+ ForEach([](HAL_NotifierHandle handle, Notifier* notifier) {
+ {
+ std::lock_guard<wpi::mutex> lock(notifier->mutex);
+ notifier->triggerTime = UINT64_MAX;
+ notifier->triggeredTime = 0;
+ notifier->active = false;
+ }
+ notifier->cond.notify_all(); // wake up any waiting threads
+ });
+ }
+};
+
+static NotifierHandleContainer* notifierHandles;
+
+static void alarmCallback(uint32_t, void*) {
+ std::lock_guard<wpi::mutex> lock(notifierMutex);
+ int32_t status = 0;
+ uint64_t currentTime = 0;
+
+ // the hardware disables itself after each alarm
+ closestTrigger = UINT64_MAX;
+
+ // process all notifiers
+ notifierHandles->ForEach([&](HAL_NotifierHandle handle, Notifier* notifier) {
+ if (notifier->triggerTime == UINT64_MAX) return;
+ if (currentTime == 0) currentTime = HAL_GetFPGATime(&status);
+ std::unique_lock<wpi::mutex> lock(notifier->mutex);
+ if (notifier->triggerTime < currentTime) {
+ notifier->triggerTime = UINT64_MAX;
+ notifier->triggeredTime = currentTime;
+ lock.unlock();
+ notifier->cond.notify_all();
+ } else if (notifier->triggerTime < closestTrigger) {
+ closestTrigger = notifier->triggerTime;
+ }
+ });
+
+ if (notifierAlarm && closestTrigger != UINT64_MAX) {
+ // Simply truncate the hardware trigger time to 32-bit.
+ notifierAlarm->writeTriggerTime(static_cast<uint32_t>(closestTrigger),
+ &status);
+ // Enable the alarm. The hardware disables itself after each alarm.
+ notifierAlarm->writeEnable(true, &status);
+ }
+}
+
+static void cleanupNotifierAtExit() {
+ notifierAlarm = nullptr;
+ notifierManager = nullptr;
+}
+
+namespace hal {
+namespace init {
+void InitializeNotifier() {
+ static NotifierHandleContainer nH;
+ notifierHandles = &nH;
+}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+HAL_NotifierHandle HAL_InitializeNotifier(int32_t* status) {
+ hal::init::CheckInit();
+ if (!notifierAtexitRegistered.test_and_set())
+ std::atexit(cleanupNotifierAtExit);
+
+ if (notifierRefCount.fetch_add(1) == 0) {
+ std::lock_guard<wpi::mutex> lock(notifierMutex);
+ // create manager and alarm if not already created
+ if (!notifierManager) {
+ notifierManager = std::make_unique<tInterruptManager>(
+ 1 << kTimerInterruptNumber, false, status);
+ notifierManager->registerHandler(alarmCallback, nullptr, status);
+ notifierManager->enable(status);
+ }
+ if (!notifierAlarm) notifierAlarm.reset(tAlarm::create(status));
+ }
+
+ 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_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) {
+ auto notifier = notifierHandles->Get(notifierHandle);
+ if (!notifier) return;
+
+ {
+ std::lock_guard<wpi::mutex> lock(notifier->mutex);
+ notifier->triggerTime = UINT64_MAX;
+ notifier->triggeredTime = 0;
+ notifier->active = false;
+ }
+ notifier->cond.notify_all(); // wake up any waiting threads
+}
+
+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::lock_guard<wpi::mutex> lock(notifier->mutex);
+ notifier->triggerTime = UINT64_MAX;
+ notifier->triggeredTime = 0;
+ notifier->active = false;
+ }
+ notifier->cond.notify_all();
+
+ if (notifierRefCount.fetch_sub(1) == 1) {
+ // if this was the last notifier, clean up alarm and manager
+ // the notifier can call back into our callback, so don't hold the lock
+ // here (the atomic fetch_sub will prevent multiple parallel entries
+ // into this function)
+
+ // Cleaning up the manager takes up to a second to complete, so don't do
+ // that here. Fix it more permanently in 2019...
+
+ // if (notifierAlarm) notifierAlarm->writeEnable(false, status);
+ // if (notifierManager) notifierManager->disable(status);
+
+ // std::lock_guard<wpi::mutex> lock(notifierMutex);
+ // notifierAlarm = nullptr;
+ // notifierManager = nullptr;
+ // closestTrigger = UINT64_MAX;
+ }
+}
+
+void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
+ uint64_t triggerTime, int32_t* status) {
+ auto notifier = notifierHandles->Get(notifierHandle);
+ if (!notifier) return;
+
+ {
+ std::lock_guard<wpi::mutex> lock(notifier->mutex);
+ notifier->triggerTime = triggerTime;
+ notifier->triggeredTime = UINT64_MAX;
+ }
+
+ std::lock_guard<wpi::mutex> lock(notifierMutex);
+ // Update alarm time if closer than current.
+ if (triggerTime < closestTrigger) {
+ bool wasActive = (closestTrigger != UINT64_MAX);
+ closestTrigger = triggerTime;
+ // Simply truncate the hardware trigger time to 32-bit.
+ notifierAlarm->writeTriggerTime(static_cast<uint32_t>(closestTrigger),
+ status);
+ // Enable the alarm.
+ if (!wasActive) notifierAlarm->writeEnable(true, status);
+ }
+}
+
+void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
+ int32_t* status) {
+ auto notifier = notifierHandles->Get(notifierHandle);
+ if (!notifier) return;
+
+ {
+ std::lock_guard<wpi::mutex> lock(notifier->mutex);
+ notifier->triggerTime = UINT64_MAX;
+ }
+}
+
+uint64_t HAL_WaitForNotifierAlarm(HAL_NotifierHandle notifierHandle,
+ int32_t* status) {
+ auto notifier = notifierHandles->Get(notifierHandle);
+ if (!notifier) return 0;
+ std::unique_lock<wpi::mutex> lock(notifier->mutex);
+ notifier->cond.wait(lock, [&] {
+ return !notifier->active || notifier->triggeredTime != UINT64_MAX;
+ });
+ return notifier->active ? notifier->triggeredTime : 0;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/PCMInternal.cpp b/hal/src/main/native/athena/PCMInternal.cpp
new file mode 100644
index 0000000..dee64cf
--- /dev/null
+++ b/hal/src/main/native/athena/PCMInternal.cpp
@@ -0,0 +1,38 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "PCMInternal.h"
+
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/Errors.h"
+#include "hal/Solenoid.h"
+
+namespace hal {
+
+std::unique_ptr<PCM> PCM_modules[kNumPCMModules];
+
+namespace init {
+void InitializePCMInternal() {
+ for (int i = 0; i < kNumPCMModules; i++) {
+ PCM_modules[i] = nullptr;
+ }
+}
+} // namespace init
+
+void initializePCM(int32_t module, int32_t* status) {
+ hal::init::CheckInit();
+ if (!HAL_CheckSolenoidModule(module)) {
+ *status = RESOURCE_OUT_OF_RANGE;
+ return;
+ }
+ if (!PCM_modules[module]) {
+ PCM_modules[module] = std::make_unique<PCM>(module);
+ }
+}
+
+} // namespace hal
diff --git a/hal/src/main/native/athena/PCMInternal.h b/hal/src/main/native/athena/PCMInternal.h
new file mode 100644
index 0000000..52f0f75
--- /dev/null
+++ b/hal/src/main/native/athena/PCMInternal.h
@@ -0,0 +1,38 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "ctre/PCM.h"
+#include "hal/Errors.h"
+#include "hal/Ports.h"
+#include "hal/Solenoid.h"
+
+namespace hal {
+
+extern std::unique_ptr<PCM> PCM_modules[kNumPCMModules];
+
+static inline bool checkPCMInit(int32_t module, int32_t* status) {
+ if (!HAL_CheckSolenoidModule(module)) {
+ *status = RESOURCE_OUT_OF_RANGE;
+ return false;
+ }
+ if (!PCM_modules[module]) {
+ *status = INCOMPATIBLE_STATE;
+ return false;
+ }
+ return true;
+}
+
+void initializePCM(int32_t module, int32_t* status);
+
+} // namespace hal
diff --git a/hal/src/main/native/athena/PDP.cpp b/hal/src/main/native/athena/PDP.cpp
new file mode 100644
index 0000000..ff1eb81
--- /dev/null
+++ b/hal/src/main/native/athena/PDP.cpp
@@ -0,0 +1,341 @@
+/*----------------------------------------------------------------------------*/
+/* 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/PDP.h"
+
+#include <memory>
+
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/CANAPI.h"
+#include "hal/Errors.h"
+#include "hal/Ports.h"
+#include "hal/handles/IndexedHandleResource.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;
+
+static constexpr int32_t Status1 = 0x50;
+static constexpr int32_t Status2 = 0x51;
+static constexpr int32_t Status3 = 0x52;
+static constexpr int32_t StatusEnergy = 0x5D;
+
+static constexpr int32_t Control1 = 0x70;
+
+static constexpr int32_t TimeoutMs = 100;
+static constexpr int32_t StatusPeriodMs = 25;
+
+/* encoder/decoders */
+union PdpStatus1 {
+ uint8_t data[8];
+ struct Bits {
+ unsigned chan1_h8 : 8;
+ unsigned chan2_h6 : 6;
+ unsigned chan1_l2 : 2;
+ unsigned chan3_h4 : 4;
+ unsigned chan2_l4 : 4;
+ unsigned chan4_h2 : 2;
+ unsigned chan3_l6 : 6;
+ unsigned chan4_l8 : 8;
+ unsigned chan5_h8 : 8;
+ unsigned chan6_h6 : 6;
+ unsigned chan5_l2 : 2;
+ unsigned reserved4 : 4;
+ unsigned chan6_l4 : 4;
+ } bits;
+};
+
+union PdpStatus2 {
+ uint8_t data[8];
+ struct Bits {
+ unsigned chan7_h8 : 8;
+ unsigned chan8_h6 : 6;
+ unsigned chan7_l2 : 2;
+ unsigned chan9_h4 : 4;
+ unsigned chan8_l4 : 4;
+ unsigned chan10_h2 : 2;
+ unsigned chan9_l6 : 6;
+ unsigned chan10_l8 : 8;
+ unsigned chan11_h8 : 8;
+ unsigned chan12_h6 : 6;
+ unsigned chan11_l2 : 2;
+ unsigned reserved4 : 4;
+ unsigned chan12_l4 : 4;
+ } bits;
+};
+
+union PdpStatus3 {
+ uint8_t data[8];
+ struct Bits {
+ unsigned chan13_h8 : 8;
+ unsigned chan14_h6 : 6;
+ unsigned chan13_l2 : 2;
+ unsigned chan15_h4 : 4;
+ unsigned chan14_l4 : 4;
+ unsigned chan16_h2 : 2;
+ unsigned chan15_l6 : 6;
+ unsigned chan16_l8 : 8;
+ unsigned internalResBattery_mOhms : 8;
+ unsigned busVoltage : 8;
+ unsigned temp : 8;
+ } bits;
+};
+
+union PdpStatusEnergy {
+ uint8_t data[8];
+ struct Bits {
+ unsigned TmeasMs_likelywillbe20ms_ : 8;
+ unsigned TotalCurrent_125mAperunit_h8 : 8;
+ unsigned Power_125mWperunit_h4 : 4;
+ unsigned TotalCurrent_125mAperunit_l4 : 4;
+ unsigned Power_125mWperunit_m8 : 8;
+ unsigned Energy_125mWPerUnitXTmeas_h4 : 4;
+ unsigned Power_125mWperunit_l4 : 4;
+ unsigned Energy_125mWPerUnitXTmeas_mh8 : 8;
+ unsigned Energy_125mWPerUnitXTmeas_ml8 : 8;
+ unsigned Energy_125mWPerUnitXTmeas_l8 : 8;
+ } bits;
+};
+
+namespace hal {
+namespace init {
+void InitializePDP() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+HAL_PDPHandle HAL_InitializePDP(int32_t module, int32_t* status) {
+ hal::init::CheckInit();
+ if (!HAL_CheckPDPModule(module)) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+
+ auto handle = HAL_InitializeCAN(manufacturer, module, deviceType, status);
+
+ if (*status != 0) {
+ HAL_CleanCAN(handle);
+ return HAL_kInvalidHandle;
+ }
+
+ return handle;
+}
+
+void HAL_CleanPDP(HAL_PDPHandle handle) { HAL_CleanCAN(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;
+}
+
+double HAL_GetPDPTemperature(HAL_PDPHandle handle, int32_t* status) {
+ PdpStatus3 pdpStatus;
+ int32_t length = 0;
+ uint64_t receivedTimestamp = 0;
+
+ HAL_ReadCANPeriodicPacket(handle, Status3, pdpStatus.data, &length,
+ &receivedTimestamp, TimeoutMs, StatusPeriodMs,
+ status);
+
+ return pdpStatus.bits.temp * 1.03250836957542 - 67.8564500484966;
+}
+
+double HAL_GetPDPVoltage(HAL_PDPHandle handle, int32_t* status) {
+ PdpStatus3 pdpStatus;
+ int32_t length = 0;
+ uint64_t receivedTimestamp = 0;
+
+ HAL_ReadCANPeriodicPacket(handle, Status3, pdpStatus.data, &length,
+ &receivedTimestamp, TimeoutMs, StatusPeriodMs,
+ status);
+
+ return pdpStatus.bits.busVoltage * 0.05 + 4.0; /* 50mV per unit plus 4V. */
+}
+
+double HAL_GetPDPChannelCurrent(HAL_PDPHandle handle, int32_t channel,
+ int32_t* status) {
+ if (!HAL_CheckPDPChannel(channel)) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return 0;
+ }
+
+ int32_t length = 0;
+ uint64_t receivedTimestamp = 0;
+
+ double raw = 0;
+
+ if (channel <= 5) {
+ PdpStatus1 pdpStatus;
+ HAL_ReadCANPeriodicPacket(handle, Status1, pdpStatus.data, &length,
+ &receivedTimestamp, TimeoutMs, StatusPeriodMs,
+ status);
+ switch (channel) {
+ case 0:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan1_h8) << 2) |
+ pdpStatus.bits.chan1_l2;
+ break;
+ case 1:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan2_h6) << 4) |
+ pdpStatus.bits.chan2_l4;
+ break;
+ case 2:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan3_h4) << 6) |
+ pdpStatus.bits.chan3_l6;
+ break;
+ case 3:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan4_h2) << 8) |
+ pdpStatus.bits.chan4_l8;
+ break;
+ case 4:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan5_h8) << 2) |
+ pdpStatus.bits.chan5_l2;
+ break;
+ case 5:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan6_h6) << 4) |
+ pdpStatus.bits.chan6_l4;
+ break;
+ }
+ } else if (channel <= 11) {
+ PdpStatus2 pdpStatus;
+ HAL_ReadCANPeriodicPacket(handle, Status2, pdpStatus.data, &length,
+ &receivedTimestamp, TimeoutMs, StatusPeriodMs,
+ status);
+ switch (channel) {
+ case 6:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan7_h8) << 2) |
+ pdpStatus.bits.chan7_l2;
+ break;
+ case 7:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan8_h6) << 4) |
+ pdpStatus.bits.chan8_l4;
+ break;
+ case 8:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan9_h4) << 6) |
+ pdpStatus.bits.chan9_l6;
+ break;
+ case 9:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan10_h2) << 8) |
+ pdpStatus.bits.chan10_l8;
+ break;
+ case 10:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan11_h8) << 2) |
+ pdpStatus.bits.chan11_l2;
+ break;
+ case 11:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan12_h6) << 4) |
+ pdpStatus.bits.chan12_l4;
+ break;
+ }
+ } else {
+ PdpStatus3 pdpStatus;
+ HAL_ReadCANPeriodicPacket(handle, Status3, pdpStatus.data, &length,
+ &receivedTimestamp, TimeoutMs, StatusPeriodMs,
+ status);
+ switch (channel) {
+ case 12:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan13_h8) << 2) |
+ pdpStatus.bits.chan13_l2;
+ break;
+ case 13:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan14_h6) << 4) |
+ pdpStatus.bits.chan14_l4;
+ break;
+ case 14:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan15_h4) << 6) |
+ pdpStatus.bits.chan15_l6;
+ break;
+ case 15:
+ raw = (static_cast<uint32_t>(pdpStatus.bits.chan16_h2) << 8) |
+ pdpStatus.bits.chan16_l8;
+ break;
+ }
+ }
+
+ /* convert to amps */
+ return raw * 0.125; /* 7.3 fixed pt value in Amps */
+}
+
+double HAL_GetPDPTotalCurrent(HAL_PDPHandle handle, int32_t* status) {
+ PdpStatusEnergy pdpStatus;
+ int32_t length = 0;
+ uint64_t receivedTimestamp = 0;
+
+ HAL_ReadCANPeriodicPacket(handle, StatusEnergy, pdpStatus.data, &length,
+ &receivedTimestamp, TimeoutMs, StatusPeriodMs,
+ status);
+
+ uint32_t raw;
+ raw = pdpStatus.bits.TotalCurrent_125mAperunit_h8;
+ raw <<= 4;
+ raw |= pdpStatus.bits.TotalCurrent_125mAperunit_l4;
+ return 0.125 * raw; /* 7.3 fixed pt value in Amps */
+}
+
+double HAL_GetPDPTotalPower(HAL_PDPHandle handle, int32_t* status) {
+ PdpStatusEnergy pdpStatus;
+ int32_t length = 0;
+ uint64_t receivedTimestamp = 0;
+
+ HAL_ReadCANPeriodicPacket(handle, StatusEnergy, pdpStatus.data, &length,
+ &receivedTimestamp, TimeoutMs, StatusPeriodMs,
+ status);
+
+ uint32_t raw;
+ raw = pdpStatus.bits.Power_125mWperunit_h4;
+ raw <<= 8;
+ raw |= pdpStatus.bits.Power_125mWperunit_m8;
+ raw <<= 4;
+ raw |= pdpStatus.bits.Power_125mWperunit_l4;
+ return 0.125 * raw; /* 7.3 fixed pt value in Watts */
+}
+
+double HAL_GetPDPTotalEnergy(HAL_PDPHandle handle, int32_t* status) {
+ PdpStatusEnergy pdpStatus;
+ int32_t length = 0;
+ uint64_t receivedTimestamp = 0;
+
+ HAL_ReadCANPeriodicPacket(handle, StatusEnergy, pdpStatus.data, &length,
+ &receivedTimestamp, TimeoutMs, StatusPeriodMs,
+ status);
+
+ uint32_t raw;
+ raw = pdpStatus.bits.Energy_125mWPerUnitXTmeas_h4;
+ raw <<= 8;
+ raw |= pdpStatus.bits.Energy_125mWPerUnitXTmeas_mh8;
+ raw <<= 8;
+ raw |= pdpStatus.bits.Energy_125mWPerUnitXTmeas_ml8;
+ raw <<= 8;
+ raw |= pdpStatus.bits.Energy_125mWPerUnitXTmeas_l8;
+
+ double energyJoules = 0.125 * raw; /* mW integrated every TmeasMs */
+ energyJoules *= 0.001; /* convert from mW to W */
+ energyJoules *=
+ pdpStatus.bits
+ .TmeasMs_likelywillbe20ms_; /* multiplied by TmeasMs = joules */
+ return 0.125 * raw;
+}
+
+void HAL_ResetPDPTotalEnergy(HAL_PDPHandle handle, int32_t* status) {
+ uint8_t pdpControl[] = {0x40}; /* only bit set is ResetEnergy */
+ HAL_WriteCANPacket(handle, pdpControl, 1, Control1, status);
+}
+
+void HAL_ClearPDPStickyFaults(HAL_PDPHandle handle, int32_t* status) {
+ uint8_t pdpControl[] = {0x80}; /* only bit set is ClearStickyFaults */
+ HAL_WriteCANPacket(handle, pdpControl, 1, Control1, status);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/PWM.cpp b/hal/src/main/native/athena/PWM.cpp
new file mode 100644
index 0000000..06b527c
--- /dev/null
+++ b/hal/src/main/native/athena/PWM.cpp
@@ -0,0 +1,458 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <cmath>
+#include <thread>
+
+#include <wpi/raw_ostream.h>
+
+#include "ConstantsInternal.h"
+#include "DigitalInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/cpp/fpga_clock.h"
+#include "hal/handles/HandlesInternal.h"
+
+using namespace hal;
+
+static inline int32_t GetMaxPositivePwm(DigitalPort* port) {
+ return port->maxPwm;
+}
+
+static inline int32_t GetMinPositivePwm(DigitalPort* port) {
+ if (port->eliminateDeadband) {
+ return port->deadbandMaxPwm;
+ } else {
+ return port->centerPwm + 1;
+ }
+}
+
+static inline int32_t GetCenterPwm(DigitalPort* port) {
+ return port->centerPwm;
+}
+
+static inline int32_t GetMaxNegativePwm(DigitalPort* port) {
+ if (port->eliminateDeadband) {
+ return port->deadbandMinPwm;
+ } else {
+ return port->centerPwm - 1;
+ }
+}
+
+static inline int32_t GetMinNegativePwm(DigitalPort* port) {
+ return port->minPwm;
+}
+
+static inline int32_t GetPositiveScaleFactor(DigitalPort* port) {
+ return GetMaxPositivePwm(port) - GetMinPositivePwm(port);
+} ///< The scale for positive speeds.
+
+static inline int32_t GetNegativeScaleFactor(DigitalPort* port) {
+ return GetMaxNegativePwm(port) - GetMinNegativePwm(port);
+} ///< The scale for negative speeds.
+
+static inline int32_t GetFullRangeScaleFactor(DigitalPort* port) {
+ return GetMaxPositivePwm(port) - GetMinNegativePwm(port);
+} ///< The scale for positions.
+
+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();
+ initializeDigital(status);
+
+ if (*status != 0) return HAL_kInvalidHandle;
+
+ int16_t channel = getPortHandleChannel(portHandle);
+ if (channel == InvalidHandleIndex || channel >= kNumPWMChannels) {
+ *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;
+
+ if (port->channel > tPWM::kNumHdrRegisters - 1) {
+ int32_t bitToSet = 1 << remapMXPPWMChannel(port->channel);
+ uint16_t specialFunctions =
+ digitalSystem->readEnableMXPSpecialFunction(status);
+ digitalSystem->writeEnableMXPSpecialFunction(specialFunctions | bitToSet,
+ status);
+ }
+
+ // 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;
+ }
+
+ digitalChannelHandles->Free(pwmPortHandle, HAL_HandleEnum::PWM);
+
+ // Wait for no other object to hold this handle.
+ auto start = hal::fpga_clock::now();
+ while (port.use_count() != 1) {
+ auto current = hal::fpga_clock::now();
+ if (start + std::chrono::seconds(1) < current) {
+ wpi::outs() << "PWM handle free timeout\n";
+ wpi::outs().flush();
+ break;
+ }
+ std::this_thread::yield();
+ }
+
+ if (port->channel > tPWM::kNumHdrRegisters - 1) {
+ int32_t bitToUnset = 1 << remapMXPPWMChannel(port->channel);
+ uint16_t specialFunctions =
+ digitalSystem->readEnableMXPSpecialFunction(status);
+ digitalSystem->writeEnableMXPSpecialFunction(specialFunctions & ~bitToUnset,
+ status);
+ }
+}
+
+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;
+ }
+
+ if (port->channel < tPWM::kNumHdrRegisters) {
+ pwmSystem->writeHdr(port->channel, value, status);
+ } else {
+ pwmSystem->writeMXP(port->channel - tPWM::kNumHdrRegisters, value, status);
+ }
+}
+
+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;
+ }
+
+ DigitalPort* dPort = port.get();
+
+ if (speed < -1.0) {
+ speed = -1.0;
+ } else if (speed > 1.0) {
+ speed = 1.0;
+ } else if (!std::isfinite(speed)) {
+ speed = 0.0;
+ }
+
+ // calculate the desired output pwm value by scaling the speed appropriately
+ int32_t rawValue;
+ if (speed == 0.0) {
+ rawValue = GetCenterPwm(dPort);
+ } else if (speed > 0.0) {
+ rawValue = static_cast<int32_t>(
+ speed * static_cast<double>(GetPositiveScaleFactor(dPort)) +
+ static_cast<double>(GetMinPositivePwm(dPort)) + 0.5);
+ } else {
+ rawValue = static_cast<int32_t>(
+ speed * static_cast<double>(GetNegativeScaleFactor(dPort)) +
+ static_cast<double>(GetMaxNegativePwm(dPort)) + 0.5);
+ }
+
+ if (!((rawValue >= GetMinNegativePwm(dPort)) &&
+ (rawValue <= GetMaxPositivePwm(dPort))) ||
+ rawValue == kPwmDisabled) {
+ *status = HAL_PWM_SCALE_ERROR;
+ return;
+ }
+
+ HAL_SetPWMRaw(pwmPortHandle, rawValue, status);
+}
+
+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;
+ }
+ DigitalPort* dPort = port.get();
+
+ if (pos < 0.0) {
+ pos = 0.0;
+ } else if (pos > 1.0) {
+ pos = 1.0;
+ }
+
+ // note, need to perform the multiplication below as floating point before
+ // converting to int
+ int32_t rawValue = static_cast<int32_t>(
+ (pos * static_cast<double>(GetFullRangeScaleFactor(dPort))) +
+ GetMinNegativePwm(dPort));
+
+ if (rawValue == kPwmDisabled) {
+ *status = HAL_PWM_SCALE_ERROR;
+ return;
+ }
+
+ HAL_SetPWMRaw(pwmPortHandle, rawValue, status);
+}
+
+void HAL_SetPWMDisabled(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
+ HAL_SetPWMRaw(pwmPortHandle, kPwmDisabled, status);
+}
+
+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;
+ }
+
+ if (port->channel < tPWM::kNumHdrRegisters) {
+ return pwmSystem->readHdr(port->channel, status);
+ } else {
+ return pwmSystem->readMXP(port->channel - tPWM::kNumHdrRegisters, status);
+ }
+}
+
+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;
+ }
+
+ int32_t value = HAL_GetPWMRaw(pwmPortHandle, status);
+ if (*status != 0) return 0;
+ DigitalPort* dPort = port.get();
+
+ if (value == kPwmDisabled) {
+ return 0.0;
+ } else if (value > GetMaxPositivePwm(dPort)) {
+ return 1.0;
+ } else if (value < GetMinNegativePwm(dPort)) {
+ return -1.0;
+ } else if (value > GetMinPositivePwm(dPort)) {
+ return static_cast<double>(value - GetMinPositivePwm(dPort)) /
+ static_cast<double>(GetPositiveScaleFactor(dPort));
+ } else if (value < GetMaxNegativePwm(dPort)) {
+ return static_cast<double>(value - GetMaxNegativePwm(dPort)) /
+ static_cast<double>(GetNegativeScaleFactor(dPort));
+ } else {
+ return 0.0;
+ }
+}
+
+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;
+ }
+
+ int32_t value = HAL_GetPWMRaw(pwmPortHandle, status);
+ if (*status != 0) return 0;
+ DigitalPort* dPort = port.get();
+
+ if (value < GetMinNegativePwm(dPort)) {
+ return 0.0;
+ } else if (value > GetMaxPositivePwm(dPort)) {
+ return 1.0;
+ } else {
+ return static_cast<double>(value - GetMinNegativePwm(dPort)) /
+ static_cast<double>(GetFullRangeScaleFactor(dPort));
+ }
+}
+
+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;
+ }
+
+ pwmSystem->writeZeroLatch(port->channel, true, status);
+ pwmSystem->writeZeroLatch(port->channel, false, status);
+}
+
+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;
+ }
+
+ if (port->channel < tPWM::kNumPeriodScaleHdrElements) {
+ pwmSystem->writePeriodScaleHdr(port->channel, squelchMask, status);
+ } else {
+ pwmSystem->writePeriodScaleMXP(
+ port->channel - tPWM::kNumPeriodScaleHdrElements, squelchMask, status);
+ }
+}
+
+int32_t HAL_GetPWMLoopTiming(int32_t* status) {
+ initializeDigital(status);
+ if (*status != 0) return 0;
+ return pwmSystem->readLoopTiming(status);
+}
+
+uint64_t HAL_GetPWMCycleStartTime(int32_t* status) {
+ initializeDigital(status);
+ if (*status != 0) return 0;
+
+ uint64_t upper1 = pwmSystem->readCycleStartTimeUpper(status);
+ uint32_t lower = pwmSystem->readCycleStartTime(status);
+ uint64_t upper2 = pwmSystem->readCycleStartTimeUpper(status);
+ if (*status != 0) return 0;
+ if (upper1 != upper2) {
+ // Rolled over between the lower call, reread lower
+ lower = pwmSystem->readCycleStartTime(status);
+ if (*status != 0) return 0;
+ }
+ return (upper2 << 32) + lower;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/Ports.cpp b/hal/src/main/native/athena/Ports.cpp
new file mode 100644
index 0000000..9a52736
--- /dev/null
+++ b/hal/src/main/native/athena/Ports.cpp
@@ -0,0 +1,41 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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; }
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/PortsInternal.h b/hal/src/main/native/athena/PortsInternal.h
new file mode 100644
index 0000000..b3eb6b0
--- /dev/null
+++ b/hal/src/main/native/athena/PortsInternal.h
@@ -0,0 +1,39 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/ChipObject.h"
+
+namespace hal {
+
+constexpr int32_t kNumAccumulators = tAccumulator::kNumSystems;
+constexpr int32_t kNumAnalogTriggers = tAnalogTrigger::kNumSystems;
+constexpr int32_t kNumAnalogInputs = 8;
+constexpr int32_t kNumAnalogOutputs = tAO::kNumMXPRegisters;
+constexpr int32_t kNumCounters = tCounter::kNumSystems;
+constexpr int32_t kNumDigitalHeaders = 10;
+constexpr int32_t kNumDigitalMXPChannels = 16;
+constexpr int32_t kNumDigitalSPIPortChannels = 5;
+constexpr int32_t kNumPWMHeaders = tPWM::kNumHdrRegisters;
+constexpr int32_t kNumDigitalChannels =
+ kNumDigitalHeaders + kNumDigitalMXPChannels + kNumDigitalSPIPortChannels;
+constexpr int32_t kNumPWMChannels = tPWM::kNumMXPRegisters + kNumPWMHeaders;
+constexpr int32_t kNumDigitalPWMOutputs =
+ tDIO::kNumPWMDutyCycleAElements + tDIO::kNumPWMDutyCycleBElements;
+constexpr int32_t kNumEncoders = tEncoder::kNumSystems;
+constexpr int32_t kNumInterrupts = tInterrupt::kNumSystems;
+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;
+
+} // namespace hal
diff --git a/hal/src/main/native/athena/Power.cpp b/hal/src/main/native/athena/Power.cpp
new file mode 100644
index 0000000..2cf4d33
--- /dev/null
+++ b/hal/src/main/native/athena/Power.cpp
@@ -0,0 +1,111 @@
+/*----------------------------------------------------------------------------*/
+/* 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/Power.h"
+
+#include <memory>
+
+#include "HALInitializer.h"
+#include "hal/ChipObject.h"
+
+using namespace hal;
+
+namespace hal {
+
+static std::unique_ptr<tPower> power{nullptr};
+
+static void initializePower(int32_t* status) {
+ hal::init::CheckInit();
+ if (power == nullptr) {
+ power.reset(tPower::create(status));
+ }
+}
+
+} // namespace hal
+
+namespace hal {
+namespace init {
+void InitializePower() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+double HAL_GetVinVoltage(int32_t* status) {
+ initializePower(status);
+ return power->readVinVoltage(status) / 4.096 * 0.025733 - 0.029;
+}
+
+double HAL_GetVinCurrent(int32_t* status) {
+ initializePower(status);
+ return power->readVinCurrent(status) / 4.096 * 0.017042 - 0.071;
+}
+
+double HAL_GetUserVoltage6V(int32_t* status) {
+ initializePower(status);
+ return power->readUserVoltage6V(status) / 4.096 * 0.007019 - 0.014;
+}
+
+double HAL_GetUserCurrent6V(int32_t* status) {
+ initializePower(status);
+ return power->readUserCurrent6V(status) / 4.096 * 0.005566 - 0.009;
+}
+
+HAL_Bool HAL_GetUserActive6V(int32_t* status) {
+ initializePower(status);
+ return power->readStatus_User6V(status) == 4;
+}
+
+int32_t HAL_GetUserCurrentFaults6V(int32_t* status) {
+ initializePower(status);
+ return static_cast<int32_t>(
+ power->readFaultCounts_OverCurrentFaultCount6V(status));
+}
+
+double HAL_GetUserVoltage5V(int32_t* status) {
+ initializePower(status);
+ return power->readUserVoltage5V(status) / 4.096 * 0.005962 - 0.013;
+}
+
+double HAL_GetUserCurrent5V(int32_t* status) {
+ initializePower(status);
+ return power->readUserCurrent5V(status) / 4.096 * 0.001996 - 0.002;
+}
+
+HAL_Bool HAL_GetUserActive5V(int32_t* status) {
+ initializePower(status);
+ return power->readStatus_User5V(status) == 4;
+}
+
+int32_t HAL_GetUserCurrentFaults5V(int32_t* status) {
+ initializePower(status);
+ return static_cast<int32_t>(
+ power->readFaultCounts_OverCurrentFaultCount5V(status));
+}
+
+double HAL_GetUserVoltage3V3(int32_t* status) {
+ initializePower(status);
+ return power->readUserVoltage3V3(status) / 4.096 * 0.004902 - 0.01;
+}
+
+double HAL_GetUserCurrent3V3(int32_t* status) {
+ initializePower(status);
+ return power->readUserCurrent3V3(status) / 4.096 * 0.002486 - 0.003;
+}
+
+HAL_Bool HAL_GetUserActive3V3(int32_t* status) {
+ initializePower(status);
+ return power->readStatus_User3V3(status) == 4;
+}
+
+int32_t HAL_GetUserCurrentFaults3V3(int32_t* status) {
+ initializePower(status);
+ return static_cast<int32_t>(
+ power->readFaultCounts_OverCurrentFaultCount3V3(status));
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/Relay.cpp b/hal/src/main/native/athena/Relay.cpp
new file mode 100644
index 0000000..9f7d6c0
--- /dev/null
+++ b/hal/src/main/native/athena/Relay.cpp
@@ -0,0 +1,143 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "DigitalInternal.h"
+#include "HALInitializer.h"
+#include "PortsInternal.h"
+#include "hal/handles/IndexedHandleResource.h"
+
+using namespace hal;
+
+namespace {
+
+struct Relay {
+ uint8_t channel;
+ bool fwd;
+};
+
+} // namespace
+
+static IndexedHandleResource<HAL_RelayHandle, Relay, kNumRelayChannels,
+ HAL_HandleEnum::Relay>* relayHandles;
+
+// Create a mutex to protect changes to the relay values
+static wpi::mutex digitalRelayMutex;
+
+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();
+ initializeDigital(status);
+
+ 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
+ } else {
+ port->fwd = true; // set to forward
+ }
+
+ port->channel = static_cast<uint8_t>(channel);
+ return handle;
+}
+
+void HAL_FreeRelayPort(HAL_RelayHandle relayPortHandle) {
+ // no status, so no need to check for a proper free.
+ relayHandles->Free(relayPortHandle);
+}
+
+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;
+ }
+ std::lock_guard<wpi::mutex> lock(digitalRelayMutex);
+ uint8_t relays = 0;
+ if (port->fwd) {
+ relays = relaySystem->readValue_Forward(status);
+ } else {
+ relays = relaySystem->readValue_Reverse(status);
+ }
+
+ if (*status != 0) return; // bad status read
+
+ if (on) {
+ relays |= 1 << port->channel;
+ } else {
+ relays &= ~(1 << port->channel);
+ }
+
+ if (port->fwd) {
+ relaySystem->writeValue_Forward(relays, status);
+ } else {
+ relaySystem->writeValue_Reverse(relays, status);
+ }
+}
+
+HAL_Bool HAL_GetRelay(HAL_RelayHandle relayPortHandle, int32_t* status) {
+ auto port = relayHandles->Get(relayPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return false;
+ }
+
+ uint8_t relays = 0;
+ if (port->fwd) {
+ relays = relaySystem->readValue_Forward(status);
+ } else {
+ relays = relaySystem->readValue_Reverse(status);
+ }
+
+ return (relays & (1 << port->channel)) != 0;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/SPI.cpp b/hal/src/main/native/athena/SPI.cpp
new file mode 100644
index 0000000..ddced41
--- /dev/null
+++ b/hal/src/main/native/athena/SPI.cpp
@@ -0,0 +1,634 @@
+/*----------------------------------------------------------------------------*/
+/* 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/SPI.h"
+
+#include <fcntl.h>
+#include <linux/spi/spidev.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <array>
+#include <atomic>
+#include <cstring>
+
+#include <wpi/mutex.h>
+#include <wpi/raw_ostream.h>
+
+#include "DigitalInternal.h"
+#include "HALInitializer.h"
+#include "hal/DIO.h"
+#include "hal/HAL.h"
+#include "hal/handles/HandlesInternal.h"
+
+using namespace hal;
+
+static int32_t m_spiCS0Handle{0};
+static int32_t m_spiCS1Handle{0};
+static int32_t m_spiCS2Handle{0};
+static int32_t m_spiCS3Handle{0};
+static int32_t m_spiMXPHandle{0};
+
+static constexpr int32_t kSpiMaxHandles = 5;
+
+// Indices 0-3 are for onboard CS0-CS2. Index 4 is for MXP.
+static std::array<wpi::mutex, kSpiMaxHandles> spiHandleMutexes;
+static std::array<wpi::mutex, kSpiMaxHandles> spiApiMutexes;
+static std::array<wpi::mutex, kSpiMaxHandles> spiAccumulatorMutexes;
+
+// MXP SPI does not count towards this
+static std::atomic<int32_t> spiPortCount{0};
+
+static HAL_DigitalHandle digitalHandles[9]{HAL_kInvalidHandle};
+
+static wpi::mutex spiAutoMutex;
+static int32_t spiAutoPort = kSpiMaxHandles;
+static std::atomic_bool spiAutoRunning{false};
+static std::unique_ptr<tDMAManager> spiAutoDMA;
+
+static bool SPIInUseByAuto(HAL_SPIPort port) {
+ // SPI engine conflicts with any other chip selects on the same SPI device.
+ // There are two SPI devices: one for ports 0-3 (onboard), the other for port
+ // 4 (MXP).
+ if (!spiAutoRunning) return false;
+ std::lock_guard<wpi::mutex> lock(spiAutoMutex);
+ return (spiAutoPort >= 0 && spiAutoPort <= 3 && port >= 0 && port <= 3) ||
+ (spiAutoPort == 4 && port == 4);
+}
+
+namespace hal {
+namespace init {
+void InitializeSPI() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+static void CommonSPIPortInit(int32_t* status) {
+ // All false cases will set
+ if (spiPortCount.fetch_add(1) == 0) {
+ // Have not been initialized yet
+ initializeDigital(status);
+ if (*status != 0) return;
+ // MISO
+ if ((digitalHandles[3] = HAL_InitializeDIOPort(createPortHandleForSPI(29),
+ false, status)) ==
+ HAL_kInvalidHandle) {
+ std::printf("Failed to allocate DIO 29 (MISO)\n");
+ return;
+ }
+ // MOSI
+ if ((digitalHandles[4] = HAL_InitializeDIOPort(createPortHandleForSPI(30),
+ false, status)) ==
+ HAL_kInvalidHandle) {
+ std::printf("Failed to allocate DIO 30 (MOSI)\n");
+ HAL_FreeDIOPort(digitalHandles[3]); // free the first port allocated
+ return;
+ }
+ }
+}
+
+static void CommonSPIPortFree(void) {
+ if (spiPortCount.fetch_sub(1) == 1) {
+ // Clean up SPI Handles
+ HAL_FreeDIOPort(digitalHandles[3]);
+ HAL_FreeDIOPort(digitalHandles[4]);
+ }
+}
+
+void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status) {
+ hal::init::CheckInit();
+ if (port < 0 || port >= kSpiMaxHandles) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return;
+ }
+
+ int handle;
+ if (HAL_GetSPIHandle(port) != 0) return;
+ switch (port) {
+ case HAL_SPI_kOnboardCS0:
+ CommonSPIPortInit(status);
+ if (*status != 0) return;
+ // CS0 is not a DIO port, so nothing to allocate
+ handle = open("/dev/spidev0.0", O_RDWR);
+ if (handle < 0) {
+ std::printf("Failed to open SPI port %d: %s\n", port,
+ std::strerror(errno));
+ CommonSPIPortFree();
+ return;
+ }
+ HAL_SetSPIHandle(HAL_SPI_kOnboardCS0, handle);
+ break;
+ case HAL_SPI_kOnboardCS1:
+ CommonSPIPortInit(status);
+ if (*status != 0) return;
+ // CS1, Allocate
+ if ((digitalHandles[0] = HAL_InitializeDIOPort(createPortHandleForSPI(26),
+ false, status)) ==
+ HAL_kInvalidHandle) {
+ std::printf("Failed to allocate DIO 26 (CS1)\n");
+ CommonSPIPortFree();
+ return;
+ }
+ handle = open("/dev/spidev0.1", O_RDWR);
+ if (handle < 0) {
+ std::printf("Failed to open SPI port %d: %s\n", port,
+ std::strerror(errno));
+ CommonSPIPortFree();
+ HAL_FreeDIOPort(digitalHandles[0]);
+ return;
+ }
+ HAL_SetSPIHandle(HAL_SPI_kOnboardCS1, handle);
+ break;
+ case HAL_SPI_kOnboardCS2:
+ CommonSPIPortInit(status);
+ if (*status != 0) return;
+ // CS2, Allocate
+ if ((digitalHandles[1] = HAL_InitializeDIOPort(createPortHandleForSPI(27),
+ false, status)) ==
+ HAL_kInvalidHandle) {
+ std::printf("Failed to allocate DIO 27 (CS2)\n");
+ CommonSPIPortFree();
+ return;
+ }
+ handle = open("/dev/spidev0.2", O_RDWR);
+ if (handle < 0) {
+ std::printf("Failed to open SPI port %d: %s\n", port,
+ std::strerror(errno));
+ CommonSPIPortFree();
+ HAL_FreeDIOPort(digitalHandles[1]);
+ return;
+ }
+ HAL_SetSPIHandle(HAL_SPI_kOnboardCS2, handle);
+ break;
+ case HAL_SPI_kOnboardCS3:
+ CommonSPIPortInit(status);
+ if (*status != 0) return;
+ // CS3, Allocate
+ if ((digitalHandles[2] = HAL_InitializeDIOPort(createPortHandleForSPI(28),
+ false, status)) ==
+ HAL_kInvalidHandle) {
+ std::printf("Failed to allocate DIO 28 (CS3)\n");
+ CommonSPIPortFree();
+ return;
+ }
+ handle = open("/dev/spidev0.3", O_RDWR);
+ if (handle < 0) {
+ std::printf("Failed to open SPI port %d: %s\n", port,
+ std::strerror(errno));
+ CommonSPIPortFree();
+ HAL_FreeDIOPort(digitalHandles[2]);
+ return;
+ }
+ HAL_SetSPIHandle(HAL_SPI_kOnboardCS3, handle);
+ break;
+ case HAL_SPI_kMXP:
+ initializeDigital(status);
+ if (*status != 0) return;
+ if ((digitalHandles[5] = HAL_InitializeDIOPort(createPortHandleForSPI(14),
+ false, status)) ==
+ HAL_kInvalidHandle) {
+ wpi::outs() << "Failed to allocate DIO 14\n";
+ return;
+ }
+ if ((digitalHandles[6] = HAL_InitializeDIOPort(createPortHandleForSPI(15),
+ false, status)) ==
+ HAL_kInvalidHandle) {
+ wpi::outs() << "Failed to allocate DIO 15\n";
+ HAL_FreeDIOPort(digitalHandles[5]); // free the first port allocated
+ return;
+ }
+ if ((digitalHandles[7] = HAL_InitializeDIOPort(createPortHandleForSPI(16),
+ false, status)) ==
+ HAL_kInvalidHandle) {
+ wpi::outs() << "Failed to allocate DIO 16\n";
+ HAL_FreeDIOPort(digitalHandles[5]); // free the first port allocated
+ HAL_FreeDIOPort(digitalHandles[6]); // free the second port allocated
+ return;
+ }
+ if ((digitalHandles[8] = HAL_InitializeDIOPort(createPortHandleForSPI(17),
+ false, status)) ==
+ HAL_kInvalidHandle) {
+ wpi::outs() << "Failed to allocate DIO 17\n";
+ HAL_FreeDIOPort(digitalHandles[5]); // free the first port allocated
+ HAL_FreeDIOPort(digitalHandles[6]); // free the second port allocated
+ HAL_FreeDIOPort(digitalHandles[7]); // free the third port allocated
+ return;
+ }
+ digitalSystem->writeEnableMXPSpecialFunction(
+ digitalSystem->readEnableMXPSpecialFunction(status) | 0x00F0, status);
+ handle = open("/dev/spidev1.0", O_RDWR);
+ if (handle < 0) {
+ std::printf("Failed to open SPI port %d: %s\n", port,
+ std::strerror(errno));
+ HAL_FreeDIOPort(digitalHandles[5]); // free the first port allocated
+ HAL_FreeDIOPort(digitalHandles[6]); // free the second port allocated
+ HAL_FreeDIOPort(digitalHandles[7]); // free the third port allocated
+ HAL_FreeDIOPort(digitalHandles[8]); // free the fourth port allocated
+ return;
+ }
+ HAL_SetSPIHandle(HAL_SPI_kMXP, handle);
+ break;
+ default:
+ *status = PARAMETER_OUT_OF_RANGE;
+ break;
+ }
+}
+
+int32_t HAL_TransactionSPI(HAL_SPIPort port, const uint8_t* dataToSend,
+ uint8_t* dataReceived, int32_t size) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ return -1;
+ }
+
+ if (SPIInUseByAuto(port)) return -1;
+
+ struct spi_ioc_transfer xfer;
+ std::memset(&xfer, 0, sizeof(xfer));
+ xfer.tx_buf = (__u64)dataToSend;
+ xfer.rx_buf = (__u64)dataReceived;
+ xfer.len = size;
+
+ std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
+ return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
+}
+
+int32_t HAL_WriteSPI(HAL_SPIPort port, const uint8_t* dataToSend,
+ int32_t sendSize) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ return -1;
+ }
+
+ if (SPIInUseByAuto(port)) return -1;
+
+ struct spi_ioc_transfer xfer;
+ std::memset(&xfer, 0, sizeof(xfer));
+ xfer.tx_buf = (__u64)dataToSend;
+ xfer.len = sendSize;
+
+ std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
+ return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
+}
+
+int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ return -1;
+ }
+
+ if (SPIInUseByAuto(port)) return -1;
+
+ struct spi_ioc_transfer xfer;
+ std::memset(&xfer, 0, sizeof(xfer));
+ xfer.rx_buf = (__u64)buffer;
+ xfer.len = count;
+
+ std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
+ return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
+}
+
+void HAL_CloseSPI(HAL_SPIPort port) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ return;
+ }
+
+ int32_t status = 0;
+ HAL_FreeSPIAuto(port, &status);
+
+ {
+ std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
+ close(HAL_GetSPIHandle(port));
+ }
+
+ HAL_SetSPIHandle(port, 0);
+ if (port < 4) {
+ CommonSPIPortFree();
+ }
+
+ switch (port) {
+ // Case 0 does not need to do anything
+ case 1:
+ HAL_FreeDIOPort(digitalHandles[0]);
+ break;
+ case 2:
+ HAL_FreeDIOPort(digitalHandles[1]);
+ break;
+ case 3:
+ HAL_FreeDIOPort(digitalHandles[2]);
+ break;
+ case 4:
+ HAL_FreeDIOPort(digitalHandles[5]);
+ HAL_FreeDIOPort(digitalHandles[6]);
+ HAL_FreeDIOPort(digitalHandles[7]);
+ HAL_FreeDIOPort(digitalHandles[8]);
+ break;
+ default:
+ break;
+ }
+}
+
+void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ return;
+ }
+
+ std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
+ ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MAX_SPEED_HZ, &speed);
+}
+
+void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
+ HAL_Bool sampleOnTrailing, HAL_Bool clkIdleHigh) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ return;
+ }
+
+ uint8_t mode = 0;
+ mode |= (!msbFirst ? 8 : 0);
+ mode |= (clkIdleHigh ? 2 : 0);
+ mode |= (sampleOnTrailing ? 1 : 0);
+
+ std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
+ ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MODE, &mode);
+}
+
+void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return;
+ }
+
+ std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
+ if (port < 4) {
+ spiSystem->writeChipSelectActiveHigh_Hdr(
+ spiSystem->readChipSelectActiveHigh_Hdr(status) | (1 << port), status);
+ } else {
+ spiSystem->writeChipSelectActiveHigh_MXP(1, status);
+ }
+}
+
+void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return;
+ }
+
+ std::lock_guard<wpi::mutex> lock(spiApiMutexes[port]);
+ if (port < 4) {
+ spiSystem->writeChipSelectActiveHigh_Hdr(
+ spiSystem->readChipSelectActiveHigh_Hdr(status) & ~(1 << port), status);
+ } else {
+ spiSystem->writeChipSelectActiveHigh_MXP(0, status);
+ }
+}
+
+int32_t HAL_GetSPIHandle(HAL_SPIPort port) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ return 0;
+ }
+
+ std::lock_guard<wpi::mutex> lock(spiHandleMutexes[port]);
+ switch (port) {
+ case 0:
+ return m_spiCS0Handle;
+ case 1:
+ return m_spiCS1Handle;
+ case 2:
+ return m_spiCS2Handle;
+ case 3:
+ return m_spiCS3Handle;
+ case 4:
+ return m_spiMXPHandle;
+ default:
+ return 0;
+ }
+}
+
+void HAL_SetSPIHandle(HAL_SPIPort port, int32_t handle) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ return;
+ }
+
+ std::lock_guard<wpi::mutex> lock(spiHandleMutexes[port]);
+ switch (port) {
+ case 0:
+ m_spiCS0Handle = handle;
+ break;
+ case 1:
+ m_spiCS1Handle = handle;
+ break;
+ case 2:
+ m_spiCS2Handle = handle;
+ break;
+ case 3:
+ m_spiCS3Handle = handle;
+ break;
+ case 4:
+ m_spiMXPHandle = handle;
+ break;
+ default:
+ break;
+ }
+}
+
+void HAL_InitSPIAuto(HAL_SPIPort port, int32_t bufferSize, int32_t* status) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return;
+ }
+
+ std::lock_guard<wpi::mutex> lock(spiAutoMutex);
+ // FPGA only has one auto SPI engine
+ if (spiAutoPort != kSpiMaxHandles) {
+ *status = RESOURCE_IS_ALLOCATED;
+ return;
+ }
+
+ // remember the initialized port for other entry points
+ spiAutoPort = port;
+
+ // configure the correct chip select
+ if (port < 4) {
+ spiSystem->writeAutoSPI1Select(false, status);
+ spiSystem->writeAutoChipSelect(port, status);
+ } else {
+ spiSystem->writeAutoSPI1Select(true, status);
+ spiSystem->writeAutoChipSelect(0, status);
+ }
+
+ // configure DMA
+ tDMAChannelDescriptor desc;
+ spiSystem->getSystemInterface()->getDmaDescriptor(g_SpiAutoData_index, &desc);
+ spiAutoDMA = std::make_unique<tDMAManager>(desc.channel, bufferSize, status);
+}
+
+void HAL_FreeSPIAuto(HAL_SPIPort port, int32_t* status) {
+ if (port < 0 || port >= kSpiMaxHandles) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return;
+ }
+
+ std::lock_guard<wpi::mutex> lock(spiAutoMutex);
+ if (spiAutoPort != port) return;
+ spiAutoPort = kSpiMaxHandles;
+
+ // disable by setting to internal clock and setting rate=0
+ spiSystem->writeAutoRate(0, status);
+ spiSystem->writeAutoTriggerConfig_ExternalClock(false, status);
+
+ // stop the DMA
+ spiAutoDMA->stop(status);
+
+ spiAutoDMA.reset(nullptr);
+
+ spiAutoRunning = false;
+}
+
+void HAL_StartSPIAutoRate(HAL_SPIPort port, double period, int32_t* status) {
+ std::lock_guard<wpi::mutex> lock(spiAutoMutex);
+ // FPGA only has one auto SPI engine
+ if (port != spiAutoPort) {
+ *status = INCOMPATIBLE_STATE;
+ return;
+ }
+
+ spiAutoRunning = true;
+
+ // start the DMA
+ spiAutoDMA->start(status);
+
+ // auto rate is in microseconds
+ spiSystem->writeAutoRate(period * 1000000, status);
+
+ // disable the external clock
+ spiSystem->writeAutoTriggerConfig_ExternalClock(false, status);
+}
+
+void HAL_StartSPIAutoTrigger(HAL_SPIPort port, HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ HAL_Bool triggerRising, HAL_Bool triggerFalling,
+ int32_t* status) {
+ std::lock_guard<wpi::mutex> lock(spiAutoMutex);
+ // FPGA only has one auto SPI engine
+ if (port != spiAutoPort) {
+ *status = INCOMPATIBLE_STATE;
+ return;
+ }
+
+ spiAutoRunning = true;
+
+ // start the DMA
+ spiAutoDMA->start(status);
+
+ // get channel routing
+ bool routingAnalogTrigger = false;
+ uint8_t routingChannel = 0;
+ uint8_t routingModule = 0;
+ if (!remapDigitalSource(digitalSourceHandle, analogTriggerType,
+ routingChannel, routingModule,
+ routingAnalogTrigger)) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ // configure external trigger and enable it
+ tSPI::tAutoTriggerConfig config;
+ config.ExternalClock = 1;
+ config.FallingEdge = triggerFalling ? 1 : 0;
+ config.RisingEdge = triggerRising ? 1 : 0;
+ config.ExternalClockSource_AnalogTrigger = routingAnalogTrigger ? 1 : 0;
+ config.ExternalClockSource_Module = routingModule;
+ config.ExternalClockSource_Channel = routingChannel;
+ spiSystem->writeAutoTriggerConfig(config, status);
+}
+
+void HAL_StopSPIAuto(HAL_SPIPort port, int32_t* status) {
+ std::lock_guard<wpi::mutex> lock(spiAutoMutex);
+ // FPGA only has one auto SPI engine
+ if (port != spiAutoPort) {
+ *status = INCOMPATIBLE_STATE;
+ return;
+ }
+
+ // disable by setting to internal clock and setting rate=0
+ spiSystem->writeAutoRate(0, status);
+ spiSystem->writeAutoTriggerConfig_ExternalClock(false, status);
+
+ // stop the DMA
+ spiAutoDMA->stop(status);
+
+ spiAutoRunning = false;
+}
+
+void HAL_SetSPIAutoTransmitData(HAL_SPIPort port, const uint8_t* dataToSend,
+ int32_t dataSize, int32_t zeroSize,
+ int32_t* status) {
+ if (dataSize < 0 || dataSize > 16) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return;
+ }
+
+ if (zeroSize < 0 || zeroSize > 127) {
+ *status = PARAMETER_OUT_OF_RANGE;
+ return;
+ }
+
+ std::lock_guard<wpi::mutex> lock(spiAutoMutex);
+ // FPGA only has one auto SPI engine
+ if (port != spiAutoPort) {
+ *status = INCOMPATIBLE_STATE;
+ return;
+ }
+
+ // set tx data registers
+ for (int32_t i = 0; i < dataSize; ++i)
+ spiSystem->writeAutoTx(i >> 2, i & 3, dataToSend[i], status);
+
+ // set byte counts
+ tSPI::tAutoByteCount config;
+ config.ZeroByteCount = static_cast<unsigned>(zeroSize) & 0x7f;
+ config.TxByteCount = static_cast<unsigned>(dataSize) & 0xf;
+ spiSystem->writeAutoByteCount(config, status);
+}
+
+void HAL_ForceSPIAutoRead(HAL_SPIPort port, int32_t* status) {
+ std::lock_guard<wpi::mutex> lock(spiAutoMutex);
+ // FPGA only has one auto SPI engine
+ if (port != spiAutoPort) {
+ *status = INCOMPATIBLE_STATE;
+ return;
+ }
+
+ spiSystem->strobeAutoForceOne(status);
+}
+
+int32_t HAL_ReadSPIAutoReceivedData(HAL_SPIPort port, uint32_t* buffer,
+ int32_t numToRead, double timeout,
+ int32_t* status) {
+ std::lock_guard<wpi::mutex> lock(spiAutoMutex);
+ // FPGA only has one auto SPI engine
+ if (port != spiAutoPort) {
+ *status = INCOMPATIBLE_STATE;
+ return 0;
+ }
+
+ size_t numRemaining = 0;
+ // timeout is in ms
+ spiAutoDMA->read(buffer, numToRead, timeout * 1000, &numRemaining, status);
+ return numRemaining;
+}
+
+int32_t HAL_GetSPIAutoDroppedCount(HAL_SPIPort port, int32_t* status) {
+ std::lock_guard<wpi::mutex> lock(spiAutoMutex);
+ // FPGA only has one auto SPI engine
+ if (port != spiAutoPort) {
+ *status = INCOMPATIBLE_STATE;
+ return 0;
+ }
+
+ return spiSystem->readTransferSkippedFullCount(status);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/SerialPort.cpp b/hal/src/main/native/athena/SerialPort.cpp
new file mode 100644
index 0000000..d2597a9
--- /dev/null
+++ b/hal/src/main/native/athena/SerialPort.cpp
@@ -0,0 +1,174 @@
+/*----------------------------------------------------------------------------*/
+/* 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/SerialPort.h"
+
+#include <string>
+
+#include "HALInitializer.h"
+#include "hal/cpp/SerialHelper.h"
+#include "visa/visa.h"
+
+static int32_t resourceManagerHandle{0};
+static HAL_SerialPort portHandles[4];
+
+namespace hal {
+namespace init {
+void InitializeSerialPort() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+void HAL_InitializeSerialPort(HAL_SerialPort port, int32_t* status) {
+ hal::init::CheckInit();
+ std::string portName;
+
+ if (resourceManagerHandle == 0)
+ viOpenDefaultRM(reinterpret_cast<ViSession*>(&resourceManagerHandle));
+
+ hal::SerialHelper serialHelper;
+
+ portName = serialHelper.GetVISASerialPortName(port, status);
+
+ if (*status < 0) {
+ return;
+ }
+
+ *status = viOpen(resourceManagerHandle, const_cast<char*>(portName.c_str()),
+ VI_NULL, VI_NULL,
+ reinterpret_cast<ViSession*>(&portHandles[port]));
+ if (*status > 0) *status = 0;
+}
+
+void HAL_InitializeSerialPortDirect(HAL_SerialPort port, const char* portName,
+ int32_t* status) {
+ *status = viOpen(resourceManagerHandle, const_cast<char*>(portName), VI_NULL,
+ VI_NULL, reinterpret_cast<ViSession*>(&portHandles[port]));
+ if (*status > 0) *status = 0;
+}
+
+void HAL_SetSerialBaudRate(HAL_SerialPort port, int32_t baud, int32_t* status) {
+ *status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_BAUD, baud);
+ if (*status > 0) *status = 0;
+}
+
+void HAL_SetSerialDataBits(HAL_SerialPort port, int32_t bits, int32_t* status) {
+ *status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_DATA_BITS, bits);
+ if (*status > 0) *status = 0;
+}
+
+void HAL_SetSerialParity(HAL_SerialPort port, int32_t parity, int32_t* status) {
+ *status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_PARITY, parity);
+ if (*status > 0) *status = 0;
+}
+
+void HAL_SetSerialStopBits(HAL_SerialPort port, int32_t stopBits,
+ int32_t* status) {
+ *status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_STOP_BITS, stopBits);
+ if (*status > 0) *status = 0;
+}
+
+void HAL_SetSerialWriteMode(HAL_SerialPort port, int32_t mode,
+ int32_t* status) {
+ *status = viSetAttribute(portHandles[port], VI_ATTR_WR_BUF_OPER_MODE, mode);
+ if (*status > 0) *status = 0;
+}
+
+void HAL_SetSerialFlowControl(HAL_SerialPort port, int32_t flow,
+ int32_t* status) {
+ *status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_FLOW_CNTRL, flow);
+ if (*status > 0) *status = 0;
+}
+
+void HAL_SetSerialTimeout(HAL_SerialPort port, double timeout,
+ int32_t* status) {
+ *status = viSetAttribute(portHandles[port], VI_ATTR_TMO_VALUE,
+ static_cast<uint32_t>(timeout * 1e3));
+ if (*status > 0) *status = 0;
+}
+
+void HAL_EnableSerialTermination(HAL_SerialPort port, char terminator,
+ int32_t* status) {
+ viSetAttribute(portHandles[port], VI_ATTR_TERMCHAR_EN, VI_TRUE);
+ viSetAttribute(portHandles[port], VI_ATTR_TERMCHAR, terminator);
+ *status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_END_IN,
+ VI_ASRL_END_TERMCHAR);
+ if (*status > 0) *status = 0;
+}
+
+void HAL_DisableSerialTermination(HAL_SerialPort port, int32_t* status) {
+ viSetAttribute(portHandles[port], VI_ATTR_TERMCHAR_EN, VI_FALSE);
+ *status =
+ viSetAttribute(portHandles[port], VI_ATTR_ASRL_END_IN, VI_ASRL_END_NONE);
+ if (*status > 0) *status = 0;
+}
+
+void HAL_SetSerialReadBufferSize(HAL_SerialPort port, int32_t size,
+ int32_t* status) {
+ *status = viSetBuf(portHandles[port], VI_READ_BUF, size);
+ if (*status > 0) *status = 0;
+}
+
+void HAL_SetSerialWriteBufferSize(HAL_SerialPort port, int32_t size,
+ int32_t* status) {
+ *status = viSetBuf(portHandles[port], VI_WRITE_BUF, size);
+ if (*status > 0) *status = 0;
+}
+
+int32_t HAL_GetSerialBytesReceived(HAL_SerialPort port, int32_t* status) {
+ int32_t bytes = 0;
+
+ *status = viGetAttribute(portHandles[port], VI_ATTR_ASRL_AVAIL_NUM, &bytes);
+ if (*status > 0) *status = 0;
+ return bytes;
+}
+
+int32_t HAL_ReadSerial(HAL_SerialPort port, char* buffer, int32_t count,
+ int32_t* status) {
+ uint32_t retCount = 0;
+
+ *status =
+ viRead(portHandles[port], (ViPBuf)buffer, count, (ViPUInt32)&retCount);
+
+ if (*status == VI_ERROR_IO || *status == VI_ERROR_ASRL_OVERRUN ||
+ *status == VI_ERROR_ASRL_FRAMING || *status == VI_ERROR_ASRL_PARITY) {
+ int32_t localStatus = 0;
+ HAL_ClearSerial(port, &localStatus);
+ }
+
+ if (*status == VI_ERROR_TMO || *status > 0) *status = 0;
+ return static_cast<int32_t>(retCount);
+}
+
+int32_t HAL_WriteSerial(HAL_SerialPort port, const char* buffer, int32_t count,
+ int32_t* status) {
+ uint32_t retCount = 0;
+
+ *status =
+ viWrite(portHandles[port], (ViPBuf)buffer, count, (ViPUInt32)&retCount);
+
+ if (*status > 0) *status = 0;
+ return static_cast<int32_t>(retCount);
+}
+
+void HAL_FlushSerial(HAL_SerialPort port, int32_t* status) {
+ *status = viFlush(portHandles[port], VI_WRITE_BUF);
+ if (*status > 0) *status = 0;
+}
+
+void HAL_ClearSerial(HAL_SerialPort port, int32_t* status) {
+ *status = viClear(portHandles[port]);
+ if (*status > 0) *status = 0;
+}
+
+void HAL_CloseSerial(HAL_SerialPort port, int32_t* status) {
+ *status = viClose(portHandles[port]);
+ if (*status > 0) *status = 0;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/Solenoid.cpp b/hal/src/main/native/athena/Solenoid.cpp
new file mode 100644
index 0000000..c53db11
--- /dev/null
+++ b/hal/src/main/native/athena/Solenoid.cpp
@@ -0,0 +1,191 @@
+/*----------------------------------------------------------------------------*/
+/* 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/Solenoid.h"
+
+#include <FRC_NetworkCommunication/LoadOut.h>
+
+#include "HALInitializer.h"
+#include "PCMInternal.h"
+#include "PortsInternal.h"
+#include "ctre/PCM.h"
+#include "hal/ChipObject.h"
+#include "hal/Errors.h"
+#include "hal/Ports.h"
+#include "hal/handles/HandlesInternal.h"
+#include "hal/handles/IndexedHandleResource.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;
+ }
+
+ // initializePCM will check the module
+ if (!HAL_CheckSolenoidChannel(channel)) {
+ *status = RESOURCE_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+
+ initializePCM(module, status);
+ if (*status != 0) {
+ return HAL_kInvalidHandle;
+ }
+
+ auto handle = solenoidHandles->Allocate(
+ module * kNumSolenoidChannels + channel, status);
+ if (*status != 0) {
+ 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);
+
+ return handle;
+}
+
+void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle) {
+ solenoidHandles->Free(solenoidPortHandle);
+}
+
+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;
+ }
+ bool value;
+
+ *status = PCM_modules[port->module]->GetSolenoid(port->channel, value);
+
+ return value;
+}
+
+int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status) {
+ if (!checkPCMInit(module, status)) return 0;
+ uint8_t value;
+
+ *status = PCM_modules[module]->GetAllSolenoids(value);
+
+ return value;
+}
+
+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;
+ }
+
+ *status = PCM_modules[port->module]->SetSolenoid(port->channel, value);
+}
+
+void HAL_SetAllSolenoids(int32_t module, int32_t state, int32_t* status) {
+ if (!checkPCMInit(module, status)) return;
+
+ *status = PCM_modules[module]->SetAllSolenoids(state);
+}
+
+int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status) {
+ if (!checkPCMInit(module, status)) return 0;
+ uint8_t value;
+
+ *status = PCM_modules[module]->GetSolenoidBlackList(value);
+
+ return value;
+}
+HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status) {
+ if (!checkPCMInit(module, status)) return 0;
+ bool value;
+
+ *status = PCM_modules[module]->GetSolenoidStickyFault(value);
+
+ return value;
+}
+HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status) {
+ if (!checkPCMInit(module, status)) return false;
+ bool value;
+
+ *status = PCM_modules[module]->GetSolenoidFault(value);
+
+ return value;
+}
+void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status) {
+ if (!checkPCMInit(module, status)) return;
+
+ *status = PCM_modules[module]->ClearStickyFaults();
+}
+
+void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
+ int32_t durMS, int32_t* status) {
+ auto port = solenoidHandles->Get(solenoidPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ *status =
+ PCM_modules[port->module]->SetOneShotDurationMs(port->channel, durMS);
+}
+
+void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status) {
+ auto port = solenoidHandles->Get(solenoidPortHandle);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+
+ *status = PCM_modules[port->module]->FireOneShotSolenoid(port->channel);
+}
+} // extern "C"
diff --git a/hal/src/main/native/athena/Threads.cpp b/hal/src/main/native/athena/Threads.cpp
new file mode 100644
index 0000000..95d1f59
--- /dev/null
+++ b/hal/src/main/native/athena/Threads.cpp
@@ -0,0 +1,93 @@
+/*----------------------------------------------------------------------------*/
+/* 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/Threads.h"
+
+#include <pthread.h>
+#include <sched.h>
+
+#include "hal/Errors.h"
+
+namespace hal {
+namespace init {
+void InitializeThreads() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+
+int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
+ int32_t* status) {
+ sched_param sch;
+ int policy;
+ int success = pthread_getschedparam(
+ *reinterpret_cast<const pthread_t*>(handle), &policy, &sch);
+ if (success == 0) {
+ *status = 0;
+ } else {
+ *status = HAL_THREAD_PRIORITY_ERROR;
+ return -1;
+ }
+ if (policy == SCHED_FIFO || policy == SCHED_RR) {
+ *isRealTime = true;
+ return sch.sched_priority;
+ } else {
+ *isRealTime = false;
+ // 0 is the only suppored priority for non-realtime, so scale to 1
+ return 1;
+ }
+}
+
+int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status) {
+ auto thread = pthread_self();
+ return HAL_GetThreadPriority(&thread, isRealTime, status);
+}
+
+HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
+ int32_t priority, int32_t* status) {
+ if (handle == nullptr) {
+ *status = NULL_PARAMETER;
+ return false;
+ }
+
+ int scheduler = realTime ? SCHED_FIFO : SCHED_OTHER;
+ if (realTime) {
+ // We don't support setting priorities for non RT threads
+ // so we don't need to check for proper range
+ if (priority < sched_get_priority_min(scheduler) ||
+ priority > sched_get_priority_max(scheduler)) {
+ *status = HAL_THREAD_PRIORITY_RANGE_ERROR;
+ return false;
+ }
+ }
+
+ sched_param sch;
+ int policy;
+ pthread_getschedparam(*reinterpret_cast<const pthread_t*>(handle), &policy,
+ &sch);
+ if (scheduler == SCHED_FIFO || scheduler == SCHED_RR)
+ sch.sched_priority = priority;
+ else
+ // Only need to set 0 priority for non RT thread
+ sch.sched_priority = 0;
+ if (pthread_setschedparam(*reinterpret_cast<const pthread_t*>(handle),
+ scheduler, &sch)) {
+ *status = HAL_THREAD_PRIORITY_ERROR;
+ return false;
+ } else {
+ *status = 0;
+ return true;
+ }
+}
+
+HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority,
+ int32_t* status) {
+ auto thread = pthread_self();
+ return HAL_SetThreadPriority(&thread, realTime, priority, status);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/athena/cpp/SerialHelper.cpp b/hal/src/main/native/athena/cpp/SerialHelper.cpp
new file mode 100644
index 0000000..98b22db
--- /dev/null
+++ b/hal/src/main/native/athena/cpp/SerialHelper.cpp
@@ -0,0 +1,333 @@
+/*----------------------------------------------------------------------------*/
+/* 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/cpp/SerialHelper.h"
+
+#include <algorithm>
+#include <cstdio>
+#include <cstring>
+
+#include <wpi/FileSystem.h>
+#include <wpi/StringRef.h>
+
+#include "../visa/visa.h"
+#include "hal/Errors.h"
+
+constexpr const char* OnboardResourceVISA = "ASRL1::INSTR";
+constexpr const char* MxpResourceVISA = "ASRL2::INSTR";
+
+constexpr const char* OnboardResourceOS = "/dev/ttyS0";
+constexpr const char* MxpResourceOS = "/dev/ttyS1";
+
+namespace hal {
+
+std::string SerialHelper::m_usbNames[2]{"", ""};
+
+wpi::mutex SerialHelper::m_nameMutex;
+
+SerialHelper::SerialHelper() {
+ viOpenDefaultRM(reinterpret_cast<ViSession*>(&m_resourceHandle));
+}
+
+std::string SerialHelper::GetVISASerialPortName(HAL_SerialPort port,
+ int32_t* status) {
+ if (port == HAL_SerialPort::HAL_SerialPort_Onboard) {
+ return OnboardResourceVISA;
+ } else if (port == HAL_SerialPort::HAL_SerialPort_MXP) {
+ return MxpResourceVISA;
+ }
+
+ QueryHubPaths(status);
+
+ // If paths are empty or status error, return error
+ if (*status != 0 || m_visaResource.empty() || m_osResource.empty() ||
+ m_sortedHubPath.empty()) {
+ *status = HAL_SERIAL_PORT_NOT_FOUND;
+ return "";
+ }
+
+ int32_t visaIndex = GetIndexForPort(port, status);
+ if (visaIndex == -1) {
+ *status = HAL_SERIAL_PORT_NOT_FOUND;
+ return "";
+ // Error
+ } else {
+ return m_visaResource[visaIndex].str();
+ }
+}
+
+std::string SerialHelper::GetOSSerialPortName(HAL_SerialPort port,
+ int32_t* status) {
+ if (port == HAL_SerialPort::HAL_SerialPort_Onboard) {
+ return OnboardResourceOS;
+ } else if (port == HAL_SerialPort::HAL_SerialPort_MXP) {
+ return MxpResourceOS;
+ }
+
+ QueryHubPaths(status);
+
+ // If paths are empty or status error, return error
+ if (*status != 0 || m_visaResource.empty() || m_osResource.empty() ||
+ m_sortedHubPath.empty()) {
+ *status = HAL_SERIAL_PORT_NOT_FOUND;
+ return "";
+ }
+
+ int32_t osIndex = GetIndexForPort(port, status);
+ if (osIndex == -1) {
+ *status = HAL_SERIAL_PORT_NOT_FOUND;
+ return "";
+ // Error
+ } else {
+ return m_osResource[osIndex].str();
+ }
+}
+
+std::vector<std::string> SerialHelper::GetVISASerialPortList(int32_t* status) {
+ std::vector<std::string> retVec;
+
+ // Always add 2 onboard ports
+ retVec.emplace_back(OnboardResourceVISA);
+ retVec.emplace_back(MxpResourceVISA);
+
+ QueryHubPaths(status);
+
+ // If paths are empty or status error, return only onboard list
+ if (*status != 0 || m_visaResource.empty() || m_osResource.empty() ||
+ m_sortedHubPath.empty()) {
+ *status = 0;
+ return retVec;
+ }
+
+ for (auto& i : m_visaResource) {
+ retVec.emplace_back(i.str());
+ }
+
+ return retVec;
+}
+
+std::vector<std::string> SerialHelper::GetOSSerialPortList(int32_t* status) {
+ std::vector<std::string> retVec;
+
+ // Always add 2 onboard ports
+ retVec.emplace_back(OnboardResourceOS);
+ retVec.emplace_back(MxpResourceOS);
+
+ QueryHubPaths(status);
+
+ // If paths are empty or status error, return only onboard list
+ if (*status != 0 || m_visaResource.empty() || m_osResource.empty() ||
+ m_sortedHubPath.empty()) {
+ *status = 0;
+ return retVec;
+ }
+
+ for (auto& i : m_osResource) {
+ retVec.emplace_back(i.str());
+ }
+
+ return retVec;
+}
+
+void SerialHelper::SortHubPathVector() {
+ m_sortedHubPath.clear();
+ m_sortedHubPath = m_unsortedHubPath;
+ std::sort(m_sortedHubPath.begin(), m_sortedHubPath.end(),
+ [](const wpi::SmallVectorImpl<char>& lhs,
+ const wpi::SmallVectorImpl<char>& rhs) -> int {
+ wpi::StringRef lhsRef(lhs.begin(), lhs.size());
+ wpi::StringRef rhsRef(rhs.begin(), rhs.size());
+ return lhsRef.compare(rhsRef);
+ });
+}
+
+void SerialHelper::CoiteratedSort(
+ wpi::SmallVectorImpl<wpi::SmallString<16>>& vec) {
+ wpi::SmallVector<wpi::SmallString<16>, 4> sortedVec;
+ for (auto& str : m_sortedHubPath) {
+ for (size_t i = 0; i < m_unsortedHubPath.size(); i++) {
+ if (wpi::StringRef{m_unsortedHubPath[i].begin(),
+ m_unsortedHubPath[i].size()}
+ .equals(wpi::StringRef{str.begin(), str.size()})) {
+ sortedVec.push_back(vec[i]);
+ break;
+ }
+ }
+ }
+ vec = sortedVec;
+}
+
+void SerialHelper::QueryHubPaths(int32_t* status) {
+ // VISA resource matching string
+ const char* str = "?*";
+ // Items needed for VISA
+ ViUInt32 retCnt = 0;
+ ViFindList viList = 0;
+ ViChar desc[VI_FIND_BUFLEN];
+ *status = viFindRsrc(m_resourceHandle, const_cast<char*>(str), &viList,
+ &retCnt, desc);
+
+ if (*status < 0) {
+ // Handle the bad status elsewhere
+ // Note let positive statii (warnings) continue
+ goto done;
+ }
+ // Status might be positive, so reset it to 0
+ *status = 0;
+
+ // Storage buffer for Visa call
+ char osName[256];
+
+ // Loop through all returned VISA objects.
+ // Increment the internal VISA ptr every loop
+ for (size_t i = 0; i < retCnt; i++, viFindNext(viList, desc)) {
+ // Ignore any matches to the 2 onboard ports
+ if (std::strcmp(OnboardResourceVISA, desc) == 0 ||
+ std::strcmp(MxpResourceVISA, desc) == 0) {
+ continue;
+ }
+
+ // Open the resource, grab its interface name, and close it.
+ ViSession vSession;
+ *status = viOpen(m_resourceHandle, desc, VI_NULL, VI_NULL, &vSession);
+ if (*status < 0) goto done;
+ *status = 0;
+
+ *status = viGetAttribute(vSession, VI_ATTR_INTF_INST_NAME, &osName);
+ // Ignore an error here, as we want to close the session on an error
+ // Use a seperate close variable so we can check
+ ViStatus closeStatus = viClose(vSession);
+ if (*status < 0) goto done;
+ if (closeStatus < 0) goto done;
+ *status = 0;
+
+ // split until (/dev/
+ wpi::StringRef devNameRef = wpi::StringRef{osName}.split("(/dev/").second;
+ // String not found, continue
+ if (devNameRef.equals("")) continue;
+
+ // Split at )
+ wpi::StringRef matchString = devNameRef.split(')').first;
+ if (matchString.equals(devNameRef)) continue;
+
+ // Search directories to get a list of system accessors
+ // The directories we need are not symbolic, so we can safely
+ // disable symbolic links.
+ std::error_code ec;
+ for (auto p = wpi::sys::fs::recursive_directory_iterator(
+ "/sys/devices/soc0", ec, false);
+ p != wpi::sys::fs::recursive_directory_iterator(); p.increment(ec)) {
+ if (ec) break;
+ wpi::StringRef path{p->path()};
+ if (path.find("amba") == wpi::StringRef::npos) continue;
+ if (path.find("usb") == wpi::StringRef::npos) continue;
+ if (path.find(matchString) == wpi::StringRef::npos) continue;
+
+ wpi::SmallVector<wpi::StringRef, 16> pathSplitVec;
+ // Split path into individual directories
+ path.split(pathSplitVec, '/', -1, false);
+
+ // Find each individual item index
+ int findusb = -1;
+ int findtty = -1;
+ int findregex = -1;
+ for (size_t i = 0; i < pathSplitVec.size(); i++) {
+ if (findusb == -1 && pathSplitVec[i].equals("usb1")) {
+ findusb = i;
+ }
+ if (findtty == -1 && pathSplitVec[i].equals("tty")) {
+ findtty = i;
+ }
+ if (findregex == -1 && pathSplitVec[i].equals(matchString)) {
+ findregex = i;
+ }
+ }
+
+ // Get the index for our device
+ int hubIndex = findtty;
+ if (findtty == -1) hubIndex = findregex;
+
+ int devStart = findusb + 1;
+
+ if (hubIndex < devStart) continue;
+
+ // Add our devices to our list
+ m_unsortedHubPath.emplace_back(
+ wpi::StringRef{pathSplitVec[hubIndex - 2]});
+ m_visaResource.emplace_back(desc);
+ m_osResource.emplace_back(
+ wpi::StringRef{osName}.split("(").second.split(")").first);
+ break;
+ }
+ }
+
+ SortHubPathVector();
+
+ CoiteratedSort(m_visaResource);
+ CoiteratedSort(m_osResource);
+done:
+ viClose(viList);
+}
+
+int32_t SerialHelper::GetIndexForPort(HAL_SerialPort port, int32_t* status) {
+ // Hold lock whenever we're using the names array
+ std::lock_guard<wpi::mutex> lock(m_nameMutex);
+
+ std::string portString = m_usbNames[port - 2];
+
+ wpi::SmallVector<int32_t, 4> indices;
+
+ // If port has not been assigned, find the one to assign
+ if (portString.empty()) {
+ for (size_t i = 0; i < 2; i++) {
+ // Remove all used ports
+ auto idx = std::find(m_sortedHubPath.begin(), m_sortedHubPath.end(),
+ m_usbNames[i]);
+ if (idx != m_sortedHubPath.end()) {
+ // found
+ m_sortedHubPath.erase(idx);
+ }
+ if (m_usbNames[i] == "") {
+ indices.push_back(i);
+ }
+ }
+
+ int32_t idx = -1;
+ for (size_t i = 0; i < indices.size(); i++) {
+ if (indices[i] == port - 2) {
+ idx = i;
+ break;
+ }
+ }
+
+ if (idx == -1) {
+ *status = HAL_SERIAL_PORT_NOT_FOUND;
+ return -1;
+ }
+
+ if (idx >= static_cast<int32_t>(m_sortedHubPath.size())) {
+ *status = HAL_SERIAL_PORT_NOT_FOUND;
+ return -1;
+ }
+
+ portString = m_sortedHubPath[idx].str();
+ m_usbNames[port - 2] = portString;
+ }
+
+ int retIndex = -1;
+
+ for (size_t i = 0; i < m_sortedHubPath.size(); i++) {
+ if (m_sortedHubPath[i].equals(portString)) {
+ retIndex = i;
+ break;
+ }
+ }
+
+ return retIndex;
+}
+
+} // namespace hal
diff --git a/hal/src/main/native/athena/ctre/CtreCanNode.cpp b/hal/src/main/native/athena/ctre/CtreCanNode.cpp
new file mode 100644
index 0000000..bd3c9e8
--- /dev/null
+++ b/hal/src/main/native/athena/ctre/CtreCanNode.cpp
@@ -0,0 +1,157 @@
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+
+#include "CtreCanNode.h"
+#include "FRC_NetworkCommunication/CANSessionMux.h"
+#include <string.h> // memset
+
+static const UINT32 kFullMessageIDMask = 0x1fffffff;
+
+CtreCanNode::CtreCanNode(UINT8 deviceNumber)
+{
+ _deviceNumber = deviceNumber;
+}
+CtreCanNode::~CtreCanNode()
+{
+}
+void CtreCanNode::RegisterRx(uint32_t arbId)
+{
+ /* no need to do anything, we just use new API to poll last received message */
+}
+/**
+ * Schedule a CAN Frame for periodic transmit.
+ * @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
+ * @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
+ * @param dlc Number of bytes to transmit (0 to 8).
+ * @param initialFrame Ptr to the frame data to schedule for transmitting. Passing null will result
+ * in defaulting to zero data value.
+ */
+void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs, uint32_t dlc, const uint8_t * initialFrame)
+{
+ int32_t status = 0;
+ if(dlc > 8)
+ dlc = 8;
+ txJob_t job = {0};
+ job.arbId = arbId;
+ job.periodMs = periodMs;
+ job.dlc = dlc;
+ if(initialFrame){
+ /* caller wants to specify original data */
+ memcpy(job.toSend, initialFrame, dlc);
+ }
+ _txJobs[arbId] = job;
+ FRC_NetworkCommunication_CANSessionMux_sendMessage( job.arbId,
+ job.toSend,
+ job.dlc,
+ job.periodMs,
+ &status);
+}
+/**
+ * Schedule a CAN Frame for periodic transmit. Assume eight byte DLC and zero value for initial transmission.
+ * @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
+ * @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
+ */
+void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs)
+{
+ RegisterTx(arbId,periodMs, 8, 0);
+}
+/**
+ * Remove a CAN frame Arbid to stop transmission.
+ * @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
+ */
+void CtreCanNode::UnregisterTx(uint32_t arbId)
+{
+ /* set period to zero */
+ ChangeTxPeriod(arbId, 0);
+ /* look and remove */
+ txJobs_t::iterator iter = _txJobs.find(arbId);
+ if(iter != _txJobs.end()) {
+ _txJobs.erase(iter);
+ }
+}
+static int64_t GetTimeMs() {
+ std::chrono::time_point < std::chrono::system_clock > now;
+ now = std::chrono::system_clock::now();
+ auto duration = now.time_since_epoch();
+ auto millis = std::chrono::duration_cast < std::chrono::milliseconds
+ > (duration).count();
+ return (int64_t) millis;
+}
+CTR_Code CtreCanNode::GetRx(uint32_t arbId,uint8_t * dataBytes, uint32_t timeoutMs)
+{
+ CTR_Code retval = CTR_OKAY;
+ int32_t status = 0;
+ uint8_t len = 0;
+ uint32_t timeStamp;
+ /* cap timeout at 999ms */
+ if(timeoutMs > 999)
+ timeoutMs = 999;
+ FRC_NetworkCommunication_CANSessionMux_receiveMessage(&arbId,kFullMessageIDMask,dataBytes,&len,&timeStamp,&status);
+ std::lock_guard<wpi::mutex> lock(_lck);
+ if(status == 0){
+ /* fresh update */
+ rxEvent_t & r = _rxRxEvents[arbId]; /* lookup entry or make a default new one with all zeroes */
+ r.time = GetTimeMs();
+ memcpy(r.bytes, dataBytes, 8); /* fill in databytes */
+ }else{
+ /* did not get the message */
+ rxRxEvents_t::iterator i = _rxRxEvents.find(arbId);
+ if(i == _rxRxEvents.end()){
+ /* we've never gotten this mesage */
+ retval = CTR_RxTimeout;
+ /* fill caller's buffer with zeros */
+ memset(dataBytes,0,8);
+ }else{
+ /* we've gotten this message before but not recently */
+ memcpy(dataBytes,i->second.bytes,8);
+ /* get the time now */
+ int64_t now = GetTimeMs(); /* get now */
+ /* how long has it been? */
+ int64_t temp = now - i->second.time; /* temp = now - last */
+ if (temp > ((int64_t) timeoutMs)) {
+ retval = CTR_RxTimeout;
+ } else {
+ /* our last update was recent enough */
+ }
+ }
+ }
+
+ return retval;
+}
+void CtreCanNode::FlushTx(uint32_t arbId)
+{
+ int32_t status = 0;
+ txJobs_t::iterator iter = _txJobs.find(arbId);
+ if(iter != _txJobs.end())
+ FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
+ iter->second.toSend,
+ iter->second.dlc,
+ iter->second.periodMs,
+ &status);
+}
+/**
+ * Change the transmit period of an already scheduled CAN frame.
+ * This keeps the frame payload contents the same without caller having to perform
+ * a read-modify-write.
+ * @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
+ * @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
+ * @return true if scheduled job was found and updated, false if there was no preceding job for the specified arbID.
+ */
+bool CtreCanNode::ChangeTxPeriod(uint32_t arbId, uint32_t periodMs)
+{
+ int32_t status = 0;
+ /* lookup the data bytes and period for this message */
+ txJobs_t::iterator iter = _txJobs.find(arbId);
+ if(iter != _txJobs.end()) {
+ /* modify th periodMs */
+ iter->second.periodMs = periodMs;
+ /* reinsert into scheduler with the same data bytes, only the period changed. */
+ FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
+ iter->second.toSend,
+ iter->second.dlc,
+ iter->second.periodMs,
+ &status);
+ return true;
+ }
+ return false;
+}
+
diff --git a/hal/src/main/native/athena/ctre/CtreCanNode.h b/hal/src/main/native/athena/ctre/CtreCanNode.h
new file mode 100644
index 0000000..f00060d
--- /dev/null
+++ b/hal/src/main/native/athena/ctre/CtreCanNode.h
@@ -0,0 +1,134 @@
+#ifndef CtreCanNode_H_
+#define CtreCanNode_H_
+#include "ctre.h" //BIT Defines + Typedefs
+#include <map>
+#include <string.h> // memcpy
+#include <sys/time.h>
+#include <wpi/mutex.h>
+class CtreCanNode
+{
+public:
+ CtreCanNode(UINT8 deviceNumber);
+ ~CtreCanNode();
+
+ UINT8 GetDeviceNumber()
+ {
+ return _deviceNumber;
+ }
+protected:
+
+
+ template <typename T> class txTask{
+ public:
+ uint32_t arbId;
+ T * toSend;
+ T * operator -> ()
+ {
+ return toSend;
+ }
+ T & operator*()
+ {
+ return *toSend;
+ }
+ bool IsEmpty()
+ {
+ if(toSend == 0)
+ return true;
+ return false;
+ }
+ };
+ template <typename T> class recMsg{
+ public:
+ uint32_t arbId;
+ uint8_t bytes[8];
+ CTR_Code err;
+ T * operator -> ()
+ {
+ return (T *)bytes;
+ }
+ T & operator*()
+ {
+ return *(T *)bytes;
+ }
+ };
+ UINT8 _deviceNumber;
+ void RegisterRx(uint32_t arbId);
+ /**
+ * Schedule a CAN Frame for periodic transmit. Assume eight byte DLC and zero value for initial transmission.
+ * @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
+ * @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
+ */
+ void RegisterTx(uint32_t arbId, uint32_t periodMs);
+ /**
+ * Schedule a CAN Frame for periodic transmit.
+ * @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
+ * @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
+ * @param dlc Number of bytes to transmit (0 to 8).
+ * @param initialFrame Ptr to the frame data to schedule for transmitting. Passing null will result
+ * in defaulting to zero data value.
+ */
+ void RegisterTx(uint32_t arbId, uint32_t periodMs, uint32_t dlc, const uint8_t * initialFrame);
+ void UnregisterTx(uint32_t arbId);
+
+ CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs);
+ void FlushTx(uint32_t arbId);
+ bool ChangeTxPeriod(uint32_t arbId, uint32_t periodMs);
+
+ template<typename T> txTask<T> GetTx(uint32_t arbId)
+ {
+ txTask<T> retval = {0, nullptr};
+ txJobs_t::iterator i = _txJobs.find(arbId);
+ if(i != _txJobs.end()){
+ retval.arbId = i->second.arbId;
+ retval.toSend = (T*)i->second.toSend;
+ }
+ return retval;
+ }
+ template<class T> void FlushTx(T & par)
+ {
+ FlushTx(par.arbId);
+ }
+
+ template<class T> recMsg<T> GetRx(uint32_t arbId, uint32_t timeoutMs)
+ {
+ recMsg<T> retval;
+ retval.err = GetRx(arbId,retval.bytes, timeoutMs);
+ return retval;
+ }
+
+private:
+
+ class txJob_t {
+ public:
+ uint32_t arbId;
+ uint8_t toSend[8];
+ uint32_t periodMs;
+ uint8_t dlc;
+ };
+
+ class rxEvent_t{
+ public:
+ uint8_t bytes[8];
+ int64_t time;
+ rxEvent_t()
+ {
+ bytes[0] = 0;
+ bytes[1] = 0;
+ bytes[2] = 0;
+ bytes[3] = 0;
+ bytes[4] = 0;
+ bytes[5] = 0;
+ bytes[6] = 0;
+ bytes[7] = 0;
+ }
+ };
+
+ typedef std::map<uint32_t,txJob_t> txJobs_t;
+ txJobs_t _txJobs;
+
+ typedef std::map<uint32_t,rxEvent_t> rxRxEvents_t;
+ rxRxEvents_t _rxRxEvents;
+
+ wpi::mutex _lck;
+};
+#endif
diff --git a/hal/src/main/native/athena/ctre/PCM.cpp b/hal/src/main/native/athena/ctre/PCM.cpp
new file mode 100644
index 0000000..e05d4d4
--- /dev/null
+++ b/hal/src/main/native/athena/ctre/PCM.cpp
@@ -0,0 +1,574 @@
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+
+#include "PCM.h"
+#include "FRC_NetworkCommunication/CANSessionMux.h"
+#include <string.h> // memset
+/* This can be a constant, as long as nobody needs to update solenoids within
+ 1/50 of a second. */
+static const INT32 kCANPeriod = 20;
+
+#define STATUS_1 0x9041400
+#define STATUS_SOL_FAULTS 0x9041440
+#define STATUS_DEBUG 0x9041480
+
+#define EXPECTED_RESPONSE_TIMEOUT_MS (50)
+#define GET_PCM_STATUS() CtreCanNode::recMsg<PcmStatus_t> rx = GetRx<PcmStatus_t> (STATUS_1|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)
+#define GET_PCM_SOL_FAULTS() CtreCanNode::recMsg<PcmStatusFault_t> rx = GetRx<PcmStatusFault_t> (STATUS_SOL_FAULTS|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)
+#define GET_PCM_DEBUG() CtreCanNode::recMsg<PcmDebug_t> rx = GetRx<PcmDebug_t> (STATUS_DEBUG|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)
+
+#define CONTROL_1 0x09041C00 /* PCM_Control */
+#define CONTROL_2 0x09041C40 /* PCM_SupplemControl */
+#define CONTROL_3 0x09041C80 /* PcmControlSetOneShotDur_t */
+
+/* encoder/decoders */
+typedef struct _PcmStatus_t{
+ /* Byte 0 */
+ unsigned SolenoidBits:8;
+ /* Byte 1 */
+ unsigned compressorOn:1;
+ unsigned stickyFaultFuseTripped:1;
+ unsigned stickyFaultCompCurrentTooHigh:1;
+ unsigned faultFuseTripped:1;
+ unsigned faultCompCurrentTooHigh:1;
+ unsigned faultHardwareFailure:1;
+ unsigned isCloseloopEnabled:1;
+ unsigned pressureSwitchEn:1;
+ /* Byte 2*/
+ unsigned battVoltage:8;
+ /* Byte 3 */
+ unsigned solenoidVoltageTop8:8;
+ /* Byte 4 */
+ unsigned compressorCurrentTop6:6;
+ unsigned solenoidVoltageBtm2:2;
+ /* Byte 5 */
+ unsigned StickyFault_dItooHigh :1;
+ unsigned Fault_dItooHigh :1;
+ unsigned moduleEnabled:1;
+ unsigned closedLoopOutput:1;
+ unsigned compressorCurrentBtm4:4;
+ /* Byte 6 */
+ unsigned tokenSeedTop8:8;
+ /* Byte 7 */
+ unsigned tokenSeedBtm8:8;
+}PcmStatus_t;
+
+typedef struct _PcmControl_t{
+ /* Byte 0 */
+ unsigned tokenTop8:8;
+ /* Byte 1 */
+ unsigned tokenBtm8:8;
+ /* Byte 2 */
+ unsigned solenoidBits:8;
+ /* Byte 3*/
+ unsigned reserved:4;
+ unsigned closeLoopOutput:1;
+ unsigned compressorOn:1;
+ unsigned closedLoopEnable:1;
+ unsigned clearStickyFaults:1;
+ /* Byte 4 */
+ unsigned OneShotField_h8:8;
+ /* Byte 5 */
+ unsigned OneShotField_l8:8;
+}PcmControl_t;
+
+typedef struct _PcmControlSetOneShotDur_t{
+ uint8_t sol10MsPerUnit[8];
+}PcmControlSetOneShotDur_t;
+
+typedef struct _PcmStatusFault_t{
+ /* Byte 0 */
+ unsigned SolenoidBlacklist:8;
+ /* Byte 1 */
+ unsigned reserved_bit0 :1;
+ unsigned reserved_bit1 :1;
+ unsigned reserved_bit2 :1;
+ unsigned reserved_bit3 :1;
+ unsigned StickyFault_CompNoCurrent :1;
+ unsigned Fault_CompNoCurrent :1;
+ unsigned StickyFault_SolenoidJumper :1;
+ unsigned Fault_SolenoidJumper :1;
+}PcmStatusFault_t;
+
+typedef struct _PcmDebug_t{
+ unsigned tokFailsTop8:8;
+ unsigned tokFailsBtm8:8;
+ unsigned lastFailedTokTop8:8;
+ unsigned lastFailedTokBtm8:8;
+ unsigned tokSuccessTop8:8;
+ unsigned tokSuccessBtm8:8;
+}PcmDebug_t;
+
+
+/* PCM Constructor - Clears all vars, establishes default settings, starts PCM background process
+ *
+ * @Return - void
+ *
+ * @Param - deviceNumber - Device ID of PCM to be controlled
+ */
+PCM::PCM(UINT8 deviceNumber): CtreCanNode(deviceNumber)
+{
+ RegisterRx(STATUS_1 | deviceNumber );
+ RegisterRx(STATUS_SOL_FAULTS | deviceNumber );
+ RegisterRx(STATUS_DEBUG | deviceNumber );
+ RegisterTx(CONTROL_1 | deviceNumber, kCANPeriod);
+ /* enable close loop */
+ SetClosedLoopControl(1);
+}
+/* PCM D'tor
+ */
+PCM::~PCM()
+{
+
+}
+
+/* Set PCM solenoid state
+ *
+ * @Return - CTR_Code - Error code (if any) for setting solenoid
+ *
+ * @Param - idx - ID of solenoid (0-7)
+ * @Param - en - Enable / Disable identified solenoid
+ */
+CTR_Code PCM::SetSolenoid(unsigned char idx, bool en)
+{
+ CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
+ if(toFill.IsEmpty())return CTR_UnexpectedArbId;
+ if (en)
+ toFill->solenoidBits |= (1ul << (idx));
+ else
+ toFill->solenoidBits &= ~(1ul << (idx));
+ FlushTx(toFill);
+ return CTR_OKAY;
+}
+
+/* Set all PCM solenoid states
+ *
+ * @Return - CTR_Code - Error code (if any) for setting solenoids
+ * @Param - state Bitfield to set all solenoids to
+ */
+CTR_Code PCM::SetAllSolenoids(UINT8 state) {
+ CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
+ if(toFill.IsEmpty())return CTR_UnexpectedArbId;
+ toFill->solenoidBits = state;
+ FlushTx(toFill);
+ return CTR_OKAY;
+}
+
+/* Clears PCM sticky faults (indicators of past faults
+ *
+ * @Return - CTR_Code - Error code (if any) for setting solenoid
+ *
+ * @Param - clr - Clear / do not clear faults
+ */
+CTR_Code PCM::ClearStickyFaults()
+{
+ int32_t status = 0;
+ uint8_t pcmSupplemControl[] = { 0, 0, 0, 0x80 }; /* only bit set is ClearStickyFaults */
+ FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_2 | GetDeviceNumber(), pcmSupplemControl, sizeof(pcmSupplemControl), 0, &status);
+ if(status)
+ return CTR_TxFailed;
+ return CTR_OKAY;
+}
+
+/* Enables PCM Closed Loop Control of Compressor via pressure switch
+ *
+ * @Return - CTR_Code - Error code (if any) for setting solenoid
+ *
+ * @Param - en - Enable / Disable Closed Loop Control
+ */
+CTR_Code PCM::SetClosedLoopControl(bool en)
+{
+ CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
+ if(toFill.IsEmpty())return CTR_UnexpectedArbId;
+ toFill->closedLoopEnable = en;
+ FlushTx(toFill);
+ return CTR_OKAY;
+}
+/* Get solenoid Blacklist status
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - idx - ID of solenoid [0,7] to fire one shot pulse.
+ */
+CTR_Code PCM::FireOneShotSolenoid(UINT8 idx)
+{
+ CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
+ if(toFill.IsEmpty())return CTR_UnexpectedArbId;
+ /* grab field as it is now */
+ uint16_t oneShotField;
+ oneShotField = toFill->OneShotField_h8;
+ oneShotField <<= 8;
+ oneShotField |= toFill->OneShotField_l8;
+ /* get the caller's channel */
+ uint16_t shift = 2*idx;
+ uint16_t mask = 3; /* two bits wide */
+ uint8_t chBits = (oneShotField >> shift) & mask;
+ /* flip it */
+ chBits = (chBits)%3 + 1;
+ /* clear out 2bits for this channel*/
+ oneShotField &= ~(mask << shift);
+ /* put new field in */
+ oneShotField |= chBits << shift;
+ /* apply field as it is now */
+ toFill->OneShotField_h8 = oneShotField >> 8;
+ toFill->OneShotField_l8 = oneShotField;
+ FlushTx(toFill);
+ return CTR_OKAY;
+}
+/* Configure the pulse width of a solenoid channel for one-shot pulse.
+ * Preprogrammed pulsewidth is 10ms resolution and can be between 10ms and
+ * 2.55s.
+ *
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - idx - ID of solenoid [0,7] to configure.
+ * @Param - durMs - pulse width in ms.
+ */
+CTR_Code PCM::SetOneShotDurationMs(UINT8 idx,uint32_t durMs)
+{
+ /* sanity check caller's param */
+ if(idx > 7)
+ return CTR_InvalidParamValue;
+ /* get latest tx frame */
+ CtreCanNode::txTask<PcmControlSetOneShotDur_t> toFill = GetTx<PcmControlSetOneShotDur_t>(CONTROL_3 | GetDeviceNumber());
+ if(toFill.IsEmpty()){
+ /* only send this out if caller wants to do one-shots */
+ RegisterTx(CONTROL_3 | _deviceNumber, kCANPeriod);
+ /* grab it */
+ toFill = GetTx<PcmControlSetOneShotDur_t>(CONTROL_3 | GetDeviceNumber());
+ }
+ toFill->sol10MsPerUnit[idx] = std::min(durMs/10,(uint32_t)0xFF);
+ /* apply the new data bytes */
+ FlushTx(toFill);
+ return CTR_OKAY;
+}
+
+/* Get solenoid state
+ *
+ * @Return - True/False - True if solenoid enabled, false otherwise
+ *
+ * @Param - idx - ID of solenoid (0-7) to return status of
+ */
+CTR_Code PCM::GetSolenoid(UINT8 idx, bool &status)
+{
+ GET_PCM_STATUS();
+ status = (rx->SolenoidBits & (1ul<<(idx)) ) ? 1 : 0;
+ return rx.err;
+}
+
+/* Get solenoid state for all solenoids on the PCM
+ *
+ * @Return - Bitfield of solenoid states
+ */
+CTR_Code PCM::GetAllSolenoids(UINT8 &status)
+{
+ GET_PCM_STATUS();
+ status = rx->SolenoidBits;
+ return rx.err;
+}
+
+/* Get pressure switch state
+ *
+ * @Return - True/False - True if pressure adequate, false if low
+ */
+CTR_Code PCM::GetPressure(bool &status)
+{
+ GET_PCM_STATUS();
+ status = (rx->pressureSwitchEn ) ? 1 : 0;
+ return rx.err;
+}
+
+/* Get compressor state
+ *
+ * @Return - True/False - True if enabled, false if otherwise
+ */
+CTR_Code PCM::GetCompressor(bool &status)
+{
+ GET_PCM_STATUS();
+ status = (rx->compressorOn);
+ return rx.err;
+}
+
+/* Get closed loop control state
+ *
+ * @Return - True/False - True if closed loop enabled, false if otherwise
+ */
+CTR_Code PCM::GetClosedLoopControl(bool &status)
+{
+ GET_PCM_STATUS();
+ status = (rx->isCloseloopEnabled);
+ return rx.err;
+}
+
+/* Get compressor current draw
+ *
+ * @Return - Amperes - Compressor current
+ */
+CTR_Code PCM::GetCompressorCurrent(float &status)
+{
+ GET_PCM_STATUS();
+ uint32_t temp =(rx->compressorCurrentTop6);
+ temp <<= 4;
+ temp |= rx->compressorCurrentBtm4;
+ status = temp * 0.03125; /* 5.5 fixed pt value in Amps */
+ return rx.err;
+}
+
+/* Get voltage across solenoid rail
+ *
+ * @Return - Volts - Voltage across solenoid rail
+ */
+CTR_Code PCM::GetSolenoidVoltage(float &status)
+{
+ GET_PCM_STATUS();
+ uint32_t raw =(rx->solenoidVoltageTop8);
+ raw <<= 2;
+ raw |= rx->solenoidVoltageBtm2;
+ status = (double) raw * 0.03125; /* 5.5 fixed pt value in Volts */
+ return rx.err;
+}
+
+/* Get hardware fault value
+ *
+ * @Return - True/False - True if hardware failure detected, false if otherwise
+ */
+CTR_Code PCM::GetHardwareFault(bool &status)
+{
+ GET_PCM_STATUS();
+ status = rx->faultHardwareFailure;
+ return rx.err;
+}
+
+/* Get compressor fault value
+ *
+ * @Return - True/False - True if shorted compressor detected, false if otherwise
+ */
+CTR_Code PCM::GetCompressorCurrentTooHighFault(bool &status)
+{
+ GET_PCM_STATUS();
+ status = rx->faultCompCurrentTooHigh;
+ return rx.err;
+}
+CTR_Code PCM::GetCompressorShortedStickyFault(bool &status)
+{
+ GET_PCM_STATUS();
+ status = rx->StickyFault_dItooHigh;
+ return rx.err;
+}
+CTR_Code PCM::GetCompressorShortedFault(bool &status)
+{
+ GET_PCM_STATUS();
+ status = rx->Fault_dItooHigh;
+ return rx.err;
+}
+CTR_Code PCM::GetCompressorNotConnectedStickyFault(bool &status)
+{
+ GET_PCM_SOL_FAULTS();
+ status = rx->StickyFault_CompNoCurrent;
+ return rx.err;
+}
+CTR_Code PCM::GetCompressorNotConnectedFault(bool &status)
+{
+ GET_PCM_SOL_FAULTS();
+ status = rx->Fault_CompNoCurrent;
+ return rx.err;
+}
+
+/* Get solenoid fault value
+ *
+ * @Return - True/False - True if shorted solenoid detected, false if otherwise
+ */
+CTR_Code PCM::GetSolenoidFault(bool &status)
+{
+ GET_PCM_STATUS();
+ status = rx->faultFuseTripped;
+ return rx.err;
+}
+
+/* Get compressor sticky fault value
+ *
+ * @Return - True/False - True if solenoid had previously been shorted
+ * (and sticky fault was not cleared), false if otherwise
+ */
+CTR_Code PCM::GetCompressorCurrentTooHighStickyFault(bool &status)
+{
+ GET_PCM_STATUS();
+ status = rx->stickyFaultCompCurrentTooHigh;
+ return rx.err;
+}
+
+/* Get solenoid sticky fault value
+ *
+ * @Return - True/False - True if compressor had previously been shorted
+ * (and sticky fault was not cleared), false if otherwise
+ */
+CTR_Code PCM::GetSolenoidStickyFault(bool &status)
+{
+ GET_PCM_STATUS();
+ status = rx->stickyFaultFuseTripped;
+ return rx.err;
+}
+/* Get battery voltage
+ *
+ * @Return - Volts - Voltage across PCM power ports
+ */
+CTR_Code PCM::GetBatteryVoltage(float &status)
+{
+ GET_PCM_STATUS();
+ status = (float)rx->battVoltage * 0.05 + 4.0; /* 50mV per unit plus 4V. */
+ return rx.err;
+}
+/* Return status of module enable/disable
+ *
+ * @Return - bool - Returns TRUE if PCM is enabled, FALSE if disabled
+ */
+CTR_Code PCM::isModuleEnabled(bool &status)
+{
+ GET_PCM_STATUS();
+ status = rx->moduleEnabled;
+ return rx.err;
+}
+/* Get number of total failed PCM Control Frame
+ *
+ * @Return - Failed Control Frames - Number of failed control frames (tokenization fails)
+ *
+ * @WARNING - Return only valid if [SeekDebugFrames] is enabled
+ * See function SeekDebugFrames
+ * See function EnableSeekDebugFrames
+ */
+CTR_Code PCM::GetNumberOfFailedControlFrames(UINT16 &status)
+{
+ GET_PCM_DEBUG();
+ status = rx->tokFailsTop8;
+ status <<= 8;
+ status |= rx->tokFailsBtm8;
+ return rx.err;
+}
+/* Get raw Solenoid Blacklist
+ *
+ * @Return - BINARY - Raw binary breakdown of Solenoid Blacklist
+ * BIT7 = Solenoid 1, BIT6 = Solenoid 2, etc.
+ *
+ * @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled
+ * See function SeekStatusFaultFrames
+ * See function EnableSeekStatusFaultFrames
+ */
+CTR_Code PCM::GetSolenoidBlackList(UINT8 &status)
+{
+ GET_PCM_SOL_FAULTS();
+ status = rx->SolenoidBlacklist;
+ return rx.err;
+}
+/* Get solenoid Blacklist status
+ * - Blacklisted solenoids cannot be enabled until PCM is power cycled
+ *
+ * @Return - True/False - True if Solenoid is blacklisted, false if otherwise
+ *
+ * @Param - idx - ID of solenoid [0,7]
+ *
+ * @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled
+ * See function SeekStatusFaultFrames
+ * See function EnableSeekStatusFaultFrames
+ */
+CTR_Code PCM::IsSolenoidBlacklisted(UINT8 idx, bool &status)
+{
+ GET_PCM_SOL_FAULTS();
+ status = (rx->SolenoidBlacklist & (1ul<<(idx)) )? 1 : 0;
+ return rx.err;
+}
+//------------------ C interface --------------------------------------------//
+extern "C" {
+ void * c_PCM_Init(void) {
+ return new PCM();
+ }
+ CTR_Code c_SetSolenoid(void * handle, unsigned char idx, INT8 param) {
+ return ((PCM*) handle)->SetSolenoid(idx, param);
+ }
+ CTR_Code c_SetAllSolenoids(void * handle, UINT8 state) {
+ return ((PCM*) handle)->SetAllSolenoids(state);
+ }
+ CTR_Code c_SetClosedLoopControl(void * handle, INT8 param) {
+ return ((PCM*) handle)->SetClosedLoopControl(param);
+ }
+ CTR_Code c_ClearStickyFaults(void * handle, INT8 param) {
+ return ((PCM*) handle)->ClearStickyFaults();
+ }
+ CTR_Code c_GetSolenoid(void * handle, UINT8 idx, INT8 * status) {
+ bool bstatus;
+ CTR_Code retval = ((PCM*) handle)->GetSolenoid(idx, bstatus);
+ *status = bstatus;
+ return retval;
+ }
+ CTR_Code c_GetAllSolenoids(void * handle, UINT8 * status) {
+ return ((PCM*) handle)->GetAllSolenoids(*status);
+ }
+ CTR_Code c_GetPressure(void * handle, INT8 * status) {
+ bool bstatus;
+ CTR_Code retval = ((PCM*) handle)->GetPressure(bstatus);
+ *status = bstatus;
+ return retval;
+ }
+ CTR_Code c_GetCompressor(void * handle, INT8 * status) {
+ bool bstatus;
+ CTR_Code retval = ((PCM*) handle)->GetCompressor(bstatus);
+ *status = bstatus;
+ return retval;
+ }
+ CTR_Code c_GetClosedLoopControl(void * handle, INT8 * status) {
+ bool bstatus;
+ CTR_Code retval = ((PCM*) handle)->GetClosedLoopControl(bstatus);
+ *status = bstatus;
+ return retval;
+ }
+ CTR_Code c_GetCompressorCurrent(void * handle, float * status) {
+ CTR_Code retval = ((PCM*) handle)->GetCompressorCurrent(*status);
+ return retval;
+ }
+ CTR_Code c_GetSolenoidVoltage(void * handle, float*status) {
+ return ((PCM*) handle)->GetSolenoidVoltage(*status);
+ }
+ CTR_Code c_GetHardwareFault(void * handle, INT8*status) {
+ bool bstatus;
+ CTR_Code retval = ((PCM*) handle)->GetHardwareFault(bstatus);
+ *status = bstatus;
+ return retval;
+ }
+ CTR_Code c_GetCompressorFault(void * handle, INT8*status) {
+ bool bstatus;
+ CTR_Code retval = ((PCM*) handle)->GetCompressorCurrentTooHighFault(bstatus);
+ *status = bstatus;
+ return retval;
+ }
+ CTR_Code c_GetSolenoidFault(void * handle, INT8*status) {
+ bool bstatus;
+ CTR_Code retval = ((PCM*) handle)->GetSolenoidFault(bstatus);
+ *status = bstatus;
+ return retval;
+ }
+ CTR_Code c_GetCompressorStickyFault(void * handle, INT8*status) {
+ bool bstatus;
+ CTR_Code retval = ((PCM*) handle)->GetCompressorCurrentTooHighStickyFault(bstatus);
+ *status = bstatus;
+ return retval;
+ }
+ CTR_Code c_GetSolenoidStickyFault(void * handle, INT8*status) {
+ bool bstatus;
+ CTR_Code retval = ((PCM*) handle)->GetSolenoidStickyFault(bstatus);
+ *status = bstatus;
+ return retval;
+ }
+ CTR_Code c_GetBatteryVoltage(void * handle, float*status) {
+ CTR_Code retval = ((PCM*) handle)->GetBatteryVoltage(*status);
+ return retval;
+ }
+ void c_SetDeviceNumber_PCM(void * handle, UINT8 deviceNumber) {
+ }
+ CTR_Code c_GetNumberOfFailedControlFrames(void * handle, UINT16*status) {
+ return ((PCM*) handle)->GetNumberOfFailedControlFrames(*status);
+ }
+ CTR_Code c_GetSolenoidBlackList(void * handle, UINT8 *status) {
+ return ((PCM*) handle)->GetSolenoidBlackList(*status);
+ }
+ CTR_Code c_IsSolenoidBlacklisted(void * handle, UINT8 idx, INT8*status) {
+ bool bstatus;
+ CTR_Code retval = ((PCM*) handle)->IsSolenoidBlacklisted(idx, bstatus);
+ *status = bstatus;
+ return retval;
+ }
+}
diff --git a/hal/src/main/native/athena/ctre/PCM.h b/hal/src/main/native/athena/ctre/PCM.h
new file mode 100644
index 0000000..b485219
--- /dev/null
+++ b/hal/src/main/native/athena/ctre/PCM.h
@@ -0,0 +1,226 @@
+#ifndef PCM_H_
+#define PCM_H_
+#include "ctre.h" //BIT Defines + Typedefs
+#include "CtreCanNode.h"
+class PCM : public CtreCanNode
+{
+public:
+ PCM(UINT8 deviceNumber=0);
+ ~PCM();
+
+ /* Set PCM solenoid state
+ *
+ * @Return - CTR_Code - Error code (if any) for setting solenoid
+ * @Param - idx - ID of solenoid (0-7)
+ * @Param - en - Enable / Disable identified solenoid
+ */
+ CTR_Code SetSolenoid(unsigned char idx, bool en);
+
+ /* Set all PCM solenoid states
+ *
+ * @Return - CTR_Code - Error code (if any) for setting solenoids
+ * @Param - state Bitfield to set all solenoids to
+ */
+ CTR_Code SetAllSolenoids(UINT8 state);
+
+ /* Enables PCM Closed Loop Control of Compressor via pressure switch
+ * @Return - CTR_Code - Error code (if any) for setting solenoid
+ * @Param - en - Enable / Disable Closed Loop Control
+ */
+ CTR_Code SetClosedLoopControl(bool en);
+
+ /* Clears PCM sticky faults (indicators of past faults
+ * @Return - CTR_Code - Error code (if any) for setting solenoid
+ */
+ CTR_Code ClearStickyFaults();
+
+ /* Get solenoid state
+ *
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - idx - ID of solenoid (0-7) to return if solenoid is on.
+ * @Param - status - true if solenoid enabled, false otherwise
+ */
+ CTR_Code GetSolenoid(UINT8 idx, bool &status);
+
+ /* Get state of all solenoids
+ *
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - bitfield of solenoid states
+ */
+ CTR_Code GetAllSolenoids(UINT8 &status);
+
+ /* Get pressure switch state
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - True if pressure adequate, false if low
+ */
+ CTR_Code GetPressure(bool &status);
+
+ /* Get compressor state
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - True if compress ouput is on, false if otherwise
+ */
+ CTR_Code GetCompressor(bool &status);
+
+ /* Get closed loop control state
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - True if closed loop enabled, false if otherwise
+ */
+ CTR_Code GetClosedLoopControl(bool &status);
+
+ /* Get compressor current draw
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - Compressor current returned in Amperes (A)
+ */
+ CTR_Code GetCompressorCurrent(float &status);
+
+ /* Get voltage across solenoid rail
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - Voltage across solenoid rail in Volts (V)
+ */
+ CTR_Code GetSolenoidVoltage(float &status);
+
+ /* Get hardware fault value
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - True if hardware failure detected, false if otherwise
+ */
+ CTR_Code GetHardwareFault(bool &status);
+
+ /* Get compressor fault value
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - True if abnormally high compressor current detected, false if otherwise
+ */
+ CTR_Code GetCompressorCurrentTooHighFault(bool &status);
+
+ /* Get solenoid fault value
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - True if shorted solenoid detected, false if otherwise
+ */
+ CTR_Code GetSolenoidFault(bool &status);
+
+ /* Get compressor sticky fault value
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - True if solenoid had previously been shorted
+ * (and sticky fault was not cleared), false if otherwise
+ */
+ CTR_Code GetCompressorCurrentTooHighStickyFault(bool &status);
+ /* Get compressor shorted sticky fault value
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - True if compressor output is shorted, false if otherwise
+ */
+ CTR_Code GetCompressorShortedStickyFault(bool &status);
+ /* Get compressor shorted fault value
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - True if compressor output is shorted, false if otherwise
+ */
+ CTR_Code GetCompressorShortedFault(bool &status);
+ /* Get compressor is not connected sticky fault value
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - True if compressor current is too low,
+ * indicating compressor is not connected, false if otherwise
+ */
+ CTR_Code GetCompressorNotConnectedStickyFault(bool &status);
+ /* Get compressor is not connected fault value
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - True if compressor current is too low,
+ * indicating compressor is not connected, false if otherwise
+ */
+ CTR_Code GetCompressorNotConnectedFault(bool &status);
+
+ /* Get solenoid sticky fault value
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - True if compressor had previously been shorted
+ * (and sticky fault was not cleared), false if otherwise
+ */
+ CTR_Code GetSolenoidStickyFault(bool &status);
+
+ /* Get battery voltage
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - Voltage across PCM power ports in Volts (V)
+ */
+ CTR_Code GetBatteryVoltage(float &status);
+
+ /* Set PCM Device Number and according CAN frame IDs
+ * @Return - void
+ * @Param - deviceNumber - Device number of PCM to control
+ */
+ void SetDeviceNumber(UINT8 deviceNumber);
+ /* Get number of total failed PCM Control Frame
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - Number of failed control frames (tokenization fails)
+ * @WARNING - Return only valid if [SeekDebugFrames] is enabled
+ * See function SeekDebugFrames
+ * See function EnableSeekDebugFrames
+ */
+ CTR_Code GetNumberOfFailedControlFrames(UINT16 &status);
+
+ /* Get raw Solenoid Blacklist
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - Raw binary breakdown of Solenoid Blacklist
+ * BIT7 = Solenoid 1, BIT6 = Solenoid 2, etc.
+ * @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled
+ * See function SeekStatusFaultFrames
+ * See function EnableSeekStatusFaultFrames
+ */
+ CTR_Code GetSolenoidBlackList(UINT8 &status);
+
+ /* Get solenoid Blacklist status
+ * - Blacklisted solenoids cannot be enabled until PCM is power cycled
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - idx - ID of solenoid [0,7]
+ * @Param - status - True if Solenoid is blacklisted, false if otherwise
+ * @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled
+ * See function SeekStatusFaultFrames
+ * See function EnableSeekStatusFaultFrames
+ */
+ CTR_Code IsSolenoidBlacklisted(UINT8 idx, bool &status);
+
+ /* Return status of module enable/disable
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - status - Returns TRUE if PCM is enabled, FALSE if disabled
+ */
+ CTR_Code isModuleEnabled(bool &status);
+
+ /* Get solenoid Blacklist status
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - idx - ID of solenoid [0,7] to fire one shot pulse.
+ */
+ CTR_Code FireOneShotSolenoid(UINT8 idx);
+
+ /* Configure the pulse width of a solenoid channel for one-shot pulse.
+ * Preprogrammed pulsewidth is 10ms resolute and can be between 20ms and 5.1s.
+ * @Return - CTR_Code - Error code (if any)
+ * @Param - idx - ID of solenoid [0,7] to configure.
+ * @Param - durMs - pulse width in ms.
+ */
+ CTR_Code SetOneShotDurationMs(UINT8 idx,uint32_t durMs);
+
+};
+//------------------ C interface --------------------------------------------//
+extern "C" {
+ void * c_PCM_Init(void);
+ CTR_Code c_SetSolenoid(void * handle,unsigned char idx,INT8 param);
+ CTR_Code c_SetAllSolenoids(void * handle,UINT8 state);
+ CTR_Code c_SetClosedLoopControl(void * handle,INT8 param);
+ CTR_Code c_ClearStickyFaults(void * handle,INT8 param);
+ CTR_Code c_GetSolenoid(void * handle,UINT8 idx,INT8 * status);
+ CTR_Code c_GetAllSolenoids(void * handle,UINT8 * status);
+ CTR_Code c_GetPressure(void * handle,INT8 * status);
+ CTR_Code c_GetCompressor(void * handle,INT8 * status);
+ CTR_Code c_GetClosedLoopControl(void * handle,INT8 * status);
+ CTR_Code c_GetCompressorCurrent(void * handle,float * status);
+ CTR_Code c_GetSolenoidVoltage(void * handle,float*status);
+ CTR_Code c_GetHardwareFault(void * handle,INT8*status);
+ CTR_Code c_GetCompressorFault(void * handle,INT8*status);
+ CTR_Code c_GetSolenoidFault(void * handle,INT8*status);
+ CTR_Code c_GetCompressorStickyFault(void * handle,INT8*status);
+ CTR_Code c_GetSolenoidStickyFault(void * handle,INT8*status);
+ CTR_Code c_GetBatteryVoltage(void * handle,float*status);
+ void c_SetDeviceNumber_PCM(void * handle,UINT8 deviceNumber);
+ void c_EnableSeekStatusFrames(void * handle,INT8 enable);
+ void c_EnableSeekStatusFaultFrames(void * handle,INT8 enable);
+ void c_EnableSeekDebugFrames(void * handle,INT8 enable);
+ CTR_Code c_GetNumberOfFailedControlFrames(void * handle,UINT16*status);
+ CTR_Code c_GetSolenoidBlackList(void * handle,UINT8 *status);
+ CTR_Code c_IsSolenoidBlacklisted(void * handle,UINT8 idx,INT8*status);
+}
+#endif
diff --git a/hal/src/main/native/athena/ctre/ctre.h b/hal/src/main/native/athena/ctre/ctre.h
new file mode 100644
index 0000000..90d33c1
--- /dev/null
+++ b/hal/src/main/native/athena/ctre/ctre.h
@@ -0,0 +1,55 @@
+/**
+ * @file ctre.h
+ * Common header for all CTRE HAL modules.
+ */
+#ifndef CTRE_H
+#define CTRE_H
+
+//Bit Defines
+#define BIT0 0x01
+#define BIT1 0x02
+#define BIT2 0x04
+#define BIT3 0x08
+#define BIT4 0x10
+#define BIT5 0x20
+#define BIT6 0x40
+#define BIT7 0x80
+#define BIT8 0x0100
+#define BIT9 0x0200
+#define BIT10 0x0400
+#define BIT11 0x0800
+#define BIT12 0x1000
+#define BIT13 0x2000
+#define BIT14 0x4000
+#define BIT15 0x8000
+
+//Signed
+typedef signed char INT8;
+typedef signed short INT16;
+typedef signed int INT32;
+typedef signed long long INT64;
+
+//Unsigned
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+typedef unsigned long long UINT64;
+
+//Other
+typedef unsigned char UCHAR;
+typedef unsigned short USHORT;
+typedef unsigned int UINT;
+typedef unsigned long ULONG;
+
+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;
+
+#endif /* CTRE_H */
diff --git a/hal/src/main/native/athena/frccansae/CANDeviceInterface.h b/hal/src/main/native/athena/frccansae/CANDeviceInterface.h
new file mode 100644
index 0000000..8fe4235
--- /dev/null
+++ b/hal/src/main/native/athena/frccansae/CANDeviceInterface.h
@@ -0,0 +1,156 @@
+#ifndef __CAN_DEVICE_INTERFACE_H__
+#define __CAN_DEVICE_INTERFACE_H__
+
+#define MAX_STRING_LEN 64
+
+#define SUPPORT_UNIQUE_ID (1) /* depends entirely on old vs new build */
+#define USE_NTH_ORDER (0) /* zero to user deviceId */
+#define SUPPORT_MOTOR_CONTROLLER_PROFILE (1)
+namespace CANDeviceInterface1
+{
+
+struct PIDSlot
+{
+ // Proportional gain
+ float pGain;
+ // Integral gain
+ float iGain;
+ // Differential gain
+ float dGain;
+ // Feed-forward gain
+ float fGain;
+ // Integral zone
+ float iZone;
+ // Closed-loop ramp rate
+ float clRampRate;
+};
+
+struct DeviceDescriptor
+{
+ // The full device ID, including the device number, manufacturer, and device type.
+ // The mask of a message the device supports is 0x1FFF003F.
+ unsigned int deviceID;
+#if SUPPORT_UNIQUE_ID != 0
+ // This is the ID that uniquely identifies the device node in the UI.
+ // The purpose of this is to be able to track the device across renames or deviceID changes.
+ unsigned int uniqueID;
+#endif
+ // An dynamically assigned ID that will make setting deviceIDs robust,
+ // Never again will you need to isolate a CAN node just to fix it's ID.
+ unsigned int dynamicID;
+ // User visible name. This can be customized by the user, but should have a
+ // reasonable default.
+ char name[MAX_STRING_LEN];
+ // This is a user visible model name that should match the can_devices.ini section.
+ char model[MAX_STRING_LEN];
+ // This is a version number that represents the version of firmware currently
+ // installed on the device.
+ char currentVersion[MAX_STRING_LEN];
+ // Hardware revision.
+ char hardwareRev[MAX_STRING_LEN];
+ // Bootloader version. Will not change for the life of the product, but additional
+ // field upgrade features could be added in newer hardware.
+ char bootloaderRev[MAX_STRING_LEN];
+ // Manufacture Date. Could be a calender date or just the FRC season year.
+ // Also helps troubleshooting "old ones" vs "new ones".
+ char manufactureDate[MAX_STRING_LEN];
+ // General status of the hardware. For example if the device is in bootloader
+ // due to a bad flash UI could emphasize that.
+ char softwareStatus[MAX_STRING_LEN];
+ // Is the LED currently on?
+ bool led;
+ // Reserved fields for future use by CTRE. Not touched by frccansae
+ unsigned int dynFlags;
+ unsigned int flags; /* bitfield */
+ unsigned int ptrToString;
+ //unsigned int reserved0;
+ //unsigned int reserved1;
+ //unsigned int reserved2;
+#if SUPPORT_MOTOR_CONTROLLER_PROFILE != 0
+ // Motor controller properties (ignored if SupportsMotorControllerProperties is false or unset for this model)
+ unsigned int brakeMode; // 0=Coast, 1=Brake
+ unsigned int limitSwitchFwdMode; // 0=disabled, 1=Normally Closed, 2=Normally Open
+ unsigned int limitSwitchRevMode; // 0=disabled, 1=Normally Closed, 2=Normally Open
+ // Limit-switch soft limits
+ bool bFwdSoftLimitEnable;
+ bool bRevSoftLimitEnable;
+ float softLimitFwd;
+ float softLimitRev;
+ // PID constants for slot 0
+ struct PIDSlot slot0;
+ // PID constants for slot 1
+ struct PIDSlot slot1;
+#endif
+};
+
+#define kLimitSwitchMode_Disabled (0)
+#define kLimitSwitchMode_NormallyClosed (1)
+#define kLimitSwitchMode_NormallyOpen (2)
+
+// Interface functions that must be implemented by the CAN Firmware Update Library
+
+// Returns the number of devices that will be returned in a call to
+// getListOfDevices(). The calling library will use this info to allocate enough
+// memory to accept all device info.
+int getNumberOfDevices();
+
+// Return info about discovered devices. The array of structs should be
+// populated before returning. The numDescriptors input describes how many
+// elements were allocated to prevent memory corruption. The number of devices
+// populated should be returned from this function as well.
+int getListOfDevices(DeviceDescriptor *devices, int numDescriptors);
+
+// When the user requests to update the firmware of a device a thread will be
+// spawned and this function is called from that thread. This function should
+// complete the firmware update process before returning. The image
+// contents and size are directly from the file selected by the user. The
+// error message string can be filled with a NULL-terminated message to show the
+// user if there was a problem updating firmware. The error message is only
+// displayed if a non-zero value is returned from this function.
+int updateFirmware(const DeviceDescriptor *device, const unsigned char *imageContents, unsigned int imageSize, char *errorMessage, int errorMessageMaxSize);
+
+// This function is called periodically from the UI thread while the firmware
+// update is in progress. The percentComplete parameter should the filled in
+// with the current progress of the firmware update process to update a progress
+// bar in the UI.
+void checkUpdateProgress(const DeviceDescriptor *device, int *percentComplete);
+
+// This is called when the user selects a new ID to assign on the bus and
+// chooses to save. The newDeviceID is really just the device number. The
+// manufacturer and device type will remain unchanged. If a problem is detected
+// when assigning a new ID, this function should return a non-zero value.
+int assignBroadcastDeviceID(unsigned int newDeviceID);
+// The device descriptor should be updated with the new device ID. The name may
+// also change in the descriptor and will be updated in the UI immediately.
+// Be sure to modify the descriptor first since the refresh from the UI is
+// asynchronous.
+int assignDeviceID(DeviceDescriptor *device, unsigned int newDeviceID);
+
+// This entry-point will get called when the user chooses to change the value
+// of the device's LED. This will allow the user to identify devices which
+// support dynamic addresses or are otherwise unknown. If this function returns
+// a non-zero value, the UI will report an error.
+int saveLightLed(const DeviceDescriptor *device, bool newLEDStatus);
+
+// This entry-point will get called when the user chooses to change the alias
+// of the device with the device specified. If this function returns a non-
+// zero value, the UI will report an error. The device descriptor must be
+// updated with the new name that was selected. If a different name is saved
+// to the descriptor than the user specified, this will require a manual
+// refresh by the user. This is reported as CAR #505139
+int saveDeviceName(DeviceDescriptor *device, const char *newName);
+
+// This entry-point will get called when the user changes any of the motor
+// controller specific properties. If this function returns a non-zero value,
+// the UI will report an error. The device descriptor may be updated with
+// coerced values.
+int saveMotorParameters(DeviceDescriptor *device);
+
+// Run some sort of self-test functionality on the device. This can be anything
+// and the results will be displayed to the user. A non-zero return value
+// indicates an error.
+int selfTest(const DeviceDescriptor *device, char *detailedResults, int detailedResultsMaxSize);
+
+} /* CANDeviceInterface */
+
+#endif /* __CAN_DEVICE_INTERFACE_H__ */
diff --git a/hal/src/main/native/athena/visa/visa.h b/hal/src/main/native/athena/visa/visa.h
new file mode 100644
index 0000000..3c6ad30
--- /dev/null
+++ b/hal/src/main/native/athena/visa/visa.h
@@ -0,0 +1,1064 @@
+/*---------------------------------------------------------------------------*/
+/* Distributed by IVI Foundation Inc. */
+/* Contains National Instruments extensions. */
+/* Do not modify the contents of this file. */
+/*---------------------------------------------------------------------------*/
+/* */
+/* Title : VISA.H */
+/* Date : 10-09-2006 */
+/* Purpose : Include file for the VISA Library 4.0 specification */
+/* */
+/*---------------------------------------------------------------------------*/
+/* When using NI-VISA extensions, you must link with the VISA library that */
+/* comes with NI-VISA. Currently, the extensions provided by NI-VISA are: */
+/* */
+/* PXI (Compact PCI eXtensions for Instrumentation) and PCI support. To use */
+/* this, you must define the macro NIVISA_PXI before including this header. */
+/* You must also create an INF file with the VISA Driver Development Wizard. */
+/* */
+/* A fast set of macros for viPeekXX/viPokeXX that guarantees binary */
+/* compatibility with other implementations of VISA. To use this, you must */
+/* define the macro NIVISA_PEEKPOKE before including this header. */
+/* */
+/* Support for USB devices that do not conform to a specific class. To use */
+/* this, you must define the macro NIVISA_USB before including this header. */
+/* You must also create an INF file with the VISA Driver Development Wizard. */
+/*---------------------------------------------------------------------------*/
+
+#ifndef __VISA_HEADER__
+#define __VISA_HEADER__
+
+#include <stdarg.h>
+
+#if !defined(__VISATYPE_HEADER__)
+#include "visatype.h"
+#endif
+
+#define VI_SPEC_VERSION (0x00400000UL)
+
+#if defined(__cplusplus) || defined(__cplusplus__)
+ extern "C" {
+#endif
+
+#if defined(_CVI_)
+#pragma EnableLibraryRuntimeChecking
+#endif
+
+/*- VISA Types --------------------------------------------------------------*/
+
+typedef ViObject ViEvent;
+typedef ViEvent _VI_PTR ViPEvent;
+typedef ViObject ViFindList;
+typedef ViFindList _VI_PTR ViPFindList;
+
+#if defined(_VI_INT64_UINT64_DEFINED) && defined(_VISA_ENV_IS_64_BIT)
+typedef ViUInt64 ViBusAddress;
+typedef ViUInt64 ViBusSize;
+typedef ViUInt64 ViAttrState;
+#else
+typedef ViUInt32 ViBusAddress;
+typedef ViUInt32 ViBusSize;
+typedef ViUInt32 ViAttrState;
+#endif
+
+#if defined(_VI_INT64_UINT64_DEFINED)
+typedef ViUInt64 ViBusAddress64;
+typedef ViBusAddress64 _VI_PTR ViPBusAddress64;
+#endif
+
+typedef ViUInt32 ViEventType;
+typedef ViEventType _VI_PTR ViPEventType;
+typedef ViEventType _VI_PTR ViAEventType;
+typedef void _VI_PTR ViPAttrState;
+typedef ViAttr _VI_PTR ViPAttr;
+typedef ViAttr _VI_PTR ViAAttr;
+
+typedef ViString ViKeyId;
+typedef ViPString ViPKeyId;
+typedef ViUInt32 ViJobId;
+typedef ViJobId _VI_PTR ViPJobId;
+typedef ViUInt32 ViAccessMode;
+typedef ViAccessMode _VI_PTR ViPAccessMode;
+typedef ViBusAddress _VI_PTR ViPBusAddress;
+typedef ViUInt32 ViEventFilter;
+
+typedef va_list ViVAList;
+
+typedef ViStatus (_VI_FUNCH _VI_PTR ViHndlr)
+ (ViSession vi, ViEventType eventType, ViEvent event, ViAddr userHandle);
+
+/*- Resource Manager Functions and Operations -------------------------------*/
+
+ViStatus _VI_FUNC viOpenDefaultRM (ViPSession vi);
+ViStatus _VI_FUNC viFindRsrc (ViSession sesn, ViString expr, ViPFindList vi,
+ ViPUInt32 retCnt, ViChar _VI_FAR desc[]);
+ViStatus _VI_FUNC viFindNext (ViFindList vi, ViChar _VI_FAR desc[]);
+ViStatus _VI_FUNC viParseRsrc (ViSession rmSesn, ViRsrc rsrcName,
+ ViPUInt16 intfType, ViPUInt16 intfNum);
+ViStatus _VI_FUNC viParseRsrcEx (ViSession rmSesn, ViRsrc rsrcName, ViPUInt16 intfType,
+ ViPUInt16 intfNum, ViChar _VI_FAR rsrcClass[],
+ ViChar _VI_FAR expandedUnaliasedName[],
+ ViChar _VI_FAR aliasIfExists[]);
+ViStatus _VI_FUNC viOpen (ViSession sesn, ViRsrc name, ViAccessMode mode,
+ ViUInt32 timeout, ViPSession vi);
+
+/*- Resource Template Operations --------------------------------------------*/
+
+ViStatus _VI_FUNC viClose (ViObject vi);
+ViStatus _VI_FUNC viSetAttribute (ViObject vi, ViAttr attrName, ViAttrState attrValue);
+ViStatus _VI_FUNC viGetAttribute (ViObject vi, ViAttr attrName, void _VI_PTR attrValue);
+ViStatus _VI_FUNC viStatusDesc (ViObject vi, ViStatus status, ViChar _VI_FAR desc[]);
+ViStatus _VI_FUNC viTerminate (ViObject vi, ViUInt16 degree, ViJobId jobId);
+
+ViStatus _VI_FUNC viLock (ViSession vi, ViAccessMode lockType, ViUInt32 timeout,
+ ViKeyId requestedKey, ViChar _VI_FAR accessKey[]);
+ViStatus _VI_FUNC viUnlock (ViSession vi);
+ViStatus _VI_FUNC viEnableEvent (ViSession vi, ViEventType eventType, ViUInt16 mechanism,
+ ViEventFilter context);
+ViStatus _VI_FUNC viDisableEvent (ViSession vi, ViEventType eventType, ViUInt16 mechanism);
+ViStatus _VI_FUNC viDiscardEvents (ViSession vi, ViEventType eventType, ViUInt16 mechanism);
+ViStatus _VI_FUNC viWaitOnEvent (ViSession vi, ViEventType inEventType, ViUInt32 timeout,
+ ViPEventType outEventType, ViPEvent outContext);
+ViStatus _VI_FUNC viInstallHandler(ViSession vi, ViEventType eventType, ViHndlr handler,
+ ViAddr userHandle);
+ViStatus _VI_FUNC viUninstallHandler(ViSession vi, ViEventType eventType, ViHndlr handler,
+ ViAddr userHandle);
+
+/*- Basic I/O Operations ----------------------------------------------------*/
+
+ViStatus _VI_FUNC viRead (ViSession vi, ViPBuf buf, ViUInt32 cnt, ViPUInt32 retCnt);
+ViStatus _VI_FUNC viReadAsync (ViSession vi, ViPBuf buf, ViUInt32 cnt, ViPJobId jobId);
+ViStatus _VI_FUNC viReadToFile (ViSession vi, ViConstString filename, ViUInt32 cnt,
+ ViPUInt32 retCnt);
+ViStatus _VI_FUNC viWrite (ViSession vi, ViBuf buf, ViUInt32 cnt, ViPUInt32 retCnt);
+ViStatus _VI_FUNC viWriteAsync (ViSession vi, ViBuf buf, ViUInt32 cnt, ViPJobId jobId);
+ViStatus _VI_FUNC viWriteFromFile (ViSession vi, ViConstString filename, ViUInt32 cnt,
+ ViPUInt32 retCnt);
+ViStatus _VI_FUNC viAssertTrigger (ViSession vi, ViUInt16 protocol);
+ViStatus _VI_FUNC viReadSTB (ViSession vi, ViPUInt16 status);
+ViStatus _VI_FUNC viClear (ViSession vi);
+
+/*- Formatted and Buffered I/O Operations -----------------------------------*/
+
+ViStatus _VI_FUNC viSetBuf (ViSession vi, ViUInt16 mask, ViUInt32 size);
+ViStatus _VI_FUNC viFlush (ViSession vi, ViUInt16 mask);
+
+ViStatus _VI_FUNC viBufWrite (ViSession vi, ViBuf buf, ViUInt32 cnt, ViPUInt32 retCnt);
+ViStatus _VI_FUNC viBufRead (ViSession vi, ViPBuf buf, ViUInt32 cnt, ViPUInt32 retCnt);
+
+ViStatus _VI_FUNCC viPrintf (ViSession vi, ViString writeFmt, ...);
+ViStatus _VI_FUNC viVPrintf (ViSession vi, ViString writeFmt, ViVAList params);
+ViStatus _VI_FUNCC viSPrintf (ViSession vi, ViPBuf buf, ViString writeFmt, ...);
+ViStatus _VI_FUNC viVSPrintf (ViSession vi, ViPBuf buf, ViString writeFmt,
+ ViVAList parms);
+
+ViStatus _VI_FUNCC viScanf (ViSession vi, ViString readFmt, ...);
+ViStatus _VI_FUNC viVScanf (ViSession vi, ViString readFmt, ViVAList params);
+ViStatus _VI_FUNCC viSScanf (ViSession vi, ViBuf buf, ViString readFmt, ...);
+ViStatus _VI_FUNC viVSScanf (ViSession vi, ViBuf buf, ViString readFmt,
+ ViVAList parms);
+
+ViStatus _VI_FUNCC viQueryf (ViSession vi, ViString writeFmt, ViString readFmt, ...);
+ViStatus _VI_FUNC viVQueryf (ViSession vi, ViString writeFmt, ViString readFmt,
+ ViVAList params);
+
+/*- Memory I/O Operations ---------------------------------------------------*/
+
+ViStatus _VI_FUNC viIn8 (ViSession vi, ViUInt16 space,
+ ViBusAddress offset, ViPUInt8 val8);
+ViStatus _VI_FUNC viOut8 (ViSession vi, ViUInt16 space,
+ ViBusAddress offset, ViUInt8 val8);
+ViStatus _VI_FUNC viIn16 (ViSession vi, ViUInt16 space,
+ ViBusAddress offset, ViPUInt16 val16);
+ViStatus _VI_FUNC viOut16 (ViSession vi, ViUInt16 space,
+ ViBusAddress offset, ViUInt16 val16);
+ViStatus _VI_FUNC viIn32 (ViSession vi, ViUInt16 space,
+ ViBusAddress offset, ViPUInt32 val32);
+ViStatus _VI_FUNC viOut32 (ViSession vi, ViUInt16 space,
+ ViBusAddress offset, ViUInt32 val32);
+
+#if defined(_VI_INT64_UINT64_DEFINED)
+ViStatus _VI_FUNC viIn64 (ViSession vi, ViUInt16 space,
+ ViBusAddress offset, ViPUInt64 val64);
+ViStatus _VI_FUNC viOut64 (ViSession vi, ViUInt16 space,
+ ViBusAddress offset, ViUInt64 val64);
+
+ViStatus _VI_FUNC viIn8Ex (ViSession vi, ViUInt16 space,
+ ViBusAddress64 offset, ViPUInt8 val8);
+ViStatus _VI_FUNC viOut8Ex (ViSession vi, ViUInt16 space,
+ ViBusAddress64 offset, ViUInt8 val8);
+ViStatus _VI_FUNC viIn16Ex (ViSession vi, ViUInt16 space,
+ ViBusAddress64 offset, ViPUInt16 val16);
+ViStatus _VI_FUNC viOut16Ex (ViSession vi, ViUInt16 space,
+ ViBusAddress64 offset, ViUInt16 val16);
+ViStatus _VI_FUNC viIn32Ex (ViSession vi, ViUInt16 space,
+ ViBusAddress64 offset, ViPUInt32 val32);
+ViStatus _VI_FUNC viOut32Ex (ViSession vi, ViUInt16 space,
+ ViBusAddress64 offset, ViUInt32 val32);
+ViStatus _VI_FUNC viIn64Ex (ViSession vi, ViUInt16 space,
+ ViBusAddress64 offset, ViPUInt64 val64);
+ViStatus _VI_FUNC viOut64Ex (ViSession vi, ViUInt16 space,
+ ViBusAddress64 offset, ViUInt64 val64);
+#endif
+
+ViStatus _VI_FUNC viMoveIn8 (ViSession vi, ViUInt16 space, ViBusAddress offset,
+ ViBusSize length, ViAUInt8 buf8);
+ViStatus _VI_FUNC viMoveOut8 (ViSession vi, ViUInt16 space, ViBusAddress offset,
+ ViBusSize length, ViAUInt8 buf8);
+ViStatus _VI_FUNC viMoveIn16 (ViSession vi, ViUInt16 space, ViBusAddress offset,
+ ViBusSize length, ViAUInt16 buf16);
+ViStatus _VI_FUNC viMoveOut16 (ViSession vi, ViUInt16 space, ViBusAddress offset,
+ ViBusSize length, ViAUInt16 buf16);
+ViStatus _VI_FUNC viMoveIn32 (ViSession vi, ViUInt16 space, ViBusAddress offset,
+ ViBusSize length, ViAUInt32 buf32);
+ViStatus _VI_FUNC viMoveOut32 (ViSession vi, ViUInt16 space, ViBusAddress offset,
+ ViBusSize length, ViAUInt32 buf32);
+
+#if defined(_VI_INT64_UINT64_DEFINED)
+ViStatus _VI_FUNC viMoveIn64 (ViSession vi, ViUInt16 space, ViBusAddress offset,
+ ViBusSize length, ViAUInt64 buf64);
+ViStatus _VI_FUNC viMoveOut64 (ViSession vi, ViUInt16 space, ViBusAddress offset,
+ ViBusSize length, ViAUInt64 buf64);
+
+ViStatus _VI_FUNC viMoveIn8Ex (ViSession vi, ViUInt16 space, ViBusAddress64 offset,
+ ViBusSize length, ViAUInt8 buf8);
+ViStatus _VI_FUNC viMoveOut8Ex (ViSession vi, ViUInt16 space, ViBusAddress64 offset,
+ ViBusSize length, ViAUInt8 buf8);
+ViStatus _VI_FUNC viMoveIn16Ex (ViSession vi, ViUInt16 space, ViBusAddress64 offset,
+ ViBusSize length, ViAUInt16 buf16);
+ViStatus _VI_FUNC viMoveOut16Ex (ViSession vi, ViUInt16 space, ViBusAddress64 offset,
+ ViBusSize length, ViAUInt16 buf16);
+ViStatus _VI_FUNC viMoveIn32Ex (ViSession vi, ViUInt16 space, ViBusAddress64 offset,
+ ViBusSize length, ViAUInt32 buf32);
+ViStatus _VI_FUNC viMoveOut32Ex (ViSession vi, ViUInt16 space, ViBusAddress64 offset,
+ ViBusSize length, ViAUInt32 buf32);
+ViStatus _VI_FUNC viMoveIn64Ex (ViSession vi, ViUInt16 space, ViBusAddress64 offset,
+ ViBusSize length, ViAUInt64 buf64);
+ViStatus _VI_FUNC viMoveOut64Ex (ViSession vi, ViUInt16 space, ViBusAddress64 offset,
+ ViBusSize length, ViAUInt64 buf64);
+#endif
+
+ViStatus _VI_FUNC viMove (ViSession vi, ViUInt16 srcSpace, ViBusAddress srcOffset,
+ ViUInt16 srcWidth, ViUInt16 destSpace,
+ ViBusAddress destOffset, ViUInt16 destWidth,
+ ViBusSize srcLength);
+ViStatus _VI_FUNC viMoveAsync (ViSession vi, ViUInt16 srcSpace, ViBusAddress srcOffset,
+ ViUInt16 srcWidth, ViUInt16 destSpace,
+ ViBusAddress destOffset, ViUInt16 destWidth,
+ ViBusSize srcLength, ViPJobId jobId);
+
+#if defined(_VI_INT64_UINT64_DEFINED)
+ViStatus _VI_FUNC viMoveEx (ViSession vi, ViUInt16 srcSpace, ViBusAddress64 srcOffset,
+ ViUInt16 srcWidth, ViUInt16 destSpace,
+ ViBusAddress64 destOffset, ViUInt16 destWidth,
+ ViBusSize srcLength);
+ViStatus _VI_FUNC viMoveAsyncEx (ViSession vi, ViUInt16 srcSpace, ViBusAddress64 srcOffset,
+ ViUInt16 srcWidth, ViUInt16 destSpace,
+ ViBusAddress64 destOffset, ViUInt16 destWidth,
+ ViBusSize srcLength, ViPJobId jobId);
+#endif
+
+ViStatus _VI_FUNC viMapAddress (ViSession vi, ViUInt16 mapSpace, ViBusAddress mapOffset,
+ ViBusSize mapSize, ViBoolean access,
+ ViAddr suggested, ViPAddr address);
+ViStatus _VI_FUNC viUnmapAddress (ViSession vi);
+
+#if defined(_VI_INT64_UINT64_DEFINED)
+ViStatus _VI_FUNC viMapAddressEx (ViSession vi, ViUInt16 mapSpace, ViBusAddress64 mapOffset,
+ ViBusSize mapSize, ViBoolean access,
+ ViAddr suggested, ViPAddr address);
+#endif
+
+void _VI_FUNC viPeek8 (ViSession vi, ViAddr address, ViPUInt8 val8);
+void _VI_FUNC viPoke8 (ViSession vi, ViAddr address, ViUInt8 val8);
+void _VI_FUNC viPeek16 (ViSession vi, ViAddr address, ViPUInt16 val16);
+void _VI_FUNC viPoke16 (ViSession vi, ViAddr address, ViUInt16 val16);
+void _VI_FUNC viPeek32 (ViSession vi, ViAddr address, ViPUInt32 val32);
+void _VI_FUNC viPoke32 (ViSession vi, ViAddr address, ViUInt32 val32);
+
+#if defined(_VI_INT64_UINT64_DEFINED)
+void _VI_FUNC viPeek64 (ViSession vi, ViAddr address, ViPUInt64 val64);
+void _VI_FUNC viPoke64 (ViSession vi, ViAddr address, ViUInt64 val64);
+#endif
+
+/*- Shared Memory Operations ------------------------------------------------*/
+
+ViStatus _VI_FUNC viMemAlloc (ViSession vi, ViBusSize size, ViPBusAddress offset);
+ViStatus _VI_FUNC viMemFree (ViSession vi, ViBusAddress offset);
+
+#if defined(_VI_INT64_UINT64_DEFINED)
+ViStatus _VI_FUNC viMemAllocEx (ViSession vi, ViBusSize size, ViPBusAddress64 offset);
+ViStatus _VI_FUNC viMemFreeEx (ViSession vi, ViBusAddress64 offset);
+#endif
+
+/*- Interface Specific Operations -------------------------------------------*/
+
+ViStatus _VI_FUNC viGpibControlREN(ViSession vi, ViUInt16 mode);
+ViStatus _VI_FUNC viGpibControlATN(ViSession vi, ViUInt16 mode);
+ViStatus _VI_FUNC viGpibSendIFC (ViSession vi);
+ViStatus _VI_FUNC viGpibCommand (ViSession vi, ViBuf cmd, ViUInt32 cnt, ViPUInt32 retCnt);
+ViStatus _VI_FUNC viGpibPassControl(ViSession vi, ViUInt16 primAddr, ViUInt16 secAddr);
+
+ViStatus _VI_FUNC viVxiCommandQuery(ViSession vi, ViUInt16 mode, ViUInt32 cmd,
+ ViPUInt32 response);
+ViStatus _VI_FUNC viAssertUtilSignal(ViSession vi, ViUInt16 line);
+ViStatus _VI_FUNC viAssertIntrSignal(ViSession vi, ViInt16 mode, ViUInt32 statusID);
+ViStatus _VI_FUNC viMapTrigger (ViSession vi, ViInt16 trigSrc, ViInt16 trigDest,
+ ViUInt16 mode);
+ViStatus _VI_FUNC viUnmapTrigger (ViSession vi, ViInt16 trigSrc, ViInt16 trigDest);
+ViStatus _VI_FUNC viUsbControlOut (ViSession vi, ViInt16 bmRequestType, ViInt16 bRequest,
+ ViUInt16 wValue, ViUInt16 wIndex, ViUInt16 wLength,
+ ViBuf buf);
+ViStatus _VI_FUNC viUsbControlIn (ViSession vi, ViInt16 bmRequestType, ViInt16 bRequest,
+ ViUInt16 wValue, ViUInt16 wIndex, ViUInt16 wLength,
+ ViPBuf buf, ViPUInt16 retCnt);
+
+/*- Attributes (platform independent size) ----------------------------------*/
+
+#define VI_ATTR_RSRC_CLASS (0xBFFF0001UL)
+#define VI_ATTR_RSRC_NAME (0xBFFF0002UL)
+#define VI_ATTR_RSRC_IMPL_VERSION (0x3FFF0003UL)
+#define VI_ATTR_RSRC_LOCK_STATE (0x3FFF0004UL)
+#define VI_ATTR_MAX_QUEUE_LENGTH (0x3FFF0005UL)
+#define VI_ATTR_USER_DATA_32 (0x3FFF0007UL)
+#define VI_ATTR_FDC_CHNL (0x3FFF000DUL)
+#define VI_ATTR_FDC_MODE (0x3FFF000FUL)
+#define VI_ATTR_FDC_GEN_SIGNAL_EN (0x3FFF0011UL)
+#define VI_ATTR_FDC_USE_PAIR (0x3FFF0013UL)
+#define VI_ATTR_SEND_END_EN (0x3FFF0016UL)
+#define VI_ATTR_TERMCHAR (0x3FFF0018UL)
+#define VI_ATTR_TMO_VALUE (0x3FFF001AUL)
+#define VI_ATTR_GPIB_READDR_EN (0x3FFF001BUL)
+#define VI_ATTR_IO_PROT (0x3FFF001CUL)
+#define VI_ATTR_DMA_ALLOW_EN (0x3FFF001EUL)
+#define VI_ATTR_ASRL_BAUD (0x3FFF0021UL)
+#define VI_ATTR_ASRL_DATA_BITS (0x3FFF0022UL)
+#define VI_ATTR_ASRL_PARITY (0x3FFF0023UL)
+#define VI_ATTR_ASRL_STOP_BITS (0x3FFF0024UL)
+#define VI_ATTR_ASRL_FLOW_CNTRL (0x3FFF0025UL)
+#define VI_ATTR_RD_BUF_OPER_MODE (0x3FFF002AUL)
+#define VI_ATTR_RD_BUF_SIZE (0x3FFF002BUL)
+#define VI_ATTR_WR_BUF_OPER_MODE (0x3FFF002DUL)
+#define VI_ATTR_WR_BUF_SIZE (0x3FFF002EUL)
+#define VI_ATTR_SUPPRESS_END_EN (0x3FFF0036UL)
+#define VI_ATTR_TERMCHAR_EN (0x3FFF0038UL)
+#define VI_ATTR_DEST_ACCESS_PRIV (0x3FFF0039UL)
+#define VI_ATTR_DEST_BYTE_ORDER (0x3FFF003AUL)
+#define VI_ATTR_SRC_ACCESS_PRIV (0x3FFF003CUL)
+#define VI_ATTR_SRC_BYTE_ORDER (0x3FFF003DUL)
+#define VI_ATTR_SRC_INCREMENT (0x3FFF0040UL)
+#define VI_ATTR_DEST_INCREMENT (0x3FFF0041UL)
+#define VI_ATTR_WIN_ACCESS_PRIV (0x3FFF0045UL)
+#define VI_ATTR_WIN_BYTE_ORDER (0x3FFF0047UL)
+#define VI_ATTR_GPIB_ATN_STATE (0x3FFF0057UL)
+#define VI_ATTR_GPIB_ADDR_STATE (0x3FFF005CUL)
+#define VI_ATTR_GPIB_CIC_STATE (0x3FFF005EUL)
+#define VI_ATTR_GPIB_NDAC_STATE (0x3FFF0062UL)
+#define VI_ATTR_GPIB_SRQ_STATE (0x3FFF0067UL)
+#define VI_ATTR_GPIB_SYS_CNTRL_STATE (0x3FFF0068UL)
+#define VI_ATTR_GPIB_HS488_CBL_LEN (0x3FFF0069UL)
+#define VI_ATTR_CMDR_LA (0x3FFF006BUL)
+#define VI_ATTR_VXI_DEV_CLASS (0x3FFF006CUL)
+#define VI_ATTR_MAINFRAME_LA (0x3FFF0070UL)
+#define VI_ATTR_MANF_NAME (0xBFFF0072UL)
+#define VI_ATTR_MODEL_NAME (0xBFFF0077UL)
+#define VI_ATTR_VXI_VME_INTR_STATUS (0x3FFF008BUL)
+#define VI_ATTR_VXI_TRIG_STATUS (0x3FFF008DUL)
+#define VI_ATTR_VXI_VME_SYSFAIL_STATE (0x3FFF0094UL)
+#define VI_ATTR_WIN_BASE_ADDR_32 (0x3FFF0098UL)
+#define VI_ATTR_WIN_SIZE_32 (0x3FFF009AUL)
+#define VI_ATTR_ASRL_AVAIL_NUM (0x3FFF00ACUL)
+#define VI_ATTR_MEM_BASE_32 (0x3FFF00ADUL)
+#define VI_ATTR_ASRL_CTS_STATE (0x3FFF00AEUL)
+#define VI_ATTR_ASRL_DCD_STATE (0x3FFF00AFUL)
+#define VI_ATTR_ASRL_DSR_STATE (0x3FFF00B1UL)
+#define VI_ATTR_ASRL_DTR_STATE (0x3FFF00B2UL)
+#define VI_ATTR_ASRL_END_IN (0x3FFF00B3UL)
+#define VI_ATTR_ASRL_END_OUT (0x3FFF00B4UL)
+#define VI_ATTR_ASRL_REPLACE_CHAR (0x3FFF00BEUL)
+#define VI_ATTR_ASRL_RI_STATE (0x3FFF00BFUL)
+#define VI_ATTR_ASRL_RTS_STATE (0x3FFF00C0UL)
+#define VI_ATTR_ASRL_XON_CHAR (0x3FFF00C1UL)
+#define VI_ATTR_ASRL_XOFF_CHAR (0x3FFF00C2UL)
+#define VI_ATTR_WIN_ACCESS (0x3FFF00C3UL)
+#define VI_ATTR_RM_SESSION (0x3FFF00C4UL)
+#define VI_ATTR_VXI_LA (0x3FFF00D5UL)
+#define VI_ATTR_MANF_ID (0x3FFF00D9UL)
+#define VI_ATTR_MEM_SIZE_32 (0x3FFF00DDUL)
+#define VI_ATTR_MEM_SPACE (0x3FFF00DEUL)
+#define VI_ATTR_MODEL_CODE (0x3FFF00DFUL)
+#define VI_ATTR_SLOT (0x3FFF00E8UL)
+#define VI_ATTR_INTF_INST_NAME (0xBFFF00E9UL)
+#define VI_ATTR_IMMEDIATE_SERV (0x3FFF0100UL)
+#define VI_ATTR_INTF_PARENT_NUM (0x3FFF0101UL)
+#define VI_ATTR_RSRC_SPEC_VERSION (0x3FFF0170UL)
+#define VI_ATTR_INTF_TYPE (0x3FFF0171UL)
+#define VI_ATTR_GPIB_PRIMARY_ADDR (0x3FFF0172UL)
+#define VI_ATTR_GPIB_SECONDARY_ADDR (0x3FFF0173UL)
+#define VI_ATTR_RSRC_MANF_NAME (0xBFFF0174UL)
+#define VI_ATTR_RSRC_MANF_ID (0x3FFF0175UL)
+#define VI_ATTR_INTF_NUM (0x3FFF0176UL)
+#define VI_ATTR_TRIG_ID (0x3FFF0177UL)
+#define VI_ATTR_GPIB_REN_STATE (0x3FFF0181UL)
+#define VI_ATTR_GPIB_UNADDR_EN (0x3FFF0184UL)
+#define VI_ATTR_DEV_STATUS_BYTE (0x3FFF0189UL)
+#define VI_ATTR_FILE_APPEND_EN (0x3FFF0192UL)
+#define VI_ATTR_VXI_TRIG_SUPPORT (0x3FFF0194UL)
+#define VI_ATTR_TCPIP_ADDR (0xBFFF0195UL)
+#define VI_ATTR_TCPIP_HOSTNAME (0xBFFF0196UL)
+#define VI_ATTR_TCPIP_PORT (0x3FFF0197UL)
+#define VI_ATTR_TCPIP_DEVICE_NAME (0xBFFF0199UL)
+#define VI_ATTR_TCPIP_NODELAY (0x3FFF019AUL)
+#define VI_ATTR_TCPIP_KEEPALIVE (0x3FFF019BUL)
+#define VI_ATTR_4882_COMPLIANT (0x3FFF019FUL)
+#define VI_ATTR_USB_SERIAL_NUM (0xBFFF01A0UL)
+#define VI_ATTR_USB_INTFC_NUM (0x3FFF01A1UL)
+#define VI_ATTR_USB_PROTOCOL (0x3FFF01A7UL)
+#define VI_ATTR_USB_MAX_INTR_SIZE (0x3FFF01AFUL)
+#define VI_ATTR_PXI_DEV_NUM (0x3FFF0201UL)
+#define VI_ATTR_PXI_FUNC_NUM (0x3FFF0202UL)
+#define VI_ATTR_PXI_BUS_NUM (0x3FFF0205UL)
+#define VI_ATTR_PXI_CHASSIS (0x3FFF0206UL)
+#define VI_ATTR_PXI_SLOTPATH (0xBFFF0207UL)
+#define VI_ATTR_PXI_SLOT_LBUS_LEFT (0x3FFF0208UL)
+#define VI_ATTR_PXI_SLOT_LBUS_RIGHT (0x3FFF0209UL)
+#define VI_ATTR_PXI_TRIG_BUS (0x3FFF020AUL)
+#define VI_ATTR_PXI_STAR_TRIG_BUS (0x3FFF020BUL)
+#define VI_ATTR_PXI_STAR_TRIG_LINE (0x3FFF020CUL)
+#define VI_ATTR_PXI_MEM_TYPE_BAR0 (0x3FFF0211UL)
+#define VI_ATTR_PXI_MEM_TYPE_BAR1 (0x3FFF0212UL)
+#define VI_ATTR_PXI_MEM_TYPE_BAR2 (0x3FFF0213UL)
+#define VI_ATTR_PXI_MEM_TYPE_BAR3 (0x3FFF0214UL)
+#define VI_ATTR_PXI_MEM_TYPE_BAR4 (0x3FFF0215UL)
+#define VI_ATTR_PXI_MEM_TYPE_BAR5 (0x3FFF0216UL)
+#define VI_ATTR_PXI_MEM_BASE_BAR0 (0x3FFF0221UL)
+#define VI_ATTR_PXI_MEM_BASE_BAR1 (0x3FFF0222UL)
+#define VI_ATTR_PXI_MEM_BASE_BAR2 (0x3FFF0223UL)
+#define VI_ATTR_PXI_MEM_BASE_BAR3 (0x3FFF0224UL)
+#define VI_ATTR_PXI_MEM_BASE_BAR4 (0x3FFF0225UL)
+#define VI_ATTR_PXI_MEM_BASE_BAR5 (0x3FFF0226UL)
+#define VI_ATTR_PXI_MEM_SIZE_BAR0 (0x3FFF0231UL)
+#define VI_ATTR_PXI_MEM_SIZE_BAR1 (0x3FFF0232UL)
+#define VI_ATTR_PXI_MEM_SIZE_BAR2 (0x3FFF0233UL)
+#define VI_ATTR_PXI_MEM_SIZE_BAR3 (0x3FFF0234UL)
+#define VI_ATTR_PXI_MEM_SIZE_BAR4 (0x3FFF0235UL)
+#define VI_ATTR_PXI_MEM_SIZE_BAR5 (0x3FFF0236UL)
+#define VI_ATTR_PXI_IS_EXPRESS (0x3FFF0240UL)
+#define VI_ATTR_PXI_SLOT_LWIDTH (0x3FFF0241UL)
+#define VI_ATTR_PXI_MAX_LWIDTH (0x3FFF0242UL)
+#define VI_ATTR_PXI_ACTUAL_LWIDTH (0x3FFF0243UL)
+#define VI_ATTR_PXI_DSTAR_BUS (0x3FFF0244UL)
+#define VI_ATTR_PXI_DSTAR_SET (0x3FFF0245UL)
+
+#define VI_ATTR_JOB_ID (0x3FFF4006UL)
+#define VI_ATTR_EVENT_TYPE (0x3FFF4010UL)
+#define VI_ATTR_SIGP_STATUS_ID (0x3FFF4011UL)
+#define VI_ATTR_RECV_TRIG_ID (0x3FFF4012UL)
+#define VI_ATTR_INTR_STATUS_ID (0x3FFF4023UL)
+#define VI_ATTR_STATUS (0x3FFF4025UL)
+#define VI_ATTR_RET_COUNT_32 (0x3FFF4026UL)
+#define VI_ATTR_BUFFER (0x3FFF4027UL)
+#define VI_ATTR_RECV_INTR_LEVEL (0x3FFF4041UL)
+#define VI_ATTR_OPER_NAME (0xBFFF4042UL)
+#define VI_ATTR_GPIB_RECV_CIC_STATE (0x3FFF4193UL)
+#define VI_ATTR_RECV_TCPIP_ADDR (0xBFFF4198UL)
+#define VI_ATTR_USB_RECV_INTR_SIZE (0x3FFF41B0UL)
+#define VI_ATTR_USB_RECV_INTR_DATA (0xBFFF41B1UL)
+
+/*- Attributes (platform dependent size) ------------------------------------*/
+
+#if defined(_VI_INT64_UINT64_DEFINED) && defined(_VISA_ENV_IS_64_BIT)
+#define VI_ATTR_USER_DATA_64 (0x3FFF000AUL)
+#define VI_ATTR_RET_COUNT_64 (0x3FFF4028UL)
+#define VI_ATTR_USER_DATA (VI_ATTR_USER_DATA_64)
+#define VI_ATTR_RET_COUNT (VI_ATTR_RET_COUNT_64)
+#else
+#define VI_ATTR_USER_DATA (VI_ATTR_USER_DATA_32)
+#define VI_ATTR_RET_COUNT (VI_ATTR_RET_COUNT_32)
+#endif
+
+#if defined(_VI_INT64_UINT64_DEFINED)
+#define VI_ATTR_WIN_BASE_ADDR_64 (0x3FFF009BUL)
+#define VI_ATTR_WIN_SIZE_64 (0x3FFF009CUL)
+#define VI_ATTR_MEM_BASE_64 (0x3FFF00D0UL)
+#define VI_ATTR_MEM_SIZE_64 (0x3FFF00D1UL)
+#endif
+#if defined(_VI_INT64_UINT64_DEFINED) && defined(_VISA_ENV_IS_64_BIT)
+#define VI_ATTR_WIN_BASE_ADDR (VI_ATTR_WIN_BASE_ADDR_64)
+#define VI_ATTR_WIN_SIZE (VI_ATTR_WIN_SIZE_64)
+#define VI_ATTR_MEM_BASE (VI_ATTR_MEM_BASE_64)
+#define VI_ATTR_MEM_SIZE (VI_ATTR_MEM_SIZE_64)
+#else
+#define VI_ATTR_WIN_BASE_ADDR (VI_ATTR_WIN_BASE_ADDR_32)
+#define VI_ATTR_WIN_SIZE (VI_ATTR_WIN_SIZE_32)
+#define VI_ATTR_MEM_BASE (VI_ATTR_MEM_BASE_32)
+#define VI_ATTR_MEM_SIZE (VI_ATTR_MEM_SIZE_32)
+#endif
+
+/*- Event Types -------------------------------------------------------------*/
+
+#define VI_EVENT_IO_COMPLETION (0x3FFF2009UL)
+#define VI_EVENT_TRIG (0xBFFF200AUL)
+#define VI_EVENT_SERVICE_REQ (0x3FFF200BUL)
+#define VI_EVENT_CLEAR (0x3FFF200DUL)
+#define VI_EVENT_EXCEPTION (0xBFFF200EUL)
+#define VI_EVENT_GPIB_CIC (0x3FFF2012UL)
+#define VI_EVENT_GPIB_TALK (0x3FFF2013UL)
+#define VI_EVENT_GPIB_LISTEN (0x3FFF2014UL)
+#define VI_EVENT_VXI_VME_SYSFAIL (0x3FFF201DUL)
+#define VI_EVENT_VXI_VME_SYSRESET (0x3FFF201EUL)
+#define VI_EVENT_VXI_SIGP (0x3FFF2020UL)
+#define VI_EVENT_VXI_VME_INTR (0xBFFF2021UL)
+#define VI_EVENT_PXI_INTR (0x3FFF2022UL)
+#define VI_EVENT_TCPIP_CONNECT (0x3FFF2036UL)
+#define VI_EVENT_USB_INTR (0x3FFF2037UL)
+
+#define VI_ALL_ENABLED_EVENTS (0x3FFF7FFFUL)
+
+/*- Completion and Error Codes ----------------------------------------------*/
+
+#define VI_SUCCESS_EVENT_EN (0x3FFF0002L) /* 3FFF0002, 1073676290 */
+#define VI_SUCCESS_EVENT_DIS (0x3FFF0003L) /* 3FFF0003, 1073676291 */
+#define VI_SUCCESS_QUEUE_EMPTY (0x3FFF0004L) /* 3FFF0004, 1073676292 */
+#define VI_SUCCESS_TERM_CHAR (0x3FFF0005L) /* 3FFF0005, 1073676293 */
+#define VI_SUCCESS_MAX_CNT (0x3FFF0006L) /* 3FFF0006, 1073676294 */
+#define VI_SUCCESS_DEV_NPRESENT (0x3FFF007DL) /* 3FFF007D, 1073676413 */
+#define VI_SUCCESS_TRIG_MAPPED (0x3FFF007EL) /* 3FFF007E, 1073676414 */
+#define VI_SUCCESS_QUEUE_NEMPTY (0x3FFF0080L) /* 3FFF0080, 1073676416 */
+#define VI_SUCCESS_NCHAIN (0x3FFF0098L) /* 3FFF0098, 1073676440 */
+#define VI_SUCCESS_NESTED_SHARED (0x3FFF0099L) /* 3FFF0099, 1073676441 */
+#define VI_SUCCESS_NESTED_EXCLUSIVE (0x3FFF009AL) /* 3FFF009A, 1073676442 */
+#define VI_SUCCESS_SYNC (0x3FFF009BL) /* 3FFF009B, 1073676443 */
+
+#define VI_WARN_QUEUE_OVERFLOW (0x3FFF000CL) /* 3FFF000C, 1073676300 */
+#define VI_WARN_CONFIG_NLOADED (0x3FFF0077L) /* 3FFF0077, 1073676407 */
+#define VI_WARN_NULL_OBJECT (0x3FFF0082L) /* 3FFF0082, 1073676418 */
+#define VI_WARN_NSUP_ATTR_STATE (0x3FFF0084L) /* 3FFF0084, 1073676420 */
+#define VI_WARN_UNKNOWN_STATUS (0x3FFF0085L) /* 3FFF0085, 1073676421 */
+#define VI_WARN_NSUP_BUF (0x3FFF0088L) /* 3FFF0088, 1073676424 */
+#define VI_WARN_EXT_FUNC_NIMPL (0x3FFF00A9L) /* 3FFF00A9, 1073676457 */
+
+#define VI_ERROR_SYSTEM_ERROR (_VI_ERROR+0x3FFF0000L) /* BFFF0000, -1073807360 */
+#define VI_ERROR_INV_OBJECT (_VI_ERROR+0x3FFF000EL) /* BFFF000E, -1073807346 */
+#define VI_ERROR_RSRC_LOCKED (_VI_ERROR+0x3FFF000FL) /* BFFF000F, -1073807345 */
+#define VI_ERROR_INV_EXPR (_VI_ERROR+0x3FFF0010L) /* BFFF0010, -1073807344 */
+#define VI_ERROR_RSRC_NFOUND (_VI_ERROR+0x3FFF0011L) /* BFFF0011, -1073807343 */
+#define VI_ERROR_INV_RSRC_NAME (_VI_ERROR+0x3FFF0012L) /* BFFF0012, -1073807342 */
+#define VI_ERROR_INV_ACC_MODE (_VI_ERROR+0x3FFF0013L) /* BFFF0013, -1073807341 */
+#define VI_ERROR_TMO (_VI_ERROR+0x3FFF0015L) /* BFFF0015, -1073807339 */
+#define VI_ERROR_CLOSING_FAILED (_VI_ERROR+0x3FFF0016L) /* BFFF0016, -1073807338 */
+#define VI_ERROR_INV_DEGREE (_VI_ERROR+0x3FFF001BL) /* BFFF001B, -1073807333 */
+#define VI_ERROR_INV_JOB_ID (_VI_ERROR+0x3FFF001CL) /* BFFF001C, -1073807332 */
+#define VI_ERROR_NSUP_ATTR (_VI_ERROR+0x3FFF001DL) /* BFFF001D, -1073807331 */
+#define VI_ERROR_NSUP_ATTR_STATE (_VI_ERROR+0x3FFF001EL) /* BFFF001E, -1073807330 */
+#define VI_ERROR_ATTR_READONLY (_VI_ERROR+0x3FFF001FL) /* BFFF001F, -1073807329 */
+#define VI_ERROR_INV_LOCK_TYPE (_VI_ERROR+0x3FFF0020L) /* BFFF0020, -1073807328 */
+#define VI_ERROR_INV_ACCESS_KEY (_VI_ERROR+0x3FFF0021L) /* BFFF0021, -1073807327 */
+#define VI_ERROR_INV_EVENT (_VI_ERROR+0x3FFF0026L) /* BFFF0026, -1073807322 */
+#define VI_ERROR_INV_MECH (_VI_ERROR+0x3FFF0027L) /* BFFF0027, -1073807321 */
+#define VI_ERROR_HNDLR_NINSTALLED (_VI_ERROR+0x3FFF0028L) /* BFFF0028, -1073807320 */
+#define VI_ERROR_INV_HNDLR_REF (_VI_ERROR+0x3FFF0029L) /* BFFF0029, -1073807319 */
+#define VI_ERROR_INV_CONTEXT (_VI_ERROR+0x3FFF002AL) /* BFFF002A, -1073807318 */
+#define VI_ERROR_QUEUE_OVERFLOW (_VI_ERROR+0x3FFF002DL) /* BFFF002D, -1073807315 */
+#define VI_ERROR_NENABLED (_VI_ERROR+0x3FFF002FL) /* BFFF002F, -1073807313 */
+#define VI_ERROR_ABORT (_VI_ERROR+0x3FFF0030L) /* BFFF0030, -1073807312 */
+#define VI_ERROR_RAW_WR_PROT_VIOL (_VI_ERROR+0x3FFF0034L) /* BFFF0034, -1073807308 */
+#define VI_ERROR_RAW_RD_PROT_VIOL (_VI_ERROR+0x3FFF0035L) /* BFFF0035, -1073807307 */
+#define VI_ERROR_OUTP_PROT_VIOL (_VI_ERROR+0x3FFF0036L) /* BFFF0036, -1073807306 */
+#define VI_ERROR_INP_PROT_VIOL (_VI_ERROR+0x3FFF0037L) /* BFFF0037, -1073807305 */
+#define VI_ERROR_BERR (_VI_ERROR+0x3FFF0038L) /* BFFF0038, -1073807304 */
+#define VI_ERROR_IN_PROGRESS (_VI_ERROR+0x3FFF0039L) /* BFFF0039, -1073807303 */
+#define VI_ERROR_INV_SETUP (_VI_ERROR+0x3FFF003AL) /* BFFF003A, -1073807302 */
+#define VI_ERROR_QUEUE_ERROR (_VI_ERROR+0x3FFF003BL) /* BFFF003B, -1073807301 */
+#define VI_ERROR_ALLOC (_VI_ERROR+0x3FFF003CL) /* BFFF003C, -1073807300 */
+#define VI_ERROR_INV_MASK (_VI_ERROR+0x3FFF003DL) /* BFFF003D, -1073807299 */
+#define VI_ERROR_IO (_VI_ERROR+0x3FFF003EL) /* BFFF003E, -1073807298 */
+#define VI_ERROR_INV_FMT (_VI_ERROR+0x3FFF003FL) /* BFFF003F, -1073807297 */
+#define VI_ERROR_NSUP_FMT (_VI_ERROR+0x3FFF0041L) /* BFFF0041, -1073807295 */
+#define VI_ERROR_LINE_IN_USE (_VI_ERROR+0x3FFF0042L) /* BFFF0042, -1073807294 */
+#define VI_ERROR_NSUP_MODE (_VI_ERROR+0x3FFF0046L) /* BFFF0046, -1073807290 */
+#define VI_ERROR_SRQ_NOCCURRED (_VI_ERROR+0x3FFF004AL) /* BFFF004A, -1073807286 */
+#define VI_ERROR_INV_SPACE (_VI_ERROR+0x3FFF004EL) /* BFFF004E, -1073807282 */
+#define VI_ERROR_INV_OFFSET (_VI_ERROR+0x3FFF0051L) /* BFFF0051, -1073807279 */
+#define VI_ERROR_INV_WIDTH (_VI_ERROR+0x3FFF0052L) /* BFFF0052, -1073807278 */
+#define VI_ERROR_NSUP_OFFSET (_VI_ERROR+0x3FFF0054L) /* BFFF0054, -1073807276 */
+#define VI_ERROR_NSUP_VAR_WIDTH (_VI_ERROR+0x3FFF0055L) /* BFFF0055, -1073807275 */
+#define VI_ERROR_WINDOW_NMAPPED (_VI_ERROR+0x3FFF0057L) /* BFFF0057, -1073807273 */
+#define VI_ERROR_RESP_PENDING (_VI_ERROR+0x3FFF0059L) /* BFFF0059, -1073807271 */
+#define VI_ERROR_NLISTENERS (_VI_ERROR+0x3FFF005FL) /* BFFF005F, -1073807265 */
+#define VI_ERROR_NCIC (_VI_ERROR+0x3FFF0060L) /* BFFF0060, -1073807264 */
+#define VI_ERROR_NSYS_CNTLR (_VI_ERROR+0x3FFF0061L) /* BFFF0061, -1073807263 */
+#define VI_ERROR_NSUP_OPER (_VI_ERROR+0x3FFF0067L) /* BFFF0067, -1073807257 */
+#define VI_ERROR_INTR_PENDING (_VI_ERROR+0x3FFF0068L) /* BFFF0068, -1073807256 */
+#define VI_ERROR_ASRL_PARITY (_VI_ERROR+0x3FFF006AL) /* BFFF006A, -1073807254 */
+#define VI_ERROR_ASRL_FRAMING (_VI_ERROR+0x3FFF006BL) /* BFFF006B, -1073807253 */
+#define VI_ERROR_ASRL_OVERRUN (_VI_ERROR+0x3FFF006CL) /* BFFF006C, -1073807252 */
+#define VI_ERROR_TRIG_NMAPPED (_VI_ERROR+0x3FFF006EL) /* BFFF006E, -1073807250 */
+#define VI_ERROR_NSUP_ALIGN_OFFSET (_VI_ERROR+0x3FFF0070L) /* BFFF0070, -1073807248 */
+#define VI_ERROR_USER_BUF (_VI_ERROR+0x3FFF0071L) /* BFFF0071, -1073807247 */
+#define VI_ERROR_RSRC_BUSY (_VI_ERROR+0x3FFF0072L) /* BFFF0072, -1073807246 */
+#define VI_ERROR_NSUP_WIDTH (_VI_ERROR+0x3FFF0076L) /* BFFF0076, -1073807242 */
+#define VI_ERROR_INV_PARAMETER (_VI_ERROR+0x3FFF0078L) /* BFFF0078, -1073807240 */
+#define VI_ERROR_INV_PROT (_VI_ERROR+0x3FFF0079L) /* BFFF0079, -1073807239 */
+#define VI_ERROR_INV_SIZE (_VI_ERROR+0x3FFF007BL) /* BFFF007B, -1073807237 */
+#define VI_ERROR_WINDOW_MAPPED (_VI_ERROR+0x3FFF0080L) /* BFFF0080, -1073807232 */
+#define VI_ERROR_NIMPL_OPER (_VI_ERROR+0x3FFF0081L) /* BFFF0081, -1073807231 */
+#define VI_ERROR_INV_LENGTH (_VI_ERROR+0x3FFF0083L) /* BFFF0083, -1073807229 */
+#define VI_ERROR_INV_MODE (_VI_ERROR+0x3FFF0091L) /* BFFF0091, -1073807215 */
+#define VI_ERROR_SESN_NLOCKED (_VI_ERROR+0x3FFF009CL) /* BFFF009C, -1073807204 */
+#define VI_ERROR_MEM_NSHARED (_VI_ERROR+0x3FFF009DL) /* BFFF009D, -1073807203 */
+#define VI_ERROR_LIBRARY_NFOUND (_VI_ERROR+0x3FFF009EL) /* BFFF009E, -1073807202 */
+#define VI_ERROR_NSUP_INTR (_VI_ERROR+0x3FFF009FL) /* BFFF009F, -1073807201 */
+#define VI_ERROR_INV_LINE (_VI_ERROR+0x3FFF00A0L) /* BFFF00A0, -1073807200 */
+#define VI_ERROR_FILE_ACCESS (_VI_ERROR+0x3FFF00A1L) /* BFFF00A1, -1073807199 */
+#define VI_ERROR_FILE_IO (_VI_ERROR+0x3FFF00A2L) /* BFFF00A2, -1073807198 */
+#define VI_ERROR_NSUP_LINE (_VI_ERROR+0x3FFF00A3L) /* BFFF00A3, -1073807197 */
+#define VI_ERROR_NSUP_MECH (_VI_ERROR+0x3FFF00A4L) /* BFFF00A4, -1073807196 */
+#define VI_ERROR_INTF_NUM_NCONFIG (_VI_ERROR+0x3FFF00A5L) /* BFFF00A5, -1073807195 */
+#define VI_ERROR_CONN_LOST (_VI_ERROR+0x3FFF00A6L) /* BFFF00A6, -1073807194 */
+#define VI_ERROR_MACHINE_NAVAIL (_VI_ERROR+0x3FFF00A7L) /* BFFF00A7, -1073807193 */
+#define VI_ERROR_NPERMISSION (_VI_ERROR+0x3FFF00A8L) /* BFFF00A8, -1073807192 */
+
+/*- Other VISA Definitions --------------------------------------------------*/
+
+#define VI_VERSION_MAJOR(ver) ((((ViVersion)ver) & 0xFFF00000UL) >> 20)
+#define VI_VERSION_MINOR(ver) ((((ViVersion)ver) & 0x000FFF00UL) >> 8)
+#define VI_VERSION_SUBMINOR(ver) ((((ViVersion)ver) & 0x000000FFUL) )
+
+#define VI_FIND_BUFLEN (256)
+
+#define VI_INTF_GPIB (1)
+#define VI_INTF_VXI (2)
+#define VI_INTF_GPIB_VXI (3)
+#define VI_INTF_ASRL (4)
+#define VI_INTF_PXI (5)
+#define VI_INTF_TCPIP (6)
+#define VI_INTF_USB (7)
+
+#define VI_PROT_NORMAL (1)
+#define VI_PROT_FDC (2)
+#define VI_PROT_HS488 (3)
+#define VI_PROT_4882_STRS (4)
+#define VI_PROT_USBTMC_VENDOR (5)
+
+#define VI_FDC_NORMAL (1)
+#define VI_FDC_STREAM (2)
+
+#define VI_LOCAL_SPACE (0)
+#define VI_A16_SPACE (1)
+#define VI_A24_SPACE (2)
+#define VI_A32_SPACE (3)
+#define VI_A64_SPACE (4)
+#define VI_PXI_ALLOC_SPACE (9)
+#define VI_PXI_CFG_SPACE (10)
+#define VI_PXI_BAR0_SPACE (11)
+#define VI_PXI_BAR1_SPACE (12)
+#define VI_PXI_BAR2_SPACE (13)
+#define VI_PXI_BAR3_SPACE (14)
+#define VI_PXI_BAR4_SPACE (15)
+#define VI_PXI_BAR5_SPACE (16)
+#define VI_OPAQUE_SPACE (0xFFFF)
+
+#define VI_UNKNOWN_LA (-1)
+#define VI_UNKNOWN_SLOT (-1)
+#define VI_UNKNOWN_LEVEL (-1)
+#define VI_UNKNOWN_CHASSIS (-1)
+
+#define VI_QUEUE (1)
+#define VI_HNDLR (2)
+#define VI_SUSPEND_HNDLR (4)
+#define VI_ALL_MECH (0xFFFF)
+
+#define VI_ANY_HNDLR (0)
+
+#define VI_TRIG_ALL (-2)
+#define VI_TRIG_SW (-1)
+#define VI_TRIG_TTL0 (0)
+#define VI_TRIG_TTL1 (1)
+#define VI_TRIG_TTL2 (2)
+#define VI_TRIG_TTL3 (3)
+#define VI_TRIG_TTL4 (4)
+#define VI_TRIG_TTL5 (5)
+#define VI_TRIG_TTL6 (6)
+#define VI_TRIG_TTL7 (7)
+#define VI_TRIG_ECL0 (8)
+#define VI_TRIG_ECL1 (9)
+#define VI_TRIG_PANEL_IN (27)
+#define VI_TRIG_PANEL_OUT (28)
+
+#define VI_TRIG_PROT_DEFAULT (0)
+#define VI_TRIG_PROT_ON (1)
+#define VI_TRIG_PROT_OFF (2)
+#define VI_TRIG_PROT_SYNC (5)
+#define VI_TRIG_PROT_RESERVE (6)
+#define VI_TRIG_PROT_UNRESERVE (7)
+
+#define VI_READ_BUF (1)
+#define VI_WRITE_BUF (2)
+#define VI_READ_BUF_DISCARD (4)
+#define VI_WRITE_BUF_DISCARD (8)
+#define VI_IO_IN_BUF (16)
+#define VI_IO_OUT_BUF (32)
+#define VI_IO_IN_BUF_DISCARD (64)
+#define VI_IO_OUT_BUF_DISCARD (128)
+
+#define VI_FLUSH_ON_ACCESS (1)
+#define VI_FLUSH_WHEN_FULL (2)
+#define VI_FLUSH_DISABLE (3)
+
+#define VI_NMAPPED (1)
+#define VI_USE_OPERS (2)
+#define VI_DEREF_ADDR (3)
+#define VI_DEREF_ADDR_BYTE_SWAP (4)
+
+#define VI_TMO_IMMEDIATE (0L)
+#define VI_TMO_INFINITE (0xFFFFFFFFUL)
+
+#define VI_NO_LOCK (0)
+#define VI_EXCLUSIVE_LOCK (1)
+#define VI_SHARED_LOCK (2)
+#define VI_LOAD_CONFIG (4)
+
+#define VI_NO_SEC_ADDR (0xFFFF)
+
+#define VI_ASRL_PAR_NONE (0)
+#define VI_ASRL_PAR_ODD (1)
+#define VI_ASRL_PAR_EVEN (2)
+#define VI_ASRL_PAR_MARK (3)
+#define VI_ASRL_PAR_SPACE (4)
+
+#define VI_ASRL_STOP_ONE (10)
+#define VI_ASRL_STOP_ONE5 (15)
+#define VI_ASRL_STOP_TWO (20)
+
+#define VI_ASRL_FLOW_NONE (0)
+#define VI_ASRL_FLOW_XON_XOFF (1)
+#define VI_ASRL_FLOW_RTS_CTS (2)
+#define VI_ASRL_FLOW_DTR_DSR (4)
+
+#define VI_ASRL_END_NONE (0)
+#define VI_ASRL_END_LAST_BIT (1)
+#define VI_ASRL_END_TERMCHAR (2)
+#define VI_ASRL_END_BREAK (3)
+
+#define VI_STATE_ASSERTED (1)
+#define VI_STATE_UNASSERTED (0)
+#define VI_STATE_UNKNOWN (-1)
+
+#define VI_BIG_ENDIAN (0)
+#define VI_LITTLE_ENDIAN (1)
+
+#define VI_DATA_PRIV (0)
+#define VI_DATA_NPRIV (1)
+#define VI_PROG_PRIV (2)
+#define VI_PROG_NPRIV (3)
+#define VI_BLCK_PRIV (4)
+#define VI_BLCK_NPRIV (5)
+#define VI_D64_PRIV (6)
+#define VI_D64_NPRIV (7)
+
+#define VI_WIDTH_8 (1)
+#define VI_WIDTH_16 (2)
+#define VI_WIDTH_32 (4)
+#define VI_WIDTH_64 (8)
+
+#define VI_GPIB_REN_DEASSERT (0)
+#define VI_GPIB_REN_ASSERT (1)
+#define VI_GPIB_REN_DEASSERT_GTL (2)
+#define VI_GPIB_REN_ASSERT_ADDRESS (3)
+#define VI_GPIB_REN_ASSERT_LLO (4)
+#define VI_GPIB_REN_ASSERT_ADDRESS_LLO (5)
+#define VI_GPIB_REN_ADDRESS_GTL (6)
+
+#define VI_GPIB_ATN_DEASSERT (0)
+#define VI_GPIB_ATN_ASSERT (1)
+#define VI_GPIB_ATN_DEASSERT_HANDSHAKE (2)
+#define VI_GPIB_ATN_ASSERT_IMMEDIATE (3)
+
+#define VI_GPIB_HS488_DISABLED (0)
+#define VI_GPIB_HS488_NIMPL (-1)
+
+#define VI_GPIB_UNADDRESSED (0)
+#define VI_GPIB_TALKER (1)
+#define VI_GPIB_LISTENER (2)
+
+#define VI_VXI_CMD16 (0x0200)
+#define VI_VXI_CMD16_RESP16 (0x0202)
+#define VI_VXI_RESP16 (0x0002)
+#define VI_VXI_CMD32 (0x0400)
+#define VI_VXI_CMD32_RESP16 (0x0402)
+#define VI_VXI_CMD32_RESP32 (0x0404)
+#define VI_VXI_RESP32 (0x0004)
+
+#define VI_ASSERT_SIGNAL (-1)
+#define VI_ASSERT_USE_ASSIGNED (0)
+#define VI_ASSERT_IRQ1 (1)
+#define VI_ASSERT_IRQ2 (2)
+#define VI_ASSERT_IRQ3 (3)
+#define VI_ASSERT_IRQ4 (4)
+#define VI_ASSERT_IRQ5 (5)
+#define VI_ASSERT_IRQ6 (6)
+#define VI_ASSERT_IRQ7 (7)
+
+#define VI_UTIL_ASSERT_SYSRESET (1)
+#define VI_UTIL_ASSERT_SYSFAIL (2)
+#define VI_UTIL_DEASSERT_SYSFAIL (3)
+
+#define VI_VXI_CLASS_MEMORY (0)
+#define VI_VXI_CLASS_EXTENDED (1)
+#define VI_VXI_CLASS_MESSAGE (2)
+#define VI_VXI_CLASS_REGISTER (3)
+#define VI_VXI_CLASS_OTHER (4)
+
+#define VI_PXI_ADDR_NONE (0)
+#define VI_PXI_ADDR_MEM (1)
+#define VI_PXI_ADDR_IO (2)
+#define VI_PXI_ADDR_CFG (3)
+
+#define VI_TRIG_UNKNOWN (-1)
+
+#define VI_PXI_LBUS_UNKNOWN (-1)
+#define VI_PXI_LBUS_NONE (0)
+#define VI_PXI_LBUS_STAR_TRIG_BUS_0 (1000)
+#define VI_PXI_LBUS_STAR_TRIG_BUS_1 (1001)
+#define VI_PXI_LBUS_STAR_TRIG_BUS_2 (1002)
+#define VI_PXI_LBUS_STAR_TRIG_BUS_3 (1003)
+#define VI_PXI_LBUS_STAR_TRIG_BUS_4 (1004)
+#define VI_PXI_LBUS_STAR_TRIG_BUS_5 (1005)
+#define VI_PXI_LBUS_STAR_TRIG_BUS_6 (1006)
+#define VI_PXI_LBUS_STAR_TRIG_BUS_7 (1007)
+#define VI_PXI_LBUS_STAR_TRIG_BUS_8 (1008)
+#define VI_PXI_LBUS_STAR_TRIG_BUS_9 (1009)
+#define VI_PXI_STAR_TRIG_CONTROLLER (1413)
+
+/*- Backward Compatibility Macros -------------------------------------------*/
+
+#define viGetDefaultRM(vi) viOpenDefaultRM(vi)
+#define VI_ERROR_INV_SESSION (VI_ERROR_INV_OBJECT)
+#define VI_INFINITE (VI_TMO_INFINITE)
+#define VI_NORMAL (VI_PROT_NORMAL)
+#define VI_FDC (VI_PROT_FDC)
+#define VI_HS488 (VI_PROT_HS488)
+#define VI_ASRL488 (VI_PROT_4882_STRS)
+#define VI_ASRL_IN_BUF (VI_IO_IN_BUF)
+#define VI_ASRL_OUT_BUF (VI_IO_OUT_BUF)
+#define VI_ASRL_IN_BUF_DISCARD (VI_IO_IN_BUF_DISCARD)
+#define VI_ASRL_OUT_BUF_DISCARD (VI_IO_OUT_BUF_DISCARD)
+
+/*- National Instruments ----------------------------------------------------*/
+
+#define VI_INTF_RIO (8)
+#define VI_INTF_FIREWIRE (9)
+
+#define VI_ATTR_SYNC_MXI_ALLOW_EN (0x3FFF0161UL) /* ViBoolean, read/write */
+
+/* This is for VXI SERVANT resources */
+
+#define VI_EVENT_VXI_DEV_CMD (0xBFFF200FUL)
+#define VI_ATTR_VXI_DEV_CMD_TYPE (0x3FFF4037UL) /* ViInt16, read-only */
+#define VI_ATTR_VXI_DEV_CMD_VALUE (0x3FFF4038UL) /* ViUInt32, read-only */
+
+#define VI_VXI_DEV_CMD_TYPE_16 (16)
+#define VI_VXI_DEV_CMD_TYPE_32 (32)
+
+ViStatus _VI_FUNC viVxiServantResponse(ViSession vi, ViInt16 mode, ViUInt32 resp);
+/* mode values include VI_VXI_RESP16, VI_VXI_RESP32, and the next 2 values */
+#define VI_VXI_RESP_NONE (0)
+#define VI_VXI_RESP_PROT_ERROR (-1)
+
+/* This allows extended Serial support on Win32 and on NI ENET Serial products */
+
+#define VI_ATTR_ASRL_DISCARD_NULL (0x3FFF00B0UL)
+#define VI_ATTR_ASRL_CONNECTED (0x3FFF01BBUL)
+#define VI_ATTR_ASRL_BREAK_STATE (0x3FFF01BCUL)
+#define VI_ATTR_ASRL_BREAK_LEN (0x3FFF01BDUL)
+#define VI_ATTR_ASRL_ALLOW_TRANSMIT (0x3FFF01BEUL)
+#define VI_ATTR_ASRL_WIRE_MODE (0x3FFF01BFUL)
+
+#define VI_ASRL_WIRE_485_4 (0)
+#define VI_ASRL_WIRE_485_2_DTR_ECHO (1)
+#define VI_ASRL_WIRE_485_2_DTR_CTRL (2)
+#define VI_ASRL_WIRE_485_2_AUTO (3)
+#define VI_ASRL_WIRE_232_DTE (128)
+#define VI_ASRL_WIRE_232_DCE (129)
+#define VI_ASRL_WIRE_232_AUTO (130)
+
+#define VI_EVENT_ASRL_BREAK (0x3FFF2023UL)
+#define VI_EVENT_ASRL_CTS (0x3FFF2029UL)
+#define VI_EVENT_ASRL_DSR (0x3FFF202AUL)
+#define VI_EVENT_ASRL_DCD (0x3FFF202CUL)
+#define VI_EVENT_ASRL_RI (0x3FFF202EUL)
+#define VI_EVENT_ASRL_CHAR (0x3FFF2035UL)
+#define VI_EVENT_ASRL_TERMCHAR (0x3FFF2024UL)
+
+/* This is for fast viPeek/viPoke macros */
+
+#if defined(NIVISA_PEEKPOKE)
+
+#if defined(NIVISA_PEEKPOKE_SUPP)
+#undef NIVISA_PEEKPOKE_SUPP
+#endif
+
+#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) && !defined(_NI_mswin16_)
+/* This macro is supported for all Win32 compilers, including CVI. */
+#define NIVISA_PEEKPOKE_SUPP
+#elif (defined(_WINDOWS) || defined(_Windows)) && !defined(_CVI_) && !defined(_NI_mswin16_)
+/* This macro is supported for Borland and Microsoft compilers on Win16, but not CVI. */
+#define NIVISA_PEEKPOKE_SUPP
+#elif defined(_CVI_) && defined(_NI_sparc_)
+/* This macro is supported for Solaris 1 and 2, from CVI only. */
+#define NIVISA_PEEKPOKE_SUPP
+#else
+/* This macro is not supported on other platforms. */
+#endif
+
+#if defined(NIVISA_PEEKPOKE_SUPP)
+
+extern ViBoolean NI_viImplVISA1;
+ViStatus _VI_FUNC NI_viOpenDefaultRM (ViPSession vi);
+#define viOpenDefaultRM(vi) NI_viOpenDefaultRM(vi)
+
+#define viPeek8(vi,addr,val) \
+ { \
+ if ((NI_viImplVISA1) && (*((ViPUInt32)(vi)))) \
+ { \
+ do (*((ViPUInt8)(val)) = *((volatile ViUInt8 _VI_PTR)(addr))); \
+ while (**((volatile ViUInt8 _VI_PTR _VI_PTR)(vi)) & 0x10); \
+ } \
+ else \
+ { \
+ (viPeek8)((vi),(addr),(val)); \
+ } \
+ }
+
+#define viPoke8(vi,addr,val) \
+ { \
+ if ((NI_viImplVISA1) && (*((ViPUInt32)(vi)))) \
+ { \
+ do (*((volatile ViUInt8 _VI_PTR)(addr)) = ((ViUInt8)(val))); \
+ while (**((volatile ViUInt8 _VI_PTR _VI_PTR)(vi)) & 0x10); \
+ } \
+ else \
+ { \
+ (viPoke8)((vi),(addr),(val)); \
+ } \
+ }
+
+#define viPeek16(vi,addr,val) \
+ { \
+ if ((NI_viImplVISA1) && (*((ViPUInt32)(vi)))) \
+ { \
+ do (*((ViPUInt16)(val)) = *((volatile ViUInt16 _VI_PTR)(addr))); \
+ while (**((volatile ViUInt8 _VI_PTR _VI_PTR)(vi)) & 0x10); \
+ } \
+ else \
+ { \
+ (viPeek16)((vi),(addr),(val)); \
+ } \
+ }
+
+#define viPoke16(vi,addr,val) \
+ { \
+ if ((NI_viImplVISA1) && (*((ViPUInt32)(vi)))) \
+ { \
+ do (*((volatile ViUInt16 _VI_PTR)(addr)) = ((ViUInt16)(val))); \
+ while (**((volatile ViUInt8 _VI_PTR _VI_PTR)(vi)) & 0x10); \
+ } \
+ else \
+ { \
+ (viPoke16)((vi),(addr),(val)); \
+ } \
+ }
+
+#define viPeek32(vi,addr,val) \
+ { \
+ if ((NI_viImplVISA1) && (*((ViPUInt32)(vi)))) \
+ { \
+ do (*((ViPUInt32)(val)) = *((volatile ViUInt32 _VI_PTR)(addr))); \
+ while (**((volatile ViUInt8 _VI_PTR _VI_PTR)(vi)) & 0x10); \
+ } \
+ else \
+ { \
+ (viPeek32)((vi),(addr),(val)); \
+ } \
+ }
+
+#define viPoke32(vi,addr,val) \
+ { \
+ if ((NI_viImplVISA1) && (*((ViPUInt32)(vi)))) \
+ { \
+ do (*((volatile ViUInt32 _VI_PTR)(addr)) = ((ViUInt32)(val))); \
+ while (**((volatile ViUInt8 _VI_PTR _VI_PTR)(vi)) & 0x10); \
+ } \
+ else \
+ { \
+ (viPoke32)((vi),(addr),(val)); \
+ } \
+ }
+
+#endif
+
+#endif
+
+#if defined(NIVISA_PXI) || defined(PXISAVISA_PXI)
+
+#if 0
+/* The following 2 attributes were incorrectly implemented in earlier
+ versions of NI-VISA. You should now query VI_ATTR_MANF_ID or
+ VI_ATTR_MODEL_CODE. Those attributes contain sub-vendor information
+ when it exists. To get both the actual primary and subvendor codes
+ from the device, you should call viIn16 using VI_PXI_CFG_SPACE. */
+#define VI_ATTR_PXI_SUB_MANF_ID (0x3FFF0203UL)
+#define VI_ATTR_PXI_SUB_MODEL_CODE (0x3FFF0204UL)
+#endif
+
+#define VI_ATTR_PXI_SRC_TRIG_BUS (0x3FFF020DUL)
+#define VI_ATTR_PXI_DEST_TRIG_BUS (0x3FFF020EUL)
+
+#define VI_ATTR_PXI_RECV_INTR_SEQ (0x3FFF4240UL)
+#define VI_ATTR_PXI_RECV_INTR_DATA (0x3FFF4241UL)
+
+#endif
+
+#if defined(NIVISA_USB)
+
+#define VI_ATTR_USB_BULK_OUT_PIPE (0x3FFF01A2UL)
+#define VI_ATTR_USB_BULK_IN_PIPE (0x3FFF01A3UL)
+#define VI_ATTR_USB_INTR_IN_PIPE (0x3FFF01A4UL)
+#define VI_ATTR_USB_CLASS (0x3FFF01A5UL)
+#define VI_ATTR_USB_SUBCLASS (0x3FFF01A6UL)
+#define VI_ATTR_USB_ALT_SETTING (0x3FFF01A8UL)
+#define VI_ATTR_USB_END_IN (0x3FFF01A9UL)
+#define VI_ATTR_USB_NUM_INTFCS (0x3FFF01AAUL)
+#define VI_ATTR_USB_NUM_PIPES (0x3FFF01ABUL)
+#define VI_ATTR_USB_BULK_OUT_STATUS (0x3FFF01ACUL)
+#define VI_ATTR_USB_BULK_IN_STATUS (0x3FFF01ADUL)
+#define VI_ATTR_USB_INTR_IN_STATUS (0x3FFF01AEUL)
+#define VI_ATTR_USB_CTRL_PIPE (0x3FFF01B0UL)
+
+#define VI_USB_PIPE_STATE_UNKNOWN (-1)
+#define VI_USB_PIPE_READY (0)
+#define VI_USB_PIPE_STALLED (1)
+
+#define VI_USB_END_NONE (0)
+#define VI_USB_END_SHORT (4)
+#define VI_USB_END_SHORT_OR_COUNT (5)
+
+#endif
+
+#define VI_ATTR_FIREWIRE_DEST_UPPER_OFFSET (0x3FFF01F0UL)
+#define VI_ATTR_FIREWIRE_SRC_UPPER_OFFSET (0x3FFF01F1UL)
+#define VI_ATTR_FIREWIRE_WIN_UPPER_OFFSET (0x3FFF01F2UL)
+#define VI_ATTR_FIREWIRE_VENDOR_ID (0x3FFF01F3UL)
+#define VI_ATTR_FIREWIRE_LOWER_CHIP_ID (0x3FFF01F4UL)
+#define VI_ATTR_FIREWIRE_UPPER_CHIP_ID (0x3FFF01F5UL)
+
+#define VI_FIREWIRE_DFLT_SPACE (5)
+
+#if defined(__cplusplus) || defined(__cplusplus__)
+ }
+#endif
+
+#endif
+
+/*- The End -----------------------------------------------------------------*/
diff --git a/hal/src/main/native/athena/visa/visatype.h b/hal/src/main/native/athena/visa/visatype.h
new file mode 100644
index 0000000..ef089dd
--- /dev/null
+++ b/hal/src/main/native/athena/visa/visatype.h
@@ -0,0 +1,201 @@
+/*---------------------------------------------------------------------------*/
+/* Distributed by IVI Foundation Inc. */
+/* */
+/* Do not modify the contents of this file. */
+/*---------------------------------------------------------------------------*/
+/* */
+/* Title : VISATYPE.H */
+/* Date : 04-14-2006 */
+/* Purpose : Fundamental VISA data types and macro definitions */
+/* */
+/*---------------------------------------------------------------------------*/
+
+#ifndef __VISATYPE_HEADER__
+#define __VISATYPE_HEADER__
+
+#if defined(_WIN64)
+#define _VI_FAR
+#define _VI_FUNC __fastcall
+#define _VI_FUNCC __fastcall
+#define _VI_FUNCH __fastcall
+#define _VI_SIGNED signed
+#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) && !defined(_NI_mswin16_)
+#define _VI_FAR
+#define _VI_FUNC __stdcall
+#define _VI_FUNCC __cdecl
+#define _VI_FUNCH __stdcall
+#define _VI_SIGNED signed
+#elif defined(_CVI_) && defined(_NI_i386_)
+#define _VI_FAR
+#define _VI_FUNC _pascal
+#define _VI_FUNCC
+#define _VI_FUNCH _pascal
+#define _VI_SIGNED signed
+#elif (defined(_WINDOWS) || defined(_Windows)) && !defined(_NI_mswin16_)
+#define _VI_FAR _far
+#define _VI_FUNC _far _pascal _export
+#define _VI_FUNCC _far _cdecl _export
+#define _VI_FUNCH _far _pascal
+#define _VI_SIGNED signed
+#elif (defined(hpux) || defined(__hpux)) && (defined(__cplusplus) || defined(__cplusplus__))
+#define _VI_FAR
+#define _VI_FUNC
+#define _VI_FUNCC
+#define _VI_FUNCH
+#define _VI_SIGNED
+#else
+#define _VI_FAR
+#define _VI_FUNC
+#define _VI_FUNCC
+#define _VI_FUNCH
+#define _VI_SIGNED signed
+#endif
+
+#define _VI_ERROR (-2147483647L-1) /* 0x80000000 */
+#define _VI_PTR _VI_FAR *
+
+/*- VISA Types --------------------------------------------------------------*/
+
+#ifndef _VI_INT64_UINT64_DEFINED
+#if defined(_WIN64) || ((defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) && !defined(_NI_mswin16_))
+#if (defined(_MSC_VER) && (_MSC_VER >= 1200)) || (defined(_CVI_) && (_CVI_ >= 700)) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0520))
+typedef unsigned __int64 ViUInt64;
+typedef _VI_SIGNED __int64 ViInt64;
+#define _VI_INT64_UINT64_DEFINED
+#if defined(_WIN64)
+#define _VISA_ENV_IS_64_BIT
+#else
+/* This is a 32-bit OS, not a 64-bit OS */
+#endif
+#endif
+#elif defined(__GNUC__) && (__GNUC__ >= 3)
+#include <limits.h>
+#include <sys/types.h>
+typedef u_int64_t ViUInt64;
+typedef int64_t ViInt64;
+#define _VI_INT64_UINT64_DEFINED
+#if defined(LONG_MAX) && (LONG_MAX > 0x7FFFFFFFL)
+#define _VISA_ENV_IS_64_BIT
+#else
+/* This is a 32-bit OS, not a 64-bit OS */
+#endif
+#else
+/* This platform does not support 64-bit types */
+#endif
+#endif
+
+#if defined(_VI_INT64_UINT64_DEFINED)
+typedef ViUInt64 _VI_PTR ViPUInt64;
+typedef ViUInt64 _VI_PTR ViAUInt64;
+typedef ViInt64 _VI_PTR ViPInt64;
+typedef ViInt64 _VI_PTR ViAInt64;
+#endif
+
+#if defined(LONG_MAX) && (LONG_MAX > 0x7FFFFFFFL)
+typedef unsigned int ViUInt32;
+typedef _VI_SIGNED int ViInt32;
+#else
+typedef unsigned long ViUInt32;
+typedef _VI_SIGNED long ViInt32;
+#endif
+
+typedef ViUInt32 _VI_PTR ViPUInt32;
+typedef ViUInt32 _VI_PTR ViAUInt32;
+typedef ViInt32 _VI_PTR ViPInt32;
+typedef ViInt32 _VI_PTR ViAInt32;
+
+typedef unsigned short ViUInt16;
+typedef ViUInt16 _VI_PTR ViPUInt16;
+typedef ViUInt16 _VI_PTR ViAUInt16;
+
+typedef _VI_SIGNED short ViInt16;
+typedef ViInt16 _VI_PTR ViPInt16;
+typedef ViInt16 _VI_PTR ViAInt16;
+
+typedef unsigned char ViUInt8;
+typedef ViUInt8 _VI_PTR ViPUInt8;
+typedef ViUInt8 _VI_PTR ViAUInt8;
+
+typedef _VI_SIGNED char ViInt8;
+typedef ViInt8 _VI_PTR ViPInt8;
+typedef ViInt8 _VI_PTR ViAInt8;
+
+typedef char ViChar;
+typedef ViChar _VI_PTR ViPChar;
+typedef ViChar _VI_PTR ViAChar;
+
+typedef unsigned char ViByte;
+typedef ViByte _VI_PTR ViPByte;
+typedef ViByte _VI_PTR ViAByte;
+
+typedef void _VI_PTR ViAddr;
+typedef ViAddr _VI_PTR ViPAddr;
+typedef ViAddr _VI_PTR ViAAddr;
+
+typedef float ViReal32;
+typedef ViReal32 _VI_PTR ViPReal32;
+typedef ViReal32 _VI_PTR ViAReal32;
+
+typedef double ViReal64;
+typedef ViReal64 _VI_PTR ViPReal64;
+typedef ViReal64 _VI_PTR ViAReal64;
+
+typedef ViPByte ViBuf;
+typedef ViPByte ViPBuf;
+typedef ViPByte _VI_PTR ViABuf;
+
+typedef ViPChar ViString;
+typedef ViPChar ViPString;
+typedef ViPChar _VI_PTR ViAString;
+
+typedef ViString ViRsrc;
+typedef ViString ViPRsrc;
+typedef ViString _VI_PTR ViARsrc;
+
+typedef ViUInt16 ViBoolean;
+typedef ViBoolean _VI_PTR ViPBoolean;
+typedef ViBoolean _VI_PTR ViABoolean;
+
+typedef ViInt32 ViStatus;
+typedef ViStatus _VI_PTR ViPStatus;
+typedef ViStatus _VI_PTR ViAStatus;
+
+typedef ViUInt32 ViVersion;
+typedef ViVersion _VI_PTR ViPVersion;
+typedef ViVersion _VI_PTR ViAVersion;
+
+typedef ViUInt32 ViObject;
+typedef ViObject _VI_PTR ViPObject;
+typedef ViObject _VI_PTR ViAObject;
+
+typedef ViObject ViSession;
+typedef ViSession _VI_PTR ViPSession;
+typedef ViSession _VI_PTR ViASession;
+
+typedef ViUInt32 ViAttr;
+
+#ifndef _VI_CONST_STRING_DEFINED
+typedef const ViChar * ViConstString;
+#define _VI_CONST_STRING_DEFINED
+#endif
+
+/*- Completion and Error Codes ----------------------------------------------*/
+
+#define VI_SUCCESS (0L)
+
+/*- Other VISA Definitions --------------------------------------------------*/
+
+#define VI_NULL (0)
+
+#define VI_TRUE (1)
+#define VI_FALSE (0)
+
+/*- Backward Compatibility Macros -------------------------------------------*/
+
+#define VISAFN _VI_FUNC
+#define ViPtr _VI_PTR
+
+#endif
+
+/*- The End -----------------------------------------------------------------*/
+
diff --git a/hal/src/main/native/cpp/cpp/fpga_clock.cpp b/hal/src/main/native/cpp/cpp/fpga_clock.cpp
new file mode 100644
index 0000000..751eae1
--- /dev/null
+++ b/hal/src/main/native/cpp/cpp/fpga_clock.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/cpp/fpga_clock.h"
+
+#include <wpi/raw_ostream.h>
+
+#include "hal/HAL.h"
+
+namespace hal {
+const fpga_clock::time_point fpga_clock::min_time =
+ fpga_clock::time_point(fpga_clock::duration(
+ std::numeric_limits<fpga_clock::duration::rep>::min()));
+
+fpga_clock::time_point fpga_clock::now() noexcept {
+ int32_t status = 0;
+ uint64_t currentTime = HAL_GetFPGATime(&status);
+ if (status != 0) {
+ wpi::errs()
+ << "Call to HAL_GetFPGATime failed."
+ << "Initialization might have failed. Time will not be correct\n";
+ wpi::errs().flush();
+ return epoch();
+ }
+ return time_point(std::chrono::microseconds(currentTime));
+}
+} // namespace hal
diff --git a/hal/src/main/native/cpp/handles/HandlesInternal.cpp b/hal/src/main/native/cpp/handles/HandlesInternal.cpp
new file mode 100644
index 0000000..45ffb31
--- /dev/null
+++ b/hal/src/main/native/cpp/handles/HandlesInternal.cpp
@@ -0,0 +1,95 @@
+/*----------------------------------------------------------------------------*/
+/* 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/handles/HandlesInternal.h"
+
+#include <algorithm>
+
+#include <wpi/SmallVector.h>
+#include <wpi/mutex.h>
+
+namespace hal {
+static wpi::SmallVector<HandleBase*, 32>* globalHandles = nullptr;
+static wpi::mutex globalHandleMutex;
+HandleBase::HandleBase() {
+ static wpi::SmallVector<HandleBase*, 32> gH;
+ std::lock_guard<wpi::mutex> lock(globalHandleMutex);
+ if (!globalHandles) {
+ globalHandles = &gH;
+ }
+
+ auto index = std::find(globalHandles->begin(), globalHandles->end(), this);
+ if (index == globalHandles->end()) {
+ globalHandles->push_back(this);
+ } else {
+ *index = this;
+ }
+}
+HandleBase::~HandleBase() {
+ std::lock_guard<wpi::mutex> lock(globalHandleMutex);
+ auto index = std::find(globalHandles->begin(), globalHandles->end(), this);
+ if (index != globalHandles->end()) {
+ *index = nullptr;
+ }
+}
+void HandleBase::ResetHandles() {
+ m_version++;
+ if (m_version > 255) {
+ m_version = 0;
+ }
+}
+void HandleBase::ResetGlobalHandles() {
+ std::unique_lock<wpi::mutex> lock(globalHandleMutex);
+ for (auto&& i : *globalHandles) {
+ if (i != nullptr) {
+ lock.unlock();
+ i->ResetHandles();
+ lock.lock();
+ }
+ }
+}
+HAL_PortHandle createPortHandle(uint8_t channel, uint8_t module) {
+ // set last 8 bits, then shift to first 8 bits
+ HAL_PortHandle handle = static_cast<HAL_PortHandle>(HAL_HandleEnum::Port);
+ handle = handle << 24;
+ // shift module and add to 3rd set of 8 bits
+ int32_t temp = module;
+ temp = (temp << 8) & 0xff00;
+ handle += temp;
+ // add channel to last 8 bits
+ handle += channel;
+ return handle;
+}
+HAL_PortHandle createPortHandleForSPI(uint8_t channel) {
+ // set last 8 bits, then shift to first 8 bits
+ HAL_PortHandle handle = static_cast<HAL_PortHandle>(HAL_HandleEnum::Port);
+ handle = handle << 16;
+ // set second set up bits to 1
+ int32_t temp = 1;
+ temp = (temp << 8) & 0xff00;
+ handle += temp;
+ // shift to last set of bits
+ handle = handle << 8;
+ // add channel to last 8 bits
+ handle += channel;
+ return handle;
+}
+HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType,
+ int16_t version) {
+ if (index < 0) return HAL_kInvalidHandle;
+ uint8_t hType = static_cast<uint8_t>(handleType);
+ if (hType == 0 || hType > 127) return HAL_kInvalidHandle;
+ // set last 8 bits, then shift to first 8 bits
+ HAL_Handle handle = hType;
+ handle = handle << 8;
+ handle += static_cast<uint8_t>(version);
+ handle = handle << 16;
+ // add index to set last 16 bits
+ handle += index;
+ return handle;
+}
+} // namespace hal
diff --git a/hal/src/main/native/cpp/jni/AccelerometerJNI.cpp b/hal/src/main/native/cpp/jni/AccelerometerJNI.cpp
new file mode 100644
index 0000000..6d0d256
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/AccelerometerJNI.cpp
@@ -0,0 +1,75 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include "edu_wpi_first_hal_AccelerometerJNI.h"
+#include "hal/Accelerometer.h"
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_AccelerometerJNI
+ * Method: setAccelerometerActive
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AccelerometerJNI_setAccelerometerActive
+ (JNIEnv*, jclass, jboolean active)
+{
+ HAL_SetAccelerometerActive(active);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AccelerometerJNI
+ * Method: setAccelerometerRange
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AccelerometerJNI_setAccelerometerRange
+ (JNIEnv*, jclass, jint range)
+{
+ HAL_SetAccelerometerRange((HAL_AccelerometerRange)range);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AccelerometerJNI
+ * Method: getAccelerometerX
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_AccelerometerJNI_getAccelerometerX
+ (JNIEnv*, jclass)
+{
+ return HAL_GetAccelerometerX();
+}
+
+/*
+ * Class: edu_wpi_first_hal_AccelerometerJNI
+ * Method: getAccelerometerY
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_AccelerometerJNI_getAccelerometerY
+ (JNIEnv*, jclass)
+{
+ return HAL_GetAccelerometerY();
+}
+
+/*
+ * Class: edu_wpi_first_hal_AccelerometerJNI
+ * Method: getAccelerometerZ
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_AccelerometerJNI_getAccelerometerZ
+ (JNIEnv*, jclass)
+{
+ return HAL_GetAccelerometerZ();
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/AnalogGyroJNI.cpp b/hal/src/main/native/cpp/jni/AnalogGyroJNI.cpp
new file mode 100644
index 0000000..74c1b49
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/AnalogGyroJNI.cpp
@@ -0,0 +1,248 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_AnalogGyroJNI.h"
+#include "hal/AnalogGyro.h"
+#include "hal/cpp/Log.h"
+#include "hal/handles/HandlesInternal.h"
+
+using namespace frc;
+
+// set the logging level
+TLogLevel analogGyroJNILogLevel = logWARNING;
+
+#define ANALOGGYROJNI_LOG(level) \
+ if (level > analogGyroJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+/*
+ * Class: edu_wpi_first_hal_AnalogGyroJNI
+ * Method: initializeAnalogGyro
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_AnalogGyroJNI_initializeAnalogGyro
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI initializeAnalogGyro";
+ ANALOGGYROJNI_LOG(logDEBUG)
+ << "Analog Input Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ HAL_GyroHandle handle =
+ HAL_InitializeAnalogGyro((HAL_AnalogInputHandle)id, &status);
+ ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << handle;
+ // Analog input does range checking, so we don't need to do so.
+ CheckStatusForceThrow(env, status);
+ return (jint)handle;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogGyroJNI
+ * Method: setupAnalogGyro
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogGyroJNI_setupAnalogGyro
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI setupAnalogGyro";
+ ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
+ int32_t status = 0;
+ HAL_SetupAnalogGyro((HAL_GyroHandle)id, &status);
+ ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogGyroJNI
+ * Method: freeAnalogGyro
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogGyroJNI_freeAnalogGyro
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI freeAnalogGyro";
+ ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
+ HAL_FreeAnalogGyro((HAL_GyroHandle)id);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogGyroJNI
+ * Method: setAnalogGyroParameters
+ * Signature: (IDDI)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogGyroJNI_setAnalogGyroParameters
+ (JNIEnv* env, jclass, jint id, jdouble vPDPS, jdouble offset, jint center)
+{
+ ANALOGGYROJNI_LOG(logDEBUG)
+ << "Calling ANALOGGYROJNI setAnalogGyroParameters";
+ ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
+ int32_t status = 0;
+ HAL_SetAnalogGyroParameters((HAL_GyroHandle)id, vPDPS, offset, center,
+ &status);
+ ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogGyroJNI
+ * Method: setAnalogGyroVoltsPerDegreePerSecond
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogGyroJNI_setAnalogGyroVoltsPerDegreePerSecond
+ (JNIEnv* env, jclass, jint id, jdouble vPDPS)
+{
+ ANALOGGYROJNI_LOG(logDEBUG)
+ << "Calling ANALOGGYROJNI setAnalogGyroVoltsPerDegreePerSecond";
+ ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
+ ANALOGGYROJNI_LOG(logDEBUG) << "vPDPS = " << vPDPS;
+ int32_t status = 0;
+ HAL_SetAnalogGyroVoltsPerDegreePerSecond((HAL_GyroHandle)id, vPDPS, &status);
+ ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogGyroJNI
+ * Method: resetAnalogGyro
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogGyroJNI_resetAnalogGyro
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI resetAnalogGyro";
+ ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
+ int32_t status = 0;
+ HAL_ResetAnalogGyro((HAL_GyroHandle)id, &status);
+ ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogGyroJNI
+ * Method: calibrateAnalogGyro
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogGyroJNI_calibrateAnalogGyro
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI calibrateAnalogGyro";
+ ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
+ int32_t status = 0;
+ HAL_CalibrateAnalogGyro((HAL_GyroHandle)id, &status);
+ ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogGyroJNI
+ * Method: setAnalogGyroDeadband
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogGyroJNI_setAnalogGyroDeadband
+ (JNIEnv* env, jclass, jint id, jdouble deadband)
+{
+ ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI setAnalogGyroDeadband";
+ ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
+ int32_t status = 0;
+ HAL_SetAnalogGyroDeadband((HAL_GyroHandle)id, deadband, &status);
+ ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogGyroJNI
+ * Method: getAnalogGyroAngle
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_AnalogGyroJNI_getAnalogGyroAngle
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI getAnalogGyroAngle";
+ ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
+ int32_t status = 0;
+ jdouble value = HAL_GetAnalogGyroAngle((HAL_GyroHandle)id, &status);
+ ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGGYROJNI_LOG(logDEBUG) << "Result = " << value;
+ CheckStatus(env, status);
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogGyroJNI
+ * Method: getAnalogGyroRate
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_AnalogGyroJNI_getAnalogGyroRate
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI getAnalogGyroRate";
+ ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
+ int32_t status = 0;
+ jdouble value = HAL_GetAnalogGyroRate((HAL_GyroHandle)id, &status);
+ ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGGYROJNI_LOG(logDEBUG) << "Result = " << value;
+ CheckStatus(env, status);
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogGyroJNI
+ * Method: getAnalogGyroOffset
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_AnalogGyroJNI_getAnalogGyroOffset
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI getAnalogGyroOffset";
+ ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
+ int32_t status = 0;
+ jdouble value = HAL_GetAnalogGyroOffset((HAL_GyroHandle)id, &status);
+ ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGGYROJNI_LOG(logDEBUG) << "Result = " << value;
+ CheckStatus(env, status);
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogGyroJNI
+ * Method: getAnalogGyroCenter
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_AnalogGyroJNI_getAnalogGyroCenter
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGGYROJNI_LOG(logDEBUG) << "Calling ANALOGGYROJNI getAnalogGyroCenter";
+ ANALOGGYROJNI_LOG(logDEBUG) << "Gyro Handle = " << (HAL_GyroHandle)id;
+ int32_t status = 0;
+ jint value = HAL_GetAnalogGyroCenter((HAL_GyroHandle)id, &status);
+ ANALOGGYROJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGGYROJNI_LOG(logDEBUG) << "Result = " << value;
+ CheckStatus(env, status);
+ return value;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/AnalogJNI.cpp b/hal/src/main/native/cpp/jni/AnalogJNI.cpp
new file mode 100644
index 0000000..3b2aa2d
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/AnalogJNI.cpp
@@ -0,0 +1,722 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_AnalogJNI.h"
+#include "hal/AnalogAccumulator.h"
+#include "hal/AnalogInput.h"
+#include "hal/AnalogOutput.h"
+#include "hal/AnalogTrigger.h"
+#include "hal/Ports.h"
+#include "hal/cpp/Log.h"
+#include "hal/handles/HandlesInternal.h"
+
+using namespace frc;
+
+// set the logging level
+TLogLevel analogJNILogLevel = logWARNING;
+
+#define ANALOGJNI_LOG(level) \
+ if (level > analogJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: initializeAnalogInputPort
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_initializeAnalogInputPort
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id;
+ int32_t status = 0;
+ auto analog = HAL_InitializeAnalogInputPort((HAL_PortHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << analog;
+ CheckStatusRange(env, status, 0, HAL_GetNumAnalogInputs(),
+ hal::getPortHandleChannel((HAL_PortHandle)id));
+ return (jint)analog;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: freeAnalogInputPort
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_freeAnalogInputPort
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_AnalogInputHandle)id;
+ HAL_FreeAnalogInputPort((HAL_AnalogInputHandle)id);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: initializeAnalogOutputPort
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_initializeAnalogOutputPort
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id;
+ int32_t status = 0;
+ HAL_AnalogOutputHandle analog =
+ HAL_InitializeAnalogOutputPort((HAL_PortHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << analog;
+ CheckStatusRange(env, status, 0, HAL_GetNumAnalogOutputs(),
+ hal::getPortHandleChannel((HAL_PortHandle)id));
+ return (jlong)analog;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: freeAnalogOutputPort
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_freeAnalogOutputPort
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Port Handle = " << id;
+ HAL_FreeAnalogOutputPort((HAL_AnalogOutputHandle)id);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: checkAnalogModule
+ * Signature: (B)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_checkAnalogModule
+ (JNIEnv*, jclass, jbyte value)
+{
+ // ANALOGJNI_LOG(logDEBUG) << "Module = " << (jint)value;
+ jboolean returnValue = HAL_CheckAnalogModule(value);
+ // ANALOGJNI_LOG(logDEBUG) << "checkAnalogModuleResult = " <<
+ // (jint)returnValue;
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: checkAnalogInputChannel
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_checkAnalogInputChannel
+ (JNIEnv*, jclass, jint value)
+{
+ // ANALOGJNI_LOG(logDEBUG) << "Channel = " << value;
+ jboolean returnValue = HAL_CheckAnalogInputChannel(value);
+ // ANALOGJNI_LOG(logDEBUG) << "checkAnalogChannelResult = " <<
+ // (jint)returnValue;
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: checkAnalogOutputChannel
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_checkAnalogOutputChannel
+ (JNIEnv*, jclass, jint value)
+{
+ // ANALOGJNI_LOG(logDEBUG) << "Channel = " << value;
+ jboolean returnValue = HAL_CheckAnalogOutputChannel(value);
+ // ANALOGJNI_LOG(logDEBUG) << "checkAnalogChannelResult = " <<
+ // (jint)returnValue;
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: setAnalogOutput
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_setAnalogOutput
+ (JNIEnv* env, jclass, jint id, jdouble voltage)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Calling setAnalogOutput";
+ ANALOGJNI_LOG(logDEBUG) << "Voltage = " << voltage;
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << id;
+ int32_t status = 0;
+ HAL_SetAnalogOutput((HAL_AnalogOutputHandle)id, voltage, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogOutput
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogOutput
+ (JNIEnv* env, jclass, jint id)
+{
+ int32_t status = 0;
+ double val = HAL_GetAnalogOutput((HAL_AnalogOutputHandle)id, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: setAnalogSampleRate
+ * Signature: (D)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_setAnalogSampleRate
+ (JNIEnv* env, jclass, jdouble value)
+{
+ ANALOGJNI_LOG(logDEBUG) << "SampleRate = " << value;
+ int32_t status = 0;
+ HAL_SetAnalogSampleRate(value, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogSampleRate
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogSampleRate
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ double returnValue = HAL_GetAnalogSampleRate(&status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "SampleRate = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: setAnalogAverageBits
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_setAnalogAverageBits
+ (JNIEnv* env, jclass, jint id, jint value)
+{
+ ANALOGJNI_LOG(logDEBUG) << "AverageBits = " << value;
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ HAL_SetAnalogAverageBits((HAL_AnalogInputHandle)id, value, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogAverageBits
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogAverageBits
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ jint returnValue =
+ HAL_GetAnalogAverageBits((HAL_AnalogInputHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "AverageBits = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: setAnalogOversampleBits
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_setAnalogOversampleBits
+ (JNIEnv* env, jclass, jint id, jint value)
+{
+ ANALOGJNI_LOG(logDEBUG) << "OversampleBits = " << value;
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ HAL_SetAnalogOversampleBits((HAL_AnalogInputHandle)id, value, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogOversampleBits
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogOversampleBits
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ jint returnValue =
+ HAL_GetAnalogOversampleBits((HAL_AnalogInputHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "OversampleBits = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogValue
+ * Signature: (I)S
+ */
+JNIEXPORT jshort JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogValue
+ (JNIEnv* env, jclass, jint id)
+{
+ // ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (void*)id;
+ int32_t status = 0;
+ jshort returnValue = HAL_GetAnalogValue((HAL_AnalogInputHandle)id, &status);
+ // ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ // ANALOGJNI_LOG(logDEBUG) << "Value = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogAverageValue
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogAverageValue
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ jint returnValue =
+ HAL_GetAnalogAverageValue((HAL_AnalogInputHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "AverageValue = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogVoltsToValue
+ * Signature: (ID)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogVoltsToValue
+ (JNIEnv* env, jclass, jint id, jdouble voltageValue)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ ANALOGJNI_LOG(logDEBUG) << "VoltageValue = " << voltageValue;
+ int32_t status = 0;
+ jint returnValue = HAL_GetAnalogVoltsToValue((HAL_AnalogInputHandle)id,
+ voltageValue, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "Value = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogVoltage
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogVoltage
+ (JNIEnv* env, jclass, jint id)
+{
+ // ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (void*)id;
+ int32_t status = 0;
+ jdouble returnValue =
+ HAL_GetAnalogVoltage((HAL_AnalogInputHandle)id, &status);
+ // ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ // ANALOGJNI_LOG(logDEBUG) << "Voltage = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogAverageVoltage
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogAverageVoltage
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ jdouble returnValue =
+ HAL_GetAnalogAverageVoltage((HAL_AnalogInputHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "AverageVoltage = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogLSBWeight
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogLSBWeight
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+
+ jint returnValue = HAL_GetAnalogLSBWeight((HAL_AnalogInputHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "AnalogLSBWeight = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogOffset
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogOffset
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+
+ jint returnValue = HAL_GetAnalogOffset((HAL_AnalogInputHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "AnalogOffset = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: isAccumulatorChannel
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_isAccumulatorChannel
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "isAccumulatorChannel";
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+
+ jboolean returnValue =
+ HAL_IsAccumulatorChannel((HAL_AnalogInputHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "AnalogOffset = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: initAccumulator
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_initAccumulator
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ HAL_InitAccumulator((HAL_AnalogInputHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: resetAccumulator
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_resetAccumulator
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ HAL_ResetAccumulator((HAL_AnalogInputHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: setAccumulatorCenter
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_setAccumulatorCenter
+ (JNIEnv* env, jclass, jint id, jint center)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ HAL_SetAccumulatorCenter((HAL_AnalogInputHandle)id, center, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: setAccumulatorDeadband
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_setAccumulatorDeadband
+ (JNIEnv* env, jclass, jint id, jint deadband)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ HAL_SetAccumulatorDeadband((HAL_AnalogInputHandle)id, deadband, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAccumulatorValue
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAccumulatorValue
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ jlong returnValue =
+ HAL_GetAccumulatorValue((HAL_AnalogInputHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "AccumulatorValue = " << returnValue;
+ CheckStatus(env, status);
+
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAccumulatorCount
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAccumulatorCount
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ jint returnValue =
+ HAL_GetAccumulatorCount((HAL_AnalogInputHandle)id, &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "AccumulatorCount = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAccumulatorOutput
+ * Signature: (ILjava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAccumulatorOutput
+ (JNIEnv* env, jclass, jint id, jobject accumulatorResult)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Handle = " << (HAL_AnalogInputHandle)id;
+ int32_t status = 0;
+ int64_t value = 0;
+ int64_t count = 0;
+ HAL_GetAccumulatorOutput((HAL_AnalogInputHandle)id, &value, &count, &status);
+ SetAccumulatorResultObject(env, accumulatorResult, value, count);
+ ANALOGJNI_LOG(logDEBUG) << "Value = " << value;
+ ANALOGJNI_LOG(logDEBUG) << "Count = " << count;
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: initializeAnalogTrigger
+ * Signature: (ILjava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_initializeAnalogTrigger
+ (JNIEnv* env, jclass, jint id, jobject index)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_AnalogInputHandle)id;
+ jint* indexHandle =
+ reinterpret_cast<jint*>(env->GetDirectBufferAddress(index));
+ ANALOGJNI_LOG(logDEBUG) << "Index Ptr = " << indexHandle;
+ int32_t status = 0;
+ HAL_AnalogTriggerHandle analogTrigger = HAL_InitializeAnalogTrigger(
+ (HAL_AnalogInputHandle)id, reinterpret_cast<int32_t*>(indexHandle),
+ &status);
+ ANALOGJNI_LOG(logDEBUG) << "Status = " << status;
+ ANALOGJNI_LOG(logDEBUG) << "AnalogTrigger Handle = " << analogTrigger;
+ CheckStatus(env, status);
+ return (jint)analogTrigger;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: cleanAnalogTrigger
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_cleanAnalogTrigger
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
+ << (HAL_AnalogTriggerHandle)id;
+ int32_t status = 0;
+ HAL_CleanAnalogTrigger((HAL_AnalogTriggerHandle)id, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: setAnalogTriggerLimitsRaw
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_setAnalogTriggerLimitsRaw
+ (JNIEnv* env, jclass, jint id, jint lower, jint upper)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
+ << (HAL_AnalogTriggerHandle)id;
+ int32_t status = 0;
+ HAL_SetAnalogTriggerLimitsRaw((HAL_AnalogTriggerHandle)id, lower, upper,
+ &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: setAnalogTriggerLimitsVoltage
+ * Signature: (IDD)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_setAnalogTriggerLimitsVoltage
+ (JNIEnv* env, jclass, jint id, jdouble lower, jdouble upper)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
+ << (HAL_AnalogTriggerHandle)id;
+ int32_t status = 0;
+ HAL_SetAnalogTriggerLimitsVoltage((HAL_AnalogTriggerHandle)id, lower, upper,
+ &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: setAnalogTriggerAveraged
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_setAnalogTriggerAveraged
+ (JNIEnv* env, jclass, jint id, jboolean averaged)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
+ << (HAL_AnalogTriggerHandle)id;
+ int32_t status = 0;
+ HAL_SetAnalogTriggerAveraged((HAL_AnalogTriggerHandle)id, averaged, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: setAnalogTriggerFiltered
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_setAnalogTriggerFiltered
+ (JNIEnv* env, jclass, jint id, jboolean filtered)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
+ << (HAL_AnalogTriggerHandle)id;
+ int32_t status = 0;
+ HAL_SetAnalogTriggerFiltered((HAL_AnalogTriggerHandle)id, filtered, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogTriggerInWindow
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogTriggerInWindow
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
+ << (HAL_AnalogTriggerHandle)id;
+ int32_t status = 0;
+ jboolean val =
+ HAL_GetAnalogTriggerInWindow((HAL_AnalogTriggerHandle)id, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogTriggerTriggerState
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogTriggerTriggerState
+ (JNIEnv* env, jclass, jint id)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
+ << (HAL_AnalogTriggerHandle)id;
+ int32_t status = 0;
+ jboolean val =
+ HAL_GetAnalogTriggerTriggerState((HAL_AnalogTriggerHandle)id, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_AnalogJNI
+ * Method: getAnalogTriggerOutput
+ * Signature: (II)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_AnalogJNI_getAnalogTriggerOutput
+ (JNIEnv* env, jclass, jint id, jint type)
+{
+ ANALOGJNI_LOG(logDEBUG) << "Analog Trigger Handle = "
+ << (HAL_AnalogTriggerHandle)id;
+ int32_t status = 0;
+ jboolean val = HAL_GetAnalogTriggerOutput(
+ (HAL_AnalogTriggerHandle)id, (HAL_AnalogTriggerType)type, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/CANAPIJNI.cpp b/hal/src/main/native/cpp/jni/CANAPIJNI.cpp
new file mode 100644
index 0000000..bcb285c
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/CANAPIJNI.cpp
@@ -0,0 +1,241 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <cassert>
+
+#include <wpi/SmallString.h>
+#include <wpi/jni_util.h>
+#include <wpi/raw_ostream.h>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_CANAPIJNI.h"
+#include "hal/CAN.h"
+#include "hal/CANAPI.h"
+#include "hal/Errors.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+using namespace wpi::java;
+
+extern "C" {
+/*
+ * Class: edu_wpi_first_hal_CANAPIJNI
+ * Method: initializeCAN
+ * Signature: (III)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_CANAPIJNI_initializeCAN
+ (JNIEnv* env, jclass, jint manufacturer, jint deviceId, jint deviceType)
+{
+ int32_t status = 0;
+ auto handle =
+ HAL_InitializeCAN(static_cast<HAL_CANManufacturer>(manufacturer),
+ static_cast<int32_t>(deviceId),
+ static_cast<HAL_CANDeviceType>(deviceType), &status);
+
+ CheckStatusForceThrow(env, status);
+ return handle;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CANAPIJNI
+ * Method: cleanCAN
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CANAPIJNI_cleanCAN
+ (JNIEnv* env, jclass, jint handle)
+{
+ HAL_CleanCAN(static_cast<HAL_CANHandle>(handle));
+}
+
+/*
+ * Class: edu_wpi_first_hal_CANAPIJNI
+ * Method: writeCANPacket
+ * Signature: (I[BI)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CANAPIJNI_writeCANPacket
+ (JNIEnv* env, jclass, jint handle, jbyteArray data, jint apiId)
+{
+ auto halHandle = static_cast<HAL_CANHandle>(handle);
+ JByteArrayRef arr{env, data};
+ auto arrRef = arr.array();
+ int32_t status = 0;
+ HAL_WriteCANPacket(halHandle, reinterpret_cast<const uint8_t*>(arrRef.data()),
+ arrRef.size(), apiId, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CANAPIJNI
+ * Method: writeCANPacketRepeating
+ * Signature: (I[BII)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CANAPIJNI_writeCANPacketRepeating
+ (JNIEnv* env, jclass, jint handle, jbyteArray data, jint apiId,
+ jint timeoutMs)
+{
+ auto halHandle = static_cast<HAL_CANHandle>(handle);
+ JByteArrayRef arr{env, data};
+ auto arrRef = arr.array();
+ int32_t status = 0;
+ HAL_WriteCANPacketRepeating(halHandle,
+ reinterpret_cast<const uint8_t*>(arrRef.data()),
+ arrRef.size(), apiId, timeoutMs, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CANAPIJNI
+ * Method: stopCANPacketRepeating
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CANAPIJNI_stopCANPacketRepeating
+ (JNIEnv* env, jclass, jint handle, jint apiId)
+{
+ auto halHandle = static_cast<HAL_CANHandle>(handle);
+ int32_t status = 0;
+ HAL_StopCANPacketRepeating(halHandle, apiId, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CANAPIJNI
+ * Method: readCANPacketNew
+ * Signature: (IILjava/lang/Object;)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CANAPIJNI_readCANPacketNew
+ (JNIEnv* env, jclass, jint handle, jint apiId, jobject data)
+{
+ auto halHandle = static_cast<HAL_CANHandle>(handle);
+ uint8_t dataTemp[8];
+ int32_t dataLength = 0;
+ uint64_t timestamp = 0;
+ int32_t status = 0;
+ HAL_ReadCANPacketNew(halHandle, apiId, dataTemp, &dataLength, ×tamp,
+ &status);
+ if (status == HAL_ERR_CANSessionMux_MessageNotFound) {
+ return false;
+ }
+ if (!CheckStatus(env, status)) {
+ return false;
+ }
+ if (dataLength > 8) dataLength = 8;
+
+ jbyteArray toSetArray = SetCANDataObject(env, data, dataLength, timestamp);
+ auto javaLen = env->GetArrayLength(toSetArray);
+ if (javaLen < dataLength) dataLength = javaLen;
+ env->SetByteArrayRegion(toSetArray, 0, dataLength,
+ reinterpret_cast<jbyte*>(dataTemp));
+ return true;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CANAPIJNI
+ * Method: readCANPacketLatest
+ * Signature: (IILjava/lang/Object;)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CANAPIJNI_readCANPacketLatest
+ (JNIEnv* env, jclass, jint handle, jint apiId, jobject data)
+{
+ auto halHandle = static_cast<HAL_CANHandle>(handle);
+ uint8_t dataTemp[8];
+ int32_t dataLength = 0;
+ uint64_t timestamp = 0;
+ int32_t status = 0;
+ HAL_ReadCANPacketLatest(halHandle, apiId, dataTemp, &dataLength, ×tamp,
+ &status);
+ if (status == HAL_ERR_CANSessionMux_MessageNotFound) {
+ return false;
+ }
+ if (!CheckStatus(env, status)) {
+ return false;
+ }
+ if (dataLength > 8) dataLength = 8;
+
+ jbyteArray toSetArray = SetCANDataObject(env, data, dataLength, timestamp);
+ auto javaLen = env->GetArrayLength(toSetArray);
+ if (javaLen < dataLength) dataLength = javaLen;
+ env->SetByteArrayRegion(toSetArray, 0, dataLength,
+ reinterpret_cast<jbyte*>(dataTemp));
+ return true;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CANAPIJNI
+ * Method: readCANPacketTimeout
+ * Signature: (IIILjava/lang/Object;)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CANAPIJNI_readCANPacketTimeout
+ (JNIEnv* env, jclass, jint handle, jint apiId, jint timeoutMs, jobject data)
+{
+ auto halHandle = static_cast<HAL_CANHandle>(handle);
+ uint8_t dataTemp[8];
+ int32_t dataLength = 0;
+ uint64_t timestamp = 0;
+ int32_t status = 0;
+ HAL_ReadCANPacketTimeout(halHandle, apiId, dataTemp, &dataLength, ×tamp,
+ timeoutMs, &status);
+ if (status == HAL_CAN_TIMEOUT ||
+ status == HAL_ERR_CANSessionMux_MessageNotFound) {
+ return false;
+ }
+ if (!CheckStatus(env, status)) {
+ return false;
+ }
+ if (dataLength > 8) dataLength = 8;
+
+ jbyteArray toSetArray = SetCANDataObject(env, data, dataLength, timestamp);
+ auto javaLen = env->GetArrayLength(toSetArray);
+ if (javaLen < dataLength) dataLength = javaLen;
+ env->SetByteArrayRegion(toSetArray, 0, dataLength,
+ reinterpret_cast<jbyte*>(dataTemp));
+ return true;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CANAPIJNI
+ * Method: readCANPeriodicPacket
+ * Signature: (IIIILjava/lang/Object;)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CANAPIJNI_readCANPeriodicPacket
+ (JNIEnv* env, jclass, jint handle, jint apiId, jint timeoutMs, jint periodMs,
+ jobject data)
+{
+ auto halHandle = static_cast<HAL_CANHandle>(handle);
+ uint8_t dataTemp[8];
+ int32_t dataLength = 0;
+ uint64_t timestamp = 0;
+ int32_t status = 0;
+ HAL_ReadCANPeriodicPacket(halHandle, apiId, dataTemp, &dataLength, ×tamp,
+ timeoutMs, periodMs, &status);
+ if (status == HAL_CAN_TIMEOUT ||
+ status == HAL_ERR_CANSessionMux_MessageNotFound) {
+ return false;
+ }
+ if (!CheckStatus(env, status)) {
+ return false;
+ }
+ if (dataLength > 8) dataLength = 8;
+
+ jbyteArray toSetArray = SetCANDataObject(env, data, dataLength, timestamp);
+ auto javaLen = env->GetArrayLength(toSetArray);
+ if (javaLen < dataLength) dataLength = javaLen;
+ env->SetByteArrayRegion(toSetArray, 0, dataLength,
+ reinterpret_cast<jbyte*>(dataTemp));
+ return true;
+}
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/CANJNI.cpp b/hal/src/main/native/cpp/jni/CANJNI.cpp
new file mode 100644
index 0000000..0f46d15
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/CANJNI.cpp
@@ -0,0 +1,158 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include <wpi/SmallString.h>
+#include <wpi/jni_util.h>
+#include <wpi/raw_ostream.h>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_can_CANJNI.h"
+#include "hal/CAN.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+using namespace wpi::java;
+
+// set the logging level
+// TLogLevel canJNILogLevel = logDEBUG;
+TLogLevel canJNILogLevel = logERROR;
+
+#define CANJNI_LOG(level) \
+ if (level > canJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_can_CANJNI
+ * Method: FRCNetCommCANSessionMuxSendMessage
+ * Signature: (I[BI)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_can_CANJNI_FRCNetCommCANSessionMuxSendMessage
+ (JNIEnv* env, jclass, jint messageID, jbyteArray data, jint periodMs)
+{
+ CANJNI_LOG(logDEBUG) << "Calling CANJNI FRCNetCommCANSessionMuxSendMessage";
+
+ JByteArrayRef dataArray{env, data};
+
+ const uint8_t* dataBuffer =
+ reinterpret_cast<const uint8_t*>(dataArray.array().data());
+ uint8_t dataSize = dataArray.array().size();
+
+ CANJNI_LOG(logDEBUG) << "Message ID ";
+ CANJNI_LOG(logDEBUG).write_hex(messageID);
+
+ if (logDEBUG <= canJNILogLevel) {
+ if (dataBuffer) {
+ wpi::SmallString<128> buf;
+ wpi::raw_svector_ostream str(buf);
+ for (int32_t i = 0; i < dataSize; i++) {
+ str.write_hex(dataBuffer[i]) << ' ';
+ }
+
+ Log().Get(logDEBUG) << "Data: " << str.str();
+ } else {
+ CANJNI_LOG(logDEBUG) << "Data: null";
+ }
+ }
+
+ CANJNI_LOG(logDEBUG) << "Period: " << periodMs;
+
+ int32_t status = 0;
+ HAL_CAN_SendMessage(messageID, dataBuffer, dataSize, periodMs, &status);
+
+ CANJNI_LOG(logDEBUG) << "Status: " << status;
+ CheckCANStatus(env, status, messageID);
+}
+
+/*
+ * Class: edu_wpi_first_hal_can_CANJNI
+ * Method: FRCNetCommCANSessionMuxReceiveMessage
+ * Signature: (Ljava/lang/Object;ILjava/lang/Object;)[B
+ */
+JNIEXPORT jbyteArray JNICALL
+Java_edu_wpi_first_hal_can_CANJNI_FRCNetCommCANSessionMuxReceiveMessage
+ (JNIEnv* env, jclass, jobject messageID, jint messageIDMask,
+ jobject timeStamp)
+{
+ CANJNI_LOG(logDEBUG)
+ << "Calling CANJNI FRCNetCommCANSessionMuxReceiveMessage";
+
+ uint32_t* messageIDPtr =
+ reinterpret_cast<uint32_t*>(env->GetDirectBufferAddress(messageID));
+ uint32_t* timeStampPtr =
+ reinterpret_cast<uint32_t*>(env->GetDirectBufferAddress(timeStamp));
+
+ uint8_t dataSize = 0;
+ uint8_t buffer[8];
+
+ int32_t status = 0;
+ HAL_CAN_ReceiveMessage(messageIDPtr, messageIDMask, buffer, &dataSize,
+ timeStampPtr, &status);
+
+ CANJNI_LOG(logDEBUG) << "Message ID ";
+ CANJNI_LOG(logDEBUG).write_hex(*messageIDPtr);
+
+ if (logDEBUG <= canJNILogLevel) {
+ wpi::SmallString<128> buf;
+ wpi::raw_svector_ostream str(buf);
+
+ for (int32_t i = 0; i < dataSize; i++) {
+ // Pad one-digit data with a zero
+ if (buffer[i] <= 16) {
+ str << '0';
+ }
+
+ str.write_hex(buffer[i]) << ' ';
+ }
+
+ Log().Get(logDEBUG) << "Data: " << str.str();
+ }
+
+ CANJNI_LOG(logDEBUG) << "Timestamp: " << *timeStampPtr;
+ CANJNI_LOG(logDEBUG) << "Status: " << status;
+
+ if (!CheckCANStatus(env, status, *messageIDPtr)) return nullptr;
+ return MakeJByteArray(env,
+ wpi::StringRef{reinterpret_cast<const char*>(buffer),
+ static_cast<size_t>(dataSize)});
+}
+
+/*
+ * Class: edu_wpi_first_hal_can_CANJNI
+ * Method: GetCANStatus
+ * Signature: (Ljava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_can_CANJNI_GetCANStatus
+ (JNIEnv* env, jclass, jobject canStatus)
+{
+ CANJNI_LOG(logDEBUG) << "Calling CANJNI HAL_CAN_GetCANStatus";
+
+ float percentBusUtilization = 0;
+ uint32_t busOffCount = 0;
+ uint32_t txFullCount = 0;
+ uint32_t receiveErrorCount = 0;
+ uint32_t transmitErrorCount = 0;
+ int32_t status = 0;
+ HAL_CAN_GetCANStatus(&percentBusUtilization, &busOffCount, &txFullCount,
+ &receiveErrorCount, &transmitErrorCount, &status);
+
+ if (!CheckStatus(env, status)) return;
+
+ SetCanStatusObject(env, canStatus, percentBusUtilization, busOffCount,
+ txFullCount, receiveErrorCount, transmitErrorCount);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/CompressorJNI.cpp b/hal/src/main/native/cpp/jni/CompressorJNI.cpp
new file mode 100644
index 0000000..e38abb5
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/CompressorJNI.cpp
@@ -0,0 +1,234 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HALUtil.h"
+#include "edu_wpi_first_hal_CompressorJNI.h"
+#include "hal/Compressor.h"
+#include "hal/Ports.h"
+#include "hal/Solenoid.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: initializeCompressor
+ * Signature: (B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_initializeCompressor
+ (JNIEnv* env, jclass, jbyte module)
+{
+ int32_t status = 0;
+ auto handle = HAL_InitializeCompressor(module, &status);
+ CheckStatusRange(env, status, 0, HAL_GetNumPCMModules(), module);
+
+ return (jint)handle;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: checkCompressorModule
+ * Signature: (B)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_checkCompressorModule
+ (JNIEnv* env, jclass, jbyte module)
+{
+ return HAL_CheckCompressorModule(module);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: getCompressor
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_getCompressor
+ (JNIEnv* env, jclass, jint compressorHandle)
+{
+ int32_t status = 0;
+ bool val = HAL_GetCompressor((HAL_CompressorHandle)compressorHandle, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: setCompressorClosedLoopControl
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_setCompressorClosedLoopControl
+ (JNIEnv* env, jclass, jint compressorHandle, jboolean value)
+{
+ int32_t status = 0;
+ HAL_SetCompressorClosedLoopControl((HAL_CompressorHandle)compressorHandle,
+ value, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: getCompressorClosedLoopControl
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_getCompressorClosedLoopControl
+ (JNIEnv* env, jclass, jint compressorHandle)
+{
+ int32_t status = 0;
+ bool val = HAL_GetCompressorClosedLoopControl(
+ (HAL_CompressorHandle)compressorHandle, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: getCompressorPressureSwitch
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_getCompressorPressureSwitch
+ (JNIEnv* env, jclass, jint compressorHandle)
+{
+ int32_t status = 0;
+ bool val = HAL_GetCompressorPressureSwitch(
+ (HAL_CompressorHandle)compressorHandle, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: getCompressorCurrent
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_getCompressorCurrent
+ (JNIEnv* env, jclass, jint compressorHandle)
+{
+ int32_t status = 0;
+ double val =
+ HAL_GetCompressorCurrent((HAL_CompressorHandle)compressorHandle, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: getCompressorCurrentTooHighFault
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_getCompressorCurrentTooHighFault
+ (JNIEnv* env, jclass, jint compressorHandle)
+{
+ int32_t status = 0;
+ bool val = HAL_GetCompressorCurrentTooHighFault(
+ (HAL_CompressorHandle)compressorHandle, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: getCompressorCurrentTooHighStickyFault
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_getCompressorCurrentTooHighStickyFault
+ (JNIEnv* env, jclass, jint compressorHandle)
+{
+ int32_t status = 0;
+ bool val = HAL_GetCompressorCurrentTooHighStickyFault(
+ (HAL_CompressorHandle)compressorHandle, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: getCompressorShortedStickyFault
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_getCompressorShortedStickyFault
+ (JNIEnv* env, jclass, jint compressorHandle)
+{
+ int32_t status = 0;
+ bool val = HAL_GetCompressorShortedStickyFault(
+ (HAL_CompressorHandle)compressorHandle, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: getCompressorShortedFault
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_getCompressorShortedFault
+ (JNIEnv* env, jclass, jint compressorHandle)
+{
+ int32_t status = 0;
+ bool val = HAL_GetCompressorShortedFault(
+ (HAL_CompressorHandle)compressorHandle, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: getCompressorNotConnectedStickyFault
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_getCompressorNotConnectedStickyFault
+ (JNIEnv* env, jclass, jint compressorHandle)
+{
+ int32_t status = 0;
+ bool val = HAL_GetCompressorNotConnectedStickyFault(
+ (HAL_CompressorHandle)compressorHandle, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: getCompressorNotConnectedFault
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_getCompressorNotConnectedFault
+ (JNIEnv* env, jclass, jint compressorHandle)
+{
+ int32_t status = 0;
+ bool val = HAL_GetCompressorNotConnectedFault(
+ (HAL_CompressorHandle)compressorHandle, &status);
+ CheckStatus(env, status);
+ return val;
+}
+/*
+ * Class: edu_wpi_first_hal_CompressorJNI
+ * Method: clearAllPCMStickyFaults
+ * Signature: (B)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CompressorJNI_clearAllPCMStickyFaults
+ (JNIEnv* env, jclass, jbyte module)
+{
+ int32_t status = 0;
+ HAL_ClearAllPCMStickyFaults(static_cast<int32_t>(module), &status);
+ CheckStatus(env, status);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/ConstantsJNI.cpp b/hal/src/main/native/cpp/jni/ConstantsJNI.cpp
new file mode 100644
index 0000000..3db8f5a
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/ConstantsJNI.cpp
@@ -0,0 +1,44 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_ConstantsJNI.h"
+#include "hal/Constants.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+
+// set the logging level
+TLogLevel constantsJNILogLevel = logWARNING;
+
+#define CONSTANTSJNI_LOG(level) \
+ if (level > constantsJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+/*
+ * Class: edu_wpi_first_hal_ConstantsJNI
+ * Method: getSystemClockTicksPerMicrosecond
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_ConstantsJNI_getSystemClockTicksPerMicrosecond
+ (JNIEnv* env, jclass)
+{
+ CONSTANTSJNI_LOG(logDEBUG)
+ << "Calling ConstantsJNI getSystemClockTicksPerMicrosecond";
+ jint value = HAL_GetSystemClockTicksPerMicrosecond();
+ CONSTANTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/CounterJNI.cpp b/hal/src/main/native/cpp/jni/CounterJNI.cpp
new file mode 100644
index 0000000..70ec5be
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/CounterJNI.cpp
@@ -0,0 +1,476 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_CounterJNI.h"
+#include "hal/Counter.h"
+#include "hal/Errors.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+
+// set the logging level
+TLogLevel counterJNILogLevel = logWARNING;
+
+#define COUNTERJNI_LOG(level) \
+ if (level > counterJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: initializeCounter
+ * Signature: (ILjava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_CounterJNI_initializeCounter
+ (JNIEnv* env, jclass, jint mode, jobject index)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI initializeCounter";
+ COUNTERJNI_LOG(logDEBUG) << "Mode = " << mode;
+ jint* indexPtr = reinterpret_cast<jint*>(env->GetDirectBufferAddress(index));
+ COUNTERJNI_LOG(logDEBUG) << "Index Ptr = "
+ << reinterpret_cast<int32_t*>(indexPtr);
+ int32_t status = 0;
+ auto counter = HAL_InitializeCounter(
+ (HAL_Counter_Mode)mode, reinterpret_cast<int32_t*>(indexPtr), &status);
+ COUNTERJNI_LOG(logDEBUG) << "Index = " << *indexPtr;
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ COUNTERJNI_LOG(logDEBUG) << "COUNTER Handle = " << counter;
+ CheckStatusForceThrow(env, status);
+ return (jint)counter;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: freeCounter
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_freeCounter
+ (JNIEnv* env, jclass, jint id)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI freeCounter";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ int32_t status = 0;
+ HAL_FreeCounter((HAL_CounterHandle)id, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterAverageSize
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterAverageSize
+ (JNIEnv* env, jclass, jint id, jint value)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterAverageSize";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ COUNTERJNI_LOG(logDEBUG) << "AverageSize = " << value;
+ int32_t status = 0;
+ HAL_SetCounterAverageSize((HAL_CounterHandle)id, value, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterUpSource
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterUpSource
+ (JNIEnv* env, jclass, jint id, jint digitalSourceHandle,
+ jint analogTriggerType)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterUpSource";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ COUNTERJNI_LOG(logDEBUG) << "digitalSourceHandle = " << digitalSourceHandle;
+ COUNTERJNI_LOG(logDEBUG) << "analogTriggerType = " << analogTriggerType;
+ int32_t status = 0;
+ HAL_SetCounterUpSource((HAL_CounterHandle)id, (HAL_Handle)digitalSourceHandle,
+ (HAL_AnalogTriggerType)analogTriggerType, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterUpSourceEdge
+ * Signature: (IZZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterUpSourceEdge
+ (JNIEnv* env, jclass, jint id, jboolean valueRise, jboolean valueFall)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterUpSourceEdge";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ COUNTERJNI_LOG(logDEBUG) << "Rise = " << (jint)valueRise;
+ COUNTERJNI_LOG(logDEBUG) << "Fall = " << (jint)valueFall;
+ int32_t status = 0;
+ HAL_SetCounterUpSourceEdge((HAL_CounterHandle)id, valueRise, valueFall,
+ &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: clearCounterUpSource
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_clearCounterUpSource
+ (JNIEnv* env, jclass, jint id)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI clearCounterUpSource";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ int32_t status = 0;
+ HAL_ClearCounterUpSource((HAL_CounterHandle)id, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterDownSource
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterDownSource
+ (JNIEnv* env, jclass, jint id, jint digitalSourceHandle,
+ jint analogTriggerType)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterDownSource";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ COUNTERJNI_LOG(logDEBUG) << "digitalSourceHandle = " << digitalSourceHandle;
+ COUNTERJNI_LOG(logDEBUG) << "analogTriggerType = " << analogTriggerType;
+ int32_t status = 0;
+ HAL_SetCounterDownSource((HAL_CounterHandle)id,
+ (HAL_Handle)digitalSourceHandle,
+ (HAL_AnalogTriggerType)analogTriggerType, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ if (status == PARAMETER_OUT_OF_RANGE) {
+ ThrowIllegalArgumentException(env,
+ "Counter only supports DownSource in "
+ "TwoPulse and ExternalDirection modes.");
+ return;
+ }
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterDownSourceEdge
+ * Signature: (IZZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterDownSourceEdge
+ (JNIEnv* env, jclass, jint id, jboolean valueRise, jboolean valueFall)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterDownSourceEdge";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ COUNTERJNI_LOG(logDEBUG) << "Rise = " << (jint)valueRise;
+ COUNTERJNI_LOG(logDEBUG) << "Fall = " << (jint)valueFall;
+ int32_t status = 0;
+ HAL_SetCounterDownSourceEdge((HAL_CounterHandle)id, valueRise, valueFall,
+ &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: clearCounterDownSource
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_clearCounterDownSource
+ (JNIEnv* env, jclass, jint id)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI clearCounterDownSource";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ int32_t status = 0;
+ HAL_ClearCounterDownSource((HAL_CounterHandle)id, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterUpDownMode
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterUpDownMode
+ (JNIEnv* env, jclass, jint id)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterUpDownMode";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ int32_t status = 0;
+ HAL_SetCounterUpDownMode((HAL_CounterHandle)id, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterExternalDirectionMode
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterExternalDirectionMode
+ (JNIEnv* env, jclass, jint id)
+{
+ COUNTERJNI_LOG(logDEBUG)
+ << "Calling COUNTERJNI setCounterExternalDirectionMode";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ int32_t status = 0;
+ HAL_SetCounterExternalDirectionMode((HAL_CounterHandle)id, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterSemiPeriodMode
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterSemiPeriodMode
+ (JNIEnv* env, jclass, jint id, jboolean value)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterSemiPeriodMode";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ COUNTERJNI_LOG(logDEBUG) << "SemiPeriodMode = " << (jint)value;
+ int32_t status = 0;
+ HAL_SetCounterSemiPeriodMode((HAL_CounterHandle)id, value, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterPulseLengthMode
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterPulseLengthMode
+ (JNIEnv* env, jclass, jint id, jdouble value)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterPulseLengthMode";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ COUNTERJNI_LOG(logDEBUG) << "PulseLengthMode = " << value;
+ int32_t status = 0;
+ HAL_SetCounterPulseLengthMode((HAL_CounterHandle)id, value, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: getCounterSamplesToAverage
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_CounterJNI_getCounterSamplesToAverage
+ (JNIEnv* env, jclass, jint id)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI getCounterSamplesToAverage";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ int32_t status = 0;
+ jint returnValue =
+ HAL_GetCounterSamplesToAverage((HAL_CounterHandle)id, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ COUNTERJNI_LOG(logDEBUG) << "getCounterSamplesToAverageResult = "
+ << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterSamplesToAverage
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterSamplesToAverage
+ (JNIEnv* env, jclass, jint id, jint value)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterSamplesToAverage";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ COUNTERJNI_LOG(logDEBUG) << "SamplesToAverage = " << value;
+ int32_t status = 0;
+ HAL_SetCounterSamplesToAverage((HAL_CounterHandle)id, value, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ if (status == PARAMETER_OUT_OF_RANGE) {
+ ThrowBoundaryException(env, value, 1, 127);
+ return;
+ }
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: resetCounter
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_resetCounter
+ (JNIEnv* env, jclass, jint id)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI resetCounter";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ int32_t status = 0;
+ HAL_ResetCounter((HAL_CounterHandle)id, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: getCounter
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_CounterJNI_getCounter
+ (JNIEnv* env, jclass, jint id)
+{
+ // COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI getCounter";
+ // COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ int32_t status = 0;
+ jint returnValue = HAL_GetCounter((HAL_CounterHandle)id, &status);
+ // COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ // COUNTERJNI_LOG(logDEBUG) << "getCounterResult = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: getCounterPeriod
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_CounterJNI_getCounterPeriod
+ (JNIEnv* env, jclass, jint id)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI getCounterPeriod";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ int32_t status = 0;
+ jdouble returnValue = HAL_GetCounterPeriod((HAL_CounterHandle)id, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ COUNTERJNI_LOG(logDEBUG) << "getCounterPeriodResult = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterMaxPeriod
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterMaxPeriod
+ (JNIEnv* env, jclass, jint id, jdouble value)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterMaxPeriod";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ COUNTERJNI_LOG(logDEBUG) << "MaxPeriod = " << value;
+ int32_t status = 0;
+ HAL_SetCounterMaxPeriod((HAL_CounterHandle)id, value, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterUpdateWhenEmpty
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterUpdateWhenEmpty
+ (JNIEnv* env, jclass, jint id, jboolean value)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterMaxPeriod";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ COUNTERJNI_LOG(logDEBUG) << "UpdateWhenEmpty = " << (jint)value;
+ int32_t status = 0;
+ HAL_SetCounterUpdateWhenEmpty((HAL_CounterHandle)id, value, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: getCounterStopped
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CounterJNI_getCounterStopped
+ (JNIEnv* env, jclass, jint id)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI getCounterStopped";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ int32_t status = 0;
+ jboolean returnValue = HAL_GetCounterStopped((HAL_CounterHandle)id, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ COUNTERJNI_LOG(logDEBUG) << "getCounterStoppedResult = " << (jint)returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: getCounterDirection
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_CounterJNI_getCounterDirection
+ (JNIEnv* env, jclass, jint id)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI getCounterDirection";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ int32_t status = 0;
+ jboolean returnValue =
+ HAL_GetCounterDirection((HAL_CounterHandle)id, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ COUNTERJNI_LOG(logDEBUG) << "getCounterDirectionResult = "
+ << (jint)returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_CounterJNI
+ * Method: setCounterReverseDirection
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_CounterJNI_setCounterReverseDirection
+ (JNIEnv* env, jclass, jint id, jboolean value)
+{
+ COUNTERJNI_LOG(logDEBUG) << "Calling COUNTERJNI setCounterReverseDirection";
+ COUNTERJNI_LOG(logDEBUG) << "Counter Handle = " << (HAL_CounterHandle)id;
+ COUNTERJNI_LOG(logDEBUG) << "ReverseDirection = " << (jint)value;
+ int32_t status = 0;
+ HAL_SetCounterReverseDirection((HAL_CounterHandle)id, value, &status);
+ COUNTERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/DIOJNI.cpp b/hal/src/main/native/cpp/jni/DIOJNI.cpp
new file mode 100644
index 0000000..e21edcf
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/DIOJNI.cpp
@@ -0,0 +1,319 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_DIOJNI.h"
+#include "hal/DIO.h"
+#include "hal/PWM.h"
+#include "hal/Ports.h"
+#include "hal/cpp/Log.h"
+#include "hal/handles/HandlesInternal.h"
+
+using namespace frc;
+
+// set the logging level
+TLogLevel dioJNILogLevel = logWARNING;
+
+#define DIOJNI_LOG(level) \
+ if (level > dioJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: initializeDIOPort
+ * Signature: (IZ)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DIOJNI_initializeDIOPort
+ (JNIEnv* env, jclass, jint id, jboolean input)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI initializeDIOPort";
+ DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id;
+ DIOJNI_LOG(logDEBUG) << "Input = " << (jint)input;
+ int32_t status = 0;
+ auto dio = HAL_InitializeDIOPort((HAL_PortHandle)id,
+ static_cast<uint8_t>(input), &status);
+ DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ DIOJNI_LOG(logDEBUG) << "DIO Handle = " << dio;
+ CheckStatusRange(env, status, 0, HAL_GetNumDigitalChannels(),
+ hal::getPortHandleChannel((HAL_PortHandle)id));
+ return (jint)dio;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: checkDIOChannel
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_DIOJNI_checkDIOChannel
+ (JNIEnv* env, jclass, jint channel)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI checkDIOChannel";
+ DIOJNI_LOG(logDEBUG) << "Channel = " << channel;
+ return HAL_CheckDIOChannel(channel);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: freeDIOPort
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DIOJNI_freeDIOPort
+ (JNIEnv* env, jclass, jint id)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI freeDIOPort";
+ DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
+ HAL_FreeDIOPort((HAL_DigitalHandle)id);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: setDIO
+ * Signature: (IS)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DIOJNI_setDIO
+ (JNIEnv* env, jclass, jint id, jshort value)
+{
+ // DIOJNI_LOG(logDEBUG) << "Calling DIOJNI setDIO";
+ // DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
+ // DIOJNI_LOG(logDEBUG) << "Value = " << value;
+ int32_t status = 0;
+ HAL_SetDIO((HAL_DigitalHandle)id, value, &status);
+ // DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: setDIODirection
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DIOJNI_setDIODirection
+ (JNIEnv* env, jclass, jint id, jboolean input)
+{
+ // DIOJNI_LOG(logDEBUG) << "Calling DIOJNI setDIO";
+ // DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
+ // DIOJNI_LOG(logDEBUG) << "IsInput = " << input;
+ int32_t status = 0;
+ HAL_SetDIODirection((HAL_DigitalHandle)id, input, &status);
+ // DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: getDIO
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_DIOJNI_getDIO
+ (JNIEnv* env, jclass, jint id)
+{
+ // DIOJNI_LOG(logDEBUG) << "Calling DIOJNI getDIO";
+ // DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ jboolean returnValue = HAL_GetDIO((HAL_DigitalHandle)id, &status);
+ // DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ // DIOJNI_LOG(logDEBUG) << "getDIOResult = " << (jint)returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: getDIODirection
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_DIOJNI_getDIODirection
+ (JNIEnv* env, jclass, jint id)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI getDIODirection (RR upd)";
+ // DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ jboolean returnValue = HAL_GetDIODirection((HAL_DigitalHandle)id, &status);
+ // DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ DIOJNI_LOG(logDEBUG) << "getDIODirectionResult = " << (jint)returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: pulse
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DIOJNI_pulse
+ (JNIEnv* env, jclass, jint id, jdouble value)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI pulse (RR upd)";
+ // DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
+ // DIOJNI_LOG(logDEBUG) << "Value = " << value;
+ int32_t status = 0;
+ HAL_Pulse((HAL_DigitalHandle)id, value, &status);
+ DIOJNI_LOG(logDEBUG) << "Did it work? Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: isPulsing
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_DIOJNI_isPulsing
+ (JNIEnv* env, jclass, jint id)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI isPulsing (RR upd)";
+ // DIOJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ jboolean returnValue = HAL_IsPulsing((HAL_DigitalHandle)id, &status);
+ // DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ DIOJNI_LOG(logDEBUG) << "isPulsingResult = " << (jint)returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: isAnyPulsing
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_DIOJNI_isAnyPulsing
+ (JNIEnv* env, jclass)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI isAnyPulsing (RR upd)";
+ int32_t status = 0;
+ jboolean returnValue = HAL_IsAnyPulsing(&status);
+ // DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ DIOJNI_LOG(logDEBUG) << "isAnyPulsingResult = " << (jint)returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: getLoopTiming
+ * Signature: ()S
+ */
+JNIEXPORT jshort JNICALL
+Java_edu_wpi_first_hal_DIOJNI_getLoopTiming
+ (JNIEnv* env, jclass)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI getLoopTimeing";
+ int32_t status = 0;
+ jshort returnValue = HAL_GetPWMLoopTiming(&status);
+ DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ DIOJNI_LOG(logDEBUG) << "LoopTiming = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: allocateDigitalPWM
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DIOJNI_allocateDigitalPWM
+ (JNIEnv* env, jclass)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI allocateDigitalPWM";
+ int32_t status = 0;
+ auto pwm = HAL_AllocateDigitalPWM(&status);
+ DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ DIOJNI_LOG(logDEBUG) << "PWM Handle = " << pwm;
+ CheckStatus(env, status);
+ return (jint)pwm;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: freeDigitalPWM
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DIOJNI_freeDigitalPWM
+ (JNIEnv* env, jclass, jint id)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI freeDigitalPWM";
+ DIOJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalPWMHandle)id;
+ int32_t status = 0;
+ HAL_FreeDigitalPWM((HAL_DigitalPWMHandle)id, &status);
+ DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: setDigitalPWMRate
+ * Signature: (D)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DIOJNI_setDigitalPWMRate
+ (JNIEnv* env, jclass, jdouble value)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI setDigitalPWMRate";
+ DIOJNI_LOG(logDEBUG) << "Rate= " << value;
+ int32_t status = 0;
+ HAL_SetDigitalPWMRate(value, &status);
+ DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: setDigitalPWMDutyCycle
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DIOJNI_setDigitalPWMDutyCycle
+ (JNIEnv* env, jclass, jint id, jdouble value)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI setDigitalPWMDutyCycle";
+ DIOJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalPWMHandle)id;
+ DIOJNI_LOG(logDEBUG) << "DutyCycle= " << value;
+ int32_t status = 0;
+ HAL_SetDigitalPWMDutyCycle((HAL_DigitalPWMHandle)id, value, &status);
+ DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DIOJNI
+ * Method: setDigitalPWMOutputChannel
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DIOJNI_setDigitalPWMOutputChannel
+ (JNIEnv* env, jclass, jint id, jint value)
+{
+ DIOJNI_LOG(logDEBUG) << "Calling DIOJNI setDigitalPWMOutputChannel";
+ DIOJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalPWMHandle)id;
+ DIOJNI_LOG(logDEBUG) << "Channel= " << value;
+ int32_t status = 0;
+ HAL_SetDigitalPWMOutputChannel((HAL_DigitalPWMHandle)id,
+ static_cast<uint32_t>(value), &status);
+ DIOJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/DigitalGlitchFilterJNI.cpp b/hal/src/main/native/cpp/jni/DigitalGlitchFilterJNI.cpp
new file mode 100644
index 0000000..3e39ac0
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/DigitalGlitchFilterJNI.cpp
@@ -0,0 +1,78 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_DigitalGlitchFilterJNI.h"
+#include "hal/DIO.h"
+
+using namespace frc;
+
+/*
+ * Class: edu_wpi_first_hal_DigitalGlitchFilterJNI
+ * Method: setFilterSelect
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DigitalGlitchFilterJNI_setFilterSelect
+ (JNIEnv* env, jclass, jint id, jint filter_index)
+{
+ int32_t status = 0;
+
+ HAL_SetFilterSelect(static_cast<HAL_DigitalHandle>(id), filter_index,
+ &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DigitalGlitchFilterJNI
+ * Method: getFilterSelect
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DigitalGlitchFilterJNI_getFilterSelect
+ (JNIEnv* env, jclass, jint id)
+{
+ int32_t status = 0;
+
+ jint result =
+ HAL_GetFilterSelect(static_cast<HAL_DigitalHandle>(id), &status);
+ CheckStatus(env, status);
+ return result;
+}
+
+/*
+ * Class: edu_wpi_first_hal_DigitalGlitchFilterJNI
+ * Method: setFilterPeriod
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_DigitalGlitchFilterJNI_setFilterPeriod
+ (JNIEnv* env, jclass, jint filter_index, jint fpga_cycles)
+{
+ int32_t status = 0;
+
+ HAL_SetFilterPeriod(filter_index, fpga_cycles, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_DigitalGlitchFilterJNI
+ * Method: getFilterPeriod
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_DigitalGlitchFilterJNI_getFilterPeriod
+ (JNIEnv* env, jclass, jint filter_index)
+{
+ int32_t status = 0;
+
+ jint result = HAL_GetFilterPeriod(filter_index, &status);
+ CheckStatus(env, status);
+ return result;
+}
diff --git a/hal/src/main/native/cpp/jni/EncoderJNI.cpp b/hal/src/main/native/cpp/jni/EncoderJNI.cpp
new file mode 100644
index 0000000..10c4332
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/EncoderJNI.cpp
@@ -0,0 +1,488 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_EncoderJNI.h"
+#include "hal/Encoder.h"
+#include "hal/Errors.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+
+// set the logging level
+TLogLevel encoderJNILogLevel = logWARNING;
+
+#define ENCODERJNI_LOG(level) \
+ if (level > encoderJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: initializeEncoder
+ * Signature: (IIIIZI)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_initializeEncoder
+ (JNIEnv* env, jclass, jint digitalSourceHandleA, jint analogTriggerTypeA,
+ jint digitalSourceHandleB, jint analogTriggerTypeB,
+ jboolean reverseDirection, jint encodingType)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI initializeEncoder";
+ ENCODERJNI_LOG(logDEBUG) << "Source Handle A = " << digitalSourceHandleA;
+ ENCODERJNI_LOG(logDEBUG) << "Analog Trigger Type A = " << analogTriggerTypeA;
+ ENCODERJNI_LOG(logDEBUG) << "Source Handle B = " << digitalSourceHandleB;
+ ENCODERJNI_LOG(logDEBUG) << "Analog Trigger Type B = " << analogTriggerTypeB;
+ ENCODERJNI_LOG(logDEBUG) << "Reverse direction = " << (jint)reverseDirection;
+ ENCODERJNI_LOG(logDEBUG) << "EncodingType = " << encodingType;
+ int32_t status = 0;
+ auto encoder = HAL_InitializeEncoder(
+ (HAL_Handle)digitalSourceHandleA,
+ (HAL_AnalogTriggerType)analogTriggerTypeA,
+ (HAL_Handle)digitalSourceHandleB,
+ (HAL_AnalogTriggerType)analogTriggerTypeB, reverseDirection,
+ (HAL_EncoderEncodingType)encodingType, &status);
+
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "ENCODER Handle = " << encoder;
+ CheckStatusForceThrow(env, status);
+ return (jint)encoder;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: freeEncoder
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_freeEncoder
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI freeEncoder";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ HAL_FreeEncoder((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoder
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoder
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoder";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jint returnValue = HAL_GetEncoder((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getEncoderResult = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoderRaw
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoderRaw
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderRaw";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jint returnValue = HAL_GetEncoderRaw((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getRawEncoderResult = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncodingScaleFactor
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncodingScaleFactor
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncodingScaleFactor";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jint returnValue =
+ HAL_GetEncoderEncodingScale((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getEncodingScaleFactorResult = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: resetEncoder
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_resetEncoder
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI resetEncoder";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ HAL_ResetEncoder((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoderPeriod
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoderPeriod
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderPeriod";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ double returnValue = HAL_GetEncoderPeriod((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getEncoderPeriodEncoderResult = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: setEncoderMaxPeriod
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_setEncoderMaxPeriod
+ (JNIEnv* env, jclass, jint id, jdouble value)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI setEncoderMaxPeriod";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ HAL_SetEncoderMaxPeriod((HAL_EncoderHandle)id, value, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoderStopped
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoderStopped
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderStopped";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jboolean returnValue = HAL_GetEncoderStopped((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getStoppedEncoderResult = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoderDirection
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoderDirection
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderDirection";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jboolean returnValue =
+ HAL_GetEncoderDirection((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getDirectionEncoderResult = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoderDistance
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoderDistance
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderDistance";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jdouble returnValue = HAL_GetEncoderDistance((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getDistanceEncoderResult = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoderRate
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoderRate
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderRate";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jdouble returnValue = HAL_GetEncoderRate((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getRateEncoderResult = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: setEncoderMinRate
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_setEncoderMinRate
+ (JNIEnv* env, jclass, jint id, jdouble value)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI setEncoderMinRate";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ HAL_SetEncoderMinRate((HAL_EncoderHandle)id, value, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: setEncoderDistancePerPulse
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_setEncoderDistancePerPulse
+ (JNIEnv* env, jclass, jint id, jdouble value)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI setEncoderDistancePerPulse";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ HAL_SetEncoderDistancePerPulse((HAL_EncoderHandle)id, value, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: setEncoderReverseDirection
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_setEncoderReverseDirection
+ (JNIEnv* env, jclass, jint id, jboolean value)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI setEncoderReverseDirection";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ HAL_SetEncoderReverseDirection((HAL_EncoderHandle)id, value, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: setEncoderSamplesToAverage
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_setEncoderSamplesToAverage
+ (JNIEnv* env, jclass, jint id, jint value)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI setEncoderSamplesToAverage";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ HAL_SetEncoderSamplesToAverage((HAL_EncoderHandle)id, value, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ if (status == PARAMETER_OUT_OF_RANGE) {
+ ThrowBoundaryException(env, value, 1, 127);
+ return;
+ }
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoderSamplesToAverage
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoderSamplesToAverage
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderSamplesToAverage";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jint returnValue =
+ HAL_GetEncoderSamplesToAverage((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getEncoderSamplesToAverageResult = "
+ << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: setEncoderIndexSource
+ * Signature: (IIII)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_setEncoderIndexSource
+ (JNIEnv* env, jclass, jint id, jint digitalSourceHandle,
+ jint analogTriggerType, jint type)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI setEncoderIndexSource";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ ENCODERJNI_LOG(logDEBUG) << "Source Handle = " << digitalSourceHandle;
+ ENCODERJNI_LOG(logDEBUG) << "Analog Trigger Type = " << analogTriggerType;
+ ENCODERJNI_LOG(logDEBUG) << "IndexingType = " << type;
+ int32_t status = 0;
+ HAL_SetEncoderIndexSource((HAL_EncoderHandle)id,
+ (HAL_Handle)digitalSourceHandle,
+ (HAL_AnalogTriggerType)analogTriggerType,
+ (HAL_EncoderIndexingType)type, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoderFPGAIndex
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoderFPGAIndex
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderSamplesToAverage";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jint returnValue = HAL_GetEncoderFPGAIndex((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getEncoderSamplesToAverageResult = "
+ << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoderEncodingScale
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoderEncodingScale
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderSamplesToAverage";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jint returnValue =
+ HAL_GetEncoderEncodingScale((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getEncoderSamplesToAverageResult = "
+ << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoderDecodingScaleFactor
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoderDecodingScaleFactor
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderSamplesToAverage";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jdouble returnValue =
+ HAL_GetEncoderDecodingScaleFactor((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getEncoderSamplesToAverageResult = "
+ << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoderDistancePerPulse
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoderDistancePerPulse
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderSamplesToAverage";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jdouble returnValue =
+ HAL_GetEncoderDistancePerPulse((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getEncoderSamplesToAverageResult = "
+ << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_EncoderJNI
+ * Method: getEncoderEncodingType
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_EncoderJNI_getEncoderEncodingType
+ (JNIEnv* env, jclass, jint id)
+{
+ ENCODERJNI_LOG(logDEBUG) << "Calling ENCODERJNI getEncoderSamplesToAverage";
+ ENCODERJNI_LOG(logDEBUG) << "Encoder Handle = " << (HAL_EncoderHandle)id;
+ int32_t status = 0;
+ jint returnValue = HAL_GetEncoderEncodingType((HAL_EncoderHandle)id, &status);
+ ENCODERJNI_LOG(logDEBUG) << "Status = " << status;
+ ENCODERJNI_LOG(logDEBUG) << "getEncoderSamplesToAverageResult = "
+ << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/HAL.cpp b/hal/src/main/native/cpp/jni/HAL.cpp
new file mode 100644
index 0000000..cc5f7cf
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/HAL.cpp
@@ -0,0 +1,482 @@
+/*----------------------------------------------------------------------------*/
+/* 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/HAL.h"
+
+#include <jni.h>
+
+#include <cassert>
+#include <cstring>
+
+#include <wpi/jni_util.h>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_HAL.h"
+#include "hal/DriverStation.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+using namespace wpi::java;
+
+// set the logging level
+static TLogLevel netCommLogLevel = logWARNING;
+
+#define NETCOMM_LOG(level) \
+ if (level > netCommLogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: initialize
+ * Signature: (II)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_HAL_initialize
+ (JNIEnv*, jclass, jint timeout, jint mode)
+{
+ return HAL_Initialize(timeout, mode);
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: observeUserProgramStarting
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_HAL_observeUserProgramStarting
+ (JNIEnv*, jclass)
+{
+ HAL_ObserveUserProgramStarting();
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: observeUserProgramDisabled
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_HAL_observeUserProgramDisabled
+ (JNIEnv*, jclass)
+{
+ HAL_ObserveUserProgramDisabled();
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: observeUserProgramAutonomous
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_HAL_observeUserProgramAutonomous
+ (JNIEnv*, jclass)
+{
+ HAL_ObserveUserProgramAutonomous();
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: observeUserProgramTeleop
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_HAL_observeUserProgramTeleop
+ (JNIEnv*, jclass)
+{
+ HAL_ObserveUserProgramTeleop();
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: observeUserProgramTest
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_HAL_observeUserProgramTest
+ (JNIEnv*, jclass)
+{
+ HAL_ObserveUserProgramTest();
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: report
+ * Signature: (IIILjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HAL_report
+ (JNIEnv* paramEnv, jclass, jint paramResource, jint paramInstanceNumber,
+ jint paramContext, jstring paramFeature)
+{
+ JStringRef featureStr{paramEnv, paramFeature};
+ NETCOMM_LOG(logDEBUG) << "Calling HAL report "
+ << "res:" << paramResource
+ << " instance:" << paramInstanceNumber
+ << " context:" << paramContext
+ << " feature:" << featureStr.c_str();
+ jint returnValue = HAL_Report(paramResource, paramInstanceNumber,
+ paramContext, featureStr.c_str());
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: nativeGetControlWord
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HAL_nativeGetControlWord
+ (JNIEnv*, jclass)
+{
+ NETCOMM_LOG(logDEBUG) << "Calling HAL Control Word";
+ static_assert(sizeof(HAL_ControlWord) == sizeof(jint),
+ "Java int must match the size of control word");
+ HAL_ControlWord controlWord;
+ std::memset(&controlWord, 0, sizeof(HAL_ControlWord));
+ HAL_GetControlWord(&controlWord);
+ jint retVal = 0;
+ std::memcpy(&retVal, &controlWord, sizeof(HAL_ControlWord));
+ return retVal;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: nativeGetAllianceStation
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HAL_nativeGetAllianceStation
+ (JNIEnv*, jclass)
+{
+ NETCOMM_LOG(logDEBUG) << "Calling HAL Alliance Station";
+ int32_t status = 0;
+ auto allianceStation = HAL_GetAllianceStation(&status);
+ return static_cast<jint>(allianceStation);
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getJoystickAxes
+ * Signature: (B[F)S
+ */
+JNIEXPORT jshort JNICALL
+Java_edu_wpi_first_hal_HAL_getJoystickAxes
+ (JNIEnv* env, jclass, jbyte joystickNum, jfloatArray axesArray)
+{
+ NETCOMM_LOG(logDEBUG) << "Calling HALJoystickAxes";
+ HAL_JoystickAxes axes;
+ HAL_GetJoystickAxes(joystickNum, &axes);
+
+ jsize javaSize = env->GetArrayLength(axesArray);
+ if (axes.count > javaSize) {
+ wpi::SmallString<128> errStr;
+ wpi::raw_svector_ostream oss{errStr};
+ oss << "Native array size larger then passed in java array size "
+ << "Native Size: " << static_cast<int>(axes.count)
+ << " Java Size: " << static_cast<int>(javaSize);
+
+ ThrowIllegalArgumentException(env, errStr.str());
+ return 0;
+ }
+
+ env->SetFloatArrayRegion(axesArray, 0, axes.count, axes.axes);
+
+ return axes.count;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getJoystickPOVs
+ * Signature: (B[S)S
+ */
+JNIEXPORT jshort JNICALL
+Java_edu_wpi_first_hal_HAL_getJoystickPOVs
+ (JNIEnv* env, jclass, jbyte joystickNum, jshortArray povsArray)
+{
+ NETCOMM_LOG(logDEBUG) << "Calling HALJoystickPOVs";
+ HAL_JoystickPOVs povs;
+ HAL_GetJoystickPOVs(joystickNum, &povs);
+
+ jsize javaSize = env->GetArrayLength(povsArray);
+ if (povs.count > javaSize) {
+ wpi::SmallString<128> errStr;
+ wpi::raw_svector_ostream oss{errStr};
+ oss << "Native array size larger then passed in java array size "
+ << "Native Size: " << static_cast<int>(povs.count)
+ << " Java Size: " << static_cast<int>(javaSize);
+
+ ThrowIllegalArgumentException(env, errStr.str());
+ return 0;
+ }
+
+ env->SetShortArrayRegion(povsArray, 0, povs.count, povs.povs);
+
+ return povs.count;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getJoystickButtons
+ * Signature: (BLjava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HAL_getJoystickButtons
+ (JNIEnv* env, jclass, jbyte joystickNum, jobject count)
+{
+ NETCOMM_LOG(logDEBUG) << "Calling HALJoystickButtons";
+ HAL_JoystickButtons joystickButtons;
+ HAL_GetJoystickButtons(joystickNum, &joystickButtons);
+ jbyte* countPtr =
+ reinterpret_cast<jbyte*>(env->GetDirectBufferAddress(count));
+ NETCOMM_LOG(logDEBUG) << "Buttons = " << joystickButtons.buttons;
+ NETCOMM_LOG(logDEBUG) << "Count = " << (jint)joystickButtons.count;
+ *countPtr = joystickButtons.count;
+ NETCOMM_LOG(logDEBUG) << "CountBuffer = " << (jint)*countPtr;
+ return joystickButtons.buttons;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: setJoystickOutputs
+ * Signature: (BISS)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HAL_setJoystickOutputs
+ (JNIEnv*, jclass, jbyte port, jint outputs, jshort leftRumble,
+ jshort rightRumble)
+{
+ NETCOMM_LOG(logDEBUG) << "Calling HAL_SetJoystickOutputs on port " << port;
+ NETCOMM_LOG(logDEBUG) << "Outputs: " << outputs;
+ NETCOMM_LOG(logDEBUG) << "Left Rumble: " << leftRumble
+ << " Right Rumble: " << rightRumble;
+ return HAL_SetJoystickOutputs(port, outputs, leftRumble, rightRumble);
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getJoystickIsXbox
+ * Signature: (B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HAL_getJoystickIsXbox
+ (JNIEnv*, jclass, jbyte port)
+{
+ NETCOMM_LOG(logDEBUG) << "Calling HAL_GetJoystickIsXbox";
+ return HAL_GetJoystickIsXbox(port);
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getJoystickType
+ * Signature: (B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HAL_getJoystickType
+ (JNIEnv*, jclass, jbyte port)
+{
+ NETCOMM_LOG(logDEBUG) << "Calling HAL_GetJoystickType";
+ return HAL_GetJoystickType(port);
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getJoystickName
+ * Signature: (B)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_hal_HAL_getJoystickName
+ (JNIEnv* env, jclass, jbyte port)
+{
+ NETCOMM_LOG(logDEBUG) << "Calling HAL_GetJoystickName";
+ char* joystickName = HAL_GetJoystickName(port);
+ jstring str = MakeJString(env, joystickName);
+ HAL_FreeJoystickName(joystickName);
+ return str;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getJoystickAxisType
+ * Signature: (BB)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HAL_getJoystickAxisType
+ (JNIEnv*, jclass, jbyte joystickNum, jbyte axis)
+{
+ NETCOMM_LOG(logDEBUG) << "Calling HAL_GetJoystickAxisType";
+ return HAL_GetJoystickAxisType(joystickNum, axis);
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: isNewControlData
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_HAL_isNewControlData
+ (JNIEnv*, jclass)
+{
+ return static_cast<jboolean>(HAL_IsNewControlData());
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: waitForDSData
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_HAL_waitForDSData
+ (JNIEnv* env, jclass)
+{
+ HAL_WaitForDSData();
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: releaseDSMutex
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_HAL_releaseDSMutex
+ (JNIEnv* env, jclass)
+{
+ HAL_ReleaseDSMutex();
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: waitForDSDataTimeout
+ * Signature: (D)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_HAL_waitForDSDataTimeout
+ (JNIEnv*, jclass, jdouble timeout)
+{
+ return static_cast<jboolean>(HAL_WaitForDSDataTimeout(timeout));
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getMatchTime
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_HAL_getMatchTime
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ return HAL_GetMatchTime(&status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getSystemActive
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_HAL_getSystemActive
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ bool val = HAL_GetSystemActive(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getBrownedOut
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_HAL_getBrownedOut
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ bool val = HAL_GetBrownedOut(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getMatchInfo
+ * Signature: (Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HAL_getMatchInfo
+ (JNIEnv* env, jclass, jobject info)
+{
+ HAL_MatchInfo matchInfo;
+ auto status = HAL_GetMatchInfo(&matchInfo);
+ if (status == 0) {
+ SetMatchInfoObject(env, info, matchInfo);
+ }
+ return status;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: sendError
+ * Signature: (ZIZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HAL_sendError
+ (JNIEnv* env, jclass, jboolean isError, jint errorCode, jboolean isLVCode,
+ jstring details, jstring location, jstring callStack, jboolean printMsg)
+{
+ JStringRef detailsStr{env, details};
+ JStringRef locationStr{env, location};
+ JStringRef callStackStr{env, callStack};
+
+ NETCOMM_LOG(logDEBUG) << "Send Error: " << detailsStr.c_str();
+ NETCOMM_LOG(logDEBUG) << "Location: " << locationStr.c_str();
+ NETCOMM_LOG(logDEBUG) << "Call Stack: " << callStackStr.c_str();
+ jint returnValue =
+ HAL_SendError(isError, errorCode, isLVCode, detailsStr.c_str(),
+ locationStr.c_str(), callStackStr.c_str(), printMsg);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getPortWithModule
+ * Signature: (BB)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HAL_getPortWithModule
+ (JNIEnv* env, jclass, jbyte module, jbyte channel)
+{
+ // FILE_LOG(logDEBUG) << "Calling HAL getPortWithModlue";
+ // FILE_LOG(logDEBUG) << "Module = " << (jint)module;
+ // FILE_LOG(logDEBUG) << "Channel = " << (jint)channel;
+ HAL_PortHandle port = HAL_GetPortWithModule(module, channel);
+ // FILE_LOG(logDEBUG) << "Port Handle = " << port;
+ return (jint)port;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HAL
+ * Method: getPort
+ * Signature: (B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HAL_getPort
+ (JNIEnv* env, jclass, jbyte channel)
+{
+ // FILE_LOG(logDEBUG) << "Calling HAL getPortWithModlue";
+ // FILE_LOG(logDEBUG) << "Module = " << (jint)module;
+ // FILE_LOG(logDEBUG) << "Channel = " << (jint)channel;
+ HAL_PortHandle port = HAL_GetPort(channel);
+ // FILE_LOG(logDEBUG) << "Port Handle = " << port;
+ return (jint)port;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/HALUtil.cpp b/hal/src/main/native/cpp/jni/HALUtil.cpp
new file mode 100644
index 0000000..72eb22c
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/HALUtil.cpp
@@ -0,0 +1,469 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HALUtil.h"
+
+#include <jni.h>
+
+#include <cassert>
+#include <cerrno>
+#include <cstdio>
+#include <cstring>
+#include <string>
+
+#include <wpi/SmallString.h>
+#include <wpi/jni_util.h>
+#include <wpi/raw_ostream.h>
+
+#include "edu_wpi_first_hal_HALUtil.h"
+#include "hal/CAN.h"
+#include "hal/DriverStation.h"
+#include "hal/Errors.h"
+#include "hal/HAL.h"
+#include "hal/cpp/Log.h"
+
+using namespace wpi::java;
+
+// set the logging level
+TLogLevel halUtilLogLevel = logWARNING;
+
+#define HALUTIL_LOG(level) \
+ if (level > halUtilLogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+#define kRioStatusOffset -63000
+#define kRioStatusSuccess 0
+#define kRIOStatusBufferInvalidSize (kRioStatusOffset - 80)
+#define kRIOStatusOperationTimedOut -52007
+#define kRIOStatusFeatureNotSupported (kRioStatusOffset - 193)
+#define kRIOStatusResourceNotInitialized -52010
+
+static JavaVM* jvm = nullptr;
+static JException illegalArgExCls;
+static JException boundaryExCls;
+static JException allocationExCls;
+static JException halHandleExCls;
+static JException canInvalidBufferExCls;
+static JException canMessageNotFoundExCls;
+static JException canMessageNotAllowedExCls;
+static JException canNotInitializedExCls;
+static JException uncleanStatusExCls;
+static JClass pwmConfigDataResultCls;
+static JClass canStatusCls;
+static JClass matchInfoDataCls;
+static JClass accumulatorResultCls;
+static JClass canDataCls;
+
+static const JClassInit classes[] = {
+ {"edu/wpi/first/hal/PWMConfigDataResult", &pwmConfigDataResultCls},
+ {"edu/wpi/first/hal/can/CANStatus", &canStatusCls},
+ {"edu/wpi/first/hal/MatchInfoData", &matchInfoDataCls},
+ {"edu/wpi/first/hal/AccumulatorResult", &accumulatorResultCls},
+ {"edu/wpi/first/hal/CANData", &canDataCls}};
+
+static const JExceptionInit exceptions[] = {
+ {"java/lang/IllegalArgumentException", &illegalArgExCls},
+ {"edu/wpi/first/hal/util/BoundaryException", &boundaryExCls},
+ {"edu/wpi/first/hal/util/AllocationException", &allocationExCls},
+ {"edu/wpi/first/hal/util/HalHandleException", &halHandleExCls},
+ {"edu/wpi/first/hal/can/CANInvalidBufferException", &canInvalidBufferExCls},
+ {"edu/wpi/first/hal/can/CANMessageNotFoundException",
+ &canMessageNotFoundExCls},
+ {"edu/wpi/first/hal/can/CANMessageNotAllowedException",
+ &canMessageNotAllowedExCls},
+ {"edu/wpi/first/hal/can/CANNotInitializedException",
+ &canNotInitializedExCls},
+ {"edu/wpi/first/hal/util/UncleanStatusException", &uncleanStatusExCls}};
+
+namespace frc {
+
+void ThrowUncleanStatusException(JNIEnv* env, wpi::StringRef msg,
+ int32_t status) {
+ static jmethodID func =
+ env->GetMethodID(uncleanStatusExCls, "<init>", "(ILjava/lang/String;)V");
+
+ jobject exception =
+ env->NewObject(uncleanStatusExCls, func, static_cast<jint>(status),
+ MakeJString(env, msg));
+ env->Throw(static_cast<jthrowable>(exception));
+}
+
+void ThrowAllocationException(JNIEnv* env, int32_t minRange, int32_t maxRange,
+ int32_t requestedValue, int32_t status) {
+ const char* message = HAL_GetErrorMessage(status);
+ wpi::SmallString<1024> buf;
+ wpi::raw_svector_ostream oss(buf);
+ oss << " Code: " << status << ". " << message
+ << ", Minimum Value: " << minRange << ", Maximum Value: " << maxRange
+ << ", Requested Value: " << requestedValue;
+ env->ThrowNew(allocationExCls, buf.c_str());
+ allocationExCls.Throw(env, buf.c_str());
+}
+
+void ThrowHalHandleException(JNIEnv* env, int32_t status) {
+ const char* message = HAL_GetErrorMessage(status);
+ wpi::SmallString<1024> buf;
+ wpi::raw_svector_ostream oss(buf);
+ oss << " Code: " << status << ". " << message;
+ halHandleExCls.Throw(env, buf.c_str());
+}
+
+void ReportError(JNIEnv* env, int32_t status, bool doThrow) {
+ if (status == 0) return;
+ if (status == HAL_HANDLE_ERROR) {
+ ThrowHalHandleException(env, status);
+ }
+ const char* message = HAL_GetErrorMessage(status);
+ if (doThrow && status < 0) {
+ wpi::SmallString<1024> buf;
+ wpi::raw_svector_ostream oss(buf);
+ oss << " Code: " << status << ". " << message;
+ ThrowUncleanStatusException(env, buf.c_str(), status);
+ } else {
+ std::string func;
+ auto stack = GetJavaStackTrace(env, &func, "edu.wpi.first.wpilibj");
+ HAL_SendError(1, status, 0, message, func.c_str(), stack.c_str(), 1);
+ }
+}
+
+void ThrowError(JNIEnv* env, int32_t status, int32_t minRange, int32_t maxRange,
+ int32_t requestedValue) {
+ if (status == 0) return;
+ if (status == NO_AVAILABLE_RESOURCES || status == RESOURCE_IS_ALLOCATED ||
+ status == RESOURCE_OUT_OF_RANGE) {
+ ThrowAllocationException(env, minRange, maxRange, requestedValue, status);
+ }
+ if (status == HAL_HANDLE_ERROR) {
+ ThrowHalHandleException(env, status);
+ }
+ const char* message = HAL_GetErrorMessage(status);
+ wpi::SmallString<1024> buf;
+ wpi::raw_svector_ostream oss(buf);
+ oss << " Code: " << status << ". " << message;
+ ThrowUncleanStatusException(env, buf.c_str(), status);
+}
+
+void ReportCANError(JNIEnv* env, int32_t status, int message_id) {
+ if (status >= 0) return;
+ switch (status) {
+ case kRioStatusSuccess:
+ // Everything is ok... don't throw.
+ break;
+ case HAL_ERR_CANSessionMux_InvalidBuffer:
+ case kRIOStatusBufferInvalidSize: {
+ static jmethodID invalidBufConstruct = nullptr;
+ if (!invalidBufConstruct)
+ invalidBufConstruct =
+ env->GetMethodID(canInvalidBufferExCls, "<init>", "()V");
+ jobject exception =
+ env->NewObject(canInvalidBufferExCls, invalidBufConstruct);
+ env->Throw(static_cast<jthrowable>(exception));
+ break;
+ }
+ case HAL_ERR_CANSessionMux_MessageNotFound:
+ case kRIOStatusOperationTimedOut: {
+ static jmethodID messageNotFoundConstruct = nullptr;
+ if (!messageNotFoundConstruct)
+ messageNotFoundConstruct =
+ env->GetMethodID(canMessageNotFoundExCls, "<init>", "()V");
+ jobject exception =
+ env->NewObject(canMessageNotFoundExCls, messageNotFoundConstruct);
+ env->Throw(static_cast<jthrowable>(exception));
+ break;
+ }
+ case HAL_ERR_CANSessionMux_NotAllowed:
+ case kRIOStatusFeatureNotSupported: {
+ wpi::SmallString<100> buf;
+ wpi::raw_svector_ostream oss(buf);
+ oss << "MessageID = " << message_id;
+ canMessageNotAllowedExCls.Throw(env, buf.c_str());
+ break;
+ }
+ case HAL_ERR_CANSessionMux_NotInitialized:
+ case kRIOStatusResourceNotInitialized: {
+ static jmethodID notInitConstruct = nullptr;
+ if (!notInitConstruct)
+ notInitConstruct =
+ env->GetMethodID(canNotInitializedExCls, "<init>", "()V");
+ jobject exception =
+ env->NewObject(canNotInitializedExCls, notInitConstruct);
+ env->Throw(static_cast<jthrowable>(exception));
+ break;
+ }
+ default: {
+ wpi::SmallString<100> buf;
+ wpi::raw_svector_ostream oss(buf);
+ oss << "Fatal status code detected: " << status;
+ uncleanStatusExCls.Throw(env, buf.c_str());
+ break;
+ }
+ }
+}
+
+void ThrowIllegalArgumentException(JNIEnv* env, wpi::StringRef msg) {
+ illegalArgExCls.Throw(env, msg);
+}
+
+void ThrowBoundaryException(JNIEnv* env, double value, double lower,
+ double upper) {
+ static jmethodID getMessage = nullptr;
+ if (!getMessage)
+ getMessage = env->GetStaticMethodID(boundaryExCls, "getMessage",
+ "(DDD)Ljava/lang/String;");
+
+ static jmethodID constructor = nullptr;
+ if (!constructor)
+ constructor =
+ env->GetMethodID(boundaryExCls, "<init>", "(Ljava/lang/String;)V");
+
+ jobject msg = env->CallStaticObjectMethod(
+ boundaryExCls, getMessage, static_cast<jdouble>(value),
+ static_cast<jdouble>(lower), static_cast<jdouble>(upper));
+ jobject ex = env->NewObject(boundaryExCls, constructor, msg);
+ env->Throw(static_cast<jthrowable>(ex));
+}
+
+jobject CreatePWMConfigDataResult(JNIEnv* env, int32_t maxPwm,
+ int32_t deadbandMaxPwm, int32_t centerPwm,
+ int32_t deadbandMinPwm, int32_t minPwm) {
+ static jmethodID constructor =
+ env->GetMethodID(pwmConfigDataResultCls, "<init>", "(IIIII)V");
+ return env->NewObject(pwmConfigDataResultCls, constructor, maxPwm,
+ deadbandMaxPwm, centerPwm, deadbandMinPwm, minPwm);
+}
+
+void SetCanStatusObject(JNIEnv* env, jobject canStatus,
+ float percentBusUtilization, uint32_t busOffCount,
+ uint32_t txFullCount, uint32_t receiveErrorCount,
+ uint32_t transmitErrorCount) {
+ static jmethodID func =
+ env->GetMethodID(canStatusCls, "setStatus", "(DIIII)V");
+ env->CallVoidMethod(canStatus, func, (jdouble)percentBusUtilization,
+ (jint)busOffCount, (jint)txFullCount,
+ (jint)receiveErrorCount, (jint)transmitErrorCount);
+}
+
+void SetMatchInfoObject(JNIEnv* env, jobject matchStatus,
+ const HAL_MatchInfo& matchInfo) {
+ static jmethodID func =
+ env->GetMethodID(matchInfoDataCls, "setData",
+ "(Ljava/lang/String;Ljava/lang/String;III)V");
+
+ env->CallVoidMethod(
+ matchStatus, func, MakeJString(env, matchInfo.eventName),
+ MakeJString(env, wpi::StringRef{reinterpret_cast<const char*>(
+ matchInfo.gameSpecificMessage),
+ matchInfo.gameSpecificMessageSize}),
+ (jint)matchInfo.matchNumber, (jint)matchInfo.replayNumber,
+ (jint)matchInfo.matchType);
+}
+
+void SetAccumulatorResultObject(JNIEnv* env, jobject accumulatorResult,
+ int64_t value, int64_t count) {
+ static jmethodID func =
+ env->GetMethodID(accumulatorResultCls, "set", "(JJ)V");
+
+ env->CallVoidMethod(accumulatorResult, func, (jlong)value, (jlong)count);
+}
+
+jbyteArray SetCANDataObject(JNIEnv* env, jobject canData, int32_t length,
+ uint64_t timestamp) {
+ static jmethodID func = env->GetMethodID(canDataCls, "setData", "(IJ)[B");
+
+ jbyteArray retVal = static_cast<jbyteArray>(
+ env->CallObjectMethod(canData, func, (jint)length, (jlong)timestamp));
+ return retVal;
+}
+
+JavaVM* GetJVM() { return jvm; }
+
+} // namespace frc
+
+namespace sim {
+jint SimOnLoad(JavaVM* vm, void* reserved);
+void SimOnUnload(JavaVM* vm, void* reserved);
+} // namespace sim
+
+using namespace frc;
+
+extern "C" {
+
+//
+// indicate JNI version support desired and load classes
+//
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
+ jvm = vm;
+
+ // set our logging level
+ Log::ReportingLevel() = logDEBUG;
+
+ JNIEnv* env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
+ return JNI_ERR;
+
+ for (auto& c : classes) {
+ *c.cls = JClass(env, c.name);
+ if (!*c.cls) return JNI_ERR;
+ }
+
+ for (auto& c : exceptions) {
+ *c.cls = JException(env, c.name);
+ if (!*c.cls) return JNI_ERR;
+ }
+
+ return sim::SimOnLoad(vm, reserved);
+}
+
+JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) {
+ sim::SimOnUnload(vm, reserved);
+
+ JNIEnv* env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
+ return;
+ // Delete global references
+
+ for (auto& c : classes) {
+ c.cls->free(env);
+ }
+ for (auto& c : exceptions) {
+ c.cls->free(env);
+ }
+ jvm = nullptr;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HALUtil
+ * Method: getFPGAVersion
+ * Signature: ()S
+ */
+JNIEXPORT jshort JNICALL
+Java_edu_wpi_first_hal_HALUtil_getFPGAVersion
+ (JNIEnv* env, jclass)
+{
+ HALUTIL_LOG(logDEBUG) << "Calling HALUtil getFPGAVersion";
+ int32_t status = 0;
+ jshort returnValue = HAL_GetFPGAVersion(&status);
+ HALUTIL_LOG(logDEBUG) << "Status = " << status;
+ HALUTIL_LOG(logDEBUG) << "FPGAVersion = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HALUtil
+ * Method: getFPGARevision
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HALUtil_getFPGARevision
+ (JNIEnv* env, jclass)
+{
+ HALUTIL_LOG(logDEBUG) << "Calling HALUtil getFPGARevision";
+ int32_t status = 0;
+ jint returnValue = HAL_GetFPGARevision(&status);
+ HALUTIL_LOG(logDEBUG) << "Status = " << status;
+ HALUTIL_LOG(logDEBUG) << "FPGARevision = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HALUtil
+ * Method: getFPGATime
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL
+Java_edu_wpi_first_hal_HALUtil_getFPGATime
+ (JNIEnv* env, jclass)
+{
+ // HALUTIL_LOG(logDEBUG) << "Calling HALUtil getFPGATime";
+ int32_t status = 0;
+ jlong returnValue = HAL_GetFPGATime(&status);
+ // HALUTIL_LOG(logDEBUG) << "Status = " << status;
+ // HALUTIL_LOG(logDEBUG) << "FPGATime = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HALUtil
+ * Method: getHALRuntimeType
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HALUtil_getHALRuntimeType
+ (JNIEnv* env, jclass)
+{
+ // HALUTIL_LOG(logDEBUG) << "Calling HALUtil getHALRuntimeType";
+ jint returnValue = HAL_GetRuntimeType();
+ // HALUTIL_LOG(logDEBUG) << "RuntimeType = " << returnValue;
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HALUtil
+ * Method: getFPGAButton
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_HALUtil_getFPGAButton
+ (JNIEnv* env, jclass)
+{
+ // HALUTIL_LOG(logDEBUG) << "Calling HALUtil getFPGATime";
+ int32_t status = 0;
+ jboolean returnValue = HAL_GetFPGAButton(&status);
+ // HALUTIL_LOG(logDEBUG) << "Status = " << status;
+ // HALUTIL_LOG(logDEBUG) << "FPGATime = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HALUtil
+ * Method: getHALErrorMessage
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_hal_HALUtil_getHALErrorMessage
+ (JNIEnv* paramEnv, jclass, jint paramId)
+{
+ const char* msg = HAL_GetErrorMessage(paramId);
+ HALUTIL_LOG(logDEBUG) << "Calling HALUtil HAL_GetErrorMessage id=" << paramId
+ << " msg=" << msg;
+ return MakeJString(paramEnv, msg);
+}
+
+/*
+ * Class: edu_wpi_first_hal_HALUtil
+ * Method: getHALErrno
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_HALUtil_getHALErrno
+ (JNIEnv*, jclass)
+{
+ return errno;
+}
+
+/*
+ * Class: edu_wpi_first_hal_HALUtil
+ * Method: getHALstrerror
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_edu_wpi_first_hal_HALUtil_getHALstrerror
+ (JNIEnv* env, jclass, jint errorCode)
+{
+ const char* msg = std::strerror(errno);
+ HALUTIL_LOG(logDEBUG) << "Calling HALUtil getHALstrerror errorCode="
+ << errorCode << " msg=" << msg;
+ return MakeJString(env, msg);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/HALUtil.h b/hal/src/main/native/cpp/jni/HALUtil.h
new file mode 100644
index 0000000..8197e1a
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/HALUtil.h
@@ -0,0 +1,74 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+#ifndef HAL_HAL_SRC_MAIN_NATIVE_CPP_JNI_HALUTIL_H_
+#define HAL_HAL_SRC_MAIN_NATIVE_CPP_JNI_HALUTIL_H_
+
+#include <jni.h>
+#include <stdint.h>
+
+#include <wpi/StringRef.h>
+
+struct HAL_MatchInfo;
+
+namespace frc {
+
+void ReportError(JNIEnv* env, int32_t status, bool doThrow = true);
+
+void ThrowError(JNIEnv* env, int32_t status, int32_t minRange, int32_t maxRange,
+ int32_t requestedValue);
+
+inline bool CheckStatus(JNIEnv* env, int32_t status, bool doThrow = true) {
+ if (status != 0) ReportError(env, status, doThrow);
+ return status == 0;
+}
+
+inline bool CheckStatusRange(JNIEnv* env, int32_t status, int32_t minRange,
+ int32_t maxRange, int32_t requestedValue) {
+ if (status != 0) ThrowError(env, status, minRange, maxRange, requestedValue);
+ return status == 0;
+}
+
+inline bool CheckStatusForceThrow(JNIEnv* env, int32_t status) {
+ if (status != 0) ThrowError(env, status, 0, 0, 0);
+ return status == 0;
+}
+
+void ReportCANError(JNIEnv* env, int32_t status, int32_t message_id);
+
+inline bool CheckCANStatus(JNIEnv* env, int32_t status, int32_t message_id) {
+ if (status != 0) ReportCANError(env, status, message_id);
+ return status == 0;
+}
+
+void ThrowIllegalArgumentException(JNIEnv* env, wpi::StringRef msg);
+void ThrowBoundaryException(JNIEnv* env, double value, double lower,
+ double upper);
+
+jobject CreatePWMConfigDataResult(JNIEnv* env, int32_t maxPwm,
+ int32_t deadbandMaxPwm, int32_t centerPwm,
+ int32_t deadbandMinPwm, int32_t minPwm);
+
+void SetCanStatusObject(JNIEnv* env, jobject canStatus,
+ float percentBusUtilization, uint32_t busOffCount,
+ uint32_t txFullCount, uint32_t receiveErrorCount,
+ uint32_t transmitErrorCount);
+
+void SetMatchInfoObject(JNIEnv* env, jobject matchStatus,
+ const HAL_MatchInfo& matchInfo);
+
+void SetAccumulatorResultObject(JNIEnv* env, jobject accumulatorResult,
+ int64_t value, int64_t count);
+
+jbyteArray SetCANDataObject(JNIEnv* env, jobject canData, int32_t length,
+ uint64_t timestamp);
+
+JavaVM* GetJVM();
+
+} // namespace frc
+
+#endif // HAL_HAL_SRC_MAIN_NATIVE_CPP_JNI_HALUTIL_H_
diff --git a/hal/src/main/native/cpp/jni/I2CJNI.cpp b/hal/src/main/native/cpp/jni/I2CJNI.cpp
new file mode 100644
index 0000000..9dafd4a
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/I2CJNI.cpp
@@ -0,0 +1,221 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include <wpi/jni_util.h>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_I2CJNI.h"
+#include "hal/I2C.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+using namespace wpi::java;
+
+// set the logging level
+TLogLevel i2cJNILogLevel = logWARNING;
+
+#define I2CJNI_LOG(level) \
+ if (level > i2cJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_I2CJNI
+ * Method: i2CInitialize
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_I2CJNI_i2CInitialize
+ (JNIEnv* env, jclass, jint port)
+{
+ I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CInititalize";
+ I2CJNI_LOG(logDEBUG) << "Port: " << port;
+ int32_t status = 0;
+ HAL_InitializeI2C(static_cast<HAL_I2CPort>(port), &status);
+ I2CJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatusForceThrow(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_I2CJNI
+ * Method: i2CTransaction
+ * Signature: (IBLjava/lang/Object;BLjava/lang/Object;B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_I2CJNI_i2CTransaction
+ (JNIEnv* env, jclass, jint port, jbyte address, jobject dataToSend,
+ jbyte sendSize, jobject dataReceived, jbyte receiveSize)
+{
+ I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CTransaction";
+ I2CJNI_LOG(logDEBUG) << "Port = " << port;
+ I2CJNI_LOG(logDEBUG) << "Address = " << (jint)address;
+ uint8_t* dataToSendPtr = nullptr;
+ if (dataToSend != 0) {
+ dataToSendPtr =
+ reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataToSend));
+ }
+ I2CJNI_LOG(logDEBUG) << "DataToSendPtr = "
+ << reinterpret_cast<jint*>(dataToSendPtr);
+ I2CJNI_LOG(logDEBUG) << "SendSize = " << (jint)sendSize;
+ uint8_t* dataReceivedPtr =
+ reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataReceived));
+ I2CJNI_LOG(logDEBUG) << "DataReceivedPtr = "
+ << reinterpret_cast<jint*>(dataReceivedPtr);
+ I2CJNI_LOG(logDEBUG) << "ReceiveSize = " << (jint)receiveSize;
+ jint returnValue =
+ HAL_TransactionI2C(static_cast<HAL_I2CPort>(port), address, dataToSendPtr,
+ sendSize, dataReceivedPtr, receiveSize);
+ I2CJNI_LOG(logDEBUG) << "ReturnValue = " << returnValue;
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_I2CJNI
+ * Method: i2CTransactionB
+ * Signature: (IB[BB[BB)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_I2CJNI_i2CTransactionB
+ (JNIEnv* env, jclass, jint port, jbyte address, jbyteArray dataToSend,
+ jbyte sendSize, jbyteArray dataReceived, jbyte receiveSize)
+{
+ I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CTransactionB";
+ I2CJNI_LOG(logDEBUG) << "Port = " << port;
+ I2CJNI_LOG(logDEBUG) << "Address = " << (jint)address;
+ I2CJNI_LOG(logDEBUG) << "SendSize = " << (jint)sendSize;
+ wpi::SmallVector<uint8_t, 128> recvBuf;
+ recvBuf.resize(receiveSize);
+ I2CJNI_LOG(logDEBUG) << "ReceiveSize = " << (jint)receiveSize;
+ jint returnValue =
+ HAL_TransactionI2C(static_cast<HAL_I2CPort>(port), address,
+ reinterpret_cast<const uint8_t*>(
+ JByteArrayRef(env, dataToSend).array().data()),
+ sendSize, recvBuf.data(), receiveSize);
+ env->SetByteArrayRegion(dataReceived, 0, receiveSize,
+ reinterpret_cast<const jbyte*>(recvBuf.data()));
+ I2CJNI_LOG(logDEBUG) << "ReturnValue = " << returnValue;
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_I2CJNI
+ * Method: i2CWrite
+ * Signature: (IBLjava/lang/Object;B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_I2CJNI_i2CWrite
+ (JNIEnv* env, jclass, jint port, jbyte address, jobject dataToSend,
+ jbyte sendSize)
+{
+ I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CWrite";
+ I2CJNI_LOG(logDEBUG) << "Port = " << port;
+ I2CJNI_LOG(logDEBUG) << "Address = " << (jint)address;
+ uint8_t* dataToSendPtr = nullptr;
+
+ if (dataToSend != 0) {
+ dataToSendPtr =
+ reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataToSend));
+ }
+ I2CJNI_LOG(logDEBUG) << "DataToSendPtr = " << dataToSendPtr;
+ I2CJNI_LOG(logDEBUG) << "SendSize = " << (jint)sendSize;
+ jint returnValue = HAL_WriteI2C(static_cast<HAL_I2CPort>(port), address,
+ dataToSendPtr, sendSize);
+ I2CJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)returnValue;
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_I2CJNI
+ * Method: i2CWriteB
+ * Signature: (IB[BB)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_I2CJNI_i2CWriteB
+ (JNIEnv* env, jclass, jint port, jbyte address, jbyteArray dataToSend,
+ jbyte sendSize)
+{
+ I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CWrite";
+ I2CJNI_LOG(logDEBUG) << "Port = " << port;
+ I2CJNI_LOG(logDEBUG) << "Address = " << (jint)address;
+ I2CJNI_LOG(logDEBUG) << "SendSize = " << (jint)sendSize;
+ jint returnValue =
+ HAL_WriteI2C(static_cast<HAL_I2CPort>(port), address,
+ reinterpret_cast<const uint8_t*>(
+ JByteArrayRef(env, dataToSend).array().data()),
+ sendSize);
+ I2CJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)returnValue;
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_I2CJNI
+ * Method: i2CRead
+ * Signature: (IBLjava/lang/Object;B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_I2CJNI_i2CRead
+ (JNIEnv* env, jclass, jint port, jbyte address, jobject dataReceived,
+ jbyte receiveSize)
+{
+ I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CRead";
+ I2CJNI_LOG(logDEBUG) << "Port = " << port;
+ I2CJNI_LOG(logDEBUG) << "Address = " << address;
+ uint8_t* dataReceivedPtr =
+ reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataReceived));
+ I2CJNI_LOG(logDEBUG) << "DataReceivedPtr = " << dataReceivedPtr;
+ I2CJNI_LOG(logDEBUG) << "ReceiveSize = " << receiveSize;
+ jint returnValue = HAL_ReadI2C(static_cast<HAL_I2CPort>(port), address,
+ dataReceivedPtr, receiveSize);
+ I2CJNI_LOG(logDEBUG) << "ReturnValue = " << returnValue;
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_I2CJNI
+ * Method: i2CReadB
+ * Signature: (IB[BB)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_I2CJNI_i2CReadB
+ (JNIEnv* env, jclass, jint port, jbyte address, jbyteArray dataReceived,
+ jbyte receiveSize)
+{
+ I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CRead";
+ I2CJNI_LOG(logDEBUG) << "Port = " << port;
+ I2CJNI_LOG(logDEBUG) << "Address = " << address;
+ I2CJNI_LOG(logDEBUG) << "ReceiveSize = " << receiveSize;
+ wpi::SmallVector<uint8_t, 128> recvBuf;
+ recvBuf.resize(receiveSize);
+ jint returnValue = HAL_ReadI2C(static_cast<HAL_I2CPort>(port), address,
+ recvBuf.data(), receiveSize);
+ env->SetByteArrayRegion(dataReceived, 0, receiveSize,
+ reinterpret_cast<const jbyte*>(recvBuf.data()));
+ I2CJNI_LOG(logDEBUG) << "ReturnValue = " << returnValue;
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_I2CJNI
+ * Method: i2CClose
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_I2CJNI_i2CClose
+ (JNIEnv*, jclass, jint port)
+{
+ I2CJNI_LOG(logDEBUG) << "Calling I2CJNI i2CClose";
+ HAL_CloseI2C(static_cast<HAL_I2CPort>(port));
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/InterruptJNI.cpp b/hal/src/main/native/cpp/jni/InterruptJNI.cpp
new file mode 100644
index 0000000..2dd4abf
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/InterruptJNI.cpp
@@ -0,0 +1,375 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <atomic>
+#include <cassert>
+#include <thread>
+
+#include <wpi/SafeThread.h>
+#include <wpi/mutex.h>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_InterruptJNI.h"
+#include "hal/Interrupts.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+
+TLogLevel interruptJNILogLevel = logERROR;
+
+#define INTERRUPTJNI_LOG(level) \
+ if (level > interruptJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+// Thread where callbacks are actually performed.
+//
+// JNI's AttachCurrentThread() creates a Java Thread object on every
+// invocation, which is both time inefficient and causes issues with Eclipse
+// (which tries to keep a thread list up-to-date and thus gets swamped).
+//
+// Instead, this class attaches just once. When a hardware notification
+// occurs, a condition variable wakes up this thread and this thread actually
+// makes the call into Java.
+//
+// We don't want to use a FIFO here. If the user code takes too long to
+// process, we will just ignore the redundant wakeup.
+class InterruptThreadJNI : public wpi::SafeThread {
+ public:
+ void Main();
+
+ bool m_notify = false;
+ uint32_t m_mask = 0;
+ jobject m_func = nullptr;
+ jmethodID m_mid;
+ jobject m_param = nullptr;
+};
+
+class InterruptJNI : public wpi::SafeThreadOwner<InterruptThreadJNI> {
+ public:
+ void SetFunc(JNIEnv* env, jobject func, jmethodID mid, jobject param);
+
+ void Notify(uint32_t mask) {
+ auto thr = GetThread();
+ if (!thr) return;
+ thr->m_notify = true;
+ thr->m_mask = mask;
+ thr->m_cond.notify_one();
+ }
+};
+
+void InterruptJNI::SetFunc(JNIEnv* env, jobject func, jmethodID mid,
+ jobject param) {
+ auto thr = GetThread();
+ if (!thr) return;
+ // free global references
+ if (thr->m_func) env->DeleteGlobalRef(thr->m_func);
+ if (thr->m_param) env->DeleteGlobalRef(thr->m_param);
+ // create global references
+ thr->m_func = env->NewGlobalRef(func);
+ thr->m_param = param ? env->NewGlobalRef(param) : nullptr;
+ thr->m_mid = mid;
+}
+
+void InterruptThreadJNI::Main() {
+ JNIEnv* env;
+ JavaVMAttachArgs args;
+ args.version = JNI_VERSION_1_2;
+ args.name = const_cast<char*>("Interrupt");
+ args.group = nullptr;
+ jint rs = GetJVM()->AttachCurrentThreadAsDaemon(
+ reinterpret_cast<void**>(&env), &args);
+ if (rs != JNI_OK) return;
+
+ std::unique_lock<wpi::mutex> lock(m_mutex);
+ while (m_active) {
+ m_cond.wait(lock, [&] { return !m_active || m_notify; });
+ if (!m_active) break;
+ m_notify = false;
+ if (!m_func) continue;
+ jobject func = m_func;
+ jmethodID mid = m_mid;
+ uint32_t mask = m_mask;
+ jobject param = m_param;
+ lock.unlock(); // don't hold mutex during callback execution
+ env->CallVoidMethod(func, mid, static_cast<jint>(mask), param);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ lock.lock();
+ }
+
+ // free global references
+ if (m_func) env->DeleteGlobalRef(m_func);
+ if (m_param) env->DeleteGlobalRef(m_param);
+
+ GetJVM()->DetachCurrentThread();
+}
+
+void interruptHandler(uint32_t mask, void* param) {
+ static_cast<InterruptJNI*>(param)->Notify(mask);
+}
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_InterruptJNI
+ * Method: initializeInterrupts
+ * Signature: (Z)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_InterruptJNI_initializeInterrupts
+ (JNIEnv* env, jclass, jboolean watcher)
+{
+ INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI initializeInterrupts";
+ INTERRUPTJNI_LOG(logDEBUG) << "watcher = " << static_cast<bool>(watcher);
+
+ int32_t status = 0;
+ HAL_InterruptHandle interrupt = HAL_InitializeInterrupts(watcher, &status);
+
+ INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Handle = " << interrupt;
+ INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
+
+ CheckStatusForceThrow(env, status);
+ return (jint)interrupt;
+}
+
+/*
+ * Class: edu_wpi_first_hal_InterruptJNI
+ * Method: cleanInterrupts
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_InterruptJNI_cleanInterrupts
+ (JNIEnv* env, jclass, jint interruptHandle)
+{
+ INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI cleanInterrupts";
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
+
+ int32_t status = 0;
+ auto param =
+ HAL_CleanInterrupts((HAL_InterruptHandle)interruptHandle, &status);
+ if (param) {
+ delete static_cast<InterruptJNI*>(param);
+ }
+
+ INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
+
+ // ignore status, as an invalid handle just needs to be ignored.
+}
+
+/*
+ * Class: edu_wpi_first_hal_InterruptJNI
+ * Method: waitForInterrupt
+ * Signature: (IDZ)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_InterruptJNI_waitForInterrupt
+ (JNIEnv* env, jclass, jint interruptHandle, jdouble timeout,
+ jboolean ignorePrevious)
+{
+ INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI waitForInterrupt";
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
+
+ int32_t status = 0;
+ int32_t result = HAL_WaitForInterrupt((HAL_InterruptHandle)interruptHandle,
+ timeout, ignorePrevious, &status);
+
+ INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
+
+ CheckStatus(env, status);
+ return result;
+}
+
+/*
+ * Class: edu_wpi_first_hal_InterruptJNI
+ * Method: enableInterrupts
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_InterruptJNI_enableInterrupts
+ (JNIEnv* env, jclass, jint interruptHandle)
+{
+ INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI enableInterrupts";
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
+
+ int32_t status = 0;
+ HAL_EnableInterrupts((HAL_InterruptHandle)interruptHandle, &status);
+
+ INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
+
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_InterruptJNI
+ * Method: disableInterrupts
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_InterruptJNI_disableInterrupts
+ (JNIEnv* env, jclass, jint interruptHandle)
+{
+ INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI disableInterrupts";
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
+
+ int32_t status = 0;
+ HAL_DisableInterrupts((HAL_InterruptHandle)interruptHandle, &status);
+
+ INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
+
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_InterruptJNI
+ * Method: readInterruptRisingTimestamp
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL
+Java_edu_wpi_first_hal_InterruptJNI_readInterruptRisingTimestamp
+ (JNIEnv* env, jclass, jint interruptHandle)
+{
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Calling INTERRUPTJNI readInterruptRisingTimestamp";
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
+
+ int32_t status = 0;
+ jlong timeStamp = HAL_ReadInterruptRisingTimestamp(
+ (HAL_InterruptHandle)interruptHandle, &status);
+
+ INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+ return timeStamp;
+}
+
+/*
+ * Class: edu_wpi_first_hal_InterruptJNI
+ * Method: readInterruptFallingTimestamp
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL
+Java_edu_wpi_first_hal_InterruptJNI_readInterruptFallingTimestamp
+ (JNIEnv* env, jclass, jint interruptHandle)
+{
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Calling INTERRUPTJNI readInterruptFallingTimestamp";
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
+
+ int32_t status = 0;
+ jlong timeStamp = HAL_ReadInterruptFallingTimestamp(
+ (HAL_InterruptHandle)interruptHandle, &status);
+
+ INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+ return timeStamp;
+}
+
+/*
+ * Class: edu_wpi_first_hal_InterruptJNI
+ * Method: requestInterrupts
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_InterruptJNI_requestInterrupts
+ (JNIEnv* env, jclass, jint interruptHandle, jint digitalSourceHandle,
+ jint analogTriggerType)
+{
+ INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI requestInterrupts";
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
+ INTERRUPTJNI_LOG(logDEBUG) << "digitalSourceHandle = " << digitalSourceHandle;
+ INTERRUPTJNI_LOG(logDEBUG) << "analogTriggerType = " << analogTriggerType;
+
+ int32_t status = 0;
+ HAL_RequestInterrupts((HAL_InterruptHandle)interruptHandle,
+ (HAL_Handle)digitalSourceHandle,
+ (HAL_AnalogTriggerType)analogTriggerType, &status);
+
+ INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_InterruptJNI
+ * Method: attachInterruptHandler
+ * Signature: (ILjava/lang/Object;Ljava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_InterruptJNI_attachInterruptHandler
+ (JNIEnv* env, jclass, jint interruptHandle, jobject handler, jobject param)
+{
+ INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI attachInterruptHandler";
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
+
+ jclass cls = env->GetObjectClass(handler);
+ INTERRUPTJNI_LOG(logDEBUG) << "class = " << cls;
+ if (cls == 0) {
+ INTERRUPTJNI_LOG(logERROR) << "Error getting java class";
+ assert(false);
+ return;
+ }
+ jmethodID mid = env->GetMethodID(cls, "apply", "(ILjava/lang/Object;)V");
+ INTERRUPTJNI_LOG(logDEBUG) << "method = " << mid;
+ if (mid == 0) {
+ INTERRUPTJNI_LOG(logERROR) << "Error getting java method ID";
+ assert(false);
+ return;
+ }
+
+ InterruptJNI* intr = new InterruptJNI;
+ intr->Start();
+ intr->SetFunc(env, handler, mid, param);
+
+ INTERRUPTJNI_LOG(logDEBUG) << "InterruptThreadJNI Ptr = " << intr;
+
+ int32_t status = 0;
+ HAL_AttachInterruptHandler((HAL_InterruptHandle)interruptHandle,
+ interruptHandler, intr, &status);
+
+ INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_InterruptJNI
+ * Method: setInterruptUpSourceEdge
+ * Signature: (IZZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_InterruptJNI_setInterruptUpSourceEdge
+ (JNIEnv* env, jclass, jint interruptHandle, jboolean risingEdge,
+ jboolean fallingEdge)
+{
+ INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI setInterruptUpSourceEdge";
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Interrupt Handle = " << (HAL_InterruptHandle)interruptHandle;
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Rising Edge = " << static_cast<bool>(risingEdge);
+ INTERRUPTJNI_LOG(logDEBUG)
+ << "Falling Edge = " << static_cast<bool>(fallingEdge);
+
+ int32_t status = 0;
+ HAL_SetInterruptUpSourceEdge((HAL_InterruptHandle)interruptHandle, risingEdge,
+ fallingEdge, &status);
+
+ INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/NotifierJNI.cpp b/hal/src/main/native/cpp/jni/NotifierJNI.cpp
new file mode 100644
index 0000000..61fe32f
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/NotifierJNI.cpp
@@ -0,0 +1,157 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+#include <cstdio>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_NotifierJNI.h"
+#include "hal/Notifier.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+
+// set the logging level
+TLogLevel notifierJNILogLevel = logWARNING;
+
+#define NOTIFIERJNI_LOG(level) \
+ if (level > notifierJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_NotifierJNI
+ * Method: initializeNotifier
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_NotifierJNI_initializeNotifier
+ (JNIEnv* env, jclass)
+{
+ NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI initializeNotifier";
+
+ int32_t status = 0;
+ HAL_NotifierHandle notifierHandle = HAL_InitializeNotifier(&status);
+
+ NOTIFIERJNI_LOG(logDEBUG) << "Notifier Handle = " << notifierHandle;
+ NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
+
+ if (notifierHandle <= 0 || !CheckStatusForceThrow(env, status)) {
+ return 0; // something went wrong in HAL
+ }
+
+ return (jint)notifierHandle;
+}
+
+/*
+ * Class: edu_wpi_first_hal_NotifierJNI
+ * Method: stopNotifier
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_NotifierJNI_stopNotifier
+ (JNIEnv* env, jclass cls, jint notifierHandle)
+{
+ NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI stopNotifier";
+
+ NOTIFIERJNI_LOG(logDEBUG) << "Notifier Handle = " << notifierHandle;
+
+ int32_t status = 0;
+ HAL_StopNotifier((HAL_NotifierHandle)notifierHandle, &status);
+ NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_NotifierJNI
+ * Method: cleanNotifier
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_NotifierJNI_cleanNotifier
+ (JNIEnv* env, jclass, jint notifierHandle)
+{
+ NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI cleanNotifier";
+
+ NOTIFIERJNI_LOG(logDEBUG) << "Notifier Handle = " << notifierHandle;
+
+ int32_t status = 0;
+ HAL_CleanNotifier((HAL_NotifierHandle)notifierHandle, &status);
+ NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_NotifierJNI
+ * Method: updateNotifierAlarm
+ * Signature: (IJ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_NotifierJNI_updateNotifierAlarm
+ (JNIEnv* env, jclass cls, jint notifierHandle, jlong triggerTime)
+{
+ NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI updateNotifierAlarm";
+
+ NOTIFIERJNI_LOG(logDEBUG) << "Notifier Handle = " << notifierHandle;
+
+ NOTIFIERJNI_LOG(logDEBUG) << "triggerTime = " << triggerTime;
+
+ int32_t status = 0;
+ HAL_UpdateNotifierAlarm((HAL_NotifierHandle)notifierHandle,
+ static_cast<uint64_t>(triggerTime), &status);
+ NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_NotifierJNI
+ * Method: cancelNotifierAlarm
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_NotifierJNI_cancelNotifierAlarm
+ (JNIEnv* env, jclass cls, jint notifierHandle)
+{
+ NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI cancelNotifierAlarm";
+
+ NOTIFIERJNI_LOG(logDEBUG) << "Notifier Handle = " << notifierHandle;
+
+ int32_t status = 0;
+ HAL_CancelNotifierAlarm((HAL_NotifierHandle)notifierHandle, &status);
+ NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_NotifierJNI
+ * Method: waitForNotifierAlarm
+ * Signature: (I)J
+ */
+JNIEXPORT jlong JNICALL
+Java_edu_wpi_first_hal_NotifierJNI_waitForNotifierAlarm
+ (JNIEnv* env, jclass cls, jint notifierHandle)
+{
+ NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI waitForNotifierAlarm";
+
+ NOTIFIERJNI_LOG(logDEBUG) << "Notifier Handle = " << notifierHandle;
+
+ int32_t status = 0;
+ uint64_t time =
+ HAL_WaitForNotifierAlarm((HAL_NotifierHandle)notifierHandle, &status);
+ NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
+ NOTIFIERJNI_LOG(logDEBUG) << "Time = " << time;
+ CheckStatus(env, status);
+
+ return (jlong)time;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/PDPJNI.cpp b/hal/src/main/native/cpp/jni/PDPJNI.cpp
new file mode 100644
index 0000000..e8173be
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/PDPJNI.cpp
@@ -0,0 +1,174 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HALUtil.h"
+#include "edu_wpi_first_hal_PDPJNI.h"
+#include "hal/PDP.h"
+#include "hal/Ports.h"
+
+using namespace frc;
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_PDPJNI
+ * Method: initializePDP
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PDPJNI_initializePDP
+ (JNIEnv* env, jclass, jint module)
+{
+ int32_t status = 0;
+ auto handle = HAL_InitializePDP(module, &status);
+ CheckStatusRange(env, status, 0, HAL_GetNumPDPModules(), module);
+ return static_cast<jint>(handle);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PDPJNI
+ * Method: checkPDPChannel
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_PDPJNI_checkPDPChannel
+ (JNIEnv* env, jclass, jint channel)
+{
+ return HAL_CheckPDPChannel(channel);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PDPJNI
+ * Method: checkPDPModule
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_PDPJNI_checkPDPModule
+ (JNIEnv* env, jclass, jint module)
+{
+ return HAL_CheckPDPModule(module);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PDPJNI
+ * Method: getPDPTemperature
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PDPJNI_getPDPTemperature
+ (JNIEnv* env, jclass, jint handle)
+{
+ int32_t status = 0;
+ double temperature = HAL_GetPDPTemperature(handle, &status);
+ CheckStatus(env, status, false);
+ return temperature;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PDPJNI
+ * Method: getPDPVoltage
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PDPJNI_getPDPVoltage
+ (JNIEnv* env, jclass, jint handle)
+{
+ int32_t status = 0;
+ double voltage = HAL_GetPDPVoltage(handle, &status);
+ CheckStatus(env, status, false);
+ return voltage;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PDPJNI
+ * Method: getPDPChannelCurrent
+ * Signature: (BI)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PDPJNI_getPDPChannelCurrent
+ (JNIEnv* env, jclass, jbyte channel, jint handle)
+{
+ int32_t status = 0;
+ double current = HAL_GetPDPChannelCurrent(handle, channel, &status);
+ CheckStatus(env, status, false);
+ return current;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PDPJNI
+ * Method: getPDPTotalCurrent
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PDPJNI_getPDPTotalCurrent
+ (JNIEnv* env, jclass, jint handle)
+{
+ int32_t status = 0;
+ double current = HAL_GetPDPTotalCurrent(handle, &status);
+ CheckStatus(env, status, false);
+ return current;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PDPJNI
+ * Method: getPDPTotalPower
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PDPJNI_getPDPTotalPower
+ (JNIEnv* env, jclass, jint handle)
+{
+ int32_t status = 0;
+ double power = HAL_GetPDPTotalPower(handle, &status);
+ CheckStatus(env, status, false);
+ return power;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PDPJNI
+ * Method: getPDPTotalEnergy
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PDPJNI_getPDPTotalEnergy
+ (JNIEnv* env, jclass, jint handle)
+{
+ int32_t status = 0;
+ double energy = HAL_GetPDPTotalEnergy(handle, &status);
+ CheckStatus(env, status, false);
+ return energy;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PDPJNI
+ * Method: resetPDPTotalEnergy
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_PDPJNI_resetPDPTotalEnergy
+ (JNIEnv* env, jclass, jint handle)
+{
+ int32_t status = 0;
+ HAL_ResetPDPTotalEnergy(handle, &status);
+ CheckStatus(env, status, false);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PDPJNI
+ * Method: clearPDPStickyFaults
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_PDPJNI_clearPDPStickyFaults
+ (JNIEnv* env, jclass, jint handle)
+{
+ int32_t status = 0;
+ HAL_ClearPDPStickyFaults(handle, &status);
+ CheckStatus(env, status, false);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/PWMJNI.cpp b/hal/src/main/native/cpp/jni/PWMJNI.cpp
new file mode 100644
index 0000000..1509f94
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/PWMJNI.cpp
@@ -0,0 +1,330 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_PWMJNI.h"
+#include "hal/DIO.h"
+#include "hal/PWM.h"
+#include "hal/Ports.h"
+#include "hal/cpp/Log.h"
+#include "hal/handles/HandlesInternal.h"
+
+using namespace frc;
+
+// set the logging level
+TLogLevel pwmJNILogLevel = logWARNING;
+
+#define PWMJNI_LOG(level) \
+ if (level > pwmJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: initializePWMPort
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PWMJNI_initializePWMPort
+ (JNIEnv* env, jclass, jint id)
+{
+ PWMJNI_LOG(logDEBUG) << "Calling PWMJNI initializePWMPort";
+ PWMJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id;
+ int32_t status = 0;
+ auto pwm = HAL_InitializePWMPort((HAL_PortHandle)id, &status);
+ PWMJNI_LOG(logDEBUG) << "Status = " << status;
+ PWMJNI_LOG(logDEBUG) << "PWM Handle = " << pwm;
+ CheckStatusRange(env, status, 0, HAL_GetNumPWMChannels(),
+ hal::getPortHandleChannel((HAL_PortHandle)id));
+ return (jint)pwm;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: checkPWMChannel
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_PWMJNI_checkPWMChannel
+ (JNIEnv* env, jclass, jint channel)
+{
+ PWMJNI_LOG(logDEBUG) << "Calling PWMJNI checkPWMChannel";
+ PWMJNI_LOG(logDEBUG) << "Channel = " << channel;
+ return HAL_CheckPWMChannel(channel);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: freePWMPort
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_PWMJNI_freePWMPort
+ (JNIEnv* env, jclass, jint id)
+{
+ PWMJNI_LOG(logDEBUG) << "Calling PWMJNI freePWMPort";
+ PWMJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ HAL_FreePWMPort((HAL_DigitalHandle)id, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: setPWMConfigRaw
+ * Signature: (IIIIII)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_PWMJNI_setPWMConfigRaw
+ (JNIEnv* env, jclass, jint id, jint maxPwm, jint deadbandMaxPwm,
+ jint centerPwm, jint deadbandMinPwm, jint minPwm)
+{
+ PWMJNI_LOG(logDEBUG) << "Calling PWMJNI setPWMConfigRaw";
+ PWMJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ HAL_SetPWMConfigRaw((HAL_DigitalHandle)id, maxPwm, deadbandMaxPwm, centerPwm,
+ deadbandMinPwm, minPwm, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: setPWMConfig
+ * Signature: (IDDDDD)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_PWMJNI_setPWMConfig
+ (JNIEnv* env, jclass, jint id, jdouble maxPwm, jdouble deadbandMaxPwm,
+ jdouble centerPwm, jdouble deadbandMinPwm, jdouble minPwm)
+{
+ PWMJNI_LOG(logDEBUG) << "Calling PWMJNI setPWMConfig";
+ PWMJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ HAL_SetPWMConfig((HAL_DigitalHandle)id, maxPwm, deadbandMaxPwm, centerPwm,
+ deadbandMinPwm, minPwm, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: getPWMConfigRaw
+ * Signature: (I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL
+Java_edu_wpi_first_hal_PWMJNI_getPWMConfigRaw
+ (JNIEnv* env, jclass, jint id)
+{
+ PWMJNI_LOG(logDEBUG) << "Calling PWMJNI getPWMConfigRaw";
+ PWMJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ int32_t maxPwm = 0;
+ int32_t deadbandMaxPwm = 0;
+ int32_t centerPwm = 0;
+ int32_t deadbandMinPwm = 0;
+ int32_t minPwm = 0;
+ HAL_GetPWMConfigRaw((HAL_DigitalHandle)id, &maxPwm, &deadbandMaxPwm,
+ ¢erPwm, &deadbandMinPwm, &minPwm, &status);
+ CheckStatus(env, status);
+ return CreatePWMConfigDataResult(env, maxPwm, deadbandMaxPwm, centerPwm,
+ deadbandMinPwm, minPwm);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: setPWMEliminateDeadband
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_PWMJNI_setPWMEliminateDeadband
+ (JNIEnv* env, jclass, jint id, jboolean value)
+{
+ PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ HAL_SetPWMEliminateDeadband((HAL_DigitalHandle)id, value, &status);
+ PWMJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: getPWMEliminateDeadband
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_PWMJNI_getPWMEliminateDeadband
+ (JNIEnv* env, jclass, jint id)
+{
+ PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ auto val = HAL_GetPWMEliminateDeadband((HAL_DigitalHandle)id, &status);
+ PWMJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+ return (jboolean)val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: setPWMRaw
+ * Signature: (IS)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_PWMJNI_setPWMRaw
+ (JNIEnv* env, jclass, jint id, jshort value)
+{
+ PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
+ PWMJNI_LOG(logDEBUG) << "PWM Value = " << value;
+ int32_t status = 0;
+ HAL_SetPWMRaw((HAL_DigitalHandle)id, value, &status);
+ PWMJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: setPWMSpeed
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_PWMJNI_setPWMSpeed
+ (JNIEnv* env, jclass, jint id, jdouble value)
+{
+ PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
+ PWMJNI_LOG(logDEBUG) << "PWM Value = " << value;
+ int32_t status = 0;
+ HAL_SetPWMSpeed((HAL_DigitalHandle)id, value, &status);
+ PWMJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: setPWMPosition
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_PWMJNI_setPWMPosition
+ (JNIEnv* env, jclass, jint id, jdouble value)
+{
+ PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
+ PWMJNI_LOG(logDEBUG) << "PWM Value = " << value;
+ int32_t status = 0;
+ HAL_SetPWMPosition((HAL_DigitalHandle)id, value, &status);
+ PWMJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: getPWMRaw
+ * Signature: (I)S
+ */
+JNIEXPORT jshort JNICALL
+Java_edu_wpi_first_hal_PWMJNI_getPWMRaw
+ (JNIEnv* env, jclass, jint id)
+{
+ PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ jshort returnValue = HAL_GetPWMRaw((HAL_DigitalHandle)id, &status);
+ PWMJNI_LOG(logDEBUG) << "Status = " << status;
+ PWMJNI_LOG(logDEBUG) << "Value = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: getPWMSpeed
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PWMJNI_getPWMSpeed
+ (JNIEnv* env, jclass, jint id)
+{
+ PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ jdouble returnValue = HAL_GetPWMSpeed((HAL_DigitalHandle)id, &status);
+ PWMJNI_LOG(logDEBUG) << "Status = " << status;
+ PWMJNI_LOG(logDEBUG) << "Value = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: getPWMPosition
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PWMJNI_getPWMPosition
+ (JNIEnv* env, jclass, jint id)
+{
+ PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ jdouble returnValue = HAL_GetPWMPosition((HAL_DigitalHandle)id, &status);
+ PWMJNI_LOG(logDEBUG) << "Status = " << status;
+ PWMJNI_LOG(logDEBUG) << "Value = " << returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: setPWMDisabled
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_PWMJNI_setPWMDisabled
+ (JNIEnv* env, jclass, jint id)
+{
+ PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ HAL_SetPWMDisabled((HAL_DigitalHandle)id, &status);
+ PWMJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: latchPWMZero
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_PWMJNI_latchPWMZero
+ (JNIEnv* env, jclass, jint id)
+{
+ PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
+ int32_t status = 0;
+ HAL_LatchPWMZero((HAL_DigitalHandle)id, &status);
+ PWMJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_PWMJNI
+ * Method: setPWMPeriodScale
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_PWMJNI_setPWMPeriodScale
+ (JNIEnv* env, jclass, jint id, jint value)
+{
+ PWMJNI_LOG(logDEBUG) << "PWM Handle = " << (HAL_DigitalHandle)id;
+ PWMJNI_LOG(logDEBUG) << "PeriodScale Value = " << value;
+ int32_t status = 0;
+ HAL_SetPWMPeriodScale((HAL_DigitalHandle)id, value, &status);
+ PWMJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/PortsJNI.cpp b/hal/src/main/native/cpp/jni/PortsJNI.cpp
new file mode 100644
index 0000000..4e14984
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/PortsJNI.cpp
@@ -0,0 +1,298 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_PortsJNI.h"
+#include "hal/Ports.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+
+// set the logging level
+TLogLevel portsJNILogLevel = logWARNING;
+
+#define PORTSJNI_LOG(level) \
+ if (level > portsJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumAccumulators
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumAccumulators
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumAccumulators";
+ jint value = HAL_GetNumAccumulators();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumAnalogTriggers
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumAnalogTriggers
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumAnalogTriggers";
+ jint value = HAL_GetNumAnalogTriggers();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumAnalogInputs
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumAnalogInputs
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumAnalogInputs";
+ jint value = HAL_GetNumAnalogInputs();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumAnalogOutputs
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumAnalogOutputs
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumAnalogOutputs";
+ jint value = HAL_GetNumAnalogOutputs();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumCounters
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumCounters
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumCounters";
+ jint value = HAL_GetNumCounters();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumDigitalHeaders
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumDigitalHeaders
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumDigitalHeaders";
+ jint value = HAL_GetNumDigitalHeaders();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumPWMHeaders
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumPWMHeaders
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumPWMHeaders";
+ jint value = HAL_GetNumPWMHeaders();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumDigitalChannels
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumDigitalChannels
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumDigitalChannels";
+ jint value = HAL_GetNumDigitalChannels();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumPWMChannels
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumPWMChannels
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumPWMChannels";
+ jint value = HAL_GetNumPWMChannels();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumDigitalPWMOutputs
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumDigitalPWMOutputs
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumDigitalPWMOutputs";
+ jint value = HAL_GetNumDigitalPWMOutputs();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumEncoders
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumEncoders
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumEncoders";
+ jint value = HAL_GetNumEncoders();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumInterrupts
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumInterrupts
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumInterrupts";
+ jint value = HAL_GetNumInterrupts();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumRelayChannels
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumRelayChannels
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumRelayChannels";
+ jint value = HAL_GetNumRelayChannels();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumRelayHeaders
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumRelayHeaders
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumRelayHeaders";
+ jint value = HAL_GetNumRelayHeaders();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumPCMModules
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumPCMModules
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumPCMModules";
+ jint value = HAL_GetNumPCMModules();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumSolenoidChannels
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumSolenoidChannels
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumSolenoidChannels";
+ jint value = HAL_GetNumSolenoidChannels();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumPDPModules
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumPDPModules
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumPDPModules";
+ jint value = HAL_GetNumPDPModules();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PortsJNI
+ * Method: getNumPDPChannels
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PortsJNI_getNumPDPChannels
+ (JNIEnv* env, jclass)
+{
+ PORTSJNI_LOG(logDEBUG) << "Calling PortsJNI getNumPDPChannels";
+ jint value = HAL_GetNumPDPChannels();
+ PORTSJNI_LOG(logDEBUG) << "Value = " << value;
+ return value;
+}
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/PowerJNI.cpp b/hal/src/main/native/cpp/jni/PowerJNI.cpp
new file mode 100644
index 0000000..9184e9e
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/PowerJNI.cpp
@@ -0,0 +1,228 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_PowerJNI.h"
+#include "hal/Power.h"
+
+using namespace frc;
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getVinVoltage
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getVinVoltage
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ double val = HAL_GetVinVoltage(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getVinCurrent
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getVinCurrent
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ double val = HAL_GetVinCurrent(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getUserVoltage6V
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getUserVoltage6V
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ double val = HAL_GetUserVoltage6V(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getUserCurrent6V
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getUserCurrent6V
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ double val = HAL_GetUserCurrent6V(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getUserActive6V
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getUserActive6V
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ bool val = HAL_GetUserActive6V(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getUserCurrentFaults6V
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getUserCurrentFaults6V
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ int32_t val = HAL_GetUserCurrentFaults6V(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getUserVoltage5V
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getUserVoltage5V
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ double val = HAL_GetUserVoltage5V(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getUserCurrent5V
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getUserCurrent5V
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ double val = HAL_GetUserCurrent5V(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getUserActive5V
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getUserActive5V
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ bool val = HAL_GetUserActive5V(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getUserCurrentFaults5V
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getUserCurrentFaults5V
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ int32_t val = HAL_GetUserCurrentFaults5V(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getUserVoltage3V3
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getUserVoltage3V3
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ double val = HAL_GetUserVoltage3V3(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getUserCurrent3V3
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getUserCurrent3V3
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ double val = HAL_GetUserCurrent3V3(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getUserActive3V3
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getUserActive3V3
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ bool val = HAL_GetUserActive3V3(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_PowerJNI
+ * Method: getUserCurrentFaults3V3
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_PowerJNI_getUserCurrentFaults3V3
+ (JNIEnv* env, jclass)
+{
+ int32_t status = 0;
+ int32_t val = HAL_GetUserCurrentFaults3V3(&status);
+ CheckStatus(env, status);
+ return val;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/RelayJNI.cpp b/hal/src/main/native/cpp/jni/RelayJNI.cpp
new file mode 100644
index 0000000..0cc70fb
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/RelayJNI.cpp
@@ -0,0 +1,119 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_RelayJNI.h"
+#include "hal/Ports.h"
+#include "hal/Relay.h"
+#include "hal/cpp/Log.h"
+#include "hal/handles/HandlesInternal.h"
+
+using namespace frc;
+
+// set the logging level
+TLogLevel relayJNILogLevel = logWARNING;
+
+#define RELAYJNI_LOG(level) \
+ if (level > relayJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_RelayJNI
+ * Method: initializeRelayPort
+ * Signature: (IZ)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_RelayJNI_initializeRelayPort
+ (JNIEnv* env, jclass, jint id, jboolean fwd)
+{
+ RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI initializeRelayPort";
+ RELAYJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id;
+ RELAYJNI_LOG(logDEBUG) << "Forward = " << (jint)fwd;
+ int32_t status = 0;
+ HAL_RelayHandle handle = HAL_InitializeRelayPort(
+ (HAL_PortHandle)id, static_cast<uint8_t>(fwd), &status);
+ RELAYJNI_LOG(logDEBUG) << "Status = " << status;
+ RELAYJNI_LOG(logDEBUG) << "Relay Handle = " << handle;
+ CheckStatusRange(env, status, 0, HAL_GetNumRelayChannels(),
+ hal::getPortHandleChannel((HAL_PortHandle)id));
+ return (jint)handle;
+}
+
+/*
+ * Class: edu_wpi_first_hal_RelayJNI
+ * Method: freeRelayPort
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_RelayJNI_freeRelayPort
+ (JNIEnv* env, jclass, jint id)
+{
+ RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI freeRelayPort";
+ RELAYJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_RelayHandle)id;
+ HAL_FreeRelayPort((HAL_RelayHandle)id);
+}
+
+/*
+ * Class: edu_wpi_first_hal_RelayJNI
+ * Method: checkRelayChannel
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_RelayJNI_checkRelayChannel
+ (JNIEnv* env, jclass, jint channel)
+{
+ RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI checkRelayChannel";
+ RELAYJNI_LOG(logDEBUG) << "Channel = " << channel;
+ return (jboolean)HAL_CheckRelayChannel(static_cast<uint8_t>(channel));
+}
+
+/*
+ * Class: edu_wpi_first_hal_RelayJNI
+ * Method: setRelay
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_RelayJNI_setRelay
+ (JNIEnv* env, jclass, jint id, jboolean value)
+{
+ RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI setRelay";
+ RELAYJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_RelayHandle)id;
+ RELAYJNI_LOG(logDEBUG) << "Flag = " << (jint)value;
+ int32_t status = 0;
+ HAL_SetRelay((HAL_RelayHandle)id, value, &status);
+ RELAYJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_RelayJNI
+ * Method: getRelay
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_RelayJNI_getRelay
+ (JNIEnv* env, jclass, jint id)
+{
+ RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI getRelay";
+ RELAYJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_RelayHandle)id;
+ int32_t status = 0;
+ jboolean returnValue = HAL_GetRelay((HAL_RelayHandle)id, &status);
+ RELAYJNI_LOG(logDEBUG) << "Status = " << status;
+ RELAYJNI_LOG(logDEBUG) << "getRelayResult = " << (jint)returnValue;
+ CheckStatus(env, status);
+ return returnValue;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/SPIJNI.cpp b/hal/src/main/native/cpp/jni/SPIJNI.cpp
new file mode 100644
index 0000000..d594058
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/SPIJNI.cpp
@@ -0,0 +1,500 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include <wpi/jni_util.h>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_SPIJNI.h"
+#include "hal/SPI.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+using namespace wpi::java;
+
+// set the logging level
+TLogLevel spiJNILogLevel = logWARNING;
+
+#define SPIJNI_LOG(level) \
+ if (level > spiJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiInitialize
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiInitialize
+ (JNIEnv* env, jclass, jint port)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiInitialize";
+ SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ int32_t status = 0;
+ HAL_InitializeSPI(static_cast<HAL_SPIPort>(port), &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatusForceThrow(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiTransaction
+ * Signature: (ILjava/lang/Object;Ljava/lang/Object;B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiTransaction
+ (JNIEnv* env, jclass, jint port, jobject dataToSend, jobject dataReceived,
+ jbyte size)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiTransaction";
+ SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ uint8_t* dataToSendPtr = nullptr;
+ if (dataToSend != 0) {
+ dataToSendPtr =
+ reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataToSend));
+ }
+ uint8_t* dataReceivedPtr =
+ reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataReceived));
+ SPIJNI_LOG(logDEBUG) << "Size = " << (jint)size;
+ SPIJNI_LOG(logDEBUG) << "DataToSendPtr = " << dataToSendPtr;
+ SPIJNI_LOG(logDEBUG) << "DataReceivedPtr = " << dataReceivedPtr;
+ jint retVal = HAL_TransactionSPI(static_cast<HAL_SPIPort>(port),
+ dataToSendPtr, dataReceivedPtr, size);
+ SPIJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)retVal;
+ return retVal;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiTransactionB
+ * Signature: (I[B[BB)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiTransactionB
+ (JNIEnv* env, jclass, jint port, jbyteArray dataToSend,
+ jbyteArray dataReceived, jbyte size)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiTransactionB";
+ SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ SPIJNI_LOG(logDEBUG) << "Size = " << (jint)size;
+ wpi::SmallVector<uint8_t, 128> recvBuf;
+ recvBuf.resize(size);
+ jint retVal =
+ HAL_TransactionSPI(static_cast<HAL_SPIPort>(port),
+ reinterpret_cast<const uint8_t*>(
+ JByteArrayRef(env, dataToSend).array().data()),
+ recvBuf.data(), size);
+ env->SetByteArrayRegion(dataReceived, 0, size,
+ reinterpret_cast<const jbyte*>(recvBuf.data()));
+ SPIJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)retVal;
+ return retVal;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiWrite
+ * Signature: (ILjava/lang/Object;B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiWrite
+ (JNIEnv* env, jclass, jint port, jobject dataToSend, jbyte size)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiWrite";
+ SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ uint8_t* dataToSendPtr = nullptr;
+ if (dataToSend != 0) {
+ dataToSendPtr =
+ reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataToSend));
+ }
+ SPIJNI_LOG(logDEBUG) << "Size = " << (jint)size;
+ SPIJNI_LOG(logDEBUG) << "DataToSendPtr = " << dataToSendPtr;
+ jint retVal =
+ HAL_WriteSPI(static_cast<HAL_SPIPort>(port), dataToSendPtr, size);
+ SPIJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)retVal;
+ return retVal;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiWriteB
+ * Signature: (I[BB)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiWriteB
+ (JNIEnv* env, jclass, jint port, jbyteArray dataToSend, jbyte size)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiWriteB";
+ SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ SPIJNI_LOG(logDEBUG) << "Size = " << (jint)size;
+ jint retVal = HAL_WriteSPI(static_cast<HAL_SPIPort>(port),
+ reinterpret_cast<const uint8_t*>(
+ JByteArrayRef(env, dataToSend).array().data()),
+ size);
+ SPIJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)retVal;
+ return retVal;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiRead
+ * Signature: (IZLjava/lang/Object;B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiRead
+ (JNIEnv* env, jclass, jint port, jboolean initiate, jobject dataReceived,
+ jbyte size)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiRead";
+ SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ SPIJNI_LOG(logDEBUG) << "Initiate = " << (jboolean)initiate;
+ uint8_t* dataReceivedPtr =
+ reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(dataReceived));
+ SPIJNI_LOG(logDEBUG) << "Size = " << (jint)size;
+ SPIJNI_LOG(logDEBUG) << "DataReceivedPtr = " << dataReceivedPtr;
+ jint retVal;
+ if (initiate) {
+ wpi::SmallVector<uint8_t, 128> sendBuf;
+ sendBuf.resize(size);
+ retVal = HAL_TransactionSPI(static_cast<HAL_SPIPort>(port), sendBuf.data(),
+ dataReceivedPtr, size);
+ } else {
+ retVal = HAL_ReadSPI(static_cast<HAL_SPIPort>(port),
+ reinterpret_cast<uint8_t*>(dataReceivedPtr), size);
+ }
+ SPIJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)retVal;
+ return retVal;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiReadB
+ * Signature: (IZ[BB)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiReadB
+ (JNIEnv* env, jclass, jint port, jboolean initiate, jbyteArray dataReceived,
+ jbyte size)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiReadB";
+ SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ SPIJNI_LOG(logDEBUG) << "Initiate = " << (jboolean)initiate;
+ SPIJNI_LOG(logDEBUG) << "Size = " << (jint)size;
+ jint retVal;
+ wpi::SmallVector<uint8_t, 128> recvBuf;
+ recvBuf.resize(size);
+ if (initiate) {
+ wpi::SmallVector<uint8_t, 128> sendBuf;
+ sendBuf.resize(size);
+ retVal = HAL_TransactionSPI(static_cast<HAL_SPIPort>(port), sendBuf.data(),
+ recvBuf.data(), size);
+ } else {
+ retVal = HAL_ReadSPI(static_cast<HAL_SPIPort>(port), recvBuf.data(), size);
+ }
+ env->SetByteArrayRegion(dataReceived, 0, size,
+ reinterpret_cast<const jbyte*>(recvBuf.data()));
+ SPIJNI_LOG(logDEBUG) << "ReturnValue = " << (jint)retVal;
+ return retVal;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiClose
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiClose
+ (JNIEnv*, jclass, jint port)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiClose";
+ SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ HAL_CloseSPI(static_cast<HAL_SPIPort>(port));
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiSetSpeed
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiSetSpeed
+ (JNIEnv*, jclass, jint port, jint speed)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiSetSpeed";
+ SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ SPIJNI_LOG(logDEBUG) << "Speed = " << (jint)speed;
+ HAL_SetSPISpeed(static_cast<HAL_SPIPort>(port), speed);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiSetOpts
+ * Signature: (IIII)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiSetOpts
+ (JNIEnv*, jclass, jint port, jint msb_first, jint sample_on_trailing,
+ jint clk_idle_high)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiSetOpts";
+ SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ SPIJNI_LOG(logDEBUG) << "msb_first = " << msb_first;
+ SPIJNI_LOG(logDEBUG) << "sample_on_trailing = " << sample_on_trailing;
+ SPIJNI_LOG(logDEBUG) << "clk_idle_high = " << clk_idle_high;
+ HAL_SetSPIOpts(static_cast<HAL_SPIPort>(port), msb_first, sample_on_trailing,
+ clk_idle_high);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiSetChipSelectActiveHigh
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiSetChipSelectActiveHigh
+ (JNIEnv* env, jclass, jint port)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiSetCSActiveHigh";
+ SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ int32_t status = 0;
+ HAL_SetSPIChipSelectActiveHigh(static_cast<HAL_SPIPort>(port), &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiSetChipSelectActiveLow
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiSetChipSelectActiveLow
+ (JNIEnv* env, jclass, jint port)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiSetCSActiveLow";
+ SPIJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ int32_t status = 0;
+ HAL_SetSPIChipSelectActiveLow(static_cast<HAL_SPIPort>(port), &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiInitAuto
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiInitAuto
+ (JNIEnv* env, jclass, jint port, jint bufferSize)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiInitAuto";
+ SPIJNI_LOG(logDEBUG) << "Port = " << port;
+ SPIJNI_LOG(logDEBUG) << "BufferSize = " << bufferSize;
+ int32_t status = 0;
+ HAL_InitSPIAuto(static_cast<HAL_SPIPort>(port), bufferSize, &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiFreeAuto
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiFreeAuto
+ (JNIEnv* env, jclass, jint port)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiFreeAuto";
+ SPIJNI_LOG(logDEBUG) << "Port = " << port;
+ int32_t status = 0;
+ HAL_FreeSPIAuto(static_cast<HAL_SPIPort>(port), &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiStartAutoRate
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiStartAutoRate
+ (JNIEnv* env, jclass, jint port, jdouble period)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiStartAutoRate";
+ SPIJNI_LOG(logDEBUG) << "Port = " << port;
+ SPIJNI_LOG(logDEBUG) << "Period = " << period;
+ int32_t status = 0;
+ HAL_StartSPIAutoRate(static_cast<HAL_SPIPort>(port), period, &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiStartAutoTrigger
+ * Signature: (IIIZZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiStartAutoTrigger
+ (JNIEnv* env, jclass, jint port, jint digitalSourceHandle,
+ jint analogTriggerType, jboolean triggerRising, jboolean triggerFalling)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiStartAutoTrigger";
+ SPIJNI_LOG(logDEBUG) << "Port = " << port;
+ SPIJNI_LOG(logDEBUG) << "DigitalSourceHandle = " << digitalSourceHandle;
+ SPIJNI_LOG(logDEBUG) << "AnalogTriggerType = " << analogTriggerType;
+ SPIJNI_LOG(logDEBUG) << "TriggerRising = " << (jint)triggerRising;
+ SPIJNI_LOG(logDEBUG) << "TriggerFalling = " << (jint)triggerFalling;
+ int32_t status = 0;
+ HAL_StartSPIAutoTrigger(static_cast<HAL_SPIPort>(port), digitalSourceHandle,
+ static_cast<HAL_AnalogTriggerType>(analogTriggerType),
+ triggerRising, triggerFalling, &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiStopAuto
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiStopAuto
+ (JNIEnv* env, jclass, jint port)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiStopAuto";
+ SPIJNI_LOG(logDEBUG) << "Port = " << port;
+ int32_t status = 0;
+ HAL_StopSPIAuto(static_cast<HAL_SPIPort>(port), &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiSetAutoTransmitData
+ * Signature: (I[BI)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiSetAutoTransmitData
+ (JNIEnv* env, jclass, jint port, jbyteArray dataToSend, jint zeroSize)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiSetAutoTransmitData";
+ SPIJNI_LOG(logDEBUG) << "Port = " << port;
+ SPIJNI_LOG(logDEBUG) << "ZeroSize = " << zeroSize;
+ JByteArrayRef jarr(env, dataToSend);
+ int32_t status = 0;
+ HAL_SetSPIAutoTransmitData(
+ static_cast<HAL_SPIPort>(port),
+ reinterpret_cast<const uint8_t*>(jarr.array().data()),
+ jarr.array().size(), zeroSize, &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiForceAutoRead
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiForceAutoRead
+ (JNIEnv* env, jclass, jint port)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiForceAutoRead";
+ SPIJNI_LOG(logDEBUG) << "Port = " << port;
+ int32_t status = 0;
+ HAL_ForceSPIAutoRead(static_cast<HAL_SPIPort>(port), &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiReadAutoReceivedData
+ * Signature: (ILjava/lang/Object;ID)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiReadAutoReceivedData__ILjava_nio_ByteBuffer_2ID
+ (JNIEnv* env, jclass, jint port, jobject buffer, jint numToRead,
+ jdouble timeout)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiReadAutoReceivedData";
+ SPIJNI_LOG(logDEBUG) << "Port = " << port;
+ SPIJNI_LOG(logDEBUG) << "NumToRead = " << numToRead;
+ SPIJNI_LOG(logDEBUG) << "Timeout = " << timeout;
+ uint32_t* recvBuf =
+ reinterpret_cast<uint32_t*>(env->GetDirectBufferAddress(buffer));
+ int32_t status = 0;
+ jint retval = HAL_ReadSPIAutoReceivedData(
+ static_cast<HAL_SPIPort>(port), recvBuf, numToRead, timeout, &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ SPIJNI_LOG(logDEBUG) << "Return = " << retval;
+ CheckStatus(env, status);
+ return retval;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiReadAutoReceivedData
+ * Signature: (I[IID)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiReadAutoReceivedData__I_3IID
+ (JNIEnv* env, jclass, jint port, jintArray buffer, jint numToRead,
+ jdouble timeout)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiReadAutoReceivedData";
+ SPIJNI_LOG(logDEBUG) << "Port = " << port;
+ SPIJNI_LOG(logDEBUG) << "NumToRead = " << numToRead;
+ SPIJNI_LOG(logDEBUG) << "Timeout = " << timeout;
+ wpi::SmallVector<uint32_t, 128> recvBuf;
+ recvBuf.resize(numToRead);
+ int32_t status = 0;
+ jint retval =
+ HAL_ReadSPIAutoReceivedData(static_cast<HAL_SPIPort>(port),
+ recvBuf.data(), numToRead, timeout, &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ SPIJNI_LOG(logDEBUG) << "Return = " << retval;
+ if (!CheckStatus(env, status)) return retval;
+ if (numToRead > 0) {
+ env->SetIntArrayRegion(buffer, 0, numToRead,
+ reinterpret_cast<const jint*>(recvBuf.data()));
+ }
+ return retval;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SPIJNI
+ * Method: spiGetAutoDroppedCount
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SPIJNI_spiGetAutoDroppedCount
+ (JNIEnv* env, jclass, jint port)
+{
+ SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiGetAutoDroppedCount";
+ SPIJNI_LOG(logDEBUG) << "Port = " << port;
+ int32_t status = 0;
+ auto retval =
+ HAL_GetSPIAutoDroppedCount(static_cast<HAL_SPIPort>(port), &status);
+ SPIJNI_LOG(logDEBUG) << "Status = " << status;
+ SPIJNI_LOG(logDEBUG) << "Return = " << retval;
+ CheckStatus(env, status);
+ return retval;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/SerialPortJNI.cpp b/hal/src/main/native/cpp/jni/SerialPortJNI.cpp
new file mode 100644
index 0000000..4524fe6
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/SerialPortJNI.cpp
@@ -0,0 +1,369 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include <wpi/jni_util.h>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_SerialPortJNI.h"
+#include "hal/SerialPort.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+using namespace wpi::java;
+
+// set the logging level
+TLogLevel serialJNILogLevel = logWARNING;
+
+#define SERIALJNI_LOG(level) \
+ if (level > serialJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialInitializePort
+ * Signature: (B)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialInitializePort
+ (JNIEnv* env, jclass, jbyte port)
+{
+ SERIALJNI_LOG(logDEBUG) << "Calling Serial Initialize";
+ SERIALJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ int32_t status = 0;
+ HAL_InitializeSerialPort(static_cast<HAL_SerialPort>(port), &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatusForceThrow(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialInitializePortDirect
+ * Signature: (BLjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialInitializePortDirect
+ (JNIEnv* env, jclass, jbyte port, jstring portName)
+{
+ SERIALJNI_LOG(logDEBUG) << "Calling Serial Initialize Direct";
+ SERIALJNI_LOG(logDEBUG) << "Port = " << (jint)port;
+ JStringRef portNameRef{env, portName};
+ SERIALJNI_LOG(logDEBUG) << "PortName = " << portNameRef.c_str();
+ int32_t status = 0;
+ HAL_InitializeSerialPortDirect(static_cast<HAL_SerialPort>(port),
+ portNameRef.c_str(), &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatusForceThrow(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialSetBaudRate
+ * Signature: (BI)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialSetBaudRate
+ (JNIEnv* env, jclass, jbyte port, jint rate)
+{
+ SERIALJNI_LOG(logDEBUG) << "Setting Serial Baud Rate";
+ SERIALJNI_LOG(logDEBUG) << "Baud: " << rate;
+ int32_t status = 0;
+ HAL_SetSerialBaudRate(static_cast<HAL_SerialPort>(port), rate, &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialSetDataBits
+ * Signature: (BB)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialSetDataBits
+ (JNIEnv* env, jclass, jbyte port, jbyte bits)
+{
+ SERIALJNI_LOG(logDEBUG) << "Setting Serial Data Bits";
+ SERIALJNI_LOG(logDEBUG) << "Data Bits: " << bits;
+ int32_t status = 0;
+ HAL_SetSerialDataBits(static_cast<HAL_SerialPort>(port), bits, &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialSetParity
+ * Signature: (BB)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialSetParity
+ (JNIEnv* env, jclass, jbyte port, jbyte parity)
+{
+ SERIALJNI_LOG(logDEBUG) << "Setting Serial Parity";
+ SERIALJNI_LOG(logDEBUG) << "Parity: " << parity;
+ int32_t status = 0;
+ HAL_SetSerialParity(static_cast<HAL_SerialPort>(port), parity, &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialSetStopBits
+ * Signature: (BB)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialSetStopBits
+ (JNIEnv* env, jclass, jbyte port, jbyte bits)
+{
+ SERIALJNI_LOG(logDEBUG) << "Setting Serial Stop Bits";
+ SERIALJNI_LOG(logDEBUG) << "Stop Bits: " << bits;
+ int32_t status = 0;
+ HAL_SetSerialStopBits(static_cast<HAL_SerialPort>(port), bits, &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialSetWriteMode
+ * Signature: (BB)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialSetWriteMode
+ (JNIEnv* env, jclass, jbyte port, jbyte mode)
+{
+ SERIALJNI_LOG(logDEBUG) << "Setting Serial Write Mode";
+ SERIALJNI_LOG(logDEBUG) << "Write mode: " << mode;
+ int32_t status = 0;
+ HAL_SetSerialWriteMode(static_cast<HAL_SerialPort>(port), mode, &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialSetFlowControl
+ * Signature: (BB)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialSetFlowControl
+ (JNIEnv* env, jclass, jbyte port, jbyte flow)
+{
+ SERIALJNI_LOG(logDEBUG) << "Setting Serial Flow Control";
+ SERIALJNI_LOG(logDEBUG) << "Flow Control: " << flow;
+ int32_t status = 0;
+ HAL_SetSerialFlowControl(static_cast<HAL_SerialPort>(port), flow, &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialSetTimeout
+ * Signature: (BD)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialSetTimeout
+ (JNIEnv* env, jclass, jbyte port, jdouble timeout)
+{
+ SERIALJNI_LOG(logDEBUG) << "Setting Serial Timeout";
+ SERIALJNI_LOG(logDEBUG) << "Timeout: " << timeout;
+ int32_t status = 0;
+ HAL_SetSerialTimeout(static_cast<HAL_SerialPort>(port), timeout, &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialEnableTermination
+ * Signature: (BC)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialEnableTermination
+ (JNIEnv* env, jclass, jbyte port, jchar terminator)
+{
+ SERIALJNI_LOG(logDEBUG) << "Setting Serial Enable Termination";
+ SERIALJNI_LOG(logDEBUG) << "Terminator: " << terminator;
+ int32_t status = 0;
+ HAL_EnableSerialTermination(static_cast<HAL_SerialPort>(port), terminator,
+ &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialDisableTermination
+ * Signature: (B)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialDisableTermination
+ (JNIEnv* env, jclass, jbyte port)
+{
+ SERIALJNI_LOG(logDEBUG) << "Setting Serial Disable termination";
+ int32_t status = 0;
+ HAL_DisableSerialTermination(static_cast<HAL_SerialPort>(port), &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialSetReadBufferSize
+ * Signature: (BI)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialSetReadBufferSize
+ (JNIEnv* env, jclass, jbyte port, jint size)
+{
+ SERIALJNI_LOG(logDEBUG) << "Setting Serial Read Buffer Size";
+ SERIALJNI_LOG(logDEBUG) << "Size: " << size;
+ int32_t status = 0;
+ HAL_SetSerialReadBufferSize(static_cast<HAL_SerialPort>(port), size, &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialSetWriteBufferSize
+ * Signature: (BI)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialSetWriteBufferSize
+ (JNIEnv* env, jclass, jbyte port, jint size)
+{
+ SERIALJNI_LOG(logDEBUG) << "Setting Serial Write Buffer Size";
+ SERIALJNI_LOG(logDEBUG) << "Size: " << size;
+ int32_t status = 0;
+ HAL_SetSerialWriteBufferSize(static_cast<HAL_SerialPort>(port), size,
+ &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialGetBytesReceived
+ * Signature: (B)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialGetBytesReceived
+ (JNIEnv* env, jclass, jbyte port)
+{
+ SERIALJNI_LOG(logDEBUG) << "Serial Get Bytes Received";
+ int32_t status = 0;
+ jint retVal =
+ HAL_GetSerialBytesReceived(static_cast<HAL_SerialPort>(port), &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+ return retVal;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialRead
+ * Signature: (B[BI)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialRead
+ (JNIEnv* env, jclass, jbyte port, jbyteArray dataReceived, jint size)
+{
+ SERIALJNI_LOG(logDEBUG) << "Serial Read";
+ wpi::SmallVector<char, 128> recvBuf;
+ recvBuf.resize(size);
+ int32_t status = 0;
+ jint retVal = HAL_ReadSerial(static_cast<HAL_SerialPort>(port),
+ recvBuf.data(), size, &status);
+ env->SetByteArrayRegion(dataReceived, 0, size,
+ reinterpret_cast<const jbyte*>(recvBuf.data()));
+ SERIALJNI_LOG(logDEBUG) << "ReturnValue = " << retVal;
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+ return retVal;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialWrite
+ * Signature: (B[BI)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialWrite
+ (JNIEnv* env, jclass, jbyte port, jbyteArray dataToSend, jint size)
+{
+ SERIALJNI_LOG(logDEBUG) << "Serial Write";
+ int32_t status = 0;
+ jint retVal =
+ HAL_WriteSerial(static_cast<HAL_SerialPort>(port),
+ reinterpret_cast<const char*>(
+ JByteArrayRef(env, dataToSend).array().data()),
+ size, &status);
+ SERIALJNI_LOG(logDEBUG) << "ReturnValue = " << retVal;
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+ return retVal;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialFlush
+ * Signature: (B)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialFlush
+ (JNIEnv* env, jclass, jbyte port)
+{
+ SERIALJNI_LOG(logDEBUG) << "Serial Flush";
+ int32_t status = 0;
+ HAL_FlushSerial(static_cast<HAL_SerialPort>(port), &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialClear
+ * Signature: (B)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialClear
+ (JNIEnv* env, jclass, jbyte port)
+{
+ SERIALJNI_LOG(logDEBUG) << "Serial Clear";
+ int32_t status = 0;
+ HAL_ClearSerial(static_cast<HAL_SerialPort>(port), &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SerialPortJNI
+ * Method: serialClose
+ * Signature: (B)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SerialPortJNI_serialClose
+ (JNIEnv* env, jclass, jbyte port)
+{
+ SERIALJNI_LOG(logDEBUG) << "Serial Close";
+ int32_t status = 0;
+ HAL_CloseSerial(static_cast<HAL_SerialPort>(port), &status);
+ SERIALJNI_LOG(logDEBUG) << "Status = " << status;
+ CheckStatus(env, status);
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/SolenoidJNI.cpp b/hal/src/main/native/cpp/jni/SolenoidJNI.cpp
new file mode 100644
index 0000000..524b70e
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/SolenoidJNI.cpp
@@ -0,0 +1,242 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_SolenoidJNI.h"
+#include "hal/Ports.h"
+#include "hal/Solenoid.h"
+#include "hal/cpp/Log.h"
+#include "hal/handles/HandlesInternal.h"
+
+using namespace frc;
+
+TLogLevel solenoidJNILogLevel = logERROR;
+
+#define SOLENOIDJNI_LOG(level) \
+ if (level > solenoidJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: initializeSolenoidPort
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_initializeSolenoidPort
+ (JNIEnv* env, jclass, jint id)
+{
+ SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI initializeSolenoidPort";
+
+ SOLENOIDJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_PortHandle)id;
+
+ int32_t status = 0;
+ HAL_SolenoidHandle handle =
+ HAL_InitializeSolenoidPort((HAL_PortHandle)id, &status);
+
+ SOLENOIDJNI_LOG(logDEBUG) << "Status = " << status;
+ SOLENOIDJNI_LOG(logDEBUG) << "Solenoid Port Handle = " << handle;
+
+ // Use solenoid channels, as we have to pick one.
+ CheckStatusRange(env, status, 0, HAL_GetNumSolenoidChannels(),
+ hal::getPortHandleChannel((HAL_PortHandle)id));
+ return (jint)handle;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: checkSolenoidChannel
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_checkSolenoidChannel
+ (JNIEnv* env, jclass, jint channel)
+{
+ SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI checkSolenoidChannel";
+ SOLENOIDJNI_LOG(logDEBUG) << "Channel = " << channel;
+ return HAL_CheckSolenoidChannel(channel);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: checkSolenoidModule
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_checkSolenoidModule
+ (JNIEnv* env, jclass, jint module)
+{
+ SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI checkSolenoidModule";
+ SOLENOIDJNI_LOG(logDEBUG) << "Module = " << module;
+ return HAL_CheckSolenoidModule(module);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: freeSolenoidPort
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_freeSolenoidPort
+ (JNIEnv* env, jclass, jint id)
+{
+ SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI initializeSolenoidPort";
+
+ SOLENOIDJNI_LOG(logDEBUG) << "Port Handle = " << (HAL_SolenoidHandle)id;
+ HAL_FreeSolenoidPort((HAL_SolenoidHandle)id);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: setSolenoid
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_setSolenoid
+ (JNIEnv* env, jclass, jint solenoid_port, jboolean value)
+{
+ SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI SetSolenoid";
+
+ SOLENOIDJNI_LOG(logDEBUG)
+ << "Solenoid Port Handle = " << (HAL_SolenoidHandle)solenoid_port;
+
+ int32_t status = 0;
+ HAL_SetSolenoid((HAL_SolenoidHandle)solenoid_port, value, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: getSolenoid
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_getSolenoid
+ (JNIEnv* env, jclass, jint solenoid_port)
+{
+ int32_t status = 0;
+ jboolean val = HAL_GetSolenoid((HAL_SolenoidHandle)solenoid_port, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: getAllSolenoids
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_getAllSolenoids
+ (JNIEnv* env, jclass, jint module)
+{
+ int32_t status = 0;
+ jint val = HAL_GetAllSolenoids(module, &status);
+ CheckStatus(env, status);
+ return val;
+}
+
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: getPCMSolenoidBlackList
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_getPCMSolenoidBlackList
+ (JNIEnv* env, jclass, jint module)
+{
+ int32_t status = 0;
+ jint val = HAL_GetPCMSolenoidBlackList(module, &status);
+ CheckStatus(env, status);
+ return val;
+}
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: getPCMSolenoidVoltageStickyFault
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_getPCMSolenoidVoltageStickyFault
+ (JNIEnv* env, jclass, jint module)
+{
+ int32_t status = 0;
+ bool val = HAL_GetPCMSolenoidVoltageStickyFault(module, &status);
+ CheckStatus(env, status);
+ return val;
+}
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: getPCMSolenoidVoltageFault
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_getPCMSolenoidVoltageFault
+ (JNIEnv* env, jclass, jint module)
+{
+ int32_t status = 0;
+ bool val = HAL_GetPCMSolenoidVoltageFault(module, &status);
+ CheckStatus(env, status);
+ return val;
+}
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: clearAllPCMStickyFaults
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_clearAllPCMStickyFaults
+ (JNIEnv* env, jclass, jint module)
+{
+ int32_t status = 0;
+ HAL_ClearAllPCMStickyFaults(module, &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: setOneShotDuration
+ * Signature: (IJ)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_setOneShotDuration
+ (JNIEnv* env, jclass, jint solenoid_port, jlong durationMS)
+{
+ SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI SetOneShotDuration";
+
+ SOLENOIDJNI_LOG(logDEBUG)
+ << "Solenoid Port Handle = " << (HAL_SolenoidHandle)solenoid_port;
+ SOLENOIDJNI_LOG(logDEBUG) << "Duration (MS) = " << durationMS;
+
+ int32_t status = 0;
+ HAL_SetOneShotDuration((HAL_SolenoidHandle)solenoid_port, durationMS,
+ &status);
+ CheckStatus(env, status);
+}
+
+/*
+ * Class: edu_wpi_first_hal_SolenoidJNI
+ * Method: fireOneShot
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_edu_wpi_first_hal_SolenoidJNI_fireOneShot
+ (JNIEnv* env, jclass, jint solenoid_port)
+{
+ SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI fireOneShot";
+
+ SOLENOIDJNI_LOG(logDEBUG)
+ << "Solenoid Port Handle = " << (HAL_SolenoidHandle)solenoid_port;
+
+ int32_t status = 0;
+ HAL_FireOneShot((HAL_SolenoidHandle)solenoid_port, &status);
+ CheckStatus(env, status);
+}
+} // extern "C"
diff --git a/hal/src/main/native/cpp/jni/ThreadsJNI.cpp b/hal/src/main/native/cpp/jni/ThreadsJNI.cpp
new file mode 100644
index 0000000..ea3cac6
--- /dev/null
+++ b/hal/src/main/native/cpp/jni/ThreadsJNI.cpp
@@ -0,0 +1,80 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <cassert>
+
+#include "HALUtil.h"
+#include "edu_wpi_first_hal_ThreadsJNI.h"
+#include "hal/Threads.h"
+#include "hal/cpp/Log.h"
+
+using namespace frc;
+
+// set the logging level
+TLogLevel threadsJNILogLevel = logWARNING;
+
+#define THREADSJNI_LOG(level) \
+ if (level > threadsJNILogLevel) \
+ ; \
+ else \
+ Log().Get(level)
+
+extern "C" {
+/*
+ * Class: edu_wpi_first_hal_ThreadsJNI
+ * Method: getCurrentThreadPriority
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_edu_wpi_first_hal_ThreadsJNI_getCurrentThreadPriority
+ (JNIEnv* env, jclass)
+{
+ THREADSJNI_LOG(logDEBUG) << "Callling GetCurrentThreadPriority";
+ int32_t status = 0;
+ HAL_Bool isRT = false;
+ auto ret = HAL_GetCurrentThreadPriority(&isRT, &status);
+ CheckStatus(env, status);
+ return (jint)ret;
+}
+
+/*
+ * Class: edu_wpi_first_hal_ThreadsJNI
+ * Method: getCurrentThreadIsRealTime
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_ThreadsJNI_getCurrentThreadIsRealTime
+ (JNIEnv* env, jclass)
+{
+ THREADSJNI_LOG(logDEBUG) << "Callling GetCurrentThreadIsRealTime";
+ int32_t status = 0;
+ HAL_Bool isRT = false;
+ HAL_GetCurrentThreadPriority(&isRT, &status);
+ CheckStatus(env, status);
+ return (jboolean)isRT;
+}
+
+/*
+ * Class: edu_wpi_first_hal_ThreadsJNI
+ * Method: setCurrentThreadPriority
+ * Signature: (ZI)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_edu_wpi_first_hal_ThreadsJNI_setCurrentThreadPriority
+ (JNIEnv* env, jclass, jboolean realTime, jint priority)
+{
+ THREADSJNI_LOG(logDEBUG) << "Callling SetCurrentThreadPriority";
+ int32_t status = 0;
+ auto ret = HAL_SetCurrentThreadPriority(
+ (HAL_Bool)realTime, static_cast<int32_t>(priority), &status);
+ CheckStatus(env, status);
+ return (jboolean)ret;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/include/hal/Accelerometer.h b/hal/src/main/native/include/hal/Accelerometer.h
new file mode 100644
index 0000000..9dc488b
--- /dev/null
+++ b/hal/src/main/native/include/hal/Accelerometer.h
@@ -0,0 +1,79 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_accelerometer Accelerometer Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+// clang-format off
+/**
+ * The acceptable accelerometer ranges.
+ */
+HAL_ENUM(HAL_AccelerometerRange) {
+ HAL_AccelerometerRange_k2G = 0,
+ HAL_AccelerometerRange_k4G = 1,
+ HAL_AccelerometerRange_k8G = 2,
+};
+// clang-format on
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * Sets the accelerometer to active or standby mode.
+ *
+ * It must be in standby mode to change any configuration.
+ *
+ * @param active true to set to active, false for standby
+ */
+void HAL_SetAccelerometerActive(HAL_Bool active);
+
+/**
+ * Sets the range of values that can be measured (either 2, 4, or 8 g-forces).
+ *
+ * The accelerometer should be in standby mode when this is called.
+ *
+ * @param range the accelerometer range
+ */
+void HAL_SetAccelerometerRange(HAL_AccelerometerRange range);
+
+/**
+ * Gets the x-axis acceleration.
+ *
+ * This is a floating point value in units of 1 g-force.
+ *
+ * @return the X acceleration
+ */
+double HAL_GetAccelerometerX(void);
+
+/**
+ * Gets the y-axis acceleration.
+ *
+ * This is a floating point value in units of 1 g-force.
+ *
+ * @return the Y acceleration
+ */
+double HAL_GetAccelerometerY(void);
+
+/**
+ * Gets the z-axis acceleration.
+ *
+ * This is a floating point value in units of 1 g-force.
+ *
+ * @return the Z acceleration
+ */
+double HAL_GetAccelerometerZ(void);
+#ifdef __cplusplus
+} // extern "C"
+/** @} */
+#endif
diff --git a/hal/src/main/native/include/hal/AnalogAccumulator.h b/hal/src/main/native/include/hal/AnalogAccumulator.h
new file mode 100644
index 0000000..9e49e90
--- /dev/null
+++ b/hal/src/main/native/include/hal/AnalogAccumulator.h
@@ -0,0 +1,115 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_analogaccumulator Analog Accumulator Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Is the channel attached to an accumulator.
+ *
+ * @param analogPortHandle Handle to the analog port.
+ * @return The analog channel is attached to an accumulator.
+ */
+HAL_Bool HAL_IsAccumulatorChannel(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+
+/**
+ * Initialize the accumulator.
+ *
+ * @param analogPortHandle Handle to the analog port.
+ */
+void HAL_InitAccumulator(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+
+/**
+ * Resets the accumulator to the initial value.
+ *
+ * @param analogPortHandle Handle to the analog port.
+ */
+void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+
+/**
+ * Set the center value of the accumulator.
+ *
+ * The center value is subtracted from each A/D value before it is added to the
+ * accumulator. This is used for the center value of devices like gyros and
+ * accelerometers to make integration work and to take the device offset into
+ * account when integrating.
+ *
+ * This center value is based on the output of the oversampled and averaged
+ * source from channel 1. Because of this, any non-zero oversample bits will
+ * affect the size of the value for this field.
+ *
+ * @param analogPortHandle Handle to the analog port.
+ * @param center The center value of the accumulator.
+ */
+void HAL_SetAccumulatorCenter(HAL_AnalogInputHandle analogPortHandle,
+ int32_t center, int32_t* status);
+
+/**
+ * Set the accumulator's deadband.
+ *
+ * @param analogPortHandle Handle to the analog port.
+ * @param deadband The deadband of the accumulator.
+ */
+void HAL_SetAccumulatorDeadband(HAL_AnalogInputHandle analogPortHandle,
+ int32_t deadband, int32_t* status);
+
+/**
+ * Read the accumulated value.
+ *
+ * Read the value that has been accumulating on channel 1.
+ * The accumulator is attached after the oversample and average engine.
+ *
+ * @param analogPortHandle Handle to the analog port.
+ * @return The 64-bit value accumulated since the last Reset().
+ */
+int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+
+/**
+ * Read the number of accumulated values.
+ *
+ * Read the count of the accumulated values since the accumulator was last
+ * Reset().
+ *
+ * @param analogPortHandle Handle to the analog port.
+ * @return The number of times samples from the channel were accumulated.
+ */
+int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+
+/**
+ * Read the accumulated value and the number of accumulated values atomically.
+ *
+ * This function reads the value and count from the FPGA atomically.
+ * This can be used for averaging.
+ *
+ * @param analogPortHandle Handle to the analog port.
+ * @param value Pointer to the 64-bit accumulated output.
+ * @param count Pointer to the number of accumulation cycles.
+ */
+void HAL_GetAccumulatorOutput(HAL_AnalogInputHandle analogPortHandle,
+ int64_t* value, int64_t* count, int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/AnalogGyro.h b/hal/src/main/native/include/hal/AnalogGyro.h
new file mode 100644
index 0000000..54030bd
--- /dev/null
+++ b/hal/src/main/native/include/hal/AnalogGyro.h
@@ -0,0 +1,138 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_analoggyro Analog Gyro Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes an analog gyro.
+ *
+ * @param handle handle to the analog port
+ * @return the initialized gyro handle
+ */
+HAL_GyroHandle HAL_InitializeAnalogGyro(HAL_AnalogInputHandle handle,
+ int32_t* status);
+
+/**
+ * Sets up an analog gyro with the proper offsets and settings for the KOP
+ * analog gyro.
+ *
+ * @param handle the gyro handle
+ */
+void HAL_SetupAnalogGyro(HAL_GyroHandle handle, int32_t* status);
+
+/**
+ * Frees an analog gyro.
+ *
+ * @param handle the gyro handle
+ */
+void HAL_FreeAnalogGyro(HAL_GyroHandle handle);
+
+/**
+ * Sets the analog gyro parameters to the specified values.
+ *
+ * This is meant to be used if you want to reuse the values from a previous
+ * calibration.
+ *
+ * @param handle the gyro handle
+ * @param voltsPerDegreePerSecond the gyro volts scaling
+ * @param offset the gyro offset
+ * @param center the gyro center
+ */
+void HAL_SetAnalogGyroParameters(HAL_GyroHandle handle,
+ double voltsPerDegreePerSecond, double offset,
+ int32_t center, int32_t* status);
+
+/**
+ * Sets the analog gyro volts per degrees per second scaling.
+ *
+ * @param handle the gyro handle
+ * @param voltsPerDegreePerSecond the gyro volts scaling
+ */
+void HAL_SetAnalogGyroVoltsPerDegreePerSecond(HAL_GyroHandle handle,
+ double voltsPerDegreePerSecond,
+ int32_t* status);
+
+/**
+ * Resets the analog gyro value to 0.
+ *
+ * @param handle the gyro handle
+ */
+void HAL_ResetAnalogGyro(HAL_GyroHandle handle, int32_t* status);
+
+/**
+ * Calibrates the analog gyro.
+ *
+ * This happens by calculating the average value of the gyro over 5 seconds, and
+ * setting that as the center. Note that this call blocks for 5 seconds to
+ * perform this.
+ *
+ * @param handle the gyro handle
+ */
+void HAL_CalibrateAnalogGyro(HAL_GyroHandle handle, int32_t* status);
+
+/**
+ * Sets the deadband of the analog gyro.
+ *
+ * @param handle the gyro handle
+ * @param volts the voltage deadband
+ */
+void HAL_SetAnalogGyroDeadband(HAL_GyroHandle handle, double volts,
+ int32_t* status);
+
+/**
+ * Gets the gyro angle in degrees.
+ *
+ * @param handle the gyro handle
+ * @return the gyro angle in degrees
+ */
+double HAL_GetAnalogGyroAngle(HAL_GyroHandle handle, int32_t* status);
+
+/**
+ * Gets the gyro rate in degrees/second.
+ *
+ * @param handle the gyro handle
+ * @return the gyro rate in degrees/second
+ */
+double HAL_GetAnalogGyroRate(HAL_GyroHandle handle, int32_t* status);
+
+/**
+ * Gets the calibrated gyro offset.
+ *
+ * Can be used to not repeat a calibration but reconstruct the gyro object.
+ *
+ * @param handle the gyro handle
+ * @return the gryo offset
+ */
+double HAL_GetAnalogGyroOffset(HAL_GyroHandle handle, int32_t* status);
+
+/**
+ * Gets the calibrated gyro center.
+ *
+ * Can be used to not repeat a calibration but reconstruct the gyro object.
+ *
+ * @param handle the gyro handle
+ * @return the gyro center
+ */
+int32_t HAL_GetAnalogGyroCenter(HAL_GyroHandle handle, int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/AnalogInput.h b/hal/src/main/native/include/hal/AnalogInput.h
new file mode 100644
index 0000000..45e6662
--- /dev/null
+++ b/hal/src/main/native/include/hal/AnalogInput.h
@@ -0,0 +1,230 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_analoginput Analog Input Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes the analog input port using the given port object.
+ *
+ * @param portHandle Handle to the port to initialize.
+ * @return the created analog input handle
+ */
+HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
+ int32_t* status);
+
+/**
+ * Frees an analog input port.
+ *
+ * @param analogPortHandle Handle to the analog port.
+ */
+void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analogPortHandle);
+
+/**
+ * Checks that the analog module number is valid.
+ *
+ * @param module The analog module number.
+ * @return Analog module is valid and present
+ */
+HAL_Bool HAL_CheckAnalogModule(int32_t module);
+
+/**
+ * Checks that the analog output channel number is value.
+ * Verifies that the analog channel number is one of the legal channel numbers.
+ * Channel numbers are 0-based.
+ *
+ * @param channel The analog output channel number.
+ * @return Analog channel is valid
+ */
+HAL_Bool HAL_CheckAnalogInputChannel(int32_t channel);
+
+/**
+ * Sets the sample rate.
+ *
+ * This is a global setting for the Athena and effects all channels.
+ *
+ * @param samplesPerSecond The number of samples per channel per second.
+ */
+void HAL_SetAnalogSampleRate(double samplesPerSecond, int32_t* status);
+
+/**
+ * Gets the current sample rate.
+ *
+ * This assumes one entry in the scan list.
+ * This is a global setting for the Athena and effects all channels.
+ *
+ * @return Sample rate.
+ */
+double HAL_GetAnalogSampleRate(int32_t* status);
+
+/**
+ * Sets the number of averaging bits.
+ *
+ * This sets the number of averaging bits. The actual number of averaged samples
+ * is 2**bits. Use averaging to improve the stability of your measurement at the
+ * expense of sampling rate. The averaging is done automatically in the FPGA.
+ *
+ * @param analogPortHandle Handle to the analog port to configure.
+ * @param bits Number of bits to average.
+ */
+void HAL_SetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
+ int32_t bits, int32_t* status);
+
+/**
+ * Gets the number of averaging bits.
+ *
+ * This gets the number of averaging bits from the FPGA. The actual number of
+ * averaged samples is 2**bits. The averaging is done automatically in the FPGA.
+ *
+ * @param analogPortHandle Handle to the analog port to use.
+ * @return Bits to average.
+ */
+int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+
+/**
+ * Sets the number of oversample bits.
+ *
+ * This sets the number of oversample bits. The actual number of oversampled
+ * values is 2**bits. Use oversampling to improve the resolution of your
+ * measurements at the expense of sampling rate. The oversampling is done
+ * automatically in the FPGA.
+ *
+ * @param analogPortHandle Handle to the analog port to use.
+ * @param bits Number of bits to oversample.
+ */
+void HAL_SetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
+ int32_t bits, int32_t* status);
+
+/**
+ * Gets the number of oversample bits.
+ *
+ * This gets the number of oversample bits from the FPGA. The actual number of
+ * oversampled values is 2**bits. The oversampling is done automatically in the
+ * FPGA.
+ *
+ * @param analogPortHandle Handle to the analog port to use.
+ * @return Bits to oversample.
+ */
+int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+
+/**
+ * Gets a sample straight from the channel on this module.
+ *
+ * The sample is a 12-bit value representing the 0V to 5V range of the A/D
+ * converter in the module. The units are in A/D converter codes. Use
+ * GetVoltage() to get the analog value in calibrated units.
+ *
+ * @param analogPortHandle Handle to the analog port to use.
+ * @return A sample straight from the channel on this module.
+ */
+int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+
+/**
+ * Gets a sample from the output of the oversample and average engine for the
+ * channel.
+ *
+ * The sample is 12-bit + the value configured in SetOversampleBits().
+ * The value configured in SetAverageBits() will cause this value to be averaged
+ * 2**bits number of samples. This is not a sliding window. The sample will not
+ * change until 2**(OversamplBits + AverageBits) samples have been acquired from
+ * the module on this channel. Use GetAverageVoltage() to get the analog value
+ * in calibrated units.
+ *
+ * @param analogPortHandle Handle to the analog port to use.
+ * @return A sample from the oversample and average engine for the channel.
+ */
+int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+
+/**
+ * Converts a voltage to a raw value for a specified channel.
+ *
+ * This process depends on the calibration of each channel, so the channel must
+ * be specified.
+ *
+ * @todo This assumes raw values. Oversampling not supported as is.
+ *
+ * @param analogPortHandle Handle to the analog port to use.
+ * @param voltage The voltage to convert.
+ * @return The raw value for the channel.
+ */
+int32_t HAL_GetAnalogVoltsToValue(HAL_AnalogInputHandle analogPortHandle,
+ double voltage, int32_t* status);
+
+/**
+ * Gets a scaled sample straight from the channel on this module.
+ *
+ * The value is scaled to units of Volts using the calibrated scaling data from
+ * GetLSBWeight() and GetOffset().
+ *
+ * @param analogPortHandle Handle to the analog port to use.
+ * @return A scaled sample straight from the channel on this module.
+ */
+double HAL_GetAnalogVoltage(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+
+/**
+ * Gets a scaled sample from the output of the oversample and average engine for
+ * the channel.
+ *
+ * The value is scaled to units of Volts using the calibrated scaling data from
+ * GetLSBWeight() and GetOffset(). Using oversampling will cause this value to
+ * be higher resolution, but it will update more slowly. Using averaging will
+ * cause this value to be more stable, but it will update more slowly.
+ *
+ * @param analogPortHandle Handle to the analog port to use.
+ * @return A scaled sample from the output of the oversample and average engine
+ * for the channel.
+ */
+double HAL_GetAnalogAverageVoltage(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+
+/**
+ * Gets the factory scaling least significant bit weight constant.
+ * The least significant bit weight constant for the channel that was calibrated
+ * in manufacturing and stored in an eeprom in the module.
+ *
+ * Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
+ *
+ * @param analogPortHandle Handle to the analog port to use.
+ * @return Least significant bit weight.
+ */
+int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+
+/**
+ * Gets the factory scaling offset constant.
+ * The offset constant for the channel that was calibrated in manufacturing and
+ * stored in an eeprom in the module.
+ *
+ * Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
+ *
+ * @param analogPortHandle Handle to the analog port to use.
+ * @return Offset constant.
+ */
+int32_t HAL_GetAnalogOffset(HAL_AnalogInputHandle analogPortHandle,
+ int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/AnalogOutput.h b/hal/src/main/native/include/hal/AnalogOutput.h
new file mode 100644
index 0000000..ba0d93b
--- /dev/null
+++ b/hal/src/main/native/include/hal/AnalogOutput.h
@@ -0,0 +1,70 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_analogoutput Analog Output Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes the analog output port using the given port object.
+ *
+ * @param handle handle to the port
+ * @return the created analog output handle
+ */
+HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
+ int32_t* status);
+
+/**
+ * Frees an analog output port.
+ *
+ * @param analogOutputHandle the analog output handle
+ */
+void HAL_FreeAnalogOutputPort(HAL_AnalogOutputHandle analogOutputHandle);
+
+/**
+ * Sets an analog output value.
+ *
+ * @param analogOutputHandle the analog output handle
+ * @param voltage the voltage (0-5v) to output
+ */
+void HAL_SetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
+ double voltage, int32_t* status);
+
+/**
+ * Gets the current analog output value.
+ *
+ * @param analogOutputHandle the analog output handle
+ * @return the current output voltage (0-5v)
+ */
+double HAL_GetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
+ int32_t* status);
+
+/**
+ * Checks that the analog output channel number is value.
+ *
+ * Verifies that the analog channel number is one of the legal channel numbers.
+ * Channel numbers are 0-based.
+ *
+ * @return Analog channel is valid
+ */
+HAL_Bool HAL_CheckAnalogOutputChannel(int32_t channel);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/AnalogTrigger.h b/hal/src/main/native/include/hal/AnalogTrigger.h
new file mode 100644
index 0000000..f461f1d
--- /dev/null
+++ b/hal/src/main/native/include/hal/AnalogTrigger.h
@@ -0,0 +1,143 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_analogtrigger Analog Trigger Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+// clang-format off
+/**
+ * The type of analog trigger to trigger on.
+ */
+HAL_ENUM(HAL_AnalogTriggerType) {
+ HAL_Trigger_kInWindow = 0,
+ HAL_Trigger_kState = 1,
+ HAL_Trigger_kRisingPulse = 2,
+ HAL_Trigger_kFallingPulse = 3
+};
+// clang-format on
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes an analog trigger.
+ *
+ * @param portHandle the analog input to use for triggering
+ * @param index the trigger index value (output)
+ * @return the created analog trigger handle
+ */
+HAL_AnalogTriggerHandle HAL_InitializeAnalogTrigger(
+ HAL_AnalogInputHandle portHandle, int32_t* index, int32_t* status);
+
+/**
+ * Frees an analog trigger.
+ *
+ * @param analogTriggerHandle the trigger handle
+ */
+void HAL_CleanAnalogTrigger(HAL_AnalogTriggerHandle analogTriggerHandle,
+ int32_t* status);
+
+/**
+ * Sets the raw ADC upper and lower limits of the analog trigger.
+ *
+ * HAL_SetAnalogTriggerLimitsVoltage is likely better in most cases.
+ *
+ * @param analogTriggerHandle the trigger handle
+ * @param lower the lower ADC value
+ * @param upper the upper ADC value
+ */
+void HAL_SetAnalogTriggerLimitsRaw(HAL_AnalogTriggerHandle analogTriggerHandle,
+ int32_t lower, int32_t upper,
+ int32_t* status);
+
+/**
+ * Sets the upper and lower limits of the analog trigger.
+ *
+ * The limits are given as floating point voltage values.
+ *
+ * @param analogTriggerHandle the trigger handle
+ * @param lower the lower voltage value
+ * @param upper the upper voltage value
+ */
+void HAL_SetAnalogTriggerLimitsVoltage(
+ HAL_AnalogTriggerHandle analogTriggerHandle, double lower, double upper,
+ int32_t* status);
+
+/**
+ * Configures the analog trigger to use the averaged vs. raw values.
+ *
+ * If the value is true, then the averaged value is selected for the analog
+ * trigger, otherwise the immediate value is used.
+ *
+ * @param analogTriggerHandle the trigger handle
+ * @param useAveragedValue true to use averaged values, false for raw
+ */
+void HAL_SetAnalogTriggerAveraged(HAL_AnalogTriggerHandle analogTriggerHandle,
+ HAL_Bool useAveragedValue, int32_t* status);
+
+/**
+ * Configures the analog trigger to use a filtered value.
+ *
+ * The analog trigger will operate with a 3 point average rejection filter. This
+ * is designed to help with 360 degree pot applications for the period where the
+ * pot crosses through zero.
+ *
+ * @param analogTriggerHandle the trigger handle
+ * @param useFilteredValue true to use filtered values, false for average or
+ * raw
+ */
+void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
+ HAL_Bool useFilteredValue, int32_t* status);
+
+/**
+ * Returns the InWindow output of the analog trigger.
+ *
+ * True if the analog input is between the upper and lower limits.
+ *
+ * @param analogTriggerHandle the trigger handle
+ * @return the InWindow output of the analog trigger
+ */
+HAL_Bool HAL_GetAnalogTriggerInWindow(
+ HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status);
+
+/**
+ * Returns the TriggerState output of the analog trigger.
+ *
+ * True if above upper limit.
+ * False if below lower limit.
+ * If in Hysteresis, maintain previous state.
+ *
+ * @param analogTriggerHandle the trigger handle
+ * @return the TriggerState output of the analog trigger
+ */
+HAL_Bool HAL_GetAnalogTriggerTriggerState(
+ HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status);
+
+/**
+ * Gets the state of the analog trigger output.
+ *
+ * @param analogTriggerHandle the trigger handle
+ * @param type the type of trigger to trigger on
+ * @return the state of the analog trigger output
+ */
+HAL_Bool HAL_GetAnalogTriggerOutput(HAL_AnalogTriggerHandle analogTriggerHandle,
+ HAL_AnalogTriggerType type,
+ int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/CAN.h b/hal/src/main/native/include/hal/CAN.h
new file mode 100644
index 0000000..8cc9c17
--- /dev/null
+++ b/hal/src/main/native/include/hal/CAN.h
@@ -0,0 +1,124 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_canstream CAN Stream Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+// These are copies of defines located in CANSessionMux.h prepended with HAL_
+
+#define HAL_CAN_SEND_PERIOD_NO_REPEAT 0
+#define HAL_CAN_SEND_PERIOD_STOP_REPEATING -1
+
+/* Flags in the upper bits of the messageID */
+#define HAL_CAN_IS_FRAME_REMOTE 0x80000000
+#define HAL_CAN_IS_FRAME_11BIT 0x40000000
+
+#define HAL_ERR_CANSessionMux_InvalidBuffer -44086
+#define HAL_ERR_CANSessionMux_MessageNotFound -44087
+#define HAL_WARN_CANSessionMux_NoToken 44087
+#define HAL_ERR_CANSessionMux_NotAllowed -44088
+#define HAL_ERR_CANSessionMux_NotInitialized -44089
+#define HAL_ERR_CANSessionMux_SessionOverrun 44050
+
+/**
+ * Storage for CAN Stream Messages.
+ */
+struct HAL_CANStreamMessage {
+ uint32_t messageID;
+ uint32_t timeStamp;
+ uint8_t data[8];
+ uint8_t dataSize;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Sends a CAN message.
+ *
+ * @param messageID the CAN ID to send
+ * @param data the data to send (0-8 bytes)
+ * @param dataSize the size of the data to send (0-8 bytes)
+ * @param periodMs the period to repeat the packet at. Use
+ * HAL_CAN_SEND_PERIOD_NO_REPEAT to not repeat.
+ */
+void HAL_CAN_SendMessage(uint32_t messageID, const uint8_t* data,
+ uint8_t dataSize, int32_t periodMs, int32_t* status);
+
+/**
+ * Receives a CAN message.
+ *
+ * @param messageID store for the received message ID
+ * @param messageIDMask the message ID mask to look for
+ * @param data data output (8 bytes)
+ * @param dataSize data length (0-8 bytes)
+ * @param timeStamp the packet received timestamp (based off of
+ * CLOCK_MONOTONIC)
+ */
+void HAL_CAN_ReceiveMessage(uint32_t* messageID, uint32_t messageIDMask,
+ uint8_t* data, uint8_t* dataSize,
+ uint32_t* timeStamp, int32_t* status);
+
+/**
+ * Opens a CAN stream.
+ *
+ * @param sessionHandle output for the session handle
+ * @param messageID the message ID to read
+ * @param messageIDMask the mssage ID mask
+ * @param maxMessages the maximum number of messages to stream
+ */
+void HAL_CAN_OpenStreamSession(uint32_t* sessionHandle, uint32_t messageID,
+ uint32_t messageIDMask, uint32_t maxMessages,
+ int32_t* status);
+
+/**
+ * Closes a CAN stream.
+ *
+ * @param sessionHandle the session to close
+ */
+void HAL_CAN_CloseStreamSession(uint32_t sessionHandle);
+
+/**
+ * Reads a CAN stream message.
+ *
+ * @param sessionHandle the session handle
+ * @param messages array of messages
+ * @param messagesToRead the max number of messages to read
+ * @param messageRead the number of messages actually read
+ */
+void HAL_CAN_ReadStreamSession(uint32_t sessionHandle,
+ struct HAL_CANStreamMessage* messages,
+ uint32_t messagesToRead, uint32_t* messagesRead,
+ int32_t* status);
+
+/**
+ * Gets CAN status information.
+ *
+ * @param percentBusUtilization the bus utilization
+ * @param busOffCount the number of bus off errors
+ * @param txFullCount the number of tx full errors
+ * @param receiveErrorCount the number of receive errors
+ * @param transmitErrorCount the number of transmit errors
+ */
+void HAL_CAN_GetCANStatus(float* percentBusUtilization, uint32_t* busOffCount,
+ uint32_t* txFullCount, uint32_t* receiveErrorCount,
+ uint32_t* transmitErrorCount, int32_t* status);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/CANAPI.h b/hal/src/main/native/include/hal/CANAPI.h
new file mode 100644
index 0000000..48c254d
--- /dev/null
+++ b/hal/src/main/native/include/hal/CANAPI.h
@@ -0,0 +1,162 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <stdint.h>
+
+#include "hal/CANAPITypes.h"
+#include "hal/Types.h"
+
+/**
+ * @defgroup hal_canapi CAN API Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes a CAN device.
+ *
+ * These follow the FIRST standard CAN layout. Link TBD
+ *
+ * @param manufacturer the can manufacturer
+ * @param deviceId the device ID (0-63)
+ * @param deviceType the device type
+ * @return the created CAN handle
+ */
+HAL_CANHandle HAL_InitializeCAN(HAL_CANManufacturer manufacturer,
+ int32_t deviceId, HAL_CANDeviceType deviceType,
+ int32_t* status);
+
+/**
+ * Frees a CAN device
+ *
+ * @param handle the CAN handle
+ */
+void HAL_CleanCAN(HAL_CANHandle handle);
+
+/**
+ * Writes a packet to the CAN device with a specific ID.
+ *
+ * This ID is 10 bits.
+ *
+ * @param handle the CAN handle
+ * @param data the data to write (0-8 bytes)
+ * @param length the length of data (0-8)
+ * @param apiId the ID to write (0-1023 bits)
+ */
+void HAL_WriteCANPacket(HAL_CANHandle handle, const uint8_t* data,
+ int32_t length, int32_t apiId, int32_t* status);
+
+/**
+ * Writes a repeating packet to the CAN device with a specific ID.
+ *
+ * This ID is 10 bits.
+ *
+ * The RoboRIO will automatically repeat the packet at the specified interval
+ *
+ * @param handle the CAN handle
+ * @param data the data to write (0-8 bytes)
+ * @param length the length of data (0-8)
+ * @param apiId the ID to write (0-1023)
+ * @param repeatMs the period to repeat in ms
+ */
+void HAL_WriteCANPacketRepeating(HAL_CANHandle handle, const uint8_t* data,
+ int32_t length, int32_t apiId,
+ int32_t repeatMs, int32_t* status);
+
+/**
+ * Stops a repeating packet with a specific ID.
+ *
+ * This ID is 10 bits.
+ *
+ * @param handle the CAN handle
+ * @param apiId the ID to stop repeating (0-1023)
+ */
+void HAL_StopCANPacketRepeating(HAL_CANHandle handle, int32_t apiId,
+ int32_t* status);
+
+/**
+ * Reads a new CAN packet.
+ *
+ * This will only return properly once per packet received. Multiple calls
+ * without receiving another packet will return an error code.
+ *
+ * @param handle the CAN handle
+ * @param apiId the ID to read (0-1023)
+ * @param data the packet data (8 bytes)
+ * @param length the received length (0-8 bytes)
+ * @param receivedTimestamp the packet received timestamp (based off of
+ * CLOCK_MONOTONIC)
+ */
+void HAL_ReadCANPacketNew(HAL_CANHandle handle, int32_t apiId, uint8_t* data,
+ int32_t* length, uint64_t* receivedTimestamp,
+ int32_t* status);
+
+/**
+ * Reads a CAN packet. The will continuously return the last packet received,
+ * without accounting for packet age.
+ *
+ * @param handle the CAN handle
+ * @param apiId the ID to read (0-1023)
+ * @param data the packet data (8 bytes)
+ * @param length the received length (0-8 bytes)
+ * @param receivedTimestamp the packet received timestamp (based off of
+ * CLOCK_MONOTONIC)
+ */
+void HAL_ReadCANPacketLatest(HAL_CANHandle handle, int32_t apiId, uint8_t* data,
+ int32_t* length, uint64_t* receivedTimestamp,
+ int32_t* status);
+
+/**
+ * Reads a CAN packet. The will return the last packet received until the
+ * packet is older then the requested timeout. Then it will return an error
+ * code.
+ *
+ * @param handle the CAN handle
+ * @param apiId the ID to read (0-1023)
+ * @param data the packet data (8 bytes)
+ * @param length the received length (0-8 bytes)
+ * @param receivedTimestamp the packet received timestamp (based off of
+ * CLOCK_MONOTONIC)
+ * @param timeoutMs the timeout time for the packet
+ */
+void HAL_ReadCANPacketTimeout(HAL_CANHandle handle, int32_t apiId,
+ uint8_t* data, int32_t* length,
+ uint64_t* receivedTimestamp, int32_t timeoutMs,
+ int32_t* status);
+
+/**
+ * Reads a CAN packet. The will return the last packet received until the
+ * packet is older then the requested timeout. Then it will return an error
+ * code. The period parameter is used when you know the packet is sent at
+ * specific intervals, so calls will not attempt to read a new packet from the
+ * network until that period has passed. We do not recommend users use this
+ * API unless they know the implications.
+ *
+ * @param handle the CAN handle
+ * @param apiId the ID to read (0-1023)
+ * @param data the packet data (8 bytes)
+ * @param length the received length (0-8 bytes)
+ * @param receivedTimestamp the packet received timestamp (based off of
+ * CLOCK_MONOTONIC)
+ * @param timeoutMs the timeout time for the packet
+ * @param periodMs the standard period for the packet
+ */
+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);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/CANAPITypes.h b/hal/src/main/native/include/hal/CANAPITypes.h
new file mode 100644
index 0000000..4bf98bd
--- /dev/null
+++ b/hal/src/main/native/include/hal/CANAPITypes.h
@@ -0,0 +1,56 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <stdint.h>
+
+#include "hal/Types.h"
+
+/**
+ * @defgroup hal_canapi CAN API Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+// clang-format off
+/**
+ * The CAN device type.
+ *
+ * Teams should use HAL_CAN_Dev_kMiscellaneous
+ */
+HAL_ENUM(HAL_CANDeviceType) {
+ HAL_CAN_Dev_kBroadcast = 0,
+ HAL_CAN_Dev_kRobotController = 1,
+ HAL_CAN_Dev_kMotorController = 2,
+ HAL_CAN_Dev_kRelayController = 3,
+ HAL_CAN_Dev_kGyroSensor = 4,
+ HAL_CAN_Dev_kAccelerometer = 5,
+ HAL_CAN_Dev_kUltrasonicSensor = 6,
+ HAL_CAN_Dev_kGearToothSensor = 7,
+ HAL_CAN_Dev_kPowerDistribution = 8,
+ HAL_CAN_Dev_kPneumatics = 9,
+ HAL_CAN_Dev_kMiscellaneous = 10,
+ HAL_CAN_Dev_kFirmwareUpdate = 31
+};
+
+/**
+ * The CAN manufacturer ID.
+ *
+ * Teams should use HAL_CAN_Man_kTeamUse.
+ */
+HAL_ENUM(HAL_CANManufacturer) {
+ HAL_CAN_Man_kBroadcast = 0,
+ HAL_CAN_Man_kNI = 1,
+ HAL_CAN_Man_kLM = 2,
+ HAL_CAN_Man_kDEKA = 3,
+ HAL_CAN_Man_kCTRE = 4,
+ HAL_CAN_Man_kMS = 7,
+ HAL_CAN_Man_kTeamUse = 8,
+};
+// clang-format on
+/** @} */
diff --git a/hal/src/main/native/include/hal/ChipObject.h b/hal/src/main/native/include/hal/ChipObject.h
new file mode 100644
index 0000000..878595b
--- /dev/null
+++ b/hal/src/main/native/include/hal/ChipObject.h
@@ -0,0 +1,46 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+
+#include <stdint.h>
+
+#include <FRC_FPGA_ChipObject/RoboRIO_FRC_ChipObject_Aliases.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/nInterfaceGlobals.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAI.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAO.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAccel.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAccumulator.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAlarm.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAnalogTrigger.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tBIST.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tCounter.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tDIO.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tDMA.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tEncoder.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tGlobal.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tInterrupt.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tPWM.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tPower.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tRelay.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tSPI.h>
+#include <FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tSysWatchdog.h>
+#include <FRC_FPGA_ChipObject/tDMAChannelDescriptor.h>
+#include <FRC_FPGA_ChipObject/tDMAManager.h>
+#include <FRC_FPGA_ChipObject/tInterruptManager.h>
+#include <FRC_FPGA_ChipObject/tSystem.h>
+#include <FRC_FPGA_ChipObject/tSystemInterface.h>
+
+namespace hal {
+using namespace nFPGA;
+using namespace nRoboRIO_FPGANamespace;
+} // namespace hal
+
+#pragma GCC diagnostic pop
diff --git a/hal/src/main/native/include/hal/Compressor.h b/hal/src/main/native/include/hal/Compressor.h
new file mode 100644
index 0000000..cb58e46
--- /dev/null
+++ b/hal/src/main/native/include/hal/Compressor.h
@@ -0,0 +1,143 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_compressor Compressor Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes a compressor on the given PCM module.
+ *
+ * @param module the module number
+ * @return the created handle
+ */
+HAL_CompressorHandle HAL_InitializeCompressor(int32_t module, int32_t* status);
+
+/**
+ * Gets if a compressor module is valid.
+ *
+ * @param module the module number
+ * @return true if the module is valid, otherwise false
+ */
+HAL_Bool HAL_CheckCompressorModule(int32_t module);
+
+/**
+ * Gets the compressor state (on or off).
+ *
+ * @param compressorHandle the compressor handle
+ * @return true if the compressor is on, otherwise false
+ */
+HAL_Bool HAL_GetCompressor(HAL_CompressorHandle compressorHandle,
+ int32_t* status);
+
+/**
+ * Sets the compressor to closed loop mode.
+ *
+ * @param compressorHandle the compressor handle
+ * @param value true for closed loop mode, false for off
+ */
+void HAL_SetCompressorClosedLoopControl(HAL_CompressorHandle compressorHandle,
+ HAL_Bool value, int32_t* status);
+
+/**
+ * Gets if the compressor is in closed loop mode.
+ *
+ * @param compressorHandle the compressor handle
+ * @return true if the compressor is in closed loop mode,
+ * otherwise false
+ */
+HAL_Bool HAL_GetCompressorClosedLoopControl(
+ HAL_CompressorHandle compressorHandle, int32_t* status);
+
+/**
+ * Gets the compressor pressure switch state.
+ *
+ * @param compressorHandle the compressor handle
+ * @return true if the pressure switch is triggered, otherwise
+ * false
+ */
+HAL_Bool HAL_GetCompressorPressureSwitch(HAL_CompressorHandle compressorHandle,
+ int32_t* status);
+
+/**
+ * Gets the compressor current.
+ *
+ * @param compressorHandle the compressor handle
+ * @return the compressor current in amps
+ */
+double HAL_GetCompressorCurrent(HAL_CompressorHandle compressorHandle,
+ int32_t* status);
+
+/**
+ * Gets if the compressor is faulted because of too high of current.
+ *
+ * @param compressorHandle the compressor handle
+ * @return true if falted, otherwise false
+ */
+HAL_Bool HAL_GetCompressorCurrentTooHighFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status);
+
+/**
+ * Gets if a sticky fauly is triggered because of too high of current.
+ *
+ * @param compressorHandle the compressor handle
+ * @return true if falted, otherwise false
+ */
+HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status);
+
+/**
+ * Gets if a sticky fauly is triggered because of a short.
+ *
+ * @param compressorHandle the compressor handle
+ * @return true if falted, otherwise false
+ */
+HAL_Bool HAL_GetCompressorShortedStickyFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status);
+
+/**
+ * Gets if the compressor is faulted because of a short.
+ *
+ * @param compressorHandle the compressor handle
+ * @return true if shorted, otherwise false
+ */
+HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressorHandle,
+ int32_t* status);
+
+/**
+ * Gets if a sticky fault is triggered of the compressor not connected.
+ *
+ * @param compressorHandle the compressor handle
+ * @return true if falted, otherwise false
+ */
+HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status);
+
+/**
+ * Gets if the compressor is not connected.
+ *
+ * @param compressorHandle the compressor handle
+ * @return true if not connected, otherwise false
+ */
+HAL_Bool HAL_GetCompressorNotConnectedFault(
+ HAL_CompressorHandle compressorHandle, int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/Constants.h b/hal/src/main/native/include/hal/Constants.h
new file mode 100644
index 0000000..2a4d409
--- /dev/null
+++ b/hal/src/main/native/include/hal/Constants.h
@@ -0,0 +1,31 @@
+/*----------------------------------------------------------------------------*/
+/* 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>
+
+/**
+ * @defgroup hal_constants Constants Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Gets the number of FPGA system clock ticks per microsecond.
+ *
+ * @return the number of clock ticks per microsecond
+ */
+int32_t HAL_GetSystemClockTicksPerMicrosecond(void);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/Counter.h b/hal/src/main/native/include/hal/Counter.h
new file mode 100644
index 0000000..c0dd057
--- /dev/null
+++ b/hal/src/main/native/include/hal/Counter.h
@@ -0,0 +1,307 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/AnalogTrigger.h"
+#include "hal/Types.h"
+
+/**
+ * @defgroup hal_counter Counter Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+// clang-format off
+/**
+ * The counter mode.
+ */
+HAL_ENUM(HAL_Counter_Mode) {
+ HAL_Counter_kTwoPulse = 0,
+ HAL_Counter_kSemiperiod = 1,
+ HAL_Counter_kPulseLength = 2,
+ HAL_Counter_kExternalDirection = 3
+};
+// clang-format on
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes a counter.
+ *
+ * @param mode the counter mode
+ * @param index the compressor index (output)
+ * @return the created handle
+ */
+HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index,
+ int32_t* status);
+
+/**
+ * Frees a counter.
+ *
+ * @param counterHandle the counter handle
+ */
+void HAL_FreeCounter(HAL_CounterHandle counterHandle, int32_t* status);
+
+/**
+ * Sets the average sample size of a counter.
+ *
+ * @param counterHandle the counter handle
+ * @param size the size of samples to average
+ */
+void HAL_SetCounterAverageSize(HAL_CounterHandle counterHandle, int32_t size,
+ int32_t* status);
+
+/**
+ * Sets the source object that causes the counter to count up.
+ *
+ * @param counterHandle the counter handle
+ * @param digitalSourceHandle the digital source handle (either a
+ * HAL_AnalogTriggerHandle of a HAL_DigitalHandle)
+ * @param analogTriggerType the analog trigger type if the source is an analog
+ * trigger
+ */
+void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ int32_t* status);
+
+/**
+ * Sets the up source to either detect rising edges or falling edges.
+ *
+ * Note that both are allowed to be set true at the same time without issues.
+ *
+ * @param counterHandle the counter handle
+ * @param risingEdge true to trigger on rising
+ * @param fallingEdge true to trigger on falling
+ */
+void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
+ HAL_Bool risingEdge, HAL_Bool fallingEdge,
+ int32_t* status);
+
+/**
+ * Disables the up counting source to the counter.
+ *
+ * @param counterHandle the counter handle
+ */
+void HAL_ClearCounterUpSource(HAL_CounterHandle counterHandle, int32_t* status);
+
+/**
+ * Sets the source object that causes the counter to count down.
+ *
+ * @param counterHandle the counter handle
+ * @param digitalSourceHandle the digital source handle (either a
+ * HAL_AnalogTriggerHandle of a HAL_DigitalHandle)
+ * @param analogTriggerType the analog trigger type if the source is an analog
+ * trigger
+ */
+void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ int32_t* status);
+
+/**
+ * Sets the down source to either detect rising edges or falling edges.
+ * Note that both are allowed to be set true at the same time without issues.
+ *
+ * @param counterHandle the counter handle
+ * @param risingEdge true to trigger on rising
+ * @param fallingEdge true to trigger on falling
+ */
+void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
+ HAL_Bool risingEdge, HAL_Bool fallingEdge,
+ int32_t* status);
+
+/**
+ * Disables the down counting source to the counter.
+ *
+ * @param counterHandle the counter handle
+ */
+void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
+ int32_t* status);
+
+/**
+ * Sets standard up / down counting mode on this counter.
+ *
+ * Up and down counts are sourced independently from two inputs.
+ *
+ * @param counterHandle the counter handle
+ */
+void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle, int32_t* status);
+
+/**
+ * Sets directional counting mode on this counter.
+ *
+ * The direction is determined by the B input, with counting happening with the
+ * A input.
+ *
+ * @param counterHandle the counter handle
+ */
+void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
+ int32_t* status);
+
+/**
+ * Sets Semi-period mode on this counter.
+ *
+ * The counter counts up based on the time the input is triggered. High or Low
+ * depends on the highSemiPeriod parameter.
+ *
+ * @param counterHandle the counter handle
+ * @param highSemiPeriod true for counting when the input is high, false for low
+ */
+void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
+ HAL_Bool highSemiPeriod, int32_t* status);
+
+/**
+ * Configures the counter to count in up or down based on the length of the
+ * input pulse.
+ *
+ * This mode is most useful for direction sensitive gear tooth sensors.
+ *
+ * @param counterHandle the counter handle
+ * @param threshold The pulse length beyond which the counter counts the
+ * opposite direction (seconds)
+ */
+void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
+ double threshold, int32_t* status);
+
+/**
+ * Gets the Samples to Average which specifies the number of samples of the
+ * timer to average when calculating the period. Perform averaging to account
+ * for mechanical imperfections or as oversampling to increase resolution.
+ *
+ * @param counterHandle the counter handle
+ * @return SamplesToAverage The number of samples being averaged (from 1 to 127)
+ */
+int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
+ int32_t* status);
+
+/**
+ * Sets the Samples to Average which specifies the number of samples of the
+ * timer to average when calculating the period. Perform averaging to account
+ * for mechanical imperfections or as oversampling to increase resolution.
+ *
+ * @param counterHandle the counter handle
+ * @param samplesToAverage The number of samples to average from 1 to 127
+ */
+void HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
+ int32_t samplesToAverage, int32_t* status);
+
+/**
+ * Resets the Counter to zero.
+ *
+ * Sets the counter value to zero. This does not effect the running state of the
+ * counter, just sets the current value to zero.
+ *
+ * @param counterHandle the counter handle
+ */
+void HAL_ResetCounter(HAL_CounterHandle counterHandle, int32_t* status);
+
+/**
+ * Reads the current counter value.
+ *
+ * Reads the value at this instant. It may still be running, so it reflects the
+ * current value. Next time it is read, it might have a different value.
+ *
+ * @param counterHandle the counter handle
+ * @return the current counter value
+ */
+int32_t HAL_GetCounter(HAL_CounterHandle counterHandle, int32_t* status);
+
+/*
+ * Gets the Period of the most recent count.
+ *
+ * Returns the time interval of the most recent count. This can be used for
+ * velocity calculations to determine shaft speed.
+ *
+ * @param counterHandle the counter handle
+ * @returns the period of the last two pulses in units of seconds
+ */
+double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status);
+
+/**
+ * Sets the maximum period where the device is still considered "moving".
+ *
+ * Sets the maximum period where the device is considered moving. This value is
+ * used to determine the "stopped" state of the counter using the
+ * HAL_GetCounterStopped method.
+ *
+ * @param counterHandle the counter handle
+ * @param maxPeriod the maximum period where the counted device is
+ * considered moving in seconds
+ */
+void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
+ int32_t* status);
+
+/**
+ * Selects whether you want to continue updating the event timer output when
+ * there are no samples captured.
+ *
+ * The output of the event timer has a buffer of periods that are averaged and
+ * posted to a register on the FPGA. When the timer detects that the event
+ * source has stopped (based on the MaxPeriod) the buffer of samples to be
+ * averaged is emptied.
+ *
+ * If you enable the update when empty, you will be
+ * notified of the stopped source and the event time will report 0 samples.
+ *
+ * If you disable update when empty, the most recent average will remain on the
+ * output until a new sample is acquired.
+ *
+ * You will never see 0 samples output (except when there have been no events
+ * since an FPGA reset) and you will likely not see the stopped bit become true
+ * (since it is updated at the end of an average and there are no samples to
+ * average).
+ *
+ * @param counterHandle the counter handle
+ * @param enabled true to enable counter updating with no samples
+ */
+void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
+ HAL_Bool enabled, int32_t* status);
+
+/**
+ * Determines if the clock is stopped.
+ *
+ * Determine if the clocked input is stopped based on the MaxPeriod value set
+ * using the SetMaxPeriod method. If the clock exceeds the MaxPeriod, then the
+ * device (and counter) are assumed to be stopped and it returns true.
+ *
+ * @param counterHandle the counter handle
+ * @return true if the most recent counter period exceeds the
+ * MaxPeriod value set by SetMaxPeriod
+ */
+HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
+ int32_t* status);
+
+/**
+ * Gets the last direction the counter value changed.
+ *
+ * @param counterHandle the counter handle
+ * @return the last direction the counter value changed
+ */
+HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
+ int32_t* status);
+
+/**
+ * Sets the Counter to return reversed sensing on the direction.
+ *
+ * This allows counters to change the direction they are counting in the case of
+ * 1X and 2X quadrature encoding only. Any other counter mode isn't supported.
+ *
+ * @param counterHandle the counter handle
+ * @param reverseDirection true if the value counted should be negated.
+ */
+void HAL_SetCounterReverseDirection(HAL_CounterHandle counterHandle,
+ HAL_Bool reverseDirection, int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/DIO.h b/hal/src/main/native/include/hal/DIO.h
new file mode 100644
index 0000000..7812306
--- /dev/null
+++ b/hal/src/main/native/include/hal/DIO.h
@@ -0,0 +1,200 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_dio DIO Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Creates a new instance of a digital port.
+ *
+ * @param portHandle the port handle to create from
+ * @param input true for input, false for output
+ * @return the created digital handle
+ */
+HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
+ HAL_Bool input, int32_t* status);
+
+/**
+ * Checks if a DIO channel is valid.
+ *
+ * @param channel the channel number to check
+ * @return true if the channel is correct, otherwise false
+ */
+HAL_Bool HAL_CheckDIOChannel(int32_t channel);
+
+void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle);
+
+/**
+ * Allocates a DO PWM Generator.
+ *
+ * @return the allocated digital PWM handle
+ */
+HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status);
+
+/**
+ * Frees the resource associated with a DO PWM generator.
+ *
+ * @param pwmGenerator the digital PWM handle
+ */
+void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status);
+
+/**
+ * Changes the frequency of the DO PWM generator.
+ *
+ * The valid range is from 0.6 Hz to 19 kHz.
+ *
+ * The frequency resolution is logarithmic.
+ *
+ * @param rate the frequency to output all digital output PWM signals
+ */
+void HAL_SetDigitalPWMRate(double rate, int32_t* status);
+
+/**
+ * Configures the duty-cycle of the PWM generator.
+ *
+ * @param pwmGenerator the digital PWM handle
+ * @param dutyCycle the percent duty cycle to output [0..1]
+ */
+void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
+ double dutyCycle, int32_t* status);
+
+/**
+ * Configures which DO channel the PWM signal is output on.
+ *
+ * @param pwmGenerator the digital PWM handle
+ * @param channel the channel to output on
+ */
+void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
+ int32_t channel, int32_t* status);
+
+/**
+ * Writes a digital value to a DIO channel.
+ *
+ * @param dioPortHandle the digital port handle
+ * @param value the state to set the digital channel (if it is
+ * configured as an output)
+ */
+void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
+ int32_t* status);
+
+/**
+ * Sets the direction of a DIO channel.
+ *
+ * @param dioPortHandle the digital port handle
+ * @param input true to set input, false for output
+ */
+void HAL_SetDIODirection(HAL_DigitalHandle dioPortHandle, HAL_Bool input,
+ int32_t* status);
+
+/**
+ * Reads a digital value from a DIO channel.
+ *
+ * @param dioPortHandle the digital port handle
+ * @return the state of the specified channel
+ */
+HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status);
+
+/**
+ * Reads the direction of a DIO channel.
+ *
+ * @param dioPortHandle the digital port handle
+ * @return true for input, false for output
+ */
+HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status);
+
+/**
+ * Generates a single digital pulse.
+ *
+ * Write a pulse to the specified digital output channel. There can only be a
+ * single pulse going at any time.
+ *
+ * @param dioPortHandle the digital port handle
+ * @param pulseLength the active length of the pulse (in seconds)
+ */
+void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
+ int32_t* status);
+
+/**
+ * Checks a DIO line to see if it is currently generating a pulse.
+ *
+ * @return true if a pulse is in progress, otherwise false
+ */
+HAL_Bool HAL_IsPulsing(HAL_DigitalHandle dioPortHandle, int32_t* status);
+
+/**
+ * Checks if any DIO line is currently generating a pulse.
+ *
+ * @return true if a pulse on some line is in progress
+ */
+HAL_Bool HAL_IsAnyPulsing(int32_t* status);
+
+/**
+ * Writes the filter index from the FPGA.
+ *
+ * Set the filter index used to filter out short pulses.
+ *
+ * @param dioPortHandle the digital port handle
+ * @param filterIndex the filter index (Must be in the range 0 - 3, where 0
+ * means "none" and 1 - 3 means filter # filterIndex - 1)
+ */
+void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
+ int32_t* status);
+
+/**
+ * Reads the filter index from the FPGA.
+ *
+ * Gets the filter index used to filter out short pulses.
+ *
+ * @param dioPortHandle the digital port handle
+ * @return filterIndex the filter index (Must be in the range 0 - 3,
+ * where 0 means "none" and 1 - 3 means filter # filterIndex - 1)
+ */
+int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status);
+
+/**
+ * Sets the filter period for the specified filter index.
+ *
+ * Sets the filter period in FPGA cycles. Even though there are 2 different
+ * filter index domains (MXP vs HDR), ignore that distinction for now since it
+ * compilicates the interface. That can be changed later.
+ *
+ * @param filterIndex the filter index, 0 - 2
+ * @param value the number of cycles that the signal must not transition
+ * to be counted as a transition.
+ */
+void HAL_SetFilterPeriod(int32_t filterIndex, int64_t value, int32_t* status);
+
+/**
+ * Gets the filter period for the specified filter index.
+ *
+ * Gets the filter period in FPGA cycles. Even though there are 2 different
+ * filter index domains (MXP vs HDR), ignore that distinction for now since it
+ * compilicates the interface. Set status to NiFpga_Status_SoftwareFault if the
+ * filter values miss-match.
+ *
+ * @param filterIndex the filter index, 0 - 2
+ * @param value the number of cycles that the signal must not transition
+ * to be counted as a transition.
+ */
+int64_t HAL_GetFilterPeriod(int32_t filterIndex, int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/DriverStation.h b/hal/src/main/native/include/hal/DriverStation.h
new file mode 100644
index 0000000..1c18681
--- /dev/null
+++ b/hal/src/main/native/include/hal/DriverStation.h
@@ -0,0 +1,276 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2013-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 "hal/DriverStationTypes.h"
+#include "hal/Types.h"
+
+/**
+ * @defgroup hal_driverstation Driver Station Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Sends an error to the driver station.
+ *
+ * @param isError true for error, false for warning
+ * @param errorCode the error code
+ * @param isLVCode true for a LV error code, false for a standard error code
+ * @param details the details of the error
+ * @param location the file location of the errror
+ * @param callstack the callstack of the error
+ * @param printMsg true to print the error message to stdout as well as to the
+ * DS
+ */
+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);
+
+/**
+ * Gets the current control word of the driver station.
+ *
+ * The control work contains the robot state.
+ *
+ * @param controlWord the control word (out)
+ * @return the error code, or 0 for success
+ */
+int32_t HAL_GetControlWord(HAL_ControlWord* controlWord);
+
+/**
+ * Gets the current alliance station ID.
+ *
+ * @param status the error code, or 0 for success
+ * @return the alliance station ID
+ */
+HAL_AllianceStationID HAL_GetAllianceStation(int32_t* status);
+
+/**
+ * Gets the axes of a specific joystick.
+ *
+ * @param joystickNum the joystick number
+ * @param axes the axes values (output)
+ * @return the error code, or 0 for success
+ */
+int32_t HAL_GetJoystickAxes(int32_t joystickNum, HAL_JoystickAxes* axes);
+
+/**
+ * Gets the POVs of a specific joystick.
+ *
+ * @param joystickNum the joystick number
+ * @param povs the POV values (output)
+ * @return the error code, or 0 for success
+ */
+int32_t HAL_GetJoystickPOVs(int32_t joystickNum, HAL_JoystickPOVs* povs);
+
+/**
+ * Gets the buttons of a specific joystick.
+ *
+ * @param joystickNum the joystick number
+ * @param buttons the button values (output)
+ * @return the error code, or 0 for success
+ */
+int32_t HAL_GetJoystickButtons(int32_t joystickNum,
+ HAL_JoystickButtons* buttons);
+
+/**
+ * Retrieves the Joystick Descriptor for particular slot.
+ *
+ * @param desc [out] descriptor (data transfer object) to fill in. desc is
+ * filled in regardless of success. In other words, if descriptor is not
+ * available, desc is filled in with default values matching the init-values in
+ * Java and C++ Driverstation for when caller requests a too-large joystick
+ * index.
+ *
+ * @return error code reported from Network Comm back-end. Zero is good,
+ * nonzero is bad.
+ */
+int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
+ HAL_JoystickDescriptor* desc);
+
+/**
+ * Gets is a specific joystick is considered to be an XBox controller.
+ *
+ * @param joystickNum the joystick number
+ * @return true if xbox, false otherwise
+ */
+HAL_Bool HAL_GetJoystickIsXbox(int32_t joystickNum);
+
+/**
+ * Gets the type of joystick connected.
+ *
+ * This is device specific, and different depending on what system input type
+ * the joystick uses.
+ *
+ * @param joystickNum the joystick number
+ * @return the enumerated joystick type
+ */
+int32_t HAL_GetJoystickType(int32_t joystickNum);
+
+/**
+ * Gets the name of a joystick.
+ *
+ * The returned array must be freed with HAL_FreeJoystickName.
+ *
+ * Will be null terminated.
+ *
+ * @param joystickNum the joystick number
+ * @return the joystick name
+ */
+char* HAL_GetJoystickName(int32_t joystickNum);
+
+/**
+ * Frees a joystick name received with HAL_GetJoystickName
+ *
+ * @param name the name storage
+ */
+void HAL_FreeJoystickName(char* name);
+
+/**
+ * Gets the type of a specific joystick axis.
+ *
+ * This is device specific, and different depending on what system input type
+ * the joystick uses.
+ *
+ * @param joystickNum the joystick number
+ * @param axis the axis number
+ * @return the enumerated axis type
+ */
+int32_t HAL_GetJoystickAxisType(int32_t joystickNum, int32_t axis);
+
+/**
+ * Set joystick outputs.
+ *
+ * @param joystickNum the joystick numer
+ * @param outputs bitmask of outputs, 1 for on 0 for off
+ * @param leftRumble the left rumble value (0-FFFF)
+ * @param rightRumble the right rumble value (0-FFFF)
+ * @return the error code, or 0 for success
+ */
+int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
+ int32_t leftRumble, int32_t rightRumble);
+
+/**
+ * Returns the approximate match time.
+ *
+ * The FMS does not send an official match time to the robots, but does send
+ * an approximate match time. The value will count down the time remaining in
+ * the current period (auto or teleop).
+ *
+ * Warning: This is not an official time (so it cannot be used to dispute ref
+ * calls or guarantee that a function will trigger before the match ends).
+ *
+ * The Practice Match function of the DS approximates the behaviour seen on
+ * the field.
+ *
+ * @param status the error code, or 0 for success
+ * @return time remaining in current match period (auto or teleop)
+ */
+double HAL_GetMatchTime(int32_t* status);
+
+/**
+ * Gets info about a specific match.
+ *
+ * @param info the match info (output)
+ * @return the error code, or 0 for success
+ */
+int32_t HAL_GetMatchInfo(HAL_MatchInfo* info);
+
+#ifndef HAL_USE_LABVIEW
+
+/**
+ * Releases the DS Mutex to allow proper shutdown of any threads that are
+ * waiting on it.
+ */
+void HAL_ReleaseDSMutex(void);
+
+/**
+ * Has a new control packet from the driver station arrived since the last
+ * time this function was called?
+ *
+ * @return true if the control data has been updated since the last call
+ */
+HAL_Bool HAL_IsNewControlData(void);
+
+/**
+ * Waits for the newest DS packet to arrive. Note that this is a blocking call.
+ */
+void HAL_WaitForDSData(void);
+
+/**
+ * Waits for the newest DS packet to arrive. If timeout is <= 0, this will wait
+ * forever. Otherwise, it will wait until either a new packet, or the timeout
+ * time has passed.
+ *
+ * @param timeout timeout in seconds
+ * @return true for new data, false for timeout
+ */
+HAL_Bool HAL_WaitForDSDataTimeout(double timeout);
+
+/**
+ * Initializes the driver station communication. This will properly
+ * handle multiple calls. However note that this CANNOT be called from a library
+ * that interfaces with LabVIEW.
+ */
+void HAL_InitializeDriverStation(void);
+
+/**
+ * Sets the program starting flag in the DS.
+ *
+ * This is what changes the DS to showing robot code ready.
+ */
+void HAL_ObserveUserProgramStarting(void);
+
+/**
+ * Sets the disabled flag in the DS.
+ *
+ * This is used for the DS to ensure the robot is properly responding to its
+ * state request. Ensure this get called about every 50ms, or the robot will be
+ * disabled by the DS.
+ */
+void HAL_ObserveUserProgramDisabled(void);
+
+/**
+ * Sets the autonomous enabled flag in the DS.
+ *
+ * This is used for the DS to ensure the robot is properly responding to its
+ * state request. Ensure this get called about every 50ms, or the robot will be
+ * disabled by the DS.
+ */
+void HAL_ObserveUserProgramAutonomous(void);
+
+/**
+ * Sets the teleoperated enabled flag in the DS.
+ *
+ * This is used for the DS to ensure the robot is properly responding to its
+ * state request. Ensure this get called about every 50ms, or the robot will be
+ * disabled by the DS.
+ */
+void HAL_ObserveUserProgramTeleop(void);
+
+/**
+ * Sets the test mode flag in the DS.
+ *
+ * This is used for the DS to ensure the robot is properly responding to its
+ * state request. Ensure this get called about every 50ms, or the robot will be
+ * disabled by the DS.
+ */
+void HAL_ObserveUserProgramTest(void);
+
+#endif // HAL_USE_LABVIEW
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/DriverStationTypes.h b/hal/src/main/native/include/hal/DriverStationTypes.h
new file mode 100644
index 0000000..7c5d6f6
--- /dev/null
+++ b/hal/src/main/native/include/hal/DriverStationTypes.h
@@ -0,0 +1,110 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <stdint.h>
+
+#include "hal/Types.h"
+
+/**
+ * @defgroup hal_driverstation Driver Station Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#define HAL_IO_CONFIG_DATA_SIZE 32
+#define HAL_SYS_STATUS_DATA_SIZE 44
+#define HAL_USER_STATUS_DATA_SIZE \
+ (984 - HAL_IO_CONFIG_DATA_SIZE - HAL_SYS_STATUS_DATA_SIZE)
+
+#define HALFRC_NetworkCommunication_DynamicType_DSEnhancedIO_Input 17
+#define HALFRC_NetworkCommunication_DynamicType_DSEnhancedIO_Output 18
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Header 19
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Extra1 20
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Vertices1 21
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Extra2 22
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Vertices2 23
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Joystick 24
+#define HALFRC_NetworkCommunication_DynamicType_Kinect_Custom 25
+
+struct HAL_ControlWord {
+ uint32_t enabled : 1;
+ uint32_t autonomous : 1;
+ uint32_t test : 1;
+ uint32_t eStop : 1;
+ uint32_t fmsAttached : 1;
+ uint32_t dsAttached : 1;
+ uint32_t control_reserved : 26;
+};
+typedef struct HAL_ControlWord HAL_ControlWord;
+
+// clang-format off
+HAL_ENUM(HAL_AllianceStationID) {
+ HAL_AllianceStationID_kRed1,
+ HAL_AllianceStationID_kRed2,
+ HAL_AllianceStationID_kRed3,
+ HAL_AllianceStationID_kBlue1,
+ HAL_AllianceStationID_kBlue2,
+ HAL_AllianceStationID_kBlue3,
+};
+
+HAL_ENUM(HAL_MatchType) {
+ HAL_kMatchType_none,
+ HAL_kMatchType_practice,
+ HAL_kMatchType_qualification,
+ HAL_kMatchType_elimination,
+};
+// clang-format on
+
+/* The maximum number of axes that will be stored in a single HALJoystickAxes
+ * struct. This is used for allocating buffers, not bounds checking, since
+ * there are usually less axes in practice.
+ */
+#define HAL_kMaxJoystickAxes 12
+#define HAL_kMaxJoystickPOVs 12
+#define HAL_kMaxJoysticks 6
+
+struct HAL_JoystickAxes {
+ int16_t count;
+ float axes[HAL_kMaxJoystickAxes];
+};
+typedef struct HAL_JoystickAxes HAL_JoystickAxes;
+
+struct HAL_JoystickPOVs {
+ int16_t count;
+ int16_t povs[HAL_kMaxJoystickPOVs];
+};
+typedef struct HAL_JoystickPOVs HAL_JoystickPOVs;
+
+struct HAL_JoystickButtons {
+ uint32_t buttons;
+ uint8_t count;
+};
+typedef struct HAL_JoystickButtons HAL_JoystickButtons;
+
+struct HAL_JoystickDescriptor {
+ uint8_t isXbox;
+ uint8_t type;
+ char name[256];
+ uint8_t axisCount;
+ uint8_t axisTypes[HAL_kMaxJoystickAxes];
+ uint8_t buttonCount;
+ uint8_t povCount;
+};
+typedef struct HAL_JoystickDescriptor HAL_JoystickDescriptor;
+
+struct HAL_MatchInfo {
+ char eventName[64];
+ HAL_MatchType matchType;
+ uint16_t matchNumber;
+ uint8_t replayNumber;
+ uint8_t gameSpecificMessage[64];
+ uint16_t gameSpecificMessageSize;
+};
+typedef struct HAL_MatchInfo HAL_MatchInfo;
+/** @} */
diff --git a/hal/src/main/native/include/hal/Encoder.h b/hal/src/main/native/include/hal/Encoder.h
new file mode 100644
index 0000000..449b814
--- /dev/null
+++ b/hal/src/main/native/include/hal/Encoder.h
@@ -0,0 +1,301 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/AnalogTrigger.h"
+#include "hal/Types.h"
+
+/**
+ * @defgroup hal_encoder Encoder Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+// clang-format off
+/**
+ * The type of index pulse for the encoder.
+ */
+HAL_ENUM(HAL_EncoderIndexingType) {
+ HAL_kResetWhileHigh,
+ HAL_kResetWhileLow,
+ HAL_kResetOnFallingEdge,
+ HAL_kResetOnRisingEdge
+};
+
+/**
+ * The encoding scaling of the encoder.
+ */
+HAL_ENUM(HAL_EncoderEncodingType) {
+ HAL_Encoder_k1X,
+ HAL_Encoder_k2X,
+ HAL_Encoder_k4X
+};
+// clang-format on
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes an encoder.
+ *
+ * @param digitalSourceHandleA the A source (either a HAL_DigitalHandle or a
+ * HAL_AnalogTriggerHandle)
+ * @param analogTriggerTypeA the analog trigger type of the A source if it is
+ * an analog trigger
+ * @param digitalSourceHandleB the B source (either a HAL_DigitalHandle or a
+ * HAL_AnalogTriggerHandle)
+ * @param analogTriggerTypeB the analog trigger type of the B source if it is
+ * an analog trigger
+ * @param reverseDirection true to reverse the counting direction from
+ * standard, otherwise false
+ * @param encodingType the encoding type
+ @return the created encoder handle
+ */
+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);
+
+/**
+ * Frees an encoder.
+ *
+ * @param encoderHandle the encoder handle
+ */
+void HAL_FreeEncoder(HAL_EncoderHandle encoderHandle, int32_t* status);
+
+/**
+ * Gets the current counts of the encoder after encoding type scaling.
+ *
+ * This is scaled by the value passed duing initialization to encodingType.
+ *
+ * @param encoderHandle the encoder handle
+ * @return the current scaled count
+ */
+int32_t HAL_GetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status);
+
+/**
+ * Gets the raw counts of the encoder.
+ *
+ * This is not scaled by any values.
+ *
+ * @param encoderHandle the encoder handle
+ * @return the raw encoder count
+ */
+int32_t HAL_GetEncoderRaw(HAL_EncoderHandle encoderHandle, int32_t* status);
+
+/**
+ * Gets the encoder scale value.
+ *
+ * This is set by the value passed during initialization to encodingType.
+ *
+ * @param encoderHandle the encoder handle
+ * @return the encoder scale value
+ */
+int32_t HAL_GetEncoderEncodingScale(HAL_EncoderHandle encoderHandle,
+ int32_t* status);
+
+/**
+ * Reads the current encoder value.
+ *
+ * Read the value at this instant. It may still be running, so it reflects the
+ * current value. Next time it is read, it might have a different value.
+ *
+ * @param encoderHandle the encoder handle
+ * @return the current encoder value
+ */
+void HAL_ResetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status);
+
+/*
+ * Gets the Period of the most recent count.
+ *
+ * Returns the time interval of the most recent count. This can be used for
+ * velocity calculations to determine shaft speed.
+ *
+ * @param encoderHandle the encoder handle
+ * @returns the period of the last two pulses in units of seconds
+ */
+double HAL_GetEncoderPeriod(HAL_EncoderHandle encoderHandle, int32_t* status);
+
+/**
+ * Sets the maximum period where the device is still considered "moving".
+ *
+ * Sets the maximum period where the device is considered moving. This value is
+ * used to determine the "stopped" state of the encoder using the
+ * HAL_GetEncoderStopped method.
+ *
+ * @param encoderHandle the encoder handle
+ * @param maxPeriod the maximum period where the counted device is
+ * considered moving in seconds
+ */
+void HAL_SetEncoderMaxPeriod(HAL_EncoderHandle encoderHandle, double maxPeriod,
+ int32_t* status);
+
+/**
+ * Determines if the clock is stopped.
+ *
+ * Determines if the clocked input is stopped based on the MaxPeriod value set
+ * using the SetMaxPeriod method. If the clock exceeds the MaxPeriod, then the
+ * device (and encoder) are assumed to be stopped and it returns true.
+ *
+ * @param encoderHandle the encoder handle
+ * @return true if the most recent encoder period exceeds the
+ * MaxPeriod value set by SetMaxPeriod
+ */
+HAL_Bool HAL_GetEncoderStopped(HAL_EncoderHandle encoderHandle,
+ int32_t* status);
+
+/**
+ * Gets the last direction the encoder value changed.
+ *
+ * @param encoderHandle the encoder handle
+ * @return the last direction the encoder value changed
+ */
+HAL_Bool HAL_GetEncoderDirection(HAL_EncoderHandle encoderHandle,
+ int32_t* status);
+
+/**
+ * Gets the current distance traveled by the encoder.
+ *
+ * This is the encoder count scaled by the distance per pulse set for the
+ * encoder.
+ *
+ * @param encoderHandle the encoder handle
+ * @return the encoder distance (units are determined by the units
+ * passed to HAL_SetEncoderDistancePerPulse)
+ */
+double HAL_GetEncoderDistance(HAL_EncoderHandle encoderHandle, int32_t* status);
+
+/**
+ * Gets the current rate of the encoder.
+ *
+ * This is the encoder period scaled by the distance per pulse set for the
+ * encoder.
+ *
+ * @param encoderHandle the encoder handle
+ * @return the encoder rate (units are determined by the units
+ * passed to HAL_SetEncoderDistancePerPulse, time value is seconds)
+ */
+double HAL_GetEncoderRate(HAL_EncoderHandle encoderHandle, int32_t* status);
+
+/**
+ * Sets the minimum rate to be considered moving by the encoder.
+ *
+ * Units need to match what is set by HAL_SetEncoderDistancePerPulse, with time
+ * as seconds.
+ *
+ * @param encoderHandle the encoder handle
+ * @param minRate the minimum rate to be considered moving (units are
+ * determined by the units passed to HAL_SetEncoderDistancePerPulse, time value
+ * is seconds)
+ */
+void HAL_SetEncoderMinRate(HAL_EncoderHandle encoderHandle, double minRate,
+ int32_t* status);
+
+/**
+ * Sets the distance traveled per encoder pulse. This is used as a scaling
+ * factor for the rate and distance calls.
+ *
+ * @param encoderHandle the encoder handle
+ * @param distancePerPulse the distance traveled per encoder pulse (units user
+ * defined)
+ */
+void HAL_SetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
+ double distancePerPulse, int32_t* status);
+
+/**
+ * Sets if to reverse the direction of the encoder.
+ *
+ * Note that this is not a toggle. It is an absolute set.
+ *
+ * @param encoderHandle the encoder handle
+ * @param reverseDirection true to reverse the direction, false to not.
+ */
+void HAL_SetEncoderReverseDirection(HAL_EncoderHandle encoderHandle,
+ HAL_Bool reverseDirection, int32_t* status);
+
+/**
+ * Sets the number of encoder samples to average when calculating encoder rate.
+ *
+ * @param encoderHandle the encoder handle
+ * @param samplesToAverage the number of samples to average
+ */
+void HAL_SetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
+ int32_t samplesToAverage, int32_t* status);
+
+/**
+ * Gets the current samples to average value.
+ *
+ * @param encoderHandle the encoder handle
+ * @return the current samples to average value
+ */
+int32_t HAL_GetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
+ int32_t* status);
+
+/**
+ * Sets the source for an index pulse on the encoder.
+ *
+ * The index pulse can be used to cause an encoder to reset based on an external
+ * input.
+ *
+ * @param encoderHandle the encoder handle
+ * @param digitalSourceHandle the index source handle (either a
+ * HAL_AnalogTriggerHandle of a HAL_DigitalHandle)
+ * @param analogTriggerType the analog trigger type if the source is an analog
+ * trigger
+ * @param type the index triggering type
+ */
+void HAL_SetEncoderIndexSource(HAL_EncoderHandle encoderHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ HAL_EncoderIndexingType type, int32_t* status);
+
+/**
+ * Gets the FPGA index of the encoder.
+ *
+ * @param encoderHandle the encoder handle
+ * @return the FPGA index of the encoder
+ */
+int32_t HAL_GetEncoderFPGAIndex(HAL_EncoderHandle encoderHandle,
+ int32_t* status);
+
+/**
+ * Gets the decoding scale factor of the encoder.
+ *
+ * This is used to perform the scaling from raw to type scaled values.
+ *
+ * @param encoderHandle the encoder handle
+ * @return the scale value for the encoder
+ */
+double HAL_GetEncoderDecodingScaleFactor(HAL_EncoderHandle encoderHandle,
+ int32_t* status);
+
+/**
+ * Gets the user set distance per pulse of the encoder.
+ *
+ * @param encoderHandle the encoder handle
+ * @return the set distance per pulse
+ */
+double HAL_GetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
+ int32_t* status);
+
+/**
+ * Gets the encoding type of the encoder.
+ *
+ * @param encoderHandle the encoder handle
+ * @return the encoding type
+ */
+HAL_EncoderEncodingType HAL_GetEncoderEncodingType(
+ HAL_EncoderHandle encoderHandle, int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/Errors.h b/hal/src/main/native/include/hal/Errors.h
new file mode 100644
index 0000000..4476ab0
--- /dev/null
+++ b/hal/src/main/native/include/hal/Errors.h
@@ -0,0 +1,132 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+/**
+ * @defgroup hal_errors Error Defines
+ * @ingroup hal_capi
+ * @{
+ */
+
+#define CTR_RxTimeout_MESSAGE "CTRE CAN Receive Timeout"
+#define CTR_TxTimeout_MESSAGE "CTRE CAN Transmit Timeout"
+#define CTR_InvalidParamValue_MESSAGE "CTRE CAN Invalid Parameter"
+#define CTR_UnexpectedArbId_MESSAGE \
+ "CTRE Unexpected Arbitration ID (CAN Node ID)"
+#define CTR_TxFailed_MESSAGE "CTRE CAN Transmit Error"
+#define CTR_SigNotUpdated_MESSAGE "CTRE CAN Signal Not Updated"
+
+#define NiFpga_Status_FifoTimeout_MESSAGE "NIFPGA: FIFO timeout error"
+#define NiFpga_Status_TransferAborted_MESSAGE "NIFPGA: Transfer aborted error"
+#define NiFpga_Status_MemoryFull_MESSAGE \
+ "NIFPGA: Memory Allocation failed, memory full"
+#define NiFpga_Status_SoftwareFault_MESSAGE "NIFPGA: Unexpected software error"
+#define NiFpga_Status_InvalidParameter_MESSAGE "NIFPGA: Invalid Parameter"
+#define NiFpga_Status_ResourceNotFound_MESSAGE "NIFPGA: Resource not found"
+#define NiFpga_Status_ResourceNotInitialized_MESSAGE \
+ "NIFPGA: Resource not initialized"
+#define NiFpga_Status_HardwareFault_MESSAGE "NIFPGA: Hardware Fault"
+#define NiFpga_Status_IrqTimeout_MESSAGE "NIFPGA: Interrupt timeout"
+
+#define ERR_CANSessionMux_InvalidBuffer_MESSAGE "CAN: Invalid Buffer"
+#define ERR_CANSessionMux_MessageNotFound_MESSAGE "CAN: Message not found"
+#define WARN_CANSessionMux_NoToken_MESSAGE "CAN: No token"
+#define ERR_CANSessionMux_NotAllowed_MESSAGE "CAN: Not allowed"
+#define ERR_CANSessionMux_NotInitialized_MESSAGE "CAN: Not initialized"
+
+#define ERR_FRCSystem_NetCommNotResponding_MESSAGE \
+ "FRCSystem: NetComm not responding"
+#define ERR_FRCSystem_NoDSConnection_MESSAGE \
+ "FRCSystem: No driver station connected"
+
+#define SAMPLE_RATE_TOO_HIGH 1001
+#define SAMPLE_RATE_TOO_HIGH_MESSAGE \
+ "HAL: Analog module sample rate is too high"
+#define VOLTAGE_OUT_OF_RANGE 1002
+#define VOLTAGE_OUT_OF_RANGE_MESSAGE \
+ "HAL: Voltage to convert to raw value is out of range [0; 5]"
+#define LOOP_TIMING_ERROR 1004
+#define LOOP_TIMING_ERROR_MESSAGE \
+ "HAL: Digital module loop timing is not the expected value"
+#define SPI_WRITE_NO_MOSI 1012
+#define SPI_WRITE_NO_MOSI_MESSAGE \
+ "HAL: Cannot write to SPI port with no MOSI output"
+#define SPI_READ_NO_MISO 1013
+#define SPI_READ_NO_MISO_MESSAGE \
+ "HAL: Cannot read from SPI port with no MISO input"
+#define SPI_READ_NO_DATA 1014
+#define SPI_READ_NO_DATA_MESSAGE "HAL: No data available to read from SPI"
+#define INCOMPATIBLE_STATE 1015
+#define INCOMPATIBLE_STATE_MESSAGE \
+ "HAL: Incompatible State: The operation cannot be completed"
+#define NO_AVAILABLE_RESOURCES -1004
+#define NO_AVAILABLE_RESOURCES_MESSAGE "HAL: No available resources to allocate"
+#define NULL_PARAMETER -1005
+#define NULL_PARAMETER_MESSAGE "HAL: A pointer parameter to a method is NULL"
+#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR -1010
+#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE \
+ "HAL: AnalogTrigger limits error. Lower limit > Upper Limit"
+#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR -1011
+#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE \
+ "HAL: Attempted to read AnalogTrigger pulse output."
+#define PARAMETER_OUT_OF_RANGE -1028
+#define PARAMETER_OUT_OF_RANGE_MESSAGE "HAL: A parameter is out of range."
+#define RESOURCE_IS_ALLOCATED -1029
+#define RESOURCE_IS_ALLOCATED_MESSAGE "HAL: Resource already allocated"
+#define RESOURCE_OUT_OF_RANGE -1030
+#define RESOURCE_OUT_OF_RANGE_MESSAGE \
+ "HAL: The requested resource is out of range."
+#define HAL_INVALID_ACCUMULATOR_CHANNEL -1035
+#define HAL_INVALID_ACCUMULATOR_CHANNEL_MESSAGE \
+ "HAL: The requested input is not an accumulator channel"
+#define HAL_COUNTER_NOT_SUPPORTED -1058
+#define HAL_COUNTER_NOT_SUPPORTED_MESSAGE \
+ "HAL: Counter mode not supported for encoder method"
+#define HAL_PWM_SCALE_ERROR -1072
+#define HAL_PWM_SCALE_ERROR_MESSAGE \
+ "HAL: The PWM Scale Factors are out of range"
+#define HAL_HANDLE_ERROR -1098
+#define HAL_HANDLE_ERROR_MESSAGE \
+ "HAL: A handle parameter was passed incorrectly"
+
+#define HAL_SERIAL_PORT_NOT_FOUND -1123
+#define HAL_SERIAL_PORT_NOT_FOUND_MESSAGE \
+ "HAL: The specified serial port device was not found"
+
+#define HAL_SERIAL_PORT_OPEN_ERROR -1124
+#define HAL_SERIAL_PORT_OPEN_ERROR_MESSAGE \
+ "HAL: The serial port could not be opened"
+
+#define HAL_SERIAL_PORT_ERROR -1125
+#define HAL_SERIAL_PORT_ERROR_MESSAGE \
+ "HAL: There was an error on the serial port"
+
+#define HAL_THREAD_PRIORITY_ERROR -1152
+#define HAL_THREAD_PRIORITY_ERROR_MESSAGE \
+ "HAL: Getting or setting the priority of a thread has failed";
+
+#define HAL_THREAD_PRIORITY_RANGE_ERROR -1153
+#define HAL_THREAD_PRIORITY_RANGE_ERROR_MESSAGE \
+ "HAL: The priority requested to be set is invalid"
+
+#define HAL_CAN_TIMEOUT -1154
+#define HAL_CAN_TIMEOUT_MESSAGE "HAL: CAN Receive has Timed Out"
+
+#define VI_ERROR_SYSTEM_ERROR_MESSAGE "HAL - VISA: System Error";
+#define VI_ERROR_INV_OBJECT_MESSAGE "HAL - VISA: Invalid Object"
+#define VI_ERROR_RSRC_LOCKED_MESSAGE "HAL - VISA: Resource Locked"
+#define VI_ERROR_RSRC_NFOUND_MESSAGE "HAL - VISA: Resource Not Found"
+#define VI_ERROR_INV_RSRC_NAME_MESSAGE "HAL - VISA: Invalid Resource Name"
+#define VI_ERROR_QUEUE_OVERFLOW_MESSAGE "HAL - VISA: Queue Overflow"
+#define VI_ERROR_IO_MESSAGE "HAL - VISA: General IO Error"
+#define VI_ERROR_ASRL_PARITY_MESSAGE "HAL - VISA: Parity Error"
+#define VI_ERROR_ASRL_FRAMING_MESSAGE "HAL - VISA: Framing Error"
+#define VI_ERROR_ASRL_OVERRUN_MESSAGE "HAL - VISA: Buffer Overrun Error"
+#define VI_ERROR_RSRC_BUSY_MESSAGE "HAL - VISA: Resource Busy"
+#define VI_ERROR_INV_PARAMETER_MESSAGE "HAL - VISA: Invalid Parameter"
+/** @} */
diff --git a/hal/src/main/native/include/hal/Extensions.h b/hal/src/main/native/include/hal/Extensions.h
new file mode 100644
index 0000000..0fcbcba
--- /dev/null
+++ b/hal/src/main/native/include/hal/Extensions.h
@@ -0,0 +1,45 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+/**
+ * @defgroup hal_extensions Simulator Extensions
+ * @ingroup hal_capi
+ * HAL Simulator Extensions. These are libraries that provide additional
+ * simulator functionality, such as a Gazebo interface, or a more light weight
+ * simulation.
+ *
+ * An extension must expose the HALSIM_InitExtension entry point which is
+ * invoked after the library is loaded.
+ *
+ * The entry point is expected to return < 0 for errors that should stop
+ * the HAL completely, 0 for success, and > 0 for a non fatal error.
+ * @{
+ */
+typedef int halsim_extension_init_func_t(void);
+
+extern "C" {
+/**
+ * Loads a single extension from a direct path.
+ *
+ * Expected to be called internally, not by users.
+ *
+ * @param library the library path
+ * @return the succes state of the initialization
+ */
+int HAL_LoadOneExtension(const char* library);
+
+/**
+ * Loads any extra halsim libraries provided in the HALSIM_EXTENSIONS
+ * environment variable.
+ *
+ * @return the succes state of the initialization
+ */
+int HAL_LoadExtensions(void);
+} // extern "C"
+/** @} */
diff --git a/hal/src/main/native/include/hal/HAL.h b/hal/src/main/native/include/hal/HAL.h
new file mode 100644
index 0000000..f0da13f
--- /dev/null
+++ b/hal/src/main/native/include/hal/HAL.h
@@ -0,0 +1,46 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2013-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>
+
+#ifndef HAL_USE_LABVIEW
+
+#include "hal/Accelerometer.h"
+#include "hal/AnalogAccumulator.h"
+#include "hal/AnalogGyro.h"
+#include "hal/AnalogInput.h"
+#include "hal/AnalogOutput.h"
+#include "hal/AnalogTrigger.h"
+#include "hal/CAN.h"
+#include "hal/Compressor.h"
+#include "hal/Constants.h"
+#include "hal/Counter.h"
+#include "hal/DIO.h"
+#include "hal/DriverStation.h"
+#include "hal/Errors.h"
+#include "hal/I2C.h"
+#include "hal/Interrupts.h"
+#include "hal/Notifier.h"
+#include "hal/PDP.h"
+#include "hal/PWM.h"
+#include "hal/Ports.h"
+#include "hal/Power.h"
+#include "hal/Relay.h"
+#include "hal/SPI.h"
+#include "hal/SerialPort.h"
+#include "hal/Solenoid.h"
+
+#endif // HAL_USE_LABVIEW
+
+#include "hal/Types.h"
+#include "hal/HALBase.h"
+
+#ifdef __cplusplus
+#include "hal/FRCUsageReporting.h"
+#endif
diff --git a/hal/src/main/native/include/hal/HALBase.h b/hal/src/main/native/include/hal/HALBase.h
new file mode 100644
index 0000000..fd22c0c
--- /dev/null
+++ b/hal/src/main/native/include/hal/HALBase.h
@@ -0,0 +1,182 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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 "hal/Types.h"
+
+/**
+ * @defgroup hal_capi WPILib HAL API
+ * Hardware Abstraction Layer to hardware or simulator
+ * @{
+ */
+
+// clang-format off
+HAL_ENUM(HAL_RuntimeType) { HAL_Athena, HAL_Mock };
+// clang-format on
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Gets the error message for a specific status code.
+ *
+ * @param code the status code
+ * @return the error message for the code. This does not need to be freed.
+ */
+const char* HAL_GetErrorMessage(int32_t code);
+
+/**
+ * Returns the FPGA Version number.
+ *
+ * For now, expect this to be competition year.
+ *
+ * @return FPGA Version number.
+ */
+int32_t HAL_GetFPGAVersion(int32_t* status);
+
+/**
+ * Returns the FPGA Revision number.
+ *
+ * The format of the revision is 3 numbers.
+ * The 12 most significant bits are the Major Revision.
+ * the next 8 bits are the Minor Revision.
+ * The 12 least significant bits are the Build Number.
+ *
+ * @return FPGA Revision number.
+ */
+int64_t HAL_GetFPGARevision(int32_t* status);
+
+HAL_RuntimeType HAL_GetRuntimeType(void);
+
+/**
+ * Gets the state of the "USER" button on the roboRIO.
+ *
+ * @return true if the button is currently pressed down
+ */
+HAL_Bool HAL_GetFPGAButton(int32_t* status);
+
+/**
+ * Gets if the system outputs are currently active
+ *
+ * @return true if the system outputs are active, false if disabled
+ */
+HAL_Bool HAL_GetSystemActive(int32_t* status);
+
+/**
+ * Gets if the system is in a browned out state.
+ *
+ * @return true if the system is in a low voltage brown out, false otherwise
+ */
+HAL_Bool HAL_GetBrownedOut(int32_t* status);
+
+/**
+ * The base HAL initialize function. Useful if you need to ensure the DS and
+ * base HAL functions (the ones above this declaration in HAL.h) are properly
+ * initialized. For normal programs and executables, please use HAL_Initialize.
+ *
+ * This is mainly expected to be use from libraries that are expected to be used
+ * from LabVIEW, as it handles its own initialization for objects.
+ */
+void HAL_BaseInitialize(int32_t* status);
+
+#ifndef HAL_USE_LABVIEW
+
+/**
+ * Gets a port handle for a specific channel.
+ *
+ * The created handle does not need to be freed.
+ *
+ * @param channel the channel number
+ * @return the created port
+ */
+HAL_PortHandle HAL_GetPort(int32_t channel);
+
+/**
+ * Gets a port handle for a specific channel and module.
+ *
+ * This is expected to be used for PCMs, as the roboRIO does not work with
+ * modules anymore.
+ *
+ * The created handle does not need to be freed.
+ *
+ * @param module the module number
+ * @param channel the channel number
+ * @return the created port
+ */
+HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel);
+
+/**
+ * Reads the microsecond-resolution timer on the FPGA.
+ *
+ * @return The current time in microseconds according to the FPGA (since FPGA
+ * reset).
+ */
+uint64_t HAL_GetFPGATime(int32_t* status);
+
+/**
+ * Call this to start up HAL. This is required for robot programs.
+ *
+ * This must be called before any other HAL functions. Failure to do so will
+ * result in undefined behavior, and likely segmentation faults. This means that
+ * any statically initialized variables in a program MUST call this function in
+ * their constructors if they want to use other HAL calls.
+ *
+ * The common parameters are 500 for timeout and 0 for mode.
+ *
+ * This function is safe to call from any thread, and as many times as you wish.
+ * It internally guards from any reentrancy.
+ *
+ * The applicable modes are:
+ * 0: Try to kill an existing HAL from another program, if not successful,
+ * error.
+ * 1: Force kill a HAL from another program.
+ * 2: Just warn if another hal exists and cannot be killed. Will likely result
+ * in undefined behavior.
+ *
+ * @param timeout the initialization timeout (ms)
+ * @param mode the initialization mode (see remarks)
+ * @return true if initialization was successful, otherwise false.
+ */
+HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode);
+
+// ifdef's definition is to allow for default parameters in C++.
+#ifdef __cplusplus
+/**
+ * Reports a hardware usage to the HAL.
+ *
+ * @param resource the used resource
+ * @param instanceNumber the instance of the resource
+ * @param context a user specified context index
+ * @param feature a user specified feature string
+ * @return the index of the added value in NetComm
+ */
+int64_t HAL_Report(int32_t resource, int32_t instanceNumber,
+ int32_t context = 0, const char* feature = nullptr);
+#else
+
+/**
+ * Reports a hardware usage to the HAL.
+ *
+ * @param resource the used resource
+ * @param instanceNumber the instance of the resource
+ * @param context a user specified context index
+ * @param feature a user specified feature string
+ * @return the index of the added value in NetComm
+ */
+int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
+ const char* feature);
+#endif
+
+#endif // HAL_USE_LABVIEW
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/I2C.h b/hal/src/main/native/include/hal/I2C.h
new file mode 100644
index 0000000..fc8b5c8
--- /dev/null
+++ b/hal/src/main/native/include/hal/I2C.h
@@ -0,0 +1,93 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/I2CTypes.h"
+#include "hal/Types.h"
+
+/**
+ * @defgroup hal_i2c I2C Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes the I2C port.
+ *
+ * Opens the port if necessary and saves the handle.
+ * If opening the MXP port, also sets up the channel functions appropriately.
+ *
+ * @param port The port to open, 0 for the on-board, 1 for the MXP.
+ */
+void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status);
+
+/**
+ * Generic I2C read/write transaction.
+ *
+ * This is a lower-level interface to the I2C hardware giving you more control
+ * over each transaction.
+ *
+ * @param port The I2C port, 0 for the on-board, 1 for the MXP.
+ * @param dataToSend Buffer of data to send as part of the transaction.
+ * @param sendSize Number of bytes to send as part of the transaction.
+ * @param dataReceived Buffer to read data into.
+ * @param receiveSize Number of bytes to read from the device.
+ * @return >= 0 on success or -1 on transfer abort.
+ */
+int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
+ const uint8_t* dataToSend, int32_t sendSize,
+ uint8_t* dataReceived, int32_t receiveSize);
+
+/**
+ * Executes a write transaction with the device.
+ *
+ * Writes a single byte to a register on a device and wait until the
+ * transaction is complete.
+ *
+ * @param port The I2C port, 0 for the on-board, 1 for the MXP.
+ * @param registerAddress The address of the register on the device to be
+ * written.
+ * @param data The byte to write to the register on the device.
+ * @return >= 0 on success or -1 on transfer abort.
+ */
+int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress,
+ const uint8_t* dataToSend, int32_t sendSize);
+
+/**
+ * Executes a read transaction with the device.
+ *
+ * Reads bytes from a device.
+ * Most I2C devices will auto-increment the register pointer internally allowing
+ * you to read consecutive registers on a device in a single transaction.
+ *
+ * @param port The I2C port, 0 for the on-board, 1 for the MXP.
+ * @param registerAddress The register to read first in the transaction.
+ * @param count The number of bytes to read in the transaction.
+ * @param buffer A pointer to the array of bytes to store the data read from the
+ * device.
+ * @return >= 0 on success or -1 on transfer abort.
+ */
+int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer,
+ int32_t count);
+
+/**
+ * Closes an I2C port
+ *
+ * @param port The I2C port, 0 for the on-board, 1 for the MXP.
+ */
+void HAL_CloseI2C(HAL_I2CPort port);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/I2CTypes.h b/hal/src/main/native/include/hal/I2CTypes.h
new file mode 100644
index 0000000..d0b269f
--- /dev/null
+++ b/hal/src/main/native/include/hal/I2CTypes.h
@@ -0,0 +1,24 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <stdint.h>
+
+#include "hal/Types.h"
+
+/**
+ * @defgroup hal_i2c I2C Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+// clang-format off
+HAL_ENUM(HAL_I2CPort) { HAL_I2C_kInvalid = -1, HAL_I2C_kOnboard, HAL_I2C_kMXP };
+// clang-format on
+
+/** @} */
diff --git a/hal/src/main/native/include/hal/Interrupts.h b/hal/src/main/native/include/hal/Interrupts.h
new file mode 100644
index 0000000..126b92c
--- /dev/null
+++ b/hal/src/main/native/include/hal/Interrupts.h
@@ -0,0 +1,159 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/AnalogTrigger.h"
+#include "hal/Types.h"
+
+/**
+ * @defgroup hal_interrupts Interrupts Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*HAL_InterruptHandlerFunction)(uint32_t interruptAssertedMask,
+ void* param);
+
+/**
+ * Initializes an interrupt.
+ *
+ * @param watcher true for synchronous interrupts, false for asynchronous
+ * @return the created interrupt handle
+ */
+HAL_InterruptHandle HAL_InitializeInterrupts(HAL_Bool watcher, int32_t* status);
+
+/**
+ * Frees an interrupt.
+ *
+ * @param interruptHandle the interrupt handle
+ * @return the param passed to the interrupt, or nullptr if one
+ * wasn't passed.
+ */
+void* HAL_CleanInterrupts(HAL_InterruptHandle interruptHandle, int32_t* status);
+
+/**
+ * In synchronous mode, waits for the defined interrupt to occur.
+ *
+ * @param interruptHandle the interrupt handle
+ * @param timeout timeout in seconds
+ * @param ignorePrevious if true, ignore interrupts that happened before
+ * waitForInterrupt was called
+ * @return the mask of interrupts that fired
+ */
+int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
+ double timeout, HAL_Bool ignorePrevious,
+ int32_t* status);
+
+/**
+ * Enables interrupts to occur on this input.
+ *
+ * Interrupts are disabled when the RequestInterrupt call is made. This gives
+ * time to do the setup of the other options before starting to field
+ * interrupts.
+ *
+ * @param interruptHandle the interrupt handle
+ */
+void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle, int32_t* status);
+
+/**
+ * Disables interrupts without without deallocating structures.
+ *
+ * @param interruptHandle the interrupt handle
+ */
+void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
+ int32_t* status);
+
+/**
+ * Returns the timestamp for the rising interrupt that occurred most recently.
+ *
+ * This is in the same time domain as HAL_GetFPGATime(). It only contains the
+ * bottom 32 bits of the timestamp. If your robot has been running for over 1
+ * hour, you will need to fill in the upper 32 bits yourself.
+ *
+ * @param interruptHandle the interrupt handle
+ * @return timestamp in microseconds since FPGA Initialization
+ */
+int64_t HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
+ int32_t* status);
+
+/**
+ * Returns the timestamp for the falling interrupt that occurred most recently.
+ *
+ * This is in the same time domain as HAL_GetFPGATime(). It only contains the
+ * bottom 32 bits of the timestamp. If your robot has been running for over 1
+ * hour, you will need to fill in the upper 32 bits yourself.
+ *
+ * @param interruptHandle the interrupt handle
+ * @return timestamp in microseconds since FPGA Initialization
+ */
+int64_t HAL_ReadInterruptFallingTimestamp(HAL_InterruptHandle interruptHandle,
+ int32_t* status);
+
+/**
+ * Requests interrupts on a specific digital source.
+ *
+ * @param interruptHandle the interrupt handle
+ * @param digitalSourceHandle the digital source handle (either a
+ * HAL_AnalogTriggerHandle of a HAL_DigitalHandle)
+ * @param analogTriggerType the trigger type if the source is an AnalogTrigger
+ */
+void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
+ HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ int32_t* status);
+
+/**
+ * Attaches an asynchronous interrupt handler to the interrupt.
+ *
+ * This interrupt gets called directly on the FPGA interrupt thread, so will
+ * block other interrupts while running.
+ *
+ * @param interruptHandle the interrupt handle
+ * @param handler the handler function for the interrupt to call
+ * @param param a parameter to be passed to the handler
+ */
+void HAL_AttachInterruptHandler(HAL_InterruptHandle interruptHandle,
+ HAL_InterruptHandlerFunction handler,
+ void* param, int32_t* status);
+
+/**
+ * Attaches an asynchronous interrupt handler to the interrupt.
+ *
+ * This interrupt gets called on a thread specific to the interrupt, so will not
+ * block other interrupts.
+ *
+ * @param interruptHandle the interrupt handle
+ * @param handler the handler function for the interrupt to call
+ * @param param a parameter to be passed to the handler
+ */
+void HAL_AttachInterruptHandlerThreaded(HAL_InterruptHandle interruptHandle,
+ HAL_InterruptHandlerFunction handler,
+ void* param, int32_t* status);
+
+/**
+ * Sets the edges to trigger the interrupt on.
+ *
+ * Note that both edges triggered is a valid configuration.
+ *
+ * @param interruptHandle the interrupt handle
+ * @param risingEdge true for triggering on rising edge
+ * @param fallingEdge true for triggering on falling edge
+ */
+void HAL_SetInterruptUpSourceEdge(HAL_InterruptHandle interruptHandle,
+ HAL_Bool risingEdge, HAL_Bool fallingEdge,
+ int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/Notifier.h b/hal/src/main/native/include/hal/Notifier.h
new file mode 100644
index 0000000..27f20e3
--- /dev/null
+++ b/hal/src/main/native/include/hal/Notifier.h
@@ -0,0 +1,88 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_notifier Notifier Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes a notifier.
+ *
+ * A notifier is an FPGA controller timer that triggers at requested intervals
+ * based on the FPGA time. This can be used to make precise control loops.
+ *
+ * @return the created notifier
+ */
+HAL_NotifierHandle HAL_InitializeNotifier(int32_t* status);
+
+/**
+ * Stops a notifier from running.
+ *
+ * This will cause any call into HAL_WaitForNotifierAlarm to return.
+ *
+ * @param notifierHandle the notifier handle
+ */
+void HAL_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status);
+
+/**
+ * Cleans a notifier.
+ *
+ * Note this also stops a notifier if it is already running.
+ *
+ * @param notifierHandle the notifier handle
+ */
+void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status);
+
+/**
+ * Updates the trigger time for a notifier.
+ *
+ * Note that this time is an absolute time relative to HAL_GetFPGATime()
+ *
+ * @param notifierHandle the notifier handle
+ * @param triggerTime the updated trigger time
+ */
+void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
+ uint64_t triggerTime, int32_t* status);
+
+/**
+ * Cancels the next notifier alarm.
+ *
+ * This does not cause HAL_WaitForNotifierAlarm to return.
+ *
+ * @param notifierHandle the notifier handle
+ */
+void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
+ int32_t* status);
+
+/**
+ * Waits for the next alarm for the specific notifier.
+ *
+ * This is a blocking call until either the time elapses or HAL_StopNotifier
+ * gets called.
+ *
+ * @param notifierHandle the notifier handle
+ * @return the FPGA time the notifier returned
+ */
+uint64_t HAL_WaitForNotifierAlarm(HAL_NotifierHandle notifierHandle,
+ int32_t* status);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/PDP.h b/hal/src/main/native/include/hal/PDP.h
new file mode 100644
index 0000000..50873f8
--- /dev/null
+++ b/hal/src/main/native/include/hal/PDP.h
@@ -0,0 +1,122 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_pdp PDP Functions
+ * @ingroup hal_capi
+ * Functions to control the Power Distribution Panel.
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes a Power Distribution Panel.
+ *
+ * @param module the module number to initialize
+ * @return the created PDP
+ */
+HAL_PDPHandle HAL_InitializePDP(int32_t module, int32_t* status);
+
+/**
+ * Cleans a PDP module.
+ *
+ * @param handle the module handle
+ */
+void HAL_CleanPDP(HAL_PDPHandle handle);
+
+/**
+ * Checks if a PDP channel is valid.
+ *
+ * @param channel the channel to check
+ * @return true if the channel is valid, otherwise false
+ */
+HAL_Bool HAL_CheckPDPChannel(int32_t channel);
+
+/**
+ * Checks if a PDP module is valid.
+ *
+ * @param channel the module to check
+ * @return true if the module is valid, otherwise false
+ */
+HAL_Bool HAL_CheckPDPModule(int32_t module);
+
+/**
+ * Gets the temperature of the PDP.
+ *
+ * @param handle the module handle
+ * @return the module temperature (celsius)
+ */
+double HAL_GetPDPTemperature(HAL_PDPHandle handle, int32_t* status);
+
+/**
+ * Gets the PDP input voltage.
+ *
+ * @param handle the module handle
+ * @return the input voltage (volts)
+ */
+double HAL_GetPDPVoltage(HAL_PDPHandle handle, int32_t* status);
+
+/**
+ * Gets the current of a specific PDP channel.
+ *
+ * @param module the module
+ * @param channel the channel
+ * @return the channel current (amps)
+ */
+double HAL_GetPDPChannelCurrent(HAL_PDPHandle handle, int32_t channel,
+ int32_t* status);
+
+/**
+ * Gets the total current of the PDP.
+ *
+ * @param handle the module handle
+ * @return the total current (amps)
+ */
+double HAL_GetPDPTotalCurrent(HAL_PDPHandle handle, int32_t* status);
+
+/**
+ * Gets the total power of the PDP.
+ *
+ * @param handle the module handle
+ * @return the total power (watts)
+ */
+double HAL_GetPDPTotalPower(HAL_PDPHandle handle, int32_t* status);
+
+/**
+ * Gets the total energy of the PDP.
+ *
+ * @param handle the module handle
+ * @return the total energy (joules)
+ */
+double HAL_GetPDPTotalEnergy(HAL_PDPHandle handle, int32_t* status);
+
+/**
+ * Resets the PDP accumulated energy.
+ *
+ * @param handle the module handle
+ */
+void HAL_ResetPDPTotalEnergy(HAL_PDPHandle handle, int32_t* status);
+
+/**
+ * Clears any PDP sticky faults.
+ *
+ * @param handle the module handle
+ */
+void HAL_ClearPDPStickyFaults(HAL_PDPHandle handle, int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/PWM.h b/hal/src/main/native/include/hal/PWM.h
new file mode 100644
index 0000000..781a423
--- /dev/null
+++ b/hal/src/main/native/include/hal/PWM.h
@@ -0,0 +1,233 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_pwm PWM Output Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes a PWM port.
+ *
+ * @param portHandle the port to initialize
+ * @return the created pwm handle
+ */
+HAL_DigitalHandle HAL_InitializePWMPort(HAL_PortHandle portHandle,
+ int32_t* status);
+
+/**
+ * Frees a PWM port.
+ *
+ * @param pwmPortHandle the pwm handle
+ */
+void HAL_FreePWMPort(HAL_DigitalHandle pwmPortHandle, int32_t* status);
+
+/**
+ * Checks if a pwm channel is valid.
+ *
+ * @param channel the channel to check
+ * @return true if the channel is valid, otherwise false
+ */
+HAL_Bool HAL_CheckPWMChannel(int32_t channel);
+
+/**
+ * Sets the configuration settings for the PWM channel.
+ *
+ * All values are in milliseconds.
+ *
+ * @param pwmPortHandle the PWM handle
+ * @param maxPwm the maximum PWM value
+ * @param deadbandMaxPwm the high range of the center deadband
+ * @param centerPwm the center PWM value
+ * @param deadbandMinPwm the low range of the center deadband
+ * @param minPwm the minimum PWM value
+ */
+void HAL_SetPWMConfig(HAL_DigitalHandle pwmPortHandle, double maxPwm,
+ double deadbandMaxPwm, double centerPwm,
+ double deadbandMinPwm, double minPwm, int32_t* status);
+
+/**
+ * Sets the raw configuration settings for the PWM channel.
+ *
+ * We recommend using HAL_SetPWMConfig() instead, as those values are properly
+ * scaled. Usually used for values grabbed by HAL_GetPWMConfigRaw().
+ *
+ * Values are in raw FPGA units.
+ *
+ * @param pwmPortHandle the PWM handle
+ * @param maxPwm the maximum PWM value
+ * @param deadbandMaxPwm the high range of the center deadband
+ * @param centerPwm the center PWM value
+ * @param deadbandMinPwm the low range of the center deadband
+ * @param minPwm the minimum PWM value
+ */
+void HAL_SetPWMConfigRaw(HAL_DigitalHandle pwmPortHandle, int32_t maxPwm,
+ int32_t deadbandMaxPwm, int32_t centerPwm,
+ int32_t deadbandMinPwm, int32_t minPwm,
+ int32_t* status);
+
+/**
+ * Gets the raw pwm configuration settings for the PWM channel.
+ *
+ * Values are in raw FPGA units. These units have the potential to change for
+ * any FPGA release.
+ *
+ * @param pwmPortHandle the PWM handle
+ * @param maxPwm the maximum PWM value
+ * @param deadbandMaxPwm the high range of the center deadband
+ * @param centerPwm the center PWM value
+ * @param deadbandMinPwm the low range of the center deadband
+ * @param minPwm the minimum PWM value
+ */
+void HAL_GetPWMConfigRaw(HAL_DigitalHandle pwmPortHandle, int32_t* maxPwm,
+ int32_t* deadbandMaxPwm, int32_t* centerPwm,
+ int32_t* deadbandMinPwm, int32_t* minPwm,
+ int32_t* status);
+
+/**
+ * Sets if the FPGA should output the center value if the input value is within
+ * the deadband.
+ *
+ * @param pwmPortHandle the PWM handle
+ * @param eliminateDeadband true to eliminate deadband, otherwise false
+ */
+void HAL_SetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
+ HAL_Bool eliminateDeadband, int32_t* status);
+
+/**
+ * Gets the current eliminate deadband value.
+ *
+ * @param pwmPortHandle the PWM handle
+ * @return true if set, otherwise false
+ */
+HAL_Bool HAL_GetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
+ int32_t* status);
+
+/**
+ * Sets a PWM channel to the desired value.
+ *
+ * The values are in raw FPGA units, and have the potential to change with any
+ * FPGA release.
+ *
+ * @param pwmPortHandle the PWM handle
+ * @param value the PWM value to set
+ */
+void HAL_SetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t value,
+ int32_t* status);
+
+/**
+ * Sets a PWM channel to the desired scaled value.
+ *
+ * The values range from -1 to 1 and the period is controlled by the PWM Period
+ * and MinHigh registers.
+ *
+ * @param pwmPortHandle the PWM handle
+ * @param value the scaled PWM value to set
+ */
+void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
+ int32_t* status);
+
+/**
+ * Sets a PWM channel to the desired position value.
+ *
+ * The values range from 0 to 1 and the period is controlled by the PWM Period
+ * and MinHigh registers.
+ *
+ * @param pwmPortHandle the PWM handle
+ * @param value the positional PWM value to set
+ */
+void HAL_SetPWMPosition(HAL_DigitalHandle pwmPortHandle, double position,
+ int32_t* status);
+
+/**
+ * Sets a PWM channel to be disabled.
+ *
+ * The channel is disabled until the next time it is set. Note this is different
+ * from just setting a 0 speed, as this will actively stop all signalling on the
+ * channel.
+ *
+ * @param pwmPortHandle the PWM handle.
+ */
+void HAL_SetPWMDisabled(HAL_DigitalHandle pwmPortHandle, int32_t* status);
+
+/**
+ * Gets a value from a PWM channel.
+ *
+ * The values are in raw FPGA units, and have the potential to change with any
+ * FPGA release.
+ *
+ * @param pwmPortHandle the PWM handle
+ * @return the current raw PWM value
+ */
+int32_t HAL_GetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t* status);
+
+/**
+ * Gets a scaled value from a PWM channel.
+ *
+ * The values range from -1 to 1.
+ *
+ * @param pwmPortHandle the PWM handle
+ * @return the current speed PWM value
+ */
+double HAL_GetPWMSpeed(HAL_DigitalHandle pwmPortHandle, int32_t* status);
+
+/**
+ * Gets a position value from a PWM channel.
+ *
+ * The values range from 0 to 1.
+ *
+ * @param pwmPortHandle the PWM handle
+ * @return the current positional PWM value
+ */
+double HAL_GetPWMPosition(HAL_DigitalHandle pwmPortHandle, int32_t* status);
+
+/**
+ * Forces a PWM signal to go to 0 temporarily.
+ *
+ * @param pwmPortHandle the PWM handle.
+ */
+void HAL_LatchPWMZero(HAL_DigitalHandle pwmPortHandle, int32_t* status);
+
+/**
+ * Sets how how often the PWM signal is squelched, thus scaling the period.
+ *
+ * @param pwmPortHandle the PWM handle.
+ * @param squelchMask the 2-bit mask of outputs to squelch
+ */
+void HAL_SetPWMPeriodScale(HAL_DigitalHandle pwmPortHandle, int32_t squelchMask,
+ int32_t* status);
+
+/**
+ * Gets the loop timing of the PWM system.
+ *
+ * @return the loop time
+ */
+int32_t HAL_GetPWMLoopTiming(int32_t* status);
+
+/**
+ * Gets the pwm starting cycle time.
+ *
+ * This time is relative to the FPGA time.
+ *
+ * @return the pwm cycle start time
+ */
+uint64_t HAL_GetPWMCycleStartTime(int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/Ports.h b/hal/src/main/native/include/hal/Ports.h
new file mode 100644
index 0000000..9b29817
--- /dev/null
+++ b/hal/src/main/native/include/hal/Ports.h
@@ -0,0 +1,150 @@
+/*----------------------------------------------------------------------------*/
+/* 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>
+
+/**
+ * @defgroup hal_ports Ports Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Gets the number of analog accumulators in the current system.
+ *
+ * @return the number of analog accumulators
+ */
+int32_t HAL_GetNumAccumulators(void);
+
+/**
+ * Gets the number of analog triggers in the current system.
+ *
+ * @return the number of analog triggers
+ */
+int32_t HAL_GetNumAnalogTriggers(void);
+
+/**
+ * Gets the number of analog inputs in the current system.
+ *
+ * @return the number of analog inputs
+ */
+int32_t HAL_GetNumAnalogInputs(void);
+
+/**
+ * Gets the number of analog outputs in the current system.
+ *
+ * @return the number of analog outputs
+ */
+int32_t HAL_GetNumAnalogOutputs(void);
+
+/**
+ * Gets the number of analog counters in the current system.
+ *
+ * @return the number of counters
+ */
+int32_t HAL_GetNumCounters(void);
+
+/**
+ * Gets the number of digital headers in the current system.
+ *
+ * @return the number of digital headers
+ */
+int32_t HAL_GetNumDigitalHeaders(void);
+
+/**
+ * Gets the number of PWM headers in the current system.
+ *
+ * @return the number of PWM headers
+ */
+int32_t HAL_GetNumPWMHeaders(void);
+
+/**
+ * Gets the number of digital channels in the current system.
+ *
+ * @return the number of digital channels
+ */
+int32_t HAL_GetNumDigitalChannels(void);
+
+/**
+ * Gets the number of PWM channels in the current system.
+ *
+ * @return the number of PWM channels
+ */
+int32_t HAL_GetNumPWMChannels(void);
+
+/**
+ * Gets the number of digital IO PWM outputs in the current system.
+ *
+ * @return the number of digital IO PWM outputs
+ */
+int32_t HAL_GetNumDigitalPWMOutputs(void);
+
+/**
+ * Gets the number of quadrature encoders in the current system.
+ *
+ * @return the number of quadrature encoders
+ */
+int32_t HAL_GetNumEncoders(void);
+
+/**
+ * Gets the number of interrupts in the current system.
+ *
+ * @return the number of interrupts
+ */
+int32_t HAL_GetNumInterrupts(void);
+
+/**
+ * Gets the number of relay channels in the current system.
+ *
+ * @return the number of relay channels
+ */
+int32_t HAL_GetNumRelayChannels(void);
+
+/**
+ * Gets the number of relay headers in the current system.
+ *
+ * @return the number of relay headers
+ */
+int32_t HAL_GetNumRelayHeaders(void);
+
+/**
+ * Gets the number of PCM modules in the current system.
+ *
+ * @return the number of PCM modules
+ */
+int32_t HAL_GetNumPCMModules(void);
+
+/**
+ * Gets the number of solenoid channels in the current system.
+ *
+ * @return the number of solenoid channels
+ */
+int32_t HAL_GetNumSolenoidChannels(void);
+
+/**
+ * Gets the number of PDP modules in the current system.
+ *
+ * @return the number of PDP modules
+ */
+int32_t HAL_GetNumPDPModules(void);
+
+/**
+ * Gets the number of PDP channels in the current system.
+ *
+ * @return the number of PDP channels
+ */
+int32_t HAL_GetNumPDPChannels(void);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/Power.h b/hal/src/main/native/include/hal/Power.h
new file mode 100644
index 0000000..7ac7991
--- /dev/null
+++ b/hal/src/main/native/include/hal/Power.h
@@ -0,0 +1,124 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_power Power Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Gets the roboRIO input voltage.
+ *
+ * @return the input voltage (volts)
+ */
+double HAL_GetVinVoltage(int32_t* status);
+
+/**
+ * Gets the roboRIO input current.
+ *
+ * @return the input current (amps)
+ */
+double HAL_GetVinCurrent(int32_t* status);
+
+/**
+ * Gets the 6V rail voltage.
+ *
+ * @return the 6V rail voltage (volts)
+ */
+double HAL_GetUserVoltage6V(int32_t* status);
+
+/**
+ * Gets the 6V rail current.
+ *
+ * @return the 6V rail current (amps)
+ */
+double HAL_GetUserCurrent6V(int32_t* status);
+
+/**
+ * Gets the active state of the 6V rail.
+ *
+ * @return true if the rail is active, otherwise false
+ */
+HAL_Bool HAL_GetUserActive6V(int32_t* status);
+
+/**
+ * Gets the fault count for the 6V rail.
+ *
+ * @return the number of 6V fault counts
+ */
+int32_t HAL_GetUserCurrentFaults6V(int32_t* status);
+
+/**
+ * Gets the 5V rail voltage.
+ *
+ * @return the 5V rail voltage (volts)
+ */
+double HAL_GetUserVoltage5V(int32_t* status);
+
+/**
+ * Gets the 5V rail current.
+ *
+ * @return the 5V rail current (amps)
+ */
+double HAL_GetUserCurrent5V(int32_t* status);
+
+/**
+ * Gets the active state of the 5V rail.
+ *
+ * @return true if the rail is active, otherwise false
+ */
+HAL_Bool HAL_GetUserActive5V(int32_t* status);
+
+/**
+ * Gets the fault count for the 5V rail.
+ *
+ * @return the number of 5V fault counts
+ */
+int32_t HAL_GetUserCurrentFaults5V(int32_t* status);
+
+/**
+ * Gets the 3V3 rail voltage.
+ *
+ * @return the 3V3 rail voltage (volts)
+ */
+double HAL_GetUserVoltage3V3(int32_t* status);
+
+/**
+ * Gets the 3V3 rail current.
+ *
+ * @return the 3V3 rail current (amps)
+ */
+double HAL_GetUserCurrent3V3(int32_t* status);
+
+/**
+ * Gets the active state of the 3V3 rail.
+ *
+ * @return true if the rail is active, otherwise false
+ */
+HAL_Bool HAL_GetUserActive3V3(int32_t* status);
+
+/**
+ * Gets the fault count for the 3V3 rail.
+ *
+ * @return the number of 3V3 fault counts
+ */
+int32_t HAL_GetUserCurrentFaults3V3(int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/Relay.h b/hal/src/main/native/include/hal/Relay.h
new file mode 100644
index 0000000..281aad6
--- /dev/null
+++ b/hal/src/main/native/include/hal/Relay.h
@@ -0,0 +1,71 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_relay Relay Output Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes a relay.
+ *
+ * Note this call will only initialize either the forward or reverse port of the
+ * relay. If you need both, you will need to initialize 2 relays.
+ *
+ * @param portHandle the port handle to initialize
+ * @param fwd true for the forward port, false for the reverse port
+ * @return the created relay handle
+ */
+HAL_RelayHandle HAL_InitializeRelayPort(HAL_PortHandle portHandle, HAL_Bool fwd,
+ int32_t* status);
+
+/**
+ * Frees a relay port.
+ *
+ * @param relayPortHandle the relay handle
+ */
+void HAL_FreeRelayPort(HAL_RelayHandle relayPortHandle);
+
+/**
+ * Checks if a relay channel is valid.
+ *
+ * @param channel the channel to check
+ * @return true if the channel is valid, otherwise false
+ */
+HAL_Bool HAL_CheckRelayChannel(int32_t channel);
+
+/**
+ * Sets the state of a relay output.
+ *
+ * @param relayPortHandle the relay handle
+ * @param on true for on, false for off
+ */
+void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
+ int32_t* status);
+
+/**
+ * Gets the current state of the relay channel.
+ *
+ * @param relayPortHandle the relay handle
+ * @return true for on, false for off
+ */
+HAL_Bool HAL_GetRelay(HAL_RelayHandle relayPortHandle, int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/SPI.h b/hal/src/main/native/include/hal/SPI.h
new file mode 100644
index 0000000..4f1815f
--- /dev/null
+++ b/hal/src/main/native/include/hal/SPI.h
@@ -0,0 +1,250 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/AnalogTrigger.h"
+#include "hal/SPITypes.h"
+#include "hal/Types.h"
+
+/**
+ * @defgroup hal_spi SPI Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes the SPI port. Opens the port if necessary and saves the handle.
+ *
+ * If opening the MXP port, also sets up the channel functions appropriately.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS3, 4 for MXP
+ */
+void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status);
+
+/**
+ * Performs an SPI send/receive transaction.
+ *
+ * This is a lower-level interface to the spi hardware giving you more control
+ * over each transaction.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4
+ * for MXP
+ * @param dataToSend Buffer of data to send as part of the transaction.
+ * @param dataReceived Buffer to read data into.
+ * @param size Number of bytes to transfer. [0..7]
+ * @return Number of bytes transferred, -1 for error
+ */
+int32_t HAL_TransactionSPI(HAL_SPIPort port, const uint8_t* dataToSend,
+ uint8_t* dataReceived, int32_t size);
+
+/**
+ * Executes a write transaction with the device.
+ *
+ * Writes to a device and wait until the transaction is complete.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4
+ * for MXP
+ * @param datToSend The data to write to the register on the device.
+ * @param sendSize The number of bytes to be written
+ * @return The number of bytes written. -1 for an error
+ */
+int32_t HAL_WriteSPI(HAL_SPIPort port, const uint8_t* dataToSend,
+ int32_t sendSize);
+
+/**
+ * Executes a read from the device.
+ *
+ * This method does not write any data out to the device.
+ *
+ * Most spi devices will require a register address to be written before they
+ * begin returning data.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
+ * MXP
+ * @param buffer A pointer to the array of bytes to store the data read from the
+ * device.
+ * @param count The number of bytes to read in the transaction. [1..7]
+ * @return Number of bytes read. -1 for error.
+ */
+int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count);
+
+/**
+ * Closes the SPI port.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
+ */
+void HAL_CloseSPI(HAL_SPIPort port);
+
+/**
+ * Sets the clock speed for the SPI bus.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
+ * MXP
+ * @param speed The speed in Hz (0-1MHz)
+ */
+void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed);
+
+/**
+ * Sets the SPI options.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard
+ * CS0-CS2, 4 for MXP
+ * @param msbFirst True to write the MSB first, False for LSB first
+ * @param sampleOnTrailing True to sample on the trailing edge, False to sample
+ * on the leading edge
+ * @param clkIdleHigh True to set the clock to active low, False to set the
+ * clock active high
+ */
+void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
+ HAL_Bool sampleOnTrailing, HAL_Bool clkIdleHigh);
+
+/**
+ * Sets the CS Active high for a SPI port.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
+ */
+void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status);
+
+/**
+ * Sets the CS Active low for a SPI port.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
+ */
+void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status);
+
+/**
+ * Gets the stored handle for a SPI port.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
+ * @return The stored handle for the SPI port. 0 represents no stored
+ * handle.
+ */
+int32_t HAL_GetSPIHandle(HAL_SPIPort port);
+
+/**
+ * Sets the stored handle for a SPI port.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
+ * MXP.
+ * @param handle The value of the handle for the port.
+ */
+void HAL_SetSPIHandle(HAL_SPIPort port, int32_t handle);
+
+/**
+ * Initializes the SPI automatic accumulator.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4
+ * for MXP.
+ * @param bufferSize The accumulator buffer size.
+ */
+void HAL_InitSPIAuto(HAL_SPIPort port, int32_t bufferSize, int32_t* status);
+
+/**
+ * Frees an SPI automatic accumulator.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
+ * MXP.
+ */
+void HAL_FreeSPIAuto(HAL_SPIPort port, int32_t* status);
+
+/**
+ * Sets the period for automatic SPI accumulation.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
+ * MXP.
+ * @param period The accumlation period (seconds).
+ */
+void HAL_StartSPIAutoRate(HAL_SPIPort port, double period, int32_t* status);
+
+/**
+ * Starts the auto SPI accumulator on a specific trigger.
+ *
+ * Note that triggering on both rising and falling edges is a valid
+ * configuration.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard
+ * CS0-CS2, 4 for MXP.
+ * @param digitalSourceHandle The trigger source to use (Either
+ * HAL_AnalogTriggerHandle or HAL_DigitalHandle).
+ * @param analogTriggerType The analog trigger type, if the source is an
+ * analog trigger.
+ * @param triggerRising Trigger on the rising edge if true.
+ * @param triggerFalling Trigger on the falling edge if true.
+ */
+void HAL_StartSPIAutoTrigger(HAL_SPIPort port, HAL_Handle digitalSourceHandle,
+ HAL_AnalogTriggerType analogTriggerType,
+ HAL_Bool triggerRising, HAL_Bool triggerFalling,
+ int32_t* status);
+
+/**
+ * Stops an automatic SPI accumlation.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
+ * MXP.
+ */
+void HAL_StopSPIAuto(HAL_SPIPort port, int32_t* status);
+
+/**
+ * Sets the data to be transmitted to the device to initiate a read.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4
+ * for MXP.
+ * @param dataToSend Pointer to the data to send (Gets copied for continue use,
+ * so no need to keep alive).
+ * @param dataSize The length of the data to send.
+ * @param zeroSize The number of zeros to send after the data.
+ */
+void HAL_SetSPIAutoTransmitData(HAL_SPIPort port, const uint8_t* dataToSend,
+ int32_t dataSize, int32_t zeroSize,
+ int32_t* status);
+
+/**
+ * Immediately forces an SPI read to happen.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
+ * MXP.
+ */
+void HAL_ForceSPIAutoRead(HAL_SPIPort port, int32_t* status);
+
+/**
+ * Reads data received by the SPI accumulator. Each received data sequence
+ * consists of a timestamp followed by the received data bytes, one byte per
+ * word (in the least significant byte). The length of each received data
+ * sequence is the same as the combined dataSize + zeroSize set in
+ * HAL_SetSPIAutoTransmitData.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4
+ * for MXP.
+ * @param buffer The buffer to store the data into.
+ * @param numToRead The number of words to read.
+ * @param timeout The read timeout (in seconds).
+ * @return The number of words actually read.
+ */
+int32_t HAL_ReadSPIAutoReceivedData(HAL_SPIPort port, uint32_t* buffer,
+ int32_t numToRead, double timeout,
+ int32_t* status);
+
+/**
+ * Gets the count of how many SPI accumulations have been missed.
+ *
+ * @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
+ * MXP.
+ * @return The number of missed accumulations.
+ */
+int32_t HAL_GetSPIAutoDroppedCount(HAL_SPIPort port, int32_t* status);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/SPITypes.h b/hal/src/main/native/include/hal/SPITypes.h
new file mode 100644
index 0000000..907623c
--- /dev/null
+++ b/hal/src/main/native/include/hal/SPITypes.h
@@ -0,0 +1,30 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <stdint.h>
+
+#include "hal/Types.h"
+
+/**
+ * @defgroup hal_spi SPI Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+// clang-format off
+HAL_ENUM(HAL_SPIPort) {
+ HAL_SPI_kInvalid = -1,
+ HAL_SPI_kOnboardCS0,
+ HAL_SPI_kOnboardCS1,
+ HAL_SPI_kOnboardCS2,
+ HAL_SPI_kOnboardCS3,
+ HAL_SPI_kMXP
+};
+// clang-format on
+/** @} */
diff --git a/hal/src/main/native/include/hal/SerialPort.h b/hal/src/main/native/include/hal/SerialPort.h
new file mode 100644
index 0000000..c2fd105
--- /dev/null
+++ b/hal/src/main/native/include/hal/SerialPort.h
@@ -0,0 +1,230 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_serialport Serial Port Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+// clang-format off
+HAL_ENUM(HAL_SerialPort) {
+ HAL_SerialPort_Onboard = 0,
+ HAL_SerialPort_MXP = 1,
+ HAL_SerialPort_USB1 = 2,
+ HAL_SerialPort_USB2 = 3
+};
+// clang-format on
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes a serial port.
+ *
+ * The channels are either the onboard RS232, the mxp uart, or 2 USB ports. The
+ * top port is USB1, the bottom port is USB2.
+ *
+ * @param port the serial port to initialize
+ */
+void HAL_InitializeSerialPort(HAL_SerialPort port, int32_t* status);
+
+/**
+ * Initializes a serial port with a direct name.
+ *
+ * This name is the VISA name for a specific port (find this in the web dash).
+ * Note these are not always consistent between roboRIO reboots.
+ *
+ * @param port the serial port to initialize
+ * @param portName the VISA port name
+ */
+void HAL_InitializeSerialPortDirect(HAL_SerialPort port, const char* portName,
+ int32_t* status);
+
+/**
+ * Sets the baud rate of a serial port.
+ *
+ * Any value between 0 and 0xFFFFFFFF may be used. Default is 9600.
+ *
+ * @param port the serial port
+ * @param baud the baud rate to set
+ */
+void HAL_SetSerialBaudRate(HAL_SerialPort port, int32_t baud, int32_t* status);
+
+/**
+ * Sets the number of data bits on a serial port.
+ *
+ * Defaults to 8.
+ *
+ * @param port the serial port
+ * @param bits the number of data bits (5-8)
+ */
+void HAL_SetSerialDataBits(HAL_SerialPort port, int32_t bits, int32_t* status);
+
+/**
+ * Sets the number of parity bits on a serial port.
+ *
+ * Valid values are:
+ * 0: None (default)
+ * 1: Odd
+ * 2: Even
+ * 3: Mark - Means exists and always 1
+ * 4: Space - Means exists and always 0
+ *
+ * @param port the serial port
+ * @param parity the parity bit mode (see remarks for valid values)
+ */
+void HAL_SetSerialParity(HAL_SerialPort port, int32_t parity, int32_t* status);
+
+/**
+ * Sets the number of stop bits on a serial port.
+ *
+ * Valid values are:
+ * 10: One stop bit (default)
+ * 15: One and a half stop bits
+ * 20: Two stop bits
+ *
+ * @param port the serial port
+ * @param stopBits the stop bit value (see remarks for valid values)
+ */
+void HAL_SetSerialStopBits(HAL_SerialPort port, int32_t stopBits,
+ int32_t* status);
+
+/**
+ * Sets the write mode on a serial port.
+ *
+ * Valid values are:
+ * 1: Flush on access
+ * 2: Flush when full (default)
+ *
+ * @param port the serial port
+ * @param mode the mode to set (see remarks for valid values)
+ */
+void HAL_SetSerialWriteMode(HAL_SerialPort port, int32_t mode, int32_t* status);
+
+/**
+ * Sets the flow control mode of a serial port.
+ *
+ * Valid values are:
+ * 0: None (default)
+ * 1: XON-XOFF
+ * 2: RTS-CTS
+ * 3: DTR-DSR
+ *
+ * @param port the serial port
+ * @param flow the mode to set (see remarks for valid values)
+ */
+void HAL_SetSerialFlowControl(HAL_SerialPort port, int32_t flow,
+ int32_t* status);
+
+/**
+ * Sets the minimum serial read timeout of a port.
+ *
+ * @param port the serial port
+ * @param timeout the timeout in milliseconds
+ */
+void HAL_SetSerialTimeout(HAL_SerialPort port, double timeout, int32_t* status);
+
+/**
+ * Sets the termination character that terminates a read.
+ *
+ * By default this is disabled.
+ *
+ * @param port the serial port
+ * @param terminator the termination character to set
+ */
+void HAL_EnableSerialTermination(HAL_SerialPort port, char terminator,
+ int32_t* status);
+
+/**
+ * Disables a termination character for reads.
+ *
+ * @param port the serial port
+ */
+void HAL_DisableSerialTermination(HAL_SerialPort port, int32_t* status);
+
+/**
+ * Sets the size of the read buffer.
+ *
+ * @param port the serial port
+ * @param size the read buffer size
+ */
+void HAL_SetSerialReadBufferSize(HAL_SerialPort port, int32_t size,
+ int32_t* status);
+
+/**
+ * Sets the size of the write buffer.
+ *
+ * @param port the serial port
+ * @param size the write buffer size
+ */
+void HAL_SetSerialWriteBufferSize(HAL_SerialPort port, int32_t size,
+ int32_t* status);
+
+/**
+ * Gets the number of bytes currently in the read buffer.
+ *
+ * @param port the serial port
+ * @return the number of bytes in the read buffer
+ */
+int32_t HAL_GetSerialBytesReceived(HAL_SerialPort port, int32_t* status);
+
+/**
+ * Reads data from the serial port.
+ *
+ * Will wait for either timeout (if set), the termination char (if set), or the
+ * count to be full. Whichever one comes first.
+ *
+ * @param port the serial port
+ * @param count the number of bytes maximum to read
+ * @return the number of bytes actually read
+ */
+int32_t HAL_ReadSerial(HAL_SerialPort port, char* buffer, int32_t count,
+ int32_t* status);
+
+/**
+ * Writes data to the serial port.
+ *
+ * @param port the serial port
+ * @param buffer the buffer to write
+ * @param count the number of bytes to write from the buffer
+ * @return the number of bytes actually written
+ */
+int32_t HAL_WriteSerial(HAL_SerialPort port, const char* buffer, int32_t count,
+ int32_t* status);
+
+/**
+ * Flushes the serial write buffer out to the port.
+ *
+ * @param port the serial port
+ */
+void HAL_FlushSerial(HAL_SerialPort port, int32_t* status);
+
+/**
+ * Clears the receive buffer of the serial port.
+ *
+ * @param port the serial port
+ */
+void HAL_ClearSerial(HAL_SerialPort port, int32_t* status);
+
+/**
+ * Closes a serial port.
+ *
+ * @param port the serial port to close
+ */
+void HAL_CloseSerial(HAL_SerialPort port, int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/Solenoid.h b/hal/src/main/native/include/hal/Solenoid.h
new file mode 100644
index 0000000..53257b2
--- /dev/null
+++ b/hal/src/main/native/include/hal/Solenoid.h
@@ -0,0 +1,141 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/**
+ * @defgroup hal_solenoid Solenoid Output Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initializes a solenoid port.
+ *
+ * @param portHandle the port handle of the module and channel to initialize
+ * @return the created solenoid handle
+ */
+HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
+ int32_t* status);
+
+/**
+ * Frees a solenoid port.
+ *
+ * @param solenoidPortHandle the solenoid handle
+ */
+void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle);
+
+/**
+ * Checks if a solenoid module is in the valid range.
+ *
+ * @param module the module number to check
+ * @return true if the module number is valid, otherwise false
+ */
+HAL_Bool HAL_CheckSolenoidModule(int32_t module);
+
+/**
+ * Checks if a solenoid channel is in the valid range.
+ *
+ * @param channel the channel number to check
+ * @return true if the channel number is valid, otherwise false
+ */
+HAL_Bool HAL_CheckSolenoidChannel(int32_t channel);
+
+/**
+ * Gets the current solenoid output value.
+ *
+ * @param solenoidPortHandle the solenoid handle
+ * @return true if the solenoid is on, otherwise false
+ */
+HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
+ int32_t* status);
+
+/**
+ * Gets the status of all solenoids on a specific module.
+ *
+ * @param module the module to check
+ * @return bitmask of the channels, 1 for on 0 for off
+ */
+int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status);
+
+/**
+ * Sets a solenoid output value.
+ *
+ * @param solenoidPortHandle the solenoid handle
+ * @param value true for on, false for off
+ */
+void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
+ int32_t* status);
+
+/**
+ * Sets all channels on a specific module.
+ *
+ * @param module the module to set the channels on
+ * @param state bitmask of the channels to set, 1 for on 0 for off
+ */
+void HAL_SetAllSolenoids(int32_t module, int32_t state, int32_t* status);
+
+/**
+ * Gets the channels blacklisted from being enabled on a module.
+ *
+ * @param module the module to check
+ * @retur bitmask of the blacklisted channels, 1 for true 0 for false
+ */
+int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status);
+
+/**
+ * Gets if a specific module has an over or under voltage sticky fault.
+ *
+ * @param module the module to check
+ * @return true if a stick fault is set, otherwise false
+ */
+HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status);
+
+/**
+ * Gets if a specific module has an over or under voltage fault.
+ *
+ * @param module the module to check
+ * @return true if faulted, otherwise false
+ */
+HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status);
+
+/**
+ * Clears all faults on a module.
+ *
+ * @param module the module to clear
+ */
+void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status);
+
+/**
+ * Sets the one shot duration on a solenoid channel.
+ *
+ * @param solenoidPortHandle the solenoid handle
+ * @param durMS the one shot duration in ms
+ */
+void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
+ int32_t durMS, int32_t* status);
+
+/**
+ * Fires a single pulse on a solenoid channel.
+ *
+ * The pulse is the duration set by HAL_SetOneShotDuration().
+ *
+ * @param solenoidPortHandle the solenoid handle
+ */
+void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/Threads.h b/hal/src/main/native/include/hal/Threads.h
new file mode 100644
index 0000000..4908c9c
--- /dev/null
+++ b/hal/src/main/native/include/hal/Threads.h
@@ -0,0 +1,72 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#define NativeThreadHandle const void*
+
+#include "hal/Types.h"
+
+/**
+ * @defgroup hal_threads Threads Functions
+ * @ingroup hal_capi
+ * @{
+ */
+
+extern "C" {
+/**
+ * Gets the thread priority for the specified thread.
+ *
+ * @param handle Native handle pointer to the thread to get the priority for
+ * @param isRealTime Set to true if thread is realtime, otherwise false
+ * @param status Error status variable. 0 on success
+ * @return The current thread priority. Scaled 1-99, with 1 being
+ * highest.
+ */
+int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
+ int32_t* status);
+
+/**
+ * Gets the thread priority for the current thread.
+ *
+ * @param handle Native handle pointer to the thread to get the priority for
+ * @param isRealTime Set to true if thread is realtime, otherwise false
+ * @param status Error status variable. 0 on success
+ * @return The current thread priority. Scaled 1-99, with 1 being
+ * highest.
+ */
+int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status);
+
+/**
+ * Sets the thread priority for the specified thread.
+ *
+ * @param thread Reference to the thread to set the priority of
+ * @param realTime Set to true to set a realtime priority, false for standard
+ * priority
+ * @param priority Priority to set the thread to. Scaled 1-99, with 1 being
+ * highest
+ * @param status Error status variable. 0 on success
+ * @return The success state of setting the priority
+ */
+HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
+ int32_t priority, int32_t* status);
+
+/**
+ * Sets the thread priority for the current thread.
+ *
+ * @param thread Reference to the thread to set the priority of
+ * @param realTime Set to true to set a realtime priority, false for standard
+ * priority
+ * @param priority Priority to set the thread to. Scaled 1-99, with 1 being
+ * highest
+ * @param status Error status variable. 0 on success
+ * @return The success state of setting the priority
+ */
+HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority,
+ int32_t* status);
+} // extern "C"
+/** @} */
diff --git a/hal/src/main/native/include/hal/Types.h b/hal/src/main/native/include/hal/Types.h
new file mode 100644
index 0000000..6180439
--- /dev/null
+++ b/hal/src/main/native/include/hal/Types.h
@@ -0,0 +1,65 @@
+/*----------------------------------------------------------------------------*/
+/* 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>
+
+/**
+ * @defgroup hal_types Type Definitions
+ * @ingroup hal_capi
+ * @{
+ */
+
+#define HAL_kInvalidHandle 0
+
+typedef int32_t HAL_Handle;
+
+typedef HAL_Handle HAL_PortHandle;
+
+typedef HAL_Handle HAL_AnalogInputHandle;
+
+typedef HAL_Handle HAL_AnalogOutputHandle;
+
+typedef HAL_Handle HAL_AnalogTriggerHandle;
+
+typedef HAL_Handle HAL_CompressorHandle;
+
+typedef HAL_Handle HAL_CounterHandle;
+
+typedef HAL_Handle HAL_DigitalHandle;
+
+typedef HAL_Handle HAL_DigitalPWMHandle;
+
+typedef HAL_Handle HAL_EncoderHandle;
+
+typedef HAL_Handle HAL_FPGAEncoderHandle;
+
+typedef HAL_Handle HAL_GyroHandle;
+
+typedef HAL_Handle HAL_InterruptHandle;
+
+typedef HAL_Handle HAL_NotifierHandle;
+
+typedef HAL_Handle HAL_RelayHandle;
+
+typedef HAL_Handle HAL_SolenoidHandle;
+
+typedef HAL_Handle HAL_CANHandle;
+
+typedef HAL_CANHandle HAL_PDPHandle;
+
+typedef int32_t HAL_Bool;
+
+#ifdef __cplusplus
+#define HAL_ENUM(name) enum name : int32_t
+#else
+#define HAL_ENUM(name) \
+ typedef int32_t name; \
+ enum name
+#endif
+/** @} */
diff --git a/hal/src/main/native/include/hal/cpp/Log.h b/hal/src/main/native/include/hal/cpp/Log.h
new file mode 100644
index 0000000..bcc3995
--- /dev/null
+++ b/hal/src/main/native/include/hal/cpp/Log.h
@@ -0,0 +1,128 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <chrono>
+#include <string>
+
+#include <wpi/SmallString.h>
+#include <wpi/raw_ostream.h>
+
+inline std::string NowTime();
+
+enum TLogLevel {
+ logNONE,
+ logERROR,
+ logWARNING,
+ logINFO,
+ logDEBUG,
+ logDEBUG1,
+ logDEBUG2,
+ logDEBUG3,
+ logDEBUG4
+};
+
+class Log {
+ public:
+ Log();
+ virtual ~Log();
+ wpi::raw_ostream& Get(TLogLevel level = logINFO);
+
+ public:
+ static TLogLevel& ReportingLevel();
+ static std::string ToString(TLogLevel level);
+ static TLogLevel FromString(const std::string& level);
+
+ protected:
+ wpi::SmallString<128> buf;
+ wpi::raw_svector_ostream oss{buf};
+
+ private:
+ Log(const Log&);
+ Log& operator=(const Log&);
+};
+
+inline Log::Log() {}
+
+inline wpi::raw_ostream& Log::Get(TLogLevel level) {
+ oss << "- " << NowTime();
+ oss << " " << ToString(level) << ": ";
+ if (level > logDEBUG) {
+ oss << std::string(level - logDEBUG, '\t');
+ }
+ return oss;
+}
+
+inline Log::~Log() {
+ oss << "\n";
+ wpi::errs() << oss.str();
+}
+
+inline TLogLevel& Log::ReportingLevel() {
+ static TLogLevel reportingLevel = logDEBUG4;
+ return reportingLevel;
+}
+
+inline std::string Log::ToString(TLogLevel level) {
+ static const char* const buffer[] = {"NONE", "ERROR", "WARNING",
+ "INFO", "DEBUG", "DEBUG1",
+ "DEBUG2", "DEBUG3", "DEBUG4"};
+ return buffer[level];
+}
+
+inline TLogLevel Log::FromString(const std::string& level) {
+ if (level == "DEBUG4") return logDEBUG4;
+ if (level == "DEBUG3") return logDEBUG3;
+ if (level == "DEBUG2") return logDEBUG2;
+ if (level == "DEBUG1") return logDEBUG1;
+ if (level == "DEBUG") return logDEBUG;
+ if (level == "INFO") return logINFO;
+ if (level == "WARNING") return logWARNING;
+ if (level == "ERROR") return logERROR;
+ if (level == "NONE") return logNONE;
+ Log().Get(logWARNING) << "Unknown logging level '" << level
+ << "'. Using INFO level as default.";
+ return logINFO;
+}
+
+using FILELog = Log; // NOLINT
+
+#define FILE_LOG(level) \
+ if (level > FILELog::ReportingLevel()) \
+ ; \
+ else \
+ Log().Get(level)
+
+inline std::string NowTime() {
+ wpi::SmallString<128> buf;
+ wpi::raw_svector_ostream oss(buf);
+
+ using std::chrono::duration_cast;
+
+ auto now = std::chrono::system_clock::now().time_since_epoch();
+
+ // Hours
+ auto count = duration_cast<std::chrono::hours>(now).count() % 24;
+ if (count < 10) oss << "0";
+ oss << count << ":";
+
+ // Minutes
+ count = duration_cast<std::chrono::minutes>(now).count() % 60;
+ if (count < 10) oss << "0";
+ oss << count << ":";
+
+ // Seconds
+ count = duration_cast<std::chrono::seconds>(now).count() % 60;
+ if (count < 10) oss << "0";
+ oss << count << ".";
+
+ // Milliseconds
+ oss << duration_cast<std::chrono::milliseconds>(now).count() % 1000;
+
+ return oss.str();
+}
diff --git a/hal/src/main/native/include/hal/cpp/SerialHelper.h b/hal/src/main/native/include/hal/cpp/SerialHelper.h
new file mode 100644
index 0000000..9f4d6a0
--- /dev/null
+++ b/hal/src/main/native/include/hal/cpp/SerialHelper.h
@@ -0,0 +1,83 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <string>
+#include <vector>
+
+#include <wpi/SmallString.h>
+#include <wpi/SmallVector.h>
+#include <wpi/mutex.h>
+
+#include "hal/SerialPort.h"
+
+namespace hal {
+/**
+ * A class for deterministically getting information about Serial Ports.
+ */
+class SerialHelper {
+ public:
+ SerialHelper();
+
+ /**
+ * Get the VISA name of a serial port.
+ *
+ * @param port the serial port index
+ * @param status status check
+ * @return the VISA name
+ */
+ std::string GetVISASerialPortName(HAL_SerialPort port, int32_t* status);
+
+ /**
+ * Get the OS name of a serial port.
+ *
+ * @param port the serial port index
+ * @param status status check
+ * @return the OS name
+ */
+ std::string GetOSSerialPortName(HAL_SerialPort port, int32_t* status);
+
+ /**
+ * Get a vector of all serial port VISA names.
+ *
+ * @param status status check
+ * @return vector of serial port VISA names
+ */
+ std::vector<std::string> GetVISASerialPortList(int32_t* status);
+
+ /**
+ * Get a vector of all serial port OS names.
+ *
+ * @param status status check
+ * @return vector of serial port OS names
+ */
+ std::vector<std::string> GetOSSerialPortList(int32_t* status);
+
+ private:
+ void SortHubPathVector();
+ void CoiteratedSort(wpi::SmallVectorImpl<wpi::SmallString<16>>& vec);
+ void QueryHubPaths(int32_t* status);
+
+ int32_t GetIndexForPort(HAL_SerialPort port, int32_t* status);
+
+ // Vectors to hold data before sorting.
+ // Note we will most likely have at max 2 instances, and the longest string
+ // is around 12, so these should never touch the heap;
+ wpi::SmallVector<wpi::SmallString<16>, 4> m_visaResource;
+ wpi::SmallVector<wpi::SmallString<16>, 4> m_osResource;
+ wpi::SmallVector<wpi::SmallString<16>, 4> m_unsortedHubPath;
+ wpi::SmallVector<wpi::SmallString<16>, 4> m_sortedHubPath;
+
+ int32_t m_resourceHandle;
+
+ static wpi::mutex m_nameMutex;
+ static std::string m_usbNames[2];
+};
+} // namespace hal
diff --git a/hal/src/main/native/include/hal/cpp/UnsafeDIO.h b/hal/src/main/native/include/hal/cpp/UnsafeDIO.h
new file mode 100644
index 0000000..ceb41c3
--- /dev/null
+++ b/hal/src/main/native/include/hal/cpp/UnsafeDIO.h
@@ -0,0 +1,95 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <wpi/mutex.h>
+
+#include "hal/ChipObject.h"
+#include "hal/Types.h"
+
+namespace hal {
+
+/**
+ * Proxy class for directly manipulating the DIO pins.
+ *
+ * This class is not copyable or movable, and should never be used
+ * outside of the UnsafeManipulateDIO callback.
+ */
+struct DIOSetProxy {
+ DIOSetProxy(const DIOSetProxy&) = delete;
+ DIOSetProxy(DIOSetProxy&&) = delete;
+ DIOSetProxy& operator=(const DIOSetProxy&) = delete;
+ DIOSetProxy& operator=(DIOSetProxy&&) = delete;
+
+ void SetOutputMode(int32_t* status) {
+ m_dio->writeOutputEnable(m_setOutputDirReg, status);
+ }
+
+ void SetInputMode(int32_t* status) {
+ m_dio->writeOutputEnable(m_unsetOutputDirReg, status);
+ }
+
+ void SetOutputTrue(int32_t* status) {
+ m_dio->writeDO(m_setOutputStateReg, status);
+ }
+
+ void SetOutputFalse(int32_t* status) {
+ m_dio->writeDO(m_unsetOutputStateReg, status);
+ }
+
+ tDIO::tOutputEnable m_setOutputDirReg;
+ tDIO::tOutputEnable m_unsetOutputDirReg;
+ tDIO::tDO m_setOutputStateReg;
+ tDIO::tDO m_unsetOutputStateReg;
+ tDIO* m_dio;
+};
+namespace detail {
+wpi::mutex& UnsafeGetDIOMutex();
+tDIO* UnsafeGetDigialSystem();
+int32_t ComputeDigitalMask(HAL_DigitalHandle handle, int32_t* status);
+} // namespace detail
+
+/**
+ * Unsafe digital output set function
+ * This function can be used to perform fast and determinstically set digital
+ * outputs. This function holds the DIO lock, so calling anyting other then
+ * functions on the Proxy object passed as a parameter can deadlock your
+ * program.
+ *
+ * @param handle the HAL digital handle of the pin to toggle.
+ * @param status status check
+ * @param func A functor taking a ref to a DIOSetProxy object.
+ */
+template <typename Functor>
+void UnsafeManipulateDIO(HAL_DigitalHandle handle, int32_t* status,
+ Functor func) {
+ auto port = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
+ if (port == nullptr) {
+ *status = HAL_HANDLE_ERROR;
+ return;
+ }
+ wpi::mutex& dioMutex = detail::UnsafeGetDIOMutex();
+ tDIO* dSys = detail::UnsafeGetDigialSystem();
+ auto mask = detail::ComputeDigitalMask(handle, status);
+ if (status != 0) return;
+ std::lock_guard<wpi::mutex> lock(dioMutex);
+
+ tDIO::tOutputEnable enableOE = dSys->readOutputEnable(status);
+ enableOE.value |= mask;
+ auto disableOE = enableOE;
+ disableOE.value &= ~mask;
+ tDIO::tDO enableDO = dSys->readDO(status);
+ enableDO.value |= mask;
+ auto disableDO = enableDO;
+ disableDO.value &= ~mask;
+
+ DIOSetProxy dioData{enableOE, disableOE, enableDO, disableDO, dSys};
+ func(dioData);
+}
+
+} // namespace hal
diff --git a/hal/src/main/native/include/hal/cpp/fpga_clock.h b/hal/src/main/native/include/hal/cpp/fpga_clock.h
new file mode 100644
index 0000000..94031b1
--- /dev/null
+++ b/hal/src/main/native/include/hal/cpp/fpga_clock.h
@@ -0,0 +1,35 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <chrono>
+#include <limits>
+
+/** WPILib Hardware Abstraction Layer (HAL) namespace */
+namespace hal {
+
+/**
+ * A std::chrono compatible wrapper around the FPGA Timer.
+ */
+class fpga_clock {
+ public:
+ using rep = std::chrono::microseconds::rep;
+ using period = std::chrono::microseconds::period;
+ using duration = std::chrono::microseconds;
+ using time_point = std::chrono::time_point<fpga_clock>;
+
+ static fpga_clock::time_point now() noexcept;
+ static constexpr bool is_steady = true;
+
+ static fpga_clock::time_point epoch() noexcept { return time_point(zero()); }
+
+ static fpga_clock::duration zero() noexcept { return duration(0); }
+
+ static const time_point min_time;
+};
+} // namespace hal
diff --git a/hal/src/main/native/include/hal/handles/DigitalHandleResource.h b/hal/src/main/native/include/hal/handles/DigitalHandleResource.h
new file mode 100644
index 0000000..23fb676
--- /dev/null
+++ b/hal/src/main/native/include/hal/handles/DigitalHandleResource.h
@@ -0,0 +1,105 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <array>
+#include <memory>
+
+#include <wpi/mutex.h>
+
+#include "hal/Errors.h"
+#include "hal/Types.h"
+#include "hal/handles/HandlesInternal.h"
+
+namespace hal {
+
+/**
+ * The DigitalHandleResource class is a way to track handles. This version
+ * allows a limited number of handles that are allocated by index.
+ * The enum value is seperate, as 2 enum values are allowed per handle
+ * Because they are allocated by index, each individual index holds its own
+ * mutex, which reduces contention heavily.]
+ *
+ * @tparam THandle The Handle Type (Must be typedefed from HAL_Handle)
+ * @tparam TStruct The struct type held by this resource
+ * @tparam size The number of resources allowed to be allocated
+ *
+ */
+template <typename THandle, typename TStruct, int16_t size>
+class DigitalHandleResource : public HandleBase {
+ friend class DigitalHandleResourceTest;
+
+ public:
+ DigitalHandleResource() = default;
+ DigitalHandleResource(const DigitalHandleResource&) = delete;
+ DigitalHandleResource& operator=(const DigitalHandleResource&) = delete;
+
+ THandle Allocate(int16_t index, HAL_HandleEnum enumValue, int32_t* status);
+ std::shared_ptr<TStruct> Get(THandle handle, HAL_HandleEnum enumValue);
+ void Free(THandle handle, HAL_HandleEnum enumValue);
+ void ResetHandles() override;
+
+ private:
+ std::array<std::shared_ptr<TStruct>, size> m_structures;
+ std::array<wpi::mutex, size> m_handleMutexes;
+};
+
+template <typename THandle, typename TStruct, int16_t size>
+THandle DigitalHandleResource<THandle, TStruct, size>::Allocate(
+ int16_t index, HAL_HandleEnum enumValue, int32_t* status) {
+ // don't aquire the lock if we can fail early.
+ if (index < 0 || index >= size) {
+ *status = RESOURCE_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
+ // check for allocation, otherwise allocate and return a valid handle
+ if (m_structures[index] != nullptr) {
+ *status = RESOURCE_IS_ALLOCATED;
+ return HAL_kInvalidHandle;
+ }
+ m_structures[index] = std::make_shared<TStruct>();
+ return static_cast<THandle>(hal::createHandle(index, enumValue, m_version));
+}
+
+template <typename THandle, typename TStruct, int16_t size>
+std::shared_ptr<TStruct> DigitalHandleResource<THandle, TStruct, size>::Get(
+ THandle handle, HAL_HandleEnum enumValue) {
+ // get handle index, and fail early if index out of range or wrong handle
+ int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
+ if (index < 0 || index >= size) {
+ return nullptr;
+ }
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
+ // return structure. Null will propogate correctly, so no need to manually
+ // check.
+ return m_structures[index];
+}
+
+template <typename THandle, typename TStruct, int16_t size>
+void DigitalHandleResource<THandle, TStruct, size>::Free(
+ THandle handle, HAL_HandleEnum enumValue) {
+ // get handle index, and fail early if index out of range or wrong handle
+ int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
+ if (index < 0 || index >= size) return;
+ // lock and deallocated handle
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
+ m_structures[index].reset();
+}
+
+template <typename THandle, typename TStruct, int16_t size>
+void DigitalHandleResource<THandle, TStruct, size>::ResetHandles() {
+ for (int i = 0; i < size; i++) {
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
+ m_structures[i].reset();
+ }
+ HandleBase::ResetHandles();
+}
+} // namespace hal
diff --git a/hal/src/main/native/include/hal/handles/HandlesInternal.h b/hal/src/main/native/include/hal/handles/HandlesInternal.h
new file mode 100644
index 0000000..85b3493
--- /dev/null
+++ b/hal/src/main/native/include/hal/handles/HandlesInternal.h
@@ -0,0 +1,211 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "hal/Types.h"
+
+/* General Handle Data Layout
+ * Bits 0-15: Handle Index
+ * Bits 16-23: 8 bit rolling reset detection
+ * Bits 24-30: Handle Type
+ * Bit 31: 1 if handle error, 0 if no error
+ *
+ * Other specialized handles will use different formats, however Bits 24-31 are
+ * always reserved for type and error handling.
+ */
+
+namespace hal {
+
+/**
+ * Base for all HAL Handles.
+ */
+class HandleBase {
+ public:
+ HandleBase();
+ ~HandleBase();
+ HandleBase(const HandleBase&) = delete;
+ HandleBase& operator=(const HandleBase&) = delete;
+ virtual void ResetHandles();
+ static void ResetGlobalHandles();
+
+ protected:
+ int16_t m_version;
+};
+
+constexpr int16_t InvalidHandleIndex = -1;
+
+/**
+ * Enum of HAL handle types. Vendors/Teams should use Vendor (17).
+ */
+enum class HAL_HandleEnum {
+ Undefined = 0,
+ DIO = 1,
+ Port = 2,
+ Notifier = 3,
+ Interrupt = 4,
+ AnalogOutput = 5,
+ AnalogInput = 6,
+ AnalogTrigger = 7,
+ Relay = 8,
+ PWM = 9,
+ DigitalPWM = 10,
+ Counter = 11,
+ FPGAEncoder = 12,
+ Encoder = 13,
+ Compressor = 14,
+ Solenoid = 15,
+ AnalogGyro = 16,
+ Vendor = 17,
+ SimulationJni = 18,
+ CAN = 19,
+};
+
+/**
+ * Get the handle index from a handle.
+ *
+ * @param handle the handle
+ * @return the index
+ */
+static inline int16_t getHandleIndex(HAL_Handle handle) {
+ // mask and return last 16 bits
+ return static_cast<int16_t>(handle & 0xffff);
+}
+
+/**
+ * Get the handle type from a handle.
+ *
+ * @param handle the handle
+ * @return the type
+ */
+static inline HAL_HandleEnum getHandleType(HAL_Handle handle) {
+ // mask first 8 bits and cast to enum
+ return static_cast<HAL_HandleEnum>((handle >> 24) & 0xff);
+}
+
+/**
+ * Get if the handle is a specific type.
+ *
+ * @param handle the handle
+ * @param handleType the type to check
+ * @return true if the type is correct, otherwise false
+ */
+static inline bool isHandleType(HAL_Handle handle, HAL_HandleEnum handleType) {
+ return handleType == getHandleType(handle);
+}
+
+/**
+ * Get if the version of the handle is correct.
+ *
+ * Do not use on the roboRIO, used specifically for the sim to handle resets.
+ *
+ * @param handle the handle
+ * @param version the handle version to check
+ * @return true if the handle is the right version, otherwise false
+ */
+static inline bool isHandleCorrectVersion(HAL_Handle handle, int16_t version) {
+ return (((handle & 0xFF0000) >> 16) & version) == version;
+}
+
+/**
+ * Get if the handle is a correct type and version.
+ *
+ * Note the version is not checked on the roboRIO.
+ *
+ * @param handle the handle
+ * @param handleType the type to check
+ * @param version the handle version to check
+ * @return true if the handle is proper version and type, otherwise
+ * false.
+ */
+static inline int16_t getHandleTypedIndex(HAL_Handle handle,
+ HAL_HandleEnum enumType,
+ int16_t version) {
+ if (!isHandleType(handle, enumType)) return InvalidHandleIndex;
+#if !defined(__FRC_ROBORIO__)
+ if (!isHandleCorrectVersion(handle, version)) return InvalidHandleIndex;
+#endif
+ return getHandleIndex(handle);
+}
+
+/* specialized functions for Port handle
+ * Port Handle Data Layout
+ * Bits 0-7: Channel Number
+ * Bits 8-15: Module Number
+ * Bits 16-23: Unused
+ * Bits 24-30: Handle Type
+ * Bit 31: 1 if handle error, 0 if no error
+ */
+
+// using a 16 bit value so we can store 0-255 and still report error
+/**
+ * Gets the port channel of a port handle.
+ *
+ * @param handle the port handle
+ * @return the port channel
+ */
+static inline int16_t getPortHandleChannel(HAL_PortHandle handle) {
+ if (!isHandleType(handle, HAL_HandleEnum::Port)) return InvalidHandleIndex;
+ return static_cast<uint8_t>(handle & 0xff);
+}
+
+// using a 16 bit value so we can store 0-255 and still report error
+/**
+ * Gets the port module of a port handle.
+ *
+ * @param handle the port handle
+ * @return the port module
+ */
+static inline int16_t getPortHandleModule(HAL_PortHandle handle) {
+ if (!isHandleType(handle, HAL_HandleEnum::Port)) return InvalidHandleIndex;
+ return static_cast<uint8_t>((handle >> 8) & 0xff);
+}
+
+// using a 16 bit value so we can store 0-255 and still report error
+/**
+ * Gets the SPI channel of a port handle.
+ *
+ * @param handle the port handle
+ * @return the port SPI channel
+ */
+static inline int16_t getPortHandleSPIEnable(HAL_PortHandle handle) {
+ if (!isHandleType(handle, HAL_HandleEnum::Port)) return InvalidHandleIndex;
+ return static_cast<uint8_t>((handle >> 16) & 0xff);
+}
+
+/**
+ * Create a port handle.
+ *
+ * @param channel the channel
+ * @param module the module
+ * @return port handle for the module and channel
+ */
+HAL_PortHandle createPortHandle(uint8_t channel, uint8_t module);
+
+/**
+ * Create a port handle for SPI.
+ *
+ * @param channel the SPI channel
+ * @return port handle for the channel
+ */
+HAL_PortHandle createPortHandleForSPI(uint8_t channel);
+
+/**
+ * Create a handle for a specific index, type and version.
+ *
+ * Note the version is not checked on the roboRIO.
+ *
+ * @param index the index
+ * @param handleType the handle type
+ * @param version the handle version
+ * @return the created handle
+ */
+HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType,
+ int16_t version);
+} // namespace hal
diff --git a/hal/src/main/native/include/hal/handles/IndexedClassedHandleResource.h b/hal/src/main/native/include/hal/handles/IndexedClassedHandleResource.h
new file mode 100644
index 0000000..a038e04
--- /dev/null
+++ b/hal/src/main/native/include/hal/handles/IndexedClassedHandleResource.h
@@ -0,0 +1,117 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <array>
+#include <memory>
+#include <vector>
+
+#include <wpi/mutex.h>
+
+#include "hal/Errors.h"
+#include "hal/Types.h"
+#include "hal/handles/HandlesInternal.h"
+
+namespace hal {
+
+/**
+ * The IndexedClassedHandleResource class is a way to track handles. This
+ * version
+ * allows a limited number of handles that are allocated by index.
+ * Because they are allocated by index, each individual index holds its own
+ * mutex, which reduces contention heavily.]
+ *
+ * @tparam THandle The Handle Type (Must be typedefed from HAL_Handle)
+ * @tparam TStruct The struct type held by this resource
+ * @tparam size The number of resources allowed to be allocated
+ * @tparam enumValue The type value stored in the handle
+ *
+ */
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+class IndexedClassedHandleResource : public HandleBase {
+ friend class IndexedClassedHandleResourceTest;
+
+ public:
+ IndexedClassedHandleResource() = default;
+ IndexedClassedHandleResource(const IndexedClassedHandleResource&) = delete;
+ IndexedClassedHandleResource& operator=(const IndexedClassedHandleResource&) =
+ delete;
+
+ THandle Allocate(int16_t index, std::shared_ptr<TStruct> toSet,
+ int32_t* status);
+ std::shared_ptr<TStruct> Get(THandle handle);
+ void Free(THandle handle);
+ void ResetHandles();
+
+ private:
+ std::array<std::shared_ptr<TStruct>, size> m_structures;
+ std::array<wpi::mutex, size> m_handleMutexes;
+};
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+THandle
+IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
+ int16_t index, std::shared_ptr<TStruct> toSet, int32_t* status) {
+ // don't aquire the lock if we can fail early.
+ if (index < 0 || index >= size) {
+ *status = RESOURCE_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
+ // check for allocation, otherwise allocate and return a valid handle
+ if (m_structures[index] != nullptr) {
+ *status = RESOURCE_IS_ALLOCATED;
+ return HAL_kInvalidHandle;
+ }
+ m_structures[index] = toSet;
+ return static_cast<THandle>(hal::createHandle(index, enumValue, m_version));
+}
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+std::shared_ptr<TStruct>
+IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Get(
+ THandle handle) {
+ // get handle index, and fail early if index out of range or wrong handle
+ int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
+ if (index < 0 || index >= size) {
+ return nullptr;
+ }
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
+ // return structure. Null will propogate correctly, so no need to manually
+ // check.
+ return m_structures[index];
+}
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+void IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Free(
+ THandle handle) {
+ // get handle index, and fail early if index out of range or wrong handle
+ int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
+ if (index < 0 || index >= size) return;
+ // lock and deallocated handle
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
+ m_structures[index].reset();
+}
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+void IndexedClassedHandleResource<THandle, TStruct, size,
+ enumValue>::ResetHandles() {
+ for (int i = 0; i < size; i++) {
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
+ m_structures[i].reset();
+ }
+ HandleBase::ResetHandles();
+}
+} // namespace hal
diff --git a/hal/src/main/native/include/hal/handles/IndexedHandleResource.h b/hal/src/main/native/include/hal/handles/IndexedHandleResource.h
new file mode 100644
index 0000000..39abf58
--- /dev/null
+++ b/hal/src/main/native/include/hal/handles/IndexedHandleResource.h
@@ -0,0 +1,110 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <array>
+#include <memory>
+
+#include <wpi/mutex.h>
+
+#include "hal/Errors.h"
+#include "hal/Types.h"
+#include "hal/handles/HandlesInternal.h"
+
+namespace hal {
+
+/**
+ * The IndexedHandleResource class is a way to track handles. This version
+ * allows a limited number of handles that are allocated by index.
+ * Because they are allocated by index, each individual index holds its own
+ * mutex, which reduces contention heavily.]
+ *
+ * @tparam THandle The Handle Type (Must be typedefed from HAL_Handle)
+ * @tparam TStruct The struct type held by this resource
+ * @tparam size The number of resources allowed to be allocated
+ * @tparam enumValue The type value stored in the handle
+ *
+ */
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+class IndexedHandleResource : public HandleBase {
+ friend class IndexedHandleResourceTest;
+
+ public:
+ IndexedHandleResource() = default;
+ IndexedHandleResource(const IndexedHandleResource&) = delete;
+ IndexedHandleResource& operator=(const IndexedHandleResource&) = delete;
+
+ THandle Allocate(int16_t index, int32_t* status);
+ std::shared_ptr<TStruct> Get(THandle handle);
+ void Free(THandle handle);
+ void ResetHandles() override;
+
+ private:
+ std::array<std::shared_ptr<TStruct>, size> m_structures;
+ std::array<wpi::mutex, size> m_handleMutexes;
+};
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+THandle IndexedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
+ int16_t index, int32_t* status) {
+ // don't aquire the lock if we can fail early.
+ if (index < 0 || index >= size) {
+ *status = RESOURCE_OUT_OF_RANGE;
+ return HAL_kInvalidHandle;
+ }
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
+ // check for allocation, otherwise allocate and return a valid handle
+ if (m_structures[index] != nullptr) {
+ *status = RESOURCE_IS_ALLOCATED;
+ return HAL_kInvalidHandle;
+ }
+ m_structures[index] = std::make_shared<TStruct>();
+ return static_cast<THandle>(hal::createHandle(index, enumValue, m_version));
+}
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+std::shared_ptr<TStruct>
+IndexedHandleResource<THandle, TStruct, size, enumValue>::Get(THandle handle) {
+ // get handle index, and fail early if index out of range or wrong handle
+ int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
+ if (index < 0 || index >= size) {
+ return nullptr;
+ }
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
+ // return structure. Null will propogate correctly, so no need to manually
+ // check.
+ return m_structures[index];
+}
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+void IndexedHandleResource<THandle, TStruct, size, enumValue>::Free(
+ THandle handle) {
+ // get handle index, and fail early if index out of range or wrong handle
+ int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
+ if (index < 0 || index >= size) return;
+ // lock and deallocated handle
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
+ m_structures[index].reset();
+}
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+void IndexedHandleResource<THandle, TStruct, size, enumValue>::ResetHandles() {
+ for (int i = 0; i < size; i++) {
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
+ m_structures[i].reset();
+ }
+ HandleBase::ResetHandles();
+}
+} // namespace hal
diff --git a/hal/src/main/native/include/hal/handles/LimitedClassedHandleResource.h b/hal/src/main/native/include/hal/handles/LimitedClassedHandleResource.h
new file mode 100644
index 0000000..2723129
--- /dev/null
+++ b/hal/src/main/native/include/hal/handles/LimitedClassedHandleResource.h
@@ -0,0 +1,116 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <array>
+#include <memory>
+
+#include <wpi/mutex.h>
+
+#include "hal/Types.h"
+#include "hal/handles/HandlesInternal.h"
+
+namespace hal {
+
+/**
+ * The LimitedClassedHandleResource class is a way to track handles. This
+ * version
+ * allows a limited number of handles that are allocated sequentially.
+ *
+ * @tparam THandle The Handle Type (Must be typedefed from HAL_Handle)
+ * @tparam TStruct The struct type held by this resource
+ * @tparam size The number of resources allowed to be allocated
+ * @tparam enumValue The type value stored in the handle
+ *
+ */
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+class LimitedClassedHandleResource : public HandleBase {
+ friend class LimitedClassedHandleResourceTest;
+
+ public:
+ LimitedClassedHandleResource() = default;
+ LimitedClassedHandleResource(const LimitedClassedHandleResource&) = delete;
+ LimitedClassedHandleResource& operator=(const LimitedClassedHandleResource&) =
+ delete;
+
+ THandle Allocate(std::shared_ptr<TStruct> toSet);
+ std::shared_ptr<TStruct> Get(THandle handle);
+ void Free(THandle handle);
+ void ResetHandles() override;
+
+ private:
+ std::array<std::shared_ptr<TStruct>, size> m_structures;
+ std::array<wpi::mutex, size> m_handleMutexes;
+ wpi::mutex m_allocateMutex;
+};
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+THandle
+LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
+ std::shared_ptr<TStruct> toSet) {
+ // globally lock to loop through indices
+ std::lock_guard<wpi::mutex> lock(m_allocateMutex);
+ for (int16_t i = 0; i < size; i++) {
+ if (m_structures[i] == nullptr) {
+ // if a false index is found, grab its specific mutex
+ // and allocate it.
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
+ m_structures[i] = toSet;
+ return static_cast<THandle>(createHandle(i, enumValue, m_version));
+ }
+ }
+ return HAL_kInvalidHandle;
+}
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+std::shared_ptr<TStruct>
+LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Get(
+ THandle handle) {
+ // get handle index, and fail early if index out of range or wrong handle
+ int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
+ if (index < 0 || index >= size) {
+ return nullptr;
+ }
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
+ // return structure. Null will propogate correctly, so no need to manually
+ // check.
+ return m_structures[index];
+}
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+void LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Free(
+ THandle handle) {
+ // get handle index, and fail early if index out of range or wrong handle
+ int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
+ if (index < 0 || index >= size) return;
+ // lock and deallocated handle
+ std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
+ std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[index]);
+ m_structures[index].reset();
+}
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+void LimitedClassedHandleResource<THandle, TStruct, size,
+ enumValue>::ResetHandles() {
+ {
+ std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
+ for (int i = 0; i < size; i++) {
+ std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[i]);
+ m_structures[i].reset();
+ }
+ }
+ HandleBase::ResetHandles();
+}
+} // namespace hal
diff --git a/hal/src/main/native/include/hal/handles/LimitedHandleResource.h b/hal/src/main/native/include/hal/handles/LimitedHandleResource.h
new file mode 100644
index 0000000..a535829
--- /dev/null
+++ b/hal/src/main/native/include/hal/handles/LimitedHandleResource.h
@@ -0,0 +1,110 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <array>
+#include <memory>
+
+#include <wpi/mutex.h>
+
+#include "HandlesInternal.h"
+#include "hal/Types.h"
+
+namespace hal {
+
+/**
+ * The LimitedHandleResource class is a way to track handles. This version
+ * allows a limited number of handles that are allocated sequentially.
+ *
+ * @tparam THandle The Handle Type (Must be typedefed from HAL_Handle)
+ * @tparam TStruct The struct type held by this resource
+ * @tparam size The number of resources allowed to be allocated
+ * @tparam enumValue The type value stored in the handle
+ *
+ */
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+class LimitedHandleResource : public HandleBase {
+ friend class LimitedHandleResourceTest;
+
+ public:
+ LimitedHandleResource() = default;
+ LimitedHandleResource(const LimitedHandleResource&) = delete;
+ LimitedHandleResource& operator=(const LimitedHandleResource&) = delete;
+
+ THandle Allocate();
+ std::shared_ptr<TStruct> Get(THandle handle);
+ void Free(THandle handle);
+ void ResetHandles() override;
+
+ private:
+ std::array<std::shared_ptr<TStruct>, size> m_structures;
+ std::array<wpi::mutex, size> m_handleMutexes;
+ wpi::mutex m_allocateMutex;
+};
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+THandle LimitedHandleResource<THandle, TStruct, size, enumValue>::Allocate() {
+ // globally lock to loop through indices
+ std::lock_guard<wpi::mutex> lock(m_allocateMutex);
+ for (int16_t i = 0; i < size; i++) {
+ if (m_structures[i] == nullptr) {
+ // if a false index is found, grab its specific mutex
+ // and allocate it.
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
+ m_structures[i] = std::make_shared<TStruct>();
+ return static_cast<THandle>(createHandle(i, enumValue, m_version));
+ }
+ }
+ return HAL_kInvalidHandle;
+}
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+std::shared_ptr<TStruct>
+LimitedHandleResource<THandle, TStruct, size, enumValue>::Get(THandle handle) {
+ // get handle index, and fail early if index out of range or wrong handle
+ int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
+ if (index < 0 || index >= size) {
+ return nullptr;
+ }
+ std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
+ // return structure. Null will propogate correctly, so no need to manually
+ // check.
+ return m_structures[index];
+}
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+void LimitedHandleResource<THandle, TStruct, size, enumValue>::Free(
+ THandle handle) {
+ // get handle index, and fail early if index out of range or wrong handle
+ int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
+ if (index < 0 || index >= size) return;
+ // lock and deallocated handle
+ std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
+ std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[index]);
+ m_structures[index].reset();
+}
+
+template <typename THandle, typename TStruct, int16_t size,
+ HAL_HandleEnum enumValue>
+void LimitedHandleResource<THandle, TStruct, size, enumValue>::ResetHandles() {
+ {
+ std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
+ for (int i = 0; i < size; i++) {
+ std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[i]);
+ m_structures[i].reset();
+ }
+ }
+ HandleBase::ResetHandles();
+}
+} // namespace hal
diff --git a/hal/src/main/native/include/hal/handles/UnlimitedHandleResource.h b/hal/src/main/native/include/hal/handles/UnlimitedHandleResource.h
new file mode 100644
index 0000000..7df8061
--- /dev/null
+++ b/hal/src/main/native/include/hal/handles/UnlimitedHandleResource.h
@@ -0,0 +1,126 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-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 <utility>
+#include <vector>
+
+#include <wpi/mutex.h>
+
+#include "hal/Types.h"
+#include "hal/handles/HandlesInternal.h"
+
+namespace hal {
+
+/**
+ * The UnlimitedHandleResource class is a way to track handles. This version
+ * allows an unlimted number of handles that are allocated sequentially. When
+ * possible, indices are reused to save memory usage and keep the array length
+ * down.
+ * However, automatic array management has not been implemented, but might be in
+ * the future.
+ * Because we have to loop through the allocator, we must use a global mutex.
+
+ * @tparam THandle The Handle Type (Must be typedefed from HAL_Handle)
+ * @tparam TStruct The struct type held by this resource
+ * @tparam enumValue The type value stored in the handle
+ *
+ */
+template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
+class UnlimitedHandleResource : public HandleBase {
+ friend class UnlimitedHandleResourceTest;
+
+ public:
+ UnlimitedHandleResource() = default;
+ UnlimitedHandleResource(const UnlimitedHandleResource&) = delete;
+ UnlimitedHandleResource& operator=(const UnlimitedHandleResource&) = delete;
+
+ THandle Allocate(std::shared_ptr<TStruct> structure);
+ std::shared_ptr<TStruct> Get(THandle handle);
+ /* Returns structure previously at that handle (or nullptr if none) */
+ std::shared_ptr<TStruct> Free(THandle handle);
+ void ResetHandles() override;
+
+ /* Calls func(THandle, TStruct*) for each handle. Note this holds the
+ * global lock for the entirety of execution.
+ */
+ template <typename Functor>
+ void ForEach(Functor func);
+
+ private:
+ std::vector<std::shared_ptr<TStruct>> m_structures;
+ wpi::mutex m_handleMutex;
+};
+
+template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
+THandle UnlimitedHandleResource<THandle, TStruct, enumValue>::Allocate(
+ std::shared_ptr<TStruct> structure) {
+ std::lock_guard<wpi::mutex> lock(m_handleMutex);
+ size_t i;
+ for (i = 0; i < m_structures.size(); i++) {
+ if (m_structures[i] == nullptr) {
+ m_structures[i] = structure;
+ return static_cast<THandle>(createHandle(i, enumValue, m_version));
+ }
+ }
+ if (i >= INT16_MAX) return HAL_kInvalidHandle;
+
+ m_structures.push_back(structure);
+ return static_cast<THandle>(
+ createHandle(static_cast<int16_t>(i), enumValue, m_version));
+}
+
+template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
+std::shared_ptr<TStruct>
+UnlimitedHandleResource<THandle, TStruct, enumValue>::Get(THandle handle) {
+ int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
+ std::lock_guard<wpi::mutex> lock(m_handleMutex);
+ if (index < 0 || index >= static_cast<int16_t>(m_structures.size()))
+ return nullptr;
+ return m_structures[index];
+}
+
+template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
+std::shared_ptr<TStruct>
+UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(THandle handle) {
+ int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
+ std::lock_guard<wpi::mutex> lock(m_handleMutex);
+ if (index < 0 || index >= static_cast<int16_t>(m_structures.size()))
+ return nullptr;
+ return std::move(m_structures[index]);
+}
+
+template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
+void UnlimitedHandleResource<THandle, TStruct, enumValue>::ResetHandles() {
+ {
+ std::lock_guard<wpi::mutex> lock(m_handleMutex);
+ for (size_t i = 0; i < m_structures.size(); i++) {
+ m_structures[i].reset();
+ }
+ }
+ HandleBase::ResetHandles();
+}
+
+template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
+template <typename Functor>
+void UnlimitedHandleResource<THandle, TStruct, enumValue>::ForEach(
+ Functor func) {
+ std::lock_guard<wpi::mutex> lock(m_handleMutex);
+ size_t i;
+ for (i = 0; i < m_structures.size(); i++) {
+ if (m_structures[i] != nullptr) {
+ func(static_cast<THandle>(createHandle(i, enumValue, m_version)),
+ m_structures[i].get());
+ }
+ }
+}
+
+} // namespace hal
diff --git a/hal/src/main/native/include/hal/labview/HAL.h b/hal/src/main/native/include/hal/labview/HAL.h
new file mode 100644
index 0000000..db9f20f
--- /dev/null
+++ b/hal/src/main/native/include/hal/labview/HAL.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
+
+#define HAL_USE_LABVIEW
+
+#include "hal/DriverStation.h"
+#include "hal/HAL.h"
+#include "hal/Types.h"
diff --git a/hal/src/main/native/include/mockdata/AccelerometerData.h b/hal/src/main/native/include/mockdata/AccelerometerData.h
new file mode 100644
index 0000000..79f151d
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/AccelerometerData.h
@@ -0,0 +1,70 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Accelerometer.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetAccelerometerData(int32_t index);
+int32_t HALSIM_RegisterAccelerometerActiveCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAccelerometerActiveCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetAccelerometerActive(int32_t index);
+void HALSIM_SetAccelerometerActive(int32_t index, HAL_Bool active);
+
+int32_t HALSIM_RegisterAccelerometerRangeCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAccelerometerRangeCallback(int32_t index, int32_t uid);
+HAL_AccelerometerRange HALSIM_GetAccelerometerRange(int32_t index);
+void HALSIM_SetAccelerometerRange(int32_t index, HAL_AccelerometerRange range);
+
+int32_t HALSIM_RegisterAccelerometerXCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAccelerometerXCallback(int32_t index, int32_t uid);
+double HALSIM_GetAccelerometerX(int32_t index);
+void HALSIM_SetAccelerometerX(int32_t index, double x);
+
+int32_t HALSIM_RegisterAccelerometerYCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAccelerometerYCallback(int32_t index, int32_t uid);
+double HALSIM_GetAccelerometerY(int32_t index);
+void HALSIM_SetAccelerometerY(int32_t index, double y);
+
+int32_t HALSIM_RegisterAccelerometerZCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAccelerometerZCallback(int32_t index, int32_t uid);
+double HALSIM_GetAccelerometerZ(int32_t index);
+void HALSIM_SetAccelerometerZ(int32_t index, double z);
+
+void HALSIM_RegisterAccelerometerAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/AnalogGyroData.h b/hal/src/main/native/include/mockdata/AnalogGyroData.h
new file mode 100644
index 0000000..5b648ee
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/AnalogGyroData.h
@@ -0,0 +1,51 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetAnalogGyroData(int32_t index);
+int32_t HALSIM_RegisterAnalogGyroAngleCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogGyroAngleCallback(int32_t index, int32_t uid);
+double HALSIM_GetAnalogGyroAngle(int32_t index);
+void HALSIM_SetAnalogGyroAngle(int32_t index, double angle);
+
+int32_t HALSIM_RegisterAnalogGyroRateCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogGyroRateCallback(int32_t index, int32_t uid);
+double HALSIM_GetAnalogGyroRate(int32_t index);
+void HALSIM_SetAnalogGyroRate(int32_t index, double rate);
+
+int32_t HALSIM_RegisterAnalogGyroInitializedCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogGyroInitializedCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetAnalogGyroInitialized(int32_t index);
+void HALSIM_SetAnalogGyroInitialized(int32_t index, HAL_Bool initialized);
+
+void HALSIM_RegisterAnalogGyroAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/AnalogInData.h b/hal/src/main/native/include/mockdata/AnalogInData.h
new file mode 100644
index 0000000..7a95164
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/AnalogInData.h
@@ -0,0 +1,101 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetAnalogInData(int32_t index);
+int32_t HALSIM_RegisterAnalogInInitializedCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogInInitializedCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetAnalogInInitialized(int32_t index);
+void HALSIM_SetAnalogInInitialized(int32_t index, HAL_Bool initialized);
+
+int32_t HALSIM_RegisterAnalogInAverageBitsCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogInAverageBitsCallback(int32_t index, int32_t uid);
+int32_t HALSIM_GetAnalogInAverageBits(int32_t index);
+void HALSIM_SetAnalogInAverageBits(int32_t index, int32_t averageBits);
+
+int32_t HALSIM_RegisterAnalogInOversampleBitsCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogInOversampleBitsCallback(int32_t index, int32_t uid);
+int32_t HALSIM_GetAnalogInOversampleBits(int32_t index);
+void HALSIM_SetAnalogInOversampleBits(int32_t index, int32_t oversampleBits);
+
+int32_t HALSIM_RegisterAnalogInVoltageCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogInVoltageCallback(int32_t index, int32_t uid);
+double HALSIM_GetAnalogInVoltage(int32_t index);
+void HALSIM_SetAnalogInVoltage(int32_t index, double voltage);
+
+int32_t HALSIM_RegisterAnalogInAccumulatorInitializedCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogInAccumulatorInitializedCallback(int32_t index,
+ int32_t uid);
+HAL_Bool HALSIM_GetAnalogInAccumulatorInitialized(int32_t index);
+void HALSIM_SetAnalogInAccumulatorInitialized(int32_t index,
+ HAL_Bool accumulatorInitialized);
+
+int32_t HALSIM_RegisterAnalogInAccumulatorValueCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogInAccumulatorValueCallback(int32_t index, int32_t uid);
+int64_t HALSIM_GetAnalogInAccumulatorValue(int32_t index);
+void HALSIM_SetAnalogInAccumulatorValue(int32_t index,
+ int64_t accumulatorValue);
+
+int32_t HALSIM_RegisterAnalogInAccumulatorCountCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogInAccumulatorCountCallback(int32_t index, int32_t uid);
+int64_t HALSIM_GetAnalogInAccumulatorCount(int32_t index);
+void HALSIM_SetAnalogInAccumulatorCount(int32_t index,
+ int64_t accumulatorCount);
+
+int32_t HALSIM_RegisterAnalogInAccumulatorCenterCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogInAccumulatorCenterCallback(int32_t index, int32_t uid);
+int32_t HALSIM_GetAnalogInAccumulatorCenter(int32_t index);
+void HALSIM_SetAnalogInAccumulatorCenter(int32_t index,
+ int32_t accumulatorCenter);
+
+int32_t HALSIM_RegisterAnalogInAccumulatorDeadbandCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogInAccumulatorDeadbandCallback(int32_t index,
+ int32_t uid);
+int32_t HALSIM_GetAnalogInAccumulatorDeadband(int32_t index);
+void HALSIM_SetAnalogInAccumulatorDeadband(int32_t index,
+ int32_t accumulatorDeadband);
+
+void HALSIM_RegisterAnalogInAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/AnalogOutData.h b/hal/src/main/native/include/mockdata/AnalogOutData.h
new file mode 100644
index 0000000..48046ec
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/AnalogOutData.h
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetAnalogOutData(int32_t index);
+int32_t HALSIM_RegisterAnalogOutVoltageCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogOutVoltageCallback(int32_t index, int32_t uid);
+double HALSIM_GetAnalogOutVoltage(int32_t index);
+void HALSIM_SetAnalogOutVoltage(int32_t index, double voltage);
+
+int32_t HALSIM_RegisterAnalogOutInitializedCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogOutInitializedCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetAnalogOutInitialized(int32_t index);
+void HALSIM_SetAnalogOutInitialized(int32_t index, HAL_Bool initialized);
+
+void HALSIM_RegisterAnalogOutAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/AnalogTriggerData.h b/hal/src/main/native/include/mockdata/AnalogTriggerData.h
new file mode 100644
index 0000000..8146b8f
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/AnalogTriggerData.h
@@ -0,0 +1,68 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+enum HALSIM_AnalogTriggerMode : int32_t {
+ HALSIM_AnalogTriggerUnassigned,
+ HALSIM_AnalogTriggerFiltered,
+ HALSIM_AnalogTriggerAveraged
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetAnalogTriggerData(int32_t index);
+int32_t HALSIM_RegisterAnalogTriggerInitializedCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogTriggerInitializedCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetAnalogTriggerInitialized(int32_t index);
+void HALSIM_SetAnalogTriggerInitialized(int32_t index, HAL_Bool initialized);
+
+int32_t HALSIM_RegisterAnalogTriggerTriggerLowerBoundCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogTriggerTriggerLowerBoundCallback(int32_t index,
+ int32_t uid);
+double HALSIM_GetAnalogTriggerTriggerLowerBound(int32_t index);
+void HALSIM_SetAnalogTriggerTriggerLowerBound(int32_t index,
+ double triggerLowerBound);
+
+int32_t HALSIM_RegisterAnalogTriggerTriggerUpperBoundCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogTriggerTriggerUpperBoundCallback(int32_t index,
+ int32_t uid);
+double HALSIM_GetAnalogTriggerTriggerUpperBound(int32_t index);
+void HALSIM_SetAnalogTriggerTriggerUpperBound(int32_t index,
+ double triggerUpperBound);
+
+int32_t HALSIM_RegisterAnalogTriggerTriggerModeCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelAnalogTriggerTriggerModeCallback(int32_t index, int32_t uid);
+HALSIM_AnalogTriggerMode HALSIM_GetAnalogTriggerTriggerMode(int32_t index);
+void HALSIM_SetAnalogTriggerTriggerMode(int32_t index,
+ HALSIM_AnalogTriggerMode triggerMode);
+
+void HALSIM_RegisterAnalogTriggerAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/CanData.h b/hal/src/main/native/include/mockdata/CanData.h
new file mode 100644
index 0000000..4d76dca
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/CanData.h
@@ -0,0 +1,78 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "HAL_Value.h"
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+typedef void (*HAL_CAN_SendMessageCallback)(const char* name, void* param,
+ uint32_t messageID,
+ const uint8_t* data,
+ uint8_t dataSize, int32_t periodMs,
+ int32_t* status);
+
+typedef void (*HAL_CAN_ReceiveMessageCallback)(
+ const char* name, void* param, uint32_t* messageID, uint32_t messageIDMask,
+ uint8_t* data, uint8_t* dataSize, uint32_t* timeStamp, int32_t* status);
+
+typedef void (*HAL_CAN_OpenStreamSessionCallback)(
+ const char* name, void* param, uint32_t* sessionHandle, uint32_t messageID,
+ uint32_t messageIDMask, uint32_t maxMessages, int32_t* status);
+
+typedef void (*HAL_CAN_CloseStreamSessionCallback)(const char* name,
+ void* param,
+ uint32_t sessionHandle);
+
+typedef void (*HAL_CAN_ReadStreamSessionCallback)(
+ const char* name, void* param, uint32_t sessionHandle,
+ struct HAL_CANStreamMessage* messages, uint32_t messagesToRead,
+ uint32_t* messagesRead, int32_t* status);
+
+typedef void (*HAL_CAN_GetCANStatusCallback)(
+ const char* name, void* param, float* percentBusUtilization,
+ uint32_t* busOffCount, uint32_t* txFullCount, uint32_t* receiveErrorCount,
+ uint32_t* transmitErrorCount, int32_t* status);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetCanData(void);
+
+int32_t HALSIM_RegisterCanSendMessageCallback(
+ HAL_CAN_SendMessageCallback callback, void* param);
+void HALSIM_CancelCanSendMessageCallback(int32_t uid);
+
+int32_t HALSIM_RegisterCanReceiveMessageCallback(
+ HAL_CAN_ReceiveMessageCallback callback, void* param);
+void HALSIM_CancelCanReceiveMessageCallback(int32_t uid);
+
+int32_t HALSIM_RegisterCanOpenStreamCallback(
+ HAL_CAN_OpenStreamSessionCallback callback, void* param);
+void HALSIM_CancelCanOpenStreamCallback(int32_t uid);
+
+int32_t HALSIM_RegisterCanCloseStreamCallback(
+ HAL_CAN_CloseStreamSessionCallback callback, void* param);
+void HALSIM_CancelCanCloseStreamCallback(int32_t uid);
+
+int32_t HALSIM_RegisterCanReadStreamCallback(
+ HAL_CAN_ReadStreamSessionCallback callback, void* param);
+void HALSIM_CancelCanReadStreamCallback(int32_t uid);
+
+int32_t HALSIM_RegisterCanGetCANStatusCallback(
+ HAL_CAN_GetCANStatusCallback callback, void* param);
+void HALSIM_CancelCanGetCANStatusCallback(int32_t uid);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/DIOData.h b/hal/src/main/native/include/mockdata/DIOData.h
new file mode 100644
index 0000000..b3bd9f2
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/DIOData.h
@@ -0,0 +1,65 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetDIOData(int32_t index);
+int32_t HALSIM_RegisterDIOInitializedCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelDIOInitializedCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetDIOInitialized(int32_t index);
+void HALSIM_SetDIOInitialized(int32_t index, HAL_Bool initialized);
+
+int32_t HALSIM_RegisterDIOValueCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+void HALSIM_CancelDIOValueCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetDIOValue(int32_t index);
+void HALSIM_SetDIOValue(int32_t index, HAL_Bool value);
+
+int32_t HALSIM_RegisterDIOPulseLengthCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelDIOPulseLengthCallback(int32_t index, int32_t uid);
+double HALSIM_GetDIOPulseLength(int32_t index);
+void HALSIM_SetDIOPulseLength(int32_t index, double pulseLength);
+
+int32_t HALSIM_RegisterDIOIsInputCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+void HALSIM_CancelDIOIsInputCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetDIOIsInput(int32_t index);
+void HALSIM_SetDIOIsInput(int32_t index, HAL_Bool isInput);
+
+int32_t HALSIM_RegisterDIOFilterIndexCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelDIOFilterIndexCallback(int32_t index, int32_t uid);
+int32_t HALSIM_GetDIOFilterIndex(int32_t index);
+void HALSIM_SetDIOFilterIndex(int32_t index, int32_t filterIndex);
+
+void HALSIM_RegisterDIOAllCallbacks(int32_t index, HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/DigitalPWMData.h b/hal/src/main/native/include/mockdata/DigitalPWMData.h
new file mode 100644
index 0000000..d35e313
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/DigitalPWMData.h
@@ -0,0 +1,51 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetDigitalPWMData(int32_t index);
+int32_t HALSIM_RegisterDigitalPWMInitializedCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelDigitalPWMInitializedCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetDigitalPWMInitialized(int32_t index);
+void HALSIM_SetDigitalPWMInitialized(int32_t index, HAL_Bool initialized);
+
+int32_t HALSIM_RegisterDigitalPWMDutyCycleCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelDigitalPWMDutyCycleCallback(int32_t index, int32_t uid);
+double HALSIM_GetDigitalPWMDutyCycle(int32_t index);
+void HALSIM_SetDigitalPWMDutyCycle(int32_t index, double dutyCycle);
+
+int32_t HALSIM_RegisterDigitalPWMPinCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelDigitalPWMPinCallback(int32_t index, int32_t uid);
+int32_t HALSIM_GetDigitalPWMPin(int32_t index);
+void HALSIM_SetDigitalPWMPin(int32_t index, int32_t pin);
+
+void HALSIM_RegisterDigitalPWMAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/DriverStationData.h b/hal/src/main/native/include/mockdata/DriverStationData.h
new file mode 100644
index 0000000..57ca4e0
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/DriverStationData.h
@@ -0,0 +1,95 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/DriverStationTypes.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetDriverStationData(void);
+int32_t HALSIM_RegisterDriverStationEnabledCallback(HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelDriverStationEnabledCallback(int32_t uid);
+HAL_Bool HALSIM_GetDriverStationEnabled(void);
+void HALSIM_SetDriverStationEnabled(HAL_Bool enabled);
+
+int32_t HALSIM_RegisterDriverStationAutonomousCallback(
+ HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
+void HALSIM_CancelDriverStationAutonomousCallback(int32_t uid);
+HAL_Bool HALSIM_GetDriverStationAutonomous(void);
+void HALSIM_SetDriverStationAutonomous(HAL_Bool autonomous);
+
+int32_t HALSIM_RegisterDriverStationTestCallback(HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelDriverStationTestCallback(int32_t uid);
+HAL_Bool HALSIM_GetDriverStationTest(void);
+void HALSIM_SetDriverStationTest(HAL_Bool test);
+
+int32_t HALSIM_RegisterDriverStationEStopCallback(HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelDriverStationEStopCallback(int32_t uid);
+HAL_Bool HALSIM_GetDriverStationEStop(void);
+void HALSIM_SetDriverStationEStop(HAL_Bool eStop);
+
+int32_t HALSIM_RegisterDriverStationFmsAttachedCallback(
+ HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
+void HALSIM_CancelDriverStationFmsAttachedCallback(int32_t uid);
+HAL_Bool HALSIM_GetDriverStationFmsAttached(void);
+void HALSIM_SetDriverStationFmsAttached(HAL_Bool fmsAttached);
+
+int32_t HALSIM_RegisterDriverStationDsAttachedCallback(
+ HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
+void HALSIM_CancelDriverStationDsAttachedCallback(int32_t uid);
+HAL_Bool HALSIM_GetDriverStationDsAttached(void);
+void HALSIM_SetDriverStationDsAttached(HAL_Bool dsAttached);
+
+int32_t HALSIM_RegisterDriverStationAllianceStationIdCallback(
+ HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
+void HALSIM_CancelDriverStationAllianceStationIdCallback(int32_t uid);
+HAL_AllianceStationID HALSIM_GetDriverStationAllianceStationId(void);
+void HALSIM_SetDriverStationAllianceStationId(
+ HAL_AllianceStationID allianceStationId);
+
+int32_t HALSIM_RegisterDriverStationMatchTimeCallback(
+ HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify);
+void HALSIM_CancelDriverStationMatchTimeCallback(int32_t uid);
+double HALSIM_GetDriverStationMatchTime(void);
+void HALSIM_SetDriverStationMatchTime(double matchTime);
+
+void HALSIM_SetJoystickAxes(int32_t joystickNum, const HAL_JoystickAxes* axes);
+void HALSIM_SetJoystickPOVs(int32_t joystickNum, const HAL_JoystickPOVs* povs);
+void HALSIM_SetJoystickButtons(int32_t joystickNum,
+ const HAL_JoystickButtons* buttons);
+void HALSIM_SetJoystickDescriptor(int32_t joystickNum,
+ const HAL_JoystickDescriptor* descriptor);
+
+void HALSIM_GetJoystickOutputs(int32_t joystickNum, int64_t* outputs,
+ int32_t* leftRumble, int32_t* rightRumble);
+
+void HALSIM_SetMatchInfo(const HAL_MatchInfo* info);
+
+void HALSIM_RegisterDriverStationAllCallbacks(HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+
+void HALSIM_NotifyDriverStationNewData(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/EncoderData.h b/hal/src/main/native/include/mockdata/EncoderData.h
new file mode 100644
index 0000000..bcd00a7
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/EncoderData.h
@@ -0,0 +1,99 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetEncoderData(int32_t index);
+int16_t HALSIM_GetDigitalChannelA(int32_t index);
+int32_t HALSIM_RegisterEncoderInitializedCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelEncoderInitializedCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetEncoderInitialized(int32_t index);
+void HALSIM_SetEncoderInitialized(int32_t index, HAL_Bool initialized);
+
+int32_t HALSIM_RegisterEncoderCountCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelEncoderCountCallback(int32_t index, int32_t uid);
+int32_t HALSIM_GetEncoderCount(int32_t index);
+void HALSIM_SetEncoderCount(int32_t index, int32_t count);
+
+int32_t HALSIM_RegisterEncoderPeriodCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelEncoderPeriodCallback(int32_t index, int32_t uid);
+double HALSIM_GetEncoderPeriod(int32_t index);
+void HALSIM_SetEncoderPeriod(int32_t index, double period);
+
+int32_t HALSIM_RegisterEncoderResetCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelEncoderResetCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetEncoderReset(int32_t index);
+void HALSIM_SetEncoderReset(int32_t index, HAL_Bool reset);
+
+int32_t HALSIM_RegisterEncoderMaxPeriodCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelEncoderMaxPeriodCallback(int32_t index, int32_t uid);
+double HALSIM_GetEncoderMaxPeriod(int32_t index);
+void HALSIM_SetEncoderMaxPeriod(int32_t index, double maxPeriod);
+
+int32_t HALSIM_RegisterEncoderDirectionCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelEncoderDirectionCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetEncoderDirection(int32_t index);
+void HALSIM_SetEncoderDirection(int32_t index, HAL_Bool direction);
+
+int32_t HALSIM_RegisterEncoderReverseDirectionCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelEncoderReverseDirectionCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetEncoderReverseDirection(int32_t index);
+void HALSIM_SetEncoderReverseDirection(int32_t index,
+ HAL_Bool reverseDirection);
+
+int32_t HALSIM_RegisterEncoderSamplesToAverageCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelEncoderSamplesToAverageCallback(int32_t index, int32_t uid);
+int32_t HALSIM_GetEncoderSamplesToAverage(int32_t index);
+void HALSIM_SetEncoderSamplesToAverage(int32_t index, int32_t samplesToAverage);
+
+int32_t HALSIM_RegisterEncoderDistancePerPulseCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelEncoderDistancePerPulseCallback(int32_t index, int32_t uid);
+double HALSIM_GetEncoderDistancePerPulse(int32_t index);
+void HALSIM_SetEncoderDistancePerPulse(int32_t index, double distancePerPulse);
+
+void HALSIM_RegisterEncoderAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/HAL_Value.h b/hal/src/main/native/include/mockdata/HAL_Value.h
new file mode 100644
index 0000000..ee348b9
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/HAL_Value.h
@@ -0,0 +1,71 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "hal/Types.h"
+
+/** HAL data types. */
+enum HAL_Type {
+ HAL_UNASSIGNED = 0,
+ HAL_BOOLEAN = 0x01,
+ HAL_DOUBLE = 0x02,
+ HAL_ENUM = 0x16,
+ HAL_INT = 0x32,
+ HAL_LONG = 0x64,
+};
+
+/** HAL Entry Value. Note this is a typed union. */
+struct HAL_Value {
+ union {
+ HAL_Bool v_boolean;
+ int32_t v_enum;
+ int32_t v_int;
+ int64_t v_long;
+ double v_double;
+ } data;
+ enum HAL_Type type;
+};
+
+inline HAL_Value MakeBoolean(HAL_Bool v) {
+ HAL_Value value;
+ value.type = HAL_BOOLEAN;
+ value.data.v_boolean = v;
+ return value;
+}
+
+inline HAL_Value MakeEnum(int v) {
+ HAL_Value value;
+ value.type = HAL_ENUM;
+ value.data.v_enum = v;
+ return value;
+}
+
+inline HAL_Value MakeInt(int v) {
+ HAL_Value value;
+ value.type = HAL_INT;
+ value.data.v_int = v;
+ return value;
+}
+
+inline HAL_Value MakeLong(int64_t v) {
+ HAL_Value value;
+ value.type = HAL_LONG;
+ value.data.v_long = v;
+ return value;
+}
+
+inline HAL_Value MakeDouble(double v) {
+ HAL_Value value;
+ value.type = HAL_DOUBLE;
+ value.data.v_double = v;
+ return value;
+}
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/I2CData.h b/hal/src/main/native/include/mockdata/I2CData.h
new file mode 100644
index 0000000..8565fdb
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/I2CData.h
@@ -0,0 +1,43 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetI2CData(int32_t index);
+
+int32_t HALSIM_RegisterI2CInitializedCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelI2CInitializedCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetI2CInitialized(int32_t index);
+void HALSIM_SetI2CInitialized(int32_t index, HAL_Bool initialized);
+
+int32_t HALSIM_RegisterI2CReadCallback(int32_t index,
+ HAL_BufferCallback callback,
+ void* param);
+void HALSIM_CancelI2CReadCallback(int32_t index, int32_t uid);
+
+int32_t HALSIM_RegisterI2CWriteCallback(int32_t index,
+ HAL_ConstBufferCallback callback,
+ void* param);
+void HALSIM_CancelI2CWriteCallback(int32_t index, int32_t uid);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/MockHooks.h b/hal/src/main/native/include/mockdata/MockHooks.h
new file mode 100644
index 0000000..37eb0e7
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/MockHooks.h
@@ -0,0 +1,21 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "hal/Types.h"
+
+extern "C" {
+void HALSIM_WaitForProgramStart(void);
+void HALSIM_SetProgramStarted(void);
+HAL_Bool HALSIM_GetProgramStarted(void);
+void HALSIM_RestartTiming(void);
+} // extern "C"
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/NotifyListener.h b/hal/src/main/native/include/mockdata/NotifyListener.h
new file mode 100644
index 0000000..8d7e199
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/NotifyListener.h
@@ -0,0 +1,40 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "HAL_Value.h"
+
+typedef void (*HAL_NotifyCallback)(const char* name, void* param,
+ const struct HAL_Value* value);
+
+typedef void (*HAL_BufferCallback)(const char* name, void* param,
+ unsigned char* buffer, unsigned int count);
+
+typedef void (*HAL_ConstBufferCallback)(const char* name, void* param,
+ const unsigned char* buffer,
+ unsigned int count);
+
+namespace hal {
+
+template <typename CallbackFunction>
+struct HalCallbackListener {
+ HalCallbackListener() = default;
+ HalCallbackListener(void* param_, CallbackFunction callback_)
+ : callback(callback_), param(param_) {}
+
+ explicit operator bool() const { return callback != nullptr; }
+
+ CallbackFunction callback;
+ void* param;
+};
+
+} // namespace hal
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/PCMData.h b/hal/src/main/native/include/mockdata/PCMData.h
new file mode 100644
index 0000000..d919cc9
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/PCMData.h
@@ -0,0 +1,93 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetPCMData(int32_t index);
+int32_t HALSIM_RegisterPCMSolenoidInitializedCallback(
+ int32_t index, int32_t channel, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelPCMSolenoidInitializedCallback(int32_t index, int32_t channel,
+ int32_t uid);
+HAL_Bool HALSIM_GetPCMSolenoidInitialized(int32_t index, int32_t channel);
+void HALSIM_SetPCMSolenoidInitialized(int32_t index, int32_t channel,
+ HAL_Bool solenoidInitialized);
+
+int32_t HALSIM_RegisterPCMSolenoidOutputCallback(int32_t index, int32_t channel,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelPCMSolenoidOutputCallback(int32_t index, int32_t channel,
+ int32_t uid);
+HAL_Bool HALSIM_GetPCMSolenoidOutput(int32_t index, int32_t channel);
+void HALSIM_SetPCMSolenoidOutput(int32_t index, int32_t channel,
+ HAL_Bool solenoidOutput);
+
+int32_t HALSIM_RegisterPCMCompressorInitializedCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelPCMCompressorInitializedCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetPCMCompressorInitialized(int32_t index);
+void HALSIM_SetPCMCompressorInitialized(int32_t index,
+ HAL_Bool compressorInitialized);
+
+int32_t HALSIM_RegisterPCMCompressorOnCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelPCMCompressorOnCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetPCMCompressorOn(int32_t index);
+void HALSIM_SetPCMCompressorOn(int32_t index, HAL_Bool compressorOn);
+
+int32_t HALSIM_RegisterPCMClosedLoopEnabledCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelPCMClosedLoopEnabledCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetPCMClosedLoopEnabled(int32_t index);
+void HALSIM_SetPCMClosedLoopEnabled(int32_t index, HAL_Bool closedLoopEnabled);
+
+int32_t HALSIM_RegisterPCMPressureSwitchCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelPCMPressureSwitchCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetPCMPressureSwitch(int32_t index);
+void HALSIM_SetPCMPressureSwitch(int32_t index, HAL_Bool pressureSwitch);
+
+int32_t HALSIM_RegisterPCMCompressorCurrentCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelPCMCompressorCurrentCallback(int32_t index, int32_t uid);
+double HALSIM_GetPCMCompressorCurrent(int32_t index);
+void HALSIM_SetPCMCompressorCurrent(int32_t index, double compressorCurrent);
+
+void HALSIM_RegisterPCMAllNonSolenoidCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+
+void HALSIM_RegisterPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/PDPData.h b/hal/src/main/native/include/mockdata/PDPData.h
new file mode 100644
index 0000000..be24da8
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/PDPData.h
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetPDPData(int32_t index);
+int32_t HALSIM_RegisterPDPInitializedCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelPDPInitializedCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetPDPInitialized(int32_t index);
+void HALSIM_SetPDPInitialized(int32_t index, HAL_Bool initialized);
+
+int32_t HALSIM_RegisterPDPTemperatureCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelPDPTemperatureCallback(int32_t index, int32_t uid);
+double HALSIM_GetPDPTemperature(int32_t index);
+void HALSIM_SetPDPTemperature(int32_t index, double temperature);
+
+int32_t HALSIM_RegisterPDPVoltageCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+void HALSIM_CancelPDPVoltageCallback(int32_t index, int32_t uid);
+double HALSIM_GetPDPVoltage(int32_t index);
+void HALSIM_SetPDPVoltage(int32_t index, double voltage);
+
+int32_t HALSIM_RegisterPDPCurrentCallback(int32_t index, int32_t channel,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+void HALSIM_CancelPDPCurrentCallback(int32_t index, int32_t channel,
+ int32_t uid);
+double HALSIM_GetPDPCurrent(int32_t index, int32_t channel);
+void HALSIM_SetPDPCurrent(int32_t index, int32_t channel, double current);
+
+void HALSIM_RegisterPDPAllNonCurrentCallbacks(int32_t index, int32_t channel,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/PWMData.h b/hal/src/main/native/include/mockdata/PWMData.h
new file mode 100644
index 0000000..08ba357
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/PWMData.h
@@ -0,0 +1,72 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetPWMData(int32_t index);
+int32_t HALSIM_RegisterPWMInitializedCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelPWMInitializedCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetPWMInitialized(int32_t index);
+void HALSIM_SetPWMInitialized(int32_t index, HAL_Bool initialized);
+
+int32_t HALSIM_RegisterPWMRawValueCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+void HALSIM_CancelPWMRawValueCallback(int32_t index, int32_t uid);
+int32_t HALSIM_GetPWMRawValue(int32_t index);
+void HALSIM_SetPWMRawValue(int32_t index, int32_t rawValue);
+
+int32_t HALSIM_RegisterPWMSpeedCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+void HALSIM_CancelPWMSpeedCallback(int32_t index, int32_t uid);
+double HALSIM_GetPWMSpeed(int32_t index);
+void HALSIM_SetPWMSpeed(int32_t index, double speed);
+
+int32_t HALSIM_RegisterPWMPositionCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+void HALSIM_CancelPWMPositionCallback(int32_t index, int32_t uid);
+double HALSIM_GetPWMPosition(int32_t index);
+void HALSIM_SetPWMPosition(int32_t index, double position);
+
+int32_t HALSIM_RegisterPWMPeriodScaleCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelPWMPeriodScaleCallback(int32_t index, int32_t uid);
+int32_t HALSIM_GetPWMPeriodScale(int32_t index);
+void HALSIM_SetPWMPeriodScale(int32_t index, int32_t periodScale);
+
+int32_t HALSIM_RegisterPWMZeroLatchCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelPWMZeroLatchCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetPWMZeroLatch(int32_t index);
+void HALSIM_SetPWMZeroLatch(int32_t index, HAL_Bool zeroLatch);
+
+void HALSIM_RegisterPWMAllCallbacks(int32_t index, HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/RelayData.h b/hal/src/main/native/include/mockdata/RelayData.h
new file mode 100644
index 0000000..6fdac7f
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/RelayData.h
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetRelayData(int32_t index);
+int32_t HALSIM_RegisterRelayInitializedForwardCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRelayInitializedForwardCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetRelayInitializedForward(int32_t index);
+void HALSIM_SetRelayInitializedForward(int32_t index,
+ HAL_Bool initializedForward);
+
+int32_t HALSIM_RegisterRelayInitializedReverseCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRelayInitializedReverseCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetRelayInitializedReverse(int32_t index);
+void HALSIM_SetRelayInitializedReverse(int32_t index,
+ HAL_Bool initializedReverse);
+
+int32_t HALSIM_RegisterRelayForwardCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRelayForwardCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetRelayForward(int32_t index);
+void HALSIM_SetRelayForward(int32_t index, HAL_Bool forward);
+
+int32_t HALSIM_RegisterRelayReverseCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRelayReverseCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetRelayReverse(int32_t index);
+void HALSIM_SetRelayReverse(int32_t index, HAL_Bool reverse);
+
+void HALSIM_RegisterRelayAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/RoboRioData.h b/hal/src/main/native/include/mockdata/RoboRioData.h
new file mode 100644
index 0000000..88b6ece
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/RoboRioData.h
@@ -0,0 +1,146 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetRoboRioData(int32_t index);
+int32_t HALSIM_RegisterRoboRioFPGAButtonCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioFPGAButtonCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetRoboRioFPGAButton(int32_t index);
+void HALSIM_SetRoboRioFPGAButton(int32_t index, HAL_Bool fPGAButton);
+
+int32_t HALSIM_RegisterRoboRioVInVoltageCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioVInVoltageCallback(int32_t index, int32_t uid);
+double HALSIM_GetRoboRioVInVoltage(int32_t index);
+void HALSIM_SetRoboRioVInVoltage(int32_t index, double vInVoltage);
+
+int32_t HALSIM_RegisterRoboRioVInCurrentCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioVInCurrentCallback(int32_t index, int32_t uid);
+double HALSIM_GetRoboRioVInCurrent(int32_t index);
+void HALSIM_SetRoboRioVInCurrent(int32_t index, double vInCurrent);
+
+int32_t HALSIM_RegisterRoboRioUserVoltage6VCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioUserVoltage6VCallback(int32_t index, int32_t uid);
+double HALSIM_GetRoboRioUserVoltage6V(int32_t index);
+void HALSIM_SetRoboRioUserVoltage6V(int32_t index, double userVoltage6V);
+
+int32_t HALSIM_RegisterRoboRioUserCurrent6VCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioUserCurrent6VCallback(int32_t index, int32_t uid);
+double HALSIM_GetRoboRioUserCurrent6V(int32_t index);
+void HALSIM_SetRoboRioUserCurrent6V(int32_t index, double userCurrent6V);
+
+int32_t HALSIM_RegisterRoboRioUserActive6VCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioUserActive6VCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetRoboRioUserActive6V(int32_t index);
+void HALSIM_SetRoboRioUserActive6V(int32_t index, HAL_Bool userActive6V);
+
+int32_t HALSIM_RegisterRoboRioUserVoltage5VCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioUserVoltage5VCallback(int32_t index, int32_t uid);
+double HALSIM_GetRoboRioUserVoltage5V(int32_t index);
+void HALSIM_SetRoboRioUserVoltage5V(int32_t index, double userVoltage5V);
+
+int32_t HALSIM_RegisterRoboRioUserCurrent5VCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioUserCurrent5VCallback(int32_t index, int32_t uid);
+double HALSIM_GetRoboRioUserCurrent5V(int32_t index);
+void HALSIM_SetRoboRioUserCurrent5V(int32_t index, double userCurrent5V);
+
+int32_t HALSIM_RegisterRoboRioUserActive5VCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioUserActive5VCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetRoboRioUserActive5V(int32_t index);
+void HALSIM_SetRoboRioUserActive5V(int32_t index, HAL_Bool userActive5V);
+
+int32_t HALSIM_RegisterRoboRioUserVoltage3V3Callback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioUserVoltage3V3Callback(int32_t index, int32_t uid);
+double HALSIM_GetRoboRioUserVoltage3V3(int32_t index);
+void HALSIM_SetRoboRioUserVoltage3V3(int32_t index, double userVoltage3V3);
+
+int32_t HALSIM_RegisterRoboRioUserCurrent3V3Callback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioUserCurrent3V3Callback(int32_t index, int32_t uid);
+double HALSIM_GetRoboRioUserCurrent3V3(int32_t index);
+void HALSIM_SetRoboRioUserCurrent3V3(int32_t index, double userCurrent3V3);
+
+int32_t HALSIM_RegisterRoboRioUserActive3V3Callback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioUserActive3V3Callback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetRoboRioUserActive3V3(int32_t index);
+void HALSIM_SetRoboRioUserActive3V3(int32_t index, HAL_Bool userActive3V3);
+
+int32_t HALSIM_RegisterRoboRioUserFaults6VCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioUserFaults6VCallback(int32_t index, int32_t uid);
+int32_t HALSIM_GetRoboRioUserFaults6V(int32_t index);
+void HALSIM_SetRoboRioUserFaults6V(int32_t index, int32_t userFaults6V);
+
+int32_t HALSIM_RegisterRoboRioUserFaults5VCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioUserFaults5VCallback(int32_t index, int32_t uid);
+int32_t HALSIM_GetRoboRioUserFaults5V(int32_t index);
+void HALSIM_SetRoboRioUserFaults5V(int32_t index, int32_t userFaults5V);
+
+int32_t HALSIM_RegisterRoboRioUserFaults3V3Callback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelRoboRioUserFaults3V3Callback(int32_t index, int32_t uid);
+int32_t HALSIM_GetRoboRioUserFaults3V3(int32_t index);
+void HALSIM_SetRoboRioUserFaults3V3(int32_t index, int32_t userFaults3V3);
+
+void HALSIM_RegisterRoboRioAllCallbacks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param, HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/SPIAccelerometerData.h b/hal/src/main/native/include/mockdata/SPIAccelerometerData.h
new file mode 100644
index 0000000..6e37f40
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/SPIAccelerometerData.h
@@ -0,0 +1,67 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetSPIAccelerometerData(int32_t index);
+int32_t HALSIM_RegisterSPIAccelerometerActiveCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelSPIAccelerometerActiveCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetSPIAccelerometerActive(int32_t index);
+void HALSIM_SetSPIAccelerometerActive(int32_t index, HAL_Bool active);
+
+int32_t HALSIM_RegisterSPIAccelerometerRangeCallback(
+ int32_t index, HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelSPIAccelerometerRangeCallback(int32_t index, int32_t uid);
+int32_t HALSIM_GetSPIAccelerometerRange(int32_t index);
+void HALSIM_SetSPIAccelerometerRange(int32_t index, int32_t range);
+
+int32_t HALSIM_RegisterSPIAccelerometerXCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelSPIAccelerometerXCallback(int32_t index, int32_t uid);
+double HALSIM_GetSPIAccelerometerX(int32_t index);
+void HALSIM_SetSPIAccelerometerX(int32_t index, double x);
+
+int32_t HALSIM_RegisterSPIAccelerometerYCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelSPIAccelerometerYCallback(int32_t index, int32_t uid);
+double HALSIM_GetSPIAccelerometerY(int32_t index);
+void HALSIM_SetSPIAccelerometerY(int32_t index, double y);
+
+int32_t HALSIM_RegisterSPIAccelerometerZCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelSPIAccelerometerZCallback(int32_t index, int32_t uid);
+double HALSIM_GetSPIAccelerometerZ(int32_t index);
+void HALSIM_SetSPIAccelerometerZ(int32_t index, double z);
+
+void HALSIM_RegisterSPIAccelerometerAllCallbcaks(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/SPIData.h b/hal/src/main/native/include/mockdata/SPIData.h
new file mode 100644
index 0000000..54a2ec9
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/SPIData.h
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#ifndef __FRC_ROBORIO__
+
+#include "NotifyListener.h"
+#include "hal/Types.h"
+
+typedef void (*HAL_SpiReadAutoReceiveBufferCallback)(const char* name,
+ void* param,
+ uint32_t* buffer,
+ int32_t numToRead,
+ int32_t* outputCount);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetSPIData(int32_t index);
+
+int32_t HALSIM_RegisterSPIInitializedCallback(int32_t index,
+ HAL_NotifyCallback callback,
+ void* param,
+ HAL_Bool initialNotify);
+void HALSIM_CancelSPIInitializedCallback(int32_t index, int32_t uid);
+HAL_Bool HALSIM_GetSPIInitialized(int32_t index);
+void HALSIM_SetSPIInitialized(int32_t index, HAL_Bool initialized);
+
+int32_t HALSIM_RegisterSPIReadCallback(int32_t index,
+ HAL_BufferCallback callback,
+ void* param);
+void HALSIM_CancelSPIReadCallback(int32_t index, int32_t uid);
+
+int32_t HALSIM_RegisterSPIWriteCallback(int32_t index,
+ HAL_ConstBufferCallback callback,
+ void* param);
+void HALSIM_CancelSPIWriteCallback(int32_t index, int32_t uid);
+
+int32_t HALSIM_RegisterSPIReadAutoReceivedDataCallback(
+ int32_t index, HAL_SpiReadAutoReceiveBufferCallback callback, void* param);
+void HALSIM_CancelSPIReadAutoReceivedDataCallback(int32_t index, int32_t uid);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/hal/src/main/native/include/mockdata/SimCallbackRegistry.h b/hal/src/main/native/include/mockdata/SimCallbackRegistry.h
new file mode 100644
index 0000000..da3f0f9
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/SimCallbackRegistry.h
@@ -0,0 +1,151 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+#include <utility>
+
+#include <wpi/Compiler.h>
+#include <wpi/UidVector.h>
+#include <wpi/spinlock.h>
+
+#include "mockdata/NotifyListener.h"
+
+namespace hal {
+
+namespace impl {
+
+class SimCallbackRegistryBase {
+ public:
+ using RawFunctor = void (*)();
+
+ protected:
+ using CallbackVector = wpi::UidVector<HalCallbackListener<RawFunctor>, 4>;
+
+ public:
+ void Cancel(int32_t uid) {
+ std::lock_guard<wpi::recursive_spinlock> lock(m_mutex);
+ if (m_callbacks) m_callbacks->erase(uid - 1);
+ }
+
+ void Reset() {
+ std::lock_guard<wpi::recursive_spinlock> lock(m_mutex);
+ DoReset();
+ }
+
+ wpi::recursive_spinlock& GetMutex() { return m_mutex; }
+
+ protected:
+ int32_t DoRegister(RawFunctor 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, callback) + 1;
+ }
+
+ LLVM_ATTRIBUTE_ALWAYS_INLINE void DoReset() {
+ if (m_callbacks) m_callbacks->clear();
+ }
+
+ mutable wpi::recursive_spinlock m_mutex;
+ std::unique_ptr<CallbackVector> m_callbacks;
+};
+
+} // namespace impl
+
+/**
+ * Simulation callback registry. Provides callback functionality.
+ *
+ * @tparam CallbackFunction callback function type (e.g. HAL_BufferCallback)
+ * @tparam GetName function that returns a const char* for the name
+ */
+template <typename CallbackFunction, const char* (*GetName)()>
+class SimCallbackRegistry : public impl::SimCallbackRegistryBase {
+ public:
+ int32_t Register(CallbackFunction callback, void* param) {
+ std::lock_guard<wpi::recursive_spinlock> lock(m_mutex);
+ return DoRegister(reinterpret_cast<RawFunctor>(callback), param);
+ }
+
+ template <typename... U>
+ void Invoke(U&&... u) const {
+ std::lock_guard<wpi::recursive_spinlock> lock(m_mutex);
+ if (m_callbacks) {
+ const char* name = GetName();
+ 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)...);
+ }
+};
+
+/**
+ * Define a name functor for use with SimCallbackRegistry.
+ * This creates a function named GetNAMEName() that returns "NAME".
+ * @param NAME the name to return
+ */
+#define HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(NAME) \
+ static LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr const char* \
+ Get##NAME##Name() { \
+ return #NAME; \
+ }
+
+/**
+ * Define a standard C API for SimCallbackRegistry.
+ *
+ * Functions defined:
+ * - int32 NS_RegisterCAPINAMECallback(
+ * int32_t index, TYPE callback, void* param)
+ * - void NS_CancelCAPINAMECallback(int32_t index, int32_t uid)
+ *
+ * @param TYPE the underlying callback type (e.g. HAL_BufferCallback)
+ * @param NS the "namespace" (e.g. HALSIM)
+ * @param CAPINAME the C API name (usually first letter capitalized)
+ * @param DATA the backing data array
+ * @param LOWERNAME the lowercase name of the backing data registry
+ */
+#define HAL_SIMCALLBACKREGISTRY_DEFINE_CAPI(TYPE, NS, CAPINAME, DATA, \
+ LOWERNAME) \
+ int32_t NS##_Register##CAPINAME##Callback(int32_t index, TYPE callback, \
+ void* param) { \
+ return DATA[index].LOWERNAME.Register(callback, param); \
+ } \
+ \
+ void NS##_Cancel##CAPINAME##Callback(int32_t index, int32_t uid) { \
+ DATA[index].LOWERNAME.Cancel(uid); \
+ }
+
+/**
+ * Define a standard C API for SimCallbackRegistry (no index variant).
+ *
+ * Functions defined:
+ * - int32 NS_RegisterCAPINAMECallback(TYPE callback, void* param)
+ * - void NS_CancelCAPINAMECallback(int32_t uid)
+ *
+ * @param TYPE the underlying callback type (e.g. HAL_BufferCallback)
+ * @param NS the "namespace" (e.g. HALSIM)
+ * @param CAPINAME the C API name (usually first letter capitalized)
+ * @param DATA the backing data pointer
+ * @param LOWERNAME the lowercase name of the backing data registry
+ */
+#define HAL_SIMCALLBACKREGISTRY_DEFINE_CAPI_NOINDEX(TYPE, NS, CAPINAME, DATA, \
+ LOWERNAME) \
+ int32_t NS##_Register##CAPINAME##Callback(TYPE callback, void* param) { \
+ return DATA->LOWERNAME.Register(callback, param); \
+ } \
+ \
+ void NS##_Cancel##CAPINAME##Callback(int32_t uid) { \
+ DATA->LOWERNAME.Cancel(uid); \
+ }
+
+} // namespace hal
diff --git a/hal/src/main/native/include/mockdata/SimDataValue.h b/hal/src/main/native/include/mockdata/SimDataValue.h
new file mode 100644
index 0000000..3b518b9
--- /dev/null
+++ b/hal/src/main/native/include/mockdata/SimDataValue.h
@@ -0,0 +1,227 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+
+#include <wpi/Compiler.h>
+#include <wpi/UidVector.h>
+#include <wpi/spinlock.h>
+
+#include "mockdata/NotifyListener.h"
+#include "mockdata/SimCallbackRegistry.h"
+
+namespace hal {
+
+namespace impl {
+template <typename T, HAL_Value (*MakeValue)(T)>
+class SimDataValueBase : protected SimCallbackRegistryBase {
+ public:
+ explicit SimDataValueBase(T value) : m_value(value) {}
+
+ LLVM_ATTRIBUTE_ALWAYS_INLINE void CancelCallback(int32_t uid) { Cancel(uid); }
+
+ T Get() const {
+ std::lock_guard<wpi::recursive_spinlock> lock(m_mutex);
+ return m_value;
+ }
+
+ LLVM_ATTRIBUTE_ALWAYS_INLINE operator T() const { return Get(); }
+
+ void Reset(T value) {
+ std::lock_guard<wpi::recursive_spinlock> lock(m_mutex);
+ DoReset();
+ m_value = value;
+ }
+
+ wpi::recursive_spinlock& GetMutex() { return m_mutex; }
+
+ protected:
+ int32_t DoRegisterCallback(HAL_NotifyCallback callback, void* param,
+ HAL_Bool initialNotify, const char* name) {
+ std::unique_lock<wpi::recursive_spinlock> lock(m_mutex);
+ int32_t newUid = DoRegister(reinterpret_cast<RawFunctor>(callback), param);
+ if (newUid == -1) return -1;
+ if (initialNotify) {
+ // We know that the callback is not null because of earlier null check
+ HAL_Value value = MakeValue(m_value);
+ lock.unlock();
+ callback(name, param, &value);
+ }
+ return newUid + 1;
+ }
+
+ void DoSet(T value, const char* name) {
+ std::lock_guard<wpi::recursive_spinlock> lock(this->m_mutex);
+ if (m_value != value) {
+ m_value = value;
+ if (m_callbacks) {
+ HAL_Value halValue = MakeValue(value);
+ for (auto&& cb : *m_callbacks)
+ reinterpret_cast<HAL_NotifyCallback>(cb.callback)(name, cb.param,
+ &halValue);
+ }
+ }
+ }
+
+ T m_value;
+};
+} // namespace impl
+
+/**
+ * Simulation data value wrapper. Provides callback functionality when the
+ * data value is changed.
+ *
+ * @tparam T value type (e.g. double)
+ * @tparam MakeValue function that takes a T and returns a HAL_Value
+ * @tparam GetName function that returns a const char* for the name
+ * @tparam GetDefault function that returns the default T (used only for
+ * default constructor)
+ */
+template <typename T, HAL_Value (*MakeValue)(T), const char* (*GetName)(),
+ T (*GetDefault)() = nullptr>
+class SimDataValue final : public impl::SimDataValueBase<T, MakeValue> {
+ public:
+ SimDataValue()
+ : impl::SimDataValueBase<T, MakeValue>(
+ GetDefault != nullptr ? GetDefault() : T()) {}
+ explicit SimDataValue(T value)
+ : impl::SimDataValueBase<T, MakeValue>(value) {}
+
+ LLVM_ATTRIBUTE_ALWAYS_INLINE int32_t RegisterCallback(
+ HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+ return this->DoRegisterCallback(callback, param, initialNotify, GetName());
+ }
+
+ LLVM_ATTRIBUTE_ALWAYS_INLINE void Set(T value) {
+ this->DoSet(value, GetName());
+ }
+
+ LLVM_ATTRIBUTE_ALWAYS_INLINE SimDataValue& operator=(T value) {
+ Set(value);
+ return *this;
+ }
+};
+
+/**
+ * Define a name functor for use with SimDataValue.
+ * This creates a function named GetNAMEName() that returns "NAME".
+ * @param NAME the name to return
+ */
+#define HAL_SIMDATAVALUE_DEFINE_NAME(NAME) \
+ static LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr const char* \
+ Get##NAME##Name() { \
+ return #NAME; \
+ }
+
+/**
+ * Define a standard C API for simulation data.
+ *
+ * Functions defined:
+ * - int32 NS_RegisterCAPINAMECallback(
+ * int32_t index, HAL_NotifyCallback callback, void* param,
+ * HAL_Bool initialNotify)
+ * - void NS_CancelCAPINAMECallback(int32_t index, int32_t uid)
+ * - TYPE NS_GetCAPINAME(int32_t index)
+ * - void NS_SetCAPINAME(int32_t index, TYPE value)
+ *
+ * @param TYPE the underlying value type (e.g. double)
+ * @param NS the "namespace" (e.g. HALSIM)
+ * @param CAPINAME the C API name (usually first letter capitalized)
+ * @param DATA the backing data array
+ * @param LOWERNAME the lowercase name of the backing data variable
+ */
+#define HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, NS, CAPINAME, DATA, LOWERNAME) \
+ int32_t NS##_Register##CAPINAME##Callback( \
+ int32_t index, HAL_NotifyCallback callback, void* param, \
+ HAL_Bool initialNotify) { \
+ return DATA[index].LOWERNAME.RegisterCallback(callback, param, \
+ initialNotify); \
+ } \
+ \
+ void NS##_Cancel##CAPINAME##Callback(int32_t index, int32_t uid) { \
+ DATA[index].LOWERNAME.CancelCallback(uid); \
+ } \
+ \
+ TYPE NS##_Get##CAPINAME(int32_t index) { return DATA[index].LOWERNAME; } \
+ \
+ void NS##_Set##CAPINAME(int32_t index, TYPE LOWERNAME) { \
+ DATA[index].LOWERNAME = LOWERNAME; \
+ }
+
+/**
+ * Define a standard C API for simulation data (channel variant).
+ *
+ * Functions defined:
+ * - int32 NS_RegisterCAPINAMECallback(
+ * int32_t index, int32_t channel, HAL_NotifyCallback callback,
+ * void* param, HAL_Bool initialNotify)
+ * - void NS_CancelCAPINAMECallback(int32_t index, int32_t channel, int32_t uid)
+ * - TYPE NS_GetCAPINAME(int32_t index, int32_t channel)
+ * - void NS_SetCAPINAME(int32_t index, int32_t channel, TYPE value)
+ *
+ * @param TYPE the underlying value type (e.g. double)
+ * @param NS the "namespace" (e.g. HALSIM)
+ * @param CAPINAME the C API name (usually first letter capitalized)
+ * @param DATA the backing data array
+ * @param LOWERNAME the lowercase name of the backing data variable array
+ */
+#define HAL_SIMDATAVALUE_DEFINE_CAPI_CHANNEL(TYPE, NS, CAPINAME, DATA, \
+ LOWERNAME) \
+ int32_t NS##_Register##CAPINAME##Callback( \
+ int32_t index, int32_t channel, HAL_NotifyCallback callback, \
+ void* param, HAL_Bool initialNotify) { \
+ return DATA[index].LOWERNAME[channel].RegisterCallback(callback, param, \
+ initialNotify); \
+ } \
+ \
+ void NS##_Cancel##CAPINAME##Callback(int32_t index, int32_t channel, \
+ int32_t uid) { \
+ DATA[index].LOWERNAME[channel].CancelCallback(uid); \
+ } \
+ \
+ TYPE NS##_Get##CAPINAME(int32_t index, int32_t channel) { \
+ return DATA[index].LOWERNAME[channel]; \
+ } \
+ \
+ void NS##_Set##CAPINAME(int32_t index, int32_t channel, TYPE LOWERNAME) { \
+ DATA[index].LOWERNAME[channel] = LOWERNAME; \
+ }
+
+/**
+ * Define a standard C API for simulation data (no index variant).
+ *
+ * Functions defined:
+ * - int32 NS_RegisterCAPINAMECallback(
+ * HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify)
+ * - void NS_CancelCAPINAMECallback(int32_t uid)
+ * - TYPE NS_GetCAPINAME(void)
+ * - void NS_SetCAPINAME(TYPE value)
+ *
+ * @param TYPE the underlying value type (e.g. double)
+ * @param NS the "namespace" (e.g. HALSIM)
+ * @param CAPINAME the C API name (usually first letter capitalized)
+ * @param DATA the backing data pointer
+ * @param LOWERNAME the lowercase name of the backing data variable
+ */
+#define HAL_SIMDATAVALUE_DEFINE_CAPI_NOINDEX(TYPE, NS, CAPINAME, DATA, \
+ LOWERNAME) \
+ int32_t NS##_Register##CAPINAME##Callback( \
+ HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) { \
+ return DATA->LOWERNAME.RegisterCallback(callback, param, initialNotify); \
+ } \
+ \
+ void NS##_Cancel##CAPINAME##Callback(int32_t uid) { \
+ DATA->LOWERNAME.CancelCallback(uid); \
+ } \
+ \
+ TYPE NS##_Get##CAPINAME(void) { return DATA->LOWERNAME; } \
+ \
+ void NS##_Set##CAPINAME(TYPE LOWERNAME) { DATA->LOWERNAME = LOWERNAME; }
+
+} // namespace hal
diff --git a/hal/src/main/native/include/simulation/AccelerometerSim.h b/hal/src/main/native/include/simulation/AccelerometerSim.h
new file mode 100644
index 0000000..ea873c7
--- /dev/null
+++ b/hal/src/main/native/include/simulation/AccelerometerSim.h
@@ -0,0 +1,102 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/AccelerometerData.h"
+
+namespace frc {
+namespace sim {
+class AccelerometerSim {
+ public:
+ explicit AccelerometerSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterActiveCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAccelerometerActiveCallback);
+ store->SetUid(HALSIM_RegisterAccelerometerActiveCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetActive() const { return HALSIM_GetAccelerometerActive(m_index); }
+
+ void SetActive(bool active) {
+ HALSIM_SetAccelerometerActive(m_index, active);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterRangeCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAccelerometerRangeCallback);
+ store->SetUid(HALSIM_RegisterAccelerometerRangeCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ HAL_AccelerometerRange GetRange() const {
+ return HALSIM_GetAccelerometerRange(m_index);
+ }
+
+ void SetRange(HAL_AccelerometerRange range) {
+ HALSIM_SetAccelerometerRange(m_index, range);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterXCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAccelerometerXCallback);
+ store->SetUid(HALSIM_RegisterAccelerometerXCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetX() const { return HALSIM_GetAccelerometerX(m_index); }
+
+ void SetX(double x) { HALSIM_SetAccelerometerX(m_index, x); }
+
+ std::unique_ptr<CallbackStore> RegisterYCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAccelerometerYCallback);
+ store->SetUid(HALSIM_RegisterAccelerometerYCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetY() const { return HALSIM_GetAccelerometerY(m_index); }
+
+ void SetY(double y) { HALSIM_SetAccelerometerY(m_index, y); }
+
+ std::unique_ptr<CallbackStore> RegisterZCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAccelerometerZCallback);
+ store->SetUid(HALSIM_RegisterAccelerometerZCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetZ() const { return HALSIM_GetAccelerometerZ(m_index); }
+
+ void SetZ(double z) { HALSIM_SetAccelerometerZ(m_index, z); }
+
+ void ResetData() { HALSIM_ResetAccelerometerData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/AnalogGyroSim.h b/hal/src/main/native/include/simulation/AnalogGyroSim.h
new file mode 100644
index 0000000..b4c48ca
--- /dev/null
+++ b/hal/src/main/native/include/simulation/AnalogGyroSim.h
@@ -0,0 +1,74 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/AnalogGyroData.h"
+
+namespace frc {
+namespace sim {
+class AnalogGyroSim {
+ public:
+ explicit AnalogGyroSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterAngleCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogGyroAngleCallback);
+ store->SetUid(HALSIM_RegisterAnalogGyroAngleCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetAngle() const { return HALSIM_GetAnalogGyroAngle(m_index); }
+
+ void SetAngle(double angle) { HALSIM_SetAnalogGyroAngle(m_index, angle); }
+
+ std::unique_ptr<CallbackStore> RegisterRateCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogGyroRateCallback);
+ store->SetUid(HALSIM_RegisterAnalogGyroRateCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetRate() const { return HALSIM_GetAnalogGyroRate(m_index); }
+
+ void SetRate(double rate) { HALSIM_SetAnalogGyroRate(m_index, rate); }
+
+ std::unique_ptr<CallbackStore> RegisterInitializedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogGyroInitializedCallback);
+ store->SetUid(HALSIM_RegisterAnalogGyroInitializedCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetInitialized() const {
+ return HALSIM_GetAnalogGyroInitialized(m_index);
+ }
+
+ void SetInitialized(bool initialized) {
+ HALSIM_SetAnalogGyroInitialized(m_index, initialized);
+ }
+
+ void ResetData() { HALSIM_ResetAnalogGyroData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/AnalogInSim.h b/hal/src/main/native/include/simulation/AnalogInSim.h
new file mode 100644
index 0000000..a513c33
--- /dev/null
+++ b/hal/src/main/native/include/simulation/AnalogInSim.h
@@ -0,0 +1,180 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/AnalogInData.h"
+
+namespace frc {
+namespace sim {
+class AnalogInSim {
+ public:
+ explicit AnalogInSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterInitializedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogInInitializedCallback);
+ store->SetUid(HALSIM_RegisterAnalogInInitializedCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetInitialized() const { return HALSIM_GetAnalogInInitialized(m_index); }
+
+ void SetInitialized(bool initialized) {
+ HALSIM_SetAnalogInInitialized(m_index, initialized);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterAverageBitsCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogInAverageBitsCallback);
+ store->SetUid(HALSIM_RegisterAnalogInAverageBitsCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetAverageBits() const { return HALSIM_GetAnalogInAverageBits(m_index); }
+
+ void SetAverageBits(int averageBits) {
+ HALSIM_SetAnalogInAverageBits(m_index, averageBits);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterOversampleBitsCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogInOversampleBitsCallback);
+ store->SetUid(HALSIM_RegisterAnalogInOversampleBitsCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetOversampleBits() const {
+ return HALSIM_GetAnalogInOversampleBits(m_index);
+ }
+
+ void SetOversampleBits(int oversampleBits) {
+ HALSIM_SetAnalogInOversampleBits(m_index, oversampleBits);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterVoltageCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogInVoltageCallback);
+ store->SetUid(HALSIM_RegisterAnalogInVoltageCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetVoltage() const { return HALSIM_GetAnalogInVoltage(m_index); }
+
+ void SetVoltage(double voltage) {
+ HALSIM_SetAnalogInVoltage(m_index, voltage);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterAccumulatorInitializedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback,
+ &HALSIM_CancelAnalogInAccumulatorInitializedCallback);
+ store->SetUid(HALSIM_RegisterAnalogInAccumulatorInitializedCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetAccumulatorInitialized() const {
+ return HALSIM_GetAnalogInAccumulatorInitialized(m_index);
+ }
+
+ void SetAccumulatorInitialized(bool accumulatorInitialized) {
+ HALSIM_SetAnalogInAccumulatorInitialized(m_index, accumulatorInitialized);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterAccumulatorValueCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogInAccumulatorValueCallback);
+ store->SetUid(HALSIM_RegisterAnalogInAccumulatorValueCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int64_t GetAccumulatorValue() const {
+ return HALSIM_GetAnalogInAccumulatorValue(m_index);
+ }
+
+ void SetAccumulatorValue(int64_t accumulatorValue) {
+ HALSIM_SetAnalogInAccumulatorValue(m_index, accumulatorValue);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterAccumulatorCountCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogInAccumulatorCountCallback);
+ store->SetUid(HALSIM_RegisterAnalogInAccumulatorCountCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int64_t GetAccumulatorCount() const {
+ return HALSIM_GetAnalogInAccumulatorCount(m_index);
+ }
+
+ void SetAccumulatorCount(int64_t accumulatorCount) {
+ HALSIM_SetAnalogInAccumulatorCount(m_index, accumulatorCount);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterAccumulatorCenterCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogInAccumulatorCenterCallback);
+ store->SetUid(HALSIM_RegisterAnalogInAccumulatorCenterCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetAccumulatorCenter() const {
+ return HALSIM_GetAnalogInAccumulatorCenter(m_index);
+ }
+
+ void SetAccumulatorCenter(int accumulatorCenter) {
+ HALSIM_SetAnalogInAccumulatorCenter(m_index, accumulatorCenter);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterAccumulatorDeadbandCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback,
+ &HALSIM_CancelAnalogInAccumulatorDeadbandCallback);
+ store->SetUid(HALSIM_RegisterAnalogInAccumulatorDeadbandCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetAccumulatorDeadband() const {
+ return HALSIM_GetAnalogInAccumulatorDeadband(m_index);
+ }
+
+ void SetAccumulatorDeadband(int accumulatorDeadband) {
+ HALSIM_SetAnalogInAccumulatorDeadband(m_index, accumulatorDeadband);
+ }
+
+ void ResetData() { HALSIM_ResetAnalogInData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/AnalogOutSim.h b/hal/src/main/native/include/simulation/AnalogOutSim.h
new file mode 100644
index 0000000..3617a66
--- /dev/null
+++ b/hal/src/main/native/include/simulation/AnalogOutSim.h
@@ -0,0 +1,63 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/AnalogOutData.h"
+
+namespace frc {
+namespace sim {
+class AnalogOutSim {
+ public:
+ explicit AnalogOutSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterVoltageCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogOutVoltageCallback);
+ store->SetUid(HALSIM_RegisterAnalogOutVoltageCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetVoltage() const { return HALSIM_GetAnalogOutVoltage(m_index); }
+
+ void SetVoltage(double voltage) {
+ HALSIM_SetAnalogOutVoltage(m_index, voltage);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterInitializedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogOutInitializedCallback);
+ store->SetUid(HALSIM_RegisterAnalogOutInitializedCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetInitialized() const {
+ return HALSIM_GetAnalogOutInitialized(m_index);
+ }
+
+ void SetInitialized(bool initialized) {
+ HALSIM_SetAnalogOutInitialized(m_index, initialized);
+ }
+
+ void ResetData() { HALSIM_ResetAnalogOutData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/AnalogTriggerSim.h b/hal/src/main/native/include/simulation/AnalogTriggerSim.h
new file mode 100644
index 0000000..04faf05
--- /dev/null
+++ b/hal/src/main/native/include/simulation/AnalogTriggerSim.h
@@ -0,0 +1,84 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/AnalogTriggerData.h"
+
+namespace frc {
+namespace sim {
+class AnalogTriggerSim {
+ public:
+ explicit AnalogTriggerSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterInitializedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelAnalogTriggerInitializedCallback);
+ store->SetUid(HALSIM_RegisterAnalogTriggerInitializedCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetInitialized() const {
+ return HALSIM_GetAnalogTriggerInitialized(m_index);
+ }
+
+ void SetInitialized(bool initialized) {
+ HALSIM_SetAnalogTriggerInitialized(m_index, initialized);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterTriggerLowerBoundCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback,
+ &HALSIM_CancelAnalogTriggerTriggerLowerBoundCallback);
+ store->SetUid(HALSIM_RegisterAnalogTriggerTriggerLowerBoundCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetTriggerLowerBound() const {
+ return HALSIM_GetAnalogTriggerTriggerLowerBound(m_index);
+ }
+
+ void SetTriggerLowerBound(double triggerLowerBound) {
+ HALSIM_SetAnalogTriggerTriggerLowerBound(m_index, triggerLowerBound);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterTriggerUpperBoundCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback,
+ &HALSIM_CancelAnalogTriggerTriggerUpperBoundCallback);
+ store->SetUid(HALSIM_RegisterAnalogTriggerTriggerUpperBoundCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetTriggerUpperBound() const {
+ return HALSIM_GetAnalogTriggerTriggerUpperBound(m_index);
+ }
+
+ void SetTriggerUpperBound(double triggerUpperBound) {
+ HALSIM_SetAnalogTriggerTriggerUpperBound(m_index, triggerUpperBound);
+ }
+
+ void ResetData() { HALSIM_ResetAnalogTriggerData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/CallbackStore.h b/hal/src/main/native/include/simulation/CallbackStore.h
new file mode 100644
index 0000000..967e963
--- /dev/null
+++ b/hal/src/main/native/include/simulation/CallbackStore.h
@@ -0,0 +1,93 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <functional>
+
+#include <wpi/StringRef.h>
+
+#include "mockdata/HAL_Value.h"
+
+namespace frc {
+namespace sim {
+
+using NotifyCallback = std::function<void(wpi::StringRef, const HAL_Value*)>;
+typedef void (*CancelCallbackFunc)(int32_t index, int32_t uid);
+typedef void (*CancelCallbackNoIndexFunc)(int32_t uid);
+typedef void (*CancelCallbackChannelFunc)(int32_t index, int32_t channel,
+ int32_t uid);
+
+void CallbackStoreThunk(const char* name, void* param, const HAL_Value* value);
+
+class CallbackStore {
+ public:
+ CallbackStore(int32_t i, NotifyCallback cb, CancelCallbackNoIndexFunc ccf) {
+ index = i;
+ callback = cb;
+ this->ccnif = ccf;
+ cancelType = NoIndex;
+ }
+
+ CallbackStore(int32_t i, int32_t u, NotifyCallback cb,
+ CancelCallbackFunc ccf) {
+ index = i;
+ uid = u;
+ callback = cb;
+ this->ccf = ccf;
+ cancelType = Normal;
+ }
+
+ CallbackStore(int32_t i, int32_t c, int32_t u, NotifyCallback cb,
+ CancelCallbackChannelFunc ccf) {
+ index = i;
+ channel = c;
+ uid = u;
+ callback = cb;
+ this->cccf = ccf;
+ cancelType = Channel;
+ }
+
+ ~CallbackStore() {
+ switch (cancelType) {
+ case Normal:
+ ccf(index, uid);
+ break;
+ case Channel:
+ cccf(index, channel, uid);
+ break;
+ case NoIndex:
+ ccnif(uid);
+ break;
+ }
+ }
+
+ void SetUid(int32_t uid) { this->uid = uid; }
+
+ friend void CallbackStoreThunk(const char* name, void* param,
+ const HAL_Value* value);
+
+ private:
+ int32_t index;
+ int32_t channel;
+ int32_t uid;
+
+ NotifyCallback callback;
+ union {
+ CancelCallbackFunc ccf;
+ CancelCallbackChannelFunc cccf;
+ CancelCallbackNoIndexFunc ccnif;
+ };
+ enum CancelType { Normal, Channel, NoIndex };
+ CancelType cancelType;
+};
+} // namespace sim
+} // namespace frc
+
+#endif
diff --git a/hal/src/main/native/include/simulation/DIOSim.h b/hal/src/main/native/include/simulation/DIOSim.h
new file mode 100644
index 0000000..b4fe947
--- /dev/null
+++ b/hal/src/main/native/include/simulation/DIOSim.h
@@ -0,0 +1,102 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/DIOData.h"
+
+namespace frc {
+namespace sim {
+class DIOSim {
+ public:
+ explicit DIOSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterInitializedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelDIOInitializedCallback);
+ store->SetUid(HALSIM_RegisterDIOInitializedCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetInitialized() const { return HALSIM_GetDIOInitialized(m_index); }
+
+ void SetInitialized(bool initialized) {
+ HALSIM_SetDIOInitialized(m_index, initialized);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterValueCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelDIOValueCallback);
+ store->SetUid(HALSIM_RegisterDIOValueCallback(m_index, &CallbackStoreThunk,
+ store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetValue() const { return HALSIM_GetDIOValue(m_index); }
+
+ void SetValue(bool value) { HALSIM_SetDIOValue(m_index, value); }
+
+ std::unique_ptr<CallbackStore> RegisterPulseLengthCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelDIOPulseLengthCallback);
+ store->SetUid(HALSIM_RegisterDIOPulseLengthCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetPulseLength() const { return HALSIM_GetDIOPulseLength(m_index); }
+
+ void SetPulseLength(double pulseLength) {
+ HALSIM_SetDIOPulseLength(m_index, pulseLength);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterIsInputCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelDIOIsInputCallback);
+ store->SetUid(HALSIM_RegisterDIOIsInputCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetIsInput() const { return HALSIM_GetDIOIsInput(m_index); }
+
+ void SetIsInput(bool isInput) { HALSIM_SetDIOIsInput(m_index, isInput); }
+
+ std::unique_ptr<CallbackStore> RegisterFilterIndexCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelDIOFilterIndexCallback);
+ store->SetUid(HALSIM_RegisterDIOFilterIndexCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetFilterIndex() const { return HALSIM_GetDIOFilterIndex(m_index); }
+
+ void SetFilterIndex(int filterIndex) {
+ HALSIM_SetDIOFilterIndex(m_index, filterIndex);
+ }
+
+ void ResetData() { HALSIM_ResetDIOData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/DigitalPWMSim.h b/hal/src/main/native/include/simulation/DigitalPWMSim.h
new file mode 100644
index 0000000..ecfc56d
--- /dev/null
+++ b/hal/src/main/native/include/simulation/DigitalPWMSim.h
@@ -0,0 +1,76 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/DigitalPWMData.h"
+
+namespace frc {
+namespace sim {
+class DigitalPWMSim {
+ public:
+ explicit DigitalPWMSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterInitializedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelDigitalPWMInitializedCallback);
+ store->SetUid(HALSIM_RegisterDigitalPWMInitializedCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetInitialized() const {
+ return HALSIM_GetDigitalPWMInitialized(m_index);
+ }
+
+ void SetInitialized(bool initialized) {
+ HALSIM_SetDigitalPWMInitialized(m_index, initialized);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterDutyCycleCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelDigitalPWMDutyCycleCallback);
+ store->SetUid(HALSIM_RegisterDigitalPWMDutyCycleCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetDutyCycle() const { return HALSIM_GetDigitalPWMDutyCycle(m_index); }
+
+ void SetDutyCycle(double dutyCycle) {
+ HALSIM_SetDigitalPWMDutyCycle(m_index, dutyCycle);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterPinCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelDigitalPWMPinCallback);
+ store->SetUid(HALSIM_RegisterDigitalPWMPinCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetPin() const { return HALSIM_GetDigitalPWMPin(m_index); }
+
+ void SetPin(int pin) { HALSIM_SetDigitalPWMPin(m_index, pin); }
+
+ void ResetData() { HALSIM_ResetDigitalPWMData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/DriverStationSim.h b/hal/src/main/native/include/simulation/DriverStationSim.h
new file mode 100644
index 0000000..55c38a9
--- /dev/null
+++ b/hal/src/main/native/include/simulation/DriverStationSim.h
@@ -0,0 +1,112 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/DriverStationData.h"
+
+namespace frc {
+namespace sim {
+class DriverStationSim {
+ public:
+ std::unique_ptr<CallbackStore> RegisterEnabledCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ -1, callback, &HALSIM_CancelDriverStationEnabledCallback);
+ store->SetUid(HALSIM_RegisterDriverStationEnabledCallback(
+ &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetEnabled() const { return HALSIM_GetDriverStationEnabled(); }
+
+ void SetEnabled(bool enabled) { HALSIM_SetDriverStationEnabled(enabled); }
+
+ std::unique_ptr<CallbackStore> RegisterAutonomousCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ -1, callback, &HALSIM_CancelDriverStationAutonomousCallback);
+ store->SetUid(HALSIM_RegisterDriverStationAutonomousCallback(
+ &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetAutonomous() const { return HALSIM_GetDriverStationAutonomous(); }
+
+ void SetAutonomous(bool autonomous) {
+ HALSIM_SetDriverStationAutonomous(autonomous);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterTestCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ -1, callback, &HALSIM_CancelDriverStationTestCallback);
+ store->SetUid(HALSIM_RegisterDriverStationTestCallback(
+ &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetTest() const { return HALSIM_GetDriverStationTest(); }
+
+ void SetTest(bool test) { HALSIM_SetDriverStationTest(test); }
+
+ std::unique_ptr<CallbackStore> RegisterEStopCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ -1, callback, &HALSIM_CancelDriverStationEStopCallback);
+ store->SetUid(HALSIM_RegisterDriverStationEStopCallback(
+ &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetEStop() const { return HALSIM_GetDriverStationEStop(); }
+
+ void SetEStop(bool eStop) { HALSIM_SetDriverStationEStop(eStop); }
+
+ std::unique_ptr<CallbackStore> RegisterFmsAttachedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ -1, callback, &HALSIM_CancelDriverStationFmsAttachedCallback);
+ store->SetUid(HALSIM_RegisterDriverStationFmsAttachedCallback(
+ &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetFmsAttached() const { return HALSIM_GetDriverStationFmsAttached(); }
+
+ void SetFmsAttached(bool fmsAttached) {
+ HALSIM_SetDriverStationFmsAttached(fmsAttached);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterDsAttachedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ -1, callback, &HALSIM_CancelDriverStationDsAttachedCallback);
+ store->SetUid(HALSIM_RegisterDriverStationDsAttachedCallback(
+ &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetDsAttached() const { return HALSIM_GetDriverStationDsAttached(); }
+
+ void SetDsAttached(bool dsAttached) {
+ HALSIM_SetDriverStationDsAttached(dsAttached);
+ }
+
+ void NotifyNewData() { HALSIM_NotifyDriverStationNewData(); }
+
+ void ResetData() { HALSIM_ResetDriverStationData(); }
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/EncoderSim.h b/hal/src/main/native/include/simulation/EncoderSim.h
new file mode 100644
index 0000000..493f338
--- /dev/null
+++ b/hal/src/main/native/include/simulation/EncoderSim.h
@@ -0,0 +1,166 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/EncoderData.h"
+
+namespace frc {
+namespace sim {
+class EncoderSim {
+ public:
+ explicit EncoderSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterInitializedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelEncoderInitializedCallback);
+ store->SetUid(HALSIM_RegisterEncoderInitializedCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetInitialized() const { return HALSIM_GetEncoderInitialized(m_index); }
+
+ void SetInitialized(bool initialized) {
+ HALSIM_SetEncoderInitialized(m_index, initialized);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterCountCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelEncoderCountCallback);
+ store->SetUid(HALSIM_RegisterEncoderCountCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetCount() const { return HALSIM_GetEncoderCount(m_index); }
+
+ void SetCount(int count) { HALSIM_SetEncoderCount(m_index, count); }
+
+ std::unique_ptr<CallbackStore> RegisterPeriodCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelEncoderPeriodCallback);
+ store->SetUid(HALSIM_RegisterEncoderPeriodCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetPeriod() const { return HALSIM_GetEncoderPeriod(m_index); }
+
+ void SetPeriod(double period) { HALSIM_SetEncoderPeriod(m_index, period); }
+
+ std::unique_ptr<CallbackStore> RegisterResetCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelEncoderResetCallback);
+ store->SetUid(HALSIM_RegisterEncoderResetCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetReset() const { return HALSIM_GetEncoderReset(m_index); }
+
+ void SetReset(bool reset) { HALSIM_SetEncoderReset(m_index, reset); }
+
+ std::unique_ptr<CallbackStore> RegisterMaxPeriodCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelEncoderMaxPeriodCallback);
+ store->SetUid(HALSIM_RegisterEncoderMaxPeriodCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetMaxPeriod() const { return HALSIM_GetEncoderMaxPeriod(m_index); }
+
+ void SetMaxPeriod(double maxPeriod) {
+ HALSIM_SetEncoderMaxPeriod(m_index, maxPeriod);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterDirectionCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelEncoderDirectionCallback);
+ store->SetUid(HALSIM_RegisterEncoderDirectionCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetDirection() const { return HALSIM_GetEncoderDirection(m_index); }
+
+ void SetDirection(bool direction) {
+ HALSIM_SetEncoderDirection(m_index, direction);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterReverseDirectionCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelEncoderReverseDirectionCallback);
+ store->SetUid(HALSIM_RegisterEncoderReverseDirectionCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetReverseDirection() const {
+ return HALSIM_GetEncoderReverseDirection(m_index);
+ }
+
+ void SetReverseDirection(bool reverseDirection) {
+ HALSIM_SetEncoderReverseDirection(m_index, reverseDirection);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterSamplesToAverageCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelEncoderSamplesToAverageCallback);
+ store->SetUid(HALSIM_RegisterEncoderSamplesToAverageCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetSamplesToAverage() const {
+ return HALSIM_GetEncoderSamplesToAverage(m_index);
+ }
+
+ void SetSamplesToAverage(int samplesToAverage) {
+ HALSIM_SetEncoderSamplesToAverage(m_index, samplesToAverage);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterDistancePerPulseCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelEncoderDistancePerPulseCallback);
+ store->SetUid(HALSIM_RegisterEncoderDistancePerPulseCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetDistancePerPulse() const {
+ return HALSIM_GetEncoderDistancePerPulse(m_index);
+ }
+
+ void SetDistancePerPulse(double distancePerPulse) {
+ HALSIM_SetEncoderDistancePerPulse(m_index, distancePerPulse);
+ }
+
+ void ResetData() { HALSIM_ResetEncoderData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/PCMSim.h b/hal/src/main/native/include/simulation/PCMSim.h
new file mode 100644
index 0000000..bfefa6e
--- /dev/null
+++ b/hal/src/main/native/include/simulation/PCMSim.h
@@ -0,0 +1,150 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/PCMData.h"
+
+namespace frc {
+namespace sim {
+class PCMSim {
+ public:
+ explicit PCMSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterSolenoidInitializedCallback(
+ int channel, NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, channel, -1, callback,
+ &HALSIM_CancelPCMSolenoidInitializedCallback);
+ store->SetUid(HALSIM_RegisterPCMSolenoidInitializedCallback(
+ m_index, channel, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetSolenoidInitialized(int channel) const {
+ return HALSIM_GetPCMSolenoidInitialized(m_index, channel);
+ }
+
+ void SetSolenoidInitialized(int channel, bool solenoidInitialized) {
+ HALSIM_SetPCMSolenoidInitialized(m_index, channel, solenoidInitialized);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterSolenoidOutputCallback(
+ int channel, NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, channel, -1, callback,
+ &HALSIM_CancelPCMSolenoidOutputCallback);
+ store->SetUid(HALSIM_RegisterPCMSolenoidOutputCallback(
+ m_index, channel, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetSolenoidOutput(int channel) const {
+ return HALSIM_GetPCMSolenoidOutput(m_index, channel);
+ }
+
+ void SetSolenoidOutput(int channel, bool solenoidOutput) {
+ HALSIM_SetPCMSolenoidOutput(m_index, channel, solenoidOutput);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterCompressorInitializedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPCMCompressorInitializedCallback);
+ store->SetUid(HALSIM_RegisterPCMCompressorInitializedCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetCompressorInitialized() const {
+ return HALSIM_GetPCMCompressorInitialized(m_index);
+ }
+
+ void SetCompressorInitialized(bool compressorInitialized) {
+ HALSIM_SetPCMCompressorInitialized(m_index, compressorInitialized);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterCompressorOnCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPCMCompressorOnCallback);
+ store->SetUid(HALSIM_RegisterPCMCompressorOnCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetCompressorOn() const { return HALSIM_GetPCMCompressorOn(m_index); }
+
+ void SetCompressorOn(bool compressorOn) {
+ HALSIM_SetPCMCompressorOn(m_index, compressorOn);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterClosedLoopEnabledCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPCMClosedLoopEnabledCallback);
+ store->SetUid(HALSIM_RegisterPCMClosedLoopEnabledCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetClosedLoopEnabled() const {
+ return HALSIM_GetPCMClosedLoopEnabled(m_index);
+ }
+
+ void SetClosedLoopEnabled(bool closedLoopEnabled) {
+ HALSIM_SetPCMClosedLoopEnabled(m_index, closedLoopEnabled);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterPressureSwitchCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPCMPressureSwitchCallback);
+ store->SetUid(HALSIM_RegisterPCMPressureSwitchCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetPressureSwitch() const {
+ return HALSIM_GetPCMPressureSwitch(m_index);
+ }
+
+ void SetPressureSwitch(bool pressureSwitch) {
+ HALSIM_SetPCMPressureSwitch(m_index, pressureSwitch);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterCompressorCurrentCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPCMCompressorCurrentCallback);
+ store->SetUid(HALSIM_RegisterPCMCompressorCurrentCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetCompressorCurrent() const {
+ return HALSIM_GetPCMCompressorCurrent(m_index);
+ }
+
+ void SetCompressorCurrent(double compressorCurrent) {
+ HALSIM_SetPCMCompressorCurrent(m_index, compressorCurrent);
+ }
+
+ void ResetData() { HALSIM_ResetPCMData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/PDPSim.h b/hal/src/main/native/include/simulation/PDPSim.h
new file mode 100644
index 0000000..7677ec2
--- /dev/null
+++ b/hal/src/main/native/include/simulation/PDPSim.h
@@ -0,0 +1,91 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/PDPData.h"
+
+namespace frc {
+namespace sim {
+class PDPSim {
+ public:
+ explicit PDPSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterInitializedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPDPInitializedCallback);
+ store->SetUid(HALSIM_RegisterPDPInitializedCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetInitialized() const { return HALSIM_GetPDPInitialized(m_index); }
+
+ void SetInitialized(bool initialized) {
+ HALSIM_SetPDPInitialized(m_index, initialized);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterTemperatureCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPDPTemperatureCallback);
+ store->SetUid(HALSIM_RegisterPDPTemperatureCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetTemperature() const { return HALSIM_GetPDPTemperature(m_index); }
+
+ void SetTemperature(double temperature) {
+ HALSIM_SetPDPTemperature(m_index, temperature);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterVoltageCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPDPVoltageCallback);
+ store->SetUid(HALSIM_RegisterPDPVoltageCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetVoltage() const { return HALSIM_GetPDPVoltage(m_index); }
+
+ void SetVoltage(double voltage) { HALSIM_SetPDPVoltage(m_index, voltage); }
+
+ std::unique_ptr<CallbackStore> RegisterCurrentCallback(
+ int channel, NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, channel, -1, callback, &HALSIM_CancelPDPCurrentCallback);
+ store->SetUid(HALSIM_RegisterPDPCurrentCallback(
+ m_index, channel, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetCurrent(int channel) const {
+ return HALSIM_GetPDPCurrent(m_index, channel);
+ }
+
+ void SetCurrent(int channel, double current) {
+ HALSIM_SetPDPCurrent(m_index, channel, current);
+ }
+
+ void ResetData() { HALSIM_ResetPDPData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/PWMSim.h b/hal/src/main/native/include/simulation/PWMSim.h
new file mode 100644
index 0000000..b90b76f
--- /dev/null
+++ b/hal/src/main/native/include/simulation/PWMSim.h
@@ -0,0 +1,117 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/PWMData.h"
+
+namespace frc {
+namespace sim {
+class PWMSim {
+ public:
+ explicit PWMSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterInitializedCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPWMInitializedCallback);
+ store->SetUid(HALSIM_RegisterPWMInitializedCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetInitialized() const { return HALSIM_GetPWMInitialized(m_index); }
+
+ void SetInitialized(bool initialized) {
+ HALSIM_SetPWMInitialized(m_index, initialized);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterRawValueCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPWMRawValueCallback);
+ store->SetUid(HALSIM_RegisterPWMRawValueCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetRawValue() const { return HALSIM_GetPWMRawValue(m_index); }
+
+ void SetRawValue(int rawValue) { HALSIM_SetPWMRawValue(m_index, rawValue); }
+
+ std::unique_ptr<CallbackStore> RegisterSpeedCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPWMSpeedCallback);
+ store->SetUid(HALSIM_RegisterPWMSpeedCallback(m_index, &CallbackStoreThunk,
+ store.get(), initialNotify));
+ return store;
+ }
+
+ double GetSpeed() const { return HALSIM_GetPWMSpeed(m_index); }
+
+ void SetSpeed(double speed) { HALSIM_SetPWMSpeed(m_index, speed); }
+
+ std::unique_ptr<CallbackStore> RegisterPositionCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPWMPositionCallback);
+ store->SetUid(HALSIM_RegisterPWMPositionCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetPosition() const { return HALSIM_GetPWMPosition(m_index); }
+
+ void SetPosition(double position) {
+ HALSIM_SetPWMPosition(m_index, position);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterPeriodScaleCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPWMPeriodScaleCallback);
+ store->SetUid(HALSIM_RegisterPWMPeriodScaleCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetPeriodScale() const { return HALSIM_GetPWMPeriodScale(m_index); }
+
+ void SetPeriodScale(int periodScale) {
+ HALSIM_SetPWMPeriodScale(m_index, periodScale);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterZeroLatchCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelPWMZeroLatchCallback);
+ store->SetUid(HALSIM_RegisterPWMZeroLatchCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetZeroLatch() const { return HALSIM_GetPWMZeroLatch(m_index); }
+
+ void SetZeroLatch(bool zeroLatch) {
+ HALSIM_SetPWMZeroLatch(m_index, zeroLatch);
+ }
+
+ void ResetData() { HALSIM_ResetPWMData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/RelaySim.h b/hal/src/main/native/include/simulation/RelaySim.h
new file mode 100644
index 0000000..b21a047
--- /dev/null
+++ b/hal/src/main/native/include/simulation/RelaySim.h
@@ -0,0 +1,91 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/RelayData.h"
+
+namespace frc {
+namespace sim {
+class RelaySim {
+ public:
+ explicit RelaySim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterInitializedForwardCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRelayInitializedForwardCallback);
+ store->SetUid(HALSIM_RegisterRelayInitializedForwardCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetInitializedForward() const {
+ return HALSIM_GetRelayInitializedForward(m_index);
+ }
+
+ void SetInitializedForward(bool initializedForward) {
+ HALSIM_SetRelayInitializedForward(m_index, initializedForward);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterInitializedReverseCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRelayInitializedReverseCallback);
+ store->SetUid(HALSIM_RegisterRelayInitializedReverseCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetInitializedReverse() const {
+ return HALSIM_GetRelayInitializedReverse(m_index);
+ }
+
+ void SetInitializedReverse(bool initializedReverse) {
+ HALSIM_SetRelayInitializedReverse(m_index, initializedReverse);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterForwardCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRelayForwardCallback);
+ store->SetUid(HALSIM_RegisterRelayForwardCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetForward() const { return HALSIM_GetRelayForward(m_index); }
+
+ void SetForward(bool forward) { HALSIM_SetRelayForward(m_index, forward); }
+
+ std::unique_ptr<CallbackStore> RegisterReverseCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRelayReverseCallback);
+ store->SetUid(HALSIM_RegisterRelayReverseCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetReverse() const { return HALSIM_GetRelayReverse(m_index); }
+
+ void SetReverse(bool reverse) { HALSIM_SetRelayReverse(m_index, reverse); }
+
+ void ResetData() { HALSIM_ResetRelayData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/RoboRioSim.h b/hal/src/main/native/include/simulation/RoboRioSim.h
new file mode 100644
index 0000000..0d7c31c
--- /dev/null
+++ b/hal/src/main/native/include/simulation/RoboRioSim.h
@@ -0,0 +1,276 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/RoboRioData.h"
+
+namespace frc {
+namespace sim {
+class RoboRioSim {
+ public:
+ explicit RoboRioSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterFPGAButtonCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioFPGAButtonCallback);
+ store->SetUid(HALSIM_RegisterRoboRioFPGAButtonCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetFPGAButton() const { return HALSIM_GetRoboRioFPGAButton(m_index); }
+
+ void SetFPGAButton(bool fPGAButton) {
+ HALSIM_SetRoboRioFPGAButton(m_index, fPGAButton);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterVInVoltageCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioVInVoltageCallback);
+ store->SetUid(HALSIM_RegisterRoboRioVInVoltageCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetVInVoltage() const { return HALSIM_GetRoboRioVInVoltage(m_index); }
+
+ void SetVInVoltage(double vInVoltage) {
+ HALSIM_SetRoboRioVInVoltage(m_index, vInVoltage);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterVInCurrentCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioVInCurrentCallback);
+ store->SetUid(HALSIM_RegisterRoboRioVInCurrentCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetVInCurrent() const { return HALSIM_GetRoboRioVInCurrent(m_index); }
+
+ void SetVInCurrent(double vInCurrent) {
+ HALSIM_SetRoboRioVInCurrent(m_index, vInCurrent);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterUserVoltage6VCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioUserVoltage6VCallback);
+ store->SetUid(HALSIM_RegisterRoboRioUserVoltage6VCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetUserVoltage6V() const {
+ return HALSIM_GetRoboRioUserVoltage6V(m_index);
+ }
+
+ void SetUserVoltage6V(double userVoltage6V) {
+ HALSIM_SetRoboRioUserVoltage6V(m_index, userVoltage6V);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterUserCurrent6VCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioUserCurrent6VCallback);
+ store->SetUid(HALSIM_RegisterRoboRioUserCurrent6VCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetUserCurrent6V() const {
+ return HALSIM_GetRoboRioUserCurrent6V(m_index);
+ }
+
+ void SetUserCurrent6V(double userCurrent6V) {
+ HALSIM_SetRoboRioUserCurrent6V(m_index, userCurrent6V);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterUserActive6VCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioUserActive6VCallback);
+ store->SetUid(HALSIM_RegisterRoboRioUserActive6VCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetUserActive6V() const {
+ return HALSIM_GetRoboRioUserActive6V(m_index);
+ }
+
+ void SetUserActive6V(bool userActive6V) {
+ HALSIM_SetRoboRioUserActive6V(m_index, userActive6V);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterUserVoltage5VCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioUserVoltage5VCallback);
+ store->SetUid(HALSIM_RegisterRoboRioUserVoltage5VCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetUserVoltage5V() const {
+ return HALSIM_GetRoboRioUserVoltage5V(m_index);
+ }
+
+ void SetUserVoltage5V(double userVoltage5V) {
+ HALSIM_SetRoboRioUserVoltage5V(m_index, userVoltage5V);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterUserCurrent5VCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioUserCurrent5VCallback);
+ store->SetUid(HALSIM_RegisterRoboRioUserCurrent5VCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetUserCurrent5V() const {
+ return HALSIM_GetRoboRioUserCurrent5V(m_index);
+ }
+
+ void SetUserCurrent5V(double userCurrent5V) {
+ HALSIM_SetRoboRioUserCurrent5V(m_index, userCurrent5V);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterUserActive5VCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioUserActive5VCallback);
+ store->SetUid(HALSIM_RegisterRoboRioUserActive5VCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetUserActive5V() const {
+ return HALSIM_GetRoboRioUserActive5V(m_index);
+ }
+
+ void SetUserActive5V(bool userActive5V) {
+ HALSIM_SetRoboRioUserActive5V(m_index, userActive5V);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterUserVoltage3V3Callback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioUserVoltage3V3Callback);
+ store->SetUid(HALSIM_RegisterRoboRioUserVoltage3V3Callback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetUserVoltage3V3() const {
+ return HALSIM_GetRoboRioUserVoltage3V3(m_index);
+ }
+
+ void SetUserVoltage3V3(double userVoltage3V3) {
+ HALSIM_SetRoboRioUserVoltage3V3(m_index, userVoltage3V3);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterUserCurrent3V3Callback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioUserCurrent3V3Callback);
+ store->SetUid(HALSIM_RegisterRoboRioUserCurrent3V3Callback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetUserCurrent3V3() const {
+ return HALSIM_GetRoboRioUserCurrent3V3(m_index);
+ }
+
+ void SetUserCurrent3V3(double userCurrent3V3) {
+ HALSIM_SetRoboRioUserCurrent3V3(m_index, userCurrent3V3);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterUserActive3V3Callback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioUserActive3V3Callback);
+ store->SetUid(HALSIM_RegisterRoboRioUserActive3V3Callback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetUserActive3V3() const {
+ return HALSIM_GetRoboRioUserActive3V3(m_index);
+ }
+
+ void SetUserActive3V3(bool userActive3V3) {
+ HALSIM_SetRoboRioUserActive3V3(m_index, userActive3V3);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterUserFaults6VCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioUserFaults6VCallback);
+ store->SetUid(HALSIM_RegisterRoboRioUserFaults6VCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetUserFaults6V() const { return HALSIM_GetRoboRioUserFaults6V(m_index); }
+
+ void SetUserFaults6V(int userFaults6V) {
+ HALSIM_SetRoboRioUserFaults6V(m_index, userFaults6V);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterUserFaults5VCallback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioUserFaults5VCallback);
+ store->SetUid(HALSIM_RegisterRoboRioUserFaults5VCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetUserFaults5V() const { return HALSIM_GetRoboRioUserFaults5V(m_index); }
+
+ void SetUserFaults5V(int userFaults5V) {
+ HALSIM_SetRoboRioUserFaults5V(m_index, userFaults5V);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterUserFaults3V3Callback(
+ NotifyCallback callback, bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelRoboRioUserFaults3V3Callback);
+ store->SetUid(HALSIM_RegisterRoboRioUserFaults3V3Callback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetUserFaults3V3() const {
+ return HALSIM_GetRoboRioUserFaults3V3(m_index);
+ }
+
+ void SetUserFaults3V3(int userFaults3V3) {
+ HALSIM_SetRoboRioUserFaults3V3(m_index, userFaults3V3);
+ }
+
+ void ResetData() { HALSIM_ResetRoboRioData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/SPIAccelerometerSim.h b/hal/src/main/native/include/simulation/SPIAccelerometerSim.h
new file mode 100644
index 0000000..4369938
--- /dev/null
+++ b/hal/src/main/native/include/simulation/SPIAccelerometerSim.h
@@ -0,0 +1,98 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include <memory>
+#include <utility>
+
+#include "CallbackStore.h"
+#include "mockdata/SPIAccelerometerData.h"
+
+namespace frc {
+namespace sim {
+class SPIAccelerometerSim {
+ public:
+ explicit SPIAccelerometerSim(int index) { m_index = index; }
+
+ std::unique_ptr<CallbackStore> RegisterActiveCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelSPIAccelerometerActiveCallback);
+ store->SetUid(HALSIM_RegisterSPIAccelerometerActiveCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ bool GetActive() const { return HALSIM_GetSPIAccelerometerActive(m_index); }
+
+ void SetActive(bool active) {
+ HALSIM_SetSPIAccelerometerActive(m_index, active);
+ }
+
+ std::unique_ptr<CallbackStore> RegisterRangeCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelSPIAccelerometerRangeCallback);
+ store->SetUid(HALSIM_RegisterSPIAccelerometerRangeCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ int GetRange() const { return HALSIM_GetSPIAccelerometerRange(m_index); }
+
+ void SetRange(int range) { HALSIM_SetSPIAccelerometerRange(m_index, range); }
+
+ std::unique_ptr<CallbackStore> RegisterXCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelSPIAccelerometerXCallback);
+ store->SetUid(HALSIM_RegisterSPIAccelerometerXCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetX() const { return HALSIM_GetSPIAccelerometerX(m_index); }
+
+ void SetX(double x) { HALSIM_SetSPIAccelerometerX(m_index, x); }
+
+ std::unique_ptr<CallbackStore> RegisterYCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelSPIAccelerometerYCallback);
+ store->SetUid(HALSIM_RegisterSPIAccelerometerYCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetY() const { return HALSIM_GetSPIAccelerometerY(m_index); }
+
+ void SetY(double y) { HALSIM_SetSPIAccelerometerY(m_index, y); }
+
+ std::unique_ptr<CallbackStore> RegisterZCallback(NotifyCallback callback,
+ bool initialNotify) {
+ auto store = std::make_unique<CallbackStore>(
+ m_index, -1, callback, &HALSIM_CancelSPIAccelerometerZCallback);
+ store->SetUid(HALSIM_RegisterSPIAccelerometerZCallback(
+ m_index, &CallbackStoreThunk, store.get(), initialNotify));
+ return store;
+ }
+
+ double GetZ() const { return HALSIM_GetSPIAccelerometerZ(m_index); }
+
+ void SetZ(double z) { HALSIM_SetSPIAccelerometerZ(m_index, z); }
+
+ void ResetData() { HALSIM_ResetSPIAccelerometerData(m_index); }
+
+ private:
+ int m_index;
+};
+} // namespace sim
+} // namespace frc
+#endif // __FRC_ROBORIO__
diff --git a/hal/src/main/native/include/simulation/SimHooks.h b/hal/src/main/native/include/simulation/SimHooks.h
new file mode 100644
index 0000000..6f03952
--- /dev/null
+++ b/hal/src/main/native/include/simulation/SimHooks.h
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifndef __FRC_ROBORIO__
+
+#include "mockdata/MockHooks.h"
+
+namespace frc {
+namespace sim {
+
+void WaitForProgramStart() { HALSIM_WaitForProgramStart(); }
+
+void SetProgramStarted() { HALSIM_SetProgramStarted(); }
+
+bool GetProgramStarted() { return HALSIM_GetProgramStarted(); }
+
+void RestartTiming() { HALSIM_RestartTiming(); }
+
+} // namespace sim
+} // namespace frc
+
+#endif
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/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..a0f44a7
--- /dev/null
+++ b/hal/src/main/native/sim/AnalogInput.cpp
@@ -0,0 +1,179 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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;
+
+ 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_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_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..53b165c
--- /dev/null
+++ b/hal/src/main/native/sim/AnalogTrigger.cpp
@@ -0,0 +1,261 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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* index, 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));
+ *index = trigger->index;
+
+ SimAnalogTriggerData[trigger->index].initialized = true;
+
+ trigger->trigState = false;
+
+ return handle;
+}
+
+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_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_AnalogTriggerFiltered) {
+ *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_AnalogTriggerAveraged) {
+ *status = INCOMPATIBLE_STATE;
+ return;
+ }
+
+ auto setVal = useFilteredValue ? HALSIM_AnalogTriggerAveraged
+ : 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;
+ }
+}
+} // 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..d55eafd
--- /dev/null
+++ b/hal/src/main/native/sim/CAN.cpp
@@ -0,0 +1,55 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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) {
+ SimCanData->receiveMessage(messageID, messageIDMask, data, dataSize,
+ timeStamp, status);
+}
+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..a54f06f
--- /dev/null
+++ b/hal/src/main/native/sim/CANAPI.cpp
@@ -0,0 +1,335 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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::lock_guard<wpi::mutex> lock(data->mapMutex);
+
+ for (auto&& i : data->periodicSends) {
+ int32_t s = 0;
+ HAL_CAN_SendMessage(i.first, 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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> lock(can->mapMutex);
+ can->periodicSends[apiId] = repeatMs;
+}
+
+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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> 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..e67b756
--- /dev/null
+++ b/hal/src/main/native/sim/DIO.cpp
@@ -0,0 +1,247 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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;
+
+ 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 = true;
+}
+
+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/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..89644a1
--- /dev/null
+++ b/hal/src/main/native/sim/DigitalInternal.h
@@ -0,0 +1,93 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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.05;
+/**
+ * kDefaultPwmCenter is the PWM range center in ms
+ */
+constexpr float kDefaultPwmCenter = 1.5;
+/**
+ * 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..0c9c028
--- /dev/null
+++ b/hal/src/main/native/sim/DriverStation.cpp
@@ -0,0 +1,291 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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};
+
+namespace hal {
+namespace init {
+void InitializeDriverStation() {
+ static wpi::condition_variable nddaC;
+ newDSDataAvailableCond = &nddaC;
+}
+} // namespace init
+} // namespace hal
+
+using namespace hal;
+
+extern "C" {
+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) {
+ // 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::lock_guard<wpi::mutex> 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
+
+HAL_Bool HAL_IsNewControlData(void) {
+#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
+ // 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.
+ int currentCount = 0;
+ {
+ std::unique_lock<wpi::mutex> 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<wpi::mutex> 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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> 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/Encoder.cpp b/hal/src/main/native/sim/Encoder.cpp
new file mode 100644
index 0000000..3f197a2
--- /dev/null
+++ b/hal/src/main/native/sim/Encoder.cpp
@@ -0,0 +1,345 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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].initialized = true;
+ SimEncoderData[index].reverseDirection = reverseDirection;
+ // 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;
+}
+
+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..6ef7903
--- /dev/null
+++ b/hal/src/main/native/sim/Extensions.cpp
@@ -0,0 +1,85 @@
+/*----------------------------------------------------------------------------*/
+/* 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/Extensions.h"
+
+#include <wpi/SmallString.h>
+#include <wpi/StringRef.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
+
+extern "C" {
+
+int HAL_LoadOneExtension(const char* library) {
+ int rc = 1; // It is expected and reasonable not to find an extra simulation
+ 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
+ handle = DLOPEN(libraryName.c_str());
+ }
+#endif
+ if (!handle) return rc;
+
+ auto init = reinterpret_cast<halsim_extension_init_func_t*>(
+ DLSYM(handle, "HALSIM_InitExtension"));
+
+ if (init) rc = (*init)();
+
+ if (rc != 0) DLCLOSE(handle);
+ return rc;
+}
+
+int HAL_LoadExtensions(void) {
+ int rc = 1;
+ wpi::SmallVector<wpi::StringRef, 2> libraries;
+ const char* e = std::getenv("HALSIM_EXTENSIONS");
+ if (!e) 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;
+}
+
+} // 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..d058c1a
--- /dev/null
+++ b/hal/src/main/native/sim/HAL.cpp
@@ -0,0 +1,256 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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();
+ InitializeAnalogGyroData();
+ InitializeAnalogInData();
+ InitializeAnalogOutData();
+ InitializeAnalogTriggerData();
+ InitializeCanData();
+ InitializeCANAPI();
+ InitializeDigitalPWMData();
+ InitializeDIOData();
+ InitializeDriverStationData();
+ InitializeEncoderData();
+ InitializeI2CData();
+ InitializePCMData();
+ InitializePDPData();
+ InitializePWMData();
+ InitializeRelayData();
+ InitializeRoboRioData();
+ InitializeSPIAccelerometerData();
+ InitializeSPIData();
+ InitializeAccelerometer();
+ InitializeAnalogAccumulator();
+ InitializeAnalogGyro();
+ InitializeAnalogInput();
+ InitializeAnalogInternal();
+ InitializeAnalogOutput();
+ InitializeCAN();
+ InitializeCompressor();
+ InitializeConstants();
+ InitializeCounter();
+ InitializeDigitalInternal();
+ InitializeDIO();
+ InitializeDriverStation();
+ InitializeEncoder();
+ InitializeExtensions();
+ InitializeI2C();
+ InitializeInterrupts();
+ InitializeMockHooks();
+ InitializeNotifier();
+ InitializePDP();
+ InitializePorts();
+ InitializePower();
+ InitializePWM();
+ InitializeRelay();
+ InitializeSerialPort();
+ 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;
+ 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(); }
+
+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::lock_guard<wpi::mutex> 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..d369a3b
--- /dev/null
+++ b/hal/src/main/native/sim/HALInitializer.h
@@ -0,0 +1,71 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <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 InitializeAnalogGyroData();
+extern void InitializeAnalogInData();
+extern void InitializeAnalogOutData();
+extern void InitializeAnalogTriggerData();
+extern void InitializeCanData();
+extern void InitializeCANAPI();
+extern void InitializeDigitalPWMData();
+extern void InitializeDIOData();
+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 InitializeSPIAccelerometerData();
+extern void InitializeSPIData();
+extern void InitializeAccelerometer();
+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 InitializeMockHooks();
+extern void InitializeNotifier();
+extern void InitializePDP();
+extern void InitializePorts();
+extern void InitializePower();
+extern void InitializePWM();
+extern void InitializeRelay();
+extern void InitializeSerialPort();
+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..75247ca
--- /dev/null
+++ b/hal/src/main/native/sim/Interrupts.cpp
@@ -0,0 +1,565 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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/handles/HandlesInternal.h"
+#include "hal/handles/LimitedHandleResource.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/AnalogInDataInternal.h"
+#include "mockdata/DIODataInternal.h"
+#include "mockdata/HAL_Value.h"
+
+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;
+ wpi::condition_variable waitCond;
+ HAL_Bool waitPredicate;
+};
+} // 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<wpi::mutex> 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);
+ 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<wpi::mutex> 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);
+ 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..25c1d9f
--- /dev/null
+++ b/hal/src/main/native/sim/MockHooks.cpp
@@ -0,0 +1,59 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <atomic>
+#include <chrono>
+#include <cstdio>
+#include <thread>
+
+#include <wpi/timestamp.h>
+
+#include "MockHooksInternal.h"
+
+static std::atomic<bool> programStarted{false};
+
+static std::atomic<uint64_t> programStartTime{0};
+
+namespace hal {
+namespace init {
+void InitializeMockHooks() {}
+} // namespace init
+} // namespace hal
+
+namespace hal {
+void RestartTiming() { programStartTime = wpi::Now(); }
+
+int64_t GetFPGATime() {
+ auto now = wpi::Now();
+ auto currentTime = now - programStartTime;
+ return currentTime;
+}
+
+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(); }
+} // 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..e8c09a9
--- /dev/null
+++ b/hal/src/main/native/sim/MockHooksInternal.h
@@ -0,0 +1,22 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <stdint.h>
+
+#include "mockdata/MockHooks.h"
+
+namespace hal {
+void RestartTiming();
+
+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..9f549d5
--- /dev/null
+++ b/hal/src/main/native/sim/Notifier.cpp
@@ -0,0 +1,159 @@
+/*----------------------------------------------------------------------------*/
+/* 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/Notifier.h"
+
+#include <chrono>
+
+#include <wpi/condition_variable.h>
+#include <wpi/mutex.h>
+#include <wpi/timestamp.h>
+
+#include "HALInitializer.h"
+#include "hal/HAL.h"
+#include "hal/cpp/fpga_clock.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+
+namespace {
+struct Notifier {
+ uint64_t waitTime;
+ bool updatedAlarm = false;
+ 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::lock_guard<wpi::mutex> lock(notifier->mutex);
+ notifier->active = false;
+ notifier->running = false;
+ }
+ notifier->cond.notify_all(); // wake up any waiting threads
+ });
+ }
+};
+
+static NotifierHandleContainer* notifierHandles;
+
+namespace hal {
+namespace init {
+void InitializeNotifier() {
+ static NotifierHandleContainer nH;
+ notifierHandles = &nH;
+}
+} // namespace init
+} // 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_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status) {
+ auto notifier = notifierHandles->Get(notifierHandle);
+ if (!notifier) return;
+
+ {
+ std::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> lock(notifier->mutex);
+ notifier->waitTime = triggerTime;
+ notifier->running = true;
+ notifier->updatedAlarm = 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::lock_guard<wpi::mutex> 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<wpi::mutex> lock(notifier->mutex);
+ while (notifier->active) {
+ double waitTime;
+ if (!notifier->running) {
+ waitTime = (HAL_GetFPGATime(status) * 1e-6) + 1000.0;
+ // If not running, wait 1000 seconds
+ } else {
+ waitTime = notifier->waitTime * 1e-6;
+ }
+
+ // Don't wait twice
+ notifier->updatedAlarm = false;
+
+ auto timeoutTime =
+ hal::fpga_clock::epoch() + std::chrono::duration<double>(waitTime);
+ notifier->cond.wait_until(lock, timeoutTime);
+ if (notifier->updatedAlarm) {
+ notifier->updatedAlarm = false;
+ continue;
+ }
+ if (!notifier->running) continue;
+ if (!notifier->active) break;
+ notifier->running = false;
+ return HAL_GetFPGATime(status);
+ }
+ return 0;
+}
+
+} // extern "C"
diff --git a/hal/src/main/native/sim/PDP.cpp b/hal/src/main/native/sim/PDP.cpp
new file mode 100644
index 0000000..07f4dcd
--- /dev/null
+++ b/hal/src/main/native/sim/PDP.cpp
@@ -0,0 +1,92 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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];
+}
+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..f50304f
--- /dev/null
+++ b/hal/src/main/native/sim/Ports.cpp
@@ -0,0 +1,40 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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_GetNumCanTalons(void) { return kNumCanTalons; }
+} // 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..0b899f7
--- /dev/null
+++ b/hal/src/main/native/sim/PortsInternal.h
@@ -0,0 +1,32 @@
+/*----------------------------------------------------------------------------*/
+/* 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 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 kNumCanTalons = 63;
+} // 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..8c539d3
--- /dev/null
+++ b/hal/src/main/native/sim/SPI.cpp
@@ -0,0 +1,65 @@
+/*----------------------------------------------------------------------------*/
+/* 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/SPI.h"
+
+#include "HALInitializer.h"
+#include "mockdata/SPIDataInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeSPI() {}
+} // namespace init
+} // namespace hal
+
+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;
+}
diff --git a/hal/src/main/native/sim/SerialPort.cpp b/hal/src/main/native/sim/SerialPort.cpp
new file mode 100644
index 0000000..bc08566
--- /dev/null
+++ b/hal/src/main/native/sim/SerialPort.cpp
@@ -0,0 +1,77 @@
+/*----------------------------------------------------------------------------*/
+/* 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/SerialPort.h"
+
+#include "HALInitializer.h"
+
+namespace hal {
+namespace init {
+void InitializeSerialPort() {}
+} // namespace init
+} // namespace hal
+
+extern "C" {
+void HAL_InitializeSerialPort(HAL_SerialPort port, int32_t* status) {
+ hal::init::CheckInit();
+}
+
+void HAL_InitializeSerialPortDirect(HAL_SerialPort port, const char* portName,
+ int32_t* status) {}
+
+void HAL_SetSerialBaudRate(HAL_SerialPort port, int32_t baud, int32_t* status) {
+}
+
+void HAL_SetSerialDataBits(HAL_SerialPort port, int32_t bits, int32_t* status) {
+}
+
+void HAL_SetSerialParity(HAL_SerialPort port, int32_t parity, int32_t* status) {
+}
+
+void HAL_SetSerialStopBits(HAL_SerialPort port, int32_t stopBits,
+ int32_t* status) {}
+
+void HAL_SetSerialWriteMode(HAL_SerialPort port, int32_t mode,
+ int32_t* status) {}
+
+void HAL_SetSerialFlowControl(HAL_SerialPort port, int32_t flow,
+ int32_t* status) {}
+
+void HAL_SetSerialTimeout(HAL_SerialPort port, double timeout,
+ int32_t* status) {}
+
+void HAL_EnableSerialTermination(HAL_SerialPort port, char terminator,
+ int32_t* status) {}
+
+void HAL_DisableSerialTermination(HAL_SerialPort port, int32_t* status) {}
+
+void HAL_SetSerialReadBufferSize(HAL_SerialPort port, int32_t size,
+ int32_t* status) {}
+
+void HAL_SetSerialWriteBufferSize(HAL_SerialPort port, int32_t size,
+ int32_t* status) {}
+
+int32_t HAL_GetSerialBytesReceived(HAL_SerialPort port, int32_t* status) {
+ return 0;
+}
+
+int32_t HAL_ReadSerial(HAL_SerialPort port, char* buffer, int32_t count,
+ int32_t* status) {
+ return 0;
+}
+
+int32_t HAL_WriteSerial(HAL_SerialPort port, const char* buffer, int32_t count,
+ int32_t* status) {
+ return 0;
+}
+
+void HAL_FlushSerial(HAL_SerialPort port, int32_t* status) {}
+
+void HAL_ClearSerial(HAL_SerialPort port, int32_t* status) {}
+
+void HAL_CloseSerial(HAL_SerialPort port, int32_t* status) {}
+} // 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..d3f0c5d
--- /dev/null
+++ b/hal/src/main/native/sim/Solenoid.cpp
@@ -0,0 +1,136 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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);
+}
+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/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..fbf3adc
--- /dev/null
+++ b/hal/src/main/native/sim/jni/BufferCallbackStore.cpp
@@ -0,0 +1,125 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "BufferCallbackStore.h"
+
+#include <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/HAL_Value.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..b9d49ac
--- /dev/null
+++ b/hal/src/main/native/sim/jni/BufferCallbackStore.h
@@ -0,0 +1,45 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/HAL_Value.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..abef9b0
--- /dev/null
+++ b/hal/src/main/native/sim/jni/CallbackStore.cpp
@@ -0,0 +1,194 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "CallbackStore.h"
+
+#include <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/HAL_Value.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..94454b0
--- /dev/null
+++ b/hal/src/main/native/sim/jni/CallbackStore.h
@@ -0,0 +1,66 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/HAL_Value.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..781725b
--- /dev/null
+++ b/hal/src/main/native/sim/jni/ConstBufferCallbackStore.cpp
@@ -0,0 +1,117 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "ConstBufferCallbackStore.h"
+
+#include <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/HAL_Value.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..1b0f54e
--- /dev/null
+++ b/hal/src/main/native/sim/jni/ConstBufferCallbackStore.h
@@ -0,0 +1,46 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/HAL_Value.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..621650a
--- /dev/null
+++ b/hal/src/main/native/sim/jni/DriverStationDataJNI.cpp
@@ -0,0 +1,461 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <cstring>
+
+#include <wpi/jni_util.h>
+
+#include "CallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_DriverStationDataJNI.h"
+#include "mockdata/DriverStationData.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: 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/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/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/SimulatorJNI.cpp b/hal/src/main/native/sim/jni/SimulatorJNI.cpp
new file mode 100644
index 0000000..d1e0f7d
--- /dev/null
+++ b/hal/src/main/native/sim/jni/SimulatorJNI.cpp
@@ -0,0 +1,157 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "SimulatorJNI.h"
+
+#include "BufferCallbackStore.h"
+#include "CallbackStore.h"
+#include "ConstBufferCallbackStore.h"
+#include "SpiReadAutoReceiveBufferCallbackStore.h"
+#include "edu_wpi_first_hal_sim_mockdata_SimulatorJNI.h"
+#include "hal/HAL.h"
+#include "hal/cpp/Log.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/MockHooks.h"
+
+using namespace wpi::java;
+
+static JavaVM* jvm = nullptr;
+static JClass simValueCls;
+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;
+
+ simValueCls = JClass(env, "edu/wpi/first/hal/sim/SimValue");
+ if (!simValueCls) 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();
+
+ 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;
+
+ simValueCls.free(env);
+ notifyCallbackCls.free(env);
+ bufferCallbackCls.free(env);
+ constBufferCallbackCls.free(env);
+ spiReadAutoReceiveBufferCallbackCls.free(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: 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..60d0ca3
--- /dev/null
+++ b/hal/src/main/native/sim/jni/SimulatorJNI.h
@@ -0,0 +1,25 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <wpi/jni_util.h>
+
+#include "hal/Types.h"
+#include "jni.h"
+#include "mockdata/HAL_Value.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..935c8bf
--- /dev/null
+++ b/hal/src/main/native/sim/jni/SpiReadAutoReceiveBufferCallbackStore.cpp
@@ -0,0 +1,130 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "SpiReadAutoReceiveBufferCallbackStore.h"
+
+#include <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/HAL_Value.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..643a874
--- /dev/null
+++ b/hal/src/main/native/sim/jni/SpiReadAutoReceiveBufferCallbackStore.h
@@ -0,0 +1,47 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <jni.h>
+
+#include <wpi/jni_util.h>
+
+#include "SimulatorJNI.h"
+#include "hal/Types.h"
+#include "hal/handles/UnlimitedHandleResource.h"
+#include "mockdata/HAL_Value.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..15e55ac
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AccelerometerDataInternal.h
@@ -0,0 +1,36 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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 MakeEnum(value);
+ }
+
+ public:
+ SimDataValue<HAL_Bool, MakeBoolean, GetActiveName> active{false};
+ SimDataValue<HAL_AccelerometerRange, MakeRangeValue, GetRangeName> range{
+ static_cast<HAL_AccelerometerRange>(0)};
+ SimDataValue<double, MakeDouble, GetXName> x{0.0};
+ SimDataValue<double, MakeDouble, GetYName> y{0.0};
+ SimDataValue<double, MakeDouble, GetZName> z{0.0};
+
+ virtual void ResetData();
+};
+extern AccelerometerData* SimAccelerometerData;
+} // 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..8dfcb52
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogGyroDataInternal.h
@@ -0,0 +1,27 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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, MakeDouble, GetAngleName> angle{0.0};
+ SimDataValue<double, MakeDouble, GetRateName> rate{0.0};
+ SimDataValue<HAL_Bool, 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..1efdf50
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogInData.cpp
@@ -0,0 +1,70 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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);
+ 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();
+}
+
+#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..94121ca
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogInDataInternal.h
@@ -0,0 +1,41 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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, MakeBoolean, GetInitializedName> initialized{false};
+ SimDataValue<int32_t, MakeInt, GetAverageBitsName> averageBits{7};
+ SimDataValue<int32_t, MakeInt, GetOversampleBitsName> oversampleBits{0};
+ SimDataValue<double, MakeDouble, GetVoltageName> voltage{0.0};
+ SimDataValue<HAL_Bool, MakeBoolean, GetAccumulatorInitializedName>
+ accumulatorInitialized{false};
+ SimDataValue<int64_t, MakeLong, GetAccumulatorValueName> accumulatorValue{0};
+ SimDataValue<int64_t, MakeLong, GetAccumulatorCountName> accumulatorCount{0};
+ SimDataValue<int32_t, MakeInt, GetAccumulatorCenterName> accumulatorCenter{0};
+ SimDataValue<int32_t, 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..84af837
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogOutDataInternal.h
@@ -0,0 +1,25 @@
+/*----------------------------------------------------------------------------*/
+/* 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/AnalogOutData.h"
+#include "mockdata/SimDataValue.h"
+
+namespace hal {
+class AnalogOutData {
+ HAL_SIMDATAVALUE_DEFINE_NAME(Voltage)
+ HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
+
+ public:
+ SimDataValue<double, MakeDouble, GetVoltageName> voltage{0.0};
+ SimDataValue<HAL_Bool, 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..131ba7a
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/AnalogTriggerDataInternal.h
@@ -0,0 +1,38 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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 MakeEnum(value);
+ }
+
+ public:
+ SimDataValue<HAL_Bool, MakeBoolean, GetInitializedName> initialized{0};
+ SimDataValue<double, MakeDouble, GetTriggerLowerBoundName> triggerLowerBound{
+ 0};
+ SimDataValue<double, 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..ea66de3
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DIOData.cpp
@@ -0,0 +1,55 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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);
+ value.Reset(true);
+ pulseLength.Reset(0.0);
+ isInput.Reset(true);
+ filterIndex.Reset(-1);
+}
+
+extern "C" {
+void HALSIM_ResetDIOData(int32_t index) { SimDIOData[index].ResetData(); }
+
+#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..0b022f9
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DIODataInternal.h
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+#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, MakeBoolean, GetInitializedName> initialized{false};
+ SimDataValue<HAL_Bool, MakeBoolean, GetValueName> value{true};
+ SimDataValue<double, MakeDouble, GetPulseLengthName> pulseLength{0.0};
+ SimDataValue<HAL_Bool, MakeBoolean, GetIsInputName> isInput{true};
+ SimDataValue<int32_t, 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..00d8b4a
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DigitalPWMDataInternal.h
@@ -0,0 +1,27 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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, MakeBoolean, GetInitializedName> initialized{false};
+ SimDataValue<double, MakeDouble, GetDutyCycleName> dutyCycle{0.0};
+ SimDataValue<int32_t, 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..d72d6b3
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DriverStationData.cpp
@@ -0,0 +1,209 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <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::lock_guard<wpi::spinlock> 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::lock_guard<wpi::spinlock> lock(m_matchInfoMutex);
+
+ m_matchInfo = std::make_unique<HAL_MatchInfo>();
+ }
+}
+
+void DriverStationData::GetJoystickAxes(int32_t joystickNum,
+ HAL_JoystickAxes* axes) {
+ std::lock_guard<wpi::spinlock> lock(m_joystickDataMutex);
+ *axes = m_joystickAxes[joystickNum];
+}
+void DriverStationData::GetJoystickPOVs(int32_t joystickNum,
+ HAL_JoystickPOVs* povs) {
+ std::lock_guard<wpi::spinlock> lock(m_joystickDataMutex);
+ *povs = m_joystickPOVs[joystickNum];
+}
+void DriverStationData::GetJoystickButtons(int32_t joystickNum,
+ HAL_JoystickButtons* buttons) {
+ std::lock_guard<wpi::spinlock> lock(m_joystickDataMutex);
+ *buttons = m_joystickButtons[joystickNum];
+}
+void DriverStationData::GetJoystickDescriptor(
+ int32_t joystickNum, HAL_JoystickDescriptor* descriptor) {
+ std::lock_guard<wpi::spinlock> 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::lock_guard<wpi::spinlock> 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::lock_guard<wpi::spinlock> lock(m_matchInfoMutex);
+ *info = *m_matchInfo;
+}
+
+void DriverStationData::SetJoystickAxes(int32_t joystickNum,
+ const HAL_JoystickAxes* axes) {
+ std::lock_guard<wpi::spinlock> lock(m_joystickDataMutex);
+ m_joystickAxes[joystickNum] = *axes;
+}
+void DriverStationData::SetJoystickPOVs(int32_t joystickNum,
+ const HAL_JoystickPOVs* povs) {
+ std::lock_guard<wpi::spinlock> lock(m_joystickDataMutex);
+ m_joystickPOVs[joystickNum] = *povs;
+}
+void DriverStationData::SetJoystickButtons(int32_t joystickNum,
+ const HAL_JoystickButtons* buttons) {
+ std::lock_guard<wpi::spinlock> lock(m_joystickDataMutex);
+ m_joystickButtons[joystickNum] = *buttons;
+}
+
+void DriverStationData::SetJoystickDescriptor(
+ int32_t joystickNum, const HAL_JoystickDescriptor* descriptor) {
+ std::lock_guard<wpi::spinlock> lock(m_joystickDataMutex);
+ m_joystickDescriptor[joystickNum] = *descriptor;
+}
+
+void DriverStationData::SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
+ int32_t leftRumble,
+ int32_t rightRumble) {
+ std::lock_guard<wpi::spinlock> 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::lock_guard<wpi::spinlock> 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..f7eb132
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/DriverStationDataInternal.h
@@ -0,0 +1,85 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <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 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, MakeBoolean, GetEnabledName> enabled{false};
+ SimDataValue<HAL_Bool, MakeBoolean, GetAutonomousName> autonomous{false};
+ SimDataValue<HAL_Bool, MakeBoolean, GetTestName> test{false};
+ SimDataValue<HAL_Bool, MakeBoolean, GetEStopName> eStop{false};
+ SimDataValue<HAL_Bool, MakeBoolean, GetFmsAttachedName> fmsAttached{false};
+ SimDataValue<HAL_Bool, MakeBoolean, GetDsAttachedName> dsAttached{true};
+ SimDataValue<HAL_AllianceStationID, MakeAllianceStationIdValue,
+ GetAllianceStationIdName>
+ allianceStationId{static_cast<HAL_AllianceStationID>(0)};
+ SimDataValue<double, 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/EncoderData.cpp b/hal/src/main/native/sim/mockdata/EncoderData.cpp
new file mode 100644
index 0000000..59ba48f
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/EncoderData.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 "../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;
+ initialized.Reset(false);
+ 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();
+}
+
+int16_t HALSIM_GetDigitalChannelA(int32_t index) {
+ return SimEncoderData[index].digitalChannelA;
+}
+
+#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..657d977
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/EncoderDataInternal.h
@@ -0,0 +1,45 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <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<int16_t> digitalChannelA{0};
+ SimDataValue<HAL_Bool, MakeBoolean, GetInitializedName> initialized{false};
+ SimDataValue<int32_t, MakeInt, GetCountName> count{0};
+ SimDataValue<double, MakeDouble, GetPeriodName> period{
+ std::numeric_limits<double>::max()};
+ SimDataValue<HAL_Bool, MakeBoolean, GetResetName> reset{false};
+ SimDataValue<double, MakeDouble, GetMaxPeriodName> maxPeriod{0};
+ SimDataValue<HAL_Bool, MakeBoolean, GetDirectionName> direction{false};
+ SimDataValue<HAL_Bool, MakeBoolean, GetReverseDirectionName> reverseDirection{
+ false};
+ SimDataValue<int32_t, MakeInt, GetSamplesToAverageName> samplesToAverage{0};
+ SimDataValue<double, MakeDouble, GetDistancePerPulseName> distancePerPulse{1};
+
+ virtual void ResetData();
+};
+extern EncoderData* SimEncoderData;
+} // namespace hal
diff --git a/hal/src/main/native/sim/mockdata/HALValueInternal.h b/hal/src/main/native/sim/mockdata/HALValueInternal.h
new file mode 100644
index 0000000..f659403
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/HALValueInternal.h
@@ -0,0 +1,27 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+#include <string>
+
+#include "mockdata/HALValue.h"
+#include "mockdata/wpi/StringRef.h"
+
+namespace hal {
+
+class Value;
+
+void ConvertToC(const Value& in, HAL_Value* out);
+std::shared_ptr<Value> ConvertFromC(const HAL_Value& value);
+void ConvertToC(wpi::StringRef in, HALString* out);
+inline wpi::StringRef ConvertFromC(const HALString& str) {
+ return wpi::StringRef(str.str, str.len);
+}
+
+} // 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..1c2df0e
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/I2CDataInternal.h
@@ -0,0 +1,32 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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, 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..df68e04
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/PCMData.cpp
@@ -0,0 +1,73 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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)
+
+#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..4144987
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/PCMDataInternal.h
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+#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, MakeBoolean, GetSolenoidInitializedName,
+ GetSolenoidInitializedDefault>
+ solenoidInitialized[kNumSolenoidChannels];
+ SimDataValue<HAL_Bool, MakeBoolean, GetSolenoidOutputName,
+ GetSolenoidOutputDefault>
+ solenoidOutput[kNumSolenoidChannels];
+ SimDataValue<HAL_Bool, MakeBoolean, GetCompressorInitializedName>
+ compressorInitialized{false};
+ SimDataValue<HAL_Bool, MakeBoolean, GetCompressorOnName> compressorOn{false};
+ SimDataValue<HAL_Bool, MakeBoolean, GetClosedLoopEnabledName>
+ closedLoopEnabled{true};
+ SimDataValue<HAL_Bool, MakeBoolean, GetPressureSwitchName> pressureSwitch{
+ false};
+ SimDataValue<double, 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..9c6143e
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/PDPData.cpp
@@ -0,0 +1,56 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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)
+
+#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..a7170c7
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/PDPDataInternal.h
@@ -0,0 +1,35 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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, MakeBoolean, GetInitializedName> initialized{false};
+ SimDataValue<double, MakeDouble, GetTemperatureName> temperature{0.0};
+ SimDataValue<double, MakeDouble, GetVoltageName> voltage{12.0};
+ SimDataValue<double, 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..85eae44
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/PWMDataInternal.h
@@ -0,0 +1,33 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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, MakeBoolean, GetInitializedName> initialized{false};
+ SimDataValue<int32_t, MakeInt, GetRawValueName> rawValue{0};
+ SimDataValue<double, MakeDouble, GetSpeedName> speed{0};
+ SimDataValue<double, MakeDouble, GetPositionName> position{0};
+ SimDataValue<int32_t, MakeInt, GetPeriodScaleName> periodScale{0};
+ SimDataValue<HAL_Bool, 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..88e79ff
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/RelayDataInternal.h
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+#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, MakeBoolean, GetInitializedForwardName>
+ initializedForward{false};
+ SimDataValue<HAL_Bool, MakeBoolean, GetInitializedReverseName>
+ initializedReverse{false};
+ SimDataValue<HAL_Bool, MakeBoolean, GetForwardName> forward{false};
+ SimDataValue<HAL_Bool, 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..92aa0c8
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/RoboRioDataInternal.h
@@ -0,0 +1,52 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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, MakeBoolean, GetFPGAButtonName> fpgaButton{false};
+ SimDataValue<double, MakeDouble, GetVInVoltageName> vInVoltage{0.0};
+ SimDataValue<double, MakeDouble, GetVInCurrentName> vInCurrent{0.0};
+ SimDataValue<double, MakeDouble, GetUserVoltage6VName> userVoltage6V{6.0};
+ SimDataValue<double, MakeDouble, GetUserCurrent6VName> userCurrent6V{0.0};
+ SimDataValue<HAL_Bool, MakeBoolean, GetUserActive6VName> userActive6V{false};
+ SimDataValue<double, MakeDouble, GetUserVoltage5VName> userVoltage5V{5.0};
+ SimDataValue<double, MakeDouble, GetUserCurrent5VName> userCurrent5V{0.0};
+ SimDataValue<HAL_Bool, MakeBoolean, GetUserActive5VName> userActive5V{false};
+ SimDataValue<double, MakeDouble, GetUserVoltage3V3Name> userVoltage3V3{3.3};
+ SimDataValue<double, MakeDouble, GetUserCurrent3V3Name> userCurrent3V3{0.0};
+ SimDataValue<HAL_Bool, MakeBoolean, GetUserActive3V3Name> userActive3V3{
+ false};
+ SimDataValue<int32_t, MakeInt, GetUserFaults6VName> userFaults6V{0};
+ SimDataValue<int32_t, MakeInt, GetUserFaults5VName> userFaults5V{0};
+ SimDataValue<int32_t, 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..ee9f79d
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/SPIAccelerometerDataInternal.h
@@ -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. */
+/*----------------------------------------------------------------------------*/
+
+#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, MakeBoolean, GetActiveName> active{false};
+ SimDataValue<int32_t, MakeInt, GetRangeName> range{0};
+ SimDataValue<double, MakeDouble, GetXName> x{0.0};
+ SimDataValue<double, MakeDouble, GetYName> y{0.0};
+ SimDataValue<double, 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..b10e741
--- /dev/null
+++ b/hal/src/main/native/sim/mockdata/SPIDataInternal.h
@@ -0,0 +1,39 @@
+/*----------------------------------------------------------------------------*/
+/* 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/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, 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/test/java/edu/wpi/first/hal/sim/AccelerometerSimTest.java b/hal/src/test/java/edu/wpi/first/hal/sim/AccelerometerSimTest.java
new file mode 100644
index 0000000..383165c
--- /dev/null
+++ b/hal/src/test/java/edu/wpi/first/hal/sim/AccelerometerSimTest.java
@@ -0,0 +1,42 @@
+/*----------------------------------------------------------------------------*/
+/* 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. */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.hal.sim;
+
+import org.junit.jupiter.api.Test;
+
+import edu.wpi.first.hal.AccelerometerJNI;
+import edu.wpi.first.hal.HAL;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class AccelerometerSimTest {
+ static class TriggeredStore {
+ public boolean m_wasTriggered;
+ public boolean m_setValue = true;
+ }
+
+ @Test
+ void testCallbacks() {
+ HAL.initialize(500, 0);
+ AccelerometerSim sim = new AccelerometerSim();
+ sim.resetData();
+
+ TriggeredStore store = new TriggeredStore();
+
+ try (CallbackStore cb = sim.registerActiveCallback((s, v) -> {
+ store.m_wasTriggered = true;
+ store.m_setValue = v.getBoolean();
+ }, false)) {
+ assertFalse(store.m_wasTriggered);
+ AccelerometerJNI.setAccelerometerActive(true);
+ assertTrue(store.m_wasTriggered);
+ assertTrue(store.m_setValue);
+ }
+ }
+}
diff --git a/hal/src/test/native/cpp/HALTests.cpp b/hal/src/test/native/cpp/HALTests.cpp
new file mode 100644
index 0000000..b387c14
--- /dev/null
+++ b/hal/src/test/native/cpp/HALTests.cpp
@@ -0,0 +1,22 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 "gtest/gtest.h"
+#include "hal/HAL.h"
+#include "hal/Solenoid.h"
+
+namespace hal {
+TEST(HALTests, RuntimeType) {
+ EXPECT_EQ(HAL_RuntimeType::HAL_Mock, HAL_GetRuntimeType());
+}
+
+TEST(HALSOLENOID, SolenoidTest) {
+ int32_t status = 0;
+ HAL_InitializeSolenoidPort(0, &status);
+ EXPECT_NE(status, 0);
+}
+} // namespace hal
diff --git a/hal/src/test/native/cpp/can/CANTest.cpp b/hal/src/test/native/cpp/can/CANTest.cpp
new file mode 100644
index 0000000..6f5549c
--- /dev/null
+++ b/hal/src/test/native/cpp/can/CANTest.cpp
@@ -0,0 +1,83 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 "gtest/gtest.h"
+#include "hal/CANAPI.h"
+#include "hal/HAL.h"
+#include "mockdata/CanData.h"
+
+namespace hal {
+struct CANTestStore {
+ CANTestStore(int32_t deviceId, int32_t* status) {
+ this->deviceId = deviceId;
+ handle = HAL_InitializeCAN(
+ HAL_CANManufacturer::HAL_CAN_Man_kTeamUse, deviceId,
+ HAL_CANDeviceType::HAL_CAN_Dev_kMiscellaneous, status);
+ }
+
+ ~CANTestStore() {
+ if (handle != HAL_kInvalidHandle) {
+ HAL_CleanCAN(handle);
+ }
+ }
+
+ int32_t deviceId;
+ HAL_CANHandle handle;
+};
+
+struct CANReceiveCallbackStore {
+ explicit CANReceiveCallbackStore(int32_t handle) { this->handle = handle; }
+ ~CANReceiveCallbackStore() { HALSIM_CancelCanReceiveMessageCallback(handle); }
+ int32_t handle;
+};
+
+struct CANSendCallbackStore {
+ explicit CANSendCallbackStore(int32_t handle) { this->handle = handle; }
+ ~CANSendCallbackStore() { HALSIM_CancelCanSendMessageCallback(handle); }
+ int32_t handle;
+};
+
+TEST(HALCanTests, CanIdPackingTest) {
+ int32_t status = 0;
+ int32_t deviceId = 12;
+ CANTestStore testStore(deviceId, &status);
+ ASSERT_EQ(0, status);
+
+ std::pair<int32_t, bool> storePair;
+ storePair.second = false;
+
+ auto cbHandle = HALSIM_RegisterCanSendMessageCallback(
+ [](const char* name, void* param, uint32_t messageID, const uint8_t* data,
+ uint8_t dataSize, int32_t periodMs, int32_t* status) {
+ std::pair<int32_t, bool>* paramI =
+ reinterpret_cast<std::pair<int32_t, bool>*>(param);
+ paramI->first = messageID;
+ paramI->second = true;
+ },
+ &storePair);
+
+ CANSendCallbackStore cbStore(cbHandle);
+ uint8_t data[8];
+
+ int32_t apiId = 42;
+
+ HAL_WriteCANPacket(testStore.handle, data, 8, 42, &status);
+
+ ASSERT_EQ(0, status);
+
+ ASSERT_TRUE(storePair.second);
+
+ ASSERT_NE(0, storePair.first);
+
+ ASSERT_EQ(deviceId, storePair.first & 0x3F);
+ ASSERT_EQ(apiId, (storePair.first & 0x0000FFC0) >> 6);
+ ASSERT_EQ(static_cast<int32_t>(HAL_CANManufacturer::HAL_CAN_Man_kTeamUse),
+ (storePair.first & 0x00FF0000) >> 16);
+ ASSERT_EQ(static_cast<int32_t>(HAL_CANDeviceType::HAL_CAN_Dev_kMiscellaneous),
+ (storePair.first & 0x1F000000) >> 24);
+}
+} // namespace hal
diff --git a/hal/src/test/native/cpp/handles/HandleTests.cpp b/hal/src/test/native/cpp/handles/HandleTests.cpp
new file mode 100644
index 0000000..e893c78
--- /dev/null
+++ b/hal/src/test/native/cpp/handles/HandleTests.cpp
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "gtest/gtest.h"
+#include "hal/HAL.h"
+#include "hal/handles/IndexedClassedHandleResource.h"
+
+#define HAL_TestHandle HAL_Handle
+
+namespace {
+class MyTestClass {};
+} // namespace
+
+namespace hal {
+TEST(HandleTests, ClassedHandleTest) {
+ hal::IndexedClassedHandleResource<HAL_TestHandle, MyTestClass, 8,
+ HAL_HandleEnum::Vendor>
+ testClass;
+ int32_t status = 0;
+ testClass.Allocate(0, std::make_unique<MyTestClass>(), &status);
+ EXPECT_EQ(0, status);
+}
+
+} // namespace hal
diff --git a/hal/src/test/native/cpp/main.cpp b/hal/src/test/native/cpp/main.cpp
new file mode 100644
index 0000000..33990f0
--- /dev/null
+++ b/hal/src/test/native/cpp/main.cpp
@@ -0,0 +1,16 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 "gtest/gtest.h"
+#include "hal/HAL.h"
+
+int main(int argc, char** argv) {
+ HAL_Initialize(500, 0);
+ ::testing::InitGoogleTest(&argc, argv);
+ int ret = RUN_ALL_TESTS();
+ return ret;
+}
diff --git a/hal/src/test/native/cpp/mockdata/AnalogInDataTests.cpp b/hal/src/test/native/cpp/mockdata/AnalogInDataTests.cpp
new file mode 100644
index 0000000..791be79
--- /dev/null
+++ b/hal/src/test/native/cpp/mockdata/AnalogInDataTests.cpp
@@ -0,0 +1,80 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 "gtest/gtest.h"
+#include "hal/AnalogInput.h"
+#include "hal/HAL.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/AnalogInData.h"
+
+namespace hal {
+
+std::string gTestAnalogInCallbackName;
+HAL_Value gTestAnalogInCallbackValue;
+
+void TestAnalogInInitializationCallback(const char* name, void* param,
+ const struct HAL_Value* value) {
+ gTestAnalogInCallbackName = name;
+ gTestAnalogInCallbackValue = *value;
+}
+
+TEST(AnalogInSimTests, TestAnalogInInitialization) {
+ const int INDEX_TO_TEST = 1;
+
+ int callbackParam = 0;
+ int callbackId = HALSIM_RegisterAnalogInInitializedCallback(
+ INDEX_TO_TEST, &TestAnalogInInitializationCallback, &callbackParam,
+ false);
+ ASSERT_TRUE(0 != callbackId);
+
+ int32_t status;
+ HAL_PortHandle portHandle;
+ HAL_DigitalHandle analogInHandle;
+
+ // Use out of range index
+ status = 0;
+ portHandle = 8000;
+ gTestAnalogInCallbackName = "Unset";
+ analogInHandle = HAL_InitializeAnalogInputPort(portHandle, &status);
+ EXPECT_EQ(HAL_kInvalidHandle, analogInHandle);
+ EXPECT_EQ(PARAMETER_OUT_OF_RANGE, status);
+ EXPECT_STREQ("Unset", gTestAnalogInCallbackName.c_str());
+
+ // Successful setup
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestAnalogInCallbackName = "Unset";
+ analogInHandle = HAL_InitializeAnalogInputPort(portHandle, &status);
+ EXPECT_TRUE(HAL_kInvalidHandle != analogInHandle);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("Initialized", gTestAnalogInCallbackName.c_str());
+
+ // Double initialize... should fail
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestAnalogInCallbackName = "Unset";
+ analogInHandle = HAL_InitializeAnalogInputPort(portHandle, &status);
+ EXPECT_EQ(HAL_kInvalidHandle, analogInHandle);
+ EXPECT_EQ(RESOURCE_IS_ALLOCATED, status);
+ EXPECT_STREQ("Unset", gTestAnalogInCallbackName.c_str());
+
+ // Reset, should allow you to re-register
+ hal::HandleBase::ResetGlobalHandles();
+ HALSIM_ResetAnalogInData(INDEX_TO_TEST);
+ callbackId = HALSIM_RegisterAnalogInInitializedCallback(
+ INDEX_TO_TEST, &TestAnalogInInitializationCallback, &callbackParam,
+ false);
+
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestAnalogInCallbackName = "Unset";
+ analogInHandle = HAL_InitializeAnalogInputPort(portHandle, &status);
+ EXPECT_TRUE(HAL_kInvalidHandle != analogInHandle);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("Initialized", gTestAnalogInCallbackName.c_str());
+}
+} // namespace hal
diff --git a/hal/src/test/native/cpp/mockdata/AnalogOutDataTests.cpp b/hal/src/test/native/cpp/mockdata/AnalogOutDataTests.cpp
new file mode 100644
index 0000000..8f6d6f0
--- /dev/null
+++ b/hal/src/test/native/cpp/mockdata/AnalogOutDataTests.cpp
@@ -0,0 +1,80 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 "gtest/gtest.h"
+#include "hal/AnalogOutput.h"
+#include "hal/HAL.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/AnalogOutData.h"
+
+namespace hal {
+
+std::string gTestAnalogOutCallbackName;
+HAL_Value gTestAnalogOutCallbackValue;
+
+void TestAnalogOutInitializationCallback(const char* name, void* param,
+ const struct HAL_Value* value) {
+ gTestAnalogOutCallbackName = name;
+ gTestAnalogOutCallbackValue = *value;
+}
+
+TEST(AnalogOutSimTests, TestAnalogOutInitialization) {
+ const int INDEX_TO_TEST = 1;
+
+ int callbackParam = 0;
+ int callbackId = HALSIM_RegisterAnalogOutInitializedCallback(
+ INDEX_TO_TEST, &TestAnalogOutInitializationCallback, &callbackParam,
+ false);
+ ASSERT_TRUE(0 != callbackId);
+
+ int32_t status;
+ HAL_PortHandle portHandle;
+ HAL_DigitalHandle analogOutHandle;
+
+ // Use out of range index
+ status = 0;
+ portHandle = 8000;
+ gTestAnalogOutCallbackName = "Unset";
+ analogOutHandle = HAL_InitializeAnalogOutputPort(portHandle, &status);
+ EXPECT_EQ(HAL_kInvalidHandle, analogOutHandle);
+ EXPECT_EQ(PARAMETER_OUT_OF_RANGE, status);
+ EXPECT_STREQ("Unset", gTestAnalogOutCallbackName.c_str());
+
+ // Successful setup
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestAnalogOutCallbackName = "Unset";
+ analogOutHandle = HAL_InitializeAnalogOutputPort(portHandle, &status);
+ EXPECT_TRUE(HAL_kInvalidHandle != analogOutHandle);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("Initialized", gTestAnalogOutCallbackName.c_str());
+
+ // Double initialize... should fail
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestAnalogOutCallbackName = "Unset";
+ analogOutHandle = HAL_InitializeAnalogOutputPort(portHandle, &status);
+ EXPECT_EQ(HAL_kInvalidHandle, analogOutHandle);
+ EXPECT_EQ(RESOURCE_IS_ALLOCATED, status);
+ EXPECT_STREQ("Unset", gTestAnalogOutCallbackName.c_str());
+
+ // Reset, should allow you to re-register
+ hal::HandleBase::ResetGlobalHandles();
+ HALSIM_ResetAnalogOutData(INDEX_TO_TEST);
+ callbackId = HALSIM_RegisterAnalogOutInitializedCallback(
+ INDEX_TO_TEST, &TestAnalogOutInitializationCallback, &callbackParam,
+ false);
+
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestAnalogOutCallbackName = "Unset";
+ analogOutHandle = HAL_InitializeAnalogOutputPort(portHandle, &status);
+ EXPECT_TRUE(HAL_kInvalidHandle != analogOutHandle);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("Initialized", gTestAnalogOutCallbackName.c_str());
+}
+} // namespace hal
diff --git a/hal/src/test/native/cpp/mockdata/DIODataTests.cpp b/hal/src/test/native/cpp/mockdata/DIODataTests.cpp
new file mode 100644
index 0000000..19fe994
--- /dev/null
+++ b/hal/src/test/native/cpp/mockdata/DIODataTests.cpp
@@ -0,0 +1,81 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 "gtest/gtest.h"
+#include "hal/DIO.h"
+#include "hal/HAL.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/DIOData.h"
+
+namespace hal {
+
+std::string gTestDigitalIoCallbackName;
+HAL_Value gTestDigitalIoCallbackValue;
+
+void TestDigitalIoInitializationCallback(const char* name, void* param,
+ const struct HAL_Value* value) {
+ gTestDigitalIoCallbackName = name;
+ gTestDigitalIoCallbackValue = *value;
+}
+
+TEST(DigitalIoSimTests, TestDigitalIoInitialization) {
+ const int INDEX_TO_TEST = 3;
+
+ int callbackParam = 0;
+ int callbackId = HALSIM_RegisterDIOInitializedCallback(
+ INDEX_TO_TEST, &TestDigitalIoInitializationCallback, &callbackParam,
+ false);
+ ASSERT_TRUE(0 != callbackId);
+
+ int32_t status;
+ HAL_PortHandle portHandle;
+ HAL_DigitalHandle digitalIoHandle;
+
+ // Use out of range index
+ status = 0;
+ portHandle = 8000;
+ gTestDigitalIoCallbackName = "Unset";
+ digitalIoHandle = HAL_InitializeDIOPort(portHandle, true, &status);
+ EXPECT_EQ(HAL_kInvalidHandle, digitalIoHandle);
+ EXPECT_EQ(PARAMETER_OUT_OF_RANGE, status);
+ EXPECT_STREQ("Unset", gTestDigitalIoCallbackName.c_str());
+
+ // Successful setup
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestDigitalIoCallbackName = "Unset";
+ digitalIoHandle = HAL_InitializeDIOPort(portHandle, true, &status);
+ EXPECT_TRUE(HAL_kInvalidHandle != digitalIoHandle);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("Initialized", gTestDigitalIoCallbackName.c_str());
+
+ // Double initialize... should fail
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestDigitalIoCallbackName = "Unset";
+ digitalIoHandle = HAL_InitializeDIOPort(portHandle, true, &status);
+ EXPECT_EQ(HAL_kInvalidHandle, digitalIoHandle);
+ EXPECT_EQ(RESOURCE_IS_ALLOCATED, status);
+ EXPECT_STREQ("Unset", gTestDigitalIoCallbackName.c_str());
+
+ // Reset, should allow you to re-register
+ hal::HandleBase::ResetGlobalHandles();
+ HALSIM_ResetDIOData(INDEX_TO_TEST);
+ callbackId = HALSIM_RegisterDIOInitializedCallback(
+ INDEX_TO_TEST, &TestDigitalIoInitializationCallback, &callbackParam,
+ false);
+
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestDigitalIoCallbackName = "Unset";
+ digitalIoHandle = HAL_InitializeDIOPort(portHandle, true, &status);
+ EXPECT_TRUE(HAL_kInvalidHandle != digitalIoHandle);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("Initialized", gTestDigitalIoCallbackName.c_str());
+}
+
+} // namespace hal
diff --git a/hal/src/test/native/cpp/mockdata/DriverStationDataTests.cpp b/hal/src/test/native/cpp/mockdata/DriverStationDataTests.cpp
new file mode 100644
index 0000000..35c0d54
--- /dev/null
+++ b/hal/src/test/native/cpp/mockdata/DriverStationDataTests.cpp
@@ -0,0 +1,143 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 <cstring>
+
+#include "gtest/gtest.h"
+#include "hal/HAL.h"
+#include "hal/Solenoid.h"
+#include "mockdata/DriverStationData.h"
+
+namespace hal {
+
+TEST(DriverStationTests, JoystickTests) {
+ HAL_JoystickAxes axes;
+ HAL_JoystickPOVs povs;
+ HAL_JoystickButtons buttons;
+
+ // Check default values before anything has been set
+ for (int joystickNum = 0; joystickNum < 6; ++joystickNum) {
+ HAL_GetJoystickAxes(joystickNum, &axes);
+ HAL_GetJoystickPOVs(joystickNum, &povs);
+ HAL_GetJoystickButtons(joystickNum, &buttons);
+
+ EXPECT_EQ(0, axes.count);
+ for (int i = 0; i < HAL_kMaxJoystickAxes; ++i) {
+ EXPECT_EQ(0, axes.axes[i]);
+ }
+
+ EXPECT_EQ(0, povs.count);
+ for (int i = 0; i < HAL_kMaxJoystickPOVs; ++i) {
+ EXPECT_EQ(0, povs.povs[i]);
+ }
+
+ EXPECT_EQ(0, buttons.count);
+ EXPECT_EQ(0u, buttons.buttons);
+ }
+
+ HAL_JoystickAxes set_axes;
+ std::memset(&set_axes, 0, sizeof(HAL_JoystickAxes));
+ HAL_JoystickPOVs set_povs;
+ std::memset(&set_povs, 0, sizeof(HAL_JoystickPOVs));
+ HAL_JoystickButtons set_buttons;
+ std::memset(&set_buttons, 0, sizeof(HAL_JoystickButtons));
+
+ // Set values
+ int joystickUnderTest = 4;
+ set_axes.count = 5;
+ for (int i = 0; i < set_axes.count; ++i) {
+ set_axes.axes[i] = i * .125;
+ }
+
+ set_povs.count = 3;
+ for (int i = 0; i < set_povs.count; ++i) {
+ set_povs.povs[i] = i * 15 + 12;
+ }
+
+ set_buttons.count = 8;
+ set_buttons.buttons = 0xDEADBEEF;
+
+ HALSIM_SetJoystickAxes(joystickUnderTest, &set_axes);
+ HALSIM_SetJoystickPOVs(joystickUnderTest, &set_povs);
+ HALSIM_SetJoystickButtons(joystickUnderTest, &set_buttons);
+
+ // Check the set values
+ HAL_GetJoystickAxes(joystickUnderTest, &axes);
+ HAL_GetJoystickPOVs(joystickUnderTest, &povs);
+ HAL_GetJoystickButtons(joystickUnderTest, &buttons);
+
+ EXPECT_EQ(5, axes.count);
+ EXPECT_NEAR(0.000, axes.axes[0], 0.000001);
+ EXPECT_NEAR(0.125, axes.axes[1], 0.000001);
+ EXPECT_NEAR(0.250, axes.axes[2], 0.000001);
+ EXPECT_NEAR(0.375, axes.axes[3], 0.000001);
+ EXPECT_NEAR(0.500, axes.axes[4], 0.000001);
+ EXPECT_NEAR(0, axes.axes[5], 0.000001); // Should not have been set, still 0
+ EXPECT_NEAR(0, axes.axes[6], 0.000001); // Should not have been set, still 0
+
+ EXPECT_EQ(3, povs.count);
+ EXPECT_EQ(12, povs.povs[0]);
+ EXPECT_EQ(27, povs.povs[1]);
+ EXPECT_EQ(42, povs.povs[2]);
+ EXPECT_EQ(0, povs.povs[3]); // Should not have been set, still 0
+ EXPECT_EQ(0, povs.povs[4]); // Should not have been set, still 0
+ EXPECT_EQ(0, povs.povs[5]); // Should not have been set, still 0
+ EXPECT_EQ(0, povs.povs[6]); // Should not have been set, still 0
+
+ EXPECT_EQ(8, buttons.count);
+ EXPECT_EQ(0xDEADBEEFu, buttons.buttons);
+
+ // Reset
+ HALSIM_ResetDriverStationData();
+ for (int joystickNum = 0; joystickNum < 6; ++joystickNum) {
+ HAL_GetJoystickAxes(joystickNum, &axes);
+ HAL_GetJoystickPOVs(joystickNum, &povs);
+ HAL_GetJoystickButtons(joystickNum, &buttons);
+
+ EXPECT_EQ(0, axes.count);
+ for (int i = 0; i < HAL_kMaxJoystickAxes; ++i) {
+ EXPECT_EQ(0, axes.axes[i]);
+ }
+
+ EXPECT_EQ(0, povs.count);
+ for (int i = 0; i < HAL_kMaxJoystickPOVs; ++i) {
+ EXPECT_EQ(0, povs.povs[i]);
+ }
+
+ EXPECT_EQ(0, buttons.count);
+ EXPECT_EQ(0u, buttons.buttons);
+ }
+}
+
+TEST(DriverStationTests, EventInfoTest) {
+ std::string eventName = "UnitTest";
+ std::string gameData = "Insert game specific info here :D";
+ HAL_MatchInfo info;
+ std::snprintf(info.eventName, sizeof(info.eventName), "%s",
+ eventName.c_str());
+ std::snprintf(reinterpret_cast<char*>(info.gameSpecificMessage),
+ sizeof(info.gameSpecificMessage), "%s", gameData.c_str());
+ info.gameSpecificMessageSize = gameData.size();
+ info.matchNumber = 5;
+ info.matchType = HAL_MatchType::HAL_kMatchType_qualification;
+ info.replayNumber = 42;
+ HALSIM_SetMatchInfo(&info);
+
+ HAL_MatchInfo dataBack;
+ HAL_GetMatchInfo(&dataBack);
+
+ std::string gsm{reinterpret_cast<char*>(dataBack.gameSpecificMessage),
+ dataBack.gameSpecificMessageSize};
+
+ EXPECT_STREQ(eventName.c_str(), dataBack.eventName);
+ EXPECT_EQ(gameData, gsm);
+ EXPECT_EQ(5, dataBack.matchNumber);
+ EXPECT_EQ(HAL_MatchType::HAL_kMatchType_qualification, dataBack.matchType);
+ EXPECT_EQ(42, dataBack.replayNumber);
+}
+
+} // namespace hal
diff --git a/hal/src/test/native/cpp/mockdata/I2CDataTests.cpp b/hal/src/test/native/cpp/mockdata/I2CDataTests.cpp
new file mode 100644
index 0000000..3a8e01c
--- /dev/null
+++ b/hal/src/test/native/cpp/mockdata/I2CDataTests.cpp
@@ -0,0 +1,43 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 "gtest/gtest.h"
+#include "hal/HAL.h"
+#include "hal/I2C.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/I2CData.h"
+
+namespace hal {
+
+std::string gTestI2CCallbackName;
+HAL_Value gTestI2CCallbackValue;
+
+void TestI2CInitializationCallback(const char* name, void* param,
+ const struct HAL_Value* value) {
+ gTestI2CCallbackName = name;
+ gTestI2CCallbackValue = *value;
+}
+
+TEST(I2CSimTests, TestI2CInitialization) {
+ const int INDEX_TO_TEST = 1;
+
+ int32_t status;
+ HAL_I2CPort port;
+
+ int callbackParam = 0;
+ int callbackId = HALSIM_RegisterI2CInitializedCallback(
+ INDEX_TO_TEST, &TestI2CInitializationCallback, &callbackParam, false);
+ ASSERT_TRUE(0 != callbackId);
+
+ status = 0;
+ port = HAL_I2C_kMXP;
+ gTestI2CCallbackName = "Unset";
+ HAL_InitializeI2C(port, &status);
+ EXPECT_STREQ("Initialized", gTestI2CCallbackName.c_str());
+}
+
+} // namespace hal
diff --git a/hal/src/test/native/cpp/mockdata/PCMDataTests.cpp b/hal/src/test/native/cpp/mockdata/PCMDataTests.cpp
new file mode 100644
index 0000000..50a8ae3
--- /dev/null
+++ b/hal/src/test/native/cpp/mockdata/PCMDataTests.cpp
@@ -0,0 +1,83 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 "gtest/gtest.h"
+#include "hal/HAL.h"
+#include "hal/Solenoid.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/PCMData.h"
+
+namespace hal {
+
+std::string gTestSolenoidCallbackName;
+HAL_Value gTestSolenoidCallbackValue;
+
+void TestSolenoidInitializationCallback(const char* name, void* param,
+ const struct HAL_Value* value) {
+ gTestSolenoidCallbackName = name;
+ gTestSolenoidCallbackValue = *value;
+}
+
+TEST(SolenoidSimTests, TestSolenoidInitialization) {
+ const int MODULE_TO_TEST = 2;
+ const int CHANNEL_TO_TEST = 3;
+
+ int callbackParam = 0;
+ int callbackId = HALSIM_RegisterPCMSolenoidInitializedCallback(
+ MODULE_TO_TEST, CHANNEL_TO_TEST, &TestSolenoidInitializationCallback,
+ &callbackParam, false);
+ ASSERT_TRUE(0 != callbackId);
+
+ int32_t status;
+ HAL_PortHandle portHandle;
+ HAL_DigitalHandle solenoidHandle;
+
+ // Use out of range index
+ status = 0;
+ portHandle = 8000;
+ gTestSolenoidCallbackName = "Unset";
+ solenoidHandle = HAL_InitializeSolenoidPort(portHandle, &status);
+ EXPECT_EQ(HAL_kInvalidHandle, solenoidHandle);
+ EXPECT_EQ(HAL_HANDLE_ERROR, status);
+ EXPECT_STREQ("Unset", gTestSolenoidCallbackName.c_str());
+
+ // Successful setup
+ status = 0;
+ portHandle = HAL_GetPortWithModule(MODULE_TO_TEST, CHANNEL_TO_TEST);
+ gTestSolenoidCallbackName = "Unset";
+ solenoidHandle = HAL_InitializeSolenoidPort(portHandle, &status);
+ EXPECT_TRUE(HAL_kInvalidHandle != solenoidHandle);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("SolenoidInitialized", gTestSolenoidCallbackName.c_str());
+
+ // Double initialize... should fail
+ status = 0;
+ portHandle = HAL_GetPortWithModule(MODULE_TO_TEST, CHANNEL_TO_TEST);
+ gTestSolenoidCallbackName = "Unset";
+ solenoidHandle = HAL_InitializeSolenoidPort(portHandle, &status);
+ EXPECT_EQ(HAL_kInvalidHandle, solenoidHandle);
+ EXPECT_EQ(NO_AVAILABLE_RESOURCES, status);
+ EXPECT_STREQ("Unset", gTestSolenoidCallbackName.c_str());
+
+ // Reset, should allow you to re-register
+ hal::HandleBase::ResetGlobalHandles();
+ HALSIM_ResetPCMData(MODULE_TO_TEST);
+ callbackId = HALSIM_RegisterPCMSolenoidInitializedCallback(
+ MODULE_TO_TEST, CHANNEL_TO_TEST, &TestSolenoidInitializationCallback,
+ &callbackParam, false);
+ ASSERT_TRUE(0 != callbackId);
+
+ status = 0;
+ portHandle = HAL_GetPortWithModule(MODULE_TO_TEST, CHANNEL_TO_TEST);
+ gTestSolenoidCallbackName = "Unset";
+ solenoidHandle = HAL_InitializeSolenoidPort(portHandle, &status);
+ EXPECT_TRUE(HAL_kInvalidHandle != solenoidHandle);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("SolenoidInitialized", gTestSolenoidCallbackName.c_str());
+}
+
+} // namespace hal
diff --git a/hal/src/test/native/cpp/mockdata/PDPDataTests.cpp b/hal/src/test/native/cpp/mockdata/PDPDataTests.cpp
new file mode 100644
index 0000000..a46454f
--- /dev/null
+++ b/hal/src/test/native/cpp/mockdata/PDPDataTests.cpp
@@ -0,0 +1,43 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 "gtest/gtest.h"
+#include "hal/HAL.h"
+#include "hal/PDP.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/PDPData.h"
+
+namespace hal {
+
+std::string gTestPdpCallbackName;
+HAL_Value gTestPdpCallbackValue;
+
+void TestPdpInitializationCallback(const char* name, void* param,
+ const struct HAL_Value* value) {
+ gTestPdpCallbackName = name;
+ gTestPdpCallbackValue = *value;
+}
+
+TEST(PdpSimTests, TestPdpInitialization) {
+ const int INDEX_TO_TEST = 1;
+
+ int callbackParam = 0;
+ int callbackId = HALSIM_RegisterPDPInitializedCallback(
+ INDEX_TO_TEST, &TestPdpInitializationCallback, &callbackParam, false);
+ ASSERT_TRUE(0 != callbackId);
+
+ int32_t status;
+
+ // Use out of range index
+ status = 0;
+ gTestPdpCallbackName = "Unset";
+ HAL_InitializePDP(INDEX_TO_TEST, &status);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("Initialized", gTestPdpCallbackName.c_str());
+}
+
+} // namespace hal
diff --git a/hal/src/test/native/cpp/mockdata/PWMDataTests.cpp b/hal/src/test/native/cpp/mockdata/PWMDataTests.cpp
new file mode 100644
index 0000000..447a510
--- /dev/null
+++ b/hal/src/test/native/cpp/mockdata/PWMDataTests.cpp
@@ -0,0 +1,78 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 "gtest/gtest.h"
+#include "hal/HAL.h"
+#include "hal/PWM.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/PWMData.h"
+
+namespace hal {
+
+std::string gTestPwmCallbackName;
+HAL_Value gTestPwmCallbackValue;
+
+void TestPwmInitializationCallback(const char* name, void* param,
+ const struct HAL_Value* value) {
+ gTestPwmCallbackName = name;
+ gTestPwmCallbackValue = *value;
+}
+
+TEST(PWMSimTests, TestPwmInitialization) {
+ const int INDEX_TO_TEST = 7;
+
+ int callbackParam = 0;
+ int callbackId = HALSIM_RegisterPWMInitializedCallback(
+ INDEX_TO_TEST, &TestPwmInitializationCallback, &callbackParam, false);
+ ASSERT_TRUE(0 != callbackId);
+
+ int32_t status;
+ HAL_PortHandle portHandle;
+ HAL_DigitalHandle pwmHandle;
+
+ // Use out of range index
+ status = 0;
+ portHandle = 8000;
+ gTestPwmCallbackName = "Unset";
+ pwmHandle = HAL_InitializePWMPort(portHandle, &status);
+ EXPECT_EQ(HAL_kInvalidHandle, pwmHandle);
+ EXPECT_EQ(PARAMETER_OUT_OF_RANGE, status);
+ EXPECT_STREQ("Unset", gTestPwmCallbackName.c_str());
+
+ // Successful setup
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestPwmCallbackName = "Unset";
+ pwmHandle = HAL_InitializePWMPort(portHandle, &status);
+ EXPECT_TRUE(HAL_kInvalidHandle != pwmHandle);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("Initialized", gTestPwmCallbackName.c_str());
+
+ // Double initialize... should fail
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestPwmCallbackName = "Unset";
+ pwmHandle = HAL_InitializePWMPort(portHandle, &status);
+ EXPECT_EQ(HAL_kInvalidHandle, pwmHandle);
+ EXPECT_EQ(RESOURCE_IS_ALLOCATED, status);
+ EXPECT_STREQ("Unset", gTestPwmCallbackName.c_str());
+
+ // Reset, should allow you to re-register
+ hal::HandleBase::ResetGlobalHandles();
+ HALSIM_ResetPWMData(INDEX_TO_TEST);
+ callbackId = HALSIM_RegisterPWMInitializedCallback(
+ INDEX_TO_TEST, &TestPwmInitializationCallback, &callbackParam, false);
+
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestPwmCallbackName = "Unset";
+ pwmHandle = HAL_InitializePWMPort(portHandle, &status);
+ EXPECT_TRUE(HAL_kInvalidHandle != pwmHandle);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("Initialized", gTestPwmCallbackName.c_str());
+}
+} // namespace hal
diff --git a/hal/src/test/native/cpp/mockdata/RelayDataTests.cpp b/hal/src/test/native/cpp/mockdata/RelayDataTests.cpp
new file mode 100644
index 0000000..408657a
--- /dev/null
+++ b/hal/src/test/native/cpp/mockdata/RelayDataTests.cpp
@@ -0,0 +1,79 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 "gtest/gtest.h"
+#include "hal/HAL.h"
+#include "hal/Relay.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/RelayData.h"
+
+namespace hal {
+
+std::string gTestRelayCallbackName;
+HAL_Value gTestRelayCallbackValue;
+
+void TestRelayInitializationCallback(const char* name, void* param,
+ const struct HAL_Value* value) {
+ gTestRelayCallbackName = name;
+ gTestRelayCallbackValue = *value;
+}
+
+TEST(RelaySimTests, TestRelayInitialization) {
+ const int INDEX_TO_TEST = 3;
+
+ int callbackParam = 0;
+ int callbackId = HALSIM_RegisterRelayInitializedForwardCallback(
+ INDEX_TO_TEST, &TestRelayInitializationCallback, &callbackParam, false);
+ ASSERT_TRUE(0 != callbackId);
+
+ int32_t status;
+ HAL_PortHandle portHandle;
+ HAL_DigitalHandle pdpHandle;
+
+ // Use out of range index
+ status = 0;
+ portHandle = 8000;
+ gTestRelayCallbackName = "Unset";
+ pdpHandle = HAL_InitializeRelayPort(portHandle, true, &status);
+ EXPECT_EQ(HAL_kInvalidHandle, pdpHandle);
+ EXPECT_EQ(PARAMETER_OUT_OF_RANGE, status);
+ EXPECT_STREQ("Unset", gTestRelayCallbackName.c_str());
+
+ // Successful setup
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestRelayCallbackName = "Unset";
+ pdpHandle = HAL_InitializeRelayPort(portHandle, true, &status);
+ EXPECT_TRUE(HAL_kInvalidHandle != pdpHandle);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("InitializedForward", gTestRelayCallbackName.c_str());
+
+ // Double initialize... should fail
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestRelayCallbackName = "Unset";
+ pdpHandle = HAL_InitializeRelayPort(portHandle, true, &status);
+ EXPECT_EQ(HAL_kInvalidHandle, pdpHandle);
+ EXPECT_EQ(RESOURCE_IS_ALLOCATED, status);
+ EXPECT_STREQ("Unset", gTestRelayCallbackName.c_str());
+
+ // Reset, should allow you to re-register
+ hal::HandleBase::ResetGlobalHandles();
+ HALSIM_ResetRelayData(INDEX_TO_TEST);
+ callbackId = HALSIM_RegisterRelayInitializedForwardCallback(
+ INDEX_TO_TEST, &TestRelayInitializationCallback, &callbackParam, false);
+
+ status = 0;
+ portHandle = HAL_GetPort(INDEX_TO_TEST);
+ gTestRelayCallbackName = "Unset";
+ pdpHandle = HAL_InitializeRelayPort(portHandle, true, &status);
+ EXPECT_TRUE(HAL_kInvalidHandle != pdpHandle);
+ EXPECT_EQ(0, status);
+ EXPECT_STREQ("InitializedForward", gTestRelayCallbackName.c_str());
+}
+
+} // namespace hal
diff --git a/hal/src/test/native/cpp/mockdata/SPIDataTests.cpp b/hal/src/test/native/cpp/mockdata/SPIDataTests.cpp
new file mode 100644
index 0000000..64c8555
--- /dev/null
+++ b/hal/src/test/native/cpp/mockdata/SPIDataTests.cpp
@@ -0,0 +1,43 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2015-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 "gtest/gtest.h"
+#include "hal/HAL.h"
+#include "hal/SPI.h"
+#include "hal/handles/HandlesInternal.h"
+#include "mockdata/SPIData.h"
+
+namespace hal {
+
+std::string gTestSpiCallbackName;
+HAL_Value gTestSpiCallbackValue;
+
+void TestSpiInitializationCallback(const char* name, void* param,
+ const struct HAL_Value* value) {
+ gTestSpiCallbackName = name;
+ gTestSpiCallbackValue = *value;
+}
+
+TEST(SpiSimTests, TestSpiInitialization) {
+ const int INDEX_TO_TEST = 2;
+
+ int32_t status;
+ HAL_SPIPort port;
+
+ int callbackParam = 0;
+ int callbackId = HALSIM_RegisterSPIInitializedCallback(
+ INDEX_TO_TEST, &TestSpiInitializationCallback, &callbackParam, false);
+ ASSERT_TRUE(0 != callbackId);
+
+ status = 0;
+ port = HAL_SPI_kOnboardCS2;
+ gTestSpiCallbackName = "Unset";
+ HAL_InitializeSPI(port, &status);
+ EXPECT_STREQ("Initialized", gTestSpiCallbackName.c_str());
+}
+
+} // namespace hal
diff --git a/hal/src/test/native/cpp/sim/AccelerometerSimTest.cpp b/hal/src/test/native/cpp/sim/AccelerometerSimTest.cpp
new file mode 100644
index 0000000..54be6e3
--- /dev/null
+++ b/hal/src/test/native/cpp/sim/AccelerometerSimTest.cpp
@@ -0,0 +1,42 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "gtest/gtest.h"
+#include "hal/Accelerometer.h"
+#include "hal/HAL.h"
+#include "simulation/AccelerometerSim.h"
+
+using namespace frc::sim;
+
+namespace hal {
+
+TEST(AcclerometerSimTests, TestActiveCallback) {
+ HAL_Initialize(500, 0);
+
+ AccelerometerSim sim{0};
+
+ sim.ResetData();
+
+ bool wasTriggered = false;
+ bool lastValue = false;
+
+ auto cb = sim.RegisterActiveCallback(
+ [&](wpi::StringRef name, const HAL_Value* value) {
+ wasTriggered = true;
+ lastValue = value->data.v_boolean;
+ },
+ false);
+
+ EXPECT_FALSE(wasTriggered);
+
+ HAL_SetAccelerometerActive(true);
+
+ EXPECT_TRUE(wasTriggered);
+ EXPECT_TRUE(lastValue);
+}
+
+} // namespace hal
diff --git a/hal/src/test/native/cpp/sim/SimInitializationTest.cpp b/hal/src/test/native/cpp/sim/SimInitializationTest.cpp
new file mode 100644
index 0000000..fdd34cd
--- /dev/null
+++ b/hal/src/test/native/cpp/sim/SimInitializationTest.cpp
@@ -0,0 +1,49 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "gtest/gtest.h"
+#include "hal/HAL.h"
+#include "simulation/AccelerometerSim.h"
+#include "simulation/AnalogGyroSim.h"
+#include "simulation/AnalogInSim.h"
+#include "simulation/AnalogOutSim.h"
+#include "simulation/AnalogTriggerSim.h"
+#include "simulation/DIOSim.h"
+#include "simulation/DigitalPWMSim.h"
+#include "simulation/DriverStationSim.h"
+#include "simulation/EncoderSim.h"
+#include "simulation/PCMSim.h"
+#include "simulation/PDPSim.h"
+#include "simulation/PWMSim.h"
+#include "simulation/RelaySim.h"
+#include "simulation/RoboRioSim.h"
+#include "simulation/SPIAccelerometerSim.h"
+
+using namespace frc::sim;
+
+namespace hal {
+
+TEST(SimInitializationTests, TestAllInitialize) {
+ HAL_Initialize(500, 0);
+ AccelerometerSim acsim{0};
+ AnalogGyroSim agsim{0};
+ AnalogInSim aisim{0};
+ AnalogOutSim aosim{0};
+ AnalogTriggerSim atsim{0};
+ DigitalPWMSim dpsim{0};
+ DIOSim diosim{0};
+ DriverStationSim dssim;
+ (void)dssim;
+ EncoderSim esim{0};
+ PCMSim pcmsim{0};
+ PDPSim pdpsim{0};
+ PWMSim pwmsim{0};
+ RelaySim rsim{0};
+ RoboRioSim rrsim{0};
+ SPIAccelerometerSim sasim{0};
+}
+} // namespace hal