Squashed 'third_party/allwpilib_2017/' content from commit 35ac87d

Change-Id: I7bb6f5556c30d3f5a092e68de0be9c710c60c9f4
git-subtree-dir: third_party/allwpilib_2017
git-subtree-split: 35ac87d6ff8b7f061c4f18c9ea316e5dccd4888a
diff --git a/hal/include/HAL/Accelerometer.h b/hal/include/HAL/Accelerometer.h
new file mode 100644
index 0000000..69bd85e
--- /dev/null
+++ b/hal/include/HAL/Accelerometer.h
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/AnalogAccumulator.h b/hal/include/HAL/AnalogAccumulator.h
new file mode 100644
index 0000000..35235f8
--- /dev/null
+++ b/hal/include/HAL/AnalogAccumulator.h
@@ -0,0 +1,36 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/AnalogGyro.h b/hal/include/HAL/AnalogGyro.h
new file mode 100644
index 0000000..d1c6aaf
--- /dev/null
+++ b/hal/include/HAL/AnalogGyro.h
@@ -0,0 +1,38 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/AnalogInput.h b/hal/include/HAL/AnalogInput.h
new file mode 100644
index 0000000..7cc07db
--- /dev/null
+++ b/hal/include/HAL/AnalogInput.h
@@ -0,0 +1,50 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/AnalogOutput.h b/hal/include/HAL/AnalogOutput.h
new file mode 100644
index 0000000..5607d5d
--- /dev/null
+++ b/hal/include/HAL/AnalogOutput.h
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/AnalogTrigger.h b/hal/include/HAL/AnalogTrigger.h
new file mode 100644
index 0000000..17ef929
--- /dev/null
+++ b/hal/include/HAL/AnalogTrigger.h
@@ -0,0 +1,47 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/CAN.h b/hal/include/HAL/CAN.h
new file mode 100644
index 0000000..67b34bb
--- /dev/null
+++ b/hal/include/HAL/CAN.h
@@ -0,0 +1,35 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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 "FRC_NetworkCommunication/CANSessionMux.h"
+
+void canTxSend(uint32_t arbID, uint8_t length,
+               int32_t period = CAN_SEND_PERIOD_NO_REPEAT);
+
+void canTxPackInt8(uint32_t arbID, uint8_t offset, uint8_t value);
+void canTxPackInt16(uint32_t arbID, uint8_t offset, uint16_t value);
+void canTxPackInt32(uint32_t arbID, uint8_t offset, uint32_t value);
+void canTxPackFXP16(uint32_t arbID, uint8_t offset, double value);
+void canTxPackFXP32(uint32_t arbID, uint8_t offset, double value);
+
+uint8_t canTxUnpackInt8(uint32_t arbID, uint8_t offset);
+uint32_t canTxUnpackInt32(uint32_t arbID, uint8_t offset);
+uint16_t canTxUnpackInt16(uint32_t arbID, uint8_t offset);
+double canTxUnpackFXP16(uint32_t arbID, uint8_t offset);
+double canTxUnpackFXP32(uint32_t arbID, uint8_t offset);
+
+bool canRxReceive(uint32_t arbID);
+
+uint8_t canRxUnpackInt8(uint32_t arbID, uint8_t offset);
+uint16_t canRxUnpackInt16(uint32_t arbID, uint8_t offset);
+uint32_t canRxUnpackInt32(uint32_t arbID, uint8_t offset);
+double canRxUnpackFXP16(uint32_t arbID, uint8_t offset);
+double canRxUnpackFXP32(uint32_t arbID, uint8_t offset);
diff --git a/hal/include/HAL/ChipObject.h b/hal/include/HAL/ChipObject.h
new file mode 100644
index 0000000..c45c01d
--- /dev/null
+++ b/hal/include/HAL/ChipObject.h
@@ -0,0 +1,46 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+
+#include <stdint.h>
+
+#include "FRC_FPGA_ChipObject/RoboRIO_FRC_ChipObject_Aliases.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/nInterfaceGlobals.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAI.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAO.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAccel.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAccumulator.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAlarm.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAnalogTrigger.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tBIST.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tCounter.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tDIO.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tDMA.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tEncoder.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tGlobal.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tInterrupt.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tPWM.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tPower.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tRelay.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tSPI.h"
+#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tSysWatchdog.h"
+#include "FRC_FPGA_ChipObject/tDMAChannelDescriptor.h"
+#include "FRC_FPGA_ChipObject/tDMAManager.h"
+#include "FRC_FPGA_ChipObject/tInterruptManager.h"
+#include "FRC_FPGA_ChipObject/tSystem.h"
+#include "FRC_FPGA_ChipObject/tSystemInterface.h"
+
+namespace hal {
+using namespace nFPGA;
+using namespace nRoboRIO_FPGANamespace;
+}  // namespace hal
+
+#pragma GCC diagnostic pop
diff --git a/hal/include/HAL/Compressor.h b/hal/include/HAL/Compressor.h
new file mode 100644
index 0000000..aea7211
--- /dev/null
+++ b/hal/include/HAL/Compressor.h
@@ -0,0 +1,48 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/Constants.h b/hal/include/HAL/Constants.h
new file mode 100644
index 0000000..b764ccc
--- /dev/null
+++ b/hal/include/HAL/Constants.h
@@ -0,0 +1,19 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/Counter.h b/hal/include/HAL/Counter.h
new file mode 100644
index 0000000..90b9cdc
--- /dev/null
+++ b/hal/include/HAL/Counter.h
@@ -0,0 +1,73 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/DIO.h b/hal/include/HAL/DIO.h
new file mode 100644
index 0000000..0348d76
--- /dev/null
+++ b/hal/include/HAL/DIO.h
@@ -0,0 +1,45 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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);
+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
+}
+#endif
diff --git a/hal/include/HAL/DriverStation.h b/hal/include/HAL/DriverStation.h
new file mode 100644
index 0000000..e2097f2
--- /dev/null
+++ b/hal/include/HAL/DriverStation.h
@@ -0,0 +1,122 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2013-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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,
+};
+
+/* 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;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+int32_t HAL_SetErrorData(const char* errors, int32_t errorsLength,
+                         int32_t waitMs);
+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);
+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);
+
+#ifndef HAL_USE_LABVIEW
+
+void HAL_WaitForDSData(void);
+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/hal/include/HAL/Encoder.h b/hal/include/HAL/Encoder.h
new file mode 100644
index 0000000..c86ca8e
--- /dev/null
+++ b/hal/include/HAL/Encoder.h
@@ -0,0 +1,79 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/Errors.h b/hal/include/HAL/Errors.h
new file mode 100644
index 0000000..a31fa9f
--- /dev/null
+++ b/hal/include/HAL/Errors.h
@@ -0,0 +1,117 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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/hal/include/HAL/HAL.h b/hal/include/HAL/HAL.h
new file mode 100644
index 0000000..73d2719
--- /dev/null
+++ b/hal/include/HAL/HAL.h
@@ -0,0 +1,85 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2013-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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/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 "FRC_NetworkCommunication/UsageReporting.h"
+#include "HAL/Types.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();
+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);
+
+int32_t HAL_Initialize(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
+}
+#endif
diff --git a/hal/include/HAL/I2C.h b/hal/include/HAL/I2C.h
new file mode 100644
index 0000000..3543f37
--- /dev/null
+++ b/hal/include/HAL/I2C.h
@@ -0,0 +1,27 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+
+void HAL_InitializeI2C(int32_t port, int32_t* status);
+int32_t HAL_TransactionI2C(int32_t port, int32_t deviceAddress,
+                           uint8_t* dataToSend, int32_t sendSize,
+                           uint8_t* dataReceived, int32_t receiveSize);
+int32_t HAL_WriteI2C(int32_t port, int32_t deviceAddress, uint8_t* dataToSend,
+                     int32_t sendSize);
+int32_t HAL_ReadI2C(int32_t port, int32_t deviceAddress, uint8_t* buffer,
+                    int32_t count);
+void HAL_CloseI2C(int32_t port);
+#ifdef __cplusplus
+}
+#endif
diff --git a/hal/include/HAL/Interrupts.h b/hal/include/HAL/Interrupts.h
new file mode 100644
index 0000000..af2fd7b
--- /dev/null
+++ b/hal/include/HAL/Interrupts.h
@@ -0,0 +1,50 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/LabVIEW/HAL.h b/hal/include/HAL/LabVIEW/HAL.h
new file mode 100644
index 0000000..722c251
--- /dev/null
+++ b/hal/include/HAL/LabVIEW/HAL.h
@@ -0,0 +1,14 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#define HAL_USE_LABVIEW
+
+#include "HAL/DriverStation.h"
+#include "HAL/HAL.h"
+#include "HAL/Types.h"
diff --git a/hal/include/HAL/Notifier.h b/hal/include/HAL/Notifier.h
new file mode 100644
index 0000000..4df1819
--- /dev/null
+++ b/hal/include/HAL/Notifier.h
@@ -0,0 +1,32 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+
+typedef void (*HAL_NotifierProcessFunction)(uint64_t currentTime,
+                                            HAL_NotifierHandle handle);
+
+HAL_NotifierHandle HAL_InitializeNotifier(HAL_NotifierProcessFunction process,
+                                          void* param, int32_t* status);
+HAL_NotifierHandle HAL_InitializeNotifierThreaded(
+    HAL_NotifierProcessFunction process, void* param, int32_t* status);
+void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status);
+void* HAL_GetNotifierParam(HAL_NotifierHandle notifierHandle, int32_t* status);
+void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
+                             uint64_t triggerTime, int32_t* status);
+void HAL_StopNotifierAlarm(HAL_NotifierHandle notifierHandle, int32_t* status);
+#ifdef __cplusplus
+}
+#endif
diff --git a/hal/include/HAL/OSSerialPort.h b/hal/include/HAL/OSSerialPort.h
new file mode 100644
index 0000000..21696cc
--- /dev/null
+++ b/hal/include/HAL/OSSerialPort.h
@@ -0,0 +1,50 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/PDP.h b/hal/include/HAL/PDP.h
new file mode 100644
index 0000000..e63bb7b
--- /dev/null
+++ b/hal/include/HAL/PDP.h
@@ -0,0 +1,32 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/PWM.h b/hal/include/HAL/PWM.h
new file mode 100644
index 0000000..6db7bdc
--- /dev/null
+++ b/hal/include/HAL/PWM.h
@@ -0,0 +1,55 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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_GetLoopTiming(int32_t* status);
+#ifdef __cplusplus
+}
+#endif
diff --git a/hal/include/HAL/Ports.h b/hal/include/HAL/Ports.h
new file mode 100644
index 0000000..afa691a
--- /dev/null
+++ b/hal/include/HAL/Ports.h
@@ -0,0 +1,36 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/Power.h b/hal/include/HAL/Power.h
new file mode 100644
index 0000000..da53f72
--- /dev/null
+++ b/hal/include/HAL/Power.h
@@ -0,0 +1,34 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/Relay.h b/hal/include/HAL/Relay.h
new file mode 100644
index 0000000..cc83799
--- /dev/null
+++ b/hal/include/HAL/Relay.h
@@ -0,0 +1,29 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/SPI.h b/hal/include/HAL/SPI.h
new file mode 100644
index 0000000..d29d9f3
--- /dev/null
+++ b/hal/include/HAL/SPI.h
@@ -0,0 +1,50 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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_InitializeSPI(int32_t port, int32_t* status);
+int32_t HAL_TransactionSPI(int32_t port, uint8_t* dataToSend,
+                           uint8_t* dataReceived, int32_t size);
+int32_t HAL_WriteSPI(int32_t port, uint8_t* dataToSend, int32_t sendSize);
+int32_t HAL_ReadSPI(int32_t port, uint8_t* buffer, int32_t count);
+void HAL_CloseSPI(int32_t port);
+void HAL_SetSPISpeed(int32_t port, int32_t speed);
+void HAL_SetSPIOpts(int32_t port, HAL_Bool msbFirst, HAL_Bool sampleOnTrailing,
+                    HAL_Bool clkIdleHigh);
+void HAL_SetSPIChipSelectActiveHigh(int32_t port, int32_t* status);
+void HAL_SetSPIChipSelectActiveLow(int32_t port, int32_t* status);
+int32_t HAL_GetSPIHandle(int32_t port);
+void HAL_SetSPIHandle(int32_t port, int32_t handle);
+
+void HAL_InitSPIAccumulator(int32_t port, int32_t period, int32_t cmd,
+                            int32_t xferSize, int32_t validMask,
+                            int32_t validValue, int32_t dataShift,
+                            int32_t dataSize, HAL_Bool isSigned,
+                            HAL_Bool bigEndian, int32_t* status);
+void HAL_FreeSPIAccumulator(int32_t port, int32_t* status);
+void HAL_ResetSPIAccumulator(int32_t port, int32_t* status);
+void HAL_SetSPIAccumulatorCenter(int32_t port, int32_t center, int32_t* status);
+void HAL_SetSPIAccumulatorDeadband(int32_t port, int32_t deadband,
+                                   int32_t* status);
+int32_t HAL_GetSPIAccumulatorLastValue(int32_t port, int32_t* status);
+int64_t HAL_GetSPIAccumulatorValue(int32_t port, int32_t* status);
+int64_t HAL_GetSPIAccumulatorCount(int32_t port, int32_t* status);
+double HAL_GetSPIAccumulatorAverage(int32_t port, int32_t* status);
+void HAL_GetSPIAccumulatorOutput(int32_t port, int64_t* value, int64_t* count,
+                                 int32_t* status);
+#ifdef __cplusplus
+}
+#endif
diff --git a/hal/include/HAL/SerialPort.h b/hal/include/HAL/SerialPort.h
new file mode 100644
index 0000000..3b5aa92
--- /dev/null
+++ b/hal/include/HAL/SerialPort.h
@@ -0,0 +1,50 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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
+}
+#endif
diff --git a/hal/include/HAL/Solenoid.h b/hal/include/HAL/Solenoid.h
new file mode 100644
index 0000000..f434592
--- /dev/null
+++ b/hal/include/HAL/Solenoid.h
@@ -0,0 +1,35 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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);
+#ifdef __cplusplus
+}
+#endif
diff --git a/hal/include/HAL/Threads.h b/hal/include/HAL/Threads.h
new file mode 100644
index 0000000..8fe5578
--- /dev/null
+++ b/hal/include/HAL/Threads.h
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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"
+
+#ifdef _WIN32
+#include <windows.h>
+#define NativeThreadHandle const HANDLE*
+#else
+#include <pthread.h>
+#define NativeThreadHandle const pthread_t*
+#endif
+
+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);
+}
diff --git a/hal/include/HAL/Types.h b/hal/include/HAL/Types.h
new file mode 100644
index 0000000..3b91159
--- /dev/null
+++ b/hal/include/HAL/Types.h
@@ -0,0 +1,46 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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/hal/include/HAL/cpp/Log.h b/hal/include/HAL/cpp/Log.h
new file mode 100644
index 0000000..4ddbd4f
--- /dev/null
+++ b/hal/include/HAL/cpp/Log.h
@@ -0,0 +1,111 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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 <iomanip>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+inline std::string NowTime();
+
+enum TLogLevel {
+  logNONE,
+  logERROR,
+  logWARNING,
+  logINFO,
+  logDEBUG,
+  logDEBUG1,
+  logDEBUG2,
+  logDEBUG3,
+  logDEBUG4
+};
+
+class Log {
+ public:
+  Log();
+  virtual ~Log();
+  std::ostringstream& Get(TLogLevel level = logINFO);
+
+ public:
+  static TLogLevel& ReportingLevel();
+  static std::string ToString(TLogLevel level);
+  static TLogLevel FromString(const std::string& level);
+
+ protected:
+  std::ostringstream os;
+
+ private:
+  Log(const Log&);
+  Log& operator=(const Log&);
+};
+
+inline Log::Log() {}
+
+inline std::ostringstream& Log::Get(TLogLevel level) {
+  os << "- " << NowTime();
+  os << " " << ToString(level) << ": ";
+  os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
+  return os;
+}
+
+inline Log::~Log() {
+  os << std::endl;
+  std::cerr << os.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() {
+  std::stringstream ss;
+  ss << std::setfill('0') << std::setw(2);
+
+  using namespace std::chrono;
+  auto now = system_clock::now().time_since_epoch();
+
+  ss << duration_cast<hours>(now).count() % 24 << ":"
+     << duration_cast<minutes>(now).count() % 60 << ":"
+     << duration_cast<seconds>(now).count() % 60 << "."
+     << duration_cast<milliseconds>(now).count() % 1000;
+
+  return ss.str();
+}
diff --git a/hal/include/HAL/cpp/Semaphore.h b/hal/include/HAL/cpp/Semaphore.h
new file mode 100644
index 0000000..53e17d7
--- /dev/null
+++ b/hal/include/HAL/cpp/Semaphore.h
@@ -0,0 +1,41 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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 <condition_variable>
+
+#include "HAL/cpp/priority_mutex.h"
+#include "support/deprecated.h"
+
+class WPI_DEPRECATED(
+    "Semaphore scheduled for removal in 2018. Recommended to replace with a "
+    "std::mutex and std::condition_variable") Semaphore {
+ public:
+  explicit Semaphore(int32_t count = 0);
+  Semaphore(Semaphore&&);
+  Semaphore& operator=(Semaphore&&);
+
+  void give();
+  void take();
+
+  // @return true if semaphore was locked successfully. false if not.
+  bool tryTake();
+
+  static const int32_t kNoWait = 0;
+  static const int32_t kWaitForever = -1;
+
+  static const int32_t kEmpty = 0;
+  static const int32_t kFull = 1;
+
+ private:
+  priority_mutex m_mutex;
+  std::condition_variable_any m_condition;
+  int32_t m_count = 0;
+};
diff --git a/hal/include/HAL/cpp/SerialHelper.h b/hal/include/HAL/cpp/SerialHelper.h
new file mode 100644
index 0000000..f416818
--- /dev/null
+++ b/hal/include/HAL/cpp/SerialHelper.h
@@ -0,0 +1,51 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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 "HAL/SerialPort.h"
+#include "HAL/cpp/priority_mutex.h"
+#include "llvm/SmallString.h"
+#include "llvm/SmallVector.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 priority_mutex m_nameMutex;
+  static std::string m_usbNames[2];
+};
+}  // namespace hal
diff --git a/hal/include/HAL/cpp/make_unique.h b/hal/include/HAL/cpp/make_unique.h
new file mode 100644
index 0000000..d70f873
--- /dev/null
+++ b/hal/include/HAL/cpp/make_unique.h
@@ -0,0 +1,47 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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/hal/include/HAL/cpp/priority_condition_variable.h b/hal/include/HAL/cpp/priority_condition_variable.h
new file mode 100644
index 0000000..12aeba9
--- /dev/null
+++ b/hal/include/HAL/cpp/priority_condition_variable.h
@@ -0,0 +1,132 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+/* std::condition_variable provides the native_handle() method to return its
+ * underlying pthread_cond_t*. WPILib uses this to interface with the FRC
+ * network communication library. Since WPILib uses a custom mutex class and
+ * not std::mutex, std::condition_variable_any must be used instead.
+ * std::condition_variable_any doesn't expose its internal handle, so this
+ * class provides the same interface and implementation in addition to a
+ * native_handle() method.
+ */
+
+#include <condition_variable>
+#include <memory>
+#include <utility>
+
+#include "priority_mutex.h"
+
+class priority_condition_variable {
+  typedef std::chrono::system_clock clock;
+
+ public:
+  typedef std::condition_variable::native_handle_type native_handle_type;
+
+  priority_condition_variable() : m_mutex(std::make_shared<std::mutex>()) {}
+  ~priority_condition_variable() = default;
+
+  priority_condition_variable(const priority_condition_variable&) = delete;
+  priority_condition_variable& operator=(const priority_condition_variable&) =
+      delete;
+
+  void notify_one() noexcept {
+    std::lock_guard<std::mutex> lock(*m_mutex);
+    m_cond.notify_one();
+  }
+
+  void notify_all() noexcept {
+    std::lock_guard<std::mutex> lock(*m_mutex);
+    m_cond.notify_all();
+  }
+
+  template <typename Lock>
+  void wait(Lock& _lock) {
+    std::shared_ptr<std::mutex> _mutex = m_mutex;
+    std::unique_lock<std::mutex> my_lock(*_mutex);
+    Unlock<Lock> unlock(_lock);
+
+    // *mutex must be unlocked before re-locking _lock so move
+    // ownership of *_mutex lock to an object with shorter lifetime.
+    std::unique_lock<std::mutex> my_lock2(std::move(my_lock));
+    m_cond.wait(my_lock2);
+  }
+
+  template <typename Lock, typename Predicate>
+  void wait(Lock& lock, Predicate p) {
+    while (!p()) {
+      wait(lock);
+    }
+  }
+
+  template <typename Lock, typename Clock, typename Duration>
+  std::cv_status wait_until(
+      Lock& _lock, const std::chrono::time_point<Clock, Duration>& atime) {
+    std::shared_ptr<std::mutex> _mutex = m_mutex;
+    std::unique_lock<std::mutex> my_lock(*_mutex);
+    Unlock<Lock> unlock(_lock);
+
+    // *_mutex must be unlocked before re-locking _lock so move
+    // ownership of *_mutex lock to an object with shorter lifetime.
+    std::unique_lock<std::mutex> my_lock2(std::move(my_lock));
+    return m_cond.wait_until(my_lock2, atime);
+  }
+
+  template <typename Lock, typename Clock, typename Duration,
+            typename Predicate>
+  bool wait_until(Lock& lock,
+                  const std::chrono::time_point<Clock, Duration>& atime,
+                  Predicate p) {
+    while (!p()) {
+      if (wait_until(lock, atime) == std::cv_status::timeout) {
+        return p();
+      }
+    }
+    return true;
+  }
+
+  template <typename Lock, typename Rep, typename Period>
+  std::cv_status wait_for(Lock& lock,
+                          const std::chrono::duration<Rep, Period>& rtime) {
+    return wait_until(lock, clock::now() + rtime);
+  }
+
+  template <typename Lock, typename Rep, typename Period, typename Predicate>
+  bool wait_for(Lock& lock, const std::chrono::duration<Rep, Period>& rtime,
+                Predicate p) {
+    return wait_until(lock, clock::now() + rtime, std::move(p));
+  }
+
+  native_handle_type native_handle() { return m_cond.native_handle(); }
+
+ private:
+  std::condition_variable m_cond;
+  std::shared_ptr<std::mutex> m_mutex;
+
+  // scoped unlock - unlocks in ctor, re-locks in dtor
+  template <typename Lock>
+  struct Unlock {
+    explicit Unlock(Lock& lk) : m_lock(lk) { lk.unlock(); }
+
+    ~Unlock() /*noexcept(false)*/ {
+      if (std::uncaught_exception()) {
+        try {
+          m_lock.lock();
+        } catch (...) {
+        }
+      } else {
+        m_lock.lock();
+      }
+    }
+
+    Unlock(const Unlock&) = delete;
+    Unlock& operator=(const Unlock&) = delete;
+
+    Lock& m_lock;
+  };
+};
diff --git a/hal/include/HAL/cpp/priority_mutex.h b/hal/include/HAL/cpp/priority_mutex.h
new file mode 100644
index 0000000..c156bed
--- /dev/null
+++ b/hal/include/HAL/cpp/priority_mutex.h
@@ -0,0 +1,81 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+// Allows usage with std::lock_guard without including <mutex> separately
+#include <mutex>
+
+#if defined(FRC_SIMULATOR) || defined(_WIN32)
+// We do not want to use pthreads if in the simulator; however, in the
+// simulator, we do not care about priority inversion.
+typedef std::mutex priority_mutex;
+typedef std::recursive_mutex priority_recursive_mutex;
+#else  // Covers rest of file.
+
+#include <pthread.h>
+
+class priority_recursive_mutex {
+ public:
+  typedef pthread_mutex_t* native_handle_type;
+
+  constexpr priority_recursive_mutex() noexcept = default;
+  priority_recursive_mutex(const priority_recursive_mutex&) = delete;
+  priority_recursive_mutex& operator=(const priority_recursive_mutex&) = delete;
+
+  // Lock the mutex, blocking until it's available.
+  void lock();
+
+  // Unlock the mutex.
+  void unlock();
+
+  // Tries to lock the mutex.
+  bool try_lock() noexcept;
+
+  pthread_mutex_t* native_handle();
+
+ private:
+// Do the equivalent of setting PTHREAD_PRIO_INHERIT and
+// PTHREAD_MUTEX_RECURSIVE_NP.
+#if __WORDSIZE == 64
+  pthread_mutex_t m_mutex = {
+      {0, 0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, 0, {0, 0}}};
+#else
+  pthread_mutex_t m_mutex = {
+      {0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, {0}}};
+#endif
+};
+
+class priority_mutex {
+ public:
+  typedef pthread_mutex_t* native_handle_type;
+
+  constexpr priority_mutex() noexcept = default;
+  priority_mutex(const priority_mutex&) = delete;
+  priority_mutex& operator=(const priority_mutex&) = delete;
+
+  // Lock the mutex, blocking until it's available.
+  void lock();
+
+  // Unlock the mutex.
+  void unlock();
+
+  // Tries to lock the mutex.
+  bool try_lock() noexcept;
+
+  pthread_mutex_t* native_handle();
+
+ private:
+// Do the equivalent of setting PTHREAD_PRIO_INHERIT.
+#if __WORDSIZE == 64
+  pthread_mutex_t m_mutex = {{0, 0, 0, 0, 0x20, 0, 0, {0, 0}}};
+#else
+  pthread_mutex_t m_mutex = {{0, 0, 0, 0x20, 0, {0}}};
+#endif
+};
+
+#endif  // FRC_SIMULATOR
diff --git a/hal/include/HAL/handles/DigitalHandleResource.h b/hal/include/HAL/handles/DigitalHandleResource.h
new file mode 100644
index 0000000..653011e
--- /dev/null
+++ b/hal/include/HAL/handles/DigitalHandleResource.h
@@ -0,0 +1,95 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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 "HAL/Errors.h"
+#include "HAL/Types.h"
+#include "HAL/cpp/make_unique.h"
+#include "HAL/cpp/priority_mutex.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 {
+  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);
+
+ private:
+  std::array<std::shared_ptr<TStruct>, size> m_structures;
+  std::array<priority_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<priority_mutex> sync(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));
+}
+
+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);
+  if (index < 0 || index >= size) {
+    return nullptr;
+  }
+  std::lock_guard<priority_mutex> sync(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);
+  if (index < 0 || index >= size) return;
+  // lock and deallocated handle
+  std::lock_guard<priority_mutex> sync(m_handleMutexes[index]);
+  m_structures[index].reset();
+}
+}  // namespace hal
diff --git a/hal/include/HAL/handles/HandlesInternal.h b/hal/include/HAL/handles/HandlesInternal.h
new file mode 100644
index 0000000..27596dc
--- /dev/null
+++ b/hal/include/HAL/handles/HandlesInternal.h
@@ -0,0 +1,98 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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: Unused
+ * 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 {
+
+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 int16_t getHandleTypedIndex(HAL_Handle handle,
+                                          HAL_HandleEnum enumType) {
+  if (!isHandleType(handle, enumType)) return InvalidHandleIndex;
+  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);
+}  // namespace hal
diff --git a/hal/include/HAL/handles/IndexedClassedHandleResource.h b/hal/include/HAL/handles/IndexedClassedHandleResource.h
new file mode 100644
index 0000000..0f69b1d
--- /dev/null
+++ b/hal/include/HAL/handles/IndexedClassedHandleResource.h
@@ -0,0 +1,112 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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 <vector>
+
+#include "HAL/Errors.h"
+#include "HAL/Types.h"
+#include "HAL/cpp/make_unique.h"
+#include "HAL/cpp/priority_mutex.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 {
+  friend class IndexedClassedHandleResourceTest;
+
+ public:
+  IndexedClassedHandleResource();
+  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);
+
+ private:
+  // Dynamic array to shrink HAL file size.
+  std::unique_ptr<std::shared_ptr<TStruct>[]> m_structures;
+  std::unique_ptr<priority_mutex[]> m_handleMutexes;
+};
+
+template <typename THandle, typename TStruct, int16_t size,
+          HAL_HandleEnum enumValue>
+IndexedClassedHandleResource<THandle, TStruct, size,
+                             enumValue>::IndexedClassedHandleResource() {
+  m_structures = std::make_unique<std::shared_ptr<TStruct>[]>(size);
+  m_handleMutexes = std::make_unique<priority_mutex[]>(size);
+}
+
+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<priority_mutex> sync(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));
+}
+
+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);
+  if (index < 0 || index >= size) {
+    return nullptr;
+  }
+  std::lock_guard<priority_mutex> sync(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);
+  if (index < 0 || index >= size) return;
+  // lock and deallocated handle
+  std::lock_guard<priority_mutex> sync(m_handleMutexes[index]);
+  m_structures[index].reset();
+}
+}  // namespace hal
diff --git a/hal/include/HAL/handles/IndexedHandleResource.h b/hal/include/HAL/handles/IndexedHandleResource.h
new file mode 100644
index 0000000..cfe0668
--- /dev/null
+++ b/hal/include/HAL/handles/IndexedHandleResource.h
@@ -0,0 +1,99 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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 "HAL/Errors.h"
+#include "HAL/Types.h"
+#include "HAL/cpp/make_unique.h"
+#include "HAL/cpp/priority_mutex.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 {
+  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);
+
+ private:
+  std::array<std::shared_ptr<TStruct>, size> m_structures;
+  std::array<priority_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<priority_mutex> sync(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));
+}
+
+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);
+  if (index < 0 || index >= size) {
+    return nullptr;
+  }
+  std::lock_guard<priority_mutex> sync(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);
+  if (index < 0 || index >= size) return;
+  // lock and deallocated handle
+  std::lock_guard<priority_mutex> sync(m_handleMutexes[index]);
+  m_structures[index].reset();
+}
+}  // namespace hal
diff --git a/hal/include/HAL/handles/LimitedClassedHandleResource.h b/hal/include/HAL/handles/LimitedClassedHandleResource.h
new file mode 100644
index 0000000..178bf1d
--- /dev/null
+++ b/hal/include/HAL/handles/LimitedClassedHandleResource.h
@@ -0,0 +1,101 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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 "HAL/Types.h"
+#include "HAL/cpp/make_unique.h"
+#include "HAL/cpp/priority_mutex.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 {
+  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);
+
+ private:
+  std::array<std::shared_ptr<TStruct>, size> m_structures;
+  std::array<priority_mutex, size> m_handleMutexes;
+  priority_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<priority_mutex> sync(m_allocateMutex);
+  int16_t i;
+  for (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<priority_mutex> sync(m_handleMutexes[i]);
+      m_structures[i] = toSet;
+      return static_cast<THandle>(createHandle(i, enumValue));
+    }
+  }
+  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);
+  if (index < 0 || index >= size) {
+    return nullptr;
+  }
+  std::lock_guard<priority_mutex> sync(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);
+  if (index < 0 || index >= size) return;
+  // lock and deallocated handle
+  std::lock_guard<priority_mutex> sync(m_allocateMutex);
+  std::lock_guard<priority_mutex> lock(m_handleMutexes[index]);
+  m_structures[index].reset();
+}
+}  // namespace hal
diff --git a/hal/include/HAL/handles/LimitedHandleResource.h b/hal/include/HAL/handles/LimitedHandleResource.h
new file mode 100644
index 0000000..522328e
--- /dev/null
+++ b/hal/include/HAL/handles/LimitedHandleResource.h
@@ -0,0 +1,97 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2016-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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 "HAL/Types.h"
+#include "HAL/cpp/make_unique.h"
+#include "HAL/cpp/priority_mutex.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 {
+  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);
+
+ private:
+  std::array<std::shared_ptr<TStruct>, size> m_structures;
+  std::array<priority_mutex, size> m_handleMutexes;
+  priority_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<priority_mutex> sync(m_allocateMutex);
+  int16_t i;
+  for (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<priority_mutex> sync(m_handleMutexes[i]);
+      m_structures[i] = std::make_shared<TStruct>();
+      return static_cast<THandle>(createHandle(i, enumValue));
+    }
+  }
+  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);
+  if (index < 0 || index >= size) {
+    return nullptr;
+  }
+  std::lock_guard<priority_mutex> sync(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);
+  if (index < 0 || index >= size) return;
+  // lock and deallocated handle
+  std::lock_guard<priority_mutex> sync(m_allocateMutex);
+  std::lock_guard<priority_mutex> lock(m_handleMutexes[index]);
+  m_structures[index].reset();
+}
+}  // namespace hal
diff --git a/hal/include/HAL/handles/UnlimitedHandleResource.h b/hal/include/HAL/handles/UnlimitedHandleResource.h
new file mode 100644
index 0000000..ab77914
--- /dev/null
+++ b/hal/include/HAL/handles/UnlimitedHandleResource.h
@@ -0,0 +1,88 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008-2017. All Rights Reserved.                        */
+/* Open Source Software - may be modified and 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 <vector>
+
+#include "HAL/Types.h"
+#include "HAL/cpp/priority_mutex.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 {
+  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);
+  void Free(THandle handle);
+
+ private:
+  std::vector<std::shared_ptr<TStruct>> m_structures;
+  priority_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<priority_mutex> sync(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));
+    }
+  }
+  if (i >= INT16_MAX) return HAL_kInvalidHandle;
+
+  m_structures.push_back(structure);
+  return static_cast<THandle>(createHandle(static_cast<int16_t>(i), enumValue));
+}
+
+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);
+  std::lock_guard<priority_mutex> sync(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>
+void UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(
+    THandle handle) {
+  int16_t index = getHandleTypedIndex(handle, enumValue);
+  std::lock_guard<priority_mutex> sync(m_handleMutex);
+  if (index < 0 || index >= static_cast<int16_t>(m_structures.size())) return;
+  m_structures[index].reset();
+}
+}  // namespace hal
diff --git a/hal/include/ctre/CtreCanNode.h b/hal/include/ctre/CtreCanNode.h
new file mode 100644
index 0000000..2707598
--- /dev/null
+++ b/hal/include/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/hal/include/ctre/PCM.h b/hal/include/ctre/PCM.h
new file mode 100644
index 0000000..03d9b2d
--- /dev/null
+++ b/hal/include/ctre/PCM.h
@@ -0,0 +1,226 @@
+#ifndef PCM_H_

+#define PCM_H_

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

+#include "CtreCanNode.h"

+class PCM : public CtreCanNode

+{

+public:

+    PCM(UINT8 deviceNumber=0);

+    ~PCM();

+

+    /* Set PCM solenoid state

+     *

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

+     * @Param 	-	idx			- 	ID of solenoid (0-7)

+     * @Param 	-	en			- 	Enable / Disable identified solenoid

+     */

