Put in new allwiplib-2018 and packaged the large files

added new allwpilib

added ntcore

Added new wpiutil

Change-Id: I5bbb966a69ac2fbdce056e4c092a13f246dbaa6a
diff --git a/third_party/allwpilib_2018/hal/.styleguide b/third_party/allwpilib_2018/hal/.styleguide
new file mode 100644
index 0000000..83d03b0
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/.styleguide
@@ -0,0 +1,43 @@
+cppHeaderFileInclude {
+  \.h$
+  \.hpp$
+  \.inc$
+}
+
+cppSrcFileInclude {
+  \.cpp$
+}
+
+generatedFileExclude {
+  gmock/
+  ni-libraries/include/
+  ni-libraries/lib/
+  hal/src/main/native/athena/ctre/
+  hal/src/main/native/athena/frccansae/
+  hal/src/main/native/athena/visa/
+  hal/src/main/native/include/ctre/
+  UsageReporting\.h$
+}
+
+modifiableFileExclude {
+  wpilibj/src/arm-linux-jni/
+  wpilibj/src/main/native/cpp/
+  \.patch$
+  \.png$
+  \.py$
+  \.so$
+}
+
+includeOtherLibs {
+  ^FRC_FPGA_ChipObject/
+  ^FRC_NetworkCommunication/
+  ^i2clib/
+  ^llvm/
+  ^opencv2/
+  ^spilib/
+  ^support/
+}
+
+includeProject {
+  ^ctre/
+}
diff --git a/third_party/allwpilib_2018/hal/build.gradle b/third_party/allwpilib_2018/hal/build.gradle
new file mode 100644
index 0000000..3fef7b1
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/build.gradle
@@ -0,0 +1,222 @@
+apply plugin: 'cpp'
+apply plugin: 'google-test'
+apply plugin: 'visual-studio'
+apply plugin: 'edu.wpi.first.NativeUtils'
+
+apply from: '../config.gradle'
+
+ext.addHalToLinker = { binary->
+    if (binary.targetPlatform.architecture.name == 'athena') {
+        binary.lib project: ':hal', library: 'halAthena', linkage: 'shared'
+    } else {
+        binary.lib project: ':hal', library: 'halSim', linkage: 'shared'
+    }
+}
+
+model {
+    dependencyConfigs {
+        wpiutil(DependencyConfig) {
+            groupId = 'edu.wpi.first.wpiutil'
+            artifactId = 'wpiutil-cpp'
+            headerClassifier = 'headers'
+            ext = 'zip'
+            version = '3.+'
+            sharedConfigs = [ halAthena: [], halSim: [], halDev: [], halSimTestingBaseTest: [] ]
+            staticConfigs = [ halSimStaticDeps: [] ]
+        }
+    }
+    // Exports config is a utility to enable exporting all symbols in a C++ library on windows to a DLL.
+    // This removes the need for DllExport on a library. However, the gradle C++ builder has a bug
+    // where some extra symbols are added that cannot be resolved at link time. This configuration
+    // lets you specify specific symbols to exlude from exporting.
+    exportsConfigs {
+        halSim(ExportsConfig) {
+            x86ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure',
+                                  '_CT??_R0?AVbad_cast',
+                                  '_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure',
+                                  '_TI5?AVfailure' ]
+            x64ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure',
+                                  '_CT??_R0?AVbad_cast',
+                                  '_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure',
+                                  '_TI5?AVfailure' ]
+        }
+        halSimStaticDeps(ExportsConfig) {
+            x86SymbolFilter = { symbols->
+                def retList = []
+                symbols.each { symbol->
+                    if (symbol.startsWith('HAL_')) {
+                        retList << symbol
+                    }
+                }
+                return retList
+            }
+            x64SymbolFilter = { symbols->
+                def retList = []
+                symbols.each { symbol->
+                    if (symbol.startsWith('HAL_')) {
+                        retList << symbol
+                    }
+                }
+                return retList
+            }
+        }
+    }
+    components {
+        if (!project.hasProperty('skipAthena')) {
+            halAthena(NativeLibrarySpec) {
+                baseName = 'wpiHal'
+                sources {
+                    cpp {
+                        source {
+                            srcDirs = [ 'src/main/native/shared', 'src/main/native/athena' ]
+                            includes = ["**/*.cpp"]
+                        }
+                        exportedHeaders {
+                            srcDirs = ["src/main/native/include"]
+                        }
+                    }
+                }
+                binaries.all { binary->
+                    if (binary.targetPlatform.architecture.name != 'athena') {
+                        binary.buildable = false
+                    }
+                }
+            }
+        }
+        if (!project.hasProperty('onlyAthena')) {
+            halSim(NativeLibrarySpec) {
+                baseName = 'wpiHal'
+                sources {
+                    cpp {
+                        source {
+                            srcDirs = [ 'src/main/native/shared', 'src/main/native/sim' ]
+                            includes = ["**/*.cpp"]
+                        }
+                        exportedHeaders {
+                            srcDirs = ["src/main/native/include"]
+                        }
+                    }
+                }
+                binaries.all { binary ->
+                    if (binary.targetPlatform.operatingSystem.linux) {
+                        linker.args "-ldl"
+                    }
+                }
+            }
+            if (project.hasProperty('buildHalStaticDeps')) {
+                halSimStaticDeps(NativeLibrarySpec) {
+                    baseName = 'wpiHal'
+                    binaries {
+                        withType(StaticLibraryBinarySpec) {
+                            buildable = false
+                        }
+                    }
+                    sources {
+                        cpp {
+                            source {
+                                srcDirs = [ 'src/main/native/shared', 'src/main/native/sim' ]
+                                includes = ["**/*.cpp"]
+                            }
+                            exportedHeaders {
+                                srcDirs = ["src/main/native/include"]
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        // The TestingBase library is a workaround for an issue with the GoogleTest plugin.
+        // The plugin by default will rebuild the entire test source set, which increases
+        // build time. By testing an empty library, and then just linking the already built component
+        // into the test, we save the extra build
+        halSimTestingBase(NativeLibrarySpec) { }
+        // By default, a development executable will be generated. This is to help the case of
+        // testing specific functionality of the library.
+        if (!project.hasProperty('skipDevExe')) {
+            halDev(NativeExecutableSpec) {
+                binaries.all {
+                    project.addHalToLinker(it)
+                }
+                sources {
+                    cpp {
+                        source {
+                            srcDirs 'src/dev/native/cpp'
+                            include '**/*.cpp'
+                        }
+                        exportedHeaders {
+                            srcDirs 'src/dev/native/include'
+                        }
+                    }
+                }
+            }
+        }
+    }
+    testSuites {
+        halSimTestingBaseTest {
+            sources {
+                cpp.source.srcDir 'src/test/native/cpp'
+                cpp.exportedHeaders.srcDir 'src/test/native/include'
+            }
+        }
+    }
+    binaries {
+        all {
+            project(':ni-libraries').addNiLibrariesToLinker(it)
+        }
+        withType(GoogleTestTestSuiteBinarySpec) {
+            if (it.component.testedComponent.name.contains('TestingBase') && !project.hasProperty('onlyAthena')) {
+                project(':gmock').addGmockToLinker(it)
+                project.addHalToLinker(it)
+            } else {
+                it.buildable = false
+            }
+        }
+    }
+    tasks {
+        runCpp(Exec) {
+            def found = false
+            $.components.each {
+                if (it in NativeExecutableSpec && it.name == 'halDev') {
+                    it.binaries.each {
+                        if (!found) {
+                            def arch = it.targetPlatform.architecture.name
+                            if (arch == 'x86-64' || arch == 'x86') {
+                                dependsOn it.tasks.install
+                                commandLine it.tasks.install.runScript
+                                found = true
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        getHeaders(Task) {
+            def list = []
+            $.components.each {
+                if (it in NativeLibrarySpec && (it.name == 'halAthena' || it.name == 'halSim')) {
+                    it.sources.each {
+                        it.exportedHeaders.srcDirs.each {
+                            list.add(it)
+                        }
+                    }
+                    it.binaries.each {
+                        it.libs.each {
+                            it.includeRoots.each {
+                                list.add(it)
+                            }
+                        }
+                    }
+                }
+            }
+            list = list.unique(false)
+            doLast {
+                list.each {
+                    print "WPIHEADER: "
+                    println it
+                }
+            }
+        }
+    }
+}
+
+apply from: 'publish.gradle'
diff --git a/third_party/allwpilib_2018/hal/publish.gradle b/third_party/allwpilib_2018/hal/publish.gradle
new file mode 100644
index 0000000..924bf17
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/publish.gradle
@@ -0,0 +1,125 @@
+apply plugin: 'maven-publish'
+apply plugin: 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin'
+
+if (!hasProperty('releaseType')) {
+    WPILibVersion {
+        releaseType = 'dev'
+    }
+}
+
+def pubVersion = ''
+if (project.hasProperty("publishVersion")) {
+    pubVersion = project.publishVersion
+} else {
+    pubVersion = WPILibVersion.version
+}
+
+def baseArtifactId = 'hal'
+def artifactGroupId = 'edu.wpi.first.hal'
+
+def outputsFolder = file("$project.buildDir/outputs")
+
+task cppSourcesZip(type: Zip) {
+    destinationDir = outputsFolder
+    baseName = 'hal'
+    classifier = "sources"
+
+    from(licenseFile) {
+        into '/'
+    }
+
+    from('src/main/native/athena') {
+        into '/athena'
+    }
+
+    from('src/main/native/sim') {
+        into '/sim'
+    }
+
+    from('src/main/native/shared') {
+        into '/shared'
+    }
+}
+
+task cppHeadersZip(type: Zip) {
+    destinationDir = outputsFolder
+    baseName = 'hal'
+    classifier = "headers"
+
+    from(licenseFile) {
+        into '/'
+    }
+
+    from('src/main/native/include') {
+        into '/'
+    }
+}
+
+build.dependsOn cppHeadersZip
+build.dependsOn cppSourcesZip
+
+
+model {
+    publishing {
+        def halAthenaTaskList  = []
+        if (!project.hasProperty('skipAthena')) {
+            halAthenaTaskList = createComponentZipTasks($.components, 'halAthena', 'zipcpp', Zip, project, includeStandardZipFormat)
+        }
+        def halSimTaskList = []
+        if (!project.hasProperty('onlyAthena')) {
+            halSimTaskList = createComponentZipTasks($.components, 'halSim', 'zipcpp', Zip, project, includeStandardZipFormat)
+        }
+
+        def allTask
+        if (!project.hasProperty('jenkinsBuild')) {
+            def combinedList = []
+            halAthenaTaskList.each {
+                combinedList.add(it)
+            }
+            halSimTaskList.each {
+                combinedList.add(it)
+            }
+            allTask = createAllCombined(combinedList, 'hal', 'zipcpp', Zip, project)
+        }
+
+        def halSimStaticDepsTaskList = []
+        if (project.hasProperty('buildHalStaticDeps')) {
+            halSimStaticDepsTaskList = createComponentZipTasks($.components, 'halSimStaticDeps', 'zipcpp', Zip, project, includeStandardZipFormat)
+            if (!project.hasProperty('jenkinsBuild')) {
+                def staticAllTask = createAllCombined(halSimStaticDepsTaskList, 'halSimStaticDeps', 'zipcpp', Zip, project)
+                halSimStaticDepsTaskList.add(staticAllTask)
+            }
+        }
+
+        publications {
+            cpp(MavenPublication) {
+                halAthenaTaskList.each {
+                    artifact it
+                }
+                halSimTaskList.each {
+                    artifact it
+                }
+                if (!project.hasProperty('jenkinsBuild')) {
+                    artifact allTask
+                }
+                artifact cppHeadersZip
+                artifact cppSourcesZip
+
+                artifactId = baseArtifactId
+                groupId artifactGroupId
+                version pubVersion
+            }
+            if (project.hasProperty('buildHalStaticDeps')) {
+                cppStaticDeps(MavenPublication) {
+                    halSimStaticDepsTaskList.each {
+                        artifact it
+                    }
+
+                    artifactId = baseArtifactId + 'StaticDeps'
+                    groupId artifactGroupId
+                    version pubVersion
+                }
+            }
+        }
+    }
+}
diff --git a/third_party/allwpilib_2018/hal/src/dev/native/cpp/main.cpp b/third_party/allwpilib_2018/hal/src/dev/native/cpp/main.cpp
new file mode 100644
index 0000000..4b3e1f7
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/athena/Accelerometer.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/Accelerometer.cpp
new file mode 100644
index 0000000..f0917f4
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/Accelerometer.cpp
@@ -0,0 +1,264 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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() {
+  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" {
+
+/**
+ * Set the accelerometer to active or standby mode.  It must be in standby
+ * mode to change any configuration.
+ */
+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));
+}
+
+/**
+ * Set 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.
+ */
+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);
+}
+
+/**
+ * Get the x-axis acceleration
+ *
+ * This is a floating point value in units of 1 g-force
+ */
+double HAL_GetAccelerometerX(void) {
+  initializeAccelerometer();
+
+  int32_t raw =
+      (readRegister(kReg_OutXMSB) << 4) | (readRegister(kReg_OutXLSB) >> 4);
+  return unpackAxis(raw);
+}
+
+/**
+ * Get the y-axis acceleration
+ *
+ * This is a floating point value in units of 1 g-force
+ */
+double HAL_GetAccelerometerY(void) {
+  initializeAccelerometer();
+
+  int32_t raw =
+      (readRegister(kReg_OutYMSB) << 4) | (readRegister(kReg_OutYLSB) >> 4);
+  return unpackAxis(raw);
+}
+
+/**
+ * Get the z-axis acceleration
+ *
+ * This is a floating point value in units of 1 g-force
+ */
+double HAL_GetAccelerometerZ(void) {
+  initializeAccelerometer();
+
+  int32_t raw =
+      (readRegister(kReg_OutZMSB) << 4) | (readRegister(kReg_OutZLSB) >> 4);
+  return unpackAxis(raw);
+}
+
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogAccumulator.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogAccumulator.cpp
new file mode 100644
index 0000000..fe017e5
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogAccumulator.cpp
@@ -0,0 +1,204 @@
+/*----------------------------------------------------------------------------*/
+/* 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" {
+
+/**
+ * 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) {
+  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;
+}
+
+/**
+ * Initialize the accumulator.
+ *
+ * @param analogPortHandle Handle to the analog port.
+ */
+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);
+}
+
+/**
+ * Resets the accumulator to the initial value.
+ *
+ * @param analogPortHandle Handle to the analog port.
+ */
+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);
+}
+
+/**
+ * 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) {
+  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);
+}
+
+/**
+ * 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) {
+  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);
+}
+
+/**
+ * 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) {
+  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;
+}
+
+/**
+ * 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) {
+  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);
+}
+
+/**
+ * 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) {
+  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/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogGyro.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogGyro.cpp
new file mode 100644
index 0000000..cdc9b0c
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogGyro.cpp
@@ -0,0 +1,255 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "AnalogInternal.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) {
+  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;
+  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/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogInput.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogInput.cpp
new file mode 100644
index 0000000..e307eb1
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogInput.cpp
@@ -0,0 +1,392 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <support/mutex.h>
+
+#include "AnalogInternal.h"
+#include "HAL/AnalogAccumulator.h"
+#include "HAL/HAL.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "PortsInternal.h"
+
+namespace hal {
+namespace init {
+void InitializeAnalogInput() {}
+}  // namespace init
+}  // namespace hal
+
+using namespace hal;
+
+extern "C" {
+
+/**
+ * Initialize the analog input port using the given port object.
+ *
+ * @param portHandle Handle to the port to initialize.
+ */
+HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
+                                                    int32_t* status) {
+  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;
+}
+
+/**
+ * @param analogPortHandle Handle to the analog port.
+ */
+void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analogPortHandle) {
+  // no status, so no need to check for a proper free.
+  analogInputHandles->Free(analogPortHandle);
+}
+
+/**
+ * Check 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) { return module == 1; }
+
+/**
+ * Check that the analog output channel number is value.
+ * Verify 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) {
+  return channel < kNumAnalogInputs && channel >= 0;
+}
+
+/**
+ * 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 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);
+}
+
+/**
+ * Get 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) {
+  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);
+}
+
+/**
+ * Set 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) {
+  auto port = analogInputHandles->Get(analogPortHandle);
+  if (port == nullptr) {
+    *status = HAL_HANDLE_ERROR;
+    return;
+  }
+  analogInputSystem->writeAverageBits(port->channel, static_cast<uint8_t>(bits),
+                                      status);
+}
+
+/**
+ * Get 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) {
+  auto port = analogInputHandles->Get(analogPortHandle);
+  if (port == nullptr) {
+    *status = HAL_HANDLE_ERROR;
+    return kDefaultAverageBits;
+  }
+  uint8_t result = analogInputSystem->readAverageBits(port->channel, status);
+  return result;
+}
+
+/**
+ * Set 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) {
+  auto port = analogInputHandles->Get(analogPortHandle);
+  if (port == nullptr) {
+    *status = HAL_HANDLE_ERROR;
+    return;
+  }
+  analogInputSystem->writeOversampleBits(port->channel,
+                                         static_cast<uint8_t>(bits), status);
+}
+
+/**
+ * Get 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) {
+  auto port = analogInputHandles->Get(analogPortHandle);
+  if (port == nullptr) {
+    *status = HAL_HANDLE_ERROR;
+    return kDefaultOversampleBits;
+  }
+  uint8_t result = analogInputSystem->readOversampleBits(port->channel, status);
+  return result;
+}
+
+/**
+ * Get 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) {
+  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));
+}
+
+/**
+ * Get 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) {
+  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));
+}
+
+/**
+ * Get 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) {
+  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;
+}
+
+/**
+ * Get 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) {
+  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;
+}
+
+/**
+ * Convert 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) {
+  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;
+}
+
+/**
+ * Get 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) {
+  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;
+}
+
+/**
+ * Get 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) {
+  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/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogInternal.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogInternal.cpp
new file mode 100644
index 0000000..e219f94
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogInternal.cpp
@@ -0,0 +1,133 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <support/mutex.h>
+
+#include "HAL/AnalogInput.h"
+#include "HAL/ChipObject.h"
+#include "PortsInternal.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
+
+/**
+ * Initialize the analog System.
+ */
+void initializeAnalog(int32_t* status) {
+  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;
+}
+
+/**
+ * Return the number of channels on the module in use.
+ *
+ * @return Active channels.
+ */
+int32_t getAnalogNumActiveChannels(int32_t* status) {
+  int32_t scanSize = analogInputSystem->readConfig_ScanSize(status);
+  if (scanSize == 0) return 8;
+  return scanSize;
+}
+
+/**
+ * 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) {
+  if (analogNumChannelsToActivate == 0)
+    return getAnalogNumActiveChannels(status);
+  return analogNumChannelsToActivate;
+}
+
+/**
+ * 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) {
+  // 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);
+}
+
+/**
+ * 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) {
+  analogNumChannelsToActivate = channels;
+}
+
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogInternal.h b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogInternal.h
new file mode 100644
index 0000000..5c3a863
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogInternal.h
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <stdint.h>
+
+#include <memory>
+
+#include <support/mutex.h>
+
+#include "HAL/ChipObject.h"
+#include "HAL/Ports.h"
+#include "HAL/handles/IndexedHandleResource.h"
+#include "PortsInternal.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;
+
+int32_t getAnalogNumActiveChannels(int32_t* status);
+int32_t getAnalogNumChannelsToActivate(int32_t* status);
+void setAnalogNumChannelsToActivate(int32_t channels);
+void setAnalogSampleRate(double samplesPerSecond, int32_t* status);
+void initializeAnalog(int32_t* status);
+
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogOutput.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogOutput.cpp
new file mode 100644
index 0000000..eae0e21
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogOutput.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/AnalogOutput.h"
+
+#include "AnalogInternal.h"
+#include "HAL/Errors.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "HAL/handles/IndexedHandleResource.h"
+#include "PortsInternal.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" {
+
+/**
+ * Initialize the analog output port using the given port object.
+ */
+HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
+                                                      int32_t* status) {
+  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);
+}
+
+/**
+ * Check that the analog output channel number is value.
+ * Verify 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) {
+  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;
+  }
+
+  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;
+}
+
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogTrigger.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogTrigger.cpp
new file mode 100644
index 0000000..bcbe68a
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/AnalogTrigger.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 "HAL/AnalogTrigger.h"
+
+#include "AnalogInternal.h"
+#include "HAL/AnalogInput.h"
+#include "HAL/Errors.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "HAL/handles/LimitedHandleResource.h"
+#include "PortsInternal.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) {
+  // 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);
+}
+
+/**
+ * Set the upper and lower limits of the analog trigger.
+ * The limits are given as floating point voltage values.
+ */
+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);
+}
+
+/**
+ * Configure 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.
+ */
+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);
+}
+
+/**
+ * Configure 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.
+ */
+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);
+}
+
+/**
+ * Return the InWindow output of the analog trigger.
+ * True if the analog input is between the upper and lower limits.
+ * @return The InWindow output of the analog trigger.
+ */
+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;
+}
+
+/**
+ * Return the TriggerState output of the analog trigger.
+ * True if above upper limit.
+ * False if below lower limit.
+ * If in Hysteresis, maintain previous state.
+ * @return The TriggerState output of the analog trigger.
+ */
+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;
+}
+
+/**
+ * Get the state of the analog trigger output.
+ * @return The state of the analog trigger output.
+ */
+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/third_party/allwpilib_2018/hal/src/main/native/athena/CAN.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/CAN.cpp
new file mode 100644
index 0000000..251daef
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/athena/Compressor.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/Compressor.cpp
new file mode 100644
index 0000000..c5277ef
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/Compressor.cpp
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "HAL/Compressor.h"
+
+#include "HAL/Errors.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "PCMInternal.h"
+#include "PortsInternal.h"
+#include "ctre/PCM.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) {
+  // 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/third_party/allwpilib_2018/hal/src/main/native/athena/Constants.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/Constants.cpp
new file mode 100644
index 0000000..13cf290
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/athena/ConstantsInternal.h b/third_party/allwpilib_2018/hal/src/main/native/athena/ConstantsInternal.h
new file mode 100644
index 0000000..55bbdee
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/athena/Counter.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/Counter.cpp
new file mode 100644
index 0000000..ec2f9c4
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/Counter.cpp
@@ -0,0 +1,480 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/HAL.h"
+#include "HAL/handles/LimitedHandleResource.h"
+#include "PortsInternal.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) {
+  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);
+}
+
+/**
+ * Set the source object that causes the counter to count up.
+ * Set the up counting DigitalSource.
+ */
+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);
+}
+
+/**
+ * Set the edge sensitivity on an up counting source.
+ * Set the up source to either detect rising edges or falling edges.
+ */
+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);
+}
+
+/**
+ * Disable the up counting source to the counter.
+ */
+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);
+}
+
+/**
+ * Set the source object that causes the counter to count down.
+ * Set the down counting DigitalSource.
+ */
+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);
+}
+
+/**
+ * Set the edge sensitivity on a down counting source.
+ * Set the down source to either detect rising edges or falling edges.
+ */
+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);
+}
+
+/**
+ * Disable the down counting source to the counter.
+ */
+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);
+}
+
+/**
+ * Set standard up / down counting mode on this counter.
+ * Up and down counts are sourced independently from two inputs.
+ */
+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);
+}
+
+/**
+ * Set external direction mode on this counter.
+ * Counts are sourced on the Up counter input.
+ * The Down counter input represents the direction to count.
+ */
+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);
+}
+
+/**
+ * Set Semi-period mode on this counter.
+ * Counts up on both rising and falling edges.
+ */
+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);
+}
+
+/**
+ * Configure 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 threshold The pulse length beyond which the counter counts the
+ * opposite direction.  Units are seconds.
+ */
+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);
+}
+
+/**
+ * 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_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);
+}
+
+/**
+ * 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_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);
+}
+
+/**
+ * Reset the Counter to zero.
+ * Set the counter value to zero. This doesn't effect the running state of the
+ * counter, just sets the current value to zero.
+ */
+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);
+}
+
+/**
+ * Read the current counter 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.
+ */
+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;
+}
+
+/*
+ * Get 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.
+ * @returns The period of the last two pulses in units of seconds.
+ */
+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)
+}
+
+/**
+ * Set 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 GetStopped
+ * method.
+ * @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) {
+  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);
+}
+
+/**
+ * Select 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).
+ */
+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);
+}
+
+/**
+ * Determine 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.
+ * @return Returns true if the most recent counter period exceeds the MaxPeriod
+ * value set by SetMaxPeriod.
+ */
+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);
+}
+
+/**
+ * The last direction the counter value changed.
+ * @return The last direction the counter value changed.
+ */
+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;
+}
+
+/**
+ * Set 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 reverseDirection true if the value counted should be negated.
+ */
+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/third_party/allwpilib_2018/hal/src/main/native/athena/DIO.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/DIO.cpp
new file mode 100644
index 0000000..6608071
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/DIO.cpp
@@ -0,0 +1,587 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/handles/HandlesInternal.h"
+#include "HAL/handles/LimitedHandleResource.h"
+#include "PortsInternal.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" {
+
+/**
+ * Create a new instance of a digital port.
+ */
+HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
+                                        HAL_Bool input, int32_t* status) {
+  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.
+  digitalChannelHandles->Free(dioPortHandle, HAL_HandleEnum::DIO);
+  if (port == nullptr) return;
+  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);
+  }
+}
+
+/**
+ * Allocate a DO PWM Generator.
+ * Allocate PWM generators so that they are not accidentally reused.
+ *
+ * @return PWM Generator handle
+ */
+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;
+}
+
+/**
+ * Free the resource associated with a DO PWM generator.
+ *
+ * @param pwmGenerator The pwmGen to free that was allocated with
+ * allocateDigitalPWM()
+ */
+void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status) {
+  digitalPWMHandles->Free(pwmGenerator);
+}
+
+/**
+ * Change 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) {
+  // 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);
+}
+
+/**
+ * Configure the duty-cycle of the PWM generator
+ *
+ * @param pwmGenerator The generator index reserved by allocateDigitalPWM()
+ * @param dutyCycle The percent duty cycle to output [0..1].
+ */
+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);
+  }
+}
+
+/**
+ * Configure which DO channel the PWM signal is output on
+ *
+ * @param pwmGenerator The generator index reserved by allocateDigitalPWM()
+ * @param channel The Digital Output channel to output on
+ */
+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);
+}
+
+/**
+ * Write a digital I/O bit to the FPGA.
+ * Set a single value on a digital I/O channel.
+ *
+ * @param channel The Digital I/O channel
+ * @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) {
+  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);
+  }
+}
+
+/**
+ * Set direction of a DIO channel.
+ *
+ * @param channel The Digital I/O channel
+ * @param input true to set input, false for output
+ */
+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);
+  }
+}
+
+/**
+ * Read a digital I/O bit from the FPGA.
+ * Get a single value from a digital I/O channel.
+ *
+ * @param channel The digital I/O channel
+ * @return The state of the specified channel
+ */
+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;
+  }
+}
+
+/**
+ * Read the direction of a the Digital I/O lines
+ * A 1 bit means output and a 0 bit means input.
+ *
+ * @param channel The digital I/O channel
+ * @return The direction of the specified channel
+ */
+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;
+  }
+}
+
+/**
+ * Generate a single pulse.
+ * Write a pulse to the specified digital output channel. There can only be a
+ * single pulse going at any time.
+ *
+ * @param channel The Digital Output channel that the pulse should be output on
+ * @param pulseLength The active length of the pulse (in seconds)
+ */
+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);
+}
+
+/**
+ * Check a DIO line to see if it is currently generating a pulse.
+ *
+ * @return A pulse is in progress
+ */
+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;
+  }
+}
+
+/**
+ * Check if any DIO line is currently generating a pulse.
+ *
+ * @return A pulse on some line is in progress
+ */
+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;
+}
+
+/**
+ * Write the filter index from the FPGA.
+ * Set the filter index used to filter out short pulses.
+ *
+ * @param dioPortHandle Handle to the digital I/O channel
+ * @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) {
+  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);
+  }
+}
+
+/**
+ * Read the filter index from the FPGA.
+ * Get the filter index used to filter out short pulses.
+ *
+ * @param dioPortHandle Handle to the digital I/O channel
+ * @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) {
+  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);
+  }
+}
+
+/**
+ * Set the filter period for the specified filter index.
+ *
+ * Set 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) {
+  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);
+  }
+}
+
+/**
+ * Get the filter period for the specified filter index.
+ *
+ * Get 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) {
+  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/third_party/allwpilib_2018/hal/src/main/native/athena/DigitalInternal.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/DigitalInternal.cpp
new file mode 100644
index 0000000..2305ce2
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/DigitalInternal.cpp
@@ -0,0 +1,198 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <support/mutex.h>
+
+#include "ConstantsInternal.h"
+#include "HAL/AnalogTrigger.h"
+#include "HAL/ChipObject.h"
+#include "HAL/HAL.h"
+#include "HAL/Ports.h"
+#include "HAL/cpp/UnsafeDIO.h"
+#include "PortsInternal.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
+
+/**
+ * Initialize the digital system.
+ */
+void initializeDigital(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;
+
+  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;
+}
+
+/**
+ * Map SPI channel numbers from their physical number (27 to 31) to their
+ * position in the bit field.
+ */
+int32_t remapSPIChannel(int32_t channel) { return channel - 26; }
+
+/**
+ * Map DIO channel numbers from their physical number (10 to 26) to their
+ * position in the bit field.
+ */
+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
+  }
+}
+
+/**
+ * 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) {
+  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;
+  }
+}
+
+}  // namespace hal
+
+// Unused function here to test template compile.
+__attribute__((unused)) static void CompileFunctorTest() {
+  hal::UnsafeManipulateDIO(0, nullptr, [](hal::DIOSetProxy& proxy) {});
+}
diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/DigitalInternal.h b/third_party/allwpilib_2018/hal/src/main/native/athena/DigitalInternal.h
new file mode 100644
index 0000000..6ef8e29
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/DigitalInternal.h
@@ -0,0 +1,92 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <support/mutex.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"
+#include "PortsInternal.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;
+
+void initializeDigital(int32_t* status);
+bool remapDigitalSource(HAL_Handle digitalSourceHandle,
+                        HAL_AnalogTriggerType analogTriggerType,
+                        uint8_t& channel, uint8_t& module, bool& analogTrigger);
+int32_t remapSPIChannel(int32_t channel);
+int32_t remapMXPPWMChannel(int32_t channel);
+int32_t remapMXPChannel(int32_t channel);
+
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/Encoder.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/Encoder.cpp
new file mode 100644
index 0000000..240c252
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/Encoder.cpp
@@ -0,0 +1,460 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/ChipObject.h"
+#include "HAL/Counter.h"
+#include "HAL/Errors.h"
+#include "HAL/handles/LimitedClassedHandleResource.h"
+#include "PortsInternal.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) {
+  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/third_party/allwpilib_2018/hal/src/main/native/athena/EncoderInternal.h b/third_party/allwpilib_2018/hal/src/main/native/athena/EncoderInternal.h
new file mode 100644
index 0000000..f25bb5a
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/athena/FPGAEncoder.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/FPGAEncoder.cpp
new file mode 100644
index 0000000..764728e
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/FPGAEncoder.cpp
@@ -0,0 +1,310 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/handles/LimitedHandleResource.h"
+#include "PortsInternal.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) {
+  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);
+}
+
+/**
+ * Reset the Encoder distance to zero.
+ * Resets the current count to zero on the encoder.
+ */
+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);
+}
+
+/**
+ * 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) {
+  auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+  if (encoder == nullptr) {
+    *status = HAL_HANDLE_ERROR;
+    return 0;
+  }
+  return encoder->encoder->readOutput_Value(status);
+}
+
+/**
+ * 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) {
+  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;
+}
+
+/**
+ * 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) {
+  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);
+}
+
+/**
+ * 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) {
+  auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+  if (encoder == nullptr) {
+    *status = HAL_HANDLE_ERROR;
+    return false;
+  }
+  return encoder->encoder->readTimerOutput_Stalled(status) != 0;
+}
+
+/**
+ * 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) {
+  auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+  if (encoder == nullptr) {
+    *status = HAL_HANDLE_ERROR;
+    return false;
+  }
+  return encoder->encoder->readOutput_Direction(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) {
+  auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+  if (encoder == nullptr) {
+    *status = HAL_HANDLE_ERROR;
+    return;
+  }
+  encoder->encoder->writeConfig_Reverse(reverseDirection, 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) {
+  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);
+}
+
+/**
+ * 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) {
+  auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
+  if (encoder == nullptr) {
+    *status = HAL_HANDLE_ERROR;
+    return 0;
+  }
+  return encoder->encoder->readTimerConfig_AverageSize(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) {
+  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/third_party/allwpilib_2018/hal/src/main/native/athena/FPGAEncoder.h b/third_party/allwpilib_2018/hal/src/main/native/athena/FPGAEncoder.h
new file mode 100644
index 0000000..c05d436
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/FPGAEncoder.h
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#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);
+void HAL_ResetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+                          int32_t* status);
+int32_t HAL_GetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+                           int32_t* status);  // Raw value
+double HAL_GetFPGAEncoderPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+                                int32_t* status);
+void HAL_SetFPGAEncoderMaxPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+                                 double maxPeriod, int32_t* status);
+HAL_Bool HAL_GetFPGAEncoderStopped(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+                                   int32_t* status);
+HAL_Bool HAL_GetFPGAEncoderDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+                                     int32_t* status);
+void HAL_SetFPGAEncoderReverseDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+                                        HAL_Bool reverseDirection,
+                                        int32_t* status);
+void HAL_SetFPGAEncoderSamplesToAverage(HAL_FPGAEncoderHandle fpgaEncoderHandle,
+                                        int32_t samplesToAverage,
+                                        int32_t* status);
+int32_t HAL_GetFPGAEncoderSamplesToAverage(
+    HAL_FPGAEncoderHandle fpgaEncoderHandle, int32_t* status);
+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/third_party/allwpilib_2018/hal/src/main/native/athena/FRCDriverStation.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/FRCDriverStation.cpp
new file mode 100644
index 0000000..32d29b9
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/FRCDriverStation.cpp
@@ -0,0 +1,406 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <llvm/raw_ostream.h>
+#include <support/condition_variable.h>
+#include <support/mutex.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 wpi::mutex msgMutex;
+static wpi::condition_variable* newDSDataAvailableCond;
+static wpi::mutex newDSDataAvailableMutex;
+static int newDSDataAvailableCounter{0};
+
+namespace hal {
+namespace init {
+void InitializeFRCDriverStation() {
+  static wpi::condition_variable nddaC;
+  newDSDataAvailableCond = &nddaC;
+}
+}  // 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') {
+        llvm::errs() << (isError ? "Error" : "Warning") << " at " << location
+                     << ": ";
+      }
+      llvm::errs() << details << "\n";
+      if (callStack && callStack[0] != '\0') {
+        llvm::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));
+  return FRC_NetworkCommunication_getControlWord(
+      reinterpret_cast<ControlWord_t*>(controlWord));
+}
+
+HAL_AllianceStationID HAL_GetAllianceStation(int32_t* status) {
+  HAL_AllianceStationID allianceStation;
+  *status = FRC_NetworkCommunication_getAllianceStation(
+      reinterpret_cast<AllianceStationID_t*>(&allianceStation));
+  return allianceStation;
+}
+
+int32_t HAL_GetJoystickAxes(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;
+}
+
+int32_t HAL_GetJoystickPOVs(int32_t joystickNum, HAL_JoystickPOVs* povs) {
+  return FRC_NetworkCommunication_getJoystickPOVs(
+      joystickNum, reinterpret_cast<JoystickPOV_t*>(povs),
+      HAL_kMaxJoystickPOVs);
+}
+
+int32_t HAL_GetJoystickButtons(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.
+ */
+int32_t HAL_GetJoystickDescriptor(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;
+}
+
+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;
+}
+
+int HAL_GetMatchInfo(HAL_MatchInfo* info) {
+  uint16_t gameSpecificMessageSize = 0;
+  int status = FRC_NetworkCommunication_getMatchInfo(
+      nullptr, nullptr, nullptr, nullptr, nullptr, &gameSpecificMessageSize);
+  if (status < 0) {
+    info->eventName = nullptr;
+    info->gameSpecificMessage = nullptr;
+    return status;
+  }
+  info->eventName = static_cast<char*>(std::malloc(256));
+  gameSpecificMessageSize = ((gameSpecificMessageSize + 1023) / 1024) * 1024;
+  uint16_t originalGameSpecificSize = gameSpecificMessageSize;
+  uint8_t* gameSpecificMessage =
+      static_cast<uint8_t*>(std::malloc(gameSpecificMessageSize));
+  MatchType_t matchType = MatchType_t::kMatchType_none;
+  uint16_t matchNumber = 0;
+  uint8_t replayNumber = 0;
+  status = FRC_NetworkCommunication_getMatchInfo(
+      info->eventName, &matchType, &matchNumber, &replayNumber,
+      gameSpecificMessage, &gameSpecificMessageSize);
+  if (status < 0) {
+    std::free(info->eventName);
+    std::free(gameSpecificMessage);
+    info->eventName = nullptr;
+    info->gameSpecificMessage = nullptr;
+    return status;
+  }
+  if (gameSpecificMessageSize >= originalGameSpecificSize) {
+    // Data has updated between size and read calls. Retry.
+    // Unless large lag, this call will be right.
+    std::free(gameSpecificMessage);
+    gameSpecificMessageSize = ((gameSpecificMessageSize + 1023) / 1024) * 1024;
+    gameSpecificMessage =
+        static_cast<uint8_t*>(std::malloc(gameSpecificMessageSize));
+    int status = FRC_NetworkCommunication_getMatchInfo(
+        nullptr, nullptr, nullptr, nullptr, gameSpecificMessage,
+        &gameSpecificMessageSize);
+    if (status < 0) {
+      std::free(info->eventName);
+      std::free(gameSpecificMessage);
+      info->eventName = nullptr;
+      info->gameSpecificMessage = nullptr;
+      return status;
+    }
+  }
+  info->eventName[255] = '\0';
+  info->matchType = static_cast<HAL_MatchType>(matchType);
+  info->matchNumber = matchNumber;
+  info->replayNumber = replayNumber;
+  info->gameSpecificMessage = reinterpret_cast<char*>(gameSpecificMessage);
+  info->gameSpecificMessage[gameSpecificMessageSize] = '\0';
+  return status;
+}
+
+void HAL_FreeMatchInfo(HAL_MatchInfo* info) {
+  std::free(info->eventName);
+  std::free(info->gameSpecificMessage);
+  info->eventName = nullptr;
+  info->gameSpecificMessage = nullptr;
+}
+
+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();
+}
+
+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};
+  int currentCount = 0;
+  {
+    std::unique_lock<wpi::mutex> lock(newDSDataAvailableMutex);
+    currentCount = 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);
+
+  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 void newDataOccur(uint32_t refNum) {
+  // Since we could get other values, require our specific handle
+  // to signal our threads
+  if (refNum != refNumber) return;
+  std::lock_guard<wpi::mutex> lock(newDSDataAvailableMutex);
+  // Nofify all threads
+  newDSDataAvailableCounter++;
+  newDSDataAvailableCond->notify_all();
+}
+
+/*
+ * 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;
+
+  // 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/third_party/allwpilib_2018/hal/src/main/native/athena/HAL.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/HAL.cpp
new file mode 100644
index 0000000..4c65597
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/HAL.cpp
@@ -0,0 +1,434 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <llvm/raw_ostream.h>
+#include <support/mutex.h>
+#include <support/timestamp.h>
+
+#include "HAL/ChipObject.h"
+#include "HAL/DriverStation.h"
+#include "HAL/Errors.h"
+#include "HAL/Notifier.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "HALInitializer.h"
+#include "ctre/ctre.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() {
+  InitializeHandlesInternal();
+  InitializeAccelerometer();
+  InitializeAnalogAccumulator();
+  InitializeAnalogGyro();
+  InitializeAnalogInput();
+  InitializeAnalogInternal();
+  InitializeAnalogOutput();
+  InitializeAnalogTrigger();
+  InitializeCAN();
+  InitializeCompressor();
+  InitializeConstants();
+  InitializeCounter();
+  InitializeDigitalInternal();
+  InitializeDIO();
+  InitializeEncoder();
+  InitializeFPGAEncoder();
+  InitializeFRCDriverStation();
+  InitializeI2C();
+  InitialzeInterrupts();
+  InitializeNotifier();
+  InitializeOSSerialPort();
+  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);
+}
+
+/**
+ * @deprecated Uses module numbers
+ */
+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;
+    default:
+      return "Unknown error status";
+  }
+}
+
+/**
+ * Returns the runtime type of this HAL
+ */
+HAL_RuntimeType HAL_GetRuntimeType(void) { return HAL_Athena; }
+
+/**
+ * Return the FPGA Version number.
+ * For now, expect this to be competition year.
+ * @return FPGA Version number.
+ */
+int32_t HAL_GetFPGAVersion(int32_t* status) {
+  if (!global) {
+    *status = NiFpga_Status_ResourceNotInitialized;
+    return 0;
+  }
+  return global->readVersion(status);
+}
+
+/**
+ * Return 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) {
+  if (!global) {
+    *status = NiFpga_Status_ResourceNotInitialized;
+    return 0;
+  }
+  return global->readRevision(status);
+}
+
+/**
+ * Read 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) {
+  if (!global) {
+    *status = NiFpga_Status_ResourceNotInitialized;
+    return 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;
+}
+
+/**
+ * Get 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) {
+  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()) {
+      llvm::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
+        if (mode == 0) {
+          llvm::outs() << "FRC pid " << pid << " did not die within " << timeout
+                       << "ms. Aborting\n";
+          return 0;              // just fail
+        } else if (mode == 1) {  // kill -9 it
+          kill(pid, SIGKILL);
+        } else {
+          llvm::outs() << "WARNING: FRC pid " << pid << " did not die within "
+                       << timeout << "ms.\n";
+        }
+      }
+    }
+  }
+  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;
+}
+
+/**
+ * Call this to start up HAL. This is required for robot programs.
+ */
+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();
+
+  setlinebuf(stdin);
+  setlinebuf(stdout);
+  llvm::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) {
+      llvm::errs()
+          << "Call to HAL_GetFPGATime failed."
+          << "Initialization might have failed. Time will not be correct\n";
+      llvm::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/third_party/allwpilib_2018/hal/src/main/native/athena/HALInitializer.h b/third_party/allwpilib_2018/hal/src/main/native/athena/HALInitializer.h
new file mode 100644
index 0000000..9527097
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/HALInitializer.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
+
+namespace hal {
+namespace init {
+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 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 InitializeOSSerialPort();
+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();
+extern void InitializeHandlesInternal();
+}  // namespace init
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/I2C.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/I2C.cpp
new file mode 100644
index 0000000..98c5776
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/I2C.cpp
@@ -0,0 +1,231 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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" {
+
+/*
+ * Initialize 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) {
+  initializeDigital(status);
+  if (*status != 0) return;
+
+  if (port > 1) {
+    // Set port out of range error here
+    return;
+  }
+
+  if (port == 0) {
+    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;
+  }
+}
+
+/**
+ * Generic transaction.
+ *
+ * This is a lower-level interface to the I2C hardware giving you more control
+ * over each transaction.
+ *
+ * @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) {
+  if (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 == 0) {
+    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);
+  }
+}
+
+/**
+ * Execute a write transaction with the device.
+ *
+ * Write a single byte to a register on a device and wait until the
+ *   transaction is complete.
+ *
+ * @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) {
+  if (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 == 0) {
+    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);
+  }
+}
+
+/**
+ * Execute a read transaction with the device.
+ *
+ * Read 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 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) {
+  if (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 == 0) {
+    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 > 1) {
+    // Set port out of range error here
+    return;
+  }
+
+  if (port == 0) {
+    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/third_party/allwpilib_2018/hal/src/main/native/athena/Interrupts.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/Interrupts.cpp
new file mode 100644
index 0000000..afc6ec0
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/Interrupts.cpp
@@ -0,0 +1,270 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <support/SafeThread.h>
+
+#include "DigitalInternal.h"
+#include "HAL/ChipObject.h"
+#include "HAL/Errors.h"
+#include "HAL/cpp/make_unique.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "HAL/handles/LimitedHandleResource.h"
+#include "PortsInternal.h"
+
+using namespace hal;
+
+namespace {
+
+struct Interrupt {
+  std::unique_ptr<tInterrupt> anInterrupt;
+  std::unique_ptr<tInterruptManager> manager;
+};
+
+// 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);
+}
+
+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_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) {
+  interruptHandles->Free(interruptHandle);
+}
+
+/**
+ * In synchronous mode, wait for the defined interrupt to occur.
+ * @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) {
+  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;
+}
+
+/**
+ * Enable 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.
+ */
+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);
+}
+
+/**
+ * Disable Interrupts without without deallocating structures.
+ */
+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);
+}
+
+/**
+ * Return the timestamp for the rising interrupt that occurred most recently.
+ * This is in the same time domain as GetClock().
+ * @return Timestamp in seconds since boot.
+ */
+double 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 * 1e-6;
+}
+
+/**
+ * Return the timestamp for the falling interrupt that occurred most recently.
+ * This is in the same time domain as GetClock().
+ * @return Timestamp in seconds since boot.
+ */
+double 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 * 1e-6;
+}
+
+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);
+}
+
+void HAL_AttachInterruptHandlerThreaded(HAL_InterruptHandle interrupt_handle,
+                                        HAL_InterruptHandlerFunction handler,
+                                        void* param, int32_t* status) {
+  InterruptThreadOwner* intr = new InterruptThreadOwner;
+  intr->Start();
+  intr->SetFunc(handler, param);
+
+  HAL_AttachInterruptHandler(interrupt_handle, threadedInterruptHandler, intr,
+                             status);
+
+  if (*status != 0) {
+    delete intr;
+  }
+}
+
+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/third_party/allwpilib_2018/hal/src/main/native/athena/Notifier.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/Notifier.cpp
new file mode 100644
index 0000000..10aa0d2
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/Notifier.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 "HAL/Notifier.h"
+
+#include <atomic>
+#include <cstdlib>  // For std::atexit()
+#include <memory>
+
+#include <support/condition_variable.h>
+#include <support/mutex.h>
+
+#include "HAL/ChipObject.h"
+#include "HAL/Errors.h"
+#include "HAL/HAL.h"
+#include "HAL/cpp/make_unique.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) {
+  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)
+    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/third_party/allwpilib_2018/hal/src/main/native/athena/OSSerialPort.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/OSSerialPort.cpp
new file mode 100644
index 0000000..ccb49fd
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/OSSerialPort.cpp
@@ -0,0 +1,244 @@
+/*----------------------------------------------------------------------------*/
+/* 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/OSSerialPort.h"
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <chrono>
+#include <cstring>
+#include <string>
+
+#include "HAL/Errors.h"
+#include "HAL/cpp/SerialHelper.h"
+
+static int portHandles[4]{-1, -1, -1, -1};
+static std::chrono::milliseconds portTimeouts[4]{
+    std::chrono::milliseconds(0), std::chrono::milliseconds(0),
+    std::chrono::milliseconds(0), std::chrono::milliseconds(0)};
+
+namespace hal {
+namespace init {
+void InitializeOSSerialPort() {
+  for (int i = 0; i < 4; i++) {
+    portHandles[i] = -1;
+    portTimeouts[i] = std::chrono::milliseconds(0);
+  }
+}
+}  // namespace init
+}  // namespace hal
+
+extern "C" {
+
+void HAL_InitializeOSSerialPort(HAL_SerialPort port, int32_t* status) {
+  std::string portName;
+
+  hal::SerialHelper serialHelper;
+
+  portName = serialHelper.GetOSSerialPortName(port, status);
+
+  if (*status < 0) {
+    return;
+  }
+
+  int fs = open(portName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
+  if (fs == -1) {
+    *status = HAL_SERIAL_PORT_OPEN_ERROR;
+    return;
+  }
+  portHandles[port] = fs;
+
+  struct termios options;
+  tcgetattr(fs, &options);
+  options.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
+  options.c_iflag = 0;
+  options.c_oflag = 0;
+  options.c_lflag = 0;
+  tcflush(fs, TCIFLUSH);
+  tcsetattr(fs, TCSANOW, &options);
+}
+
+void HAL_SetOSSerialBaudRate(HAL_SerialPort port, int32_t baud,
+                             int32_t* status) {
+  int baudRate = -1;
+  switch (baud) {
+    case 9600:
+      baudRate = B9600;
+      break;
+    case 19200:
+      baudRate = B19200;
+      break;
+    case 38400:
+      baudRate = B38400;
+      break;
+    case 57600:
+      baudRate = B57600;
+      break;
+    case 115200:
+      baudRate = B115200;
+      break;
+    default:
+      *status = PARAMETER_OUT_OF_RANGE;
+      return;
+  }
+
+  struct termios options;
+  tcgetattr(portHandles[port], &options);
+  auto set = cfsetospeed(&options, baudRate);
+  if (set != 0) {
+    *status = HAL_SERIAL_PORT_ERROR;
+    return;
+  }
+  set = tcsetattr(portHandles[port], TCSANOW, &options);
+  if (set != 0) {
+    *status = HAL_SERIAL_PORT_ERROR;
+    return;
+  }
+}
+
+void HAL_SetOSSerialDataBits(HAL_SerialPort port, int32_t bits,
+                             int32_t* status) {
+  int numBits = -1;
+  switch (bits) {
+    case 5:
+      numBits = CS5;
+      break;
+    case 6:
+      numBits = CS6;
+      break;
+    case 7:
+      numBits = CS7;
+      break;
+    case 8:
+      numBits = CS8;
+      break;
+    default:
+      *status = PARAMETER_OUT_OF_RANGE;
+      return;
+  }
+
+  struct termios options;
+  tcgetattr(portHandles[port], &options);
+  options.c_cflag &= ~CSIZE;
+  options.c_cflag |= numBits;
+  auto set = tcsetattr(portHandles[port], TCSANOW, &options);
+  if (set != 0) {
+    *status = HAL_SERIAL_PORT_ERROR;
+    return;
+  }
+}
+
+void HAL_SetOSSerialParity(HAL_SerialPort port, int32_t parity,
+                           int32_t* status) {
+  // Just set none parity
+  struct termios options;
+  tcgetattr(portHandles[port], &options);
+  options.c_cflag &= ~PARENB;
+  auto set = tcsetattr(portHandles[port], TCSANOW, &options);
+  if (set != 0) {
+    *status = HAL_SERIAL_PORT_ERROR;
+    return;
+  }
+}
+
+void HAL_SetOSSerialStopBits(HAL_SerialPort port, int32_t stopBits,
+                             int32_t* status) {
+  // Force 1 stop bit
+  struct termios options;
+  tcgetattr(portHandles[port], &options);
+  options.c_cflag &= ~CSTOPB;
+  auto set = tcsetattr(portHandles[port], TCSANOW, &options);
+  if (set != 0) {
+    *status = HAL_SERIAL_PORT_ERROR;
+    return;
+  }
+}
+
+void HAL_SetOSSerialWriteMode(HAL_SerialPort port, int32_t mode,
+                              int32_t* status) {
+  // No op
+}
+
+void HAL_SetOSSerialFlowControl(HAL_SerialPort port, int32_t flow,
+                                int32_t* status) {
+  // No op
+}
+
+void HAL_SetOSSerialTimeout(HAL_SerialPort port, double timeout,
+                            int32_t* status) {
+  // Convert to millis
+  int t = timeout / 1000;
+  portTimeouts[port] = std::chrono::milliseconds(t);
+}
+
+void HAL_EnableOSSerialTermination(HAL_SerialPort port, char terminator,
+                                   int32_t* status) {
+  // \n is hardcoded for now. Will fix later
+  // Seems like a VISA only setting, need to check
+}
+
+void HAL_DisableOSSerialTermination(HAL_SerialPort port, int32_t* status) {
+  // Seems like a VISA only setting, need to check
+}
+
+void HAL_SetOSSerialReadBufferSize(HAL_SerialPort port, int32_t size,
+                                   int32_t* status) {
+  // No op
+}
+
+void HAL_SetOSSerialWriteBufferSize(HAL_SerialPort port, int32_t size,
+                                    int32_t* status) {
+  // No op
+}
+
+int32_t HAL_GetOSSerialBytesReceived(HAL_SerialPort port, int32_t* status) {
+  int bytes = 0;
+  ioctl(portHandles[port], FIONREAD, &bytes);
+  return bytes;
+}
+
+int32_t HAL_ReadOSSerial(HAL_SerialPort port, char* buffer, int32_t count,
+                         int32_t* status) {
+  auto endTime = std::chrono::steady_clock::now() + portTimeouts[port];
+
+  int bytesRead = 0;
+
+  unsigned char buf[256];
+
+  do {
+    int rx = read(portHandles[port], buf, count - bytesRead);
+    std::memcpy(&buffer[bytesRead], buf, rx);
+    bytesRead += rx;
+    if (bytesRead >= count) break;
+    llvm::StringRef tmp(buffer, bytesRead);
+    auto loc = tmp.find('\n');
+    if (loc != llvm::StringRef::npos) {
+      bytesRead = loc;
+      break;
+    }
+  } while (std::chrono::steady_clock::now() < endTime);
+  return bytesRead;
+}
+
+int32_t HAL_WriteOSSerial(HAL_SerialPort port, const char* buffer,
+                          int32_t count, int32_t* status) {
+  return write(portHandles[port], buffer, count);
+}
+void HAL_FlushOSSerial(HAL_SerialPort port, int32_t* status) {
+  tcdrain(portHandles[port]);
+}
+void HAL_ClearOSSerial(HAL_SerialPort port, int32_t* status) {
+  tcflush(portHandles[port], TCIOFLUSH);
+}
+void HAL_CloseOSSerial(HAL_SerialPort port, int32_t* status) {
+  close(portHandles[port]);
+}
+
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/PCMInternal.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/PCMInternal.cpp
new file mode 100644
index 0000000..eedc611
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/PCMInternal.cpp
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "PCMInternal.h"
+
+#include "HAL/Errors.h"
+#include "HAL/Solenoid.h"
+#include "HAL/cpp/make_unique.h"
+#include "PortsInternal.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) {
+  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/third_party/allwpilib_2018/hal/src/main/native/athena/PCMInternal.h b/third_party/allwpilib_2018/hal/src/main/native/athena/PCMInternal.h
new file mode 100644
index 0000000..bbd29de
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/Errors.h"
+#include "HAL/Ports.h"
+#include "HAL/Solenoid.h"
+#include "PortsInternal.h"
+#include "ctre/PCM.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/third_party/allwpilib_2018/hal/src/main/native/athena/PDP.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/PDP.cpp
new file mode 100644
index 0000000..b0b0dd1
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/PDP.cpp
@@ -0,0 +1,137 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/Errors.h"
+#include "HAL/Ports.h"
+#include "HAL/cpp/make_unique.h"
+#include "PortsInternal.h"
+#include "ctre/PDP.h"
+
+using namespace hal;
+
+static std::unique_ptr<PDP> pdp[kNumPDPModules];
+
+static inline bool checkPDPInit(int32_t module, int32_t* status) {
+  if (!HAL_CheckPDPModule(module)) {
+    *status = RESOURCE_OUT_OF_RANGE;
+    return false;
+  }
+  if (!pdp[module]) {
+    *status = INCOMPATIBLE_STATE;
+    return false;
+  }
+  return true;
+}
+
+namespace hal {
+namespace init {
+void InitializePDP() {
+  for (int i = 0; i < kNumPDPModules; i++) {
+    pdp[i] = nullptr;
+  }
+}
+}  // namespace init
+}  // namespace hal
+
+extern "C" {
+
+void HAL_InitializePDP(int32_t module, int32_t* status) {
+  if (!HAL_CheckPDPModule(module)) {
+    *status = RESOURCE_OUT_OF_RANGE;
+    return;
+  }
+  if (!pdp[module]) {
+    pdp[module] = std::make_unique<PDP>(module);
+  }
+}
+
+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(int32_t module, int32_t* status) {
+  if (!checkPDPInit(module, status)) return 0;
+
+  double temperature;
+
+  *status = pdp[module]->GetTemperature(temperature);
+
+  return temperature;
+}
+
+double HAL_GetPDPVoltage(int32_t module, int32_t* status) {
+  if (!checkPDPInit(module, status)) return 0;
+
+  double voltage;
+
+  *status = pdp[module]->GetVoltage(voltage);
+
+  return voltage;
+}
+
+double HAL_GetPDPChannelCurrent(int32_t module, int32_t channel,
+                                int32_t* status) {
+  if (!checkPDPInit(module, status)) return 0;
+
+  double current;
+
+  *status = pdp[module]->GetChannelCurrent(channel, current);
+
+  return current;
+}
+
+double HAL_GetPDPTotalCurrent(int32_t module, int32_t* status) {
+  if (!checkPDPInit(module, status)) return 0;
+
+  double current;
+
+  *status = pdp[module]->GetTotalCurrent(current);
+
+  return current;
+}
+
+double HAL_GetPDPTotalPower(int32_t module, int32_t* status) {
+  if (!checkPDPInit(module, status)) return 0;
+
+  double power;
+
+  *status = pdp[module]->GetTotalPower(power);
+
+  return power;
+}
+
+double HAL_GetPDPTotalEnergy(int32_t module, int32_t* status) {
+  if (!checkPDPInit(module, status)) return 0;
+
+  double energy;
+
+  *status = pdp[module]->GetTotalEnergy(energy);
+
+  return energy;
+}
+
+void HAL_ResetPDPTotalEnergy(int32_t module, int32_t* status) {
+  if (!checkPDPInit(module, status)) return;
+
+  *status = pdp[module]->ResetEnergy();
+}
+
+void HAL_ClearPDPStickyFaults(int32_t module, int32_t* status) {
+  if (!checkPDPInit(module, status)) return;
+
+  *status = pdp[module]->ClearStickyFaults();
+}
+
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/PWM.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/PWM.cpp
new file mode 100644
index 0000000..05c58b4
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/PWM.cpp
@@ -0,0 +1,495 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "ConstantsInternal.h"
+#include "DigitalInternal.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "PortsInternal.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) {
+  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;
+
+  int32_t bitToSet = 1 << remapMXPPWMChannel(port->channel);
+  uint16_t specialFunctions =
+      digitalSystem->readEnableMXPSpecialFunction(status);
+  digitalSystem->writeEnableMXPSpecialFunction(specialFunctions | bitToSet,
+                                               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;
+  }
+
+  if (port->channel > tPWM::kNumHdrRegisters - 1) {
+    int32_t bitToUnset = 1 << remapMXPPWMChannel(port->channel);
+    uint16_t specialFunctions =
+        digitalSystem->readEnableMXPSpecialFunction(status);
+    digitalSystem->writeEnableMXPSpecialFunction(specialFunctions & ~bitToUnset,
+                                                 status);
+  }
+
+  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;
+}
+
+/**
+ * Set a PWM channel to the desired value. The values range from 0 to 255 and
+ * the period is controlled
+ * by the PWM Period and MinHigh registers.
+ *
+ * @param channel The PWM channel to set.
+ * @param value The PWM value to set.
+ */
+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);
+  }
+}
+
+/**
+ * Set 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 channel The PWM channel to set.
+ * @param value The scaled PWM value to set.
+ */
+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);
+}
+
+/**
+ * Set 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 channel The PWM channel to set.
+ * @param value The scaled PWM value to set.
+ */
+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);
+}
+
+/**
+ * Get a value from a PWM channel. The values range from 0 to 255.
+ *
+ * @param channel The PWM channel to read from.
+ * @return The raw PWM value.
+ */
+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);
+  }
+}
+
+/**
+ * Get a scaled value from a PWM channel. The values range from -1 to 1.
+ *
+ * @param channel The PWM channel to read from.
+ * @return The scaled PWM value.
+ */
+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;
+  }
+}
+
+/**
+ * Get a position value from a PWM channel. The values range from 0 to 1.
+ *
+ * @param channel The PWM channel to read from.
+ * @return The scaled PWM value.
+ */
+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);
+}
+
+/**
+ * Set how how often the PWM signal is squelched, thus scaling the period.
+ *
+ * @param channel The PWM channel to configure.
+ * @param squelchMask The 2-bit mask of outputs to squelch.
+ */
+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);
+  }
+}
+
+/**
+ * Get the loop timing of the PWM system
+ *
+ * @return The loop time
+ */
+int32_t HAL_GetPWMLoopTiming(int32_t* status) {
+  initializeDigital(status);
+  if (*status != 0) return 0;
+  return pwmSystem->readLoopTiming(status);
+}
+
+/**
+ * Get the pwm starting cycle time
+ *
+ * @return The pwm cycle start time.
+ */
+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/third_party/allwpilib_2018/hal/src/main/native/athena/Ports.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/Ports.cpp
new file mode 100644
index 0000000..e3b12e1
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/athena/PortsInternal.h b/third_party/allwpilib_2018/hal/src/main/native/athena/PortsInternal.h
new file mode 100644
index 0000000..6d562a6
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/athena/Power.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/Power.cpp
new file mode 100644
index 0000000..c5c4dd9
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/Power.cpp
@@ -0,0 +1,151 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/ChipObject.h"
+
+using namespace hal;
+
+namespace hal {
+
+static std::unique_ptr<tPower> power{nullptr};
+
+static void initializePower(int32_t* status) {
+  if (power == nullptr) {
+    power.reset(tPower::create(status));
+  }
+}
+
+}  // namespace hal
+
+namespace hal {
+namespace init {
+void InitializePower() {}
+}  // namespace init
+}  // namespace hal
+
+extern "C" {
+
+/**
+ * Get the roboRIO input voltage
+ */
+double HAL_GetVinVoltage(int32_t* status) {
+  initializePower(status);
+  return power->readVinVoltage(status) / 4.096 * 0.025733 - 0.029;
+}
+
+/**
+ * Get the roboRIO input current
+ */
+double HAL_GetVinCurrent(int32_t* status) {
+  initializePower(status);
+  return power->readVinCurrent(status) / 4.096 * 0.017042 - 0.071;
+}
+
+/**
+ * Get the 6V rail voltage
+ */
+double HAL_GetUserVoltage6V(int32_t* status) {
+  initializePower(status);
+  return power->readUserVoltage6V(status) / 4.096 * 0.007019 - 0.014;
+}
+
+/**
+ * Get the 6V rail current
+ */
+double HAL_GetUserCurrent6V(int32_t* status) {
+  initializePower(status);
+  return power->readUserCurrent6V(status) / 4.096 * 0.005566 - 0.009;
+}
+
+/**
+ * Get the active state of the 6V rail
+ */
+HAL_Bool HAL_GetUserActive6V(int32_t* status) {
+  initializePower(status);
+  return power->readStatus_User6V(status) == 4;
+}
+
+/**
+ * Get the fault count for the 6V rail
+ */
+int32_t HAL_GetUserCurrentFaults6V(int32_t* status) {
+  initializePower(status);
+  return static_cast<int32_t>(
+      power->readFaultCounts_OverCurrentFaultCount6V(status));
+}
+
+/**
+ * Get the 5V rail voltage
+ */
+double HAL_GetUserVoltage5V(int32_t* status) {
+  initializePower(status);
+  return power->readUserVoltage5V(status) / 4.096 * 0.005962 - 0.013;
+}
+
+/**
+ * Get the 5V rail current
+ */
+double HAL_GetUserCurrent5V(int32_t* status) {
+  initializePower(status);
+  return power->readUserCurrent5V(status) / 4.096 * 0.001996 - 0.002;
+}
+
+/**
+ * Get the active state of the 5V rail
+ */
+HAL_Bool HAL_GetUserActive5V(int32_t* status) {
+  initializePower(status);
+  return power->readStatus_User5V(status) == 4;
+}
+
+/**
+ * Get the fault count for the 5V rail
+ */
+int32_t HAL_GetUserCurrentFaults5V(int32_t* status) {
+  initializePower(status);
+  return static_cast<int32_t>(
+      power->readFaultCounts_OverCurrentFaultCount5V(status));
+}
+
+/**
+ * Get the 3.3V rail voltage
+ */
+double HAL_GetUserVoltage3V3(int32_t* status) {
+  initializePower(status);
+  return power->readUserVoltage3V3(status) / 4.096 * 0.004902 - 0.01;
+}
+
+/**
+ * Get the 3.3V rail current
+ */
+double HAL_GetUserCurrent3V3(int32_t* status) {
+  initializePower(status);
+  return power->readUserCurrent3V3(status) / 4.096 * 0.002486 - 0.003;
+}
+
+/**
+ * Get the active state of the 3.3V rail
+ */
+HAL_Bool HAL_GetUserActive3V3(int32_t* status) {
+  initializePower(status);
+  return power->readStatus_User3V3(status) == 4;
+}
+
+/**
+ * Get the fault count for the 3.3V rail
+ */
+int32_t HAL_GetUserCurrentFaults3V3(int32_t* status) {
+  initializePower(status);
+  return static_cast<int32_t>(
+      power->readFaultCounts_OverCurrentFaultCount3V3(status));
+}
+
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/Relay.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/Relay.cpp
new file mode 100644
index 0000000..886fbcf
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/Relay.cpp
@@ -0,0 +1,148 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/handles/IndexedHandleResource.h"
+#include "PortsInternal.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) {
+  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;
+}
+
+/**
+ * Set the state of a relay.
+ * Set the state of a relay output.
+ */
+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);
+  }
+}
+
+/**
+ * Get the current state of the relay channel
+ */
+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/third_party/allwpilib_2018/hal/src/main/native/athena/SPI.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/SPI.cpp
new file mode 100644
index 0000000..d8b2485
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/SPI.cpp
@@ -0,0 +1,717 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <llvm/raw_ostream.h>
+#include <support/mutex.h>
+
+#include "DigitalInternal.h"
+#include "HAL/DIO.h"
+#include "HAL/HAL.h"
+#include "HAL/cpp/make_unique.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]);
+  }
+}
+
+/*
+ * Initialize 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) {
+  if (port < 0 || port >= kSpiMaxHandles) {
+    *status = PARAMETER_OUT_OF_RANGE;
+    return;
+  }
+
+  int handle;
+  if (HAL_GetSPIHandle(port) != 0) return;
+  switch (port) {
+    case 0:
+      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 1:
+      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 2:
+      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 3:
+      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 4:
+      initializeDigital(status);
+      if (*status != 0) return;
+      if ((digitalHandles[5] = HAL_InitializeDIOPort(createPortHandleForSPI(14),
+                                                     false, status)) ==
+          HAL_kInvalidHandle) {
+        llvm::outs() << "Failed to allocate DIO 14\n";
+        return;
+      }
+      if ((digitalHandles[6] = HAL_InitializeDIOPort(createPortHandleForSPI(15),
+                                                     false, status)) ==
+          HAL_kInvalidHandle) {
+        llvm::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) {
+        llvm::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) {
+        llvm::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;
+  }
+}
+
+/**
+ * Generic 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) {
+  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);
+}
+
+/**
+ * Execute a write transaction with the device.
+ *
+ * Write 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) {
+  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);
+}
+
+/**
+ * Execute 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) {
+  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);
+}
+
+/**
+ * Close 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) {
+  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;
+  }
+}
+
+/**
+ * Set 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) {
+  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);
+}
+
+/**
+ * Set 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) {
+  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);
+}
+
+/**
+ * Set 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) {
+  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);
+  }
+}
+
+/**
+ * Set 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) {
+  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);
+  }
+}
+
+/**
+ * Get 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) {
+  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;
+  }
+}
+
+/**
+ * Set 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) {
+  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, uint8_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/third_party/allwpilib_2018/hal/src/main/native/athena/SerialPort.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/SerialPort.cpp
new file mode 100644
index 0000000..3867999
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/SerialPort.cpp
@@ -0,0 +1,165 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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) {
+  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_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/third_party/allwpilib_2018/hal/src/main/native/athena/Solenoid.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/Solenoid.cpp
new file mode 100644
index 0000000..1787b76
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/Solenoid.cpp
@@ -0,0 +1,189 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/ChipObject.h"
+#include "HAL/Errors.h"
+#include "HAL/Ports.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "HAL/handles/IndexedHandleResource.h"
+#include "PCMInternal.h"
+#include "PortsInternal.h"
+#include "ctre/PCM.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) {
+  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/third_party/allwpilib_2018/hal/src/main/native/athena/Threads.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/Threads.cpp
new file mode 100644
index 0000000..9bfb099
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/Threads.cpp
@@ -0,0 +1,130 @@
+/*----------------------------------------------------------------------------*/
+/* 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" {
+
+/**
+ * Get 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) {
+  sched_param sch;
+  int policy;
+  int success = pthread_getschedparam(*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;
+  }
+}
+
+/**
+ * Get 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) {
+  auto thread = pthread_self();
+  return HAL_GetThreadPriority(&thread, isRealTime, 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) {
+  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(*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(*handle, scheduler, &sch)) {
+    *status = HAL_THREAD_PRIORITY_ERROR;
+    return false;
+  } else {
+    *status = 0;
+    return true;
+  }
+}
+
+/**
+ * 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) {
+  auto thread = pthread_self();
+  return HAL_SetThreadPriority(&thread, realTime, priority, status);
+}
+
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/cpp/SerialHelper.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/cpp/SerialHelper.cpp
new file mode 100644
index 0000000..c990c33
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/cpp/SerialHelper.cpp
@@ -0,0 +1,331 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <llvm/FileSystem.h>
+#include <llvm/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 llvm::SmallVectorImpl<char>& lhs,
+               const llvm::SmallVectorImpl<char>& rhs) -> int {
+              llvm::StringRef lhsRef(lhs.begin(), lhs.size());
+              llvm::StringRef rhsRef(rhs.begin(), rhs.size());
+              return lhsRef.compare(rhsRef);
+            });
+}
+
+void SerialHelper::CoiteratedSort(
+    llvm::SmallVectorImpl<llvm::SmallString<16>>& vec) {
+  llvm::SmallVector<llvm::SmallString<16>, 4> sortedVec;
+  for (auto& str : m_sortedHubPath) {
+    for (size_t i = 0; i < m_unsortedHubPath.size(); i++) {
+      if (llvm::StringRef{m_unsortedHubPath[i].begin(),
+                          m_unsortedHubPath[i].size()}
+              .equals(llvm::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/
+    llvm::StringRef devNameRef = llvm::StringRef{osName}.split("(/dev/").second;
+    // String not found, continue
+    if (devNameRef.equals("")) continue;
+
+    // Split at )
+    llvm::StringRef matchString = devNameRef.split(')').first;
+    if (matchString.equals(devNameRef)) continue;
+
+    // Search directories to get a list of system accessors
+    std::error_code ec;
+    for (auto p = llvm::sys::fs::recursive_directory_iterator(
+             "/sys/devices/soc0", ec);
+         p != llvm::sys::fs::recursive_directory_iterator(); p.increment(ec)) {
+      if (ec) break;
+      llvm::StringRef path{p->path()};
+      if (path.find("amba") == llvm::StringRef::npos) continue;
+      if (path.find("usb") == llvm::StringRef::npos) continue;
+      if (path.find(matchString) == llvm::StringRef::npos) continue;
+
+      llvm::SmallVector<llvm::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(
+          llvm::StringRef{pathSplitVec[hubIndex - 2]});
+      m_visaResource.emplace_back(desc);
+      m_osResource.emplace_back(
+          llvm::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];
+
+  llvm::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/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/CtreCanNode.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/CtreCanNode.cpp
new file mode 100644
index 0000000..8772a47
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/CtreCanNode.cpp
@@ -0,0 +1,163 @@
+#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);

+	}

+}

+timespec diff(const timespec & start, const timespec & end)

+{

+	timespec temp;

+	if ((end.tv_nsec-start.tv_nsec)<0) {

+		temp.tv_sec = end.tv_sec-start.tv_sec-1;

+		temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;

+	} else {

+		temp.tv_sec = end.tv_sec-start.tv_sec;

+		temp.tv_nsec = end.tv_nsec-start.tv_nsec;

+	}

+	return temp;

+}

+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);

+	if(status == 0){

+		/* fresh update */

+		rxEvent_t & r = _rxRxEvents[arbId]; /* lookup entry or make a default new one with all zeroes */

+		clock_gettime(2,&r.time); 			/* fill in time */

+		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 */

+			struct timespec temp;

+			clock_gettime(2,&temp); /* get now */

+			/* how long has it been? */

+			temp = diff(i->second.time,temp); /* temp = now - last */

+			if(temp.tv_sec > 0){

+				retval = CTR_RxTimeout;

+			}else if(temp.tv_nsec > ((int32_t)timeoutMs*1000*1000)){

+				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/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/CtreCanNode.h b/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/CtreCanNode.h
new file mode 100644
index 0000000..2707598
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/CtreCanNode.h
@@ -0,0 +1,131 @@
+#ifndef CtreCanNode_H_

+#define CtreCanNode_H_

+#include "ctre.h"				//BIT Defines + Typedefs

+#include <map>

+#include <string.h> // memcpy

+#include <sys/time.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];

+			struct timespec 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;

+};

+#endif

diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/PCM.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/PCM.cpp
new file mode 100644
index 0000000..0839408
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/PCM.h b/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/PCM.h
new file mode 100644
index 0000000..03d9b2d
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/PDP.cpp b/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/PDP.cpp
new file mode 100644
index 0000000..61c6edb
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/PDP.cpp
@@ -0,0 +1,230 @@
+#include "PDP.h"

+#include "FRC_NetworkCommunication/CANSessionMux.h"	//CAN Comm

+#include <string.h> // memset

+

+#define STATUS_1  		0x8041400

+#define STATUS_2  		0x8041440

+#define STATUS_3  		0x8041480

+#define STATUS_ENERGY	0x8041740

+

+#define CONTROL_1		0x08041C00	/* PDP_Control_ClearStats */

+

+#define EXPECTED_RESPONSE_TIMEOUT_MS	(50)

+#define GET_STATUS1()		CtreCanNode::recMsg<PdpStatus1_t> rx = GetRx<PdpStatus1_t>(STATUS_1|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)

+#define GET_STATUS2()		CtreCanNode::recMsg<PdpStatus2_t> rx = GetRx<PdpStatus2_t>(STATUS_2|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)

+#define GET_STATUS3()		CtreCanNode::recMsg<PdpStatus3_t> rx = GetRx<PdpStatus3_t>(STATUS_3|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)

+#define GET_STATUS_ENERGY()	CtreCanNode::recMsg<PDP_Status_Energy_t> rx = GetRx<PDP_Status_Energy_t>(STATUS_ENERGY|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)

+

+/* encoder/decoders */

+typedef struct _PdpStatus1_t{

+	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;

+}PdpStatus1_t;

+typedef struct _PdpStatus2_t{

+	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;

+}PdpStatus2_t;

+typedef struct _PdpStatus3_t{

+	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;

+}PdpStatus3_t;

+typedef struct _PDP_Status_Energy_t {

+	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;

+} PDP_Status_Energy_t ;

+

+PDP::PDP(UINT8 deviceNumber): CtreCanNode(deviceNumber)

+{

+	RegisterRx(STATUS_1 | deviceNumber );

+	RegisterRx(STATUS_2 | deviceNumber );

+	RegisterRx(STATUS_3 | deviceNumber );

+}

+/* PDP D'tor

+ */

+PDP::~PDP()

+{

+}

+

+CTR_Code PDP::GetChannelCurrent(UINT8 idx, double &current)

+{

+	CTR_Code retval = CTR_InvalidParamValue;

+	uint32_t raw = 0;

+

+	if(idx <= 5){

+		GET_STATUS1();

+	    retval = rx.err;

+		switch(idx){

+			case 0:	raw = ((uint32_t)rx->chan1_h8 << 2) | rx->chan1_l2;	break;

+			case 1:	raw = ((uint32_t)rx->chan2_h6 << 4) | rx->chan2_l4;	break;

+			case 2:	raw = ((uint32_t)rx->chan3_h4 << 6) | rx->chan3_l6;	break;

+			case 3:	raw = ((uint32_t)rx->chan4_h2 << 8) | rx->chan4_l8;	break;

+			case 4:	raw = ((uint32_t)rx->chan5_h8 << 2) | rx->chan5_l2;	break;

+			case 5:	raw = ((uint32_t)rx->chan6_h6 << 4) | rx->chan6_l4;	break;

+			default:	retval = CTR_InvalidParamValue;	break;

+		}

+	}else if(idx <= 11){

+		GET_STATUS2();

+	    retval = rx.err;

+		switch(idx){

+			case  6:	raw = ((uint32_t)rx->chan7_h8  << 2) | rx->chan7_l2;	break;

+			case  7:	raw = ((uint32_t)rx->chan8_h6  << 4) | rx->chan8_l4;	break;

+			case  8:	raw = ((uint32_t)rx->chan9_h4  << 6) | rx->chan9_l6;	break;

+			case  9:	raw = ((uint32_t)rx->chan10_h2 << 8) | rx->chan10_l8;	break;

+			case 10:	raw = ((uint32_t)rx->chan11_h8 << 2) | rx->chan11_l2;	break;

+			case 11:	raw = ((uint32_t)rx->chan12_h6 << 4) | rx->chan12_l4;	break;

+			default:	retval = CTR_InvalidParamValue;	break;

+		}

+	}else if(idx <= 15){

+		GET_STATUS3();

+	    retval = rx.err;

+		switch(idx){

+			case 12:	raw = ((uint32_t)rx->chan13_h8  << 2) | rx->chan13_l2;	break;

+			case 13:	raw = ((uint32_t)rx->chan14_h6  << 4) | rx->chan14_l4;	break;

+			case 14:	raw = ((uint32_t)rx->chan15_h4  << 6) | rx->chan15_l6;	break;

+			case 15:	raw = ((uint32_t)rx->chan16_h2  << 8) | rx->chan16_l8;	break;

+			default:	retval = CTR_InvalidParamValue;	break;

+		}

+	}

+	/* convert to amps */

+	current = (double)raw * 0.125;  /* 7.3 fixed pt value in Amps */

+	/* signal caller with success */

+	return retval;

+}

+CTR_Code PDP::GetVoltage(double &voltage)

+{

+	GET_STATUS3();

+	uint32_t raw = rx->busVoltage;

+	voltage = (double)raw * 0.05 + 4.0; /* 50mV per unit plus 4V. */;

+	return rx.err;

+}

+CTR_Code PDP::GetTemperature(double &tempC)

+{

+	GET_STATUS3();

+	uint32_t raw = rx->temp;

+	tempC =	(double)raw * 1.03250836957542 - 67.8564500484966;

+	return rx.err;

+}

+CTR_Code PDP::GetTotalCurrent(double &currentAmps)

+{

+	GET_STATUS_ENERGY();

+	uint32_t raw;

+	raw = rx->TotalCurrent_125mAperunit_h8;

+	raw <<= 4;

+	raw |=  rx->TotalCurrent_125mAperunit_l4;

+	currentAmps = 0.125 * raw;

+	return rx.err;

+}

+CTR_Code PDP::GetTotalPower(double &powerWatts)

+{

+	GET_STATUS_ENERGY();

+	uint32_t raw;

+	raw = rx->Power_125mWperunit_h4;

+	raw <<= 8;

+	raw |=  rx->Power_125mWperunit_m8;

+	raw <<= 4;

+	raw |=  rx->Power_125mWperunit_l4;

+	powerWatts = 0.125 * raw;

+	return rx.err;

+}

+CTR_Code PDP::GetTotalEnergy(double &energyJoules)

+{

+	GET_STATUS_ENERGY();

+	uint32_t raw;

+	raw = rx->Energy_125mWPerUnitXTmeas_h4;

+	raw <<= 8;

+	raw |=  rx->Energy_125mWPerUnitXTmeas_mh8;

+	raw <<= 8;

+	raw |=  rx->Energy_125mWPerUnitXTmeas_ml8;

+	raw <<= 8;

+	raw |=  rx->Energy_125mWPerUnitXTmeas_l8;

+	energyJoules = 0.125 * raw; 						/* mW integrated every TmeasMs */

+	energyJoules *= 0.001;								/* convert from mW to W */

+	energyJoules *= rx->TmeasMs_likelywillbe20ms_;		/* multiplied by TmeasMs = joules */

+	return rx.err;

+}

+/* Clear sticky faults.

+ * @Return	-	CTR_Code	-	Error code (if any)

+ */

+CTR_Code PDP::ClearStickyFaults()

+{

+	int32_t status = 0;

+	uint8_t pdpControl[] = { 0x80 }; /* only bit set is ClearStickyFaults */

+	FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_1  | GetDeviceNumber(), pdpControl, sizeof(pdpControl), 0, &status);

+	if(status)

+		return CTR_TxFailed;

+	return CTR_OKAY;

+}

+

+/* Reset Energy Signals

+ * @Return	-	CTR_Code	-	Error code (if any)

+ */

+CTR_Code PDP::ResetEnergy()

+{

+	int32_t status = 0;

+	uint8_t pdpControl[] = { 0x40 }; /* only bit set is ResetEnergy */

+	FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_1  | GetDeviceNumber(), pdpControl, sizeof(pdpControl), 0, &status);

+	if(status)

+		return CTR_TxFailed;

+	return CTR_OKAY;

+}

+//------------------ C interface --------------------------------------------//

+extern "C" {

+	void * c_PDP_Init(void)

+	{

+		return new PDP();

+	}

+	CTR_Code c_GetChannelCurrent(void * handle,UINT8 idx, double *status)

+	{

+		return ((PDP*)handle)-> GetChannelCurrent(idx,*status);

+	}

+	CTR_Code c_GetVoltage(void * handle,double *status)

+	{

+		return ((PDP*)handle)-> GetVoltage(*status);

+	}

+	CTR_Code c_GetTemperature(void * handle,double *status)

+	{

+		return ((PDP*)handle)-> GetTemperature(*status);

+	}

+	void c_SetDeviceNumber_PDP(void * handle,UINT8 deviceNumber)

+	{

+	}

+}

diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/PDP.h b/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/PDP.h
new file mode 100644
index 0000000..b968a44
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/PDP.h
@@ -0,0 +1,62 @@
+#ifndef PDP_H_

+#define PDP_H_

+#include "ctre.h"				//BIT Defines + Typedefs

+#include "CtreCanNode.h"

+class PDP : public CtreCanNode

+{

+public:

+    /* Get PDP Channel Current

+     *

+     * @Param	-	deviceNumber	-	Device ID for PDP. Factory default is 60. Function defaults to 60.

+     */

+    PDP(UINT8 deviceNumber=0);

+    ~PDP();

+    /* Get PDP Channel Current

+     *

+     * @Return	-	CTR_Code	-	Error code (if any)

+     *

+     * @Param	-	idx			-	ID of channel to return current for (channels 1-16)

+     *

+     * @Param	-	status		-	Current of channel 'idx' in Amps (A)

+     */

+    CTR_Code GetChannelCurrent(UINT8 idx, double &status);

+

+    /* Get Bus Voltage of PDP

+     *

+     * @Return	-	CTR_Code	- 	Error code (if any)

+     *

+     * @Param	-	status		- 	Voltage (V) across PDP

+     */

+    CTR_Code GetVoltage(double &status);

+

+    /* Get Temperature of PDP

+     *

+     * @Return	-	CTR_Code	-	Error code (if any)

+     *

+     * @Param	-	status		-	Temperature of PDP in Centigrade / Celcius (C)

+     */

+    CTR_Code GetTemperature(double &status);

+

+	CTR_Code GetTotalCurrent(double &currentAmps);

+	CTR_Code GetTotalPower(double &powerWatts);

+	CTR_Code GetTotalEnergy(double &energyJoules);

+    /* Clear sticky faults.

+     * @Return	-	CTR_Code	-	Error code (if any)

+     */

+	CTR_Code ClearStickyFaults();

+

+	/* Reset Energy Signals

+	 * @Return	-	CTR_Code	-	Error code (if any)

+	 */

+	CTR_Code ResetEnergy();

+private:

+    uint64_t ReadCurrents(uint8_t api);

+};

+extern "C" {

+	void * c_PDP_Init();

+	CTR_Code c_GetChannelCurrent(void * handle,UINT8 idx, double *status);

+	CTR_Code c_GetVoltage(void * handle,double *status);

+	CTR_Code c_GetTemperature(void * handle,double *status);

+	void c_SetDeviceNumber_PDP(void * handle,UINT8 deviceNumber);

+}

+#endif /* PDP_H_ */

diff --git a/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/ctre.h b/third_party/allwpilib_2018/hal/src/main/native/athena/ctre/ctre.h
new file mode 100644
index 0000000..89c5c4d
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/athena/frccansae/CANDeviceInterface.h b/third_party/allwpilib_2018/hal/src/main/native/athena/frccansae/CANDeviceInterface.h
new file mode 100644
index 0000000..62a38cb
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/athena/visa/visa.h b/third_party/allwpilib_2018/hal/src/main/native/athena/visa/visa.h
new file mode 100644
index 0000000..3c6ad30
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/athena/visa/visatype.h b/third_party/allwpilib_2018/hal/src/main/native/athena/visa/visatype.h
new file mode 100644
index 0000000..ef089dd
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Accelerometer.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Accelerometer.h
new file mode 100644
index 0000000..33c0bc4
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Accelerometer.h
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+enum HAL_AccelerometerRange : int32_t {
+  HAL_AccelerometerRange_k2G = 0,
+  HAL_AccelerometerRange_k4G = 1,
+  HAL_AccelerometerRange_k8G = 2,
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void HAL_SetAccelerometerActive(HAL_Bool active);
+void HAL_SetAccelerometerRange(HAL_AccelerometerRange range);
+double HAL_GetAccelerometerX(void);
+double HAL_GetAccelerometerY(void);
+double HAL_GetAccelerometerZ(void);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogAccumulator.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogAccumulator.h
new file mode 100644
index 0000000..bb5108d
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogAccumulator.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 "HAL/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HAL_Bool HAL_IsAccumulatorChannel(HAL_AnalogInputHandle analogPortHandle,
+                                  int32_t* status);
+void HAL_InitAccumulator(HAL_AnalogInputHandle analogPortHandle,
+                         int32_t* status);
+void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
+                          int32_t* status);
+void HAL_SetAccumulatorCenter(HAL_AnalogInputHandle analogPortHandle,
+                              int32_t center, int32_t* status);
+void HAL_SetAccumulatorDeadband(HAL_AnalogInputHandle analogPortHandle,
+                                int32_t deadband, int32_t* status);
+int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
+                                int32_t* status);
+int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
+                                int32_t* status);
+void HAL_GetAccumulatorOutput(HAL_AnalogInputHandle analogPortHandle,
+                              int64_t* value, int64_t* count, int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogGyro.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogGyro.h
new file mode 100644
index 0000000..94b47fd
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogGyro.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 "HAL/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HAL_GyroHandle HAL_InitializeAnalogGyro(HAL_AnalogInputHandle handle,
+                                        int32_t* status);
+void HAL_SetupAnalogGyro(HAL_GyroHandle handle, int32_t* status);
+void HAL_FreeAnalogGyro(HAL_GyroHandle handle);
+void HAL_SetAnalogGyroParameters(HAL_GyroHandle handle,
+                                 double voltsPerDegreePerSecond, double offset,
+                                 int32_t center, int32_t* status);
+void HAL_SetAnalogGyroVoltsPerDegreePerSecond(HAL_GyroHandle handle,
+                                              double voltsPerDegreePerSecond,
+                                              int32_t* status);
+void HAL_ResetAnalogGyro(HAL_GyroHandle handle, int32_t* status);
+void HAL_CalibrateAnalogGyro(HAL_GyroHandle handle, int32_t* status);
+void HAL_SetAnalogGyroDeadband(HAL_GyroHandle handle, double volts,
+                               int32_t* status);
+double HAL_GetAnalogGyroAngle(HAL_GyroHandle handle, int32_t* status);
+double HAL_GetAnalogGyroRate(HAL_GyroHandle handle, int32_t* status);
+double HAL_GetAnalogGyroOffset(HAL_GyroHandle handle, int32_t* status);
+int32_t HAL_GetAnalogGyroCenter(HAL_GyroHandle handle, int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogInput.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogInput.h
new file mode 100644
index 0000000..e496bc2
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogInput.h
@@ -0,0 +1,50 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
+                                                    int32_t* status);
+void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analogPortHandle);
+HAL_Bool HAL_CheckAnalogModule(int32_t module);
+HAL_Bool HAL_CheckAnalogInputChannel(int32_t channel);
+
+void HAL_SetAnalogSampleRate(double samplesPerSecond, int32_t* status);
+double HAL_GetAnalogSampleRate(int32_t* status);
+void HAL_SetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
+                              int32_t bits, int32_t* status);
+int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
+                                 int32_t* status);
+void HAL_SetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
+                                 int32_t bits, int32_t* status);
+int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
+                                    int32_t* status);
+int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
+                           int32_t* status);
+int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
+                                  int32_t* status);
+int32_t HAL_GetAnalogVoltsToValue(HAL_AnalogInputHandle analogPortHandle,
+                                  double voltage, int32_t* status);
+double HAL_GetAnalogVoltage(HAL_AnalogInputHandle analogPortHandle,
+                            int32_t* status);
+double HAL_GetAnalogAverageVoltage(HAL_AnalogInputHandle analogPortHandle,
+                                   int32_t* status);
+int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
+                               int32_t* status);
+int32_t HAL_GetAnalogOffset(HAL_AnalogInputHandle analogPortHandle,
+                            int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogOutput.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogOutput.h
new file mode 100644
index 0000000..3cfd4ec
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogOutput.h
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
+                                                      int32_t* status);
+void HAL_FreeAnalogOutputPort(HAL_AnalogOutputHandle analogOutputHandle);
+void HAL_SetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
+                         double voltage, int32_t* status);
+double HAL_GetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
+                           int32_t* status);
+HAL_Bool HAL_CheckAnalogOutputChannel(int32_t channel);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogTrigger.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogTrigger.h
new file mode 100644
index 0000000..53aab00
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/AnalogTrigger.h
@@ -0,0 +1,47 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+enum HAL_AnalogTriggerType : int32_t {
+  HAL_Trigger_kInWindow = 0,
+  HAL_Trigger_kState = 1,
+  HAL_Trigger_kRisingPulse = 2,
+  HAL_Trigger_kFallingPulse = 3
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+HAL_AnalogTriggerHandle HAL_InitializeAnalogTrigger(
+    HAL_AnalogInputHandle portHandle, int32_t* index, int32_t* status);
+void HAL_CleanAnalogTrigger(HAL_AnalogTriggerHandle analogTriggerHandle,
+                            int32_t* status);
+void HAL_SetAnalogTriggerLimitsRaw(HAL_AnalogTriggerHandle analogTriggerHandle,
+                                   int32_t lower, int32_t upper,
+                                   int32_t* status);
+void HAL_SetAnalogTriggerLimitsVoltage(
+    HAL_AnalogTriggerHandle analogTriggerHandle, double lower, double upper,
+    int32_t* status);
+void HAL_SetAnalogTriggerAveraged(HAL_AnalogTriggerHandle analogTriggerHandle,
+                                  HAL_Bool useAveragedValue, int32_t* status);
+void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
+                                  HAL_Bool useFilteredValue, int32_t* status);
+HAL_Bool HAL_GetAnalogTriggerInWindow(
+    HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status);
+HAL_Bool HAL_GetAnalogTriggerTriggerState(
+    HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status);
+HAL_Bool HAL_GetAnalogTriggerOutput(HAL_AnalogTriggerHandle analogTriggerHandle,
+                                    HAL_AnalogTriggerType type,
+                                    int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/CAN.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/CAN.h
new file mode 100644
index 0000000..16a1577
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/CAN.h
@@ -0,0 +1,60 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+// 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
+
+struct HAL_CANStreamMessage {
+  uint32_t messageID;
+  uint32_t timeStamp;
+  uint8_t data[8];
+  uint8_t dataSize;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HAL_CAN_SendMessage(uint32_t messageID, const uint8_t* data,
+                         uint8_t dataSize, int32_t periodMs, int32_t* status);
+void HAL_CAN_ReceiveMessage(uint32_t* messageID, uint32_t messageIDMask,
+                            uint8_t* data, uint8_t* dataSize,
+                            uint32_t* timeStamp, int32_t* status);
+void HAL_CAN_OpenStreamSession(uint32_t* sessionHandle, uint32_t messageID,
+                               uint32_t messageIDMask, uint32_t maxMessages,
+                               int32_t* status);
+void HAL_CAN_CloseStreamSession(uint32_t sessionHandle);
+void HAL_CAN_ReadStreamSession(uint32_t sessionHandle,
+                               struct HAL_CANStreamMessage* messages,
+                               uint32_t messagesToRead, uint32_t* messagesRead,
+                               int32_t* status);
+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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/ChipObject.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/ChipObject.h
new file mode 100644
index 0000000..878595b
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Compressor.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Compressor.h
new file mode 100644
index 0000000..5c7e57f
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Compressor.h
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <stdint.h>
+
+#include "HAL/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HAL_CompressorHandle HAL_InitializeCompressor(int32_t module, int32_t* status);
+HAL_Bool HAL_CheckCompressorModule(int32_t module);
+
+HAL_Bool HAL_GetCompressor(HAL_CompressorHandle compressorHandle,
+                           int32_t* status);
+
+void HAL_SetCompressorClosedLoopControl(HAL_CompressorHandle compressorHandle,
+                                        HAL_Bool value, int32_t* status);
+HAL_Bool HAL_GetCompressorClosedLoopControl(
+    HAL_CompressorHandle compressorHandle, int32_t* status);
+
+HAL_Bool HAL_GetCompressorPressureSwitch(HAL_CompressorHandle compressorHandle,
+                                         int32_t* status);
+double HAL_GetCompressorCurrent(HAL_CompressorHandle compressorHandle,
+                                int32_t* status);
+
+HAL_Bool HAL_GetCompressorCurrentTooHighFault(
+    HAL_CompressorHandle compressorHandle, int32_t* status);
+HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault(
+    HAL_CompressorHandle compressorHandle, int32_t* status);
+HAL_Bool HAL_GetCompressorShortedStickyFault(
+    HAL_CompressorHandle compressorHandle, int32_t* status);
+HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressorHandle,
+                                       int32_t* status);
+HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
+    HAL_CompressorHandle compressorHandle, int32_t* status);
+HAL_Bool HAL_GetCompressorNotConnectedFault(
+    HAL_CompressorHandle compressorHandle, int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Constants.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Constants.h
new file mode 100644
index 0000000..60c72f6
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Constants.h
@@ -0,0 +1,19 @@
+/*----------------------------------------------------------------------------*/
+/* 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>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int32_t HAL_GetSystemClockTicksPerMicrosecond(void);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Counter.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Counter.h
new file mode 100644
index 0000000..cee8dbb
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Counter.h
@@ -0,0 +1,73 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+enum HAL_Counter_Mode : int32_t {
+  HAL_Counter_kTwoPulse = 0,
+  HAL_Counter_kSemiperiod = 1,
+  HAL_Counter_kPulseLength = 2,
+  HAL_Counter_kExternalDirection = 3
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index,
+                                        int32_t* status);
+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);
+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);
+double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status);
+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);
+HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
+                                 int32_t* status);
+void HAL_SetCounterReverseDirection(HAL_CounterHandle counterHandle,
+                                    HAL_Bool reverseDirection, int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/DIO.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/DIO.h
new file mode 100644
index 0000000..26ce1c7
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/DIO.h
@@ -0,0 +1,47 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
+                                        HAL_Bool input, int32_t* status);
+HAL_Bool HAL_CheckDIOChannel(int32_t channel);
+void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle);
+HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status);
+void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status);
+void HAL_SetDigitalPWMRate(double rate, int32_t* status);
+void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
+                                double dutyCycle, int32_t* status);
+void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
+                                    int32_t channel, int32_t* status);
+void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
+                int32_t* status);
+void HAL_SetDIODirection(HAL_DigitalHandle dioPortHandle, HAL_Bool input,
+                         int32_t* status);
+HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status);
+HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status);
+void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
+               int32_t* status);
+HAL_Bool HAL_IsPulsing(HAL_DigitalHandle dioPortHandle, int32_t* status);
+HAL_Bool HAL_IsAnyPulsing(int32_t* status);
+
+void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
+                         int32_t* status);
+int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status);
+void HAL_SetFilterPeriod(int32_t filterIndex, int64_t value, int32_t* status);
+int64_t HAL_GetFilterPeriod(int32_t filterIndex, int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/DriverStation.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/DriverStation.h
new file mode 100644
index 0000000..427afc6
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/DriverStation.h
@@ -0,0 +1,143 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <cstddef>
+
+#include "HAL/Types.h"
+
+#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;
+};
+
+enum HAL_AllianceStationID : int32_t {
+  HAL_AllianceStationID_kRed1,
+  HAL_AllianceStationID_kRed2,
+  HAL_AllianceStationID_kRed3,
+  HAL_AllianceStationID_kBlue1,
+  HAL_AllianceStationID_kBlue2,
+  HAL_AllianceStationID_kBlue3,
+};
+
+enum HAL_MatchType {
+  HAL_kMatchType_none,
+  HAL_kMatchType_practice,
+  HAL_kMatchType_qualification,
+  HAL_kMatchType_elimination,
+};
+
+/* 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
+
+struct HAL_JoystickAxes {
+  int16_t count;
+  float axes[HAL_kMaxJoystickAxes];
+};
+
+struct HAL_JoystickPOVs {
+  int16_t count;
+  int16_t povs[HAL_kMaxJoystickPOVs];
+};
+
+struct HAL_JoystickButtons {
+  uint32_t buttons;
+  uint8_t count;
+};
+
+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;
+};
+
+struct HAL_MatchInfo {
+  char* eventName;
+  HAL_MatchType matchType;
+  uint16_t matchNumber;
+  uint8_t replayNumber;
+  char* gameSpecificMessage;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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);
+
+int32_t HAL_GetControlWord(HAL_ControlWord* controlWord);
+HAL_AllianceStationID HAL_GetAllianceStation(int32_t* status);
+int32_t HAL_GetJoystickAxes(int32_t joystickNum, HAL_JoystickAxes* axes);
+int32_t HAL_GetJoystickPOVs(int32_t joystickNum, HAL_JoystickPOVs* povs);
+int32_t HAL_GetJoystickButtons(int32_t joystickNum,
+                               HAL_JoystickButtons* buttons);
+int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
+                                  HAL_JoystickDescriptor* desc);
+HAL_Bool HAL_GetJoystickIsXbox(int32_t joystickNum);
+int32_t HAL_GetJoystickType(int32_t joystickNum);
+char* HAL_GetJoystickName(int32_t joystickNum);
+void HAL_FreeJoystickName(char* name);
+int32_t HAL_GetJoystickAxisType(int32_t joystickNum, int32_t axis);
+int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
+                               int32_t leftRumble, int32_t rightRumble);
+double HAL_GetMatchTime(int32_t* status);
+
+int HAL_GetMatchInfo(HAL_MatchInfo* info);
+void HAL_FreeMatchInfo(HAL_MatchInfo* info);
+
+#ifndef HAL_USE_LABVIEW
+
+void HAL_ReleaseDSMutex(void);
+bool HAL_IsNewControlData(void);
+void HAL_WaitForDSData(void);
+HAL_Bool HAL_WaitForDSDataTimeout(double timeout);
+void HAL_InitializeDriverStation(void);
+
+void HAL_ObserveUserProgramStarting(void);
+void HAL_ObserveUserProgramDisabled(void);
+void HAL_ObserveUserProgramAutonomous(void);
+void HAL_ObserveUserProgramTeleop(void);
+void HAL_ObserveUserProgramTest(void);
+
+#endif  // HAL_USE_LABVIEW
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Encoder.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Encoder.h
new file mode 100644
index 0000000..d26e160
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Encoder.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 <stdint.h>
+
+#include "HAL/AnalogTrigger.h"
+#include "HAL/Types.h"
+
+enum HAL_EncoderIndexingType : int32_t {
+  HAL_kResetWhileHigh,
+  HAL_kResetWhileLow,
+  HAL_kResetOnFallingEdge,
+  HAL_kResetOnRisingEdge
+};
+enum HAL_EncoderEncodingType : int32_t {
+  HAL_Encoder_k1X,
+  HAL_Encoder_k2X,
+  HAL_Encoder_k4X
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+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);
+void HAL_FreeEncoder(HAL_EncoderHandle encoderHandle, int32_t* status);
+int32_t HAL_GetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status);
+int32_t HAL_GetEncoderRaw(HAL_EncoderHandle encoderHandle, int32_t* status);
+int32_t HAL_GetEncoderEncodingScale(HAL_EncoderHandle encoderHandle,
+                                    int32_t* status);
+void HAL_ResetEncoder(HAL_EncoderHandle encoderHandle, int32_t* status);
+double HAL_GetEncoderPeriod(HAL_EncoderHandle encoderHandle, int32_t* status);
+void HAL_SetEncoderMaxPeriod(HAL_EncoderHandle encoderHandle, double maxPeriod,
+                             int32_t* status);
+HAL_Bool HAL_GetEncoderStopped(HAL_EncoderHandle encoderHandle,
+                               int32_t* status);
+HAL_Bool HAL_GetEncoderDirection(HAL_EncoderHandle encoderHandle,
+                                 int32_t* status);
+double HAL_GetEncoderDistance(HAL_EncoderHandle encoderHandle, int32_t* status);
+double HAL_GetEncoderRate(HAL_EncoderHandle encoderHandle, int32_t* status);
+void HAL_SetEncoderMinRate(HAL_EncoderHandle encoderHandle, double minRate,
+                           int32_t* status);
+void HAL_SetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
+                                    double distancePerPulse, int32_t* status);
+void HAL_SetEncoderReverseDirection(HAL_EncoderHandle encoderHandle,
+                                    HAL_Bool reverseDirection, int32_t* status);
+void HAL_SetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
+                                    int32_t samplesToAverage, int32_t* status);
+int32_t HAL_GetEncoderSamplesToAverage(HAL_EncoderHandle encoderHandle,
+                                       int32_t* status);
+
+void HAL_SetEncoderIndexSource(HAL_EncoderHandle encoderHandle,
+                               HAL_Handle digitalSourceHandle,
+                               HAL_AnalogTriggerType analogTriggerType,
+                               HAL_EncoderIndexingType type, int32_t* status);
+
+int32_t HAL_GetEncoderFPGAIndex(HAL_EncoderHandle encoderHandle,
+                                int32_t* status);
+
+double HAL_GetEncoderDecodingScaleFactor(HAL_EncoderHandle encoderHandle,
+                                         int32_t* status);
+
+double HAL_GetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle,
+                                      int32_t* status);
+
+HAL_EncoderEncodingType HAL_GetEncoderEncodingType(
+    HAL_EncoderHandle encoderHandle, int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Errors.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Errors.h
new file mode 100644
index 0000000..3111a7c
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Errors.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
+
+#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 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 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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Extensions.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Extensions.h
new file mode 100644
index 0000000..1021c5d
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Extensions.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
+
+/**
+ * HAL Simulator Extensions 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" {
+int HAL_LoadOneExtension(const char* library);
+int HAL_LoadExtensions(void);
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/HAL.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/HAL.h
new file mode 100644
index 0000000..2b765e5
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/HAL.h
@@ -0,0 +1,86 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "UsageReporting.h"
+
+namespace HALUsageReporting = nUsageReporting;
+
+enum HAL_RuntimeType : int32_t { HAL_Athena, HAL_Mock };
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const char* HAL_GetErrorMessage(int32_t code);
+
+int32_t HAL_GetFPGAVersion(int32_t* status);
+int64_t HAL_GetFPGARevision(int32_t* status);
+
+HAL_RuntimeType HAL_GetRuntimeType(void);
+HAL_Bool HAL_GetFPGAButton(int32_t* status);
+
+HAL_Bool HAL_GetSystemActive(int32_t* status);
+HAL_Bool HAL_GetBrownedOut(int32_t* status);
+
+void HAL_BaseInitialize(int32_t* status);
+
+#ifndef HAL_USE_LABVIEW
+
+HAL_PortHandle HAL_GetPort(int32_t channel);
+HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel);
+
+uint64_t HAL_GetFPGATime(int32_t* status);
+
+HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode);
+
+// ifdef's definition is to allow for default parameters in C++.
+#ifdef __cplusplus
+int64_t HAL_Report(int32_t resource, int32_t instanceNumber,
+                   int32_t context = 0, const char* feature = nullptr);
+#else
+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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/I2C.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/I2C.h
new file mode 100644
index 0000000..290430d
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/I2C.h
@@ -0,0 +1,29 @@
+/*----------------------------------------------------------------------------*/
+/* 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>
+
+enum HAL_I2CPort : int32_t { HAL_I2C_kOnboard = 0, HAL_I2C_kMXP };
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status);
+int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
+                           const uint8_t* dataToSend, int32_t sendSize,
+                           uint8_t* dataReceived, int32_t receiveSize);
+int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress,
+                     const uint8_t* dataToSend, int32_t sendSize);
+int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer,
+                    int32_t count);
+void HAL_CloseI2C(HAL_I2CPort port);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Interrupts.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Interrupts.h
new file mode 100644
index 0000000..db522f9
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Interrupts.h
@@ -0,0 +1,50 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*HAL_InterruptHandlerFunction)(uint32_t interruptAssertedMask,
+                                             void* param);
+
+HAL_InterruptHandle HAL_InitializeInterrupts(HAL_Bool watcher, int32_t* status);
+void HAL_CleanInterrupts(HAL_InterruptHandle interruptHandle, int32_t* status);
+
+int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
+                             double timeout, HAL_Bool ignorePrevious,
+                             int32_t* status);
+void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle, int32_t* status);
+void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
+                           int32_t* status);
+double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
+                                        int32_t* status);
+double HAL_ReadInterruptFallingTimestamp(HAL_InterruptHandle interruptHandle,
+                                         int32_t* status);
+void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
+                           HAL_Handle digitalSourceHandle,
+                           HAL_AnalogTriggerType analogTriggerType,
+                           int32_t* status);
+void HAL_AttachInterruptHandler(HAL_InterruptHandle interruptHandle,
+                                HAL_InterruptHandlerFunction handler,
+                                void* param, int32_t* status);
+void HAL_AttachInterruptHandlerThreaded(HAL_InterruptHandle interruptHandle,
+                                        HAL_InterruptHandlerFunction handler,
+                                        void* param, int32_t* status);
+void HAL_SetInterruptUpSourceEdge(HAL_InterruptHandle interruptHandle,
+                                  HAL_Bool risingEdge, HAL_Bool fallingEdge,
+                                  int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/LabVIEW/HAL.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/LabVIEW/HAL.h
new file mode 100644
index 0000000..4268a61
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Notifier.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Notifier.h
new file mode 100644
index 0000000..bd8544b
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Notifier.h
@@ -0,0 +1,30 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HAL_NotifierHandle HAL_InitializeNotifier(int32_t* status);
+void HAL_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status);
+void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status);
+void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
+                             uint64_t triggerTime, int32_t* status);
+void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
+                             int32_t* status);
+uint64_t HAL_WaitForNotifierAlarm(HAL_NotifierHandle notifierHandle,
+                                  int32_t* status);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/OSSerialPort.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/OSSerialPort.h
new file mode 100644
index 0000000..30e6f2a
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/OSSerialPort.h
@@ -0,0 +1,50 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "SerialPort.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HAL_InitializeOSSerialPort(HAL_SerialPort port, int32_t* status);
+void HAL_SetOSSerialBaudRate(HAL_SerialPort port, int32_t baud,
+                             int32_t* status);
+void HAL_SetOSSerialDataBits(HAL_SerialPort port, int32_t bits,
+                             int32_t* status);
+void HAL_SetOSSerialParity(HAL_SerialPort port, int32_t parity,
+                           int32_t* status);
+void HAL_SetOSSerialStopBits(HAL_SerialPort port, int32_t stopBits,
+                             int32_t* status);
+void HAL_SetOSSerialWriteMode(HAL_SerialPort port, int32_t mode,
+                              int32_t* status);
+void HAL_SetOSSerialFlowControl(HAL_SerialPort port, int32_t flow,
+                                int32_t* status);
+void HAL_SetOSSerialTimeout(HAL_SerialPort port, double timeout,
+                            int32_t* status);
+void HAL_EnableOSSerialTermination(HAL_SerialPort port, char terminator,
+                                   int32_t* status);
+void HAL_DisableOSSerialTermination(HAL_SerialPort port, int32_t* status);
+void HAL_SetOSSerialReadBufferSize(HAL_SerialPort port, int32_t size,
+                                   int32_t* status);
+void HAL_SetOSSerialWriteBufferSize(HAL_SerialPort port, int32_t size,
+                                    int32_t* status);
+int32_t HAL_GetOSSerialBytesReceived(HAL_SerialPort port, int32_t* status);
+int32_t HAL_ReadOSSerial(HAL_SerialPort port, char* buffer, int32_t count,
+                         int32_t* status);
+int32_t HAL_WriteOSSerial(HAL_SerialPort port, const char* buffer,
+                          int32_t count, int32_t* status);
+void HAL_FlushOSSerial(HAL_SerialPort port, int32_t* status);
+void HAL_ClearOSSerial(HAL_SerialPort port, int32_t* status);
+void HAL_CloseOSSerial(HAL_SerialPort port, int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/PDP.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/PDP.h
new file mode 100644
index 0000000..c5c3bee
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/PDP.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>
+
+#include "HAL/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HAL_InitializePDP(int32_t module, int32_t* status);
+HAL_Bool HAL_CheckPDPChannel(int32_t channel);
+HAL_Bool HAL_CheckPDPModule(int32_t module);
+double HAL_GetPDPTemperature(int32_t module, int32_t* status);
+double HAL_GetPDPVoltage(int32_t module, int32_t* status);
+double HAL_GetPDPChannelCurrent(int32_t module, int32_t channel,
+                                int32_t* status);
+double HAL_GetPDPTotalCurrent(int32_t module, int32_t* status);
+double HAL_GetPDPTotalPower(int32_t module, int32_t* status);
+double HAL_GetPDPTotalEnergy(int32_t module, int32_t* status);
+void HAL_ResetPDPTotalEnergy(int32_t module, int32_t* status);
+void HAL_ClearPDPStickyFaults(int32_t module, int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/PWM.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/PWM.h
new file mode 100644
index 0000000..317449c
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/PWM.h
@@ -0,0 +1,56 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HAL_DigitalHandle HAL_InitializePWMPort(HAL_PortHandle portHandle,
+                                        int32_t* status);
+void HAL_FreePWMPort(HAL_DigitalHandle pwmPortHandle, int32_t* status);
+
+HAL_Bool HAL_CheckPWMChannel(int32_t channel);
+
+void HAL_SetPWMConfig(HAL_DigitalHandle pwmPortHandle, double maxPwm,
+                      double deadbandMaxPwm, double centerPwm,
+                      double deadbandMinPwm, double minPwm, int32_t* status);
+void HAL_SetPWMConfigRaw(HAL_DigitalHandle pwmPortHandle, int32_t maxPwm,
+                         int32_t deadbandMaxPwm, int32_t centerPwm,
+                         int32_t deadbandMinPwm, int32_t minPwm,
+                         int32_t* status);
+void HAL_GetPWMConfigRaw(HAL_DigitalHandle pwmPortHandle, int32_t* maxPwm,
+                         int32_t* deadbandMaxPwm, int32_t* centerPwm,
+                         int32_t* deadbandMinPwm, int32_t* minPwm,
+                         int32_t* status);
+void HAL_SetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
+                                 HAL_Bool eliminateDeadband, int32_t* status);
+HAL_Bool HAL_GetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
+                                     int32_t* status);
+void HAL_SetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t value,
+                   int32_t* status);
+void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
+                     int32_t* status);
+void HAL_SetPWMPosition(HAL_DigitalHandle pwmPortHandle, double position,
+                        int32_t* status);
+void HAL_SetPWMDisabled(HAL_DigitalHandle pwmPortHandle, int32_t* status);
+int32_t HAL_GetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t* status);
+double HAL_GetPWMSpeed(HAL_DigitalHandle pwmPortHandle, int32_t* status);
+double HAL_GetPWMPosition(HAL_DigitalHandle pwmPortHandle, int32_t* status);
+void HAL_LatchPWMZero(HAL_DigitalHandle pwmPortHandle, int32_t* status);
+void HAL_SetPWMPeriodScale(HAL_DigitalHandle pwmPortHandle, int32_t squelchMask,
+                           int32_t* status);
+int32_t HAL_GetPWMLoopTiming(int32_t* status);
+uint64_t HAL_GetPWMCycleStartTime(int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Ports.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Ports.h
new file mode 100644
index 0000000..858e8dd
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Ports.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>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int32_t HAL_GetNumAccumulators(void);
+int32_t HAL_GetNumAnalogTriggers(void);
+int32_t HAL_GetNumAnalogInputs(void);
+int32_t HAL_GetNumAnalogOutputs(void);
+int32_t HAL_GetNumCounters(void);
+int32_t HAL_GetNumDigitalHeaders(void);
+int32_t HAL_GetNumPWMHeaders(void);
+int32_t HAL_GetNumDigitalChannels(void);
+int32_t HAL_GetNumPWMChannels(void);
+int32_t HAL_GetNumDigitalPWMOutputs(void);
+int32_t HAL_GetNumEncoders(void);
+int32_t HAL_GetNumInterrupts(void);
+int32_t HAL_GetNumRelayChannels(void);
+int32_t HAL_GetNumRelayHeaders(void);
+int32_t HAL_GetNumPCMModules(void);
+int32_t HAL_GetNumSolenoidChannels(void);
+int32_t HAL_GetNumPDPModules(void);
+int32_t HAL_GetNumPDPChannels(void);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Power.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Power.h
new file mode 100644
index 0000000..1cb3634
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Power.h
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <stdint.h>
+
+#include "HAL/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+double HAL_GetVinVoltage(int32_t* status);
+double HAL_GetVinCurrent(int32_t* status);
+double HAL_GetUserVoltage6V(int32_t* status);
+double HAL_GetUserCurrent6V(int32_t* status);
+HAL_Bool HAL_GetUserActive6V(int32_t* status);
+int32_t HAL_GetUserCurrentFaults6V(int32_t* status);
+double HAL_GetUserVoltage5V(int32_t* status);
+double HAL_GetUserCurrent5V(int32_t* status);
+HAL_Bool HAL_GetUserActive5V(int32_t* status);
+int32_t HAL_GetUserCurrentFaults5V(int32_t* status);
+double HAL_GetUserVoltage3V3(int32_t* status);
+double HAL_GetUserCurrent3V3(int32_t* status);
+HAL_Bool HAL_GetUserActive3V3(int32_t* status);
+int32_t HAL_GetUserCurrentFaults3V3(int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Relay.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Relay.h
new file mode 100644
index 0000000..6bc2526
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Relay.h
@@ -0,0 +1,29 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HAL_RelayHandle HAL_InitializeRelayPort(HAL_PortHandle portHandle, HAL_Bool fwd,
+                                        int32_t* status);
+void HAL_FreeRelayPort(HAL_RelayHandle relayPortHandle);
+
+HAL_Bool HAL_CheckRelayChannel(int32_t channel);
+
+void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
+                  int32_t* status);
+HAL_Bool HAL_GetRelay(HAL_RelayHandle relayPortHandle, int32_t* status);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/SPI.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/SPI.h
new file mode 100644
index 0000000..c961e4e
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/SPI.h
@@ -0,0 +1,61 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+enum HAL_SPIPort : int32_t {
+  HAL_SPI_kOnboardCS0 = 0,
+  HAL_SPI_kOnboardCS1,
+  HAL_SPI_kOnboardCS2,
+  HAL_SPI_kOnboardCS3,
+  HAL_SPI_kMXP
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status);
+int32_t HAL_TransactionSPI(HAL_SPIPort port, const uint8_t* dataToSend,
+                           uint8_t* dataReceived, int32_t size);
+int32_t HAL_WriteSPI(HAL_SPIPort port, const uint8_t* dataToSend,
+                     int32_t sendSize);
+int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count);
+void HAL_CloseSPI(HAL_SPIPort port);
+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);
+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, uint8_t* buffer,
+                                    int32_t numToRead, double timeout,
+                                    int32_t* status);
+int32_t HAL_GetSPIAutoDroppedCount(HAL_SPIPort port, int32_t* status);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/SerialPort.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/SerialPort.h
new file mode 100644
index 0000000..fa7b2c9
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/SerialPort.h
@@ -0,0 +1,50 @@
+/*----------------------------------------------------------------------------*/
+/* 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>
+
+enum HAL_SerialPort : int32_t {
+  HAL_SerialPort_Onboard = 0,
+  HAL_SerialPort_MXP = 1,
+  HAL_SerialPort_USB1 = 2,
+  HAL_SerialPort_USB2 = 3
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HAL_InitializeSerialPort(HAL_SerialPort port, 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);
+int32_t HAL_ReadSerial(HAL_SerialPort port, char* buffer, int32_t count,
+                       int32_t* status);
+int32_t HAL_WriteSerial(HAL_SerialPort port, const char* buffer, int32_t count,
+                        int32_t* status);
+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);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Solenoid.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Solenoid.h
new file mode 100644
index 0000000..d788f27
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Solenoid.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 "HAL/Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
+                                              int32_t* status);
+void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle);
+HAL_Bool HAL_CheckSolenoidModule(int32_t module);
+HAL_Bool HAL_CheckSolenoidChannel(int32_t channel);
+HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
+                         int32_t* status);
+int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status);
+void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
+                     int32_t* status);
+void HAL_SetAllSolenoids(int32_t module, int32_t state, int32_t* status);
+int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status);
+HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status);
+HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status);
+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);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Threads.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Threads.h
new file mode 100644
index 0000000..cb41b3b
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Threads.h
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+#ifdef _WIN32
+#include <windows.h>
+#define NativeThreadHandle const HANDLE*
+#else
+#include <pthread.h>
+#define NativeThreadHandle const pthread_t*
+#endif
+
+#include "HAL/Types.h"
+
+extern "C" {
+int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
+                              int32_t* status);
+int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status);
+HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
+                               int32_t priority, int32_t* status);
+HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority,
+                                      int32_t* status);
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Types.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Types.h
new file mode 100644
index 0000000..702f538
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/Types.h
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <stdint.h>
+
+#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 int32_t HAL_Bool;
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/UsageReporting.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/UsageReporting.h
new file mode 100644
index 0000000..aaa7d8d
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/UsageReporting.h
@@ -0,0 +1,163 @@
+
+#ifndef __UsageReporting_h__
+#define __UsageReporting_h__
+
+#ifdef _WIN32
+#include <stdint.h>
+#define EXPORT_FUNC __declspec(dllexport) __cdecl
+#elif defined (__vxworks)
+#include <vxWorks.h>
+#define EXPORT_FUNC
+#else
+#include <stdint.h>
+#include <stdlib.h>
+#define EXPORT_FUNC
+#endif
+
+#define kUsageReporting_version 1
+
+namespace nUsageReporting
+{
+    typedef enum
+    {
+        kResourceType_Controller,
+        kResourceType_Module,
+        kResourceType_Language,
+        kResourceType_CANPlugin,
+        kResourceType_Accelerometer,
+        kResourceType_ADXL345,
+        kResourceType_AnalogChannel,
+        kResourceType_AnalogTrigger,
+        kResourceType_AnalogTriggerOutput,
+        kResourceType_CANJaguar,
+        kResourceType_Compressor, // 10
+        kResourceType_Counter,
+        kResourceType_Dashboard,
+        kResourceType_DigitalInput,
+        kResourceType_DigitalOutput,
+        kResourceType_DriverStationCIO,
+        kResourceType_DriverStationEIO,
+        kResourceType_DriverStationLCD,
+        kResourceType_Encoder,
+        kResourceType_GearTooth,
+        kResourceType_Gyro, // 20
+        kResourceType_I2C,
+        kResourceType_Framework,
+        kResourceType_Jaguar,
+        kResourceType_Joystick,
+        kResourceType_Kinect,
+        kResourceType_KinectStick,
+        kResourceType_PIDController,
+        kResourceType_Preferences,
+        kResourceType_PWM,
+        kResourceType_Relay, // 30
+        kResourceType_RobotDrive,
+        kResourceType_SerialPort,
+        kResourceType_Servo,
+        kResourceType_Solenoid,
+        kResourceType_SPI,
+        kResourceType_Task,
+        kResourceType_Ultrasonic,
+        kResourceType_Victor,
+        kResourceType_Button,
+        kResourceType_Command, // 40
+        kResourceType_AxisCamera,
+        kResourceType_PCVideoServer,
+        kResourceType_SmartDashboard,
+        kResourceType_Talon,
+        kResourceType_HiTechnicColorSensor,
+        kResourceType_HiTechnicAccel,
+        kResourceType_HiTechnicCompass,
+        kResourceType_SRF08,
+        kResourceType_AnalogOutput,
+        kResourceType_VictorSP, // 50
+        kResourceType_PWMTalonSRX,
+        kResourceType_CANTalonSRX,
+        kResourceType_ADXL362,
+        kResourceType_ADXRS450,
+        kResourceType_RevSPARK,
+        kResourceType_MindsensorsSD540,
+        kResourceType_DigitalFilter,
+        kResourceType_ADIS16448,
+        kResourceType_PDP,
+        kResourceType_PCM, // 60
+        kResourceType_PigeonIMU,
+        kResourceType_NidecBrushless,
+        kResourceType_CANifier,
+        kResourceType_CTRE_future0,
+        kResourceType_CTRE_future1,
+        kResourceType_CTRE_future2,
+        kResourceType_CTRE_future3,
+        kResourceType_CTRE_future4,
+        kResourceType_CTRE_future5,
+        kResourceType_CTRE_future6, // 70
+    } tResourceType;
+
+    typedef enum
+    {
+        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,
+
+        kRobotDrive_ArcadeStandard = 1,
+        kRobotDrive_ArcadeButtonSpin = 2,
+        kRobotDrive_ArcadeRatioCurve = 3,
+        kRobotDrive_Tank = 4,
+        kRobotDrive_MecanumPolar = 5,
+        kRobotDrive_MecanumCartesian = 6,
+
+        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,
+    } tInstances;
+
+    /**
+     * Report the usage of a resource of interest.
+     *
+     * @param resource one of the values in the tResourceType above (max value 51).
+     * @param instanceNumber an index that identifies the resource instance.
+     * @param context an optional additional context number for some cases (such as module number).  Set to 0 to omit.
+     * @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.
+     */
+    uint32_t EXPORT_FUNC report(tResourceType resource, uint8_t instanceNumber, uint8_t context = 0, const char *feature = NULL);
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    uint32_t EXPORT_FUNC FRC_NetworkCommunication_nUsageReporting_report(uint8_t resource, uint8_t instanceNumber, uint8_t context, const char *feature);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __UsageReporting_h__
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/Log.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/Log.h
new file mode 100644
index 0000000..e57974e
--- /dev/null
+++ b/third_party/allwpilib_2018/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 <llvm/SmallString.h>
+#include <llvm/raw_ostream.h>
+
+inline std::string NowTime();
+
+enum TLogLevel {
+  logNONE,
+  logERROR,
+  logWARNING,
+  logINFO,
+  logDEBUG,
+  logDEBUG1,
+  logDEBUG2,
+  logDEBUG3,
+  logDEBUG4
+};
+
+class Log {
+ public:
+  Log();
+  virtual ~Log();
+  llvm::raw_ostream& Get(TLogLevel level = logINFO);
+
+ public:
+  static TLogLevel& ReportingLevel();
+  static std::string ToString(TLogLevel level);
+  static TLogLevel FromString(const std::string& level);
+
+ protected:
+  llvm::SmallString<128> buf;
+  llvm::raw_svector_ostream oss{buf};
+
+ private:
+  Log(const Log&);
+  Log& operator=(const Log&);
+};
+
+inline Log::Log() {}
+
+inline llvm::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";
+  llvm::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;
+}
+
+typedef Log FILELog;
+
+#define FILE_LOG(level)                  \
+  if (level > FILELog::ReportingLevel()) \
+    ;                                    \
+  else                                   \
+    Log().Get(level)
+
+inline std::string NowTime() {
+  llvm::SmallString<128> buf;
+  llvm::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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/SerialHelper.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/SerialHelper.h
new file mode 100644
index 0000000..3b978b8
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/SerialHelper.h
@@ -0,0 +1,52 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <llvm/SmallString.h>
+#include <llvm/SmallVector.h>
+#include <support/mutex.h>
+
+#include "HAL/SerialPort.h"
+
+namespace hal {
+class SerialHelper {
+ public:
+  SerialHelper();
+
+  std::string GetVISASerialPortName(HAL_SerialPort port, int32_t* status);
+  std::string GetOSSerialPortName(HAL_SerialPort port, int32_t* status);
+
+  std::vector<std::string> GetVISASerialPortList(int32_t* status);
+  std::vector<std::string> GetOSSerialPortList(int32_t* status);
+
+ private:
+  void SortHubPathVector();
+  void CoiteratedSort(llvm::SmallVectorImpl<llvm::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;
+  llvm::SmallVector<llvm::SmallString<16>, 4> m_visaResource;
+  llvm::SmallVector<llvm::SmallString<16>, 4> m_osResource;
+  llvm::SmallVector<llvm::SmallString<16>, 4> m_unsortedHubPath;
+  llvm::SmallVector<llvm::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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/UnsafeDIO.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/UnsafeDIO.h
new file mode 100644
index 0000000..5d95100
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/UnsafeDIO.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 <support/mutex.h>
+
+#include "HAL/ChipObject.h"
+#include "HAL/Types.h"
+
+namespace hal {
+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.
+ *
+ */
+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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/fpga_clock.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/fpga_clock.h
new file mode 100644
index 0000000..6b13aaf
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/fpga_clock.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 <chrono>
+#include <limits>
+
+namespace hal {
+
+class fpga_clock {
+ public:
+  typedef std::chrono::microseconds::rep rep;
+  typedef std::chrono::microseconds::period period;
+  typedef std::chrono::microseconds duration;
+  typedef std::chrono::time_point<fpga_clock> time_point;
+
+  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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/make_unique.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/make_unique.h
new file mode 100644
index 0000000..ffc2d6f
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/cpp/make_unique.h
@@ -0,0 +1,47 @@
+/*----------------------------------------------------------------------------*/
+/* 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 make_unique for C++11-only compilers
+#if __cplusplus == 201103L
+#include <cstddef>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+namespace std {
+template <class T>
+struct _Unique_if {
+  typedef unique_ptr<T> _Single_object;
+};
+
+template <class T>
+struct _Unique_if<T[]> {
+  typedef unique_ptr<T[]> _Unknown_bound;
+};
+
+template <class T, size_t N>
+struct _Unique_if<T[N]> {
+  typedef void _Known_bound;
+};
+
+template <class T, class... Args>
+typename _Unique_if<T>::_Single_object make_unique(Args&&... args) {
+  return unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+template <class T>
+typename _Unique_if<T>::_Unknown_bound make_unique(size_t n) {
+  typedef typename remove_extent<T>::type U;
+  return unique_ptr<T>(new U[n]());
+}
+
+template <class T, class... Args>
+typename _Unique_if<T>::_Known_bound make_unique(Args&&...) = delete;
+}  // namespace std
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/DigitalHandleResource.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/DigitalHandleResource.h
new file mode 100644
index 0000000..6473d90
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/DigitalHandleResource.h
@@ -0,0 +1,106 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <support/mutex.h>
+
+#include "HAL/Errors.h"
+#include "HAL/Types.h"
+#include "HAL/cpp/make_unique.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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/HandlesInternal.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/HandlesInternal.h
new file mode 100644
index 0000000..7b353d2
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/HandlesInternal.h
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#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 {
+
+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 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
+};
+
+static inline int16_t getHandleIndex(HAL_Handle handle) {
+  // mask and return last 16 bits
+  return static_cast<int16_t>(handle & 0xffff);
+}
+static inline HAL_HandleEnum getHandleType(HAL_Handle handle) {
+  // mask first 8 bits and cast to enum
+  return static_cast<HAL_HandleEnum>((handle >> 24) & 0xff);
+}
+static inline bool isHandleType(HAL_Handle handle, HAL_HandleEnum handleType) {
+  return handleType == getHandleType(handle);
+}
+static inline bool isHandleCorrectVersion(HAL_Handle handle, int16_t version) {
+  return (((handle & 0xFF0000) >> 16) & version) == version;
+}
+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
+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
+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
+static inline int16_t getPortHandleSPIEnable(HAL_PortHandle handle) {
+  if (!isHandleType(handle, HAL_HandleEnum::Port)) return InvalidHandleIndex;
+  return static_cast<uint8_t>((handle >> 16) & 0xff);
+}
+
+HAL_PortHandle createPortHandle(uint8_t channel, uint8_t module);
+
+HAL_PortHandle createPortHandleForSPI(uint8_t channel);
+
+HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType,
+                        int16_t version);
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/IndexedClassedHandleResource.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/IndexedClassedHandleResource.h
new file mode 100644
index 0000000..c13fb2a
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/IndexedClassedHandleResource.h
@@ -0,0 +1,118 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <support/mutex.h>
+
+#include "HAL/Errors.h"
+#include "HAL/Types.h"
+#include "HAL/cpp/make_unique.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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/IndexedHandleResource.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/IndexedHandleResource.h
new file mode 100644
index 0000000..1d5ea86
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/IndexedHandleResource.h
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <stdint.h>
+
+#include <array>
+#include <memory>
+
+#include <support/mutex.h>
+
+#include "HAL/Errors.h"
+#include "HAL/Types.h"
+#include "HAL/cpp/make_unique.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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/LimitedClassedHandleResource.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/LimitedClassedHandleResource.h
new file mode 100644
index 0000000..57b15a2
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/LimitedClassedHandleResource.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 <support/mutex.h>
+
+#include "HAL/Types.h"
+#include "HAL/cpp/make_unique.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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/LimitedHandleResource.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/LimitedHandleResource.h
new file mode 100644
index 0000000..afab748
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/LimitedHandleResource.h
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <stdint.h>
+
+#include <array>
+#include <memory>
+
+#include <support/mutex.h>
+
+#include "HAL/Types.h"
+#include "HAL/cpp/make_unique.h"
+#include "HandlesInternal.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/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/UnlimitedHandleResource.h b/third_party/allwpilib_2018/hal/src/main/native/include/HAL/handles/UnlimitedHandleResource.h
new file mode 100644
index 0000000..5941628
--- /dev/null
+++ b/third_party/allwpilib_2018/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 <support/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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/AccelerometerData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/AccelerometerData.h
new file mode 100644
index 0000000..dcf7b14
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/AccelerometerData.h
@@ -0,0 +1,69 @@
+/*----------------------------------------------------------------------------*/
+/* 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/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/AnalogGyroData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/AnalogGyroData.h
new file mode 100644
index 0000000..b15ddd5
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/AnalogInData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/AnalogInData.h
new file mode 100644
index 0000000..1e46b54
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/AnalogOutData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/AnalogOutData.h
new file mode 100644
index 0000000..c1721df
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/AnalogTriggerData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/AnalogTriggerData.h
new file mode 100644
index 0000000..848f16a
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/CanData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/CanData.h
new file mode 100644
index 0000000..ca91b03
--- /dev/null
+++ b/third_party/allwpilib_2018/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/HAL.h"
+#include "HAL_Value.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/DIOData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/DIOData.h
new file mode 100644
index 0000000..fbbc02f
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/DigitalPWMData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/DigitalPWMData.h
new file mode 100644
index 0000000..cdd419d
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/DriverStationData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/DriverStationData.h
new file mode 100644
index 0000000..a9f1e76
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/DriverStationData.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 "HAL/DriverStation.h"
+#include "HAL/HAL.h"
+#include "NotifyListener.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);
+
+void HALSIM_RegisterDriverStationAllCallbacks(HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/MockData/EncoderData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/EncoderData.h
new file mode 100644
index 0000000..382e41d
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/EncoderData.h
@@ -0,0 +1,91 @@
+/*----------------------------------------------------------------------------*/
+/* 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/HAL.h"
+#include "NotifyListener.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void HALSIM_ResetEncoderData(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);
+
+void HALSIM_RegisterEncoderAllCallbacks(int32_t index,
+                                        HAL_NotifyCallback callback,
+                                        void* param, HAL_Bool initialNotify);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/MockData/HAL_Value.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/HAL_Value.h
new file mode 100644
index 0000000..19308ed
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/I2CData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/I2CData.h
new file mode 100644
index 0000000..9b12bf7
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/MockHooks.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/MockHooks.h
new file mode 100644
index 0000000..c67d198
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/MockHooks.h
@@ -0,0 +1,18 @@
+/*----------------------------------------------------------------------------*/
+/* 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__
+
+extern "C" {
+void HALSIM_WaitForProgramStart(void);
+void HALSIM_SetProgramStarted(void);
+void HALSIM_RestartTiming(void);
+}  // extern "C"
+
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/MockData/NotifyCallbackHelpers.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/NotifyCallbackHelpers.h
new file mode 100644
index 0000000..588ae1b
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/NotifyCallbackHelpers.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 <memory>
+
+#include "MockData/NotifyListenerVector.h"
+
+template <typename VectorType, typename CallbackType>
+std::shared_ptr<VectorType> RegisterCallbackImpl(
+    std::shared_ptr<VectorType> currentVector, const char* name,
+    CallbackType callback, void* param, int32_t* newUid) {
+  std::shared_ptr<VectorType> newCallbacks;
+  if (currentVector == nullptr) {
+    newCallbacks = std::make_shared<VectorType>(
+        param, callback, reinterpret_cast<unsigned int*>(newUid));
+  } else {
+    newCallbacks = currentVector->emplace_back(
+        param, callback, reinterpret_cast<unsigned int*>(newUid));
+  }
+  return newCallbacks;
+}
+
+template <typename VectorType, typename CallbackType>
+std::shared_ptr<VectorType> CancelCallbackImpl(
+    std::shared_ptr<VectorType> currentVector, int32_t uid) {
+  // Create a copy of the callbacks to erase from
+  auto newCallbacks = currentVector->erase(uid);
+  return newCallbacks;
+}
+
+std::shared_ptr<hal::NotifyListenerVector> RegisterCallback(
+    std::shared_ptr<hal::NotifyListenerVector> currentVector, const char* name,
+    HAL_NotifyCallback callback, void* param, int32_t* newUid);
+
+std::shared_ptr<hal::NotifyListenerVector> CancelCallback(
+    std::shared_ptr<hal::NotifyListenerVector> currentVector, int32_t uid);
+
+void InvokeCallback(std::shared_ptr<hal::NotifyListenerVector> currentVector,
+                    const char* name, const HAL_Value* value);
+
+std::shared_ptr<hal::BufferListenerVector> RegisterCallback(
+    std::shared_ptr<hal::BufferListenerVector> currentVector, const char* name,
+    HAL_BufferCallback callback, void* param, int32_t* newUid);
+
+std::shared_ptr<hal::BufferListenerVector> CancelCallback(
+    std::shared_ptr<hal::BufferListenerVector> currentVector, int32_t uid);
+
+void InvokeCallback(std::shared_ptr<hal::BufferListenerVector> currentVector,
+                    const char* name, uint8_t* buffer, int32_t count);
+
+std::shared_ptr<hal::ConstBufferListenerVector> RegisterCallback(
+    std::shared_ptr<hal::ConstBufferListenerVector> currentVector,
+    const char* name, HAL_ConstBufferCallback callback, void* param,
+    int32_t* newUid);
+
+std::shared_ptr<hal::ConstBufferListenerVector> CancelCallback(
+    std::shared_ptr<hal::ConstBufferListenerVector> currentVector, int32_t uid);
+
+void InvokeCallback(
+    std::shared_ptr<hal::ConstBufferListenerVector> currentVector,
+    const char* name, const uint8_t* buffer, int32_t count);
+
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/MockData/NotifyListener.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/NotifyListener.h
new file mode 100644
index 0000000..8d7e199
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/NotifyListenerVector.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/NotifyListenerVector.h
new file mode 100644
index 0000000..7164784
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/NotifyListenerVector.h
@@ -0,0 +1,142 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+#include <queue>
+#include <vector>
+
+#include "NotifyListener.h"
+
+namespace hal {
+// Vector which provides an integrated freelist for removal and reuse of
+// individual elements.
+
+template <typename ListenerType>
+class HalCallbackListenerVectorImpl {
+  struct private_init {};
+
+ public:
+  typedef typename std::vector<HalCallbackListener<ListenerType>>::size_type
+      size_type;
+
+  // Constructor for creating copies of the vector
+  HalCallbackListenerVectorImpl(const HalCallbackListenerVectorImpl* copyFrom,
+                                const private_init&);
+
+  // Delete all default constructors so they cannot be used
+  HalCallbackListenerVectorImpl& operator=(
+      const HalCallbackListenerVectorImpl&) = delete;
+  HalCallbackListenerVectorImpl() = delete;
+  HalCallbackListenerVectorImpl(const HalCallbackListenerVectorImpl&) = delete;
+
+  // Create a new vector with a single callback inside of it
+  HalCallbackListenerVectorImpl(void* param, ListenerType callback,
+                                unsigned int* newUid) {
+    *newUid = emplace_back_impl(param, callback);
+  }
+
+  size_type size() const { return m_vector.size(); }
+  HalCallbackListener<ListenerType>& operator[](size_type i) {
+    return m_vector[i];
+  }
+  const HalCallbackListener<ListenerType>& operator[](size_type i) const {
+    return m_vector[i];
+  }
+
+  // Add a new NotifyListener to a copy of the vector.  If there are elements on
+  // the freelist,
+  // reuses the last one; otherwise adds to the end of the vector.
+  // Returns the resulting element index (+1).
+  std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>> emplace_back(
+      void* param, ListenerType callback, unsigned int* newUid);
+
+  // Removes the identified element by replacing it with a default-constructed
+  // one.  The element is added to the freelist for later reuse. Returns a copy
+  std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>> erase(
+      unsigned int uid);
+
+ private:
+  std::vector<HalCallbackListener<ListenerType>> m_vector;
+  std::vector<unsigned int> m_free;
+
+  // Add a new NotifyListener to the vector.  If there are elements on the
+  // freelist,
+  // reuses the last one; otherwise adds to the end of the vector.
+  // Returns the resulting element index (+1).
+  unsigned int emplace_back_impl(void* param, ListenerType callback);
+
+  // Removes the identified element by replacing it with a default-constructed
+  // one.  The element is added to the freelist for later reuse.
+  void erase_impl(unsigned int uid);
+};
+
+template <typename ListenerType>
+HalCallbackListenerVectorImpl<ListenerType>::HalCallbackListenerVectorImpl(
+    const HalCallbackListenerVectorImpl<ListenerType>* copyFrom,
+    const private_init&)
+    : m_vector(copyFrom->m_vector), m_free(copyFrom->m_free) {}
+
+template <typename ListenerType>
+std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>>
+HalCallbackListenerVectorImpl<ListenerType>::emplace_back(
+    void* param, ListenerType callback, unsigned int* newUid) {
+  auto newVector =
+      std::make_shared<HalCallbackListenerVectorImpl<ListenerType>>(
+          this, private_init());
+  newVector->m_vector = m_vector;
+  newVector->m_free = m_free;
+  *newUid = newVector->emplace_back_impl(param, callback);
+  return newVector;
+}
+
+template <typename ListenerType>
+std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>>
+HalCallbackListenerVectorImpl<ListenerType>::erase(unsigned int uid) {
+  auto newVector =
+      std::make_shared<HalCallbackListenerVectorImpl<ListenerType>>(
+          this, private_init());
+  newVector->m_vector = m_vector;
+  newVector->m_free = m_free;
+  newVector->erase_impl(uid);
+  return newVector;
+}
+
+template <typename ListenerType>
+unsigned int HalCallbackListenerVectorImpl<ListenerType>::emplace_back_impl(
+    void* param, ListenerType callback) {
+  unsigned int uid;
+  if (m_free.empty()) {
+    uid = m_vector.size();
+    m_vector.emplace_back(param, callback);
+  } else {
+    uid = m_free.back();
+    m_free.pop_back();
+    m_vector[uid] = HalCallbackListener<ListenerType>(param, callback);
+  }
+  return uid + 1;
+}
+
+template <typename ListenerType>
+void HalCallbackListenerVectorImpl<ListenerType>::erase_impl(unsigned int uid) {
+  --uid;
+  if (uid >= m_vector.size() || !m_vector[uid]) return;
+  m_free.push_back(uid);
+  m_vector[uid] = HalCallbackListener<ListenerType>();
+}
+
+typedef HalCallbackListenerVectorImpl<HAL_NotifyCallback> NotifyListenerVector;
+typedef HalCallbackListenerVectorImpl<HAL_BufferCallback> BufferListenerVector;
+typedef HalCallbackListenerVectorImpl<HAL_ConstBufferCallback>
+    ConstBufferListenerVector;
+
+}  // namespace hal
+
+#endif
diff --git a/third_party/allwpilib_2018/hal/src/main/native/include/MockData/PCMData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/PCMData.h
new file mode 100644
index 0000000..083ef64
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/PDPData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/PDPData.h
new file mode 100644
index 0000000..cac22c9
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/PWMData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/PWMData.h
new file mode 100644
index 0000000..bf1b735
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/RelayData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/RelayData.h
new file mode 100644
index 0000000..56727ea
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/RoboRioData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/RoboRioData.h
new file mode 100644
index 0000000..7cb3ca4
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/SPIAccelerometerData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/SPIAccelerometerData.h
new file mode 100644
index 0000000..adfbaa7
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.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/third_party/allwpilib_2018/hal/src/main/native/include/MockData/SPIData.h b/third_party/allwpilib_2018/hal/src/main/native/include/MockData/SPIData.h
new file mode 100644
index 0000000..6639fa5
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "NotifyListener.h"
+
+typedef void (*HAL_SpiReadAutoReceiveBufferCallback)(const char* name,
+                                                     void* param,
+                                                     unsigned char* 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/third_party/allwpilib_2018/hal/src/main/native/shared/cpp/fpga_clock.cpp b/third_party/allwpilib_2018/hal/src/main/native/shared/cpp/fpga_clock.cpp
new file mode 100644
index 0000000..bf1ffe1
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/shared/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 <llvm/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) {
+    llvm::errs()
+        << "Call to HAL_GetFPGATime failed."
+        << "Initialization might have failed. Time will not be correct\n";
+    llvm::errs().flush();
+    return epoch();
+  }
+  return time_point(std::chrono::microseconds(currentTime));
+}
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/shared/handles/HandlesInternal.cpp b/third_party/allwpilib_2018/hal/src/main/native/shared/handles/HandlesInternal.cpp
new file mode 100644
index 0000000..89628a8
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/shared/handles/HandlesInternal.cpp
@@ -0,0 +1,96 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <llvm/SmallVector.h>
+#include <support/mutex.h>
+
+namespace hal {
+static llvm::SmallVector<HandleBase*, 32>* globalHandles;
+static wpi::mutex globalHandleMutex;
+namespace init {
+void InitializeHandlesInternal() {
+  static llvm::SmallVector<HandleBase*, 32> gH;
+  globalHandles = &gH;
+}
+}  // namespace init
+HandleBase::HandleBase() {
+  std::lock_guard<wpi::mutex> lock(globalHandleMutex);
+  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/third_party/allwpilib_2018/hal/src/main/native/sim/Accelerometer.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Accelerometer.cpp
new file mode 100644
index 0000000..c5501bb
--- /dev/null
+++ b/third_party/allwpilib_2018/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].SetActive(active);
+}
+
+void HAL_SetAccelerometerRange(HAL_AccelerometerRange range) {
+  SimAccelerometerData[0].SetRange(range);
+}
+double HAL_GetAccelerometerX(void) { return SimAccelerometerData[0].GetX(); }
+double HAL_GetAccelerometerY(void) { return SimAccelerometerData[0].GetY(); }
+double HAL_GetAccelerometerZ(void) { return SimAccelerometerData[0].GetZ(); }
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogAccumulator.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogAccumulator.cpp
new file mode 100644
index 0000000..5772d33
--- /dev/null
+++ b/third_party/allwpilib_2018/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].SetAccumulatorInitialized(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].SetAccumulatorCenter(0);
+  SimAnalogInData[port->channel].SetAccumulatorCount(0);
+  SimAnalogInData[port->channel].SetAccumulatorValue(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].SetAccumulatorCenter(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].SetAccumulatorDeadband(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].GetAccumulatorValue();
+}
+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].GetAccumulatorCount();
+}
+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].GetAccumulatorCount();
+  *value = SimAnalogInData[port->channel].GetAccumulatorValue();
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogGyro.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogGyro.cpp
new file mode 100644
index 0000000..d359675
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogGyro.cpp
@@ -0,0 +1,145 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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) {
+  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].SetInitialized(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].SetInitialized(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].SetAngle(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].GetAngle();
+}
+
+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].GetRate();
+}
+
+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/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogInput.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogInput.cpp
new file mode 100644
index 0000000..391df71
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogInput.cpp
@@ -0,0 +1,177 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/handles/HandlesInternal.h"
+#include "MockData/AnalogInDataInternal.h"
+#include "PortsInternal.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) {
+  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].SetInitialized(true);
+  SimAnalogInData[channel].SetAccumulatorInitialized(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].SetInitialized(false);
+  SimAnalogInData[port->channel].SetAccumulatorInitialized(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].SetAverageBits(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].GetAverageBits();
+}
+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].SetOversampleBits(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].GetOversampleBits();
+}
+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].GetVoltage();
+  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].GetVoltage();
+}
+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
+  double voltage = SimAnalogInData[port->channel].GetVoltage();
+  return 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/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogInternal.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogInternal.cpp
new file mode 100644
index 0000000..9bce87b
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/AnalogInput.h"
+#include "PortsInternal.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/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogInternal.h
new file mode 100644
index 0000000..0287b58
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/Ports.h"
+#include "HAL/handles/IndexedHandleResource.h"
+#include "PortsInternal.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/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogOutput.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogOutput.cpp
new file mode 100644
index 0000000..31ef32b
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogOutput.cpp
@@ -0,0 +1,100 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/Errors.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "HAL/handles/IndexedHandleResource.h"
+#include "MockData/AnalogOutDataInternal.h"
+#include "PortsInternal.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) {
+  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].SetInitialized(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].SetInitialized(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].SetVoltage(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].GetVoltage();
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogTrigger.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogTrigger.cpp
new file mode 100644
index 0000000..2b990e2
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/AnalogTrigger.cpp
@@ -0,0 +1,259 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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"
+#include "PortsInternal.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) {
+  // 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].SetInitialized(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].SetInitialized(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].SetTriggerUpperBound(trigUpper);
+  SimAnalogTriggerData[trigger->index].SetTriggerLowerBound(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].SetTriggerUpperBound(upper);
+  SimAnalogTriggerData[trigger->index].SetTriggerLowerBound(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->GetTriggerMode() == HALSIM_AnalogTriggerFiltered) {
+    *status = INCOMPATIBLE_STATE;
+    return;
+  }
+
+  auto setVal = useAveragedValue ? HALSIM_AnalogTriggerAveraged
+                                 : HALSIM_AnalogTriggerUnassigned;
+  triggerData->SetTriggerMode(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->GetTriggerMode() == HALSIM_AnalogTriggerAveraged) {
+    *status = INCOMPATIBLE_STATE;
+    return;
+  }
+
+  auto setVal = useFilteredValue ? HALSIM_AnalogTriggerAveraged
+                                 : HALSIM_AnalogTriggerUnassigned;
+  triggerData->SetTriggerMode(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].GetVoltage();
+}
+
+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;
+  }
+
+  auto trigUpper = SimAnalogTriggerData[trigger->index].GetTriggerUpperBound();
+  auto trigLower = SimAnalogTriggerData[trigger->index].GetTriggerLowerBound();
+
+  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;
+  }
+
+  auto trigUpper = SimAnalogTriggerData[trigger->index].GetTriggerUpperBound();
+  auto trigLower = SimAnalogTriggerData[trigger->index].GetTriggerLowerBound();
+
+  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/third_party/allwpilib_2018/hal/src/main/native/sim/CAN.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/CAN.cpp
new file mode 100644
index 0000000..72173c3
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/sim/Compressor.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Compressor.cpp
new file mode 100644
index 0000000..ad9b2a2
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/Compressor.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/Compressor.h"
+
+#include "HAL/Errors.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "MockData/PCMDataInternal.h"
+#include "PortsInternal.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) {
+  // As compressors can have unlimited objects, just create a
+  // handle with the module number as the index.
+
+  SimPCMData[module].SetCompressorInitialized(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].GetCompressorOn();
+}
+
+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].SetClosedLoopEnabled(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].GetClosedLoopEnabled();
+}
+
+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].GetPressureSwitch();
+}
+
+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].GetCompressorCurrent();
+}
+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/third_party/allwpilib_2018/hal/src/main/native/sim/Constants.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Constants.cpp
new file mode 100644
index 0000000..e059f2e
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/sim/ConstantsInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/ConstantsInternal.h
new file mode 100644
index 0000000..c3a6e8f
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/sim/Counter.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Counter.cpp
new file mode 100644
index 0000000..52ec724
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/Counter.cpp
@@ -0,0 +1,96 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/Errors.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "HAL/handles/LimitedHandleResource.h"
+#include "PortsInternal.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) {
+  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/third_party/allwpilib_2018/hal/src/main/native/sim/CounterInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/CounterInternal.h
new file mode 100644
index 0000000..cd2f9c2
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/handles/HandlesInternal.h"
+#include "HAL/handles/LimitedHandleResource.h"
+#include "PortsInternal.h"
+
+namespace hal {
+
+struct Counter {
+  uint8_t index;
+};
+
+extern LimitedHandleResource<HAL_CounterHandle, Counter, kNumCounters,
+                             HAL_HandleEnum::Counter>* counterHandles;
+
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/DIO.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/DIO.cpp
new file mode 100644
index 0000000..5c03927
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/DIO.cpp
@@ -0,0 +1,348 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/handles/HandlesInternal.h"
+#include "HAL/handles/LimitedHandleResource.h"
+#include "MockData/DIODataInternal.h"
+#include "MockData/DigitalPWMDataInternal.h"
+#include "PortsInternal.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" {
+
+/**
+ * Create a new instance of a digital port.
+ */
+HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
+                                        HAL_Bool input, int32_t* status) {
+  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].SetInitialized(true);
+
+  SimDIOData[channel].SetIsInput(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].SetInitialized(true);
+}
+
+/**
+ * Allocate a DO PWM Generator.
+ * Allocate PWM generators so that they are not accidentally reused.
+ *
+ * @return PWM Generator handle
+ */
+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].SetInitialized(true);
+
+  return handle;
+}
+
+/**
+ * Free the resource associated with a DO PWM generator.
+ *
+ * @param pwmGenerator The pwmGen to free that was allocated with
+ * allocateDigitalPWM()
+ */
+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].SetInitialized(false);
+}
+
+/**
+ * Change 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) {
+  // 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);
+}
+
+/**
+ * Configure the duty-cycle of the PWM generator
+ *
+ * @param pwmGenerator The generator index reserved by allocateDigitalPWM()
+ * @param dutyCycle The percent duty cycle to output [0..1].
+ */
+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].SetDutyCycle(dutyCycle);
+}
+
+/**
+ * Configure which DO channel the PWM signal is output on
+ *
+ * @param pwmGenerator The generator index reserved by allocateDigitalPWM()
+ * @param channel The Digital Output channel to output on
+ */
+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].SetPin(channel);
+}
+
+/**
+ * Write a digital I/O bit to the FPGA.
+ * Set a single value on a digital I/O channel.
+ *
+ * @param channel The Digital I/O channel
+ * @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) {
+  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].SetValue(value);
+}
+
+/**
+ * Read a digital I/O bit from the FPGA.
+ * Get a single value from a digital I/O channel.
+ *
+ * @param channel The digital I/O channel
+ * @return The state of the specified channel
+ */
+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].GetValue();
+  if (value > 1) value = 1;
+  if (value < 0) value = 0;
+  return value;
+}
+
+/**
+ * Read the direction of a the Digital I/O lines
+ * A 1 bit means output and a 0 bit means input.
+ *
+ * @param channel The digital I/O channel
+ * @return The direction of the specified channel
+ */
+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].GetIsInput();
+  if (value > 1) value = 1;
+  if (value < 0) value = 0;
+  return value;
+}
+
+/**
+ * Generate a single pulse.
+ * Write a pulse to the specified digital output channel. There can only be a
+ * single pulse going at any time.
+ *
+ * @param channel The Digital Output channel that the pulse should be output on
+ * @param pulseLength The active length of the pulse (in seconds)
+ */
+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
+}
+
+/**
+ * Check a DIO line to see if it is currently generating a pulse.
+ *
+ * @return A pulse is in progress
+ */
+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
+}
+
+/**
+ * Check if any DIO line is currently generating a pulse.
+ *
+ * @return A pulse on some line is in progress
+ */
+HAL_Bool HAL_IsAnyPulsing(int32_t* status) {
+  return false;  // TODO(Thad) Figure this out
+}
+
+/**
+ * Write the filter index from the FPGA.
+ * Set the filter index used to filter out short pulses.
+ *
+ * @param dioPortHandle Handle to the digital I/O channel
+ * @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) {
+  auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
+  if (port == nullptr) {
+    *status = HAL_HANDLE_ERROR;
+    return;
+  }
+
+  // TODO(Thad) Figure this out
+}
+
+/**
+ * Read the filter index from the FPGA.
+ * Get the filter index used to filter out short pulses.
+ *
+ * @param dioPortHandle Handle to the digital I/O channel
+ * @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) {
+  auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
+  if (port == nullptr) {
+    *status = HAL_HANDLE_ERROR;
+    return 0;
+  }
+  return 0;
+  // TODO(Thad) Figure this out
+}
+
+/**
+ * Set the filter period for the specified filter index.
+ *
+ * Set 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) {
+  // TODO(Thad) figure this out
+}
+
+/**
+ * Get the filter period for the specified filter index.
+ *
+ * Get 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) {
+  return 0;  // TODO(Thad) figure this out
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/DigitalInternal.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/DigitalInternal.cpp
new file mode 100644
index 0000000..2c1ce47
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/DigitalInternal.cpp
@@ -0,0 +1,87 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/AnalogTrigger.h"
+#include "HAL/HAL.h"
+#include "HAL/Ports.h"
+#include "PortsInternal.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
+
+/**
+ * Map DIO channel numbers from their physical number (10 to 26) to their
+ * position in the bit field.
+ */
+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
+  }
+}
+
+/**
+ * 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) {
+  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 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/third_party/allwpilib_2018/hal/src/main/native/sim/DigitalInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/DigitalInternal.h
new file mode 100644
index 0000000..053eb0b
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/DigitalInternal.h
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "HAL/AnalogTrigger.h"
+#include "HAL/Ports.h"
+#include "HAL/Types.h"
+#include "HAL/handles/DigitalHandleResource.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "PortsInternal.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;
+
+bool remapDigitalSource(HAL_Handle digitalSourceHandle,
+                        HAL_AnalogTriggerType analogTriggerType,
+                        uint8_t& channel, uint8_t& module, bool& analogTrigger);
+int32_t remapMXPPWMChannel(int32_t channel);
+int32_t remapMXPChannel(int32_t channel);
+
+int32_t GetDigitalInputChannel(HAL_DigitalHandle handle, int32_t* status);
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/DriverStation.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/DriverStation.cpp
new file mode 100644
index 0000000..d2e2f9e
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/DriverStation.cpp
@@ -0,0 +1,312 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <support/condition_variable.h>
+#include <support/mutex.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};
+
+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->GetEnabled();
+  controlWord->autonomous = SimDriverStationData->GetAutonomous();
+  controlWord->test = SimDriverStationData->GetTest();
+  controlWord->eStop = SimDriverStationData->GetEStop();
+  controlWord->fmsAttached = SimDriverStationData->GetFmsAttached();
+  controlWord->dsAttached = SimDriverStationData->GetDsAttached();
+  return 0;
+}
+
+HAL_AllianceStationID HAL_GetAllianceStation(int32_t* status) {
+  *status = 0;
+  return SimDriverStationData->GetAllianceStationId();
+}
+
+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;
+}
+/**
+ * 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.
+ */
+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::strncpy(name, desc.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) { 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->GetMatchTime();
+}
+
+int HAL_GetMatchInfo(HAL_MatchInfo* info) {
+  SimDriverStationData->GetMatchInfo(info);
+  return 0;
+}
+
+void HAL_FreeMatchInfo(HAL_MatchInfo* info) {
+  SimDriverStationData->FreeMatchInfo(info);
+}
+
+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
+
+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;
+}
+
+/**
+ * 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);
+
+  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;
+}
+
+/*
+ * 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;
+
+  SimDriverStationData->ResetData();
+
+  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/third_party/allwpilib_2018/hal/src/main/native/sim/Encoder.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Encoder.cpp
new file mode 100644
index 0000000..870719a
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/Encoder.cpp
@@ -0,0 +1,341 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/Counter.h"
+#include "HAL/Errors.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "HAL/handles/LimitedHandleResource.h"
+#include "MockData/EncoderDataInternal.h"
+#include "PortsInternal.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_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].SetInitialized(true);
+  // 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].SetInitialized(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].GetCount();
+}
+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].GetCount() /
+         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].SetCount(0);
+  SimEncoderData[encoder->index].SetPeriod(std::numeric_limits<double>::max());
+  SimEncoderData[encoder->index].SetReset(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].GetPeriod();
+}
+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].SetMaxPeriod(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].GetPeriod() >
+         SimEncoderData[encoder->index].GetMaxPeriod();
+}
+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].GetDirection();
+}
+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].GetCount() * 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].GetPeriod();
+}
+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].SetMaxPeriod(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].SetDistancePerPulse(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].SetReverseDirection(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].SetSamplesToAverage(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].GetSamplesToAverage();
+}
+
+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/third_party/allwpilib_2018/hal/src/main/native/sim/ErrorsInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/ErrorsInternal.h
new file mode 100644
index 0000000..55372d8
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/sim/Extensions.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Extensions.cpp
new file mode 100644
index 0000000..f289b43
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/Extensions.cpp
@@ -0,0 +1,89 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <llvm/SmallString.h>
+#include <llvm/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) {
+    llvm::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;
+}
+
+/**
+ * Load any extra halsim libraries provided in the HALSIM_EXTENSIONS
+ * environment variable.
+ */
+int HAL_LoadExtensions(void) {
+  int rc = 1;
+  llvm::SmallVector<llvm::StringRef, 2> libraries;
+  const char* e = std::getenv("HALSIM_EXTENSIONS");
+  if (!e) return rc;
+  llvm::StringRef env{e};
+  env.split(libraries, DELIM, -1, false);
+  for (auto& libref : libraries) {
+    llvm::SmallString<128> library(libref);
+    rc = HAL_LoadOneExtension(library.c_str());
+    if (rc < 0) break;
+  }
+  return rc;
+}
+
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/HAL.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/HAL.cpp
new file mode 100644
index 0000000..1014a97
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/HAL.cpp
@@ -0,0 +1,281 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <llvm/raw_ostream.h>
+
+#include "ErrorsInternal.h"
+#include "HAL/DriverStation.h"
+#include "HAL/Errors.h"
+#include "HAL/Extensions.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "HALInitializer.h"
+#include "MockData/RoboRioDataInternal.h"
+#include "MockHooksInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeHAL() {
+  InitializeHandlesInternal();
+  InitializeAccelerometerData();
+  InitializeAnalogGyroData();
+  InitializeAnalogInData();
+  InitializeAnalogOutData();
+  InitializeAnalogTriggerData();
+  InitializeCanData();
+  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();
+  InitializeOSSerialPort();
+  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);
+}
+
+/**
+ * @deprecated Uses module numbers
+ */
+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;
+    default:
+      return "Unknown error status";
+  }
+}
+
+/**
+ * Returns the runtime type of this HAL
+ */
+HAL_RuntimeType HAL_GetRuntimeType(void) { return HAL_Mock; }
+
+/**
+ * Return the FPGA Version number.
+ * For now, expect this to be competition year.
+ * @return FPGA Version number.
+ */
+int32_t HAL_GetFPGAVersion(int32_t* status) {
+  return 2018;  // Automatically script this at some point
+}
+
+/**
+ * Return 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) {
+  return 0;  // TODO: Find a better number to return;
+}
+
+/**
+ * Read 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) { return hal::GetFPGATime(); }
+
+/**
+ * Get 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) {
+  return SimRoboRioData[0].GetFPGAButton();
+}
+
+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();
+
+  llvm::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/third_party/allwpilib_2018/hal/src/main/native/sim/HALInitializer.h b/third_party/allwpilib_2018/hal/src/main/native/sim/HALInitializer.h
new file mode 100644
index 0000000..92318ee
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/HALInitializer.h
@@ -0,0 +1,63 @@
+/*----------------------------------------------------------------------------*/
+/* 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
+
+namespace hal {
+namespace init {
+extern void InitializeHandlesInternal();
+extern void InitializeAccelerometerData();
+extern void InitializeAnalogGyroData();
+extern void InitializeAnalogInData();
+extern void InitializeAnalogOutData();
+extern void InitializeAnalogTriggerData();
+extern void InitializeCanData();
+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 InitializeOSSerialPort();
+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/third_party/allwpilib_2018/hal/src/main/native/sim/I2C.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/I2C.cpp
new file mode 100644
index 0000000..7108ed1
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/I2C.cpp
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "HAL/I2C.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) {
+  SimI2CData[port].SetInitialized(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].SetInitialized(false); }
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/Interrupts.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Interrupts.cpp
new file mode 100644
index 0000000..27dab1e
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/Interrupts.cpp
@@ -0,0 +1,570 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <support/condition_variable.h>
+
+#include "AnalogInternal.h"
+#include "DigitalInternal.h"
+#include "ErrorsInternal.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"
+#include "MockHooksInternal.h"
+#include "PortsInternal.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;
+  double risingTimestamp;
+  double 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_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 interrupt = interruptHandles->Get(interruptHandle);
+  interruptHandles->Free(interruptHandle);
+}
+
+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].GetValue();
+
+  int32_t uid = SimDIOData[digitalIndex].RegisterValueCallback(
+      &ProcessInterruptDigitalSynchronous,
+      reinterpret_cast<void*>(static_cast<uintptr_t>(dataHandle)), false);
+
+  bool timedOut = false;
+
+  wpi::mutex waitMutex;
+
+#if defined(_MSC_VER) && _MSC_VER < 1900
+  auto timeoutTime = std::chrono::steady_clock::now() +
+                     std::chrono::duration<int64_t, std::nano>(
+                         static_cast<int64_t>(timeout * 1e9));
+#else
+  auto timeoutTime =
+      std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
+#endif
+
+  {
+    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].CancelValueCallback(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::GetFPGATimestamp();
+    return 1 << (8 + interrupt->index);
+  } else {
+    interrupt->risingTimestamp = hal::GetFPGATimestamp();
+    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].RegisterVoltageCallback(
+      &ProcessInterruptAnalogSynchronous,
+      reinterpret_cast<void*>(static_cast<uintptr_t>(dataHandle)), false);
+
+  bool timedOut = false;
+
+  wpi::mutex waitMutex;
+
+#if defined(_MSC_VER) && _MSC_VER < 1900
+  auto timeoutTime = std::chrono::steady_clock::now() +
+                     std::chrono::duration<int64_t, std::nano>(
+                         static_cast<int64_t>(timeout * 1e9));
+#else
+  auto timeoutTime =
+      std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
+#endif
+
+  {
+    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].CancelVoltageCallback(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::GetFPGATimestamp();
+    return 1 << (8 + interrupt->index);
+  } else {
+    interrupt->risingTimestamp = hal::GetFPGATimestamp();
+    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::GetFPGATimestamp();
+    mask = 1 << (8 + interrupt->index);
+    if (!interrupt->fireOnDown) return;
+  } else {
+    interrupt->previousState = retVal;
+    interrupt->risingTimestamp = hal::GetFPGATimestamp();
+    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::GetFPGATimestamp();
+    if (!interrupt->fireOnDown) return;
+    mask = 1 << (8 + interrupt->index);
+  } else {
+    interrupt->previousState = retVal;
+    interrupt->risingTimestamp = hal::GetFPGATimestamp();
+    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].GetValue();
+
+  int32_t uid = SimDIOData[digitalIndex].RegisterValueCallback(
+      &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].RegisterVoltageCallback(
+      &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].CancelVoltageCallback(interrupt->callbackId);
+  } else {
+    int32_t status = 0;
+    int32_t digitalIndex =
+        GetDigitalInputChannel(interrupt->portHandle, &status);
+    if (status != 0) return;
+    SimDIOData[digitalIndex].CancelValueCallback(interrupt->callbackId);
+  }
+  interrupt->callbackId = -1;
+}
+double 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;
+}
+double 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/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AccelerometerData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AccelerometerData.cpp
new file mode 100644
index 0000000..173d7e3
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AccelerometerData.cpp
@@ -0,0 +1,334 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+#include "MockData/NotifyCallbackHelpers.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() {
+  m_active = false;
+  m_activeCallbacks = nullptr;
+  m_range = static_cast<HAL_AccelerometerRange>(0);
+  m_rangeCallbacks = nullptr;
+  m_x = 0.0;
+  m_xCallbacks = nullptr;
+  m_y = 0.0;
+  m_yCallbacks = nullptr;
+  m_z = 0.0;
+  m_zCallbacks = nullptr;
+}
+
+int32_t AccelerometerData::RegisterActiveCallback(HAL_NotifyCallback callback,
+                                                  void* param,
+                                                  HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_activeCallbacks =
+        RegisterCallback(m_activeCallbacks, "Active", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetActive());
+    callback("Active", param, &value);
+  }
+  return newUid;
+}
+
+void AccelerometerData::CancelActiveCallback(int32_t uid) {
+  m_activeCallbacks = CancelCallback(m_activeCallbacks, uid);
+}
+
+void AccelerometerData::InvokeActiveCallback(HAL_Value value) {
+  InvokeCallback(m_activeCallbacks, "Active", &value);
+}
+
+HAL_Bool AccelerometerData::GetActive() { return m_active; }
+
+void AccelerometerData::SetActive(HAL_Bool active) {
+  HAL_Bool oldValue = m_active.exchange(active);
+  if (oldValue != active) {
+    InvokeActiveCallback(MakeBoolean(active));
+  }
+}
+
+int32_t AccelerometerData::RegisterRangeCallback(HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_rangeCallbacks =
+        RegisterCallback(m_rangeCallbacks, "Range", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeEnum(GetRange());
+    callback("Range", param, &value);
+  }
+  return newUid;
+}
+
+void AccelerometerData::CancelRangeCallback(int32_t uid) {
+  m_rangeCallbacks = CancelCallback(m_rangeCallbacks, uid);
+}
+
+void AccelerometerData::InvokeRangeCallback(HAL_Value value) {
+  InvokeCallback(m_rangeCallbacks, "Range", &value);
+}
+
+HAL_AccelerometerRange AccelerometerData::GetRange() { return m_range; }
+
+void AccelerometerData::SetRange(HAL_AccelerometerRange range) {
+  HAL_AccelerometerRange oldValue = m_range.exchange(range);
+  if (oldValue != range) {
+    InvokeRangeCallback(MakeEnum(range));
+  }
+}
+
+int32_t AccelerometerData::RegisterXCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_xCallbacks =
+        RegisterCallback(m_xCallbacks, "X", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetX());
+    callback("X", param, &value);
+  }
+  return newUid;
+}
+
+void AccelerometerData::CancelXCallback(int32_t uid) {
+  m_xCallbacks = CancelCallback(m_xCallbacks, uid);
+}
+
+void AccelerometerData::InvokeXCallback(HAL_Value value) {
+  InvokeCallback(m_xCallbacks, "X", &value);
+}
+
+double AccelerometerData::GetX() { return m_x; }
+
+void AccelerometerData::SetX(double x) {
+  double oldValue = m_x.exchange(x);
+  if (oldValue != x) {
+    InvokeXCallback(MakeDouble(x));
+  }
+}
+
+int32_t AccelerometerData::RegisterYCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_yCallbacks =
+        RegisterCallback(m_yCallbacks, "Y", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetY());
+    callback("Y", param, &value);
+  }
+  return newUid;
+}
+
+void AccelerometerData::CancelYCallback(int32_t uid) {
+  m_yCallbacks = CancelCallback(m_yCallbacks, uid);
+}
+
+void AccelerometerData::InvokeYCallback(HAL_Value value) {
+  InvokeCallback(m_yCallbacks, "Y", &value);
+}
+
+double AccelerometerData::GetY() { return m_y; }
+
+void AccelerometerData::SetY(double y) {
+  double oldValue = m_y.exchange(y);
+  if (oldValue != y) {
+    InvokeYCallback(MakeDouble(y));
+  }
+}
+
+int32_t AccelerometerData::RegisterZCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_zCallbacks =
+        RegisterCallback(m_zCallbacks, "Z", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetZ());
+    callback("Z", param, &value);
+  }
+  return newUid;
+}
+
+void AccelerometerData::CancelZCallback(int32_t uid) {
+  m_zCallbacks = CancelCallback(m_zCallbacks, uid);
+}
+
+void AccelerometerData::InvokeZCallback(HAL_Value value) {
+  InvokeCallback(m_zCallbacks, "Z", &value);
+}
+
+double AccelerometerData::GetZ() { return m_z; }
+
+void AccelerometerData::SetZ(double z) {
+  double oldValue = m_z.exchange(z);
+  if (oldValue != z) {
+    InvokeZCallback(MakeDouble(z));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetAccelerometerData(int32_t index) {
+  SimAccelerometerData[index].ResetData();
+}
+
+int32_t HALSIM_RegisterAccelerometerActiveCallback(int32_t index,
+                                                   HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  return SimAccelerometerData[index].RegisterActiveCallback(callback, param,
+                                                            initialNotify);
+}
+
+void HALSIM_CancelAccelerometerActiveCallback(int32_t index, int32_t uid) {
+  SimAccelerometerData[index].CancelActiveCallback(uid);
+}
+
+HAL_Bool HALSIM_GetAccelerometerActive(int32_t index) {
+  return SimAccelerometerData[index].GetActive();
+}
+
+void HALSIM_SetAccelerometerActive(int32_t index, HAL_Bool active) {
+  SimAccelerometerData[index].SetActive(active);
+}
+
+int32_t HALSIM_RegisterAccelerometerRangeCallback(int32_t index,
+                                                  HAL_NotifyCallback callback,
+                                                  void* param,
+                                                  HAL_Bool initialNotify) {
+  return SimAccelerometerData[index].RegisterRangeCallback(callback, param,
+                                                           initialNotify);
+}
+
+void HALSIM_CancelAccelerometerRangeCallback(int32_t index, int32_t uid) {
+  SimAccelerometerData[index].CancelRangeCallback(uid);
+}
+
+HAL_AccelerometerRange HALSIM_GetAccelerometerRange(int32_t index) {
+  return SimAccelerometerData[index].GetRange();
+}
+
+void HALSIM_SetAccelerometerRange(int32_t index, HAL_AccelerometerRange range) {
+  SimAccelerometerData[index].SetRange(range);
+}
+
+int32_t HALSIM_RegisterAccelerometerXCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimAccelerometerData[index].RegisterXCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelAccelerometerXCallback(int32_t index, int32_t uid) {
+  SimAccelerometerData[index].CancelXCallback(uid);
+}
+
+double HALSIM_GetAccelerometerX(int32_t index) {
+  return SimAccelerometerData[index].GetX();
+}
+
+void HALSIM_SetAccelerometerX(int32_t index, double x) {
+  SimAccelerometerData[index].SetX(x);
+}
+
+int32_t HALSIM_RegisterAccelerometerYCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimAccelerometerData[index].RegisterYCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelAccelerometerYCallback(int32_t index, int32_t uid) {
+  SimAccelerometerData[index].CancelYCallback(uid);
+}
+
+double HALSIM_GetAccelerometerY(int32_t index) {
+  return SimAccelerometerData[index].GetY();
+}
+
+void HALSIM_SetAccelerometerY(int32_t index, double y) {
+  SimAccelerometerData[index].SetY(y);
+}
+
+int32_t HALSIM_RegisterAccelerometerZCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimAccelerometerData[index].RegisterZCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelAccelerometerZCallback(int32_t index, int32_t uid) {
+  SimAccelerometerData[index].CancelZCallback(uid);
+}
+
+double HALSIM_GetAccelerometerZ(int32_t index) {
+  return SimAccelerometerData[index].GetZ();
+}
+
+void HALSIM_SetAccelerometerZ(int32_t index, double z) {
+  SimAccelerometerData[index].SetZ(z);
+}
+
+void HALSIM_RegisterAccelerometerAllCallbacks(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  SimAccelerometerData[index].RegisterActiveCallback(callback, param,
+                                                     initialNotify);
+  SimAccelerometerData[index].RegisterRangeCallback(callback, param,
+                                                    initialNotify);
+  SimAccelerometerData[index].RegisterXCallback(callback, param, initialNotify);
+  SimAccelerometerData[index].RegisterYCallback(callback, param, initialNotify);
+  SimAccelerometerData[index].RegisterZCallback(callback, param, initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AccelerometerDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AccelerometerDataInternal.h
new file mode 100644
index 0000000..08efbc6
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AccelerometerDataInternal.h
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <atomic>
+#include <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/AccelerometerData.h"
+#include "MockData/NotifyListenerVector.h"
+
+namespace hal {
+class AccelerometerData {
+ public:
+  int32_t RegisterActiveCallback(HAL_NotifyCallback callback, void* param,
+                                 HAL_Bool initialNotify);
+  void CancelActiveCallback(int32_t uid);
+  void InvokeActiveCallback(HAL_Value value);
+  HAL_Bool GetActive();
+  void SetActive(HAL_Bool active);
+
+  int32_t RegisterRangeCallback(HAL_NotifyCallback callback, void* param,
+                                HAL_Bool initialNotify);
+  void CancelRangeCallback(int32_t uid);
+  void InvokeRangeCallback(HAL_Value value);
+  HAL_AccelerometerRange GetRange();
+  void SetRange(HAL_AccelerometerRange range);
+
+  int32_t RegisterXCallback(HAL_NotifyCallback callback, void* param,
+                            HAL_Bool initialNotify);
+  void CancelXCallback(int32_t uid);
+  void InvokeXCallback(HAL_Value value);
+  double GetX();
+  void SetX(double x);
+
+  int32_t RegisterYCallback(HAL_NotifyCallback callback, void* param,
+                            HAL_Bool initialNotify);
+  void CancelYCallback(int32_t uid);
+  void InvokeYCallback(HAL_Value value);
+  double GetY();
+  void SetY(double y);
+
+  int32_t RegisterZCallback(HAL_NotifyCallback callback, void* param,
+                            HAL_Bool initialNotify);
+  void CancelZCallback(int32_t uid);
+  void InvokeZCallback(HAL_Value value);
+  double GetZ();
+  void SetZ(double z);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_active{false};
+  std::shared_ptr<NotifyListenerVector> m_activeCallbacks = nullptr;
+  std::atomic<HAL_AccelerometerRange> m_range{
+      static_cast<HAL_AccelerometerRange>(0)};
+  std::shared_ptr<NotifyListenerVector> m_rangeCallbacks = nullptr;
+  std::atomic<double> m_x{0.0};
+  std::shared_ptr<NotifyListenerVector> m_xCallbacks = nullptr;
+  std::atomic<double> m_y{0.0};
+  std::shared_ptr<NotifyListenerVector> m_yCallbacks = nullptr;
+  std::atomic<double> m_z{0.0};
+  std::shared_ptr<NotifyListenerVector> m_zCallbacks = nullptr;
+};
+extern AccelerometerData* SimAccelerometerData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogGyroData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogGyroData.cpp
new file mode 100644
index 0000000..cce0586
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogGyroData.cpp
@@ -0,0 +1,215 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+#include "MockData/NotifyCallbackHelpers.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() {
+  m_angle = 0.0;
+  m_angleCallbacks = nullptr;
+  m_rate = 0.0;
+  m_rateCallbacks = nullptr;
+  m_initialized = false;
+  m_initializedCallbacks = nullptr;
+}
+
+int32_t AnalogGyroData::RegisterAngleCallback(HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_angleCallbacks =
+        RegisterCallback(m_angleCallbacks, "Angle", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetAngle());
+    callback("Angle", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogGyroData::CancelAngleCallback(int32_t uid) {
+  m_angleCallbacks = CancelCallback(m_angleCallbacks, uid);
+}
+
+void AnalogGyroData::InvokeAngleCallback(HAL_Value value) {
+  InvokeCallback(m_angleCallbacks, "Angle", &value);
+}
+
+double AnalogGyroData::GetAngle() { return m_angle; }
+
+void AnalogGyroData::SetAngle(double angle) {
+  double oldValue = m_angle.exchange(angle);
+  if (oldValue != angle) {
+    InvokeAngleCallback(MakeDouble(angle));
+  }
+}
+
+int32_t AnalogGyroData::RegisterRateCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_rateCallbacks =
+        RegisterCallback(m_rateCallbacks, "Rate", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetRate());
+    callback("Rate", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogGyroData::CancelRateCallback(int32_t uid) {
+  m_rateCallbacks = CancelCallback(m_rateCallbacks, uid);
+}
+
+void AnalogGyroData::InvokeRateCallback(HAL_Value value) {
+  InvokeCallback(m_rateCallbacks, "Rate", &value);
+}
+
+double AnalogGyroData::GetRate() { return m_rate; }
+
+void AnalogGyroData::SetRate(double rate) {
+  double oldValue = m_rate.exchange(rate);
+  if (oldValue != rate) {
+    InvokeRateCallback(MakeDouble(rate));
+  }
+}
+
+int32_t AnalogGyroData::RegisterInitializedCallback(HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedCallbacks = RegisterCallback(
+        m_initializedCallbacks, "Initialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitialized());
+    callback("Initialized", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogGyroData::CancelInitializedCallback(int32_t uid) {
+  m_initializedCallbacks = CancelCallback(m_initializedCallbacks, uid);
+}
+
+void AnalogGyroData::InvokeInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_initializedCallbacks, "Initialized", &value);
+}
+
+HAL_Bool AnalogGyroData::GetInitialized() { return m_initialized; }
+
+void AnalogGyroData::SetInitialized(HAL_Bool initialized) {
+  HAL_Bool oldValue = m_initialized.exchange(initialized);
+  if (oldValue != initialized) {
+    InvokeInitializedCallback(MakeBoolean(initialized));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetAnalogGyroData(int32_t index) {
+  SimAnalogGyroData[index].ResetData();
+}
+
+int32_t HALSIM_RegisterAnalogGyroAngleCallback(int32_t index,
+                                               HAL_NotifyCallback callback,
+                                               void* param,
+                                               HAL_Bool initialNotify) {
+  return SimAnalogGyroData[index].RegisterAngleCallback(callback, param,
+                                                        initialNotify);
+}
+
+void HALSIM_CancelAnalogGyroAngleCallback(int32_t index, int32_t uid) {
+  SimAnalogGyroData[index].CancelAngleCallback(uid);
+}
+
+double HALSIM_GetAnalogGyroAngle(int32_t index) {
+  return SimAnalogGyroData[index].GetAngle();
+}
+
+void HALSIM_SetAnalogGyroAngle(int32_t index, double angle) {
+  SimAnalogGyroData[index].SetAngle(angle);
+}
+
+int32_t HALSIM_RegisterAnalogGyroRateCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimAnalogGyroData[index].RegisterRateCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelAnalogGyroRateCallback(int32_t index, int32_t uid) {
+  SimAnalogGyroData[index].CancelRateCallback(uid);
+}
+
+double HALSIM_GetAnalogGyroRate(int32_t index) {
+  return SimAnalogGyroData[index].GetRate();
+}
+
+void HALSIM_SetAnalogGyroRate(int32_t index, double rate) {
+  SimAnalogGyroData[index].SetRate(rate);
+}
+
+int32_t HALSIM_RegisterAnalogGyroInitializedCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimAnalogGyroData[index].RegisterInitializedCallback(callback, param,
+                                                              initialNotify);
+}
+
+void HALSIM_CancelAnalogGyroInitializedCallback(int32_t index, int32_t uid) {
+  SimAnalogGyroData[index].CancelInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetAnalogGyroInitialized(int32_t index) {
+  return SimAnalogGyroData[index].GetInitialized();
+}
+
+void HALSIM_SetAnalogGyroInitialized(int32_t index, HAL_Bool initialized) {
+  SimAnalogGyroData[index].SetInitialized(initialized);
+}
+
+void HALSIM_RegisterAnalogGyroAllCallbacks(int32_t index,
+                                           HAL_NotifyCallback callback,
+                                           void* param,
+                                           HAL_Bool initialNotify) {
+  SimAnalogGyroData[index].RegisterAngleCallback(callback, param,
+                                                 initialNotify);
+  SimAnalogGyroData[index].RegisterRateCallback(callback, param, initialNotify);
+  SimAnalogGyroData[index].RegisterInitializedCallback(callback, param,
+                                                       initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogGyroDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogGyroDataInternal.h
new file mode 100644
index 0000000..180d7ef
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogGyroDataInternal.h
@@ -0,0 +1,54 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/AnalogGyroData.h"
+#include "MockData/NotifyListenerVector.h"
+
+namespace hal {
+class AnalogGyroData {
+ public:
+  int32_t RegisterAngleCallback(HAL_NotifyCallback callback, void* param,
+                                HAL_Bool initialNotify);
+  void CancelAngleCallback(int32_t uid);
+  void InvokeAngleCallback(HAL_Value value);
+  double GetAngle();
+  void SetAngle(double angle);
+
+  int32_t RegisterRateCallback(HAL_NotifyCallback callback, void* param,
+                               HAL_Bool initialNotify);
+  void CancelRateCallback(int32_t uid);
+  void InvokeRateCallback(HAL_Value value);
+  double GetRate();
+  void SetRate(double rate);
+
+  int32_t RegisterInitializedCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelInitializedCallback(int32_t uid);
+  void InvokeInitializedCallback(HAL_Value value);
+  HAL_Bool GetInitialized();
+  void SetInitialized(HAL_Bool initialized);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<double> m_angle{0.0};
+  std::shared_ptr<NotifyListenerVector> m_angleCallbacks = nullptr;
+  std::atomic<double> m_rate{0.0};
+  std::shared_ptr<NotifyListenerVector> m_rateCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_initialized{false};
+  std::shared_ptr<NotifyListenerVector> m_initializedCallbacks = nullptr;
+};
+extern AnalogGyroData* SimAnalogGyroData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogInData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogInData.cpp
new file mode 100644
index 0000000..79f7a22
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogInData.cpp
@@ -0,0 +1,585 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+#include "MockData/NotifyCallbackHelpers.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() {
+  m_initialized = false;
+  m_initializedCallbacks = nullptr;
+  m_averageBits = 7;
+  m_averageBitsCallbacks = nullptr;
+  m_oversampleBits = 0;
+  m_oversampleBitsCallbacks = nullptr;
+  m_voltage = 0.0;
+  m_voltageCallbacks = nullptr;
+  m_accumulatorInitialized = false;
+  m_accumulatorInitializedCallbacks = nullptr;
+  m_accumulatorValue = 0;
+  m_accumulatorValueCallbacks = nullptr;
+  m_accumulatorCount = 0;
+  m_accumulatorCountCallbacks = nullptr;
+  m_accumulatorCenter = 0;
+  m_accumulatorCenterCallbacks = nullptr;
+  m_accumulatorDeadband = 0;
+  m_accumulatorDeadbandCallbacks = nullptr;
+}
+
+int32_t AnalogInData::RegisterInitializedCallback(HAL_NotifyCallback callback,
+                                                  void* param,
+                                                  HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedCallbacks = RegisterCallback(
+        m_initializedCallbacks, "Initialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitialized());
+    callback("Initialized", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogInData::CancelInitializedCallback(int32_t uid) {
+  m_initializedCallbacks = CancelCallback(m_initializedCallbacks, uid);
+}
+
+void AnalogInData::InvokeInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_initializedCallbacks, "Initialized", &value);
+}
+
+HAL_Bool AnalogInData::GetInitialized() { return m_initialized; }
+
+void AnalogInData::SetInitialized(HAL_Bool initialized) {
+  HAL_Bool oldValue = m_initialized.exchange(initialized);
+  if (oldValue != initialized) {
+    InvokeInitializedCallback(MakeBoolean(initialized));
+  }
+}
+
+int32_t AnalogInData::RegisterAverageBitsCallback(HAL_NotifyCallback callback,
+                                                  void* param,
+                                                  HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_averageBitsCallbacks = RegisterCallback(
+        m_averageBitsCallbacks, "AverageBits", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetAverageBits());
+    callback("AverageBits", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogInData::CancelAverageBitsCallback(int32_t uid) {
+  m_averageBitsCallbacks = CancelCallback(m_averageBitsCallbacks, uid);
+}
+
+void AnalogInData::InvokeAverageBitsCallback(HAL_Value value) {
+  InvokeCallback(m_averageBitsCallbacks, "AverageBits", &value);
+}
+
+int32_t AnalogInData::GetAverageBits() { return m_averageBits; }
+
+void AnalogInData::SetAverageBits(int32_t averageBits) {
+  int32_t oldValue = m_averageBits.exchange(averageBits);
+  if (oldValue != averageBits) {
+    InvokeAverageBitsCallback(MakeInt(averageBits));
+  }
+}
+
+int32_t AnalogInData::RegisterOversampleBitsCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_oversampleBitsCallbacks = RegisterCallback(
+        m_oversampleBitsCallbacks, "OversampleBits", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetOversampleBits());
+    callback("OversampleBits", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogInData::CancelOversampleBitsCallback(int32_t uid) {
+  m_oversampleBitsCallbacks = CancelCallback(m_oversampleBitsCallbacks, uid);
+}
+
+void AnalogInData::InvokeOversampleBitsCallback(HAL_Value value) {
+  InvokeCallback(m_oversampleBitsCallbacks, "OversampleBits", &value);
+}
+
+int32_t AnalogInData::GetOversampleBits() { return m_oversampleBits; }
+
+void AnalogInData::SetOversampleBits(int32_t oversampleBits) {
+  int32_t oldValue = m_oversampleBits.exchange(oversampleBits);
+  if (oldValue != oversampleBits) {
+    InvokeOversampleBitsCallback(MakeInt(oversampleBits));
+  }
+}
+
+int32_t AnalogInData::RegisterVoltageCallback(HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_voltageCallbacks = RegisterCallback(m_voltageCallbacks, "Voltage",
+                                          callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetVoltage());
+    callback("Voltage", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogInData::CancelVoltageCallback(int32_t uid) {
+  m_voltageCallbacks = CancelCallback(m_voltageCallbacks, uid);
+}
+
+void AnalogInData::InvokeVoltageCallback(HAL_Value value) {
+  InvokeCallback(m_voltageCallbacks, "Voltage", &value);
+}
+
+double AnalogInData::GetVoltage() { return m_voltage; }
+
+void AnalogInData::SetVoltage(double voltage) {
+  double oldValue = m_voltage.exchange(voltage);
+  if (oldValue != voltage) {
+    InvokeVoltageCallback(MakeDouble(voltage));
+  }
+}
+
+int32_t AnalogInData::RegisterAccumulatorInitializedCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_accumulatorInitializedCallbacks =
+        RegisterCallback(m_accumulatorInitializedCallbacks,
+                         "AccumulatorInitialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetAccumulatorInitialized());
+    callback("AccumulatorInitialized", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogInData::CancelAccumulatorInitializedCallback(int32_t uid) {
+  m_accumulatorInitializedCallbacks =
+      CancelCallback(m_accumulatorInitializedCallbacks, uid);
+}
+
+void AnalogInData::InvokeAccumulatorInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_accumulatorInitializedCallbacks, "AccumulatorInitialized",
+                 &value);
+}
+
+HAL_Bool AnalogInData::GetAccumulatorInitialized() {
+  return m_accumulatorInitialized;
+}
+
+void AnalogInData::SetAccumulatorInitialized(HAL_Bool accumulatorInitialized) {
+  HAL_Bool oldValue = m_accumulatorInitialized.exchange(accumulatorInitialized);
+  if (oldValue != accumulatorInitialized) {
+    InvokeAccumulatorInitializedCallback(MakeBoolean(accumulatorInitialized));
+  }
+}
+
+int32_t AnalogInData::RegisterAccumulatorValueCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_accumulatorValueCallbacks =
+        RegisterCallback(m_accumulatorValueCallbacks, "AccumulatorValue",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeLong(GetAccumulatorValue());
+    callback("AccumulatorValue", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogInData::CancelAccumulatorValueCallback(int32_t uid) {
+  m_accumulatorValueCallbacks =
+      CancelCallback(m_accumulatorValueCallbacks, uid);
+}
+
+void AnalogInData::InvokeAccumulatorValueCallback(HAL_Value value) {
+  InvokeCallback(m_accumulatorValueCallbacks, "AccumulatorValue", &value);
+}
+
+int64_t AnalogInData::GetAccumulatorValue() { return m_accumulatorValue; }
+
+void AnalogInData::SetAccumulatorValue(int64_t accumulatorValue) {
+  int64_t oldValue = m_accumulatorValue.exchange(accumulatorValue);
+  if (oldValue != accumulatorValue) {
+    InvokeAccumulatorValueCallback(MakeLong(accumulatorValue));
+  }
+}
+
+int32_t AnalogInData::RegisterAccumulatorCountCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_accumulatorCountCallbacks =
+        RegisterCallback(m_accumulatorCountCallbacks, "AccumulatorCount",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeLong(GetAccumulatorCount());
+    callback("AccumulatorCount", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogInData::CancelAccumulatorCountCallback(int32_t uid) {
+  m_accumulatorCountCallbacks =
+      CancelCallback(m_accumulatorCountCallbacks, uid);
+}
+
+void AnalogInData::InvokeAccumulatorCountCallback(HAL_Value value) {
+  InvokeCallback(m_accumulatorCountCallbacks, "AccumulatorCount", &value);
+}
+
+int64_t AnalogInData::GetAccumulatorCount() { return m_accumulatorCount; }
+
+void AnalogInData::SetAccumulatorCount(int64_t accumulatorCount) {
+  int64_t oldValue = m_accumulatorCount.exchange(accumulatorCount);
+  if (oldValue != accumulatorCount) {
+    InvokeAccumulatorCountCallback(MakeLong(accumulatorCount));
+  }
+}
+
+int32_t AnalogInData::RegisterAccumulatorCenterCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_accumulatorCenterCallbacks =
+        RegisterCallback(m_accumulatorCenterCallbacks, "AccumulatorCenter",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetAccumulatorCenter());
+    callback("AccumulatorCenter", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogInData::CancelAccumulatorCenterCallback(int32_t uid) {
+  m_accumulatorCenterCallbacks =
+      CancelCallback(m_accumulatorCenterCallbacks, uid);
+}
+
+void AnalogInData::InvokeAccumulatorCenterCallback(HAL_Value value) {
+  InvokeCallback(m_accumulatorCenterCallbacks, "AccumulatorCenter", &value);
+}
+
+int32_t AnalogInData::GetAccumulatorCenter() { return m_accumulatorCenter; }
+
+void AnalogInData::SetAccumulatorCenter(int32_t accumulatorCenter) {
+  int32_t oldValue = m_accumulatorCenter.exchange(accumulatorCenter);
+  if (oldValue != accumulatorCenter) {
+    InvokeAccumulatorCenterCallback(MakeInt(accumulatorCenter));
+  }
+}
+
+int32_t AnalogInData::RegisterAccumulatorDeadbandCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_accumulatorDeadbandCallbacks =
+        RegisterCallback(m_accumulatorDeadbandCallbacks, "AccumulatorDeadband",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetAccumulatorDeadband());
+    callback("AccumulatorDeadband", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogInData::CancelAccumulatorDeadbandCallback(int32_t uid) {
+  m_accumulatorDeadbandCallbacks =
+      CancelCallback(m_accumulatorDeadbandCallbacks, uid);
+}
+
+void AnalogInData::InvokeAccumulatorDeadbandCallback(HAL_Value value) {
+  InvokeCallback(m_accumulatorDeadbandCallbacks, "AccumulatorDeadband", &value);
+}
+
+int32_t AnalogInData::GetAccumulatorDeadband() { return m_accumulatorDeadband; }
+
+void AnalogInData::SetAccumulatorDeadband(int32_t accumulatorDeadband) {
+  int32_t oldValue = m_accumulatorDeadband.exchange(accumulatorDeadband);
+  if (oldValue != accumulatorDeadband) {
+    InvokeAccumulatorDeadbandCallback(MakeInt(accumulatorDeadband));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetAnalogInData(int32_t index) {
+  SimAnalogInData[index].ResetData();
+}
+
+int32_t HALSIM_RegisterAnalogInInitializedCallback(int32_t index,
+                                                   HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  return SimAnalogInData[index].RegisterInitializedCallback(callback, param,
+                                                            initialNotify);
+}
+
+void HALSIM_CancelAnalogInInitializedCallback(int32_t index, int32_t uid) {
+  SimAnalogInData[index].CancelInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetAnalogInInitialized(int32_t index) {
+  return SimAnalogInData[index].GetInitialized();
+}
+
+void HALSIM_SetAnalogInInitialized(int32_t index, HAL_Bool initialized) {
+  SimAnalogInData[index].SetInitialized(initialized);
+}
+
+int32_t HALSIM_RegisterAnalogInAverageBitsCallback(int32_t index,
+                                                   HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  return SimAnalogInData[index].RegisterAverageBitsCallback(callback, param,
+                                                            initialNotify);
+}
+
+void HALSIM_CancelAnalogInAverageBitsCallback(int32_t index, int32_t uid) {
+  SimAnalogInData[index].CancelAverageBitsCallback(uid);
+}
+
+int32_t HALSIM_GetAnalogInAverageBits(int32_t index) {
+  return SimAnalogInData[index].GetAverageBits();
+}
+
+void HALSIM_SetAnalogInAverageBits(int32_t index, int32_t averageBits) {
+  SimAnalogInData[index].SetAverageBits(averageBits);
+}
+
+int32_t HALSIM_RegisterAnalogInOversampleBitsCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimAnalogInData[index].RegisterOversampleBitsCallback(callback, param,
+                                                               initialNotify);
+}
+
+void HALSIM_CancelAnalogInOversampleBitsCallback(int32_t index, int32_t uid) {
+  SimAnalogInData[index].CancelOversampleBitsCallback(uid);
+}
+
+int32_t HALSIM_GetAnalogInOversampleBits(int32_t index) {
+  return SimAnalogInData[index].GetOversampleBits();
+}
+
+void HALSIM_SetAnalogInOversampleBits(int32_t index, int32_t oversampleBits) {
+  SimAnalogInData[index].SetOversampleBits(oversampleBits);
+}
+
+int32_t HALSIM_RegisterAnalogInVoltageCallback(int32_t index,
+                                               HAL_NotifyCallback callback,
+                                               void* param,
+                                               HAL_Bool initialNotify) {
+  return SimAnalogInData[index].RegisterVoltageCallback(callback, param,
+                                                        initialNotify);
+}
+
+void HALSIM_CancelAnalogInVoltageCallback(int32_t index, int32_t uid) {
+  SimAnalogInData[index].CancelVoltageCallback(uid);
+}
+
+double HALSIM_GetAnalogInVoltage(int32_t index) {
+  return SimAnalogInData[index].GetVoltage();
+}
+
+void HALSIM_SetAnalogInVoltage(int32_t index, double voltage) {
+  SimAnalogInData[index].SetVoltage(voltage);
+}
+
+int32_t HALSIM_RegisterAnalogInAccumulatorInitializedCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimAnalogInData[index].RegisterAccumulatorInitializedCallback(
+      callback, param, initialNotify);
+}
+
+void HALSIM_CancelAnalogInAccumulatorInitializedCallback(int32_t index,
+                                                         int32_t uid) {
+  SimAnalogInData[index].CancelAccumulatorInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetAnalogInAccumulatorInitialized(int32_t index) {
+  return SimAnalogInData[index].GetAccumulatorInitialized();
+}
+
+void HALSIM_SetAnalogInAccumulatorInitialized(int32_t index,
+                                              HAL_Bool accumulatorInitialized) {
+  SimAnalogInData[index].SetAccumulatorInitialized(accumulatorInitialized);
+}
+
+int32_t HALSIM_RegisterAnalogInAccumulatorValueCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimAnalogInData[index].RegisterAccumulatorValueCallback(
+      callback, param, initialNotify);
+}
+
+void HALSIM_CancelAnalogInAccumulatorValueCallback(int32_t index, int32_t uid) {
+  SimAnalogInData[index].CancelAccumulatorValueCallback(uid);
+}
+
+int64_t HALSIM_GetAnalogInAccumulatorValue(int32_t index) {
+  return SimAnalogInData[index].GetAccumulatorValue();
+}
+
+void HALSIM_SetAnalogInAccumulatorValue(int32_t index,
+                                        int64_t accumulatorValue) {
+  SimAnalogInData[index].SetAccumulatorValue(accumulatorValue);
+}
+
+int32_t HALSIM_RegisterAnalogInAccumulatorCountCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimAnalogInData[index].RegisterAccumulatorCountCallback(
+      callback, param, initialNotify);
+}
+
+void HALSIM_CancelAnalogInAccumulatorCountCallback(int32_t index, int32_t uid) {
+  SimAnalogInData[index].CancelAccumulatorCountCallback(uid);
+}
+
+int64_t HALSIM_GetAnalogInAccumulatorCount(int32_t index) {
+  return SimAnalogInData[index].GetAccumulatorCount();
+}
+
+void HALSIM_SetAnalogInAccumulatorCount(int32_t index,
+                                        int64_t accumulatorCount) {
+  SimAnalogInData[index].SetAccumulatorCount(accumulatorCount);
+}
+
+int32_t HALSIM_RegisterAnalogInAccumulatorCenterCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimAnalogInData[index].RegisterAccumulatorCenterCallback(
+      callback, param, initialNotify);
+}
+
+void HALSIM_CancelAnalogInAccumulatorCenterCallback(int32_t index,
+                                                    int32_t uid) {
+  SimAnalogInData[index].CancelAccumulatorCenterCallback(uid);
+}
+
+int32_t HALSIM_GetAnalogInAccumulatorCenter(int32_t index) {
+  return SimAnalogInData[index].GetAccumulatorCenter();
+}
+
+void HALSIM_SetAnalogInAccumulatorCenter(int32_t index,
+                                         int32_t accumulatorCenter) {
+  SimAnalogInData[index].SetAccumulatorCenter(accumulatorCenter);
+}
+
+int32_t HALSIM_RegisterAnalogInAccumulatorDeadbandCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimAnalogInData[index].RegisterAccumulatorDeadbandCallback(
+      callback, param, initialNotify);
+}
+
+void HALSIM_CancelAnalogInAccumulatorDeadbandCallback(int32_t index,
+                                                      int32_t uid) {
+  SimAnalogInData[index].CancelAccumulatorDeadbandCallback(uid);
+}
+
+int32_t HALSIM_GetAnalogInAccumulatorDeadband(int32_t index) {
+  return SimAnalogInData[index].GetAccumulatorDeadband();
+}
+
+void HALSIM_SetAnalogInAccumulatorDeadband(int32_t index,
+                                           int32_t accumulatorDeadband) {
+  SimAnalogInData[index].SetAccumulatorDeadband(accumulatorDeadband);
+}
+
+void HALSIM_RegisterAnalogInAllCallbacks(int32_t index,
+                                         HAL_NotifyCallback callback,
+                                         void* param, HAL_Bool initialNotify) {
+  SimAnalogInData[index].RegisterInitializedCallback(callback, param,
+                                                     initialNotify);
+  SimAnalogInData[index].RegisterAverageBitsCallback(callback, param,
+                                                     initialNotify);
+  SimAnalogInData[index].RegisterOversampleBitsCallback(callback, param,
+                                                        initialNotify);
+  SimAnalogInData[index].RegisterVoltageCallback(callback, param,
+                                                 initialNotify);
+  SimAnalogInData[index].RegisterAccumulatorInitializedCallback(callback, param,
+                                                                initialNotify);
+  SimAnalogInData[index].RegisterAccumulatorValueCallback(callback, param,
+                                                          initialNotify);
+  SimAnalogInData[index].RegisterAccumulatorCountCallback(callback, param,
+                                                          initialNotify);
+  SimAnalogInData[index].RegisterAccumulatorCenterCallback(callback, param,
+                                                           initialNotify);
+  SimAnalogInData[index].RegisterAccumulatorDeadbandCallback(callback, param,
+                                                             initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogInDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogInDataInternal.h
new file mode 100644
index 0000000..5000e16
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogInDataInternal.h
@@ -0,0 +1,113 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/AnalogInData.h"
+#include "MockData/NotifyListenerVector.h"
+
+namespace hal {
+class AnalogInData {
+ public:
+  int32_t RegisterInitializedCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelInitializedCallback(int32_t uid);
+  void InvokeInitializedCallback(HAL_Value value);
+  HAL_Bool GetInitialized();
+  void SetInitialized(HAL_Bool initialized);
+
+  int32_t RegisterAverageBitsCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelAverageBitsCallback(int32_t uid);
+  void InvokeAverageBitsCallback(HAL_Value value);
+  int32_t GetAverageBits();
+  void SetAverageBits(int32_t averageBits);
+
+  int32_t RegisterOversampleBitsCallback(HAL_NotifyCallback callback,
+                                         void* param, HAL_Bool initialNotify);
+  void CancelOversampleBitsCallback(int32_t uid);
+  void InvokeOversampleBitsCallback(HAL_Value value);
+  int32_t GetOversampleBits();
+  void SetOversampleBits(int32_t oversampleBits);
+
+  int32_t RegisterVoltageCallback(HAL_NotifyCallback callback, void* param,
+                                  HAL_Bool initialNotify);
+  void CancelVoltageCallback(int32_t uid);
+  void InvokeVoltageCallback(HAL_Value value);
+  double GetVoltage();
+  void SetVoltage(double voltage);
+
+  int32_t RegisterAccumulatorInitializedCallback(HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify);
+  void CancelAccumulatorInitializedCallback(int32_t uid);
+  void InvokeAccumulatorInitializedCallback(HAL_Value value);
+  HAL_Bool GetAccumulatorInitialized();
+  void SetAccumulatorInitialized(HAL_Bool accumulatorInitialized);
+
+  int32_t RegisterAccumulatorValueCallback(HAL_NotifyCallback callback,
+                                           void* param, HAL_Bool initialNotify);
+  void CancelAccumulatorValueCallback(int32_t uid);
+  void InvokeAccumulatorValueCallback(HAL_Value value);
+  int64_t GetAccumulatorValue();
+  void SetAccumulatorValue(int64_t accumulatorValue);
+
+  int32_t RegisterAccumulatorCountCallback(HAL_NotifyCallback callback,
+                                           void* param, HAL_Bool initialNotify);
+  void CancelAccumulatorCountCallback(int32_t uid);
+  void InvokeAccumulatorCountCallback(HAL_Value value);
+  int64_t GetAccumulatorCount();
+  void SetAccumulatorCount(int64_t accumulatorCount);
+
+  int32_t RegisterAccumulatorCenterCallback(HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify);
+  void CancelAccumulatorCenterCallback(int32_t uid);
+  void InvokeAccumulatorCenterCallback(HAL_Value value);
+  int32_t GetAccumulatorCenter();
+  void SetAccumulatorCenter(int32_t accumulatorCenter);
+
+  int32_t RegisterAccumulatorDeadbandCallback(HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify);
+  void CancelAccumulatorDeadbandCallback(int32_t uid);
+  void InvokeAccumulatorDeadbandCallback(HAL_Value value);
+  int32_t GetAccumulatorDeadband();
+  void SetAccumulatorDeadband(int32_t accumulatorDeadband);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_initialized{false};
+  std::shared_ptr<NotifyListenerVector> m_initializedCallbacks = nullptr;
+  std::atomic<int32_t> m_averageBits{7};
+  std::shared_ptr<NotifyListenerVector> m_averageBitsCallbacks = nullptr;
+  std::atomic<int32_t> m_oversampleBits{0};
+  std::shared_ptr<NotifyListenerVector> m_oversampleBitsCallbacks = nullptr;
+  std::atomic<double> m_voltage{0.0};
+  std::shared_ptr<NotifyListenerVector> m_voltageCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_accumulatorInitialized{false};
+  std::shared_ptr<NotifyListenerVector> m_accumulatorInitializedCallbacks =
+      nullptr;
+  std::atomic<int64_t> m_accumulatorValue{0};
+  std::shared_ptr<NotifyListenerVector> m_accumulatorValueCallbacks = nullptr;
+  std::atomic<int64_t> m_accumulatorCount{0};
+  std::shared_ptr<NotifyListenerVector> m_accumulatorCountCallbacks = nullptr;
+  std::atomic<int32_t> m_accumulatorCenter{0};
+  std::shared_ptr<NotifyListenerVector> m_accumulatorCenterCallbacks = nullptr;
+  std::atomic<int32_t> m_accumulatorDeadband{0};
+  std::shared_ptr<NotifyListenerVector> m_accumulatorDeadbandCallbacks =
+      nullptr;
+};
+extern AnalogInData* SimAnalogInData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogOutData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogOutData.cpp
new file mode 100644
index 0000000..a13c573
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogOutData.cpp
@@ -0,0 +1,156 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+#include "MockData/NotifyCallbackHelpers.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() {
+  m_voltage = 0.0;
+  m_voltageCallbacks = nullptr;
+  m_initialized = 0;
+  m_initializedCallbacks = nullptr;
+}
+
+int32_t AnalogOutData::RegisterVoltageCallback(HAL_NotifyCallback callback,
+                                               void* param,
+                                               HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_voltageCallbacks = RegisterCallback(m_voltageCallbacks, "Voltage",
+                                          callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetVoltage());
+    callback("Voltage", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogOutData::CancelVoltageCallback(int32_t uid) {
+  m_voltageCallbacks = CancelCallback(m_voltageCallbacks, uid);
+}
+
+void AnalogOutData::InvokeVoltageCallback(HAL_Value value) {
+  InvokeCallback(m_voltageCallbacks, "Voltage", &value);
+}
+
+double AnalogOutData::GetVoltage() { return m_voltage; }
+
+void AnalogOutData::SetVoltage(double voltage) {
+  double oldValue = m_voltage.exchange(voltage);
+  if (oldValue != voltage) {
+    InvokeVoltageCallback(MakeDouble(voltage));
+  }
+}
+
+int32_t AnalogOutData::RegisterInitializedCallback(HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedCallbacks = RegisterCallback(
+        m_initializedCallbacks, "Initialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitialized());
+    callback("Initialized", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogOutData::CancelInitializedCallback(int32_t uid) {
+  m_initializedCallbacks = CancelCallback(m_initializedCallbacks, uid);
+}
+
+void AnalogOutData::InvokeInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_initializedCallbacks, "Initialized", &value);
+}
+
+HAL_Bool AnalogOutData::GetInitialized() { return m_initialized; }
+
+void AnalogOutData::SetInitialized(HAL_Bool initialized) {
+  HAL_Bool oldValue = m_initialized.exchange(initialized);
+  if (oldValue != initialized) {
+    InvokeInitializedCallback(MakeBoolean(initialized));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetAnalogOutData(int32_t index) {
+  SimAnalogOutData[index].ResetData();
+}
+
+int32_t HALSIM_RegisterAnalogOutVoltageCallback(int32_t index,
+                                                HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify) {
+  return SimAnalogOutData[index].RegisterVoltageCallback(callback, param,
+                                                         initialNotify);
+}
+
+void HALSIM_CancelAnalogOutVoltageCallback(int32_t index, int32_t uid) {
+  SimAnalogOutData[index].CancelVoltageCallback(uid);
+}
+
+double HALSIM_GetAnalogOutVoltage(int32_t index) {
+  return SimAnalogOutData[index].GetVoltage();
+}
+
+void HALSIM_SetAnalogOutVoltage(int32_t index, double voltage) {
+  SimAnalogOutData[index].SetVoltage(voltage);
+}
+
+int32_t HALSIM_RegisterAnalogOutInitializedCallback(int32_t index,
+                                                    HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  return SimAnalogOutData[index].RegisterInitializedCallback(callback, param,
+                                                             initialNotify);
+}
+
+void HALSIM_CancelAnalogOutInitializedCallback(int32_t index, int32_t uid) {
+  SimAnalogOutData[index].CancelInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetAnalogOutInitialized(int32_t index) {
+  return SimAnalogOutData[index].GetInitialized();
+}
+
+void HALSIM_SetAnalogOutInitialized(int32_t index, HAL_Bool initialized) {
+  SimAnalogOutData[index].SetInitialized(initialized);
+}
+
+void HALSIM_RegisterAnalogOutAllCallbacks(int32_t index,
+                                          HAL_NotifyCallback callback,
+                                          void* param, HAL_Bool initialNotify) {
+  SimAnalogOutData[index].RegisterVoltageCallback(callback, param,
+                                                  initialNotify);
+  SimAnalogOutData[index].RegisterInitializedCallback(callback, param,
+                                                      initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogOutDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogOutDataInternal.h
new file mode 100644
index 0000000..c65e7f7
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogOutDataInternal.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 <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/AnalogOutData.h"
+#include "MockData/NotifyListenerVector.h"
+
+namespace hal {
+class AnalogOutData {
+ public:
+  int32_t RegisterVoltageCallback(HAL_NotifyCallback callback, void* param,
+                                  HAL_Bool initialNotify);
+  void CancelVoltageCallback(int32_t uid);
+  void InvokeVoltageCallback(HAL_Value value);
+  double GetVoltage();
+  void SetVoltage(double voltage);
+
+  int32_t RegisterInitializedCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelInitializedCallback(int32_t uid);
+  void InvokeInitializedCallback(HAL_Value value);
+  HAL_Bool GetInitialized();
+  void SetInitialized(HAL_Bool initialized);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<double> m_voltage{0.0};
+  std::shared_ptr<NotifyListenerVector> m_voltageCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_initialized{0};
+  std::shared_ptr<NotifyListenerVector> m_initializedCallbacks = nullptr;
+};
+extern AnalogOutData* SimAnalogOutData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogTriggerData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogTriggerData.cpp
new file mode 100644
index 0000000..3055233
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogTriggerData.cpp
@@ -0,0 +1,280 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+#include "MockData/NotifyCallbackHelpers.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() {
+  m_initialized = 0;
+  m_initializedCallbacks = nullptr;
+  m_triggerLowerBound = 0;
+  m_triggerLowerBoundCallbacks = nullptr;
+  m_triggerUpperBound = 0;
+  m_triggerUpperBoundCallbacks = nullptr;
+  m_triggerMode = static_cast<HALSIM_AnalogTriggerMode>(0);
+  m_triggerModeCallbacks = nullptr;
+}
+
+int32_t AnalogTriggerData::RegisterInitializedCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedCallbacks = RegisterCallback(
+        m_initializedCallbacks, "Initialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitialized());
+    callback("Initialized", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogTriggerData::CancelInitializedCallback(int32_t uid) {
+  m_initializedCallbacks = CancelCallback(m_initializedCallbacks, uid);
+}
+
+void AnalogTriggerData::InvokeInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_initializedCallbacks, "Initialized", &value);
+}
+
+HAL_Bool AnalogTriggerData::GetInitialized() { return m_initialized; }
+
+void AnalogTriggerData::SetInitialized(HAL_Bool initialized) {
+  HAL_Bool oldValue = m_initialized.exchange(initialized);
+  if (oldValue != initialized) {
+    InvokeInitializedCallback(MakeBoolean(initialized));
+  }
+}
+
+int32_t AnalogTriggerData::RegisterTriggerLowerBoundCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_triggerLowerBoundCallbacks =
+        RegisterCallback(m_triggerLowerBoundCallbacks, "TriggerLowerBound",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetTriggerLowerBound());
+    callback("TriggerLowerBound", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogTriggerData::CancelTriggerLowerBoundCallback(int32_t uid) {
+  m_triggerLowerBoundCallbacks =
+      CancelCallback(m_triggerLowerBoundCallbacks, uid);
+}
+
+void AnalogTriggerData::InvokeTriggerLowerBoundCallback(HAL_Value value) {
+  InvokeCallback(m_triggerLowerBoundCallbacks, "TriggerLowerBound", &value);
+}
+
+double AnalogTriggerData::GetTriggerLowerBound() { return m_triggerLowerBound; }
+
+void AnalogTriggerData::SetTriggerLowerBound(double triggerLowerBound) {
+  double oldValue = m_triggerLowerBound.exchange(triggerLowerBound);
+  if (oldValue != triggerLowerBound) {
+    InvokeTriggerLowerBoundCallback(MakeDouble(triggerLowerBound));
+  }
+}
+
+int32_t AnalogTriggerData::RegisterTriggerUpperBoundCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_triggerUpperBoundCallbacks =
+        RegisterCallback(m_triggerUpperBoundCallbacks, "TriggerUpperBound",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetTriggerUpperBound());
+    callback("TriggerUpperBound", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogTriggerData::CancelTriggerUpperBoundCallback(int32_t uid) {
+  m_triggerUpperBoundCallbacks =
+      CancelCallback(m_triggerUpperBoundCallbacks, uid);
+}
+
+void AnalogTriggerData::InvokeTriggerUpperBoundCallback(HAL_Value value) {
+  InvokeCallback(m_triggerUpperBoundCallbacks, "TriggerUpperBound", &value);
+}
+
+double AnalogTriggerData::GetTriggerUpperBound() { return m_triggerUpperBound; }
+
+void AnalogTriggerData::SetTriggerUpperBound(double triggerUpperBound) {
+  double oldValue = m_triggerUpperBound.exchange(triggerUpperBound);
+  if (oldValue != triggerUpperBound) {
+    InvokeTriggerUpperBoundCallback(MakeDouble(triggerUpperBound));
+  }
+}
+
+int32_t AnalogTriggerData::RegisterTriggerModeCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_triggerModeCallbacks = RegisterCallback(
+        m_triggerModeCallbacks, "TriggerMode", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeEnum(GetTriggerMode());
+    callback("TriggerMode", param, &value);
+  }
+  return newUid;
+}
+
+void AnalogTriggerData::CancelTriggerModeCallback(int32_t uid) {
+  m_triggerModeCallbacks = CancelCallback(m_triggerModeCallbacks, uid);
+}
+
+void AnalogTriggerData::InvokeTriggerModeCallback(HAL_Value value) {
+  InvokeCallback(m_triggerModeCallbacks, "TriggerMode", &value);
+}
+
+HALSIM_AnalogTriggerMode AnalogTriggerData::GetTriggerMode() {
+  return m_triggerMode;
+}
+
+void AnalogTriggerData::SetTriggerMode(HALSIM_AnalogTriggerMode triggerMode) {
+  HALSIM_AnalogTriggerMode oldValue = m_triggerMode.exchange(triggerMode);
+  if (oldValue != triggerMode) {
+    InvokeTriggerModeCallback(MakeEnum(triggerMode));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetAnalogTriggerData(int32_t index) {
+  SimAnalogTriggerData[index].ResetData();
+}
+
+int32_t HALSIM_RegisterAnalogTriggerInitializedCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimAnalogTriggerData[index].RegisterInitializedCallback(
+      callback, param, initialNotify);
+}
+
+void HALSIM_CancelAnalogTriggerInitializedCallback(int32_t index, int32_t uid) {
+  SimAnalogTriggerData[index].CancelInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetAnalogTriggerInitialized(int32_t index) {
+  return SimAnalogTriggerData[index].GetInitialized();
+}
+
+void HALSIM_SetAnalogTriggerInitialized(int32_t index, HAL_Bool initialized) {
+  SimAnalogTriggerData[index].SetInitialized(initialized);
+}
+
+int32_t HALSIM_RegisterAnalogTriggerTriggerLowerBoundCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimAnalogTriggerData[index].RegisterTriggerLowerBoundCallback(
+      callback, param, initialNotify);
+}
+
+void HALSIM_CancelAnalogTriggerTriggerLowerBoundCallback(int32_t index,
+                                                         int32_t uid) {
+  SimAnalogTriggerData[index].CancelTriggerLowerBoundCallback(uid);
+}
+
+double HALSIM_GetAnalogTriggerTriggerLowerBound(int32_t index) {
+  return SimAnalogTriggerData[index].GetTriggerLowerBound();
+}
+
+void HALSIM_SetAnalogTriggerTriggerLowerBound(int32_t index,
+                                              double triggerLowerBound) {
+  SimAnalogTriggerData[index].SetTriggerLowerBound(triggerLowerBound);
+}
+
+int32_t HALSIM_RegisterAnalogTriggerTriggerUpperBoundCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimAnalogTriggerData[index].RegisterTriggerUpperBoundCallback(
+      callback, param, initialNotify);
+}
+
+void HALSIM_CancelAnalogTriggerTriggerUpperBoundCallback(int32_t index,
+                                                         int32_t uid) {
+  SimAnalogTriggerData[index].CancelTriggerUpperBoundCallback(uid);
+}
+
+double HALSIM_GetAnalogTriggerTriggerUpperBound(int32_t index) {
+  return SimAnalogTriggerData[index].GetTriggerUpperBound();
+}
+
+void HALSIM_SetAnalogTriggerTriggerUpperBound(int32_t index,
+                                              double triggerUpperBound) {
+  SimAnalogTriggerData[index].SetTriggerUpperBound(triggerUpperBound);
+}
+
+int32_t HALSIM_RegisterAnalogTriggerTriggerModeCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimAnalogTriggerData[index].RegisterTriggerModeCallback(
+      callback, param, initialNotify);
+}
+
+void HALSIM_CancelAnalogTriggerTriggerModeCallback(int32_t index, int32_t uid) {
+  SimAnalogTriggerData[index].CancelTriggerModeCallback(uid);
+}
+
+HALSIM_AnalogTriggerMode HALSIM_GetAnalogTriggerTriggerMode(int32_t index) {
+  return SimAnalogTriggerData[index].GetTriggerMode();
+}
+
+void HALSIM_SetAnalogTriggerTriggerMode(int32_t index,
+                                        HALSIM_AnalogTriggerMode triggerMode) {
+  SimAnalogTriggerData[index].SetTriggerMode(triggerMode);
+}
+
+void HALSIM_RegisterAnalogTriggerAllCallbacks(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  SimAnalogTriggerData[index].RegisterInitializedCallback(callback, param,
+                                                          initialNotify);
+  SimAnalogTriggerData[index].RegisterTriggerLowerBoundCallback(callback, param,
+                                                                initialNotify);
+  SimAnalogTriggerData[index].RegisterTriggerUpperBoundCallback(callback, param,
+                                                                initialNotify);
+  SimAnalogTriggerData[index].RegisterTriggerModeCallback(callback, param,
+                                                          initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogTriggerDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogTriggerDataInternal.h
new file mode 100644
index 0000000..abb632b
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/AnalogTriggerDataInternal.h
@@ -0,0 +1,66 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/AnalogTriggerData.h"
+#include "MockData/NotifyListenerVector.h"
+
+namespace hal {
+class AnalogTriggerData {
+ public:
+  int32_t RegisterInitializedCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelInitializedCallback(int32_t uid);
+  void InvokeInitializedCallback(HAL_Value value);
+  HAL_Bool GetInitialized();
+  void SetInitialized(HAL_Bool initialized);
+
+  int32_t RegisterTriggerLowerBoundCallback(HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify);
+  void CancelTriggerLowerBoundCallback(int32_t uid);
+  void InvokeTriggerLowerBoundCallback(HAL_Value value);
+  double GetTriggerLowerBound();
+  void SetTriggerLowerBound(double triggerLowerBound);
+
+  int32_t RegisterTriggerUpperBoundCallback(HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify);
+  void CancelTriggerUpperBoundCallback(int32_t uid);
+  void InvokeTriggerUpperBoundCallback(HAL_Value value);
+  double GetTriggerUpperBound();
+  void SetTriggerUpperBound(double triggerUpperBound);
+
+  int32_t RegisterTriggerModeCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelTriggerModeCallback(int32_t uid);
+  void InvokeTriggerModeCallback(HAL_Value value);
+  HALSIM_AnalogTriggerMode GetTriggerMode();
+  void SetTriggerMode(HALSIM_AnalogTriggerMode triggerMode);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_initialized{0};
+  std::shared_ptr<NotifyListenerVector> m_initializedCallbacks = nullptr;
+  std::atomic<double> m_triggerLowerBound{0};
+  std::shared_ptr<NotifyListenerVector> m_triggerLowerBoundCallbacks = nullptr;
+  std::atomic<double> m_triggerUpperBound{0};
+  std::shared_ptr<NotifyListenerVector> m_triggerUpperBoundCallbacks = nullptr;
+  std::atomic<HALSIM_AnalogTriggerMode> m_triggerMode{
+      static_cast<HALSIM_AnalogTriggerMode>(0)};
+  std::shared_ptr<NotifyListenerVector> m_triggerModeCallbacks = nullptr;
+};
+extern AnalogTriggerData* SimAnalogTriggerData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/CanDataInternal.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/CanDataInternal.cpp
new file mode 100644
index 0000000..cb4a906
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/CanDataInternal.cpp
@@ -0,0 +1,296 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+
+#include "MockData/NotifyCallbackHelpers.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializeCanData() {
+  static CanData scd;
+  ::hal::SimCanData = &scd;
+}
+}  // namespace init
+}  // namespace hal
+
+CanData* hal::SimCanData;
+void InvokeCallback(std::shared_ptr<CanSendMessageListenerVector> currentVector,
+                    const char* name, uint32_t messageID, const uint8_t* data,
+                    uint8_t dataSize, int32_t periodMs, int32_t* status) {
+  // Return if no callbacks are assigned
+  if (currentVector == nullptr) return;
+  // Get a copy of the shared_ptr, then iterate and callback listeners
+  auto newCallbacks = currentVector;
+  for (size_t i = 0; i < newCallbacks->size(); ++i) {
+    if (!(*newCallbacks)[i]) continue;  // removed
+    auto listener = (*newCallbacks)[i];
+    listener.callback(name, listener.param, messageID, data, dataSize, periodMs,
+                      status);
+  }
+}
+
+void InvokeCallback(
+    std::shared_ptr<CanReceiveMessageListenerVector> currentVector,
+    const char* name, uint32_t* messageID, uint32_t messageIDMask,
+    uint8_t* data, uint8_t* dataSize, uint32_t* timeStamp, int32_t* status) {
+  // Return if no callbacks are assigned
+  if (currentVector == nullptr) return;
+  // Get a copy of the shared_ptr, then iterate and callback listeners
+  auto newCallbacks = currentVector;
+  for (size_t i = 0; i < newCallbacks->size(); ++i) {
+    if (!(*newCallbacks)[i]) continue;  // removed
+    auto listener = (*newCallbacks)[i];
+    listener.callback(name, listener.param, messageID, messageIDMask, data,
+                      dataSize, timeStamp, status);
+  }
+}
+
+void InvokeCallback(
+    std::shared_ptr<CanOpenStreamSessionListenerVector> currentVector,
+    const char* name, uint32_t* sessionHandle, uint32_t messageID,
+    uint32_t messageIDMask, uint32_t maxMessages, int32_t* status) {
+  // Return if no callbacks are assigned
+  if (currentVector == nullptr) return;
+  // Get a copy of the shared_ptr, then iterate and callback listeners
+  auto newCallbacks = currentVector;
+  for (size_t i = 0; i < newCallbacks->size(); ++i) {
+    if (!(*newCallbacks)[i]) continue;  // removed
+    auto listener = (*newCallbacks)[i];
+    listener.callback(name, listener.param, sessionHandle, messageID,
+                      messageIDMask, maxMessages, status);
+  }
+}
+
+void InvokeCallback(
+    std::shared_ptr<CanCloseStreamSessionListenerVector> currentVector,
+    const char* name, uint32_t sessionHandle) {
+  // Return if no callbacks are assigned
+  if (currentVector == nullptr) return;
+  // Get a copy of the shared_ptr, then iterate and callback listeners
+  auto newCallbacks = currentVector;
+  for (size_t i = 0; i < newCallbacks->size(); ++i) {
+    if (!(*newCallbacks)[i]) continue;  // removed
+    auto listener = (*newCallbacks)[i];
+    listener.callback(name, listener.param, sessionHandle);
+  }
+}
+
+void InvokeCallback(
+    std::shared_ptr<CanReadStreamSessionListenerVector> currentVector,
+    const char* name, uint32_t sessionHandle,
+    struct HAL_CANStreamMessage* messages, uint32_t messagesToRead,
+    uint32_t* messagesRead, int32_t* status) {
+  // Return if no callbacks are assigned
+  if (currentVector == nullptr) return;
+  // Get a copy of the shared_ptr, then iterate and callback listeners
+  auto newCallbacks = currentVector;
+  for (size_t i = 0; i < newCallbacks->size(); ++i) {
+    if (!(*newCallbacks)[i]) continue;  // removed
+    auto listener = (*newCallbacks)[i];
+    listener.callback(name, listener.param, sessionHandle, messages,
+                      messagesToRead, messagesRead, status);
+  }
+}
+
+void InvokeCallback(
+    std::shared_ptr<CanGetCANStatusListenerVector> currentVector,
+    const char* name, float* percentBusUtilization, uint32_t* busOffCount,
+    uint32_t* txFullCount, uint32_t* receiveErrorCount,
+    uint32_t* transmitErrorCount, int32_t* status) {
+  // Return if no callbacks are assigned
+  if (currentVector == nullptr) return;
+  // Get a copy of the shared_ptr, then iterate and callback listeners
+  auto newCallbacks = currentVector;
+  for (size_t i = 0; i < newCallbacks->size(); ++i) {
+    if (!(*newCallbacks)[i]) continue;  // removed
+    auto listener = (*newCallbacks)[i];
+    listener.callback(name, listener.param, percentBusUtilization, busOffCount,
+                      txFullCount, receiveErrorCount, transmitErrorCount,
+                      status);
+  }
+}
+
+void CanData::ResetData() {
+  m_sendMessageCallback = nullptr;
+  m_receiveMessageCallback = nullptr;
+  m_openStreamSessionCallback = nullptr;
+  m_closeStreamSessionCallback = nullptr;
+  m_readStreamSessionCallback = nullptr;
+  m_getCanStatusCallback = nullptr;
+}
+
+void CanData::SendMessage(uint32_t messageID, const uint8_t* data,
+                          uint8_t dataSize, int32_t periodMs, int32_t* status) {
+  InvokeCallback(m_sendMessageCallback, "SendMessage", messageID, data,
+                 dataSize, periodMs, status);
+}
+
+void CanData::ReceiveMessage(uint32_t* messageID, uint32_t messageIDMask,
+                             uint8_t* data, uint8_t* dataSize,
+                             uint32_t* timeStamp, int32_t* status) {
+  InvokeCallback(m_receiveMessageCallback, "ReceiveMessage", messageID,
+                 messageIDMask, data, dataSize, timeStamp, status);
+}
+
+void CanData::OpenStreamSession(uint32_t* sessionHandle, uint32_t messageID,
+                                uint32_t messageIDMask, uint32_t maxMessages,
+                                int32_t* status) {
+  InvokeCallback(m_openStreamSessionCallback, "OpenStream", sessionHandle,
+                 messageID, messageIDMask, maxMessages, status);
+}
+
+void CanData::CloseStreamSession(uint32_t sessionHandle) {
+  InvokeCallback(m_closeStreamSessionCallback, "CloseStream", sessionHandle);
+}
+
+void CanData::ReadStreamSession(uint32_t sessionHandle,
+                                struct HAL_CANStreamMessage* messages,
+                                uint32_t messagesToRead, uint32_t* messagesRead,
+                                int32_t* status) {
+  InvokeCallback(m_readStreamSessionCallback, "ReadStream", sessionHandle,
+                 messages, messagesToRead, messagesRead, status);
+}
+
+void CanData::GetCANStatus(float* percentBusUtilization, uint32_t* busOffCount,
+                           uint32_t* txFullCount, uint32_t* receiveErrorCount,
+                           uint32_t* transmitErrorCount, int32_t* status) {
+  InvokeCallback(m_getCanStatusCallback, "GetCanStatus", percentBusUtilization,
+                 busOffCount, txFullCount, receiveErrorCount,
+                 transmitErrorCount, status);
+}
+
+int32_t CanData::RegisterSendMessageCallback(
+    HAL_CAN_SendMessageCallback callback, void* param) {
+  return RegisterCanCallback<CanSendMessageListenerVector,
+                             HAL_CAN_SendMessageCallback>(
+      callback, m_sendMessageCallback, "SendMessage", param);
+}
+void CanData::CancelSendMessageCallback(int32_t uid) {
+  m_sendMessageCallback = CancelCallbackImpl<CanSendMessageListenerVector,
+                                             HAL_CAN_SendMessageCallback>(
+      m_sendMessageCallback, uid);
+}
+
+int32_t CanData::RegisterReceiveMessageCallback(
+    HAL_CAN_ReceiveMessageCallback callback, void* param) {
+  return RegisterCanCallback<CanReceiveMessageListenerVector,
+                             HAL_CAN_ReceiveMessageCallback>(
+      callback, m_receiveMessageCallback, "ReceiveMessage", param);
+}
+void CanData::CancelReceiveMessageCallback(int32_t uid) {
+  m_receiveMessageCallback = CancelCallbackImpl<CanReceiveMessageListenerVector,
+                                                HAL_CAN_ReceiveMessageCallback>(
+      m_receiveMessageCallback, uid);
+}
+
+int32_t CanData::RegisterOpenStreamCallback(
+    HAL_CAN_OpenStreamSessionCallback callback, void* param) {
+  return RegisterCanCallback<CanOpenStreamSessionListenerVector,
+                             HAL_CAN_OpenStreamSessionCallback>(
+      callback, m_openStreamSessionCallback, "OpenStream", param);
+}
+void CanData::CancelOpenStreamCallback(int32_t uid) {
+  m_openStreamSessionCallback =
+      CancelCallbackImpl<CanOpenStreamSessionListenerVector,
+                         HAL_CAN_OpenStreamSessionCallback>(
+          m_openStreamSessionCallback, uid);
+}
+
+int32_t CanData::RegisterCloseStreamCallback(
+    HAL_CAN_CloseStreamSessionCallback callback, void* param) {
+  return RegisterCanCallback<CanCloseStreamSessionListenerVector,
+                             HAL_CAN_CloseStreamSessionCallback>(
+      callback, m_closeStreamSessionCallback, "CloseStream", param);
+}
+void CanData::CancelCloseStreamCallback(int32_t uid) {
+  m_closeStreamSessionCallback =
+      CancelCallbackImpl<CanCloseStreamSessionListenerVector,
+                         HAL_CAN_CloseStreamSessionCallback>(
+          m_closeStreamSessionCallback, uid);
+}
+
+int32_t CanData::RegisterReadStreamCallback(
+    HAL_CAN_ReadStreamSessionCallback callback, void* param) {
+  return RegisterCanCallback<CanReadStreamSessionListenerVector,
+                             HAL_CAN_ReadStreamSessionCallback>(
+      callback, m_readStreamSessionCallback, "ReadStream", param);
+}
+void CanData::CancelReadStreamCallback(int32_t uid) {
+  m_readStreamSessionCallback =
+      CancelCallbackImpl<CanReadStreamSessionListenerVector,
+                         HAL_CAN_ReadStreamSessionCallback>(
+          m_readStreamSessionCallback, uid);
+}
+int32_t CanData::RegisterGetCANStatusCallback(
+    HAL_CAN_GetCANStatusCallback callback, void* param) {
+  return RegisterCanCallback<CanGetCANStatusListenerVector,
+                             HAL_CAN_GetCANStatusCallback>(
+      callback, m_getCanStatusCallback, "GetCANStatus", param);
+}
+void CanData::CancelGetCANStatusCallback(int32_t uid) {
+  m_getCanStatusCallback =
+      CancelCallbackImpl<CanGetCANStatusListenerVector,
+                         HAL_CAN_ReadStreamSessionCallback>(
+          m_getCanStatusCallback, uid);
+}
+
+extern "C" {
+
+void HALSIM_ResetCanData(void) { SimCanData->ResetData(); }
+
+int32_t HALSIM_RegisterCanSendMessageCallback(
+    HAL_CAN_SendMessageCallback callback, void* param) {
+  return SimCanData->RegisterSendMessageCallback(callback, param);
+}
+void HALSIM_CancelCanSendMessageCallback(int32_t uid) {
+  SimCanData->CancelSendMessageCallback(uid);
+}
+
+int32_t HALSIM_RegisterCanReceiveMessageCallback(
+    HAL_CAN_ReceiveMessageCallback callback, void* param) {
+  return SimCanData->RegisterReceiveMessageCallback(callback, param);
+}
+void HALSIM_CancelCanReceiveMessageCallback(int32_t uid) {
+  SimCanData->CancelReceiveMessageCallback(uid);
+}
+
+int32_t HALSIM_RegisterCanOpenStreamCallback(
+    HAL_CAN_OpenStreamSessionCallback callback, void* param) {
+  return SimCanData->RegisterOpenStreamCallback(callback, param);
+}
+void HALSIM_CancelCanOpenStreamCallback(int32_t uid) {
+  SimCanData->CancelOpenStreamCallback(uid);
+}
+
+int32_t HALSIM_RegisterCanCloseStreamCallback(
+    HAL_CAN_CloseStreamSessionCallback callback, void* param) {
+  return SimCanData->RegisterCloseStreamCallback(callback, param);
+}
+void HALSIM_CancelCanCloseStreamCallback(int32_t uid) {
+  SimCanData->CancelCloseStreamCallback(uid);
+}
+
+int32_t HALSIM_RegisterCanReadStreamCallback(
+    HAL_CAN_ReadStreamSessionCallback callback, void* param) {
+  return SimCanData->RegisterReadStreamCallback(callback, param);
+}
+void HALSIM_CancelCanReadStreamCallback(int32_t uid) {
+  SimCanData->CancelReadStreamCallback(uid);
+}
+
+int32_t HALSIM_RegisterCanGetCANStatusCallback(
+    HAL_CAN_GetCANStatusCallback callback, void* param) {
+  return SimCanData->RegisterGetCANStatusCallback(callback, param);
+}
+void HALSIM_CancelCanGetCANStatusCallback(int32_t uid) {
+  SimCanData->CancelGetCANStatusCallback(uid);
+}
+
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/CanDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/CanDataInternal.h
new file mode 100644
index 0000000..2e64d78
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/CanDataInternal.h
@@ -0,0 +1,111 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/CanData.h"
+#include "MockData/NotifyCallbackHelpers.h"
+#include "MockData/NotifyListenerVector.h"
+
+namespace hal {
+
+typedef HalCallbackListenerVectorImpl<HAL_CAN_SendMessageCallback>
+    CanSendMessageListenerVector;
+typedef HalCallbackListenerVectorImpl<HAL_CAN_ReceiveMessageCallback>
+    CanReceiveMessageListenerVector;
+typedef HalCallbackListenerVectorImpl<HAL_CAN_OpenStreamSessionCallback>
+    CanOpenStreamSessionListenerVector;
+typedef HalCallbackListenerVectorImpl<HAL_CAN_CloseStreamSessionCallback>
+    CanCloseStreamSessionListenerVector;
+typedef HalCallbackListenerVectorImpl<HAL_CAN_ReadStreamSessionCallback>
+    CanReadStreamSessionListenerVector;
+typedef HalCallbackListenerVectorImpl<HAL_CAN_GetCANStatusCallback>
+    CanGetCANStatusListenerVector;
+
+class CanData {
+ public:
+  void ResetData();
+
+  void SendMessage(uint32_t messageID, const uint8_t* data, uint8_t dataSize,
+                   int32_t periodMs, int32_t* status);
+  void ReceiveMessage(uint32_t* messageID, uint32_t messageIDMask,
+                      uint8_t* data, uint8_t* dataSize, uint32_t* timeStamp,
+                      int32_t* status);
+  void OpenStreamSession(uint32_t* sessionHandle, uint32_t messageID,
+                         uint32_t messageIDMask, uint32_t maxMessages,
+                         int32_t* status);
+  void CloseStreamSession(uint32_t sessionHandle);
+  void ReadStreamSession(uint32_t sessionHandle,
+                         struct HAL_CANStreamMessage* messages,
+                         uint32_t messagesToRead, uint32_t* messagesRead,
+                         int32_t* status);
+  void GetCANStatus(float* percentBusUtilization, uint32_t* busOffCount,
+                    uint32_t* txFullCount, uint32_t* receiveErrorCount,
+                    uint32_t* transmitErrorCount, int32_t* status);
+
+  int32_t RegisterSendMessageCallback(HAL_CAN_SendMessageCallback callback,
+                                      void* param);
+  void CancelSendMessageCallback(int32_t uid);
+
+  int32_t RegisterReceiveMessageCallback(
+      HAL_CAN_ReceiveMessageCallback callback, void* param);
+  void CancelReceiveMessageCallback(int32_t uid);
+
+  int32_t RegisterOpenStreamCallback(HAL_CAN_OpenStreamSessionCallback callback,
+                                     void* param);
+  void CancelOpenStreamCallback(int32_t uid);
+
+  int32_t RegisterCloseStreamCallback(
+      HAL_CAN_CloseStreamSessionCallback callback, void* param);
+  void CancelCloseStreamCallback(int32_t uid);
+
+  int32_t RegisterReadStreamCallback(HAL_CAN_ReadStreamSessionCallback callback,
+                                     void* param);
+  void CancelReadStreamCallback(int32_t uid);
+
+  int32_t RegisterGetCANStatusCallback(HAL_CAN_GetCANStatusCallback callback,
+                                       void* param);
+  void CancelGetCANStatusCallback(int32_t uid);
+
+ protected:
+  template <typename VectorType, typename CallbackType>
+  int32_t RegisterCanCallback(CallbackType& callback,
+                              std::shared_ptr<VectorType>& callbackVector,
+                              const char* callbackName, void* param) {
+    // Must return -1 on a null callback for error handling
+    if (callback == nullptr) return -1;
+    int32_t newUid = 0;
+    {
+      std::lock_guard<wpi::mutex> lock(m_registerMutex);
+      callbackVector = RegisterCallbackImpl(callbackVector, callbackName,
+                                            callback, param, &newUid);
+    }
+    return newUid;
+  }
+
+  wpi::mutex m_registerMutex;
+
+  std::shared_ptr<CanSendMessageListenerVector> m_sendMessageCallback;
+  std::shared_ptr<CanReceiveMessageListenerVector> m_receiveMessageCallback;
+  std::shared_ptr<CanOpenStreamSessionListenerVector>
+      m_openStreamSessionCallback;
+  std::shared_ptr<CanCloseStreamSessionListenerVector>
+      m_closeStreamSessionCallback;
+  std::shared_ptr<CanReadStreamSessionListenerVector>
+      m_readStreamSessionCallback;
+  std::shared_ptr<CanGetCANStatusListenerVector> m_getCanStatusCallback;
+};
+
+extern CanData* SimCanData;
+
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DIOData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DIOData.cpp
new file mode 100644
index 0000000..0dcf299
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DIOData.cpp
@@ -0,0 +1,324 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+#include "MockData/NotifyCallbackHelpers.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() {
+  m_initialized = false;
+  m_initializedCallbacks = nullptr;
+  m_value = true;
+  m_valueCallbacks = nullptr;
+  m_pulseLength = 0.0;
+  m_pulseLengthCallbacks = nullptr;
+  m_isInput = true;
+  m_isInputCallbacks = nullptr;
+  m_filterIndex = -1;
+  m_filterIndexCallbacks = nullptr;
+}
+
+int32_t DIOData::RegisterInitializedCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedCallbacks = RegisterCallback(
+        m_initializedCallbacks, "Initialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitialized());
+    callback("Initialized", param, &value);
+  }
+  return newUid;
+}
+
+void DIOData::CancelInitializedCallback(int32_t uid) {
+  m_initializedCallbacks = CancelCallback(m_initializedCallbacks, uid);
+}
+
+void DIOData::InvokeInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_initializedCallbacks, "Initialized", &value);
+}
+
+HAL_Bool DIOData::GetInitialized() { return m_initialized; }
+
+void DIOData::SetInitialized(HAL_Bool initialized) {
+  HAL_Bool oldValue = m_initialized.exchange(initialized);
+  if (oldValue != initialized) {
+    InvokeInitializedCallback(MakeBoolean(initialized));
+  }
+}
+
+int32_t DIOData::RegisterValueCallback(HAL_NotifyCallback callback, void* param,
+                                       HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_valueCallbacks =
+        RegisterCallback(m_valueCallbacks, "Value", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetValue());
+    callback("Value", param, &value);
+  }
+  return newUid;
+}
+
+void DIOData::CancelValueCallback(int32_t uid) {
+  m_valueCallbacks = CancelCallback(m_valueCallbacks, uid);
+}
+
+void DIOData::InvokeValueCallback(HAL_Value value) {
+  InvokeCallback(m_valueCallbacks, "Value", &value);
+}
+
+HAL_Bool DIOData::GetValue() { return m_value; }
+
+void DIOData::SetValue(HAL_Bool value) {
+  HAL_Bool oldValue = m_value.exchange(value);
+  if (oldValue != value) {
+    InvokeValueCallback(MakeBoolean(value));
+  }
+}
+
+int32_t DIOData::RegisterPulseLengthCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_pulseLengthCallbacks = RegisterCallback(
+        m_pulseLengthCallbacks, "PulseLength", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetPulseLength());
+    callback("PulseLength", param, &value);
+  }
+  return newUid;
+}
+
+void DIOData::CancelPulseLengthCallback(int32_t uid) {
+  m_pulseLengthCallbacks = CancelCallback(m_pulseLengthCallbacks, uid);
+}
+
+void DIOData::InvokePulseLengthCallback(HAL_Value value) {
+  InvokeCallback(m_pulseLengthCallbacks, "PulseLength", &value);
+}
+
+double DIOData::GetPulseLength() { return m_pulseLength; }
+
+void DIOData::SetPulseLength(double pulseLength) {
+  double oldValue = m_pulseLength.exchange(pulseLength);
+  if (oldValue != pulseLength) {
+    InvokePulseLengthCallback(MakeDouble(pulseLength));
+  }
+}
+
+int32_t DIOData::RegisterIsInputCallback(HAL_NotifyCallback callback,
+                                         void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_isInputCallbacks = RegisterCallback(m_isInputCallbacks, "IsInput",
+                                          callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetIsInput());
+    callback("IsInput", param, &value);
+  }
+  return newUid;
+}
+
+void DIOData::CancelIsInputCallback(int32_t uid) {
+  m_isInputCallbacks = CancelCallback(m_isInputCallbacks, uid);
+}
+
+void DIOData::InvokeIsInputCallback(HAL_Value value) {
+  InvokeCallback(m_isInputCallbacks, "IsInput", &value);
+}
+
+HAL_Bool DIOData::GetIsInput() { return m_isInput; }
+
+void DIOData::SetIsInput(HAL_Bool isInput) {
+  HAL_Bool oldValue = m_isInput.exchange(isInput);
+  if (oldValue != isInput) {
+    InvokeIsInputCallback(MakeBoolean(isInput));
+  }
+}
+
+int32_t DIOData::RegisterFilterIndexCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_filterIndexCallbacks = RegisterCallback(
+        m_filterIndexCallbacks, "FilterIndex", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetFilterIndex());
+    callback("FilterIndex", param, &value);
+  }
+  return newUid;
+}
+
+void DIOData::CancelFilterIndexCallback(int32_t uid) {
+  m_filterIndexCallbacks = CancelCallback(m_filterIndexCallbacks, uid);
+}
+
+void DIOData::InvokeFilterIndexCallback(HAL_Value value) {
+  InvokeCallback(m_filterIndexCallbacks, "FilterIndex", &value);
+}
+
+int32_t DIOData::GetFilterIndex() { return m_filterIndex; }
+
+void DIOData::SetFilterIndex(int32_t filterIndex) {
+  int32_t oldValue = m_filterIndex.exchange(filterIndex);
+  if (oldValue != filterIndex) {
+    InvokeFilterIndexCallback(MakeInt(filterIndex));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetDIOData(int32_t index) { SimDIOData[index].ResetData(); }
+
+int32_t HALSIM_RegisterDIOInitializedCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimDIOData[index].RegisterInitializedCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelDIOInitializedCallback(int32_t index, int32_t uid) {
+  SimDIOData[index].CancelInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetDIOInitialized(int32_t index) {
+  return SimDIOData[index].GetInitialized();
+}
+
+void HALSIM_SetDIOInitialized(int32_t index, HAL_Bool initialized) {
+  SimDIOData[index].SetInitialized(initialized);
+}
+
+int32_t HALSIM_RegisterDIOValueCallback(int32_t index,
+                                        HAL_NotifyCallback callback,
+                                        void* param, HAL_Bool initialNotify) {
+  return SimDIOData[index].RegisterValueCallback(callback, param,
+                                                 initialNotify);
+}
+
+void HALSIM_CancelDIOValueCallback(int32_t index, int32_t uid) {
+  SimDIOData[index].CancelValueCallback(uid);
+}
+
+HAL_Bool HALSIM_GetDIOValue(int32_t index) {
+  return SimDIOData[index].GetValue();
+}
+
+void HALSIM_SetDIOValue(int32_t index, HAL_Bool value) {
+  SimDIOData[index].SetValue(value);
+}
+
+int32_t HALSIM_RegisterDIOPulseLengthCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimDIOData[index].RegisterPulseLengthCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelDIOPulseLengthCallback(int32_t index, int32_t uid) {
+  SimDIOData[index].CancelPulseLengthCallback(uid);
+}
+
+double HALSIM_GetDIOPulseLength(int32_t index) {
+  return SimDIOData[index].GetPulseLength();
+}
+
+void HALSIM_SetDIOPulseLength(int32_t index, double pulseLength) {
+  SimDIOData[index].SetPulseLength(pulseLength);
+}
+
+int32_t HALSIM_RegisterDIOIsInputCallback(int32_t index,
+                                          HAL_NotifyCallback callback,
+                                          void* param, HAL_Bool initialNotify) {
+  return SimDIOData[index].RegisterIsInputCallback(callback, param,
+                                                   initialNotify);
+}
+
+void HALSIM_CancelDIOIsInputCallback(int32_t index, int32_t uid) {
+  SimDIOData[index].CancelIsInputCallback(uid);
+}
+
+HAL_Bool HALSIM_GetDIOIsInput(int32_t index) {
+  return SimDIOData[index].GetIsInput();
+}
+
+void HALSIM_SetDIOIsInput(int32_t index, HAL_Bool isInput) {
+  SimDIOData[index].SetIsInput(isInput);
+}
+
+int32_t HALSIM_RegisterDIOFilterIndexCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimDIOData[index].RegisterFilterIndexCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelDIOFilterIndexCallback(int32_t index, int32_t uid) {
+  SimDIOData[index].CancelFilterIndexCallback(uid);
+}
+
+int32_t HALSIM_GetDIOFilterIndex(int32_t index) {
+  return SimDIOData[index].GetFilterIndex();
+}
+
+void HALSIM_SetDIOFilterIndex(int32_t index, int32_t filterIndex) {
+  SimDIOData[index].SetFilterIndex(filterIndex);
+}
+
+void HALSIM_RegisterDIOAllCallbacks(int32_t index, HAL_NotifyCallback callback,
+                                    void* param, HAL_Bool initialNotify) {
+  SimDIOData[index].RegisterInitializedCallback(callback, param, initialNotify);
+  SimDIOData[index].RegisterValueCallback(callback, param, initialNotify);
+  SimDIOData[index].RegisterPulseLengthCallback(callback, param, initialNotify);
+  SimDIOData[index].RegisterIsInputCallback(callback, param, initialNotify);
+  SimDIOData[index].RegisterFilterIndexCallback(callback, param, initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DIODataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DIODataInternal.h
new file mode 100644
index 0000000..3f51a8d
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DIODataInternal.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
+
+#include <atomic>
+#include <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/DIOData.h"
+#include "MockData/NotifyListenerVector.h"
+
+namespace hal {
+class DIOData {
+ public:
+  int32_t RegisterInitializedCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelInitializedCallback(int32_t uid);
+  void InvokeInitializedCallback(HAL_Value value);
+  HAL_Bool GetInitialized();
+  void SetInitialized(HAL_Bool initialized);
+
+  int32_t RegisterValueCallback(HAL_NotifyCallback callback, void* param,
+                                HAL_Bool initialNotify);
+  void CancelValueCallback(int32_t uid);
+  void InvokeValueCallback(HAL_Value value);
+  HAL_Bool GetValue();
+  void SetValue(HAL_Bool value);
+
+  int32_t RegisterPulseLengthCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelPulseLengthCallback(int32_t uid);
+  void InvokePulseLengthCallback(HAL_Value value);
+  double GetPulseLength();
+  void SetPulseLength(double pulseLength);
+
+  int32_t RegisterIsInputCallback(HAL_NotifyCallback callback, void* param,
+                                  HAL_Bool initialNotify);
+  void CancelIsInputCallback(int32_t uid);
+  void InvokeIsInputCallback(HAL_Value value);
+  HAL_Bool GetIsInput();
+  void SetIsInput(HAL_Bool isInput);
+
+  int32_t RegisterFilterIndexCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelFilterIndexCallback(int32_t uid);
+  void InvokeFilterIndexCallback(HAL_Value value);
+  int32_t GetFilterIndex();
+  void SetFilterIndex(int32_t filterIndex);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_initialized{false};
+  std::shared_ptr<NotifyListenerVector> m_initializedCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_value{true};
+  std::shared_ptr<NotifyListenerVector> m_valueCallbacks = nullptr;
+  std::atomic<double> m_pulseLength{0.0};
+  std::shared_ptr<NotifyListenerVector> m_pulseLengthCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_isInput{true};
+  std::shared_ptr<NotifyListenerVector> m_isInputCallbacks = nullptr;
+  std::atomic<int32_t> m_filterIndex{-1};
+  std::shared_ptr<NotifyListenerVector> m_filterIndexCallbacks = nullptr;
+};
+extern DIOData* SimDIOData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DigitalPWMData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DigitalPWMData.cpp
new file mode 100644
index 0000000..f6721d5
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DigitalPWMData.cpp
@@ -0,0 +1,215 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+#include "MockData/NotifyCallbackHelpers.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() {
+  m_initialized = false;
+  m_initializedCallbacks = nullptr;
+  m_dutyCycle = false;
+  m_dutyCycleCallbacks = nullptr;
+  m_pin = 0;
+  m_pinCallbacks = nullptr;
+}
+
+int32_t DigitalPWMData::RegisterInitializedCallback(HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedCallbacks = RegisterCallback(
+        m_initializedCallbacks, "Initialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitialized());
+    callback("Initialized", param, &value);
+  }
+  return newUid;
+}
+
+void DigitalPWMData::CancelInitializedCallback(int32_t uid) {
+  m_initializedCallbacks = CancelCallback(m_initializedCallbacks, uid);
+}
+
+void DigitalPWMData::InvokeInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_initializedCallbacks, "Initialized", &value);
+}
+
+HAL_Bool DigitalPWMData::GetInitialized() { return m_initialized; }
+
+void DigitalPWMData::SetInitialized(HAL_Bool initialized) {
+  HAL_Bool oldValue = m_initialized.exchange(initialized);
+  if (oldValue != initialized) {
+    InvokeInitializedCallback(MakeBoolean(initialized));
+  }
+}
+
+int32_t DigitalPWMData::RegisterDutyCycleCallback(HAL_NotifyCallback callback,
+                                                  void* param,
+                                                  HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_dutyCycleCallbacks = RegisterCallback(m_dutyCycleCallbacks, "DutyCycle",
+                                            callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetDutyCycle());
+    callback("DutyCycle", param, &value);
+  }
+  return newUid;
+}
+
+void DigitalPWMData::CancelDutyCycleCallback(int32_t uid) {
+  m_dutyCycleCallbacks = CancelCallback(m_dutyCycleCallbacks, uid);
+}
+
+void DigitalPWMData::InvokeDutyCycleCallback(HAL_Value value) {
+  InvokeCallback(m_dutyCycleCallbacks, "DutyCycle", &value);
+}
+
+double DigitalPWMData::GetDutyCycle() { return m_dutyCycle; }
+
+void DigitalPWMData::SetDutyCycle(double dutyCycle) {
+  double oldValue = m_dutyCycle.exchange(dutyCycle);
+  if (oldValue != dutyCycle) {
+    InvokeDutyCycleCallback(MakeDouble(dutyCycle));
+  }
+}
+
+int32_t DigitalPWMData::RegisterPinCallback(HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_pinCallbacks =
+        RegisterCallback(m_pinCallbacks, "Pin", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetPin());
+    callback("Pin", param, &value);
+  }
+  return newUid;
+}
+
+void DigitalPWMData::CancelPinCallback(int32_t uid) {
+  m_pinCallbacks = CancelCallback(m_pinCallbacks, uid);
+}
+
+void DigitalPWMData::InvokePinCallback(HAL_Value value) {
+  InvokeCallback(m_pinCallbacks, "Pin", &value);
+}
+
+int32_t DigitalPWMData::GetPin() { return m_pin; }
+
+void DigitalPWMData::SetPin(int32_t pin) {
+  int32_t oldValue = m_pin.exchange(pin);
+  if (oldValue != pin) {
+    InvokePinCallback(MakeInt(pin));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetDigitalPWMData(int32_t index) {
+  SimDigitalPWMData[index].ResetData();
+}
+
+int32_t HALSIM_RegisterDigitalPWMInitializedCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimDigitalPWMData[index].RegisterInitializedCallback(callback, param,
+                                                              initialNotify);
+}
+
+void HALSIM_CancelDigitalPWMInitializedCallback(int32_t index, int32_t uid) {
+  SimDigitalPWMData[index].CancelInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetDigitalPWMInitialized(int32_t index) {
+  return SimDigitalPWMData[index].GetInitialized();
+}
+
+void HALSIM_SetDigitalPWMInitialized(int32_t index, HAL_Bool initialized) {
+  SimDigitalPWMData[index].SetInitialized(initialized);
+}
+
+int32_t HALSIM_RegisterDigitalPWMDutyCycleCallback(int32_t index,
+                                                   HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  return SimDigitalPWMData[index].RegisterDutyCycleCallback(callback, param,
+                                                            initialNotify);
+}
+
+void HALSIM_CancelDigitalPWMDutyCycleCallback(int32_t index, int32_t uid) {
+  SimDigitalPWMData[index].CancelDutyCycleCallback(uid);
+}
+
+double HALSIM_GetDigitalPWMDutyCycle(int32_t index) {
+  return SimDigitalPWMData[index].GetDutyCycle();
+}
+
+void HALSIM_SetDigitalPWMDutyCycle(int32_t index, double dutyCycle) {
+  SimDigitalPWMData[index].SetDutyCycle(dutyCycle);
+}
+
+int32_t HALSIM_RegisterDigitalPWMPinCallback(int32_t index,
+                                             HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  return SimDigitalPWMData[index].RegisterPinCallback(callback, param,
+                                                      initialNotify);
+}
+
+void HALSIM_CancelDigitalPWMPinCallback(int32_t index, int32_t uid) {
+  SimDigitalPWMData[index].CancelPinCallback(uid);
+}
+
+int32_t HALSIM_GetDigitalPWMPin(int32_t index) {
+  return SimDigitalPWMData[index].GetPin();
+}
+
+void HALSIM_SetDigitalPWMPin(int32_t index, int32_t pin) {
+  SimDigitalPWMData[index].SetPin(pin);
+}
+
+void HALSIM_RegisterDigitalPWMAllCallbacks(int32_t index,
+                                           HAL_NotifyCallback callback,
+                                           void* param,
+                                           HAL_Bool initialNotify) {
+  SimDigitalPWMData[index].RegisterInitializedCallback(callback, param,
+                                                       initialNotify);
+  SimDigitalPWMData[index].RegisterDutyCycleCallback(callback, param,
+                                                     initialNotify);
+  SimDigitalPWMData[index].RegisterPinCallback(callback, param, initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DigitalPWMDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DigitalPWMDataInternal.h
new file mode 100644
index 0000000..3ea5c24
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DigitalPWMDataInternal.h
@@ -0,0 +1,54 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/DigitalPWMData.h"
+#include "MockData/NotifyListenerVector.h"
+
+namespace hal {
+class DigitalPWMData {
+ public:
+  int32_t RegisterInitializedCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelInitializedCallback(int32_t uid);
+  void InvokeInitializedCallback(HAL_Value value);
+  HAL_Bool GetInitialized();
+  void SetInitialized(HAL_Bool initialized);
+
+  int32_t RegisterDutyCycleCallback(HAL_NotifyCallback callback, void* param,
+                                    HAL_Bool initialNotify);
+  void CancelDutyCycleCallback(int32_t uid);
+  void InvokeDutyCycleCallback(HAL_Value value);
+  double GetDutyCycle();
+  void SetDutyCycle(double dutyCycle);
+
+  int32_t RegisterPinCallback(HAL_NotifyCallback callback, void* param,
+                              HAL_Bool initialNotify);
+  void CancelPinCallback(int32_t uid);
+  void InvokePinCallback(HAL_Value value);
+  int32_t GetPin();
+  void SetPin(int32_t pin);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_initialized{false};
+  std::shared_ptr<NotifyListenerVector> m_initializedCallbacks = nullptr;
+  std::atomic<double> m_dutyCycle{false};
+  std::shared_ptr<NotifyListenerVector> m_dutyCycleCallbacks = nullptr;
+  std::atomic<int32_t> m_pin{0};
+  std::shared_ptr<NotifyListenerVector> m_pinCallbacks = nullptr;
+};
+extern DigitalPWMData* SimDigitalPWMData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DriverStationData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DriverStationData.cpp
new file mode 100644
index 0000000..c88f8b6
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DriverStationData.cpp
@@ -0,0 +1,641 @@
+/*----------------------------------------------------------------------------*/
+/* 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/cpp/make_unique.h"
+#include "MockData/NotifyCallbackHelpers.h"
+
+namespace hal {
+struct JoystickOutputStore {
+  int64_t outputs = 0;
+  int32_t leftRumble = 0;
+  int32_t rightRumble = 0;
+};
+struct MatchInfoDataStore {
+  std::string eventName;
+  std::string gameSpecificMessage;
+  int32_t replayNumber = 0;
+  int32_t matchNumber = 0;
+  HAL_MatchType matchType = HAL_MatchType::HAL_kMatchType_none;
+};
+}  // 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() {
+  m_enabled = false;
+  m_enabledCallbacks = nullptr;
+  m_autonomous = false;
+  m_autonomousCallbacks = nullptr;
+  m_test = false;
+  m_testCallbacks = nullptr;
+  m_eStop = false;
+  m_eStopCallbacks = nullptr;
+  m_fmsAttached = false;
+  m_fmsAttachedCallbacks = nullptr;
+  m_dsAttached = false;
+  m_dsAttachedCallbacks = nullptr;
+
+  {
+    std::lock_guard<wpi::mutex> 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::mutex> lock(m_matchInfoMutex);
+
+    m_matchInfo = std::make_unique<MatchInfoDataStore>();
+  }
+}
+
+int32_t DriverStationData::RegisterEnabledCallback(HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_enabledCallbacks = RegisterCallback(m_enabledCallbacks, "Enabled",
+                                          callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetEnabled());
+    callback("Enabled", param, &value);
+  }
+  return newUid;
+}
+
+void DriverStationData::CancelEnabledCallback(int32_t uid) {
+  m_enabledCallbacks = CancelCallback(m_enabledCallbacks, uid);
+}
+
+void DriverStationData::InvokeEnabledCallback(HAL_Value value) {
+  InvokeCallback(m_enabledCallbacks, "Enabled", &value);
+}
+
+HAL_Bool DriverStationData::GetEnabled() { return m_enabled; }
+
+void DriverStationData::SetEnabled(HAL_Bool enabled) {
+  HAL_Bool oldValue = m_enabled.exchange(enabled);
+  if (oldValue != enabled) {
+    InvokeEnabledCallback(MakeBoolean(enabled));
+  }
+}
+
+int32_t DriverStationData::RegisterAutonomousCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_autonomousCallbacks = RegisterCallback(
+        m_autonomousCallbacks, "Autonomous", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetAutonomous());
+    callback("Autonomous", param, &value);
+  }
+  return newUid;
+}
+
+void DriverStationData::CancelAutonomousCallback(int32_t uid) {
+  m_autonomousCallbacks = CancelCallback(m_autonomousCallbacks, uid);
+}
+
+void DriverStationData::InvokeAutonomousCallback(HAL_Value value) {
+  InvokeCallback(m_autonomousCallbacks, "Autonomous", &value);
+}
+
+HAL_Bool DriverStationData::GetAutonomous() { return m_autonomous; }
+
+void DriverStationData::SetAutonomous(HAL_Bool autonomous) {
+  HAL_Bool oldValue = m_autonomous.exchange(autonomous);
+  if (oldValue != autonomous) {
+    InvokeAutonomousCallback(MakeBoolean(autonomous));
+  }
+}
+
+int32_t DriverStationData::RegisterTestCallback(HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_testCallbacks =
+        RegisterCallback(m_testCallbacks, "Test", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetTest());
+    callback("Test", param, &value);
+  }
+  return newUid;
+}
+
+void DriverStationData::CancelTestCallback(int32_t uid) {
+  m_testCallbacks = CancelCallback(m_testCallbacks, uid);
+}
+
+void DriverStationData::InvokeTestCallback(HAL_Value value) {
+  InvokeCallback(m_testCallbacks, "Test", &value);
+}
+
+HAL_Bool DriverStationData::GetTest() { return m_test; }
+
+void DriverStationData::SetTest(HAL_Bool test) {
+  HAL_Bool oldValue = m_test.exchange(test);
+  if (oldValue != test) {
+    InvokeTestCallback(MakeBoolean(test));
+  }
+}
+
+int32_t DriverStationData::RegisterEStopCallback(HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_eStopCallbacks =
+        RegisterCallback(m_eStopCallbacks, "EStop", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetEStop());
+    callback("EStop", param, &value);
+  }
+  return newUid;
+}
+
+void DriverStationData::CancelEStopCallback(int32_t uid) {
+  m_eStopCallbacks = CancelCallback(m_eStopCallbacks, uid);
+}
+
+void DriverStationData::InvokeEStopCallback(HAL_Value value) {
+  InvokeCallback(m_eStopCallbacks, "EStop", &value);
+}
+
+HAL_Bool DriverStationData::GetEStop() { return m_eStop; }
+
+void DriverStationData::SetEStop(HAL_Bool eStop) {
+  HAL_Bool oldValue = m_eStop.exchange(eStop);
+  if (oldValue != eStop) {
+    InvokeEStopCallback(MakeBoolean(eStop));
+  }
+}
+
+int32_t DriverStationData::RegisterFmsAttachedCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_fmsAttachedCallbacks = RegisterCallback(
+        m_fmsAttachedCallbacks, "FmsAttached", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetFmsAttached());
+    callback("FmsAttached", param, &value);
+  }
+  return newUid;
+}
+
+void DriverStationData::CancelFmsAttachedCallback(int32_t uid) {
+  m_fmsAttachedCallbacks = CancelCallback(m_fmsAttachedCallbacks, uid);
+}
+
+void DriverStationData::InvokeFmsAttachedCallback(HAL_Value value) {
+  InvokeCallback(m_fmsAttachedCallbacks, "FmsAttached", &value);
+}
+
+HAL_Bool DriverStationData::GetFmsAttached() { return m_fmsAttached; }
+
+void DriverStationData::SetFmsAttached(HAL_Bool fmsAttached) {
+  HAL_Bool oldValue = m_fmsAttached.exchange(fmsAttached);
+  if (oldValue != fmsAttached) {
+    InvokeFmsAttachedCallback(MakeBoolean(fmsAttached));
+  }
+}
+
+int32_t DriverStationData::RegisterDsAttachedCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_dsAttachedCallbacks = RegisterCallback(
+        m_dsAttachedCallbacks, "DsAttached", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetDsAttached());
+    callback("DsAttached", param, &value);
+  }
+  return newUid;
+}
+
+void DriverStationData::CancelDsAttachedCallback(int32_t uid) {
+  m_dsAttachedCallbacks = CancelCallback(m_dsAttachedCallbacks, uid);
+}
+
+void DriverStationData::InvokeDsAttachedCallback(HAL_Value value) {
+  InvokeCallback(m_dsAttachedCallbacks, "DsAttached", &value);
+}
+
+HAL_Bool DriverStationData::GetDsAttached() { return m_dsAttached; }
+
+void DriverStationData::SetDsAttached(HAL_Bool dsAttached) {
+  HAL_Bool oldValue = m_dsAttached.exchange(dsAttached);
+  if (oldValue != dsAttached) {
+    InvokeDsAttachedCallback(MakeBoolean(dsAttached));
+  }
+}
+
+int32_t DriverStationData::RegisterAllianceStationIdCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_allianceStationIdCallbacks =
+        RegisterCallback(m_allianceStationIdCallbacks, "AllianceStationId",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeEnum(GetAllianceStationId());
+    callback("AllianceStationId", param, &value);
+  }
+  return newUid;
+}
+
+void DriverStationData::CancelAllianceStationIdCallback(int32_t uid) {
+  m_allianceStationIdCallbacks =
+      CancelCallback(m_allianceStationIdCallbacks, uid);
+}
+
+void DriverStationData::InvokeAllianceStationIdCallback(HAL_Value value) {
+  InvokeCallback(m_allianceStationIdCallbacks, "AllianceStationId", &value);
+}
+
+HAL_AllianceStationID DriverStationData::GetAllianceStationId() {
+  return m_allianceStationId;
+}
+
+void DriverStationData::SetAllianceStationId(
+    HAL_AllianceStationID allianceStationId) {
+  HAL_AllianceStationID oldValue =
+      m_allianceStationId.exchange(allianceStationId);
+  if (oldValue != allianceStationId) {
+    InvokeAllianceStationIdCallback(MakeEnum(allianceStationId));
+  }
+}
+
+int32_t DriverStationData::RegisterMatchTimeCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_matchTimeCallbacks = RegisterCallback(m_matchTimeCallbacks, "MatchTime",
+                                            callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetMatchTime());
+    callback("MatchTime", param, &value);
+  }
+  return newUid;
+}
+
+void DriverStationData::CancelMatchTimeCallback(int32_t uid) {
+  m_matchTimeCallbacks = CancelCallback(m_matchTimeCallbacks, uid);
+}
+
+void DriverStationData::InvokeMatchTimeCallback(HAL_Value value) {
+  InvokeCallback(m_matchTimeCallbacks, "MatchTime", &value);
+}
+
+double DriverStationData::GetMatchTime() { return m_matchTime; }
+
+void DriverStationData::SetMatchTime(double matchTime) {
+  double oldValue = m_matchTime.exchange(matchTime);
+  if (oldValue != matchTime) {
+    InvokeMatchTimeCallback(MakeDouble(matchTime));
+  }
+}
+
+void DriverStationData::GetJoystickAxes(int32_t joystickNum,
+                                        HAL_JoystickAxes* axes) {
+  std::lock_guard<wpi::mutex> lock(m_joystickDataMutex);
+  *axes = m_joystickAxes[joystickNum];
+}
+void DriverStationData::GetJoystickPOVs(int32_t joystickNum,
+                                        HAL_JoystickPOVs* povs) {
+  std::lock_guard<wpi::mutex> lock(m_joystickDataMutex);
+  *povs = m_joystickPOVs[joystickNum];
+}
+void DriverStationData::GetJoystickButtons(int32_t joystickNum,
+                                           HAL_JoystickButtons* buttons) {
+  std::lock_guard<wpi::mutex> lock(m_joystickDataMutex);
+  *buttons = m_joystickButtons[joystickNum];
+}
+void DriverStationData::GetJoystickDescriptor(
+    int32_t joystickNum, HAL_JoystickDescriptor* descriptor) {
+  std::lock_guard<wpi::mutex> 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::mutex> 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::mutex> lock(m_matchInfoMutex);
+  auto eventLen = m_matchInfo->eventName.size();
+  info->eventName = static_cast<char*>(std::malloc(eventLen + 1));
+  std::memcpy(info->eventName, m_matchInfo->eventName.c_str(), eventLen);
+  auto gameLen = m_matchInfo->gameSpecificMessage.size();
+  info->gameSpecificMessage = static_cast<char*>(std::malloc(gameLen + 1));
+  std::memcpy(info->gameSpecificMessage,
+              m_matchInfo->gameSpecificMessage.c_str(), gameLen);
+  info->gameSpecificMessage[gameLen] = '\0';
+  info->eventName[eventLen] = '\0';
+  info->matchNumber = m_matchInfo->matchNumber;
+  info->replayNumber = m_matchInfo->replayNumber;
+  info->matchType = m_matchInfo->matchType;
+}
+void DriverStationData::FreeMatchInfo(const HAL_MatchInfo* info) {
+  std::free(info->eventName);
+  std::free(info->gameSpecificMessage);
+}
+
+void DriverStationData::SetJoystickAxes(int32_t joystickNum,
+                                        const HAL_JoystickAxes* axes) {
+  std::lock_guard<wpi::mutex> lock(m_joystickDataMutex);
+  m_joystickAxes[joystickNum] = *axes;
+}
+void DriverStationData::SetJoystickPOVs(int32_t joystickNum,
+                                        const HAL_JoystickPOVs* povs) {
+  std::lock_guard<wpi::mutex> lock(m_joystickDataMutex);
+  m_joystickPOVs[joystickNum] = *povs;
+}
+void DriverStationData::SetJoystickButtons(int32_t joystickNum,
+                                           const HAL_JoystickButtons* buttons) {
+  std::lock_guard<wpi::mutex> lock(m_joystickDataMutex);
+  m_joystickButtons[joystickNum] = *buttons;
+}
+
+void DriverStationData::SetJoystickDescriptor(
+    int32_t joystickNum, const HAL_JoystickDescriptor* descriptor) {
+  std::lock_guard<wpi::mutex> 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::mutex> 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::mutex> lock(m_matchInfoMutex);
+  m_matchInfo->eventName = info->eventName;
+  m_matchInfo->gameSpecificMessage = info->gameSpecificMessage;
+  m_matchInfo->matchNumber = info->matchNumber;
+  m_matchInfo->matchType = info->matchType;
+  m_matchInfo->replayNumber = info->replayNumber;
+}
+
+void DriverStationData::NotifyNewData() { HAL_ReleaseDSMutex(); }
+
+extern "C" {
+void HALSIM_ResetDriverStationData(void) { SimDriverStationData->ResetData(); }
+
+int32_t HALSIM_RegisterDriverStationEnabledCallback(HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  return SimDriverStationData->RegisterEnabledCallback(callback, param,
+                                                       initialNotify);
+}
+void HALSIM_CancelDriverStationEnabledCallback(int32_t uid) {
+  SimDriverStationData->CancelEnabledCallback(uid);
+}
+HAL_Bool HALSIM_GetDriverStationEnabled(void) {
+  return SimDriverStationData->GetEnabled();
+}
+void HALSIM_SetDriverStationEnabled(HAL_Bool enabled) {
+  SimDriverStationData->SetEnabled(enabled);
+}
+
+int32_t HALSIM_RegisterDriverStationAutonomousCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  return SimDriverStationData->RegisterAutonomousCallback(callback, param,
+                                                          initialNotify);
+}
+void HALSIM_CancelDriverStationAutonomousCallback(int32_t uid) {
+  SimDriverStationData->CancelAutonomousCallback(uid);
+}
+HAL_Bool HALSIM_GetDriverStationAutonomous(void) {
+  return SimDriverStationData->GetAutonomous();
+}
+void HALSIM_SetDriverStationAutonomous(HAL_Bool autonomous) {
+  SimDriverStationData->SetAutonomous(autonomous);
+}
+
+int32_t HALSIM_RegisterDriverStationTestCallback(HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  return SimDriverStationData->RegisterTestCallback(callback, param,
+                                                    initialNotify);
+}
+void HALSIM_CancelDriverStationTestCallback(int32_t uid) {
+  SimDriverStationData->CancelTestCallback(uid);
+}
+HAL_Bool HALSIM_GetDriverStationTest(void) {
+  return SimDriverStationData->GetTest();
+}
+void HALSIM_SetDriverStationTest(HAL_Bool test) {
+  SimDriverStationData->SetTest(test);
+}
+
+int32_t HALSIM_RegisterDriverStationEStopCallback(HAL_NotifyCallback callback,
+                                                  void* param,
+                                                  HAL_Bool initialNotify) {
+  return SimDriverStationData->RegisterEStopCallback(callback, param,
+                                                     initialNotify);
+}
+void HALSIM_CancelDriverStationEStopCallback(int32_t uid) {
+  SimDriverStationData->CancelEStopCallback(uid);
+}
+HAL_Bool HALSIM_GetDriverStationEStop(void) {
+  return SimDriverStationData->GetEStop();
+}
+void HALSIM_SetDriverStationEStop(HAL_Bool eStop) {
+  SimDriverStationData->SetEStop(eStop);
+}
+
+int32_t HALSIM_RegisterDriverStationFmsAttachedCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  return SimDriverStationData->RegisterFmsAttachedCallback(callback, param,
+                                                           initialNotify);
+}
+void HALSIM_CancelDriverStationFmsAttachedCallback(int32_t uid) {
+  SimDriverStationData->CancelFmsAttachedCallback(uid);
+}
+HAL_Bool HALSIM_GetDriverStationFmsAttached(void) {
+  return SimDriverStationData->GetFmsAttached();
+}
+void HALSIM_SetDriverStationFmsAttached(HAL_Bool fmsAttached) {
+  SimDriverStationData->SetFmsAttached(fmsAttached);
+}
+
+int32_t HALSIM_RegisterDriverStationDsAttachedCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  return SimDriverStationData->RegisterDsAttachedCallback(callback, param,
+                                                          initialNotify);
+}
+void HALSIM_CancelDriverStationDsAttachedCallback(int32_t uid) {
+  SimDriverStationData->CancelDsAttachedCallback(uid);
+}
+HAL_Bool HALSIM_GetDriverStationDsAttached(void) {
+  return SimDriverStationData->GetDsAttached();
+}
+void HALSIM_SetDriverStationDsAttached(HAL_Bool dsAttached) {
+  SimDriverStationData->SetDsAttached(dsAttached);
+}
+
+int32_t HALSIM_RegisterDriverStationAllianceStationIdCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  return SimDriverStationData->RegisterAllianceStationIdCallback(
+      callback, param, initialNotify);
+}
+void HALSIM_CancelDriverStationAllianceStationIdCallback(int32_t uid) {
+  SimDriverStationData->CancelAllianceStationIdCallback(uid);
+}
+HAL_AllianceStationID HALSIM_GetDriverStationAllianceStationId(void) {
+  return SimDriverStationData->GetAllianceStationId();
+}
+void HALSIM_SetDriverStationAllianceStationId(
+    HAL_AllianceStationID allianceStationId) {
+  SimDriverStationData->SetAllianceStationId(allianceStationId);
+}
+
+int32_t HALSIM_RegisterDriverStationMatchTimeCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  return SimDriverStationData->RegisterMatchTimeCallback(callback, param,
+                                                         initialNotify);
+}
+void HALSIM_CancelDriverStationMatchTimeCallback(int32_t uid) {
+  SimDriverStationData->CancelMatchTimeCallback(uid);
+}
+double HALSIM_GetDriverStationMatchTime(void) {
+  return SimDriverStationData->GetMatchTime();
+}
+void HALSIM_SetDriverStationMatchTime(double matchTime) {
+  SimDriverStationData->SetMatchTime(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();
+}
+
+void HALSIM_RegisterDriverStationAllCallbacks(HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  SimDriverStationData->RegisterEnabledCallback(callback, param, initialNotify);
+  SimDriverStationData->RegisterAutonomousCallback(callback, param,
+                                                   initialNotify);
+  SimDriverStationData->RegisterTestCallback(callback, param, initialNotify);
+  SimDriverStationData->RegisterEStopCallback(callback, param, initialNotify);
+  SimDriverStationData->RegisterFmsAttachedCallback(callback, param,
+                                                    initialNotify);
+  SimDriverStationData->RegisterDsAttachedCallback(callback, param,
+                                                   initialNotify);
+  SimDriverStationData->RegisterAllianceStationIdCallback(callback, param,
+                                                          initialNotify);
+  SimDriverStationData->RegisterMatchTimeCallback(callback, param,
+                                                  initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DriverStationDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DriverStationDataInternal.h
new file mode 100644
index 0000000..16614c2
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/DriverStationDataInternal.h
@@ -0,0 +1,139 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <array>
+#include <atomic>
+#include <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/DriverStationData.h"
+#include "MockData/NotifyListenerVector.h"
+
+namespace hal {
+struct JoystickOutputStore;
+struct MatchInfoDataStore;
+
+class DriverStationData {
+ public:
+  DriverStationData();
+  void ResetData();
+
+  int32_t RegisterEnabledCallback(HAL_NotifyCallback callback, void* param,
+                                  HAL_Bool initialNotify);
+  void CancelEnabledCallback(int32_t uid);
+  void InvokeEnabledCallback(HAL_Value value);
+  HAL_Bool GetEnabled();
+  void SetEnabled(HAL_Bool enabled);
+
+  int32_t RegisterAutonomousCallback(HAL_NotifyCallback callback, void* param,
+                                     HAL_Bool initialNotify);
+  void CancelAutonomousCallback(int32_t uid);
+  void InvokeAutonomousCallback(HAL_Value value);
+  HAL_Bool GetAutonomous();
+  void SetAutonomous(HAL_Bool autonomous);
+
+  int32_t RegisterTestCallback(HAL_NotifyCallback callback, void* param,
+                               HAL_Bool initialNotify);
+  void CancelTestCallback(int32_t uid);
+  void InvokeTestCallback(HAL_Value value);
+  HAL_Bool GetTest();
+  void SetTest(HAL_Bool test);
+
+  int32_t RegisterEStopCallback(HAL_NotifyCallback callback, void* param,
+                                HAL_Bool initialNotify);
+  void CancelEStopCallback(int32_t uid);
+  void InvokeEStopCallback(HAL_Value value);
+  HAL_Bool GetEStop();
+  void SetEStop(HAL_Bool eStop);
+
+  int32_t RegisterFmsAttachedCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelFmsAttachedCallback(int32_t uid);
+  void InvokeFmsAttachedCallback(HAL_Value value);
+  HAL_Bool GetFmsAttached();
+  void SetFmsAttached(HAL_Bool fmsAttached);
+
+  int32_t RegisterDsAttachedCallback(HAL_NotifyCallback callback, void* param,
+                                     HAL_Bool initialNotify);
+  void CancelDsAttachedCallback(int32_t uid);
+  void InvokeDsAttachedCallback(HAL_Value value);
+  HAL_Bool GetDsAttached();
+  void SetDsAttached(HAL_Bool dsAttached);
+
+  int32_t RegisterAllianceStationIdCallback(HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify);
+  void CancelAllianceStationIdCallback(int32_t uid);
+  void InvokeAllianceStationIdCallback(HAL_Value value);
+  HAL_AllianceStationID GetAllianceStationId();
+  void SetAllianceStationId(HAL_AllianceStationID allianceStationId);
+
+  int32_t RegisterMatchTimeCallback(HAL_NotifyCallback callback, void* param,
+                                    HAL_Bool initialNotify);
+  void CancelMatchTimeCallback(int32_t uid);
+  void InvokeMatchTimeCallback(HAL_Value value);
+  double GetMatchTime();
+  void SetMatchTime(double matchTime);
+
+  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();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_enabled{false};
+  std::shared_ptr<NotifyListenerVector> m_enabledCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_autonomous{false};
+  std::shared_ptr<NotifyListenerVector> m_autonomousCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_test{false};
+  std::shared_ptr<NotifyListenerVector> m_testCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_eStop{false};
+  std::shared_ptr<NotifyListenerVector> m_eStopCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_fmsAttached{false};
+  std::shared_ptr<NotifyListenerVector> m_fmsAttachedCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_dsAttached{false};
+  std::shared_ptr<NotifyListenerVector> m_dsAttachedCallbacks = nullptr;
+  std::atomic<HAL_AllianceStationID> m_allianceStationId{
+      static_cast<HAL_AllianceStationID>(0)};
+  std::shared_ptr<NotifyListenerVector> m_allianceStationIdCallbacks = nullptr;
+  std::atomic<double> m_matchTime{0.0};
+  std::shared_ptr<NotifyListenerVector> m_matchTimeCallbacks = nullptr;
+
+  wpi::mutex m_joystickDataMutex;
+  wpi::mutex 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<MatchInfoDataStore> m_matchInfo;
+};
+extern DriverStationData* SimDriverStationData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/EncoderData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/EncoderData.cpp
new file mode 100644
index 0000000..b8da1b7
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/EncoderData.cpp
@@ -0,0 +1,555 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+#include "MockData/NotifyCallbackHelpers.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() {
+  m_initialized = false;
+  m_initializedCallbacks = nullptr;
+  m_count = 0;
+  m_countCallbacks = nullptr;
+  m_period = std::numeric_limits<double>::max();
+  m_periodCallbacks = nullptr;
+  m_reset = false;
+  m_resetCallbacks = nullptr;
+  m_maxPeriod = 0;
+  m_maxPeriodCallbacks = nullptr;
+  m_direction = false;
+  m_directionCallbacks = nullptr;
+  m_reverseDirection = false;
+  m_reverseDirectionCallbacks = nullptr;
+  m_samplesToAverage = 0;
+  m_samplesToAverageCallbacks = nullptr;
+  m_distancePerPulse = 0;
+  m_distancePerPulseCallbacks = nullptr;
+}
+
+int32_t EncoderData::RegisterInitializedCallback(HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedCallbacks = RegisterCallback(
+        m_initializedCallbacks, "Initialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitialized());
+    callback("Initialized", param, &value);
+  }
+  return newUid;
+}
+
+void EncoderData::CancelInitializedCallback(int32_t uid) {
+  m_initializedCallbacks = CancelCallback(m_initializedCallbacks, uid);
+}
+
+void EncoderData::InvokeInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_initializedCallbacks, "Initialized", &value);
+}
+
+HAL_Bool EncoderData::GetInitialized() { return m_initialized; }
+
+void EncoderData::SetInitialized(HAL_Bool initialized) {
+  HAL_Bool oldValue = m_initialized.exchange(initialized);
+  if (oldValue != initialized) {
+    InvokeInitializedCallback(MakeBoolean(initialized));
+  }
+}
+
+int32_t EncoderData::RegisterCountCallback(HAL_NotifyCallback callback,
+                                           void* param,
+                                           HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_countCallbacks =
+        RegisterCallback(m_countCallbacks, "Count", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetCount());
+    callback("Count", param, &value);
+  }
+  return newUid;
+}
+
+void EncoderData::CancelCountCallback(int32_t uid) {
+  m_countCallbacks = CancelCallback(m_countCallbacks, uid);
+}
+
+void EncoderData::InvokeCountCallback(HAL_Value value) {
+  InvokeCallback(m_countCallbacks, "Count", &value);
+}
+
+int32_t EncoderData::GetCount() { return m_count; }
+
+void EncoderData::SetCount(int32_t count) {
+  int32_t oldValue = m_count.exchange(count);
+  if (oldValue != count) {
+    InvokeCountCallback(MakeInt(count));
+  }
+}
+
+int32_t EncoderData::RegisterPeriodCallback(HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_periodCallbacks =
+        RegisterCallback(m_periodCallbacks, "Period", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetPeriod());
+    callback("Period", param, &value);
+  }
+  return newUid;
+}
+
+void EncoderData::CancelPeriodCallback(int32_t uid) {
+  m_periodCallbacks = CancelCallback(m_periodCallbacks, uid);
+}
+
+void EncoderData::InvokePeriodCallback(HAL_Value value) {
+  InvokeCallback(m_periodCallbacks, "Period", &value);
+}
+
+double EncoderData::GetPeriod() { return m_period; }
+
+void EncoderData::SetPeriod(double period) {
+  double oldValue = m_period.exchange(period);
+  if (oldValue != period) {
+    InvokePeriodCallback(MakeDouble(period));
+  }
+}
+
+int32_t EncoderData::RegisterResetCallback(HAL_NotifyCallback callback,
+                                           void* param,
+                                           HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_resetCallbacks =
+        RegisterCallback(m_resetCallbacks, "Reset", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetReset());
+    callback("Reset", param, &value);
+  }
+  return newUid;
+}
+
+void EncoderData::CancelResetCallback(int32_t uid) {
+  m_resetCallbacks = CancelCallback(m_resetCallbacks, uid);
+}
+
+void EncoderData::InvokeResetCallback(HAL_Value value) {
+  InvokeCallback(m_resetCallbacks, "Reset", &value);
+}
+
+HAL_Bool EncoderData::GetReset() { return m_reset; }
+
+void EncoderData::SetReset(HAL_Bool reset) {
+  HAL_Bool oldValue = m_reset.exchange(reset);
+  if (oldValue != reset) {
+    InvokeResetCallback(MakeBoolean(reset));
+  }
+}
+
+int32_t EncoderData::RegisterMaxPeriodCallback(HAL_NotifyCallback callback,
+                                               void* param,
+                                               HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_maxPeriodCallbacks = RegisterCallback(m_maxPeriodCallbacks, "MaxPeriod",
+                                            callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetMaxPeriod());
+    callback("MaxPeriod", param, &value);
+  }
+  return newUid;
+}
+
+void EncoderData::CancelMaxPeriodCallback(int32_t uid) {
+  m_maxPeriodCallbacks = CancelCallback(m_maxPeriodCallbacks, uid);
+}
+
+void EncoderData::InvokeMaxPeriodCallback(HAL_Value value) {
+  InvokeCallback(m_maxPeriodCallbacks, "MaxPeriod", &value);
+}
+
+double EncoderData::GetMaxPeriod() { return m_maxPeriod; }
+
+void EncoderData::SetMaxPeriod(double maxPeriod) {
+  double oldValue = m_maxPeriod.exchange(maxPeriod);
+  if (oldValue != maxPeriod) {
+    InvokeMaxPeriodCallback(MakeDouble(maxPeriod));
+  }
+}
+
+int32_t EncoderData::RegisterDirectionCallback(HAL_NotifyCallback callback,
+                                               void* param,
+                                               HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_directionCallbacks = RegisterCallback(m_directionCallbacks, "Direction",
+                                            callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetDirection());
+    callback("Direction", param, &value);
+  }
+  return newUid;
+}
+
+void EncoderData::CancelDirectionCallback(int32_t uid) {
+  m_directionCallbacks = CancelCallback(m_directionCallbacks, uid);
+}
+
+void EncoderData::InvokeDirectionCallback(HAL_Value value) {
+  InvokeCallback(m_directionCallbacks, "Direction", &value);
+}
+
+HAL_Bool EncoderData::GetDirection() { return m_direction; }
+
+void EncoderData::SetDirection(HAL_Bool direction) {
+  HAL_Bool oldValue = m_direction.exchange(direction);
+  if (oldValue != direction) {
+    InvokeDirectionCallback(MakeBoolean(direction));
+  }
+}
+
+int32_t EncoderData::RegisterReverseDirectionCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_reverseDirectionCallbacks =
+        RegisterCallback(m_reverseDirectionCallbacks, "ReverseDirection",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetReverseDirection());
+    callback("ReverseDirection", param, &value);
+  }
+  return newUid;
+}
+
+void EncoderData::CancelReverseDirectionCallback(int32_t uid) {
+  m_reverseDirectionCallbacks =
+      CancelCallback(m_reverseDirectionCallbacks, uid);
+}
+
+void EncoderData::InvokeReverseDirectionCallback(HAL_Value value) {
+  InvokeCallback(m_reverseDirectionCallbacks, "ReverseDirection", &value);
+}
+
+HAL_Bool EncoderData::GetReverseDirection() { return m_reverseDirection; }
+
+void EncoderData::SetReverseDirection(HAL_Bool reverseDirection) {
+  HAL_Bool oldValue = m_reverseDirection.exchange(reverseDirection);
+  if (oldValue != reverseDirection) {
+    InvokeReverseDirectionCallback(MakeBoolean(reverseDirection));
+  }
+}
+
+int32_t EncoderData::RegisterSamplesToAverageCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_samplesToAverageCallbacks =
+        RegisterCallback(m_samplesToAverageCallbacks, "SamplesToAverage",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetSamplesToAverage());
+    callback("SamplesToAverage", param, &value);
+  }
+  return newUid;
+}
+
+void EncoderData::CancelSamplesToAverageCallback(int32_t uid) {
+  m_samplesToAverageCallbacks =
+      CancelCallback(m_samplesToAverageCallbacks, uid);
+}
+
+void EncoderData::InvokeSamplesToAverageCallback(HAL_Value value) {
+  InvokeCallback(m_samplesToAverageCallbacks, "SamplesToAverage", &value);
+}
+
+int32_t EncoderData::GetSamplesToAverage() { return m_samplesToAverage; }
+
+void EncoderData::SetSamplesToAverage(int32_t samplesToAverage) {
+  int32_t oldValue = m_samplesToAverage.exchange(samplesToAverage);
+  if (oldValue != samplesToAverage) {
+    InvokeSamplesToAverageCallback(MakeInt(samplesToAverage));
+  }
+}
+
+int32_t EncoderData::RegisterDistancePerPulseCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_distancePerPulseCallbacks =
+        RegisterCallback(m_distancePerPulseCallbacks, "DistancePerPulse",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetDistancePerPulse());
+    callback("DistancePerPulse", param, &value);
+  }
+  return newUid;
+}
+void EncoderData::CancelDistancePerPulseCallback(int32_t uid) {
+  m_distancePerPulseCallbacks =
+      CancelCallback(m_distancePerPulseCallbacks, uid);
+}
+
+void EncoderData::InvokeDistancePerPulseCallback(HAL_Value value) {
+  InvokeCallback(m_distancePerPulseCallbacks, "DistancePerPulse", &value);
+}
+
+double EncoderData::GetDistancePerPulse() { return m_distancePerPulse; }
+
+void EncoderData::SetDistancePerPulse(double distancePerPulse) {
+  double oldValue = m_distancePerPulse.exchange(distancePerPulse);
+  if (oldValue != distancePerPulse) {
+    InvokeDistancePerPulseCallback(MakeDouble(distancePerPulse));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetEncoderData(int32_t index) {
+  SimEncoderData[index].ResetData();
+}
+
+int32_t HALSIM_RegisterEncoderInitializedCallback(int32_t index,
+                                                  HAL_NotifyCallback callback,
+                                                  void* param,
+                                                  HAL_Bool initialNotify) {
+  return SimEncoderData[index].RegisterInitializedCallback(callback, param,
+                                                           initialNotify);
+}
+
+void HALSIM_CancelEncoderInitializedCallback(int32_t index, int32_t uid) {
+  SimEncoderData[index].CancelInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetEncoderInitialized(int32_t index) {
+  return SimEncoderData[index].GetInitialized();
+}
+
+void HALSIM_SetEncoderInitialized(int32_t index, HAL_Bool initialized) {
+  SimEncoderData[index].SetInitialized(initialized);
+}
+
+int32_t HALSIM_RegisterEncoderCountCallback(int32_t index,
+                                            HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify) {
+  return SimEncoderData[index].RegisterCountCallback(callback, param,
+                                                     initialNotify);
+}
+
+void HALSIM_CancelEncoderCountCallback(int32_t index, int32_t uid) {
+  SimEncoderData[index].CancelCountCallback(uid);
+}
+
+int32_t HALSIM_GetEncoderCount(int32_t index) {
+  return SimEncoderData[index].GetCount();
+}
+
+void HALSIM_SetEncoderCount(int32_t index, int32_t count) {
+  SimEncoderData[index].SetCount(count);
+}
+
+int32_t HALSIM_RegisterEncoderPeriodCallback(int32_t index,
+                                             HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  return SimEncoderData[index].RegisterPeriodCallback(callback, param,
+                                                      initialNotify);
+}
+
+void HALSIM_CancelEncoderPeriodCallback(int32_t index, int32_t uid) {
+  SimEncoderData[index].CancelPeriodCallback(uid);
+}
+
+double HALSIM_GetEncoderPeriod(int32_t index) {
+  return SimEncoderData[index].GetPeriod();
+}
+
+void HALSIM_SetEncoderPeriod(int32_t index, double period) {
+  SimEncoderData[index].SetPeriod(period);
+}
+
+int32_t HALSIM_RegisterEncoderResetCallback(int32_t index,
+                                            HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify) {
+  return SimEncoderData[index].RegisterResetCallback(callback, param,
+                                                     initialNotify);
+}
+
+void HALSIM_CancelEncoderResetCallback(int32_t index, int32_t uid) {
+  SimEncoderData[index].CancelResetCallback(uid);
+}
+
+HAL_Bool HALSIM_GetEncoderReset(int32_t index) {
+  return SimEncoderData[index].GetReset();
+}
+
+void HALSIM_SetEncoderReset(int32_t index, HAL_Bool reset) {
+  SimEncoderData[index].SetReset(reset);
+}
+
+int32_t HALSIM_RegisterEncoderMaxPeriodCallback(int32_t index,
+                                                HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify) {
+  return SimEncoderData[index].RegisterMaxPeriodCallback(callback, param,
+                                                         initialNotify);
+}
+
+void HALSIM_CancelEncoderMaxPeriodCallback(int32_t index, int32_t uid) {
+  SimEncoderData[index].CancelMaxPeriodCallback(uid);
+}
+
+double HALSIM_GetEncoderMaxPeriod(int32_t index) {
+  return SimEncoderData[index].GetMaxPeriod();
+}
+
+void HALSIM_SetEncoderMaxPeriod(int32_t index, double maxPeriod) {
+  SimEncoderData[index].SetMaxPeriod(maxPeriod);
+}
+
+int32_t HALSIM_RegisterEncoderDirectionCallback(int32_t index,
+                                                HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify) {
+  return SimEncoderData[index].RegisterDirectionCallback(callback, param,
+                                                         initialNotify);
+}
+
+void HALSIM_CancelEncoderDirectionCallback(int32_t index, int32_t uid) {
+  SimEncoderData[index].CancelDirectionCallback(uid);
+}
+
+HAL_Bool HALSIM_GetEncoderDirection(int32_t index) {
+  return SimEncoderData[index].GetDirection();
+}
+
+void HALSIM_SetEncoderDirection(int32_t index, HAL_Bool direction) {
+  SimEncoderData[index].SetDirection(direction);
+}
+
+int32_t HALSIM_RegisterEncoderReverseDirectionCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimEncoderData[index].RegisterReverseDirectionCallback(callback, param,
+                                                                initialNotify);
+}
+
+void HALSIM_CancelEncoderReverseDirectionCallback(int32_t index, int32_t uid) {
+  SimEncoderData[index].CancelReverseDirectionCallback(uid);
+}
+
+HAL_Bool HALSIM_GetEncoderReverseDirection(int32_t index) {
+  return SimEncoderData[index].GetReverseDirection();
+}
+
+void HALSIM_SetEncoderReverseDirection(int32_t index,
+                                       HAL_Bool reverseDirection) {
+  SimEncoderData[index].SetReverseDirection(reverseDirection);
+}
+
+int32_t HALSIM_RegisterEncoderSamplesToAverageCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimEncoderData[index].RegisterSamplesToAverageCallback(callback, param,
+                                                                initialNotify);
+}
+
+void HALSIM_CancelEncoderSamplesToAverageCallback(int32_t index, int32_t uid) {
+  SimEncoderData[index].CancelSamplesToAverageCallback(uid);
+}
+
+int32_t HALSIM_GetEncoderSamplesToAverage(int32_t index) {
+  return SimEncoderData[index].GetSamplesToAverage();
+}
+
+void HALSIM_SetEncoderSamplesToAverage(int32_t index,
+                                       int32_t samplesToAverage) {
+  SimEncoderData[index].SetSamplesToAverage(samplesToAverage);
+}
+
+void HALSIM_RegisterEncoderAllCallbacks(int32_t index,
+                                        HAL_NotifyCallback callback,
+                                        void* param, HAL_Bool initialNotify) {
+  SimEncoderData[index].RegisterInitializedCallback(callback, param,
+                                                    initialNotify);
+  SimEncoderData[index].RegisterCountCallback(callback, param, initialNotify);
+  SimEncoderData[index].RegisterPeriodCallback(callback, param, initialNotify);
+  SimEncoderData[index].RegisterResetCallback(callback, param, initialNotify);
+  SimEncoderData[index].RegisterMaxPeriodCallback(callback, param,
+                                                  initialNotify);
+  SimEncoderData[index].RegisterDirectionCallback(callback, param,
+                                                  initialNotify);
+  SimEncoderData[index].RegisterReverseDirectionCallback(callback, param,
+                                                         initialNotify);
+  SimEncoderData[index].RegisterSamplesToAverageCallback(callback, param,
+                                                         initialNotify);
+  SimEncoderData[index].RegisterDistancePerPulseCallback(callback, param,
+                                                         initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/EncoderDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/EncoderDataInternal.h
new file mode 100644
index 0000000..df86ec6
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/EncoderDataInternal.h
@@ -0,0 +1,109 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/EncoderData.h"
+#include "MockData/NotifyListenerVector.h"
+
+namespace hal {
+class EncoderData {
+ public:
+  int32_t RegisterInitializedCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelInitializedCallback(int32_t uid);
+  void InvokeInitializedCallback(HAL_Value value);
+  HAL_Bool GetInitialized();
+  void SetInitialized(HAL_Bool initialized);
+
+  int32_t RegisterCountCallback(HAL_NotifyCallback callback, void* param,
+                                HAL_Bool initialNotify);
+  void CancelCountCallback(int32_t uid);
+  void InvokeCountCallback(HAL_Value value);
+  int32_t GetCount();
+  void SetCount(int32_t count);
+
+  int32_t RegisterPeriodCallback(HAL_NotifyCallback callback, void* param,
+                                 HAL_Bool initialNotify);
+  void CancelPeriodCallback(int32_t uid);
+  void InvokePeriodCallback(HAL_Value value);
+  double GetPeriod();
+  void SetPeriod(double period);
+
+  int32_t RegisterResetCallback(HAL_NotifyCallback callback, void* param,
+                                HAL_Bool initialNotify);
+  void CancelResetCallback(int32_t uid);
+  void InvokeResetCallback(HAL_Value value);
+  HAL_Bool GetReset();
+  void SetReset(HAL_Bool reset);
+
+  int32_t RegisterMaxPeriodCallback(HAL_NotifyCallback callback, void* param,
+                                    HAL_Bool initialNotify);
+  void CancelMaxPeriodCallback(int32_t uid);
+  void InvokeMaxPeriodCallback(HAL_Value value);
+  double GetMaxPeriod();
+  void SetMaxPeriod(double maxPeriod);
+
+  int32_t RegisterDirectionCallback(HAL_NotifyCallback callback, void* param,
+                                    HAL_Bool initialNotify);
+  void CancelDirectionCallback(int32_t uid);
+  void InvokeDirectionCallback(HAL_Value value);
+  HAL_Bool GetDirection();
+  void SetDirection(HAL_Bool direction);
+
+  int32_t RegisterReverseDirectionCallback(HAL_NotifyCallback callback,
+                                           void* param, HAL_Bool initialNotify);
+  void CancelReverseDirectionCallback(int32_t uid);
+  void InvokeReverseDirectionCallback(HAL_Value value);
+  HAL_Bool GetReverseDirection();
+  void SetReverseDirection(HAL_Bool reverseDirection);
+
+  int32_t RegisterSamplesToAverageCallback(HAL_NotifyCallback callback,
+                                           void* param, HAL_Bool initialNotify);
+  void CancelSamplesToAverageCallback(int32_t uid);
+  void InvokeSamplesToAverageCallback(HAL_Value value);
+  int32_t GetSamplesToAverage();
+  void SetSamplesToAverage(int32_t samplesToAverage);
+
+  int32_t RegisterDistancePerPulseCallback(HAL_NotifyCallback callback,
+                                           void* param, HAL_Bool initialNotify);
+  void CancelDistancePerPulseCallback(int32_t uid);
+  void InvokeDistancePerPulseCallback(HAL_Value value);
+  double GetDistancePerPulse();
+  void SetDistancePerPulse(double distancePerPulse);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_initialized{false};
+  std::shared_ptr<NotifyListenerVector> m_initializedCallbacks = nullptr;
+  std::atomic<int32_t> m_count{0};
+  std::shared_ptr<NotifyListenerVector> m_countCallbacks = nullptr;
+  std::atomic<double> m_period{std::numeric_limits<double>::max()};
+  std::shared_ptr<NotifyListenerVector> m_periodCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_reset{false};
+  std::shared_ptr<NotifyListenerVector> m_resetCallbacks = nullptr;
+  std::atomic<double> m_maxPeriod{0};
+  std::shared_ptr<NotifyListenerVector> m_maxPeriodCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_direction{false};
+  std::shared_ptr<NotifyListenerVector> m_directionCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_reverseDirection{false};
+  std::shared_ptr<NotifyListenerVector> m_reverseDirectionCallbacks = nullptr;
+  std::atomic<int32_t> m_samplesToAverage{0};
+  std::shared_ptr<NotifyListenerVector> m_samplesToAverageCallbacks = nullptr;
+  std::atomic<double> m_distancePerPulse{0};
+  std::shared_ptr<NotifyListenerVector> m_distancePerPulseCallbacks = nullptr;
+};
+extern EncoderData* SimEncoderData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/HALValueInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/HALValueInternal.h
new file mode 100644
index 0000000..05d59a1
--- /dev/null
+++ b/third_party/allwpilib_2018/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/llvm/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(llvm::StringRef in, HALString* out);
+inline llvm::StringRef ConvertFromC(const HALString& str) {
+  return llvm::StringRef(str.str, str.len);
+}
+
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/I2CData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/I2CData.cpp
new file mode 100644
index 0000000..b129ff9
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/I2CData.cpp
@@ -0,0 +1,161 @@
+/*----------------------------------------------------------------------------*/
+/* 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"
+#include "MockData/NotifyCallbackHelpers.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() {
+  m_initialized = false;
+  m_initializedCallbacks = nullptr;
+  m_readCallbacks = nullptr;
+}
+
+I2CData::I2CData() {}
+I2CData::~I2CData() {}
+
+///////////////////////////////////////////
+// Initialize
+///////////////////////////////////////////
+int32_t I2CData::RegisterInitializedCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedCallbacks = RegisterCallback(
+        m_initializedCallbacks, "Initialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitialized());
+    callback("Initialized", param, &value);
+  }
+  return newUid;
+}
+
+void I2CData::CancelInitializedCallback(int32_t uid) {
+  m_initializedCallbacks = CancelCallback(m_initializedCallbacks, uid);
+}
+
+void I2CData::InvokeInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_initializedCallbacks, "Initialized", &value);
+}
+
+HAL_Bool I2CData::GetInitialized() { return m_initialized; }
+
+void I2CData::SetInitialized(HAL_Bool initialized) {
+  HAL_Bool oldValue = m_initialized.exchange(initialized);
+  if (oldValue != initialized) {
+    InvokeInitializedCallback(MakeBoolean(initialized));
+  }
+}
+
+int32_t I2CData::RegisterReadCallback(HAL_BufferCallback callback,
+                                      void* param) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_readCallbacks =
+        RegisterCallback(m_readCallbacks, "Read", callback, param, &newUid);
+  }
+  return newUid;
+}
+
+void I2CData::CancelReadCallback(int32_t uid) {
+  m_readCallbacks = CancelCallback(m_readCallbacks, uid);
+}
+
+int32_t I2CData::RegisterWriteCallback(HAL_ConstBufferCallback callback,
+                                       void* param) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_writeCallbacks =
+        RegisterCallback(m_writeCallbacks, "Write", callback, param, &newUid);
+  }
+  return newUid;
+}
+
+void I2CData::CancelWriteCallback(int32_t uid) {
+  m_writeCallbacks = CancelCallback(m_writeCallbacks, uid);
+}
+
+void I2CData::Write(int32_t deviceAddress, const uint8_t* dataToSend,
+                    int32_t sendSize) {
+  std::lock_guard<wpi::mutex> lock(m_dataMutex);
+  InvokeCallback(m_writeCallbacks, "Write", const_cast<uint8_t*>(dataToSend),
+                 sendSize);
+}
+void I2CData::Read(int32_t deviceAddress, uint8_t* buffer, int32_t count) {
+  std::lock_guard<wpi::mutex> lock(m_dataMutex);
+  InvokeCallback(m_readCallbacks, "Read", buffer, count);
+}
+
+extern "C" {
+void HALSIM_ResetI2CData(int32_t index) { SimI2CData[index].ResetData(); }
+
+int32_t HALSIM_RegisterI2CInitializedCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimI2CData[index].RegisterInitializedCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelI2CInitializedCallback(int32_t index, int32_t uid) {
+  SimI2CData[index].CancelInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetI2CInitialized(int32_t index) {
+  return SimI2CData[index].GetInitialized();
+}
+
+void HALSIM_SetI2CInitialized(int32_t index, HAL_Bool initialized) {
+  SimI2CData[index].SetInitialized(initialized);
+}
+
+int32_t HALSIM_RegisterI2CReadCallback(int32_t index,
+                                       HAL_BufferCallback callback,
+                                       void* param) {
+  return SimI2CData[index].RegisterReadCallback(callback, param);
+}
+void HALSIM_CancelI2CReadCallback(int32_t index, int32_t uid) {
+  SimI2CData[index].CancelReadCallback(uid);
+}
+
+int32_t HALSIM_RegisterI2CWriteCallback(int32_t index,
+                                        HAL_ConstBufferCallback callback,
+                                        void* param) {
+  return SimI2CData[index].RegisterWriteCallback(callback, param);
+}
+void HALSIM_CancelI2CWriteCallback(int32_t index, int32_t uid) {
+  SimI2CData[index].CancelWriteCallback(uid);
+}
+
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/I2CDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/I2CDataInternal.h
new file mode 100644
index 0000000..3b53b25
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/I2CDataInternal.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>
+#include <limits>
+#include <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/I2CData.h"
+#include "MockData/NotifyListenerVector.h"
+
+namespace hal {
+class I2CData {
+ public:
+  I2CData();
+  ~I2CData();
+
+  int32_t RegisterInitializedCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelInitializedCallback(int32_t uid);
+  void InvokeInitializedCallback(HAL_Value value);
+  HAL_Bool GetInitialized();
+  void SetInitialized(HAL_Bool initialized);
+
+  int32_t RegisterReadCallback(HAL_BufferCallback callback, void* param);
+  void CancelReadCallback(int32_t uid);
+
+  int32_t RegisterWriteCallback(HAL_ConstBufferCallback callback, void* param);
+  void CancelWriteCallback(int32_t uid);
+
+  void Write(int32_t deviceAddress, const uint8_t* dataToSend,
+             int32_t sendSize);
+  void Read(int32_t deviceAddress, uint8_t* buffer, int32_t count);
+
+  void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  wpi::mutex m_dataMutex;
+  std::atomic<HAL_Bool> m_initialized{false};
+  std::shared_ptr<NotifyListenerVector> m_initializedCallbacks = nullptr;
+  std::shared_ptr<BufferListenerVector> m_readCallbacks = nullptr;
+  std::shared_ptr<ConstBufferListenerVector> m_writeCallbacks = nullptr;
+};
+extern I2CData* SimI2CData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/NotifyCallbackHelpers.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/NotifyCallbackHelpers.cpp
new file mode 100644
index 0000000..2a2b8b8
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/NotifyCallbackHelpers.cpp
@@ -0,0 +1,89 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "MockData/NotifyCallbackHelpers.h"
+
+using namespace hal;
+
+std::shared_ptr<NotifyListenerVector> RegisterCallback(
+    std::shared_ptr<NotifyListenerVector> currentVector, const char* name,
+    HAL_NotifyCallback callback, void* param, int32_t* newUid) {
+  return RegisterCallbackImpl<NotifyListenerVector, HAL_NotifyCallback>(
+      currentVector, name, callback, param, newUid);
+}
+
+std::shared_ptr<NotifyListenerVector> CancelCallback(
+    std::shared_ptr<NotifyListenerVector> currentVector, int32_t uid) {
+  return CancelCallbackImpl<NotifyListenerVector, HAL_NotifyCallback>(
+      currentVector, uid);
+}
+
+void InvokeCallback(std::shared_ptr<NotifyListenerVector> currentVector,
+                    const char* name, const HAL_Value* value) {
+  // Return if no callbacks are assigned
+  if (currentVector == nullptr) return;
+  // Get a copy of the shared_ptr, then iterate and callback listeners
+  auto newCallbacks = currentVector;
+  for (size_t i = 0; i < newCallbacks->size(); ++i) {
+    if (!(*newCallbacks)[i]) continue;  // removed
+    auto listener = (*newCallbacks)[i];
+    listener.callback(name, listener.param, value);
+  }
+}
+
+std::shared_ptr<BufferListenerVector> RegisterCallback(
+    std::shared_ptr<BufferListenerVector> currentVector, const char* name,
+    HAL_BufferCallback callback, void* param, int32_t* newUid) {
+  return RegisterCallbackImpl<BufferListenerVector, HAL_BufferCallback>(
+      currentVector, name, callback, param, newUid);
+}
+
+std::shared_ptr<BufferListenerVector> CancelCallback(
+    std::shared_ptr<BufferListenerVector> currentVector, int32_t uid) {
+  return CancelCallbackImpl<BufferListenerVector, HAL_BufferCallback>(
+      currentVector, uid);
+}
+
+void InvokeCallback(std::shared_ptr<BufferListenerVector> currentVector,
+                    const char* name, uint8_t* buffer, int32_t count) {
+  // Return if no callbacks are assigned
+  if (currentVector == nullptr) return;
+  // Get a copy of the shared_ptr, then iterate and callback listeners
+  auto newCallbacks = currentVector;
+  for (size_t i = 0; i < newCallbacks->size(); ++i) {
+    if (!(*newCallbacks)[i]) continue;  // removed
+    auto listener = (*newCallbacks)[i];
+    listener.callback(name, listener.param, buffer, count);
+  }
+}
+
+std::shared_ptr<ConstBufferListenerVector> RegisterCallback(
+    std::shared_ptr<ConstBufferListenerVector> currentVector, const char* name,
+    HAL_ConstBufferCallback callback, void* param, int32_t* newUid) {
+  return RegisterCallbackImpl<ConstBufferListenerVector,
+                              HAL_ConstBufferCallback>(currentVector, name,
+                                                       callback, param, newUid);
+}
+
+std::shared_ptr<ConstBufferListenerVector> CancelCallback(
+    std::shared_ptr<ConstBufferListenerVector> currentVector, int32_t uid) {
+  return CancelCallbackImpl<ConstBufferListenerVector, HAL_ConstBufferCallback>(
+      currentVector, uid);
+}
+
+void InvokeCallback(std::shared_ptr<ConstBufferListenerVector> currentVector,
+                    const char* name, const uint8_t* buffer, int32_t count) {
+  // Return if no callbacks are assigned
+  if (currentVector == nullptr) return;
+  // Get a copy of the shared_ptr, then iterate and callback listeners
+  auto newCallbacks = currentVector;
+  for (size_t i = 0; i < newCallbacks->size(); ++i) {
+    if (!(*newCallbacks)[i]) continue;  // removed
+    auto listener = (*newCallbacks)[i];
+    listener.callback(name, listener.param, buffer, count);
+  }
+}
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PCMData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PCMData.cpp
new file mode 100644
index 0000000..b0848df
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PCMData.cpp
@@ -0,0 +1,486 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "MockData/NotifyCallbackHelpers.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++) {
+    m_solenoidInitialized[i] = false;
+    m_solenoidInitializedCallbacks[i] = nullptr;
+    m_solenoidOutput[i] = false;
+    m_solenoidOutputCallbacks[i] = nullptr;
+  }
+  m_compressorInitialized = false;
+  m_compressorInitializedCallbacks = nullptr;
+  m_compressorOn = false;
+  m_compressorOnCallbacks = nullptr;
+  m_closedLoopEnabled = true;
+  m_closedLoopEnabledCallbacks = nullptr;
+  m_pressureSwitch = false;
+  m_pressureSwitchCallbacks = nullptr;
+  m_compressorCurrent = 0.0;
+  m_compressorCurrentCallbacks = nullptr;
+}
+
+int32_t PCMData::RegisterSolenoidInitializedCallback(
+    int32_t channel, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_solenoidInitializedCallbacks[channel] =
+        RegisterCallback(m_solenoidInitializedCallbacks[channel],
+                         "SolenoidInitialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetSolenoidInitialized(channel));
+    callback("SolenoidInitialized", param, &value);
+  }
+  return newUid;
+}
+
+void PCMData::CancelSolenoidInitializedCallback(int32_t channel, int32_t uid) {
+  m_solenoidInitializedCallbacks[channel] =
+      CancelCallback(m_solenoidInitializedCallbacks[channel], uid);
+}
+
+void PCMData::InvokeSolenoidInitializedCallback(int32_t channel,
+                                                HAL_Value value) {
+  InvokeCallback(m_solenoidInitializedCallbacks[channel], "SolenoidInitialized",
+                 &value);
+}
+
+HAL_Bool PCMData::GetSolenoidInitialized(int32_t channel) {
+  return m_solenoidInitialized[channel];
+}
+
+void PCMData::SetSolenoidInitialized(int32_t channel,
+                                     HAL_Bool solenoidInitialized) {
+  HAL_Bool oldValue =
+      m_solenoidInitialized[channel].exchange(solenoidInitialized);
+  if (oldValue != solenoidInitialized) {
+    InvokeSolenoidInitializedCallback(channel,
+                                      MakeBoolean(solenoidInitialized));
+  }
+}
+
+int32_t PCMData::RegisterSolenoidOutputCallback(int32_t channel,
+                                                HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_solenoidOutputCallbacks[channel] =
+        RegisterCallback(m_solenoidOutputCallbacks[channel], "SolenoidOutput",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetSolenoidOutput(channel));
+    callback("SolenoidOutput", param, &value);
+  }
+  return newUid;
+}
+
+void PCMData::CancelSolenoidOutputCallback(int32_t channel, int32_t uid) {
+  m_solenoidOutputCallbacks[channel] =
+      CancelCallback(m_solenoidOutputCallbacks[channel], uid);
+}
+
+void PCMData::InvokeSolenoidOutputCallback(int32_t channel, HAL_Value value) {
+  InvokeCallback(m_solenoidOutputCallbacks[channel], "SolenoidOutput", &value);
+}
+
+HAL_Bool PCMData::GetSolenoidOutput(int32_t channel) {
+  return m_solenoidOutput[channel];
+}
+
+void PCMData::SetSolenoidOutput(int32_t channel, HAL_Bool solenoidOutput) {
+  HAL_Bool oldValue = m_solenoidOutput[channel].exchange(solenoidOutput);
+  if (oldValue != solenoidOutput) {
+    InvokeSolenoidOutputCallback(channel, MakeBoolean(solenoidOutput));
+  }
+}
+
+int32_t PCMData::RegisterCompressorInitializedCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_compressorInitializedCallbacks =
+        RegisterCallback(m_compressorInitializedCallbacks,
+                         "CompressorInitialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetCompressorInitialized());
+    callback("CompressorInitialized", param, &value);
+  }
+  return newUid;
+}
+
+void PCMData::CancelCompressorInitializedCallback(int32_t uid) {
+  m_compressorInitializedCallbacks =
+      CancelCallback(m_compressorInitializedCallbacks, uid);
+}
+
+void PCMData::InvokeCompressorInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_compressorInitializedCallbacks, "CompressorInitialized",
+                 &value);
+}
+
+HAL_Bool PCMData::GetCompressorInitialized() { return m_compressorInitialized; }
+
+void PCMData::SetCompressorInitialized(HAL_Bool compressorInitialized) {
+  HAL_Bool oldValue = m_compressorInitialized.exchange(compressorInitialized);
+  if (oldValue != compressorInitialized) {
+    InvokeCompressorInitializedCallback(MakeBoolean(compressorInitialized));
+  }
+}
+
+int32_t PCMData::RegisterCompressorOnCallback(HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_compressorOnCallbacks = RegisterCallback(
+        m_compressorOnCallbacks, "CompressorOn", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetCompressorOn());
+    callback("CompressorOn", param, &value);
+  }
+  return newUid;
+}
+
+void PCMData::CancelCompressorOnCallback(int32_t uid) {
+  m_compressorOnCallbacks = CancelCallback(m_compressorOnCallbacks, uid);
+}
+
+void PCMData::InvokeCompressorOnCallback(HAL_Value value) {
+  InvokeCallback(m_compressorOnCallbacks, "CompressorOn", &value);
+}
+
+HAL_Bool PCMData::GetCompressorOn() { return m_compressorOn; }
+
+void PCMData::SetCompressorOn(HAL_Bool compressorOn) {
+  HAL_Bool oldValue = m_compressorOn.exchange(compressorOn);
+  if (oldValue != compressorOn) {
+    InvokeCompressorOnCallback(MakeBoolean(compressorOn));
+  }
+}
+
+int32_t PCMData::RegisterClosedLoopEnabledCallback(HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_closedLoopEnabledCallbacks =
+        RegisterCallback(m_closedLoopEnabledCallbacks, "ClosedLoopEnabled",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetClosedLoopEnabled());
+    callback("ClosedLoopEnabled", param, &value);
+  }
+  return newUid;
+}
+
+void PCMData::CancelClosedLoopEnabledCallback(int32_t uid) {
+  m_closedLoopEnabledCallbacks =
+      CancelCallback(m_closedLoopEnabledCallbacks, uid);
+}
+
+void PCMData::InvokeClosedLoopEnabledCallback(HAL_Value value) {
+  InvokeCallback(m_closedLoopEnabledCallbacks, "ClosedLoopEnabled", &value);
+}
+
+HAL_Bool PCMData::GetClosedLoopEnabled() { return m_closedLoopEnabled; }
+
+void PCMData::SetClosedLoopEnabled(HAL_Bool closedLoopEnabled) {
+  HAL_Bool oldValue = m_closedLoopEnabled.exchange(closedLoopEnabled);
+  if (oldValue != closedLoopEnabled) {
+    InvokeClosedLoopEnabledCallback(MakeBoolean(closedLoopEnabled));
+  }
+}
+
+int32_t PCMData::RegisterPressureSwitchCallback(HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_pressureSwitchCallbacks = RegisterCallback(
+        m_pressureSwitchCallbacks, "PressureSwitch", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetPressureSwitch());
+    callback("PressureSwitch", param, &value);
+  }
+  return newUid;
+}
+
+void PCMData::CancelPressureSwitchCallback(int32_t uid) {
+  m_pressureSwitchCallbacks = CancelCallback(m_pressureSwitchCallbacks, uid);
+}
+
+void PCMData::InvokePressureSwitchCallback(HAL_Value value) {
+  InvokeCallback(m_pressureSwitchCallbacks, "PressureSwitch", &value);
+}
+
+HAL_Bool PCMData::GetPressureSwitch() { return m_pressureSwitch; }
+
+void PCMData::SetPressureSwitch(HAL_Bool pressureSwitch) {
+  HAL_Bool oldValue = m_pressureSwitch.exchange(pressureSwitch);
+  if (oldValue != pressureSwitch) {
+    InvokePressureSwitchCallback(MakeBoolean(pressureSwitch));
+  }
+}
+
+int32_t PCMData::RegisterCompressorCurrentCallback(HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_compressorCurrentCallbacks =
+        RegisterCallback(m_compressorCurrentCallbacks, "CompressorCurrent",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetCompressorCurrent());
+    callback("CompressorCurrent", param, &value);
+  }
+  return newUid;
+}
+
+void PCMData::CancelCompressorCurrentCallback(int32_t uid) {
+  m_compressorCurrentCallbacks =
+      CancelCallback(m_compressorCurrentCallbacks, uid);
+}
+
+void PCMData::InvokeCompressorCurrentCallback(HAL_Value value) {
+  InvokeCallback(m_compressorCurrentCallbacks, "CompressorCurrent", &value);
+}
+
+double PCMData::GetCompressorCurrent() { return m_compressorCurrent; }
+
+void PCMData::SetCompressorCurrent(double compressorCurrent) {
+  double oldValue = m_compressorCurrent.exchange(compressorCurrent);
+  if (oldValue != compressorCurrent) {
+    InvokeCompressorCurrentCallback(MakeDouble(compressorCurrent));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetPCMData(int32_t index) { SimPCMData[index].ResetData(); }
+
+int32_t HALSIM_RegisterPCMSolenoidInitializedCallback(
+    int32_t index, int32_t channel, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimPCMData[index].RegisterSolenoidInitializedCallback(
+      channel, callback, param, initialNotify);
+}
+
+void HALSIM_CancelPCMSolenoidInitializedCallback(int32_t index, int32_t channel,
+                                                 int32_t uid) {
+  SimPCMData[index].CancelSolenoidInitializedCallback(channel, uid);
+}
+
+HAL_Bool HALSIM_GetPCMSolenoidInitialized(int32_t index, int32_t channel) {
+  return SimPCMData[index].GetSolenoidInitialized(channel);
+}
+
+void HALSIM_SetPCMSolenoidInitialized(int32_t index, int32_t channel,
+                                      HAL_Bool solenoidInitialized) {
+  SimPCMData[index].SetSolenoidInitialized(channel, solenoidInitialized);
+}
+
+int32_t HALSIM_RegisterPCMSolenoidOutputCallback(int32_t index, int32_t channel,
+                                                 HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  return SimPCMData[index].RegisterSolenoidOutputCallback(channel, callback,
+                                                          param, initialNotify);
+}
+
+void HALSIM_CancelPCMSolenoidOutputCallback(int32_t index, int32_t channel,
+                                            int32_t uid) {
+  SimPCMData[index].CancelSolenoidOutputCallback(channel, uid);
+}
+
+HAL_Bool HALSIM_GetPCMSolenoidOutput(int32_t index, int32_t channel) {
+  return SimPCMData[index].GetSolenoidOutput(channel);
+}
+
+void HALSIM_SetPCMSolenoidOutput(int32_t index, int32_t channel,
+                                 HAL_Bool solenoidOutput) {
+  SimPCMData[index].SetSolenoidOutput(channel, solenoidOutput);
+}
+
+int32_t HALSIM_RegisterPCMCompressorInitializedCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimPCMData[index].RegisterCompressorInitializedCallback(
+      callback, param, initialNotify);
+}
+
+void HALSIM_CancelPCMCompressorInitializedCallback(int32_t index, int32_t uid) {
+  SimPCMData[index].CancelCompressorInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetPCMCompressorInitialized(int32_t index) {
+  return SimPCMData[index].GetCompressorInitialized();
+}
+
+void HALSIM_SetPCMCompressorInitialized(int32_t index,
+                                        HAL_Bool compressorInitialized) {
+  SimPCMData[index].SetCompressorInitialized(compressorInitialized);
+}
+
+int32_t HALSIM_RegisterPCMCompressorOnCallback(int32_t index,
+                                               HAL_NotifyCallback callback,
+                                               void* param,
+                                               HAL_Bool initialNotify) {
+  return SimPCMData[index].RegisterCompressorOnCallback(callback, param,
+                                                        initialNotify);
+}
+
+void HALSIM_CancelPCMCompressorOnCallback(int32_t index, int32_t uid) {
+  SimPCMData[index].CancelCompressorOnCallback(uid);
+}
+
+HAL_Bool HALSIM_GetPCMCompressorOn(int32_t index) {
+  return SimPCMData[index].GetCompressorOn();
+}
+
+void HALSIM_SetPCMCompressorOn(int32_t index, HAL_Bool compressorOn) {
+  SimPCMData[index].SetCompressorOn(compressorOn);
+}
+
+int32_t HALSIM_RegisterPCMClosedLoopEnabledCallback(int32_t index,
+                                                    HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  return SimPCMData[index].RegisterClosedLoopEnabledCallback(callback, param,
+                                                             initialNotify);
+}
+
+void HALSIM_CancelPCMClosedLoopEnabledCallback(int32_t index, int32_t uid) {
+  SimPCMData[index].CancelClosedLoopEnabledCallback(uid);
+}
+
+HAL_Bool HALSIM_GetPCMClosedLoopEnabled(int32_t index) {
+  return SimPCMData[index].GetClosedLoopEnabled();
+}
+
+void HALSIM_SetPCMClosedLoopEnabled(int32_t index, HAL_Bool closedLoopEnabled) {
+  SimPCMData[index].SetClosedLoopEnabled(closedLoopEnabled);
+}
+
+int32_t HALSIM_RegisterPCMPressureSwitchCallback(int32_t index,
+                                                 HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  return SimPCMData[index].RegisterPressureSwitchCallback(callback, param,
+                                                          initialNotify);
+}
+
+void HALSIM_CancelPCMPressureSwitchCallback(int32_t index, int32_t uid) {
+  SimPCMData[index].CancelPressureSwitchCallback(uid);
+}
+
+HAL_Bool HALSIM_GetPCMPressureSwitch(int32_t index) {
+  return SimPCMData[index].GetPressureSwitch();
+}
+
+void HALSIM_SetPCMPressureSwitch(int32_t index, HAL_Bool pressureSwitch) {
+  SimPCMData[index].SetPressureSwitch(pressureSwitch);
+}
+
+int32_t HALSIM_RegisterPCMCompressorCurrentCallback(int32_t index,
+                                                    HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  return SimPCMData[index].RegisterCompressorCurrentCallback(callback, param,
+                                                             initialNotify);
+}
+
+void HALSIM_CancelPCMCompressorCurrentCallback(int32_t index, int32_t uid) {
+  SimPCMData[index].CancelCompressorCurrentCallback(uid);
+}
+
+double HALSIM_GetPCMCompressorCurrent(int32_t index) {
+  return SimPCMData[index].GetCompressorCurrent();
+}
+
+void HALSIM_SetPCMCompressorCurrent(int32_t index, double compressorCurrent) {
+  SimPCMData[index].SetCompressorCurrent(compressorCurrent);
+}
+
+void HALSIM_RegisterPCMAllNonSolenoidCallbacks(int32_t index,
+                                               HAL_NotifyCallback callback,
+                                               void* param,
+                                               HAL_Bool initialNotify) {
+  SimPCMData[index].RegisterCompressorInitializedCallback(callback, param,
+                                                          initialNotify);
+  SimPCMData[index].RegisterCompressorOnCallback(callback, param,
+                                                 initialNotify);
+  SimPCMData[index].RegisterClosedLoopEnabledCallback(callback, param,
+                                                      initialNotify);
+  SimPCMData[index].RegisterPressureSwitchCallback(callback, param,
+                                                   initialNotify);
+  SimPCMData[index].RegisterCompressorCurrentCallback(callback, param,
+                                                      initialNotify);
+}
+
+void HALSIM_RegisterPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
+                                            HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify) {
+  SimPCMData[index].RegisterSolenoidInitializedCallback(channel, callback,
+                                                        param, initialNotify);
+  SimPCMData[index].RegisterSolenoidOutputCallback(channel, callback, param,
+                                                   initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PCMDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PCMDataInternal.h
new file mode 100644
index 0000000..69b83cf
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PCMDataInternal.h
@@ -0,0 +1,100 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+
+#include <support/mutex.h>
+
+#include "../PortsInternal.h"
+#include "MockData/NotifyListenerVector.h"
+#include "MockData/PCMData.h"
+
+namespace hal {
+class PCMData {
+ public:
+  int32_t RegisterSolenoidInitializedCallback(int32_t channel,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify);
+  void CancelSolenoidInitializedCallback(int32_t channel, int32_t uid);
+  void InvokeSolenoidInitializedCallback(int32_t channel, HAL_Value value);
+  HAL_Bool GetSolenoidInitialized(int32_t channel);
+  void SetSolenoidInitialized(int32_t channel, HAL_Bool solenoidInitialized);
+
+  int32_t RegisterSolenoidOutputCallback(int32_t channel,
+                                         HAL_NotifyCallback callback,
+                                         void* param, HAL_Bool initialNotify);
+  void CancelSolenoidOutputCallback(int32_t channel, int32_t uid);
+  void InvokeSolenoidOutputCallback(int32_t channel, HAL_Value value);
+  HAL_Bool GetSolenoidOutput(int32_t channel);
+  void SetSolenoidOutput(int32_t channel, HAL_Bool solenoidOutput);
+
+  int32_t RegisterCompressorInitializedCallback(HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify);
+  void CancelCompressorInitializedCallback(int32_t uid);
+  void InvokeCompressorInitializedCallback(HAL_Value value);
+  HAL_Bool GetCompressorInitialized();
+  void SetCompressorInitialized(HAL_Bool compressorInitialized);
+
+  int32_t RegisterCompressorOnCallback(HAL_NotifyCallback callback, void* param,
+                                       HAL_Bool initialNotify);
+  void CancelCompressorOnCallback(int32_t uid);
+  void InvokeCompressorOnCallback(HAL_Value value);
+  HAL_Bool GetCompressorOn();
+  void SetCompressorOn(HAL_Bool compressorOn);
+
+  int32_t RegisterClosedLoopEnabledCallback(HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify);
+  void CancelClosedLoopEnabledCallback(int32_t uid);
+  void InvokeClosedLoopEnabledCallback(HAL_Value value);
+  HAL_Bool GetClosedLoopEnabled();
+  void SetClosedLoopEnabled(HAL_Bool closedLoopEnabled);
+
+  int32_t RegisterPressureSwitchCallback(HAL_NotifyCallback callback,
+                                         void* param, HAL_Bool initialNotify);
+  void CancelPressureSwitchCallback(int32_t uid);
+  void InvokePressureSwitchCallback(HAL_Value value);
+  HAL_Bool GetPressureSwitch();
+  void SetPressureSwitch(HAL_Bool pressureSwitch);
+
+  int32_t RegisterCompressorCurrentCallback(HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify);
+  void CancelCompressorCurrentCallback(int32_t uid);
+  void InvokeCompressorCurrentCallback(HAL_Value value);
+  double GetCompressorCurrent();
+  void SetCompressorCurrent(double compressorCurrent);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_solenoidInitialized[kNumSolenoidChannels];
+  std::shared_ptr<NotifyListenerVector>
+      m_solenoidInitializedCallbacks[kNumSolenoidChannels];
+  std::atomic<HAL_Bool> m_solenoidOutput[kNumSolenoidChannels];
+  std::shared_ptr<NotifyListenerVector>
+      m_solenoidOutputCallbacks[kNumSolenoidChannels];
+  std::atomic<HAL_Bool> m_compressorInitialized{false};
+  std::shared_ptr<NotifyListenerVector> m_compressorInitializedCallbacks =
+      nullptr;
+  std::atomic<HAL_Bool> m_compressorOn{false};
+  std::shared_ptr<NotifyListenerVector> m_compressorOnCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_closedLoopEnabled{true};
+  std::shared_ptr<NotifyListenerVector> m_closedLoopEnabledCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_pressureSwitch{false};
+  std::shared_ptr<NotifyListenerVector> m_pressureSwitchCallbacks = nullptr;
+  std::atomic<double> m_compressorCurrent{0.0};
+  std::shared_ptr<NotifyListenerVector> m_compressorCurrentCallbacks = nullptr;
+};
+extern PCMData* SimPCMData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PDPData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PDPData.cpp
new file mode 100644
index 0000000..25cbec9
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PDPData.cpp
@@ -0,0 +1,271 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "MockData/NotifyCallbackHelpers.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() {
+  m_initialized = false;
+  m_initializedCallbacks = nullptr;
+  m_temperature = 0.0;
+  m_temperatureCallbacks = nullptr;
+  m_voltage = 12.0;
+  m_voltageCallbacks = nullptr;
+  for (int i = 0; i < kNumPDPChannels; i++) {
+    m_current[i] = 0;
+    m_currentCallbacks[i] = nullptr;
+  }
+}
+
+int32_t PDPData::RegisterInitializedCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedCallbacks = RegisterCallback(
+        m_initializedCallbacks, "Initialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitialized());
+    callback("Initialized", param, &value);
+  }
+  return newUid;
+}
+
+void PDPData::CancelInitializedCallback(int32_t uid) {
+  m_initializedCallbacks = CancelCallback(m_initializedCallbacks, uid);
+}
+
+void PDPData::InvokeInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_initializedCallbacks, "Initialized", &value);
+}
+
+HAL_Bool PDPData::GetInitialized() { return m_initialized; }
+
+void PDPData::SetInitialized(HAL_Bool initialized) {
+  HAL_Bool oldValue = m_initialized.exchange(initialized);
+  if (oldValue != initialized) {
+    InvokeInitializedCallback(MakeBoolean(initialized));
+  }
+}
+
+int32_t PDPData::RegisterTemperatureCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_temperatureCallbacks = RegisterCallback(
+        m_temperatureCallbacks, "Temperature", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetTemperature());
+    callback("Temperature", param, &value);
+  }
+  return newUid;
+}
+
+void PDPData::CancelTemperatureCallback(int32_t uid) {
+  m_temperatureCallbacks = CancelCallback(m_temperatureCallbacks, uid);
+}
+
+void PDPData::InvokeTemperatureCallback(HAL_Value value) {
+  InvokeCallback(m_temperatureCallbacks, "Temperature", &value);
+}
+
+double PDPData::GetTemperature() { return m_temperature; }
+
+void PDPData::SetTemperature(double temperature) {
+  double oldValue = m_temperature.exchange(temperature);
+  if (oldValue != temperature) {
+    InvokeTemperatureCallback(MakeDouble(temperature));
+  }
+}
+
+int32_t PDPData::RegisterVoltageCallback(HAL_NotifyCallback callback,
+                                         void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_voltageCallbacks = RegisterCallback(m_voltageCallbacks, "Voltage",
+                                          callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetVoltage());
+    callback("Voltage", param, &value);
+  }
+  return newUid;
+}
+
+void PDPData::CancelVoltageCallback(int32_t uid) {
+  m_voltageCallbacks = CancelCallback(m_voltageCallbacks, uid);
+}
+
+void PDPData::InvokeVoltageCallback(HAL_Value value) {
+  InvokeCallback(m_voltageCallbacks, "Voltage", &value);
+}
+
+double PDPData::GetVoltage() { return m_voltage; }
+
+void PDPData::SetVoltage(double voltage) {
+  double oldValue = m_voltage.exchange(voltage);
+  if (oldValue != voltage) {
+    InvokeVoltageCallback(MakeDouble(voltage));
+  }
+}
+
+int32_t PDPData::RegisterCurrentCallback(int32_t channel,
+                                         HAL_NotifyCallback callback,
+                                         void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_currentCallbacks[channel] = RegisterCallback(
+        m_currentCallbacks[channel], "Current", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetCurrent(channel));
+    callback("Current", param, &value);
+  }
+  return newUid;
+}
+
+void PDPData::CancelCurrentCallback(int32_t channel, int32_t uid) {
+  m_currentCallbacks[channel] =
+      CancelCallback(m_currentCallbacks[channel], uid);
+}
+
+void PDPData::InvokeCurrentCallback(int32_t channel, HAL_Value value) {
+  InvokeCallback(m_currentCallbacks[channel], "Current", &value);
+}
+
+double PDPData::GetCurrent(int32_t channel) { return m_current[channel]; }
+
+void PDPData::SetCurrent(int32_t channel, double current) {
+  double oldValue = m_current[channel].exchange(current);
+  if (oldValue != current) {
+    InvokeCurrentCallback(channel, MakeDouble(current));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetPDPData(int32_t index) { SimPDPData[index].ResetData(); }
+
+int32_t HALSIM_RegisterPDPInitializedCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimPDPData[index].RegisterInitializedCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelPDPInitializedCallback(int32_t index, int32_t uid) {
+  SimPDPData[index].CancelInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetPDPInitialized(int32_t index) {
+  return SimPDPData[index].GetInitialized();
+}
+
+void HALSIM_SetPDPInitialized(int32_t index, HAL_Bool initialized) {
+  SimPDPData[index].SetInitialized(initialized);
+}
+
+int32_t HALSIM_RegisterPDPTemperatureCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimPDPData[index].RegisterTemperatureCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelPDPTemperatureCallback(int32_t index, int32_t uid) {
+  SimPDPData[index].CancelTemperatureCallback(uid);
+}
+
+double HALSIM_GetPDPTemperature(int32_t index) {
+  return SimPDPData[index].GetTemperature();
+}
+
+void HALSIM_SetPDPTemperature(int32_t index, double temperature) {
+  SimPDPData[index].SetTemperature(temperature);
+}
+
+int32_t HALSIM_RegisterPDPVoltageCallback(int32_t index,
+                                          HAL_NotifyCallback callback,
+                                          void* param, HAL_Bool initialNotify) {
+  return SimPDPData[index].RegisterVoltageCallback(callback, param,
+                                                   initialNotify);
+}
+
+void HALSIM_CancelPDPVoltageCallback(int32_t index, int32_t uid) {
+  SimPDPData[index].CancelVoltageCallback(uid);
+}
+
+double HALSIM_GetPDPVoltage(int32_t index) {
+  return SimPDPData[index].GetVoltage();
+}
+
+void HALSIM_SetPDPVoltage(int32_t index, double voltage) {
+  SimPDPData[index].SetVoltage(voltage);
+}
+
+int32_t HALSIM_RegisterPDPCurrentCallback(int32_t index, int32_t channel,
+                                          HAL_NotifyCallback callback,
+                                          void* param, HAL_Bool initialNotify) {
+  return SimPDPData[index].RegisterCurrentCallback(channel, callback, param,
+                                                   initialNotify);
+}
+
+void HALSIM_CancelPDPCurrentCallback(int32_t index, int32_t channel,
+                                     int32_t uid) {
+  SimPDPData[index].CancelCurrentCallback(channel, uid);
+}
+
+double HALSIM_GetPDPCurrent(int32_t index, int32_t channel) {
+  return SimPDPData[index].GetCurrent(channel);
+}
+
+void HALSIM_SetPDPCurrent(int32_t index, int32_t channel, double current) {
+  SimPDPData[index].SetCurrent(channel, current);
+}
+
+void HALSIM_RegisterPDPAllNonCurrentCallbacks(int32_t index, int32_t channel,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  SimPDPData[index].RegisterInitializedCallback(callback, param, initialNotify);
+  SimPDPData[index].RegisterTemperatureCallback(callback, param, initialNotify);
+  SimPDPData[index].RegisterVoltageCallback(callback, param, initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PDPDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PDPDataInternal.h
new file mode 100644
index 0000000..aaa8104
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PDPDataInternal.h
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <atomic>
+#include <memory>
+
+#include <support/mutex.h>
+
+#include "../PortsInternal.h"
+#include "MockData/NotifyListenerVector.h"
+#include "MockData/PDPData.h"
+
+namespace hal {
+class PDPData {
+ public:
+  int32_t RegisterInitializedCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelInitializedCallback(int32_t uid);
+  void InvokeInitializedCallback(HAL_Value value);
+  HAL_Bool GetInitialized();
+  void SetInitialized(HAL_Bool initialized);
+
+  int32_t RegisterTemperatureCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelTemperatureCallback(int32_t uid);
+  void InvokeTemperatureCallback(HAL_Value value);
+  double GetTemperature();
+  void SetTemperature(double temperature);
+
+  int32_t RegisterVoltageCallback(HAL_NotifyCallback callback, void* param,
+                                  HAL_Bool initialNotify);
+  void CancelVoltageCallback(int32_t uid);
+  void InvokeVoltageCallback(HAL_Value value);
+  double GetVoltage();
+  void SetVoltage(double voltage);
+
+  int32_t RegisterCurrentCallback(int32_t channel, HAL_NotifyCallback callback,
+                                  void* param, HAL_Bool initialNotify);
+  void CancelCurrentCallback(int32_t channel, int32_t uid);
+  void InvokeCurrentCallback(int32_t channel, HAL_Value value);
+  double GetCurrent(int32_t channel);
+  void SetCurrent(int32_t channel, double current);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_initialized{false};
+  std::shared_ptr<NotifyListenerVector> m_initializedCallbacks = nullptr;
+  std::atomic<double> m_temperature{0.0};
+  std::shared_ptr<NotifyListenerVector> m_temperatureCallbacks = nullptr;
+  std::atomic<double> m_voltage{12.0};
+  std::shared_ptr<NotifyListenerVector> m_voltageCallbacks = nullptr;
+  std::atomic<double> m_current[kNumPDPChannels];
+  std::shared_ptr<NotifyListenerVector> m_currentCallbacks[kNumPDPChannels];
+};
+extern PDPData* SimPDPData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PWMData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PWMData.cpp
new file mode 100644
index 0000000..681deaf
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PWMData.cpp
@@ -0,0 +1,383 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "MockData/NotifyCallbackHelpers.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() {
+  m_initialized = false;
+  m_initializedCallbacks = nullptr;
+  m_rawValue = 0;
+  m_rawValueCallbacks = nullptr;
+  m_speed = 0;
+  m_speedCallbacks = nullptr;
+  m_position = 0;
+  m_positionCallbacks = nullptr;
+  m_periodScale = 0;
+  m_periodScaleCallbacks = nullptr;
+  m_zeroLatch = false;
+  m_zeroLatchCallbacks = nullptr;
+}
+
+int32_t PWMData::RegisterInitializedCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedCallbacks = RegisterCallback(
+        m_initializedCallbacks, "Initialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitialized());
+    callback("Initialized", param, &value);
+  }
+  return newUid;
+}
+
+void PWMData::CancelInitializedCallback(int32_t uid) {
+  m_initializedCallbacks = CancelCallback(m_initializedCallbacks, uid);
+}
+
+void PWMData::InvokeInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_initializedCallbacks, "Initialized", &value);
+}
+
+HAL_Bool PWMData::GetInitialized() { return m_initialized; }
+
+void PWMData::SetInitialized(HAL_Bool initialized) {
+  HAL_Bool oldValue = m_initialized.exchange(initialized);
+  if (oldValue != initialized) {
+    InvokeInitializedCallback(MakeBoolean(initialized));
+  }
+}
+
+int32_t PWMData::RegisterRawValueCallback(HAL_NotifyCallback callback,
+                                          void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_rawValueCallbacks = RegisterCallback(m_rawValueCallbacks, "RawValue",
+                                           callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetRawValue());
+    callback("RawValue", param, &value);
+  }
+  return newUid;
+}
+
+void PWMData::CancelRawValueCallback(int32_t uid) {
+  m_rawValueCallbacks = CancelCallback(m_rawValueCallbacks, uid);
+}
+
+void PWMData::InvokeRawValueCallback(HAL_Value value) {
+  InvokeCallback(m_rawValueCallbacks, "RawValue", &value);
+}
+
+int32_t PWMData::GetRawValue() { return m_rawValue; }
+
+void PWMData::SetRawValue(int32_t rawValue) {
+  int32_t oldValue = m_rawValue.exchange(rawValue);
+  if (oldValue != rawValue) {
+    InvokeRawValueCallback(MakeInt(rawValue));
+  }
+}
+
+int32_t PWMData::RegisterSpeedCallback(HAL_NotifyCallback callback, void* param,
+                                       HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_speedCallbacks =
+        RegisterCallback(m_speedCallbacks, "Speed", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetSpeed());
+    callback("Speed", param, &value);
+  }
+  return newUid;
+}
+
+void PWMData::CancelSpeedCallback(int32_t uid) {
+  m_speedCallbacks = CancelCallback(m_speedCallbacks, uid);
+}
+
+void PWMData::InvokeSpeedCallback(HAL_Value value) {
+  InvokeCallback(m_speedCallbacks, "Speed", &value);
+}
+
+double PWMData::GetSpeed() { return m_speed; }
+
+void PWMData::SetSpeed(double speed) {
+  double oldValue = m_speed.exchange(speed);
+  if (oldValue != speed) {
+    InvokeSpeedCallback(MakeDouble(speed));
+  }
+}
+
+int32_t PWMData::RegisterPositionCallback(HAL_NotifyCallback callback,
+                                          void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_positionCallbacks = RegisterCallback(m_positionCallbacks, "Position",
+                                           callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetPosition());
+    callback("Position", param, &value);
+  }
+  return newUid;
+}
+
+void PWMData::CancelPositionCallback(int32_t uid) {
+  m_positionCallbacks = CancelCallback(m_positionCallbacks, uid);
+}
+
+void PWMData::InvokePositionCallback(HAL_Value value) {
+  InvokeCallback(m_positionCallbacks, "Position", &value);
+}
+
+double PWMData::GetPosition() { return m_position; }
+
+void PWMData::SetPosition(double position) {
+  double oldValue = m_position.exchange(position);
+  if (oldValue != position) {
+    InvokePositionCallback(MakeDouble(position));
+  }
+}
+
+int32_t PWMData::RegisterPeriodScaleCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_periodScaleCallbacks = RegisterCallback(
+        m_periodScaleCallbacks, "PeriodScale", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetPeriodScale());
+    callback("PeriodScale", param, &value);
+  }
+  return newUid;
+}
+
+void PWMData::CancelPeriodScaleCallback(int32_t uid) {
+  m_periodScaleCallbacks = CancelCallback(m_periodScaleCallbacks, uid);
+}
+
+void PWMData::InvokePeriodScaleCallback(HAL_Value value) {
+  InvokeCallback(m_periodScaleCallbacks, "PeriodScale", &value);
+}
+
+int32_t PWMData::GetPeriodScale() { return m_periodScale; }
+
+void PWMData::SetPeriodScale(int32_t periodScale) {
+  int32_t oldValue = m_periodScale.exchange(periodScale);
+  if (oldValue != periodScale) {
+    InvokePeriodScaleCallback(MakeInt(periodScale));
+  }
+}
+
+int32_t PWMData::RegisterZeroLatchCallback(HAL_NotifyCallback callback,
+                                           void* param,
+                                           HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_zeroLatchCallbacks = RegisterCallback(m_zeroLatchCallbacks, "ZeroLatch",
+                                            callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetZeroLatch());
+    callback("ZeroLatch", param, &value);
+  }
+  return newUid;
+}
+
+void PWMData::CancelZeroLatchCallback(int32_t uid) {
+  m_zeroLatchCallbacks = CancelCallback(m_zeroLatchCallbacks, uid);
+}
+
+void PWMData::InvokeZeroLatchCallback(HAL_Value value) {
+  InvokeCallback(m_zeroLatchCallbacks, "ZeroLatch", &value);
+}
+
+HAL_Bool PWMData::GetZeroLatch() { return m_zeroLatch; }
+
+void PWMData::SetZeroLatch(HAL_Bool zeroLatch) {
+  HAL_Bool oldValue = m_zeroLatch.exchange(zeroLatch);
+  if (oldValue != zeroLatch) {
+    InvokeZeroLatchCallback(MakeBoolean(zeroLatch));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetPWMData(int32_t index) { SimPWMData[index].ResetData(); }
+
+int32_t HALSIM_RegisterPWMInitializedCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimPWMData[index].RegisterInitializedCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelPWMInitializedCallback(int32_t index, int32_t uid) {
+  SimPWMData[index].CancelInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetPWMInitialized(int32_t index) {
+  return SimPWMData[index].GetInitialized();
+}
+
+void HALSIM_SetPWMInitialized(int32_t index, HAL_Bool initialized) {
+  SimPWMData[index].SetInitialized(initialized);
+}
+
+int32_t HALSIM_RegisterPWMRawValueCallback(int32_t index,
+                                           HAL_NotifyCallback callback,
+                                           void* param,
+                                           HAL_Bool initialNotify) {
+  return SimPWMData[index].RegisterRawValueCallback(callback, param,
+                                                    initialNotify);
+}
+
+void HALSIM_CancelPWMRawValueCallback(int32_t index, int32_t uid) {
+  SimPWMData[index].CancelRawValueCallback(uid);
+}
+
+int32_t HALSIM_GetPWMRawValue(int32_t index) {
+  return SimPWMData[index].GetRawValue();
+}
+
+void HALSIM_SetPWMRawValue(int32_t index, int32_t rawValue) {
+  SimPWMData[index].SetRawValue(rawValue);
+}
+
+int32_t HALSIM_RegisterPWMSpeedCallback(int32_t index,
+                                        HAL_NotifyCallback callback,
+                                        void* param, HAL_Bool initialNotify) {
+  return SimPWMData[index].RegisterSpeedCallback(callback, param,
+                                                 initialNotify);
+}
+
+void HALSIM_CancelPWMSpeedCallback(int32_t index, int32_t uid) {
+  SimPWMData[index].CancelSpeedCallback(uid);
+}
+
+double HALSIM_GetPWMSpeed(int32_t index) {
+  return SimPWMData[index].GetSpeed();
+}
+
+void HALSIM_SetPWMSpeed(int32_t index, double speed) {
+  SimPWMData[index].SetSpeed(speed);
+}
+
+int32_t HALSIM_RegisterPWMPositionCallback(int32_t index,
+                                           HAL_NotifyCallback callback,
+                                           void* param,
+                                           HAL_Bool initialNotify) {
+  return SimPWMData[index].RegisterPositionCallback(callback, param,
+                                                    initialNotify);
+}
+
+void HALSIM_CancelPWMPositionCallback(int32_t index, int32_t uid) {
+  SimPWMData[index].CancelPositionCallback(uid);
+}
+
+double HALSIM_GetPWMPosition(int32_t index) {
+  return SimPWMData[index].GetPosition();
+}
+
+void HALSIM_SetPWMPosition(int32_t index, double position) {
+  SimPWMData[index].SetPosition(position);
+}
+
+int32_t HALSIM_RegisterPWMPeriodScaleCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimPWMData[index].RegisterPeriodScaleCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelPWMPeriodScaleCallback(int32_t index, int32_t uid) {
+  SimPWMData[index].CancelPeriodScaleCallback(uid);
+}
+
+int32_t HALSIM_GetPWMPeriodScale(int32_t index) {
+  return SimPWMData[index].GetPeriodScale();
+}
+
+void HALSIM_SetPWMPeriodScale(int32_t index, int32_t periodScale) {
+  SimPWMData[index].SetPeriodScale(periodScale);
+}
+
+int32_t HALSIM_RegisterPWMZeroLatchCallback(int32_t index,
+                                            HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify) {
+  return SimPWMData[index].RegisterZeroLatchCallback(callback, param,
+                                                     initialNotify);
+}
+
+void HALSIM_CancelPWMZeroLatchCallback(int32_t index, int32_t uid) {
+  SimPWMData[index].CancelZeroLatchCallback(uid);
+}
+
+HAL_Bool HALSIM_GetPWMZeroLatch(int32_t index) {
+  return SimPWMData[index].GetZeroLatch();
+}
+
+void HALSIM_SetPWMZeroLatch(int32_t index, HAL_Bool zeroLatch) {
+  SimPWMData[index].SetZeroLatch(zeroLatch);
+}
+
+void HALSIM_RegisterPWMAllCallbacks(int32_t index, HAL_NotifyCallback callback,
+                                    void* param, HAL_Bool initialNotify) {
+  SimPWMData[index].RegisterInitializedCallback(callback, param, initialNotify);
+  SimPWMData[index].RegisterRawValueCallback(callback, param, initialNotify);
+  SimPWMData[index].RegisterSpeedCallback(callback, param, initialNotify);
+  SimPWMData[index].RegisterPositionCallback(callback, param, initialNotify);
+  SimPWMData[index].RegisterPeriodScaleCallback(callback, param, initialNotify);
+  SimPWMData[index].RegisterZeroLatchCallback(callback, param, initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PWMDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PWMDataInternal.h
new file mode 100644
index 0000000..76cd13a
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/PWMDataInternal.h
@@ -0,0 +1,81 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/NotifyListenerVector.h"
+#include "MockData/PWMData.h"
+
+namespace hal {
+class PWMData {
+ public:
+  int32_t RegisterInitializedCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelInitializedCallback(int32_t uid);
+  void InvokeInitializedCallback(HAL_Value value);
+  HAL_Bool GetInitialized();
+  void SetInitialized(HAL_Bool initialized);
+
+  int32_t RegisterRawValueCallback(HAL_NotifyCallback callback, void* param,
+                                   HAL_Bool initialNotify);
+  void CancelRawValueCallback(int32_t uid);
+  void InvokeRawValueCallback(HAL_Value value);
+  int32_t GetRawValue();
+  void SetRawValue(int32_t rawValue);
+
+  int32_t RegisterSpeedCallback(HAL_NotifyCallback callback, void* param,
+                                HAL_Bool initialNotify);
+  void CancelSpeedCallback(int32_t uid);
+  void InvokeSpeedCallback(HAL_Value value);
+  double GetSpeed();
+  void SetSpeed(double speed);
+
+  int32_t RegisterPositionCallback(HAL_NotifyCallback callback, void* param,
+                                   HAL_Bool initialNotify);
+  void CancelPositionCallback(int32_t uid);
+  void InvokePositionCallback(HAL_Value value);
+  double GetPosition();
+  void SetPosition(double position);
+
+  int32_t RegisterPeriodScaleCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelPeriodScaleCallback(int32_t uid);
+  void InvokePeriodScaleCallback(HAL_Value value);
+  int32_t GetPeriodScale();
+  void SetPeriodScale(int32_t periodScale);
+
+  int32_t RegisterZeroLatchCallback(HAL_NotifyCallback callback, void* param,
+                                    HAL_Bool initialNotify);
+  void CancelZeroLatchCallback(int32_t uid);
+  void InvokeZeroLatchCallback(HAL_Value value);
+  HAL_Bool GetZeroLatch();
+  void SetZeroLatch(HAL_Bool zeroLatch);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_initialized{false};
+  std::shared_ptr<NotifyListenerVector> m_initializedCallbacks = nullptr;
+  std::atomic<int32_t> m_rawValue{0};
+  std::shared_ptr<NotifyListenerVector> m_rawValueCallbacks = nullptr;
+  std::atomic<double> m_speed{0};
+  std::shared_ptr<NotifyListenerVector> m_speedCallbacks = nullptr;
+  std::atomic<double> m_position{0};
+  std::shared_ptr<NotifyListenerVector> m_positionCallbacks = nullptr;
+  std::atomic<int32_t> m_periodScale{0};
+  std::shared_ptr<NotifyListenerVector> m_periodScaleCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_zeroLatch{false};
+  std::shared_ptr<NotifyListenerVector> m_zeroLatchCallbacks = nullptr;
+};
+extern PWMData* SimPWMData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/RelayData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/RelayData.cpp
new file mode 100644
index 0000000..06c4cfe
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/RelayData.cpp
@@ -0,0 +1,274 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "MockData/NotifyCallbackHelpers.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() {
+  m_initializedForward = false;
+  m_initializedForwardCallbacks = nullptr;
+  m_initializedReverse = false;
+  m_initializedReverseCallbacks = nullptr;
+  m_forward = false;
+  m_forwardCallbacks = nullptr;
+  m_reverse = false;
+  m_reverseCallbacks = nullptr;
+}
+
+int32_t RelayData::RegisterInitializedForwardCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedForwardCallbacks =
+        RegisterCallback(m_initializedForwardCallbacks, "InitializedForward",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitializedForward());
+    callback("InitializedForward", param, &value);
+  }
+  return newUid;
+}
+
+void RelayData::CancelInitializedForwardCallback(int32_t uid) {
+  m_initializedForwardCallbacks =
+      CancelCallback(m_initializedForwardCallbacks, uid);
+}
+
+void RelayData::InvokeInitializedForwardCallback(HAL_Value value) {
+  InvokeCallback(m_initializedForwardCallbacks, "InitializedForward", &value);
+}
+
+HAL_Bool RelayData::GetInitializedForward() { return m_initializedForward; }
+
+void RelayData::SetInitializedForward(HAL_Bool initializedForward) {
+  HAL_Bool oldValue = m_initializedForward.exchange(initializedForward);
+  if (oldValue != initializedForward) {
+    InvokeInitializedForwardCallback(MakeBoolean(initializedForward));
+  }
+}
+
+int32_t RelayData::RegisterInitializedReverseCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedReverseCallbacks =
+        RegisterCallback(m_initializedReverseCallbacks, "InitializedReverse",
+                         callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitializedReverse());
+    callback("InitializedReverse", param, &value);
+  }
+  return newUid;
+}
+
+void RelayData::CancelInitializedReverseCallback(int32_t uid) {
+  m_initializedReverseCallbacks =
+      CancelCallback(m_initializedReverseCallbacks, uid);
+}
+
+void RelayData::InvokeInitializedReverseCallback(HAL_Value value) {
+  InvokeCallback(m_initializedReverseCallbacks, "InitializedReverse", &value);
+}
+
+HAL_Bool RelayData::GetInitializedReverse() { return m_initializedReverse; }
+
+void RelayData::SetInitializedReverse(HAL_Bool initializedReverse) {
+  HAL_Bool oldValue = m_initializedReverse.exchange(initializedReverse);
+  if (oldValue != initializedReverse) {
+    InvokeInitializedReverseCallback(MakeBoolean(initializedReverse));
+  }
+}
+
+int32_t RelayData::RegisterForwardCallback(HAL_NotifyCallback callback,
+                                           void* param,
+                                           HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_forwardCallbacks = RegisterCallback(m_forwardCallbacks, "Forward",
+                                          callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetForward());
+    callback("Forward", param, &value);
+  }
+  return newUid;
+}
+
+void RelayData::CancelForwardCallback(int32_t uid) {
+  m_forwardCallbacks = CancelCallback(m_forwardCallbacks, uid);
+}
+
+void RelayData::InvokeForwardCallback(HAL_Value value) {
+  InvokeCallback(m_forwardCallbacks, "Forward", &value);
+}
+
+HAL_Bool RelayData::GetForward() { return m_forward; }
+
+void RelayData::SetForward(HAL_Bool forward) {
+  HAL_Bool oldValue = m_forward.exchange(forward);
+  if (oldValue != forward) {
+    InvokeForwardCallback(MakeBoolean(forward));
+  }
+}
+
+int32_t RelayData::RegisterReverseCallback(HAL_NotifyCallback callback,
+                                           void* param,
+                                           HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_reverseCallbacks = RegisterCallback(m_reverseCallbacks, "Reverse",
+                                          callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetReverse());
+    callback("Reverse", param, &value);
+  }
+  return newUid;
+}
+
+void RelayData::CancelReverseCallback(int32_t uid) {
+  m_reverseCallbacks = CancelCallback(m_reverseCallbacks, uid);
+}
+
+void RelayData::InvokeReverseCallback(HAL_Value value) {
+  InvokeCallback(m_reverseCallbacks, "Reverse", &value);
+}
+
+HAL_Bool RelayData::GetReverse() { return m_reverse; }
+
+void RelayData::SetReverse(HAL_Bool reverse) {
+  HAL_Bool oldValue = m_reverse.exchange(reverse);
+  if (oldValue != reverse) {
+    InvokeReverseCallback(MakeBoolean(reverse));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetRelayData(int32_t index) { SimRelayData[index].ResetData(); }
+
+int32_t HALSIM_RegisterRelayInitializedForwardCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimRelayData[index].RegisterInitializedForwardCallback(callback, param,
+                                                                initialNotify);
+}
+
+void HALSIM_CancelRelayInitializedForwardCallback(int32_t index, int32_t uid) {
+  SimRelayData[index].CancelInitializedForwardCallback(uid);
+}
+
+HAL_Bool HALSIM_GetRelayInitializedForward(int32_t index) {
+  return SimRelayData[index].GetInitializedForward();
+}
+
+void HALSIM_SetRelayInitializedForward(int32_t index,
+                                       HAL_Bool initializedForward) {
+  SimRelayData[index].SetInitializedForward(initializedForward);
+}
+
+int32_t HALSIM_RegisterRelayInitializedReverseCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimRelayData[index].RegisterInitializedReverseCallback(callback, param,
+                                                                initialNotify);
+}
+
+void HALSIM_CancelRelayInitializedReverseCallback(int32_t index, int32_t uid) {
+  SimRelayData[index].CancelInitializedReverseCallback(uid);
+}
+
+HAL_Bool HALSIM_GetRelayInitializedReverse(int32_t index) {
+  return SimRelayData[index].GetInitializedReverse();
+}
+
+void HALSIM_SetRelayInitializedReverse(int32_t index,
+                                       HAL_Bool initializedReverse) {
+  SimRelayData[index].SetInitializedReverse(initializedReverse);
+}
+
+int32_t HALSIM_RegisterRelayForwardCallback(int32_t index,
+                                            HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify) {
+  return SimRelayData[index].RegisterForwardCallback(callback, param,
+                                                     initialNotify);
+}
+
+void HALSIM_CancelRelayForwardCallback(int32_t index, int32_t uid) {
+  SimRelayData[index].CancelForwardCallback(uid);
+}
+
+HAL_Bool HALSIM_GetRelayForward(int32_t index) {
+  return SimRelayData[index].GetForward();
+}
+
+void HALSIM_SetRelayForward(int32_t index, HAL_Bool forward) {
+  SimRelayData[index].SetForward(forward);
+}
+
+int32_t HALSIM_RegisterRelayReverseCallback(int32_t index,
+                                            HAL_NotifyCallback callback,
+                                            void* param,
+                                            HAL_Bool initialNotify) {
+  return SimRelayData[index].RegisterReverseCallback(callback, param,
+                                                     initialNotify);
+}
+
+void HALSIM_CancelRelayReverseCallback(int32_t index, int32_t uid) {
+  SimRelayData[index].CancelReverseCallback(uid);
+}
+
+HAL_Bool HALSIM_GetRelayReverse(int32_t index) {
+  return SimRelayData[index].GetReverse();
+}
+
+void HALSIM_SetRelayReverse(int32_t index, HAL_Bool reverse) {
+  SimRelayData[index].SetReverse(reverse);
+}
+
+void HALSIM_RegisterRelayAllCallbacks(int32_t index,
+                                      HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify) {
+  SimRelayData[index].RegisterInitializedForwardCallback(callback, param,
+                                                         initialNotify);
+  SimRelayData[index].RegisterInitializedReverseCallback(callback, param,
+                                                         initialNotify);
+  SimRelayData[index].RegisterForwardCallback(callback, param, initialNotify);
+  SimRelayData[index].RegisterReverseCallback(callback, param, initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/RelayDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/RelayDataInternal.h
new file mode 100644
index 0000000..ee32eb2
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/RelayDataInternal.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
+
+#include <atomic>
+#include <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/NotifyListenerVector.h"
+#include "MockData/RelayData.h"
+
+namespace hal {
+class RelayData {
+ public:
+  int32_t RegisterInitializedForwardCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify);
+  void CancelInitializedForwardCallback(int32_t uid);
+  void InvokeInitializedForwardCallback(HAL_Value value);
+  HAL_Bool GetInitializedForward();
+  void SetInitializedForward(HAL_Bool initializedForward);
+
+  int32_t RegisterInitializedReverseCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify);
+  void CancelInitializedReverseCallback(int32_t uid);
+  void InvokeInitializedReverseCallback(HAL_Value value);
+  HAL_Bool GetInitializedReverse();
+  void SetInitializedReverse(HAL_Bool initializedReverse);
+
+  int32_t RegisterForwardCallback(HAL_NotifyCallback callback, void* param,
+                                  HAL_Bool initialNotify);
+  void CancelForwardCallback(int32_t uid);
+  void InvokeForwardCallback(HAL_Value value);
+  HAL_Bool GetForward();
+  void SetForward(HAL_Bool forward);
+
+  int32_t RegisterReverseCallback(HAL_NotifyCallback callback, void* param,
+                                  HAL_Bool initialNotify);
+  void CancelReverseCallback(int32_t uid);
+  void InvokeReverseCallback(HAL_Value value);
+  HAL_Bool GetReverse();
+  void SetReverse(HAL_Bool reverse);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_initializedForward{false};
+  std::shared_ptr<NotifyListenerVector> m_initializedForwardCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_initializedReverse{false};
+  std::shared_ptr<NotifyListenerVector> m_initializedReverseCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_forward{false};
+  std::shared_ptr<NotifyListenerVector> m_forwardCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_reverse{false};
+  std::shared_ptr<NotifyListenerVector> m_reverseCallbacks = nullptr;
+};
+extern RelayData* SimRelayData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/RoboRioData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/RoboRioData.cpp
new file mode 100644
index 0000000..8a4ef5e
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/RoboRioData.cpp
@@ -0,0 +1,934 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "MockData/NotifyCallbackHelpers.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() {
+  m_fPGAButton = false;
+  m_fPGAButtonCallbacks = nullptr;
+  m_vInVoltage = 0.0;
+  m_vInVoltageCallbacks = nullptr;
+  m_vInCurrent = 0.0;
+  m_vInCurrentCallbacks = nullptr;
+  m_userVoltage6V = 6.0;
+  m_userVoltage6VCallbacks = nullptr;
+  m_userCurrent6V = 0.0;
+  m_userCurrent6VCallbacks = nullptr;
+  m_userActive6V = false;
+  m_userActive6VCallbacks = nullptr;
+  m_userVoltage5V = 5.0;
+  m_userVoltage5VCallbacks = nullptr;
+  m_userCurrent5V = 0.0;
+  m_userCurrent5VCallbacks = nullptr;
+  m_userActive5V = false;
+  m_userActive5VCallbacks = nullptr;
+  m_userVoltage3V3 = 3.3;
+  m_userVoltage3V3Callbacks = nullptr;
+  m_userCurrent3V3 = 0.0;
+  m_userCurrent3V3Callbacks = nullptr;
+  m_userActive3V3 = false;
+  m_userActive3V3Callbacks = nullptr;
+  m_userFaults6V = 0;
+  m_userFaults6VCallbacks = nullptr;
+  m_userFaults5V = 0;
+  m_userFaults5VCallbacks = nullptr;
+  m_userFaults3V3 = 0;
+  m_userFaults3V3Callbacks = nullptr;
+}
+
+int32_t RoboRioData::RegisterFPGAButtonCallback(HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_fPGAButtonCallbacks = RegisterCallback(
+        m_fPGAButtonCallbacks, "FPGAButton", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetFPGAButton());
+    callback("FPGAButton", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelFPGAButtonCallback(int32_t uid) {
+  m_fPGAButtonCallbacks = CancelCallback(m_fPGAButtonCallbacks, uid);
+}
+
+void RoboRioData::InvokeFPGAButtonCallback(HAL_Value value) {
+  InvokeCallback(m_fPGAButtonCallbacks, "FPGAButton", &value);
+}
+
+HAL_Bool RoboRioData::GetFPGAButton() { return m_fPGAButton; }
+
+void RoboRioData::SetFPGAButton(HAL_Bool fPGAButton) {
+  HAL_Bool oldValue = m_fPGAButton.exchange(fPGAButton);
+  if (oldValue != fPGAButton) {
+    InvokeFPGAButtonCallback(MakeBoolean(fPGAButton));
+  }
+}
+
+int32_t RoboRioData::RegisterVInVoltageCallback(HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_vInVoltageCallbacks = RegisterCallback(
+        m_vInVoltageCallbacks, "VInVoltage", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetVInVoltage());
+    callback("VInVoltage", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelVInVoltageCallback(int32_t uid) {
+  m_vInVoltageCallbacks = CancelCallback(m_vInVoltageCallbacks, uid);
+}
+
+void RoboRioData::InvokeVInVoltageCallback(HAL_Value value) {
+  InvokeCallback(m_vInVoltageCallbacks, "VInVoltage", &value);
+}
+
+double RoboRioData::GetVInVoltage() { return m_vInVoltage; }
+
+void RoboRioData::SetVInVoltage(double vInVoltage) {
+  double oldValue = m_vInVoltage.exchange(vInVoltage);
+  if (oldValue != vInVoltage) {
+    InvokeVInVoltageCallback(MakeDouble(vInVoltage));
+  }
+}
+
+int32_t RoboRioData::RegisterVInCurrentCallback(HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_vInCurrentCallbacks = RegisterCallback(
+        m_vInCurrentCallbacks, "VInCurrent", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetVInCurrent());
+    callback("VInCurrent", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelVInCurrentCallback(int32_t uid) {
+  m_vInCurrentCallbacks = CancelCallback(m_vInCurrentCallbacks, uid);
+}
+
+void RoboRioData::InvokeVInCurrentCallback(HAL_Value value) {
+  InvokeCallback(m_vInCurrentCallbacks, "VInCurrent", &value);
+}
+
+double RoboRioData::GetVInCurrent() { return m_vInCurrent; }
+
+void RoboRioData::SetVInCurrent(double vInCurrent) {
+  double oldValue = m_vInCurrent.exchange(vInCurrent);
+  if (oldValue != vInCurrent) {
+    InvokeVInCurrentCallback(MakeDouble(vInCurrent));
+  }
+}
+
+int32_t RoboRioData::RegisterUserVoltage6VCallback(HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_userVoltage6VCallbacks = RegisterCallback(
+        m_userVoltage6VCallbacks, "UserVoltage6V", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetUserVoltage6V());
+    callback("UserVoltage6V", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelUserVoltage6VCallback(int32_t uid) {
+  m_userVoltage6VCallbacks = CancelCallback(m_userVoltage6VCallbacks, uid);
+}
+
+void RoboRioData::InvokeUserVoltage6VCallback(HAL_Value value) {
+  InvokeCallback(m_userVoltage6VCallbacks, "UserVoltage6V", &value);
+}
+
+double RoboRioData::GetUserVoltage6V() { return m_userVoltage6V; }
+
+void RoboRioData::SetUserVoltage6V(double userVoltage6V) {
+  double oldValue = m_userVoltage6V.exchange(userVoltage6V);
+  if (oldValue != userVoltage6V) {
+    InvokeUserVoltage6VCallback(MakeDouble(userVoltage6V));
+  }
+}
+
+int32_t RoboRioData::RegisterUserCurrent6VCallback(HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_userCurrent6VCallbacks = RegisterCallback(
+        m_userCurrent6VCallbacks, "UserCurrent6V", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetUserCurrent6V());
+    callback("UserCurrent6V", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelUserCurrent6VCallback(int32_t uid) {
+  m_userCurrent6VCallbacks = CancelCallback(m_userCurrent6VCallbacks, uid);
+}
+
+void RoboRioData::InvokeUserCurrent6VCallback(HAL_Value value) {
+  InvokeCallback(m_userCurrent6VCallbacks, "UserCurrent6V", &value);
+}
+
+double RoboRioData::GetUserCurrent6V() { return m_userCurrent6V; }
+
+void RoboRioData::SetUserCurrent6V(double userCurrent6V) {
+  double oldValue = m_userCurrent6V.exchange(userCurrent6V);
+  if (oldValue != userCurrent6V) {
+    InvokeUserCurrent6VCallback(MakeDouble(userCurrent6V));
+  }
+}
+
+int32_t RoboRioData::RegisterUserActive6VCallback(HAL_NotifyCallback callback,
+                                                  void* param,
+                                                  HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_userActive6VCallbacks = RegisterCallback(
+        m_userActive6VCallbacks, "UserActive6V", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetUserActive6V());
+    callback("UserActive6V", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelUserActive6VCallback(int32_t uid) {
+  m_userActive6VCallbacks = CancelCallback(m_userActive6VCallbacks, uid);
+}
+
+void RoboRioData::InvokeUserActive6VCallback(HAL_Value value) {
+  InvokeCallback(m_userActive6VCallbacks, "UserActive6V", &value);
+}
+
+HAL_Bool RoboRioData::GetUserActive6V() { return m_userActive6V; }
+
+void RoboRioData::SetUserActive6V(HAL_Bool userActive6V) {
+  HAL_Bool oldValue = m_userActive6V.exchange(userActive6V);
+  if (oldValue != userActive6V) {
+    InvokeUserActive6VCallback(MakeBoolean(userActive6V));
+  }
+}
+
+int32_t RoboRioData::RegisterUserVoltage5VCallback(HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_userVoltage5VCallbacks = RegisterCallback(
+        m_userVoltage5VCallbacks, "UserVoltage5V", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetUserVoltage5V());
+    callback("UserVoltage5V", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelUserVoltage5VCallback(int32_t uid) {
+  m_userVoltage5VCallbacks = CancelCallback(m_userVoltage5VCallbacks, uid);
+}
+
+void RoboRioData::InvokeUserVoltage5VCallback(HAL_Value value) {
+  InvokeCallback(m_userVoltage5VCallbacks, "UserVoltage5V", &value);
+}
+
+double RoboRioData::GetUserVoltage5V() { return m_userVoltage5V; }
+
+void RoboRioData::SetUserVoltage5V(double userVoltage5V) {
+  double oldValue = m_userVoltage5V.exchange(userVoltage5V);
+  if (oldValue != userVoltage5V) {
+    InvokeUserVoltage5VCallback(MakeDouble(userVoltage5V));
+  }
+}
+
+int32_t RoboRioData::RegisterUserCurrent5VCallback(HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_userCurrent5VCallbacks = RegisterCallback(
+        m_userCurrent5VCallbacks, "UserCurrent5V", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetUserCurrent5V());
+    callback("UserCurrent5V", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelUserCurrent5VCallback(int32_t uid) {
+  m_userCurrent5VCallbacks = CancelCallback(m_userCurrent5VCallbacks, uid);
+}
+
+void RoboRioData::InvokeUserCurrent5VCallback(HAL_Value value) {
+  InvokeCallback(m_userCurrent5VCallbacks, "UserCurrent5V", &value);
+}
+
+double RoboRioData::GetUserCurrent5V() { return m_userCurrent5V; }
+
+void RoboRioData::SetUserCurrent5V(double userCurrent5V) {
+  double oldValue = m_userCurrent5V.exchange(userCurrent5V);
+  if (oldValue != userCurrent5V) {
+    InvokeUserCurrent5VCallback(MakeDouble(userCurrent5V));
+  }
+}
+
+int32_t RoboRioData::RegisterUserActive5VCallback(HAL_NotifyCallback callback,
+                                                  void* param,
+                                                  HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_userActive5VCallbacks = RegisterCallback(
+        m_userActive5VCallbacks, "UserActive5V", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetUserActive5V());
+    callback("UserActive5V", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelUserActive5VCallback(int32_t uid) {
+  m_userActive5VCallbacks = CancelCallback(m_userActive5VCallbacks, uid);
+}
+
+void RoboRioData::InvokeUserActive5VCallback(HAL_Value value) {
+  InvokeCallback(m_userActive5VCallbacks, "UserActive5V", &value);
+}
+
+HAL_Bool RoboRioData::GetUserActive5V() { return m_userActive5V; }
+
+void RoboRioData::SetUserActive5V(HAL_Bool userActive5V) {
+  HAL_Bool oldValue = m_userActive5V.exchange(userActive5V);
+  if (oldValue != userActive5V) {
+    InvokeUserActive5VCallback(MakeBoolean(userActive5V));
+  }
+}
+
+int32_t RoboRioData::RegisterUserVoltage3V3Callback(HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_userVoltage3V3Callbacks = RegisterCallback(
+        m_userVoltage3V3Callbacks, "UserVoltage3V3", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetUserVoltage3V3());
+    callback("UserVoltage3V3", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelUserVoltage3V3Callback(int32_t uid) {
+  m_userVoltage3V3Callbacks = CancelCallback(m_userVoltage3V3Callbacks, uid);
+}
+
+void RoboRioData::InvokeUserVoltage3V3Callback(HAL_Value value) {
+  InvokeCallback(m_userVoltage3V3Callbacks, "UserVoltage3V3", &value);
+}
+
+double RoboRioData::GetUserVoltage3V3() { return m_userVoltage3V3; }
+
+void RoboRioData::SetUserVoltage3V3(double userVoltage3V3) {
+  double oldValue = m_userVoltage3V3.exchange(userVoltage3V3);
+  if (oldValue != userVoltage3V3) {
+    InvokeUserVoltage3V3Callback(MakeDouble(userVoltage3V3));
+  }
+}
+
+int32_t RoboRioData::RegisterUserCurrent3V3Callback(HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_userCurrent3V3Callbacks = RegisterCallback(
+        m_userCurrent3V3Callbacks, "UserCurrent3V3", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetUserCurrent3V3());
+    callback("UserCurrent3V3", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelUserCurrent3V3Callback(int32_t uid) {
+  m_userCurrent3V3Callbacks = CancelCallback(m_userCurrent3V3Callbacks, uid);
+}
+
+void RoboRioData::InvokeUserCurrent3V3Callback(HAL_Value value) {
+  InvokeCallback(m_userCurrent3V3Callbacks, "UserCurrent3V3", &value);
+}
+
+double RoboRioData::GetUserCurrent3V3() { return m_userCurrent3V3; }
+
+void RoboRioData::SetUserCurrent3V3(double userCurrent3V3) {
+  double oldValue = m_userCurrent3V3.exchange(userCurrent3V3);
+  if (oldValue != userCurrent3V3) {
+    InvokeUserCurrent3V3Callback(MakeDouble(userCurrent3V3));
+  }
+}
+
+int32_t RoboRioData::RegisterUserActive3V3Callback(HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_userActive3V3Callbacks = RegisterCallback(
+        m_userActive3V3Callbacks, "UserActive3V3", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetUserActive3V3());
+    callback("UserActive3V3", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelUserActive3V3Callback(int32_t uid) {
+  m_userActive3V3Callbacks = CancelCallback(m_userActive3V3Callbacks, uid);
+}
+
+void RoboRioData::InvokeUserActive3V3Callback(HAL_Value value) {
+  InvokeCallback(m_userActive3V3Callbacks, "UserActive3V3", &value);
+}
+
+HAL_Bool RoboRioData::GetUserActive3V3() { return m_userActive3V3; }
+
+void RoboRioData::SetUserActive3V3(HAL_Bool userActive3V3) {
+  HAL_Bool oldValue = m_userActive3V3.exchange(userActive3V3);
+  if (oldValue != userActive3V3) {
+    InvokeUserActive3V3Callback(MakeBoolean(userActive3V3));
+  }
+}
+
+int32_t RoboRioData::RegisterUserFaults6VCallback(HAL_NotifyCallback callback,
+                                                  void* param,
+                                                  HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_userFaults6VCallbacks = RegisterCallback(
+        m_userFaults6VCallbacks, "UserFaults6V", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetUserFaults6V());
+    callback("UserFaults6V", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelUserFaults6VCallback(int32_t uid) {
+  m_userFaults6VCallbacks = CancelCallback(m_userFaults6VCallbacks, uid);
+}
+
+void RoboRioData::InvokeUserFaults6VCallback(HAL_Value value) {
+  InvokeCallback(m_userFaults6VCallbacks, "UserFaults6V", &value);
+}
+
+int32_t RoboRioData::GetUserFaults6V() { return m_userFaults6V; }
+
+void RoboRioData::SetUserFaults6V(int32_t userFaults6V) {
+  int32_t oldValue = m_userFaults6V.exchange(userFaults6V);
+  if (oldValue != userFaults6V) {
+    InvokeUserFaults6VCallback(MakeInt(userFaults6V));
+  }
+}
+
+int32_t RoboRioData::RegisterUserFaults5VCallback(HAL_NotifyCallback callback,
+                                                  void* param,
+                                                  HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_userFaults5VCallbacks = RegisterCallback(
+        m_userFaults5VCallbacks, "UserFaults5V", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetUserFaults5V());
+    callback("UserFaults5V", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelUserFaults5VCallback(int32_t uid) {
+  m_userFaults5VCallbacks = CancelCallback(m_userFaults5VCallbacks, uid);
+}
+
+void RoboRioData::InvokeUserFaults5VCallback(HAL_Value value) {
+  InvokeCallback(m_userFaults5VCallbacks, "UserFaults5V", &value);
+}
+
+int32_t RoboRioData::GetUserFaults5V() { return m_userFaults5V; }
+
+void RoboRioData::SetUserFaults5V(int32_t userFaults5V) {
+  int32_t oldValue = m_userFaults5V.exchange(userFaults5V);
+  if (oldValue != userFaults5V) {
+    InvokeUserFaults5VCallback(MakeInt(userFaults5V));
+  }
+}
+
+int32_t RoboRioData::RegisterUserFaults3V3Callback(HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_userFaults3V3Callbacks = RegisterCallback(
+        m_userFaults3V3Callbacks, "UserFaults3V3", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetUserFaults3V3());
+    callback("UserFaults3V3", param, &value);
+  }
+  return newUid;
+}
+
+void RoboRioData::CancelUserFaults3V3Callback(int32_t uid) {
+  m_userFaults3V3Callbacks = CancelCallback(m_userFaults3V3Callbacks, uid);
+}
+
+void RoboRioData::InvokeUserFaults3V3Callback(HAL_Value value) {
+  InvokeCallback(m_userFaults3V3Callbacks, "UserFaults3V3", &value);
+}
+
+int32_t RoboRioData::GetUserFaults3V3() { return m_userFaults3V3; }
+
+void RoboRioData::SetUserFaults3V3(int32_t userFaults3V3) {
+  int32_t oldValue = m_userFaults3V3.exchange(userFaults3V3);
+  if (oldValue != userFaults3V3) {
+    InvokeUserFaults3V3Callback(MakeInt(userFaults3V3));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetRoboRioData(int32_t index) {
+  SimRoboRioData[index].ResetData();
+}
+
+int32_t HALSIM_RegisterRoboRioFPGAButtonCallback(int32_t index,
+                                                 HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterFPGAButtonCallback(callback, param,
+                                                          initialNotify);
+}
+
+void HALSIM_CancelRoboRioFPGAButtonCallback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelFPGAButtonCallback(uid);
+}
+
+HAL_Bool HALSIM_GetRoboRioFPGAButton(int32_t index) {
+  return SimRoboRioData[index].GetFPGAButton();
+}
+
+void HALSIM_SetRoboRioFPGAButton(int32_t index, HAL_Bool fPGAButton) {
+  SimRoboRioData[index].SetFPGAButton(fPGAButton);
+}
+
+int32_t HALSIM_RegisterRoboRioVInVoltageCallback(int32_t index,
+                                                 HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterVInVoltageCallback(callback, param,
+                                                          initialNotify);
+}
+
+void HALSIM_CancelRoboRioVInVoltageCallback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelVInVoltageCallback(uid);
+}
+
+double HALSIM_GetRoboRioVInVoltage(int32_t index) {
+  return SimRoboRioData[index].GetVInVoltage();
+}
+
+void HALSIM_SetRoboRioVInVoltage(int32_t index, double vInVoltage) {
+  SimRoboRioData[index].SetVInVoltage(vInVoltage);
+}
+
+int32_t HALSIM_RegisterRoboRioVInCurrentCallback(int32_t index,
+                                                 HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterVInCurrentCallback(callback, param,
+                                                          initialNotify);
+}
+
+void HALSIM_CancelRoboRioVInCurrentCallback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelVInCurrentCallback(uid);
+}
+
+double HALSIM_GetRoboRioVInCurrent(int32_t index) {
+  return SimRoboRioData[index].GetVInCurrent();
+}
+
+void HALSIM_SetRoboRioVInCurrent(int32_t index, double vInCurrent) {
+  SimRoboRioData[index].SetVInCurrent(vInCurrent);
+}
+
+int32_t HALSIM_RegisterRoboRioUserVoltage6VCallback(int32_t index,
+                                                    HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterUserVoltage6VCallback(callback, param,
+                                                             initialNotify);
+}
+
+void HALSIM_CancelRoboRioUserVoltage6VCallback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelUserVoltage6VCallback(uid);
+}
+
+double HALSIM_GetRoboRioUserVoltage6V(int32_t index) {
+  return SimRoboRioData[index].GetUserVoltage6V();
+}
+
+void HALSIM_SetRoboRioUserVoltage6V(int32_t index, double userVoltage6V) {
+  SimRoboRioData[index].SetUserVoltage6V(userVoltage6V);
+}
+
+int32_t HALSIM_RegisterRoboRioUserCurrent6VCallback(int32_t index,
+                                                    HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterUserCurrent6VCallback(callback, param,
+                                                             initialNotify);
+}
+
+void HALSIM_CancelRoboRioUserCurrent6VCallback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelUserCurrent6VCallback(uid);
+}
+
+double HALSIM_GetRoboRioUserCurrent6V(int32_t index) {
+  return SimRoboRioData[index].GetUserCurrent6V();
+}
+
+void HALSIM_SetRoboRioUserCurrent6V(int32_t index, double userCurrent6V) {
+  SimRoboRioData[index].SetUserCurrent6V(userCurrent6V);
+}
+
+int32_t HALSIM_RegisterRoboRioUserActive6VCallback(int32_t index,
+                                                   HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterUserActive6VCallback(callback, param,
+                                                            initialNotify);
+}
+
+void HALSIM_CancelRoboRioUserActive6VCallback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelUserActive6VCallback(uid);
+}
+
+HAL_Bool HALSIM_GetRoboRioUserActive6V(int32_t index) {
+  return SimRoboRioData[index].GetUserActive6V();
+}
+
+void HALSIM_SetRoboRioUserActive6V(int32_t index, HAL_Bool userActive6V) {
+  SimRoboRioData[index].SetUserActive6V(userActive6V);
+}
+
+int32_t HALSIM_RegisterRoboRioUserVoltage5VCallback(int32_t index,
+                                                    HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterUserVoltage5VCallback(callback, param,
+                                                             initialNotify);
+}
+
+void HALSIM_CancelRoboRioUserVoltage5VCallback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelUserVoltage5VCallback(uid);
+}
+
+double HALSIM_GetRoboRioUserVoltage5V(int32_t index) {
+  return SimRoboRioData[index].GetUserVoltage5V();
+}
+
+void HALSIM_SetRoboRioUserVoltage5V(int32_t index, double userVoltage5V) {
+  SimRoboRioData[index].SetUserVoltage5V(userVoltage5V);
+}
+
+int32_t HALSIM_RegisterRoboRioUserCurrent5VCallback(int32_t index,
+                                                    HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterUserCurrent5VCallback(callback, param,
+                                                             initialNotify);
+}
+
+void HALSIM_CancelRoboRioUserCurrent5VCallback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelUserCurrent5VCallback(uid);
+}
+
+double HALSIM_GetRoboRioUserCurrent5V(int32_t index) {
+  return SimRoboRioData[index].GetUserCurrent5V();
+}
+
+void HALSIM_SetRoboRioUserCurrent5V(int32_t index, double userCurrent5V) {
+  SimRoboRioData[index].SetUserCurrent5V(userCurrent5V);
+}
+
+int32_t HALSIM_RegisterRoboRioUserActive5VCallback(int32_t index,
+                                                   HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterUserActive5VCallback(callback, param,
+                                                            initialNotify);
+}
+
+void HALSIM_CancelRoboRioUserActive5VCallback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelUserActive5VCallback(uid);
+}
+
+HAL_Bool HALSIM_GetRoboRioUserActive5V(int32_t index) {
+  return SimRoboRioData[index].GetUserActive5V();
+}
+
+void HALSIM_SetRoboRioUserActive5V(int32_t index, HAL_Bool userActive5V) {
+  SimRoboRioData[index].SetUserActive5V(userActive5V);
+}
+
+int32_t HALSIM_RegisterRoboRioUserVoltage3V3Callback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterUserVoltage3V3Callback(callback, param,
+                                                              initialNotify);
+}
+
+void HALSIM_CancelRoboRioUserVoltage3V3Callback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelUserVoltage3V3Callback(uid);
+}
+
+double HALSIM_GetRoboRioUserVoltage3V3(int32_t index) {
+  return SimRoboRioData[index].GetUserVoltage3V3();
+}
+
+void HALSIM_SetRoboRioUserVoltage3V3(int32_t index, double userVoltage3V3) {
+  SimRoboRioData[index].SetUserVoltage3V3(userVoltage3V3);
+}
+
+int32_t HALSIM_RegisterRoboRioUserCurrent3V3Callback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterUserCurrent3V3Callback(callback, param,
+                                                              initialNotify);
+}
+
+void HALSIM_CancelRoboRioUserCurrent3V3Callback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelUserCurrent3V3Callback(uid);
+}
+
+double HALSIM_GetRoboRioUserCurrent3V3(int32_t index) {
+  return SimRoboRioData[index].GetUserCurrent3V3();
+}
+
+void HALSIM_SetRoboRioUserCurrent3V3(int32_t index, double userCurrent3V3) {
+  SimRoboRioData[index].SetUserCurrent3V3(userCurrent3V3);
+}
+
+int32_t HALSIM_RegisterRoboRioUserActive3V3Callback(int32_t index,
+                                                    HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterUserActive3V3Callback(callback, param,
+                                                             initialNotify);
+}
+
+void HALSIM_CancelRoboRioUserActive3V3Callback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelUserActive3V3Callback(uid);
+}
+
+HAL_Bool HALSIM_GetRoboRioUserActive3V3(int32_t index) {
+  return SimRoboRioData[index].GetUserActive3V3();
+}
+
+void HALSIM_SetRoboRioUserActive3V3(int32_t index, HAL_Bool userActive3V3) {
+  SimRoboRioData[index].SetUserActive3V3(userActive3V3);
+}
+
+int32_t HALSIM_RegisterRoboRioUserFaults6VCallback(int32_t index,
+                                                   HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterUserFaults6VCallback(callback, param,
+                                                            initialNotify);
+}
+
+void HALSIM_CancelRoboRioUserFaults6VCallback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelUserFaults6VCallback(uid);
+}
+
+int32_t HALSIM_GetRoboRioUserFaults6V(int32_t index) {
+  return SimRoboRioData[index].GetUserFaults6V();
+}
+
+void HALSIM_SetRoboRioUserFaults6V(int32_t index, int32_t userFaults6V) {
+  SimRoboRioData[index].SetUserFaults6V(userFaults6V);
+}
+
+int32_t HALSIM_RegisterRoboRioUserFaults5VCallback(int32_t index,
+                                                   HAL_NotifyCallback callback,
+                                                   void* param,
+                                                   HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterUserFaults5VCallback(callback, param,
+                                                            initialNotify);
+}
+
+void HALSIM_CancelRoboRioUserFaults5VCallback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelUserFaults5VCallback(uid);
+}
+
+int32_t HALSIM_GetRoboRioUserFaults5V(int32_t index) {
+  return SimRoboRioData[index].GetUserFaults5V();
+}
+
+void HALSIM_SetRoboRioUserFaults5V(int32_t index, int32_t userFaults5V) {
+  SimRoboRioData[index].SetUserFaults5V(userFaults5V);
+}
+
+int32_t HALSIM_RegisterRoboRioUserFaults3V3Callback(int32_t index,
+                                                    HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  return SimRoboRioData[index].RegisterUserFaults3V3Callback(callback, param,
+                                                             initialNotify);
+}
+
+void HALSIM_CancelRoboRioUserFaults3V3Callback(int32_t index, int32_t uid) {
+  SimRoboRioData[index].CancelUserFaults3V3Callback(uid);
+}
+
+int32_t HALSIM_GetRoboRioUserFaults3V3(int32_t index) {
+  return SimRoboRioData[index].GetUserFaults3V3();
+}
+
+void HALSIM_SetRoboRioUserFaults3V3(int32_t index, int32_t userFaults3V3) {
+  SimRoboRioData[index].SetUserFaults3V3(userFaults3V3);
+}
+
+void HALSIM_RegisterRoboRioAllCallbacks(int32_t index,
+                                        HAL_NotifyCallback callback,
+                                        void* param, HAL_Bool initialNotify) {
+  SimRoboRioData[index].RegisterFPGAButtonCallback(callback, param,
+                                                   initialNotify);
+  SimRoboRioData[index].RegisterVInVoltageCallback(callback, param,
+                                                   initialNotify);
+  SimRoboRioData[index].RegisterVInCurrentCallback(callback, param,
+                                                   initialNotify);
+  SimRoboRioData[index].RegisterUserVoltage6VCallback(callback, param,
+                                                      initialNotify);
+  SimRoboRioData[index].RegisterUserCurrent6VCallback(callback, param,
+                                                      initialNotify);
+  SimRoboRioData[index].RegisterUserActive6VCallback(callback, param,
+                                                     initialNotify);
+  SimRoboRioData[index].RegisterUserVoltage5VCallback(callback, param,
+                                                      initialNotify);
+  SimRoboRioData[index].RegisterUserCurrent5VCallback(callback, param,
+                                                      initialNotify);
+  SimRoboRioData[index].RegisterUserActive5VCallback(callback, param,
+                                                     initialNotify);
+  SimRoboRioData[index].RegisterUserVoltage3V3Callback(callback, param,
+                                                       initialNotify);
+  SimRoboRioData[index].RegisterUserCurrent3V3Callback(callback, param,
+                                                       initialNotify);
+  SimRoboRioData[index].RegisterUserActive3V3Callback(callback, param,
+                                                      initialNotify);
+  SimRoboRioData[index].RegisterUserFaults6VCallback(callback, param,
+                                                     initialNotify);
+  SimRoboRioData[index].RegisterUserFaults5VCallback(callback, param,
+                                                     initialNotify);
+  SimRoboRioData[index].RegisterUserFaults3V3Callback(callback, param,
+                                                      initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/RoboRioDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/RoboRioDataInternal.h
new file mode 100644
index 0000000..01cf245
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/RoboRioDataInternal.h
@@ -0,0 +1,162 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/NotifyListenerVector.h"
+#include "MockData/RoboRioData.h"
+
+namespace hal {
+class RoboRioData {
+ public:
+  int32_t RegisterFPGAButtonCallback(HAL_NotifyCallback callback, void* param,
+                                     HAL_Bool initialNotify);
+  void CancelFPGAButtonCallback(int32_t uid);
+  void InvokeFPGAButtonCallback(HAL_Value value);
+  HAL_Bool GetFPGAButton();
+  void SetFPGAButton(HAL_Bool fPGAButton);
+
+  int32_t RegisterVInVoltageCallback(HAL_NotifyCallback callback, void* param,
+                                     HAL_Bool initialNotify);
+  void CancelVInVoltageCallback(int32_t uid);
+  void InvokeVInVoltageCallback(HAL_Value value);
+  double GetVInVoltage();
+  void SetVInVoltage(double vInVoltage);
+
+  int32_t RegisterVInCurrentCallback(HAL_NotifyCallback callback, void* param,
+                                     HAL_Bool initialNotify);
+  void CancelVInCurrentCallback(int32_t uid);
+  void InvokeVInCurrentCallback(HAL_Value value);
+  double GetVInCurrent();
+  void SetVInCurrent(double vInCurrent);
+
+  int32_t RegisterUserVoltage6VCallback(HAL_NotifyCallback callback,
+                                        void* param, HAL_Bool initialNotify);
+  void CancelUserVoltage6VCallback(int32_t uid);
+  void InvokeUserVoltage6VCallback(HAL_Value value);
+  double GetUserVoltage6V();
+  void SetUserVoltage6V(double userVoltage6V);
+
+  int32_t RegisterUserCurrent6VCallback(HAL_NotifyCallback callback,
+                                        void* param, HAL_Bool initialNotify);
+  void CancelUserCurrent6VCallback(int32_t uid);
+  void InvokeUserCurrent6VCallback(HAL_Value value);
+  double GetUserCurrent6V();
+  void SetUserCurrent6V(double userCurrent6V);
+
+  int32_t RegisterUserActive6VCallback(HAL_NotifyCallback callback, void* param,
+                                       HAL_Bool initialNotify);
+  void CancelUserActive6VCallback(int32_t uid);
+  void InvokeUserActive6VCallback(HAL_Value value);
+  HAL_Bool GetUserActive6V();
+  void SetUserActive6V(HAL_Bool userActive6V);
+
+  int32_t RegisterUserVoltage5VCallback(HAL_NotifyCallback callback,
+                                        void* param, HAL_Bool initialNotify);
+  void CancelUserVoltage5VCallback(int32_t uid);
+  void InvokeUserVoltage5VCallback(HAL_Value value);
+  double GetUserVoltage5V();
+  void SetUserVoltage5V(double userVoltage5V);
+
+  int32_t RegisterUserCurrent5VCallback(HAL_NotifyCallback callback,
+                                        void* param, HAL_Bool initialNotify);
+  void CancelUserCurrent5VCallback(int32_t uid);
+  void InvokeUserCurrent5VCallback(HAL_Value value);
+  double GetUserCurrent5V();
+  void SetUserCurrent5V(double userCurrent5V);
+
+  int32_t RegisterUserActive5VCallback(HAL_NotifyCallback callback, void* param,
+                                       HAL_Bool initialNotify);
+  void CancelUserActive5VCallback(int32_t uid);
+  void InvokeUserActive5VCallback(HAL_Value value);
+  HAL_Bool GetUserActive5V();
+  void SetUserActive5V(HAL_Bool userActive5V);
+
+  int32_t RegisterUserVoltage3V3Callback(HAL_NotifyCallback callback,
+                                         void* param, HAL_Bool initialNotify);
+  void CancelUserVoltage3V3Callback(int32_t uid);
+  void InvokeUserVoltage3V3Callback(HAL_Value value);
+  double GetUserVoltage3V3();
+  void SetUserVoltage3V3(double userVoltage3V3);
+
+  int32_t RegisterUserCurrent3V3Callback(HAL_NotifyCallback callback,
+                                         void* param, HAL_Bool initialNotify);
+  void CancelUserCurrent3V3Callback(int32_t uid);
+  void InvokeUserCurrent3V3Callback(HAL_Value value);
+  double GetUserCurrent3V3();
+  void SetUserCurrent3V3(double userCurrent3V3);
+
+  int32_t RegisterUserActive3V3Callback(HAL_NotifyCallback callback,
+                                        void* param, HAL_Bool initialNotify);
+  void CancelUserActive3V3Callback(int32_t uid);
+  void InvokeUserActive3V3Callback(HAL_Value value);
+  HAL_Bool GetUserActive3V3();
+  void SetUserActive3V3(HAL_Bool userActive3V3);
+
+  int32_t RegisterUserFaults6VCallback(HAL_NotifyCallback callback, void* param,
+                                       HAL_Bool initialNotify);
+  void CancelUserFaults6VCallback(int32_t uid);
+  void InvokeUserFaults6VCallback(HAL_Value value);
+  int32_t GetUserFaults6V();
+  void SetUserFaults6V(int32_t userFaults6V);
+
+  int32_t RegisterUserFaults5VCallback(HAL_NotifyCallback callback, void* param,
+                                       HAL_Bool initialNotify);
+  void CancelUserFaults5VCallback(int32_t uid);
+  void InvokeUserFaults5VCallback(HAL_Value value);
+  int32_t GetUserFaults5V();
+  void SetUserFaults5V(int32_t userFaults5V);
+
+  int32_t RegisterUserFaults3V3Callback(HAL_NotifyCallback callback,
+                                        void* param, HAL_Bool initialNotify);
+  void CancelUserFaults3V3Callback(int32_t uid);
+  void InvokeUserFaults3V3Callback(HAL_Value value);
+  int32_t GetUserFaults3V3();
+  void SetUserFaults3V3(int32_t userFaults3V3);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_fPGAButton{false};
+  std::shared_ptr<NotifyListenerVector> m_fPGAButtonCallbacks = nullptr;
+  std::atomic<double> m_vInVoltage{0.0};
+  std::shared_ptr<NotifyListenerVector> m_vInVoltageCallbacks = nullptr;
+  std::atomic<double> m_vInCurrent{0.0};
+  std::shared_ptr<NotifyListenerVector> m_vInCurrentCallbacks = nullptr;
+  std::atomic<double> m_userVoltage6V{6.0};
+  std::shared_ptr<NotifyListenerVector> m_userVoltage6VCallbacks = nullptr;
+  std::atomic<double> m_userCurrent6V{0.0};
+  std::shared_ptr<NotifyListenerVector> m_userCurrent6VCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_userActive6V{false};
+  std::shared_ptr<NotifyListenerVector> m_userActive6VCallbacks = nullptr;
+  std::atomic<double> m_userVoltage5V{5.0};
+  std::shared_ptr<NotifyListenerVector> m_userVoltage5VCallbacks = nullptr;
+  std::atomic<double> m_userCurrent5V{0.0};
+  std::shared_ptr<NotifyListenerVector> m_userCurrent5VCallbacks = nullptr;
+  std::atomic<HAL_Bool> m_userActive5V{false};
+  std::shared_ptr<NotifyListenerVector> m_userActive5VCallbacks = nullptr;
+  std::atomic<double> m_userVoltage3V3{3.3};
+  std::shared_ptr<NotifyListenerVector> m_userVoltage3V3Callbacks = nullptr;
+  std::atomic<double> m_userCurrent3V3{0.0};
+  std::shared_ptr<NotifyListenerVector> m_userCurrent3V3Callbacks = nullptr;
+  std::atomic<HAL_Bool> m_userActive3V3{false};
+  std::shared_ptr<NotifyListenerVector> m_userActive3V3Callbacks = nullptr;
+  std::atomic<int32_t> m_userFaults6V{0};
+  std::shared_ptr<NotifyListenerVector> m_userFaults6VCallbacks = nullptr;
+  std::atomic<int32_t> m_userFaults5V{0};
+  std::shared_ptr<NotifyListenerVector> m_userFaults5VCallbacks = nullptr;
+  std::atomic<int32_t> m_userFaults3V3{0};
+  std::shared_ptr<NotifyListenerVector> m_userFaults3V3Callbacks = nullptr;
+};
+extern RoboRioData* SimRoboRioData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/SPIAccelerometerData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/SPIAccelerometerData.cpp
new file mode 100644
index 0000000..ed13a3a
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/SPIAccelerometerData.cpp
@@ -0,0 +1,334 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "MockData/NotifyCallbackHelpers.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() {
+  m_active = false;
+  m_activeCallbacks = nullptr;
+  m_range = 0;
+  m_rangeCallbacks = nullptr;
+  m_x = 0.0;
+  m_xCallbacks = nullptr;
+  m_y = 0.0;
+  m_yCallbacks = nullptr;
+  m_z = 0.0;
+  m_zCallbacks = nullptr;
+}
+
+int32_t SPIAccelerometerData::RegisterActiveCallback(
+    HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_activeCallbacks =
+        RegisterCallback(m_activeCallbacks, "Active", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetActive());
+    callback("Active", param, &value);
+  }
+  return newUid;
+}
+
+void SPIAccelerometerData::CancelActiveCallback(int32_t uid) {
+  m_activeCallbacks = CancelCallback(m_activeCallbacks, uid);
+}
+
+void SPIAccelerometerData::InvokeActiveCallback(HAL_Value value) {
+  InvokeCallback(m_activeCallbacks, "Active", &value);
+}
+
+HAL_Bool SPIAccelerometerData::GetActive() { return m_active; }
+
+void SPIAccelerometerData::SetActive(HAL_Bool active) {
+  HAL_Bool oldValue = m_active.exchange(active);
+  if (oldValue != active) {
+    InvokeActiveCallback(MakeBoolean(active));
+  }
+}
+
+int32_t SPIAccelerometerData::RegisterRangeCallback(HAL_NotifyCallback callback,
+                                                    void* param,
+                                                    HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_rangeCallbacks =
+        RegisterCallback(m_rangeCallbacks, "Range", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeInt(GetRange());
+    callback("Range", param, &value);
+  }
+  return newUid;
+}
+
+void SPIAccelerometerData::CancelRangeCallback(int32_t uid) {
+  m_rangeCallbacks = CancelCallback(m_rangeCallbacks, uid);
+}
+
+void SPIAccelerometerData::InvokeRangeCallback(HAL_Value value) {
+  InvokeCallback(m_rangeCallbacks, "Range", &value);
+}
+
+int32_t SPIAccelerometerData::GetRange() { return m_range; }
+
+void SPIAccelerometerData::SetRange(int32_t range) {
+  int32_t oldValue = m_range.exchange(range);
+  if (oldValue != range) {
+    InvokeRangeCallback(MakeInt(range));
+  }
+}
+
+int32_t SPIAccelerometerData::RegisterXCallback(HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_xCallbacks =
+        RegisterCallback(m_xCallbacks, "X", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetX());
+    callback("X", param, &value);
+  }
+  return newUid;
+}
+
+void SPIAccelerometerData::CancelXCallback(int32_t uid) {
+  m_xCallbacks = CancelCallback(m_xCallbacks, uid);
+}
+
+void SPIAccelerometerData::InvokeXCallback(HAL_Value value) {
+  InvokeCallback(m_xCallbacks, "X", &value);
+}
+
+double SPIAccelerometerData::GetX() { return m_x; }
+
+void SPIAccelerometerData::SetX(double x) {
+  double oldValue = m_x.exchange(x);
+  if (oldValue != x) {
+    InvokeXCallback(MakeDouble(x));
+  }
+}
+
+int32_t SPIAccelerometerData::RegisterYCallback(HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_yCallbacks =
+        RegisterCallback(m_yCallbacks, "Y", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetY());
+    callback("Y", param, &value);
+  }
+  return newUid;
+}
+
+void SPIAccelerometerData::CancelYCallback(int32_t uid) {
+  m_yCallbacks = CancelCallback(m_yCallbacks, uid);
+}
+
+void SPIAccelerometerData::InvokeYCallback(HAL_Value value) {
+  InvokeCallback(m_yCallbacks, "Y", &value);
+}
+
+double SPIAccelerometerData::GetY() { return m_y; }
+
+void SPIAccelerometerData::SetY(double y) {
+  double oldValue = m_y.exchange(y);
+  if (oldValue != y) {
+    InvokeYCallback(MakeDouble(y));
+  }
+}
+
+int32_t SPIAccelerometerData::RegisterZCallback(HAL_NotifyCallback callback,
+                                                void* param,
+                                                HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_zCallbacks =
+        RegisterCallback(m_zCallbacks, "Z", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeDouble(GetZ());
+    callback("Z", param, &value);
+  }
+  return newUid;
+}
+
+void SPIAccelerometerData::CancelZCallback(int32_t uid) {
+  m_zCallbacks = CancelCallback(m_zCallbacks, uid);
+}
+
+void SPIAccelerometerData::InvokeZCallback(HAL_Value value) {
+  InvokeCallback(m_zCallbacks, "Z", &value);
+}
+
+double SPIAccelerometerData::GetZ() { return m_z; }
+
+void SPIAccelerometerData::SetZ(double z) {
+  double oldValue = m_z.exchange(z);
+  if (oldValue != z) {
+    InvokeZCallback(MakeDouble(z));
+  }
+}
+
+extern "C" {
+void HALSIM_ResetSPIAccelerometerData(int32_t index) {
+  SimSPIAccelerometerData[index].ResetData();
+}
+
+int32_t HALSIM_RegisterSPIAccelerometerActiveCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimSPIAccelerometerData[index].RegisterActiveCallback(callback, param,
+                                                               initialNotify);
+}
+
+void HALSIM_CancelSPIAccelerometerActiveCallback(int32_t index, int32_t uid) {
+  SimSPIAccelerometerData[index].CancelActiveCallback(uid);
+}
+
+HAL_Bool HALSIM_GetSPIAccelerometerActive(int32_t index) {
+  return SimSPIAccelerometerData[index].GetActive();
+}
+
+void HALSIM_SetSPIAccelerometerActive(int32_t index, HAL_Bool active) {
+  SimSPIAccelerometerData[index].SetActive(active);
+}
+
+int32_t HALSIM_RegisterSPIAccelerometerRangeCallback(
+    int32_t index, HAL_NotifyCallback callback, void* param,
+    HAL_Bool initialNotify) {
+  return SimSPIAccelerometerData[index].RegisterRangeCallback(callback, param,
+                                                              initialNotify);
+}
+
+void HALSIM_CancelSPIAccelerometerRangeCallback(int32_t index, int32_t uid) {
+  SimSPIAccelerometerData[index].CancelRangeCallback(uid);
+}
+
+int32_t HALSIM_GetSPIAccelerometerRange(int32_t index) {
+  return SimSPIAccelerometerData[index].GetRange();
+}
+
+void HALSIM_SetSPIAccelerometerRange(int32_t index, int32_t range) {
+  SimSPIAccelerometerData[index].SetRange(range);
+}
+
+int32_t HALSIM_RegisterSPIAccelerometerXCallback(int32_t index,
+                                                 HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  return SimSPIAccelerometerData[index].RegisterXCallback(callback, param,
+                                                          initialNotify);
+}
+
+void HALSIM_CancelSPIAccelerometerXCallback(int32_t index, int32_t uid) {
+  SimSPIAccelerometerData[index].CancelXCallback(uid);
+}
+
+double HALSIM_GetSPIAccelerometerX(int32_t index) {
+  return SimSPIAccelerometerData[index].GetX();
+}
+
+void HALSIM_SetSPIAccelerometerX(int32_t index, double x) {
+  SimSPIAccelerometerData[index].SetX(x);
+}
+
+int32_t HALSIM_RegisterSPIAccelerometerYCallback(int32_t index,
+                                                 HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  return SimSPIAccelerometerData[index].RegisterYCallback(callback, param,
+                                                          initialNotify);
+}
+
+void HALSIM_CancelSPIAccelerometerYCallback(int32_t index, int32_t uid) {
+  SimSPIAccelerometerData[index].CancelYCallback(uid);
+}
+
+double HALSIM_GetSPIAccelerometerY(int32_t index) {
+  return SimSPIAccelerometerData[index].GetY();
+}
+
+void HALSIM_SetSPIAccelerometerY(int32_t index, double y) {
+  SimSPIAccelerometerData[index].SetY(y);
+}
+
+int32_t HALSIM_RegisterSPIAccelerometerZCallback(int32_t index,
+                                                 HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  return SimSPIAccelerometerData[index].RegisterZCallback(callback, param,
+                                                          initialNotify);
+}
+
+void HALSIM_CancelSPIAccelerometerZCallback(int32_t index, int32_t uid) {
+  SimSPIAccelerometerData[index].CancelZCallback(uid);
+}
+
+double HALSIM_GetSPIAccelerometerZ(int32_t index) {
+  return SimSPIAccelerometerData[index].GetZ();
+}
+
+void HALSIM_SetSPIAccelerometerZ(int32_t index, double z) {
+  SimSPIAccelerometerData[index].SetZ(z);
+}
+
+void HALSIM_RegisterSPIAccelerometerAllCallbcaks(int32_t index,
+                                                 HAL_NotifyCallback callback,
+                                                 void* param,
+                                                 HAL_Bool initialNotify) {
+  SimSPIAccelerometerData[index].RegisterActiveCallback(callback, param,
+                                                        initialNotify);
+  SimSPIAccelerometerData[index].RegisterRangeCallback(callback, param,
+                                                       initialNotify);
+  SimSPIAccelerometerData[index].RegisterXCallback(callback, param,
+                                                   initialNotify);
+  SimSPIAccelerometerData[index].RegisterYCallback(callback, param,
+                                                   initialNotify);
+  SimSPIAccelerometerData[index].RegisterZCallback(callback, param,
+                                                   initialNotify);
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/SPIAccelerometerDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/SPIAccelerometerDataInternal.h
new file mode 100644
index 0000000..c0df5ba
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/SPIAccelerometerDataInternal.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
+
+#include <atomic>
+#include <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/NotifyListenerVector.h"
+#include "MockData/SPIAccelerometerData.h"
+
+namespace hal {
+class SPIAccelerometerData {
+ public:
+  int32_t RegisterActiveCallback(HAL_NotifyCallback callback, void* param,
+                                 HAL_Bool initialNotify);
+  void CancelActiveCallback(int32_t uid);
+  void InvokeActiveCallback(HAL_Value value);
+  HAL_Bool GetActive();
+  void SetActive(HAL_Bool active);
+
+  int32_t RegisterRangeCallback(HAL_NotifyCallback callback, void* param,
+                                HAL_Bool initialNotify);
+  void CancelRangeCallback(int32_t uid);
+  void InvokeRangeCallback(HAL_Value value);
+  int32_t GetRange();
+  void SetRange(int32_t range);
+
+  int32_t RegisterXCallback(HAL_NotifyCallback callback, void* param,
+                            HAL_Bool initialNotify);
+  void CancelXCallback(int32_t uid);
+  void InvokeXCallback(HAL_Value value);
+  double GetX();
+  void SetX(double x);
+
+  int32_t RegisterYCallback(HAL_NotifyCallback callback, void* param,
+                            HAL_Bool initialNotify);
+  void CancelYCallback(int32_t uid);
+  void InvokeYCallback(HAL_Value value);
+  double GetY();
+  void SetY(double y);
+
+  int32_t RegisterZCallback(HAL_NotifyCallback callback, void* param,
+                            HAL_Bool initialNotify);
+  void CancelZCallback(int32_t uid);
+  void InvokeZCallback(HAL_Value value);
+  double GetZ();
+  void SetZ(double z);
+
+  virtual void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  std::atomic<HAL_Bool> m_active{false};
+  std::shared_ptr<NotifyListenerVector> m_activeCallbacks = nullptr;
+  std::atomic<int32_t> m_range{0};
+  std::shared_ptr<NotifyListenerVector> m_rangeCallbacks = nullptr;
+  std::atomic<double> m_x{0.0};
+  std::shared_ptr<NotifyListenerVector> m_xCallbacks = nullptr;
+  std::atomic<double> m_y{0.0};
+  std::shared_ptr<NotifyListenerVector> m_yCallbacks = nullptr;
+  std::atomic<double> m_z{0.0};
+  std::shared_ptr<NotifyListenerVector> m_zCallbacks = nullptr;
+};
+extern SPIAccelerometerData* SimSPIAccelerometerData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/SPIData.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/SPIData.cpp
new file mode 100644
index 0000000..4fd29a0
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/SPIData.cpp
@@ -0,0 +1,228 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "MockData/NotifyCallbackHelpers.h"
+#include "SPIDataInternal.h"
+
+using namespace hal;
+
+void InvokeCallback(
+    std::shared_ptr<SpiAutoReceiveDataListenerVector> currentVector,
+    const char* name, uint8_t* buffer, int32_t numToRead,
+    int32_t* outputCount) {
+  // Return if no callbacks are assigned
+  if (currentVector == nullptr) return;
+  // Get a copy of the shared_ptr, then iterate and callback listeners
+  auto newCallbacks = currentVector;
+  for (size_t i = 0; i < newCallbacks->size(); ++i) {
+    if (!(*newCallbacks)[i]) continue;  // callback was removed
+    auto listener = (*newCallbacks)[i];
+    listener.callback(name, listener.param, buffer, numToRead, outputCount);
+  }
+}
+
+namespace hal {
+namespace init {
+void InitializeSPIData() {
+  static SPIData ssd[5];
+  ::hal::SimSPIData = ssd;
+}
+}  // namespace init
+}  // namespace hal
+
+SPIData* hal::SimSPIData;
+void SPIData::ResetData() {
+  m_initialized = false;
+  m_initializedCallbacks = nullptr;
+  m_readCallbacks = nullptr;
+  m_writeCallbacks = nullptr;
+  m_autoReceiveDataCallbacks = nullptr;
+}
+
+SPIData::SPIData() {}
+SPIData::~SPIData() {}
+
+int32_t SPIData::RegisterInitializedCallback(HAL_NotifyCallback callback,
+                                             void* param,
+                                             HAL_Bool initialNotify) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_initializedCallbacks = RegisterCallback(
+        m_initializedCallbacks, "Initialized", callback, param, &newUid);
+  }
+  if (initialNotify) {
+    // We know that the callback is not null because of earlier null check
+    HAL_Value value = MakeBoolean(GetInitialized());
+    callback("Initialized", param, &value);
+  }
+  return newUid;
+}
+
+void SPIData::CancelInitializedCallback(int32_t uid) {
+  m_initializedCallbacks = CancelCallback(m_initializedCallbacks, uid);
+}
+
+void SPIData::InvokeInitializedCallback(HAL_Value value) {
+  InvokeCallback(m_initializedCallbacks, "Initialized", &value);
+}
+
+HAL_Bool SPIData::GetInitialized() { return m_initialized; }
+
+void SPIData::SetInitialized(HAL_Bool initialized) {
+  HAL_Bool oldValue = m_initialized.exchange(initialized);
+  if (oldValue != initialized) {
+    InvokeInitializedCallback(MakeBoolean(initialized));
+  }
+}
+
+int32_t SPIData::RegisterReadCallback(HAL_BufferCallback callback,
+                                      void* param) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_readCallbacks =
+        RegisterCallback(m_readCallbacks, "Read", callback, param, &newUid);
+  }
+
+  return newUid;
+}
+
+void SPIData::CancelReadCallback(int32_t uid) {
+  m_readCallbacks = CancelCallback(m_readCallbacks, uid);
+}
+
+int32_t SPIData::RegisterWriteCallback(HAL_ConstBufferCallback callback,
+                                       void* param) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_writeCallbacks =
+        RegisterCallback(m_writeCallbacks, "Write", callback, param, &newUid);
+  }
+
+  return newUid;
+}
+
+void SPIData::CancelWriteCallback(int32_t uid) {
+  m_writeCallbacks = CancelCallback(m_writeCallbacks, uid);
+}
+
+int32_t SPIData::RegisterReadAutoReceivedDataCallback(
+    HAL_SpiReadAutoReceiveBufferCallback callback, void* param) {
+  // Must return -1 on a null callback for error handling
+  if (callback == nullptr) return -1;
+  int32_t newUid = 0;
+  {
+    std::lock_guard<wpi::mutex> lock(m_registerMutex);
+    m_autoReceiveDataCallbacks = RegisterCallbackImpl(
+        m_autoReceiveDataCallbacks, "AutoReceive", callback, param, &newUid);
+  }
+  return newUid;
+}
+
+void SPIData::CancelReadAutoReceivedDataCallback(int32_t uid) {
+  m_autoReceiveDataCallbacks =
+      CancelCallbackImpl<SpiAutoReceiveDataListenerVector,
+                         HAL_SpiReadAutoReceiveBufferCallback>(
+          m_autoReceiveDataCallbacks, uid);
+}
+
+int32_t SPIData::Read(uint8_t* buffer, int32_t count) {
+  std::lock_guard<wpi::mutex> lock(m_dataMutex);
+  InvokeCallback(m_readCallbacks, "Read", buffer, count);
+
+  return count;
+}
+
+int32_t SPIData::Write(const uint8_t* dataToSend, int32_t sendSize) {
+  std::lock_guard<wpi::mutex> lock(m_dataMutex);
+  InvokeCallback(m_writeCallbacks, "Write", const_cast<uint8_t*>(dataToSend),
+                 sendSize);
+
+  return sendSize;
+}
+
+int32_t SPIData::Transaction(const uint8_t* dataToSend, uint8_t* dataReceived,
+                             int32_t size) {
+  std::lock_guard<wpi::mutex> lock(m_dataMutex);
+  InvokeCallback(m_writeCallbacks, "Write", dataToSend, size);
+  InvokeCallback(m_readCallbacks, "Read", dataReceived, size);
+
+  return size;
+}
+
+int32_t SPIData::ReadAutoReceivedData(uint8_t* buffer, int32_t numToRead,
+                                      double timeout, int32_t* status) {
+  int32_t outputCount = 0;
+  InvokeCallback(m_autoReceiveDataCallbacks, "AutoReceive",
+                 const_cast<uint8_t*>(buffer), numToRead, &outputCount);
+
+  return outputCount;
+}
+
+extern "C" {
+void HALSIM_ResetSPIData(int32_t index) { SimSPIData[index].ResetData(); }
+
+int32_t HALSIM_RegisterSPIInitializedCallback(int32_t index,
+                                              HAL_NotifyCallback callback,
+                                              void* param,
+                                              HAL_Bool initialNotify) {
+  return SimSPIData[index].RegisterInitializedCallback(callback, param,
+                                                       initialNotify);
+}
+
+void HALSIM_CancelSPIInitializedCallback(int32_t index, int32_t uid) {
+  SimSPIData[index].CancelInitializedCallback(uid);
+}
+
+HAL_Bool HALSIM_GetSPIInitialized(int32_t index) {
+  return SimSPIData[index].GetInitialized();
+}
+
+void HALSIM_SetSPIInitialized(int32_t index, HAL_Bool initialized) {
+  SimSPIData[index].SetInitialized(initialized);
+}
+
+int32_t HALSIM_RegisterSPIReadCallback(int32_t index,
+                                       HAL_BufferCallback callback,
+                                       void* param) {
+  return SimSPIData[index].RegisterReadCallback(callback, param);
+}
+void HALSIM_CancelSPIReadCallback(int32_t index, int32_t uid) {
+  SimSPIData[index].CancelReadCallback(uid);
+}
+
+int32_t HALSIM_RegisterSPIWriteCallback(int32_t index,
+                                        HAL_ConstBufferCallback callback,
+                                        void* param) {
+  return SimSPIData[index].RegisterWriteCallback(callback, param);
+}
+void HALSIM_CancelSPIWriteCallback(int32_t index, int32_t uid) {
+  SimSPIData[index].CancelWriteCallback(uid);
+}
+
+int32_t HALSIM_RegisterSPIReadAutoReceivedDataCallback(
+    int32_t index, HAL_SpiReadAutoReceiveBufferCallback callback, void* param) {
+  return SimSPIData[index].RegisterReadAutoReceivedDataCallback(callback,
+                                                                param);
+}
+
+void HALSIM_CancelSPIReadAutoReceivedDataCallback(int32_t index, int32_t uid) {
+  SimSPIData[index].CancelReadAutoReceivedDataCallback(uid);
+}
+
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/SPIDataInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/SPIDataInternal.h
new file mode 100644
index 0000000..8f0180b
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockData/SPIDataInternal.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
+
+#include <atomic>
+#include <limits>
+#include <memory>
+
+#include <support/mutex.h>
+
+#include "MockData/NotifyListenerVector.h"
+#include "MockData/SPIData.h"
+
+namespace hal {
+
+typedef HalCallbackListenerVectorImpl<HAL_SpiReadAutoReceiveBufferCallback>
+    SpiAutoReceiveDataListenerVector;
+
+class SPIData {
+ public:
+  SPIData();
+  ~SPIData();
+
+  int32_t RegisterInitializedCallback(HAL_NotifyCallback callback, void* param,
+                                      HAL_Bool initialNotify);
+  void CancelInitializedCallback(int32_t uid);
+  void InvokeInitializedCallback(HAL_Value value);
+  HAL_Bool GetInitialized();
+  void SetInitialized(HAL_Bool initialized);
+
+  int32_t RegisterReadCallback(HAL_BufferCallback callback, void* param);
+  void CancelReadCallback(int32_t uid);
+
+  int32_t RegisterWriteCallback(HAL_ConstBufferCallback callback, void* param);
+  void CancelWriteCallback(int32_t uid);
+
+  int32_t RegisterReadAutoReceivedDataCallback(
+      HAL_SpiReadAutoReceiveBufferCallback callback, void* param);
+  void CancelReadAutoReceivedDataCallback(int32_t uid);
+
+  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(uint8_t* buffer, int32_t numToRead,
+                               double timeout, int32_t* status);
+
+  void ResetData();
+
+ private:
+  wpi::mutex m_registerMutex;
+  wpi::mutex m_dataMutex;
+  std::atomic<HAL_Bool> m_initialized{false};
+  std::shared_ptr<NotifyListenerVector> m_initializedCallbacks = nullptr;
+  std::shared_ptr<BufferListenerVector> m_readCallbacks = nullptr;
+  std::shared_ptr<ConstBufferListenerVector> m_writeCallbacks = nullptr;
+  std::shared_ptr<SpiAutoReceiveDataListenerVector> m_autoReceiveDataCallbacks =
+      nullptr;
+};
+extern SPIData* SimSPIData;
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockHooks.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/MockHooks.cpp
new file mode 100644
index 0000000..06ecce4
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/MockHooks.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 <atomic>
+#include <chrono>
+#include <cstdio>
+#include <thread>
+
+#include <support/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; }
+}  // 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(); }
+
+void HALSIM_RestartTiming(void) { RestartTiming(); }
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/MockHooksInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/MockHooksInternal.h
new file mode 100644
index 0000000..d7fd06f
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/sim/Notifier.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Notifier.cpp
new file mode 100644
index 0000000..264352d
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/Notifier.cpp
@@ -0,0 +1,155 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <support/condition_variable.h>
+#include <support/mutex.h>
+#include <support/timestamp.h>
+
+#include "HAL/HAL.h"
+#include "HAL/cpp/fpga_clock.h"
+#include "HAL/cpp/make_unique.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) {
+  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;
+    }
+
+    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/third_party/allwpilib_2018/hal/src/main/native/sim/OSSerialPort.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/OSSerialPort.cpp
new file mode 100644
index 0000000..b5060ff
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/OSSerialPort.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 "HAL/SerialPort.h"
+
+namespace hal {
+namespace init {
+void InitializeOSSerialPort() {}
+}  // namespace init
+}  // namespace hal
+
+extern "C" {
+void HAL_InitializeOSSerialPort(HAL_SerialPort port, int32_t* status) {}
+void HAL_SetOSSerialBaudRate(HAL_SerialPort port, int32_t baud,
+                             int32_t* status) {}
+void HAL_SetOSSerialDataBits(HAL_SerialPort port, int32_t bits,
+                             int32_t* status) {}
+void HAL_SetOSSerialParity(HAL_SerialPort port, int32_t parity,
+                           int32_t* status) {}
+void HAL_SetOSSerialStopBits(HAL_SerialPort port, int32_t stopBits,
+                             int32_t* status) {}
+void HAL_SetOSSerialWriteMode(HAL_SerialPort port, int32_t mode,
+                              int32_t* status) {}
+void HAL_SetOSSerialFlowControl(HAL_SerialPort port, int32_t flow,
+                                int32_t* status) {}
+void HAL_SetOSSerialTimeout(HAL_SerialPort port, double timeout,
+                            int32_t* status) {}
+void HAL_EnableOSSerialTermination(HAL_SerialPort port, char terminator,
+                                   int32_t* status) {}
+void HAL_DisableOSSerialTermination(HAL_SerialPort port, int32_t* status) {}
+void HAL_SetOSSerialReadBufferSize(HAL_SerialPort port, int32_t size,
+                                   int32_t* status) {}
+void HAL_SetOSSerialWriteBufferSize(HAL_SerialPort port, int32_t size,
+                                    int32_t* status) {}
+int32_t HAL_GetOSSerialBytesReceived(HAL_SerialPort port, int32_t* status) {
+  return 0;
+}
+int32_t HAL_ReadOSSerial(HAL_SerialPort port, char* buffer, int32_t count,
+                         int32_t* status) {
+  return 0;
+}
+int32_t HAL_WriteOSSerial(HAL_SerialPort port, const char* buffer,
+                          int32_t count, int32_t* status) {
+  return 0;
+}
+void HAL_FlushOSSerial(HAL_SerialPort port, int32_t* status) {}
+void HAL_ClearOSSerial(HAL_SerialPort port, int32_t* status) {}
+void HAL_CloseOSSerial(HAL_SerialPort port, int32_t* status) {}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/PDP.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/PDP.cpp
new file mode 100644
index 0000000..3b4b098
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/PDP.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 "HAL/PDP.h"
+
+#include "MockData/PDPDataInternal.h"
+#include "PortsInternal.h"
+
+using namespace hal;
+
+namespace hal {
+namespace init {
+void InitializePDP() {}
+}  // namespace init
+}  // namespace hal
+
+extern "C" {
+void HAL_InitializePDP(int32_t module, int32_t* status) {
+  SimPDPData[module].SetInitialized(true);
+}
+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(int32_t module, int32_t* status) {
+  return SimPDPData[module].GetTemperature();
+}
+double HAL_GetPDPVoltage(int32_t module, int32_t* status) {
+  return SimPDPData[module].GetVoltage();
+}
+double HAL_GetPDPChannelCurrent(int32_t module, int32_t channel,
+                                int32_t* status) {
+  return SimPDPData[module].GetCurrent(channel);
+}
+double HAL_GetPDPTotalCurrent(int32_t module, int32_t* status) { return 0.0; }
+double HAL_GetPDPTotalPower(int32_t module, int32_t* status) { return 0.0; }
+double HAL_GetPDPTotalEnergy(int32_t module, int32_t* status) { return 0.0; }
+void HAL_ResetPDPTotalEnergy(int32_t module, int32_t* status) {}
+void HAL_ClearPDPStickyFaults(int32_t module, int32_t* status) {}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/PWM.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/PWM.cpp
new file mode 100644
index 0000000..e5b6778
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/PWM.cpp
@@ -0,0 +1,357 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/handles/HandlesInternal.h"
+#include "MockData/PWMDataInternal.h"
+#include "PortsInternal.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) {
+  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].SetInitialized(true);
+
+  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].SetInitialized(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;
+}
+
+/**
+ * Set a PWM channel to the desired value. The values range from 0 to 255 and
+ * the period is controlled
+ * by the PWM Period and MinHigh registers.
+ *
+ * @param channel The PWM channel to set.
+ * @param value The PWM value to set.
+ */
+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].SetRawValue(value);
+}
+
+/**
+ * Set 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 channel The PWM channel to set.
+ * @param value The scaled PWM value to set.
+ */
+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].SetSpeed(speed);
+}
+
+/**
+ * Set 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 channel The PWM channel to set.
+ * @param value The scaled PWM value to set.
+ */
+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].SetPosition(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].SetRawValue(0);
+  SimPWMData[port->channel].SetPosition(0);
+  SimPWMData[port->channel].SetSpeed(0);
+}
+
+/**
+ * Get a value from a PWM channel. The values range from 0 to 255.
+ *
+ * @param channel The PWM channel to read from.
+ * @return The raw PWM value.
+ */
+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].GetRawValue();
+}
+
+/**
+ * Get a scaled value from a PWM channel. The values range from -1 to 1.
+ *
+ * @param channel The PWM channel to read from.
+ * @return The scaled PWM value.
+ */
+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].GetSpeed();
+  if (speed > 1) speed = 1;
+  if (speed < -1) speed = -1;
+  return speed;
+}
+
+/**
+ * Get a position value from a PWM channel. The values range from 0 to 1.
+ *
+ * @param channel The PWM channel to read from.
+ * @return The scaled PWM value.
+ */
+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].GetPosition();
+  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].SetZeroLatch(true);
+  SimPWMData[port->channel].SetZeroLatch(false);
+}
+
+/**
+ * Set how how often the PWM signal is squelched, thus scaling the period.
+ *
+ * @param channel The PWM channel to configure.
+ * @param squelchMask The 2-bit mask of outputs to squelch.
+ */
+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].SetPeriodScale(squelchMask);
+}
+
+/**
+ * Get the loop timing of the PWM system
+ *
+ * @return The loop time
+ */
+int32_t HAL_GetPWMLoopTiming(int32_t* status) { return kExpectedLoopTiming; }
+
+/**
+ * Get the pwm starting cycle time
+ *
+ * @return The pwm cycle start time.
+ */
+uint64_t HAL_GetPWMCycleStartTime(int32_t* status) { return 0; }
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/Ports.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Ports.cpp
new file mode 100644
index 0000000..d7454b5
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/sim/PortsInternal.h b/third_party/allwpilib_2018/hal/src/main/native/sim/PortsInternal.h
new file mode 100644
index 0000000..0b899f7
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/main/native/sim/Power.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Power.cpp
new file mode 100644
index 0000000..95ea752
--- /dev/null
+++ b/third_party/allwpilib_2018/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].GetVInVoltage();
+}
+double HAL_GetVinCurrent(int32_t* status) {
+  return SimRoboRioData[0].GetVInCurrent();
+}
+double HAL_GetUserVoltage6V(int32_t* status) {
+  return SimRoboRioData[0].GetUserVoltage6V();
+}
+double HAL_GetUserCurrent6V(int32_t* status) {
+  return SimRoboRioData[0].GetUserCurrent6V();
+}
+HAL_Bool HAL_GetUserActive6V(int32_t* status) {
+  return SimRoboRioData[0].GetUserActive6V();
+}
+int32_t HAL_GetUserCurrentFaults6V(int32_t* status) {
+  return SimRoboRioData[0].GetUserFaults6V();
+}
+double HAL_GetUserVoltage5V(int32_t* status) {
+  return SimRoboRioData[0].GetUserVoltage5V();
+}
+double HAL_GetUserCurrent5V(int32_t* status) {
+  return SimRoboRioData[0].GetUserCurrent5V();
+}
+HAL_Bool HAL_GetUserActive5V(int32_t* status) {
+  return SimRoboRioData[0].GetUserActive5V();
+}
+int32_t HAL_GetUserCurrentFaults5V(int32_t* status) {
+  return SimRoboRioData[0].GetUserFaults5V();
+}
+double HAL_GetUserVoltage3V3(int32_t* status) {
+  return SimRoboRioData[0].GetUserVoltage3V3();
+}
+double HAL_GetUserCurrent3V3(int32_t* status) {
+  return SimRoboRioData[0].GetUserCurrent3V3();
+}
+HAL_Bool HAL_GetUserActive3V3(int32_t* status) {
+  return SimRoboRioData[0].GetUserActive3V3();
+}
+int32_t HAL_GetUserCurrentFaults3V3(int32_t* status) {
+  return SimRoboRioData[0].GetUserFaults3V3();
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/Relay.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Relay.cpp
new file mode 100644
index 0000000..528579f
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/Relay.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 "HAL/Relay.h"
+
+#include "HAL/handles/IndexedHandleResource.h"
+#include "MockData/RelayDataInternal.h"
+#include "PortsInternal.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) {
+  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].SetInitializedReverse(true);
+  } else {
+    port->fwd = true;  // set to forward
+    SimRelayData[channel].SetInitializedForward(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].SetInitializedForward(false);
+  else
+    SimRelayData[port->channel].SetInitializedReverse(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].SetForward(on);
+  else
+    SimRelayData[port->channel].SetReverse(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].GetForward();
+  else
+    return SimRelayData[port->channel].GetReverse();
+}
+}  // extern "C"
diff --git a/third_party/allwpilib_2018/hal/src/main/native/sim/SPI.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/SPI.cpp
new file mode 100644
index 0000000..b60497d
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/SPI.cpp
@@ -0,0 +1,63 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "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) {
+  SimSPIData[port].SetInitialized(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].SetInitialized(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, uint8_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/third_party/allwpilib_2018/hal/src/main/native/sim/SerialPort.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/SerialPort.cpp
new file mode 100644
index 0000000..b44157a
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/SerialPort.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 "HAL/SerialPort.h"
+
+namespace hal {
+namespace init {
+void InitializeSerialPort() {}
+}  // namespace init
+}  // namespace hal
+
+extern "C" {
+void HAL_InitializeSerialPort(HAL_SerialPort port, 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/third_party/allwpilib_2018/hal/src/main/native/sim/Solenoid.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Solenoid.cpp
new file mode 100644
index 0000000..c227eea
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/main/native/sim/Solenoid.cpp
@@ -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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "HAL/Solenoid.h"
+
+#include "HAL/Errors.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "HAL/handles/IndexedHandleResource.h"
+#include "MockData/PCMDataInternal.h"
+#include "PortsInternal.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) {
+  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/third_party/allwpilib_2018/hal/src/main/native/sim/Threads.cpp b/third_party/allwpilib_2018/hal/src/main/native/sim/Threads.cpp
new file mode 100644
index 0000000..67ca4fe
--- /dev/null
+++ b/third_party/allwpilib_2018/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/third_party/allwpilib_2018/hal/src/test/native/cpp/HALTests.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/HALTests.cpp
new file mode 100644
index 0000000..615b6de
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "HAL/Solenoid.h"
+#include "gtest/gtest.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/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/AnalogInDataTests.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/AnalogInDataTests.cpp
new file mode 100644
index 0000000..9cf1c73
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/AnalogInput.h"
+#include "HAL/HAL.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "MockData/AnalogInData.h"
+#include "gtest/gtest.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/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/AnalogOutDataTests.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/AnalogOutDataTests.cpp
new file mode 100644
index 0000000..ffbf71a
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/AnalogOutput.h"
+#include "HAL/HAL.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "MockData/AnalogOutData.h"
+#include "gtest/gtest.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/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/DIODataTests.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/DIODataTests.cpp
new file mode 100644
index 0000000..3a86a07
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/DIO.h"
+#include "HAL/HAL.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "MockData/DIOData.h"
+#include "gtest/gtest.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/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/DriverStationDataTests.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/DriverStationDataTests.cpp
new file mode 100644
index 0000000..ef1b7e6
--- /dev/null
+++ b/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/DriverStationDataTests.cpp
@@ -0,0 +1,139 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "HAL/HAL.h"
+#include "HAL/Solenoid.h"
+#include "MockData/DriverStationData.h"
+#include "gtest/gtest.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;
+  info.eventName = const_cast<char*>(eventName.c_str());
+  info.gameSpecificMessage = const_cast<char*>(gameData.c_str());
+  info.matchNumber = 5;
+  info.matchType = HAL_MatchType::HAL_kMatchType_qualification;
+  info.replayNumber = 42;
+  HALSIM_SetMatchInfo(&info);
+
+  HAL_MatchInfo dataBack;
+  HAL_GetMatchInfo(&dataBack);
+
+  EXPECT_STREQ(eventName.c_str(), dataBack.eventName);
+  EXPECT_STREQ(gameData.c_str(), dataBack.gameSpecificMessage);
+  EXPECT_EQ(5, dataBack.matchNumber);
+  EXPECT_EQ(HAL_MatchType::HAL_kMatchType_qualification, dataBack.matchType);
+  EXPECT_EQ(42, dataBack.replayNumber);
+
+  HAL_FreeMatchInfo(&dataBack);
+}
+
+}  // namespace hal
diff --git a/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/I2CDataTests.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/I2CDataTests.cpp
new file mode 100644
index 0000000..11d01d1
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "HAL/I2C.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "MockData/I2CData.h"
+#include "gtest/gtest.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/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/PCMDataTests.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/PCMDataTests.cpp
new file mode 100644
index 0000000..ef7814f
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "HAL/Solenoid.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "MockData/PCMData.h"
+#include "gtest/gtest.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/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/PDPDataTests.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/PDPDataTests.cpp
new file mode 100644
index 0000000..e3fe139
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "HAL/PDP.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "MockData/PDPData.h"
+#include "gtest/gtest.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/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/PWMDataTests.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/PWMDataTests.cpp
new file mode 100644
index 0000000..a580b74
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "HAL/PWM.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "MockData/PWMData.h"
+#include "gtest/gtest.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/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/RelayDataTests.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/RelayDataTests.cpp
new file mode 100644
index 0000000..444d9c3
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "HAL/Relay.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "MockData/RelayData.h"
+#include "gtest/gtest.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/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/SPIDataTests.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/MockData/SPIDataTests.cpp
new file mode 100644
index 0000000..9aae6fa
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "HAL/SPI.h"
+#include "HAL/handles/HandlesInternal.h"
+#include "MockData/SPIData.h"
+#include "gtest/gtest.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/third_party/allwpilib_2018/hal/src/test/native/cpp/handles/HandleTests.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/handles/HandleTests.cpp
new file mode 100644
index 0000000..76d4ca1
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "HAL/handles/IndexedClassedHandleResource.h"
+#include "gtest/gtest.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/third_party/allwpilib_2018/hal/src/test/native/cpp/main.cpp b/third_party/allwpilib_2018/hal/src/test/native/cpp/main.cpp
new file mode 100644
index 0000000..a875f04
--- /dev/null
+++ b/third_party/allwpilib_2018/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 "HAL/HAL.h"
+#include "gtest/gtest.h"
+
+int main(int argc, char** argv) {
+  HAL_Initialize(500, 0);
+  ::testing::InitGoogleTest(&argc, argv);
+  int ret = RUN_ALL_TESTS();
+  return ret;
+}