+    CTR_Code 	SetSolenoid(unsigned char idx, bool en);

+

+    /* Set all PCM solenoid states

+     *

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

+     * @Param 	-	state			Bitfield to set all solenoids to

+     */

+    CTR_Code 	SetAllSolenoids(UINT8 state);

+

+    /* Enables PCM Closed Loop Control of Compressor via pressure switch

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

+     * @Param 	-	en		- 	Enable / Disable Closed Loop Control

+     */

+    CTR_Code 	SetClosedLoopControl(bool en);

+

+    /* Clears PCM sticky faults (indicators of past faults

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

+     */

+    CTR_Code 	ClearStickyFaults();

+

+    /* Get solenoid state

+     *

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

+     * @Param 	-	idx		- 	ID of solenoid (0-7) to return if solenoid is on.

+     * @Param	-	status	-	true if solenoid enabled, false otherwise

+     */

+    CTR_Code 	GetSolenoid(UINT8 idx, bool &status);

+

+    /* Get state of all solenoids

+     *

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

+     * @Param	-	status	-	bitfield of solenoid states

+     */

+    CTR_Code 	GetAllSolenoids(UINT8 &status);

+

+    /* Get pressure switch state

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

+     * @Param	-	status		-	True if pressure adequate, false if low

+     */

+    CTR_Code 	GetPressure(bool &status);

+

+    /* Get compressor state

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

+     * @Param	-	status		-	True if compress ouput is on, false if otherwise

+     */

+    CTR_Code	GetCompressor(bool &status);

+

+    /* Get closed loop control state

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

+     * @Param	-	status	-	True if closed loop enabled, false if otherwise

+     */

+    CTR_Code 	GetClosedLoopControl(bool &status);

+

+    /* Get compressor current draw

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

+     * @Param	-	status		-	Compressor current returned in Amperes (A)

+     */

+    CTR_Code 	GetCompressorCurrent(float &status);

+

+    /* Get voltage across solenoid rail

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

+     * @Param	-	status		-	Voltage across solenoid rail in Volts (V)

+     */

+    CTR_Code 	GetSolenoidVoltage(float &status);

+

+    /* Get hardware fault value

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

+     * @Param	-	status		-	True if hardware failure detected, false if otherwise

+     */

+    CTR_Code 	GetHardwareFault(bool &status);

+

+    /* Get compressor fault value

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

+     * @Param	-	status		-	True if abnormally high compressor current detected, false if otherwise

+     */

+    CTR_Code 	GetCompressorCurrentTooHighFault(bool &status);

+

+    /* Get solenoid fault value

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

+     * @Param	-	status		-	True if shorted solenoid detected, false if otherwise

+     */

+    CTR_Code 	GetSolenoidFault(bool &status);

+

+    /* Get compressor sticky fault value

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

+     * @Param	-	status		-	True if solenoid had previously been shorted

+     * 								(and sticky fault was not cleared), false if otherwise

+     */

+    CTR_Code 	GetCompressorCurrentTooHighStickyFault(bool &status);

+    /* Get compressor shorted sticky fault value

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

+     * @Param	-	status		-	True if compressor output is shorted, false if otherwise

+     */

+    CTR_Code 	GetCompressorShortedStickyFault(bool &status);

+    /* Get compressor shorted fault value

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

+     * @Param	-	status		-	True if compressor output is shorted, false if otherwise

+     */

+    CTR_Code 	GetCompressorShortedFault(bool &status);

+    /* Get compressor is not connected sticky fault value

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

+     * @Param	-	status		-	True if compressor current is too low,

+     * 					indicating compressor is not connected, false if otherwise

+     */

+    CTR_Code 	GetCompressorNotConnectedStickyFault(bool &status);

+    /* Get compressor is not connected fault value

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

+     * @Param	-	status		-	True if compressor current is too low,

+     * 					indicating compressor is not connected, false if otherwise

+     */

+    CTR_Code 	GetCompressorNotConnectedFault(bool &status);

+

+    /* Get solenoid sticky fault value

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

+     * @Param	-	status		-	True if compressor had previously been shorted

+     * 								(and sticky fault was not cleared), false if otherwise

+     */

+    CTR_Code 	GetSolenoidStickyFault(bool &status);

+

+    /* Get battery voltage

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

+     * @Param	-	status		-	Voltage across PCM power ports in Volts (V)

+     */

+    CTR_Code 	GetBatteryVoltage(float &status);

+

+    /* Set PCM Device Number and according CAN frame IDs

+     * @Return	-	void

+     * @Param	-	deviceNumber	-	Device number of PCM to control

+     */

+    void	SetDeviceNumber(UINT8 deviceNumber);

+    /* Get number of total failed PCM Control Frame

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

+     * @Param	-	status		-	Number of failed control frames (tokenization fails)

+     * @WARNING	-	Return only valid if [SeekDebugFrames] is enabled

+     * 				See function SeekDebugFrames

+     * 				See function EnableSeekDebugFrames

+     */

+	CTR_Code GetNumberOfFailedControlFrames(UINT16 &status);

+

+    /* Get raw Solenoid Blacklist

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

+     * @Param	-	status		-	Raw binary breakdown of Solenoid Blacklist

+     * 								BIT7 = Solenoid 1, BIT6 = Solenoid 2, etc.

+     * @WARNING	-	Return only valid if [SeekStatusFaultFrames] is enabled

+     * 				See function SeekStatusFaultFrames

+     * 				See function EnableSeekStatusFaultFrames

+     */

+    CTR_Code 	GetSolenoidBlackList(UINT8 &status);

+

+    /* Get solenoid Blacklist status

+     * - Blacklisted solenoids cannot be enabled until PCM is power cycled

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

+     * @Param	-	idx			-	ID of solenoid [0,7]

+     * @Param	-	status		-	True if Solenoid is blacklisted, false if otherwise

+     * @WARNING	-	Return only valid if [SeekStatusFaultFrames] is enabled

+     * 				See function SeekStatusFaultFrames

+     * 				See function EnableSeekStatusFaultFrames

+     */

+    CTR_Code 	IsSolenoidBlacklisted(UINT8 idx, bool &status);

+

+    /* Return status of module enable/disable

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

+     * @Param	-	status		-	Returns TRUE if PCM is enabled, FALSE if disabled

+     */

+    CTR_Code	isModuleEnabled(bool &status);

+

+    /* Get solenoid Blacklist status

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

+     * @Param	-	idx			-	ID of solenoid [0,7] to fire one shot pulse.

+     */

+    CTR_Code FireOneShotSolenoid(UINT8 idx);

+

+    /* Configure the pulse width of a solenoid channel for one-shot pulse.

+	 * Preprogrammed pulsewidth is 10ms resolute and can be between 20ms and 5.1s.

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

+     * @Param	-	idx			-	ID of solenoid [0,7] to configure.

+     * @Param	-	durMs		-	pulse width in ms.

+     */

+    CTR_Code SetOneShotDurationMs(UINT8 idx,uint32_t durMs);

+

+};

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

+extern "C" {

+	void * c_PCM_Init(void);

+	CTR_Code c_SetSolenoid(void * handle,unsigned char idx,INT8 param);

+	CTR_Code c_SetAllSolenoids(void * handle,UINT8 state);

+	CTR_Code c_SetClosedLoopControl(void * handle,INT8 param);

+	CTR_Code c_ClearStickyFaults(void * handle,INT8 param);

+	CTR_Code c_GetSolenoid(void * handle,UINT8 idx,INT8 * status);

+	CTR_Code c_GetAllSolenoids(void * handle,UINT8 * status);

+	CTR_Code c_GetPressure(void * handle,INT8 * status);

+	CTR_Code c_GetCompressor(void * handle,INT8 * status);

+	CTR_Code c_GetClosedLoopControl(void * handle,INT8 * status);

+	CTR_Code c_GetCompressorCurrent(void * handle,float * status);

+	CTR_Code c_GetSolenoidVoltage(void * handle,float*status);

+	CTR_Code c_GetHardwareFault(void * handle,INT8*status);

+	CTR_Code c_GetCompressorFault(void * handle,INT8*status);

+	CTR_Code c_GetSolenoidFault(void * handle,INT8*status);

+	CTR_Code c_GetCompressorStickyFault(void * handle,INT8*status);

+	CTR_Code c_GetSolenoidStickyFault(void * handle,INT8*status);

+	CTR_Code c_GetBatteryVoltage(void * handle,float*status);

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

+	void c_EnableSeekStatusFrames(void * handle,INT8 enable);

+	void c_EnableSeekStatusFaultFrames(void * handle,INT8 enable);

+	void c_EnableSeekDebugFrames(void * handle,INT8 enable);

+	CTR_Code c_GetNumberOfFailedControlFrames(void * handle,UINT16*status);

+	CTR_Code c_GetSolenoidBlackList(void * handle,UINT8 *status);

+	CTR_Code c_IsSolenoidBlacklisted(void * handle,UINT8 idx,INT8*status);

+}

+#endif

diff --git a/hal/include/ctre/PDP.h b/hal/include/ctre/PDP.h
new file mode 100644
index 0000000..b968a44
--- /dev/null
+++ b/hal/include/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/hal/include/ctre/ctre.h b/hal/include/ctre/ctre.h
new file mode 100644
index 0000000..a0f99b3
--- /dev/null
+++ b/hal/include/ctre/ctre.h
@@ -0,0 +1,57 @@
+/**

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

+

+#include "ctre_frames.h"

+

+#endif /* CTRE_H */

diff --git a/hal/include/ctre/ctre_frames.h b/hal/include/ctre/ctre_frames.h
new file mode 100644
index 0000000..f131538
--- /dev/null
+++ b/hal/include/ctre/ctre_frames.h
@@ -0,0 +1,243 @@
+/**
+ * @file ctre_frames.h
+ * CAN Encoder/Decoder Structures for CTRE devices.
+ */
+#ifndef CTRE_FRAMES_H
+#define CTRE_FRAMES_H
+
+/** control */
+typedef struct _TALON_Control_1_General_10ms_t {
+	unsigned TokenH:8;
+	unsigned TokenL:8;
+	unsigned DemandH:8;
+	unsigned DemandM:8;
+	unsigned DemandL:8;
+	unsigned ProfileSlotSelect:1;
+	unsigned FeedbackDeviceSelect:4;
+	unsigned OverrideLimitSwitchEn:3;
+	unsigned RevFeedbackSensor:1;
+	unsigned RevMotDuringCloseLoopEn:1;
+	unsigned OverrideBrakeType:2;
+	unsigned ModeSelect:4;
+	unsigned RampThrottle:8;
+} TALON_Control_1_General_10ms_t ;
+
+/* TALON_Control_2_Rates_OneShot_t removed since it has been deprecated */
+
+typedef struct _TALON_Control_3_ClearFlags_OneShot_t {
+	unsigned ZeroFeedbackSensor:1;
+	unsigned ClearStickyFaults:1;
+} TALON_Control_3_ClearFlags_OneShot_t ;
+
+typedef struct _TALON_Control_5_General_10ms_t {
+	unsigned ThrottleBump_h3:3;
+	unsigned ReservedZero:5;
+	unsigned ThrottleBump_l8:8;
+	unsigned DemandH:8;
+	unsigned DemandM:8;
+	unsigned DemandL:8;
+	unsigned ProfileSlotSelect:1;
+	unsigned FeedbackDeviceSelect:4;
+	unsigned OverrideLimitSwitchEn:3;
+	unsigned RevFeedbackSensor:1;
+	unsigned RevMotDuringCloseLoopEn:1;
+	unsigned OverrideBrakeType:2;
+	unsigned ModeSelect:4;
+	unsigned RampThrottle:8;
+} TALON_Control_5_General_10ms_t ;
+
+typedef struct _TALON_Control_6_MotProfAddTrajPoint_t {
+	unsigned huffCode:2; //!< Compression coding
+	unsigned NextPt_VelOnly:1;
+	unsigned NextPt_IsLast:1;
+	unsigned reserved0:2;
+	unsigned NextPt_ZeroPosition:1;
+	unsigned NextPt_ProfileSlotSelect:1;
+	unsigned Idx:4;
+	unsigned reserved1:4;
+	unsigned restOfFrame0:8;
+	unsigned restOfFrame1:8;
+	unsigned restOfFrame2:8;
+	unsigned restOfFrame3:8;
+	unsigned restOfFrame4:8;
+	unsigned restOfFrame5:8;
+} TALON_Control_6_MotProfAddTrajPoint_t;
+
+typedef struct _TALON_Control_6_MotProfAddTrajPoint_huff0_t {
+	unsigned huffCode_expect_0:2; //!< Compression coding
+	unsigned NextPt_VelOnly:1;
+	unsigned NextPt_IsLast:1;
+	unsigned reserved0:2;
+	unsigned NextPt_ZeroPosition:1;
+	unsigned NextPt_ProfileSlotSelect:1;
+	unsigned Idx:4;
+	unsigned reserved1:4;
+	unsigned NextPt_DurationMs:8;
+	unsigned NextPt_VelocityH:8;
+	unsigned NextPt_VelocityL:8;
+	unsigned NextPt_PositionH:8;
+	unsigned NextPt_PositionM:8;
+	unsigned NextPt_PositionL:8;
+} TALON_Control_6_MotProfAddTrajPoint_huff0_t;
+
+typedef struct _TALON_Control_6_MotProfAddTrajPoint_huff1_t {
+	unsigned huffCode_expect_1:2; //!< Compression coding
+	unsigned NextPt_VelOnly:1;
+	unsigned NextPt_IsLast:1;
+	unsigned reserved0:2;
+	unsigned NextPt_ZeroPosition:1;
+	unsigned NextPt_ProfileSlotSelect:1;
+	unsigned Idx:4;
+	unsigned reserved1:4;
+	unsigned NextPt_DurationMs:8;
+	unsigned NextPt_SameVelocityH:8;
+	unsigned NextPt_SameVelocityL:8;
+	unsigned NextPt_DeltaPositionH:8;
+	unsigned NextPt_DeltaPositionL:8;
+	unsigned NextPt_Count:8;
+} TALON_Control_6_MotProfAddTrajPoint_huff1_t;
+
+/** status */
+typedef struct _TALON_Status_1_General_10ms_t {
+	unsigned CloseLoopErrH:8;
+	unsigned CloseLoopErrM:8;
+	unsigned CloseLoopErrL:8;
+	unsigned AppliedThrottle_h3:3;
+	unsigned Fault_RevSoftLim:1;
+	unsigned Fault_ForSoftLim:1;
+	unsigned TokLocked:1;
+	unsigned LimitSwitchClosedRev:1;
+	unsigned LimitSwitchClosedFor:1;
+	unsigned AppliedThrottle_l8:8;
+	unsigned ModeSelect_h1:1;
+	unsigned FeedbackDeviceSelect:4;
+	unsigned LimitSwitchEn:3;
+	unsigned Fault_HardwareFailure:1;
+	unsigned Fault_RevLim:1;
+	unsigned Fault_ForLim:1;
+	unsigned Fault_UnderVoltage:1;
+	unsigned Fault_OverTemp:1;
+	unsigned ModeSelect_b3:3;
+	unsigned TokenSeed:8;
+} TALON_Status_1_General_10ms_t ;
+typedef struct _TALON_Status_2_Feedback_20ms_t {
+	unsigned SensorPositionH:8;
+	unsigned SensorPositionM:8;
+	unsigned SensorPositionL:8;
+	unsigned SensorVelocityH:8;
+	unsigned SensorVelocityL:8;
+	unsigned Current_h8:8;
+	unsigned StckyFault_RevSoftLim:1;
+	unsigned StckyFault_ForSoftLim:1;
+	unsigned StckyFault_RevLim:1;
+	unsigned StckyFault_ForLim:1;
+	unsigned StckyFault_UnderVoltage:1;
+	unsigned StckyFault_OverTemp:1;
+	unsigned Current_l2:2;
+	unsigned reserved:3;
+	unsigned Cmd5Allowed:1;
+	unsigned VelDiv4:1;
+	unsigned PosDiv8:1;
+	unsigned ProfileSlotSelect:1;
+	unsigned BrakeIsEnabled:1;
+} TALON_Status_2_Feedback_20ms_t ;
+typedef struct _TALON_Status_3_Enc_100ms_t {
+	unsigned EncPositionH:8;
+	unsigned EncPositionM:8;
+	unsigned EncPositionL:8;
+	unsigned EncVelH:8;
+	unsigned EncVelL:8;
+	unsigned EncIndexRiseEventsH:8;
+	unsigned EncIndexRiseEventsL:8;
+	unsigned reserved:3;
+	unsigned VelDiv4:1;
+	unsigned PosDiv8:1;
+	unsigned QuadIdxpin:1;
+	unsigned QuadBpin:1;
+	unsigned QuadApin:1;
+} TALON_Status_3_Enc_100ms_t ;
+typedef struct _TALON_Status_4_AinTempVbat_100ms_t {
+	unsigned AnalogInWithOvH:8;
+	unsigned AnalogInWithOvM:8;
+	unsigned AnalogInWithOvL:8;
+	unsigned AnalogInVelH:8;
+	unsigned AnalogInVelL:8;
+	unsigned Temp:8;
+	unsigned BatteryV:8;
+	unsigned reserved:6;
+	unsigned VelDiv4:1;
+	unsigned PosDiv8:1;
+} TALON_Status_4_AinTempVbat_100ms_t ;
+typedef struct _TALON_Status_5_Startup_OneShot_t {
+	unsigned ResetCountH:8;
+	unsigned ResetCountL:8;
+	unsigned ResetFlagsH:8;
+	unsigned ResetFlagsL:8;
+	unsigned FirmVersH:8;
+	unsigned FirmVersL:8;
+} TALON_Status_5_Startup_OneShot_t ;
+typedef struct _TALON_Status_6_Eol_t {
+	unsigned currentAdcUncal_h2:2;
+	unsigned reserved1:5;
+	unsigned SpiCsPin_GadgeteerPin6:1;
+	unsigned currentAdcUncal_l8:8;
+	unsigned tempAdcUncal_h2:2;
+	unsigned reserved2:6;
+	unsigned tempAdcUncal_l8:8;
+	unsigned vbatAdcUncal_h2:2;
+	unsigned reserved3:6;
+	unsigned vbatAdcUncal_l8:8;
+	unsigned analogAdcUncal_h2:2;
+	unsigned reserved4:6;
+	unsigned analogAdcUncal_l8:8;
+} TALON_Status_6_Eol_t ;
+typedef struct _TALON_Status_7_Debug_200ms_t {
+	unsigned TokenizationFails_h8:8;
+	unsigned TokenizationFails_l8:8;
+	unsigned LastFailedToken_h8:8;
+	unsigned LastFailedToken_l8:8;
+	unsigned TokenizationSucceses_h8:8;
+	unsigned TokenizationSucceses_l8:8;
+} TALON_Status_7_Debug_200ms_t ;
+typedef struct _TALON_Status_8_PulseWid_100ms_t {
+	unsigned PulseWidPositionH:8;
+	unsigned PulseWidPositionM:8;
+	unsigned PulseWidPositionL:8;
+	unsigned reserved:6;
+	unsigned VelDiv4:1;
+	unsigned PosDiv8:1;
+	unsigned PeriodUsM8:8;
+	unsigned PeriodUsL8:8;
+	unsigned PulseWidVelH:8;
+	unsigned PulseWidVelL:8;
+} TALON_Status_8_PulseWid_100ms_t ;
+typedef struct _TALON_Status_9_MotProfBuffer_100ms_t {
+	unsigned ActTraj_IsValid:1; //!< '1' if other ActTraj_* signals are valid.  '0' if there is no active trajectory pt.
+	unsigned ActTraj_ProfileSlotSelect:1;
+	unsigned ActTraj_VelOnly:1;
+	unsigned ActTraj_IsLast:1;
+	unsigned OutputType:2;
+	unsigned HasUnderrun:1;
+	unsigned IsUnderrun:1;
+	unsigned NextID:4;
+	unsigned reserved1:3;
+	unsigned BufferIsFull:1;
+	unsigned Count:8;
+	unsigned ActTraj_VelocityH:8;
+	unsigned ActTraj_VelocityL:8;
+	unsigned ActTraj_PositionH:8;
+	unsigned ActTraj_PositionM:8;
+	unsigned ActTraj_PositionL:8;
+} TALON_Status_9_MotProfBuffer_100ms_t ;
+typedef struct _TALON_Param_Request_t {
+	unsigned ParamEnum:8;
+} TALON_Param_Request_t ;
+typedef struct _TALON_Param_Response_t {
+	unsigned ParamEnum:8;
+	unsigned ParamValueL:8;
+	unsigned ParamValueML:8;
+	unsigned ParamValueMH:8;
+	unsigned ParamValueH:8;
+} TALON_Param_Response_t ;
+
+#endif /* CTRE_FRAMES_H */