Squashed 'third_party/Phoenix-frc-lib/' content from commit 666d176
Change-Id: Ibaca2fc8ffb1177e786576cc1e4cc9f7a8c98f13
git-subtree-dir: third_party/Phoenix-frc-lib
git-subtree-split: 666d176a08151793044ab74e0005f13d3732ed96
diff --git a/java/src/com/ctre/phoenix/CANifier.java b/java/src/com/ctre/phoenix/CANifier.java
new file mode 100644
index 0000000..31d33ce
--- /dev/null
+++ b/java/src/com/ctre/phoenix/CANifier.java
@@ -0,0 +1,616 @@
+/*
+ * Software License Agreement
+ *
+ * Copyright (C) Cross The Road Electronics. All rights
+ * reserved.
+ *
+ * Cross The Road Electronics (CTRE) licenses to you the right to
+ * use, publish, and distribute copies of CRF (Cross The Road) firmware files (*.crf) and Software
+ * API Libraries ONLY when in use with Cross The Road Electronics hardware products.
+ *
+ * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
+ * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * CROSS THE ROAD ELECTRONICS BE LIABLE FOR ANY INCIDENTAL, SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
+ * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
+ * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
+ * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
+ * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE
+ */
+
+package com.ctre.phoenix;
+
+import edu.wpi.first.wpilibj.hal.HAL;
+
+/**
+ * CTRE CANifier
+ *
+ * Device for interfacing common devices to the CAN bus.
+ */
+public class CANifier {
+ private long m_handle;
+
+ /**
+ * Enum for velocity periods
+ */
+ public enum VelocityPeriod {
+ Period_1Ms(1),
+ Period_2Ms(2),
+ Period_5Ms(5),
+ Period_10Ms(10),
+ Period_20Ms(20),
+ Period_25Ms(25),
+ Period_50Ms(50),
+ Period_100Ms(100);
+ public static VelocityPeriod valueOf(int value) {
+ for(VelocityPeriod period : values()) {
+ if(period.value == value) {
+ return period;
+ }
+ }
+ return null;
+ }
+ public final int value;
+ VelocityPeriod(int initValue) {
+ this.value = initValue;
+ }
+ }
+
+ /**
+ * Enum for the LED Output Channels
+ */
+ public enum LEDChannel {
+ LEDChannelA(0), LEDChannelB(1), LEDChannelC(2);
+ public static LEDChannel valueOf(int value) {
+ for (LEDChannel mode : values()) {
+ if (mode.value == value) {
+ return mode;
+ }
+ }
+ return null;
+ }
+
+ public final int value;
+
+ LEDChannel(int initValue) {
+ this.value = initValue;
+ }
+ }
+
+ /**
+ * Enum for the PWM Input Channels
+ */
+ public enum PWMChannel {
+ PWMChannel0(0), PWMChannel1(1), PWMChannel2(2), PWMChannel3(3);
+ public static PWMChannel valueOf(int value) {
+ for (PWMChannel mode : values()) {
+ if (mode.value == value) {
+ return mode;
+ }
+ }
+ return null;
+ }
+
+ public final int value;
+
+ PWMChannel(int initValue) {
+ this.value = initValue;
+ }
+ }
+
+ public final int PWMChannelCount = 4;
+
+ /**
+ * General IO Pins on the CANifier
+ */
+ public enum GeneralPin {
+ QUAD_IDX (CANifierJNI.GeneralPin.QUAD_IDX.value),
+ QUAD_B (CANifierJNI.GeneralPin.QUAD_B.value),
+ QUAD_A (CANifierJNI.GeneralPin.QUAD_A.value),
+ LIMR (CANifierJNI.GeneralPin.LIMR.value),
+ LIMF (CANifierJNI.GeneralPin.LIMF.value),
+ SDA (CANifierJNI.GeneralPin.SDA.value),
+ SCL (CANifierJNI.GeneralPin.SCL.value),
+ SPI_CS (CANifierJNI.GeneralPin.SPI_CS.value),
+ SPI_MISO_PWM2P (CANifierJNI.GeneralPin.SPI_MISO_PWM2P.value),
+ SPI_MOSI_PWM1P (CANifierJNI.GeneralPin.SPI_MOSI_PWM1P.value),
+ SPI_CLK_PWM0P (CANifierJNI.GeneralPin.SPI_CLK_PWM0P.value);
+ public static GeneralPin valueOf(int value) {
+ for (GeneralPin mode : values()) {
+ if (mode.value == value) {
+ return mode;
+ }
+ }
+ return null;
+ }
+
+ public final int value;
+
+ GeneralPin(int initValue) {
+ this.value = initValue;
+ }
+ }
+
+ /**
+ * Class to hold the pin values.
+ */
+ public static class PinValues {
+ public boolean QUAD_IDX;
+ public boolean QUAD_B;
+ public boolean QUAD_A;
+ public boolean LIMR;
+ public boolean LIMF;
+ public boolean SDA;
+ public boolean SCL;
+ public boolean SPI_CS_PWM3;
+ public boolean SPI_MISO_PWM2;
+ public boolean SPI_MOSI_PWM1;
+ public boolean SPI_CLK_PWM0;
+ }
+
+ private boolean[] _tempPins = new boolean[11];
+
+ private int m_deviceNumber;
+ /**
+ * Constructor.
+ * @param deviceId The CAN Device ID of the CANifier.
+ */
+ public CANifier(int deviceId) {
+ m_handle = CANifierJNI.JNI_new_CANifier(deviceId);
+ m_deviceNumber = deviceId;
+ HAL.report(63, deviceId + 1);
+ }
+
+ /**
+ * Sets the LED Output
+ * @param percentOutput Output duty cycle expressed as percentage.
+ * @param ledChannel Channel to set the output of.
+ */
+ public void setLEDOutput(double percentOutput, LEDChannel ledChannel) {
+ /* convert float to integral fixed pt */
+ if (percentOutput > 1) {
+ percentOutput = 1;
+ }
+ if (percentOutput < 0) {
+ percentOutput = 0;
+ }
+ int dutyCycle = (int) (percentOutput * 1023); // [0,1023]
+
+ CANifierJNI.JNI_SetLEDOutput(m_handle, dutyCycle, ledChannel.value);
+ }
+
+ /**
+ * Sets the output of a General Pin
+ * @param outputPin The pin to use as output.
+ * @param outputValue The desired output state.
+ * @param outputEnable Whether this pin is an output. "True" enables output.
+ */
+ public void setGeneralOutput(GeneralPin outputPin, boolean outputValue, boolean outputEnable) {
+ CANifierJNI.JNI_SetGeneralOutput(m_handle, outputPin.value, outputValue, outputEnable);
+ }
+
+ /**
+ * Sets the output of all General Pins
+ * @param outputBits A bit mask of all the output states. LSB->MSB is in the order of the #GeneralPin enum.
+ * @param isOutputBits A boolean bit mask that sets the pins to be outputs or inputs. A bit of 1 enables output.
+ */
+ public void setGeneralOutputs(int outputBits, int isOutputBits) {
+ CANifierJNI.JNI_SetGeneralOutputs(m_handle, outputBits, isOutputBits);
+ }
+
+ /**
+ * Gets the state of all General Pins
+ * @param allPins A structure to fill with the current state of all pins.
+ */
+ public void getGeneralInputs(PinValues allPins) {
+ CANifierJNI.JNI_GetGeneralInputs(m_handle, _tempPins);
+ allPins.LIMF = _tempPins[GeneralPin.LIMF.value];
+ allPins.LIMR = _tempPins[GeneralPin.LIMR.value];
+ allPins.QUAD_A = _tempPins[GeneralPin.QUAD_A.value];
+ allPins.QUAD_B = _tempPins[GeneralPin.QUAD_B.value];
+ allPins.QUAD_IDX = _tempPins[GeneralPin.QUAD_IDX.value];
+ allPins.SCL = _tempPins[GeneralPin.SCL.value];
+ allPins.SDA = _tempPins[GeneralPin.SDA.value];
+ allPins.SPI_CLK_PWM0 = _tempPins[GeneralPin.SPI_CLK_PWM0P.value];
+ allPins.SPI_MOSI_PWM1 = _tempPins[GeneralPin.SPI_MOSI_PWM1P.value];
+ allPins.SPI_MISO_PWM2 = _tempPins[GeneralPin.SPI_MISO_PWM2P.value];
+ allPins.SPI_CS_PWM3 = _tempPins[GeneralPin.SPI_CS.value];
+ }
+
+ /**
+ * Gets the state of the specified pin
+ * @param inputPin The index of the pin.
+ * @return The state of the pin.
+ */
+ public boolean getGeneralInput(GeneralPin inputPin) {
+ return CANifierJNI.JNI_GetGeneralInput(m_handle, inputPin.value);
+ }
+
+ /**
+ * Call GetLastError() generated by this object.
+ * Not all functions return an error code but can
+ * potentially report errors.
+ *
+ * This function can be used to retrieve those error codes.
+ *
+ * @return The last ErrorCode generated.
+ */
+ public ErrorCode getLastError() {
+ int retval = CANifierJNI.JNI_GetLastError(m_handle);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the PWM Output
+ * Currently supports PWM 0, PWM 1, and PWM 2
+ * @param pwmChannel Index of the PWM channel to output.
+ * @param dutyCycle Duty Cycle (0 to 1) to output. Default period of the signal is 4.2 ms.
+ */
+ public void setPWMOutput(int pwmChannel, double dutyCycle) {
+ if (dutyCycle < 0) {
+ dutyCycle = 0;
+ } else if (dutyCycle > 1) {
+ dutyCycle = 1;
+ }
+ if (pwmChannel < 0) {
+ pwmChannel = 0;
+ }
+
+ int dutyCyc10bit = (int) (1023 * dutyCycle);
+
+ CANifierJNI.JNI_SetPWMOutput(m_handle, (int) pwmChannel, dutyCyc10bit);
+ }
+
+ /**
+ * Enables PWM Outputs
+ * Currently supports PWM 0, PWM 1, and PWM 2
+ * @param pwmChannel Index of the PWM channel to enable.
+ * @param bEnable "True" enables output on the pwm channel.
+ */
+ public void enablePWMOutput(int pwmChannel, boolean bEnable) {
+ if (pwmChannel < 0) {
+ pwmChannel = 0;
+ }
+
+ CANifierJNI.JNI_EnablePWMOutput(m_handle, (int) pwmChannel, bEnable);
+ }
+
+ /**
+ * Gets the PWM Input
+ * @param pwmChannel PWM channel to get.
+ * @param dutyCycleAndPeriod Double array to hold Duty Cycle [0] and Period [1].
+ */
+ public void getPWMInput(PWMChannel pwmChannel, double[] dutyCycleAndPeriod) {
+ CANifierJNI.JNI_GetPWMInput(m_handle, pwmChannel.value, dutyCycleAndPeriod);
+ }
+
+ /**
+ * Gets the quadrature encoder's position
+ * @return Position of encoder
+ */
+ public int getQuadraturePosition() {
+ return CANifierJNI.JNI_GetQuadraturePosition(m_handle);
+ }
+
+ /**
+ * Sets the quadrature encoder's position
+ * @param newPosition Position to set
+ * @param timeoutMs
+ Timeout value in ms. If nonzero, function will wait for
+ config success and report an error if it times out.
+ If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setQuadraturePosition(int newPosition, int timeoutMs) {
+ return ErrorCode.valueOf(CANifierJNI.JNI_SetQuadraturePosition(m_handle, newPosition, timeoutMs));
+ }
+
+ /**
+ * Gets the quadrature encoder's velocity
+ * @return Velocity of encoder
+ */
+ public int getQuadratureVelocity() {
+ return CANifierJNI.JNI_GetQuadratureVelocity(m_handle);
+ }
+
+ /**
+ * Configures the period of each velocity sample.
+ * Every 1ms a position value is sampled, and the delta between that sample
+ * and the position sampled kPeriod ms ago is inserted into a filter.
+ * kPeriod is configured with this function.
+ *
+ * @param period
+ * Desired period for the velocity measurement. @see
+ * #VelocityMeasPeriod
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configVelocityMeasurementPeriod(VelocityPeriod period, int timeoutMs) {
+ int retval = CANifierJNI.JNI_ConfigVelocityMeasurementPeriod(m_handle, period.value, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the number of velocity samples used in the rolling average velocity
+ * measurement.
+ *
+ * @param windowSize
+ * Number of samples in the rolling average of velocity
+ * measurement. Valid values are 1,2,4,8,16,32. If another
+ * value is specified, it will truncate to nearest support value.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configVelocityMeasurementWindow(int windowSize, int timeoutMs) {
+ int retval = CANifierJNI.JNI_ConfigVelocityMeasurementWindow(m_handle, windowSize, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Sets the value of a custom parameter. This is for arbitrary use.
+ *
+ * Sometimes it is necessary to save calibration/duty cycle/output
+ * information in the device. Particularly if the
+ * device is part of a subsystem that can be replaced.
+ *
+ * @param newValue
+ * Value for custom parameter.
+ * @param paramIndex
+ * Index of custom parameter. [0-1]
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSetCustomParam(int newValue, int paramIndex, int timeoutMs) {
+ int retval = CANifierJNI.JNI_ConfigSetCustomParam(m_handle, newValue, paramIndex, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets the value of a custom parameter. This is for arbitrary use.
+ *
+ * Sometimes it is necessary to save calibration/duty cycle/output
+ * information in the device. Particularly if the
+ * device is part of a subsystem that can be replaced.
+ *
+ * @param paramIndex
+ * Index of custom parameter. [0-1]
+ * @param timoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Value of the custom param.
+ */
+ public int configGetCustomParam(int paramIndex, int timoutMs) {
+ int retval = CANifierJNI.JNI_ConfigGetCustomParam(m_handle, paramIndex, timoutMs);
+ return retval;
+ }
+
+ /**
+ * Sets a parameter. Generally this is not used.
+ * This can be utilized in
+ * - Using new features without updating API installation.
+ * - Errata workarounds to circumvent API implementation.
+ * - Allows for rapid testing / unit testing of firmware.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param value
+ * Value of parameter.
+ * @param subValue
+ * Subvalue for parameter. Maximum value of 255.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSetParameter(ParamEnum param, double value, int subValue, int ordinal, int timeoutMs) {
+ return configSetParameter(param.value, value, subValue, ordinal, timeoutMs);
+ }
+
+ /**
+ * Sets a parameter. Generally this is not used.
+ * This can be utilized in
+ * - Using new features without updating API installation.
+ * - Errata workarounds to circumvent API implementation.
+ * - Allows for rapid testing / unit testing of firmware.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param value
+ * Value of parameter.
+ * @param subValue
+ * Subvalue for parameter. Maximum value of 255.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode configSetParameter(int param, double value, int subValue, int ordinal, int timeoutMs) {
+ int retval = CANifierJNI.JNI_ConfigSetParameter(m_handle, param, value, subValue, ordinal,
+ timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Gets a parameter. Generally this is not used.
+ * This can be utilized in
+ * - Using new features without updating API installation.
+ * - Errata workarounds to circumvent API implementation.
+ * - Allows for rapid testing / unit testing of firmware.
+ *
+ * @param param
+ * Parameter enumeration.
+ * @param ordinal
+ * Ordinal of parameter.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Value of parameter.
+ */
+ public double configGetParameter(ParamEnum param, int ordinal, int timeoutMs) {
+ return CANifierJNI.JNI_ConfigGetParameter(m_handle, param.value, ordinal, timeoutMs);
+ }
+ /**
+ * Sets the period of the given status frame.
+ *
+ * @param statusFrame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setStatusFramePeriod(CANifierStatusFrame statusFrame, int periodMs, int timeoutMs) {
+ int retval = CANifierJNI.JNI_SetStatusFramePeriod(m_handle, statusFrame.value, periodMs, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Sets the period of the given status frame.
+ *
+ * @param statusFrame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setStatusFramePeriod(int statusFrame, int periodMs, int timeoutMs) {
+ int retval = CANifierJNI.JNI_SetStatusFramePeriod(m_handle, statusFrame, periodMs, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets the period of the given status frame.
+ *
+ * @param frame
+ * Frame to get the period of.
+ * @param timeoutMs
+ * Timeout value in ms. If nonzero, function will wait for
+ * config success and report an error if it times out.
+ * If zero, no blocking or checking is performed.
+ * @return Period of the given status frame.
+ */
+ public int getStatusFramePeriod(CANifierStatusFrame frame, int timeoutMs) {
+ return CANifierJNI.JNI_GetStatusFramePeriod(m_handle, frame.value, timeoutMs);
+ }
+
+ /**
+ * Sets the period of the given control frame.
+ *
+ * @param frame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setControlFramePeriod(CANifierControlFrame frame, int periodMs) {
+ int retval = CANifierJNI.JNI_SetControlFramePeriod(m_handle, frame.value, periodMs);
+ return ErrorCode.valueOf(retval);
+ }
+ /**
+ * Sets the period of the given control frame.
+ *
+ * @param frame
+ * Frame whose period is to be changed.
+ * @param periodMs
+ * Period in ms for the given frame.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode setControlFramePeriod(int frame, int periodMs) {
+ int retval = CANifierJNI.JNI_SetControlFramePeriod(m_handle, frame, periodMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets the firmware version of the device.
+ *
+ * @return Firmware version of device.
+ */
+ public int getFirmwareVersion() {
+ return CANifierJNI.JNI_GetFirmwareVersion(m_handle);
+ }
+
+ /**
+ * Returns true if the device has reset since last call.
+ *
+ * @return Has a Device Reset Occurred?
+ */
+ public boolean hasResetOccurred() {
+ return CANifierJNI.JNI_HasResetOccurred(m_handle);
+ }
+
+ // ------ Faults ----------//
+ /**
+ * Gets the CANifier fault status
+ *
+ * @param toFill
+ * Container for fault statuses.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode getFaults(CANifierFaults toFill) {
+ int bits = CANifierJNI.JNI_GetFaults(m_handle);
+ toFill.update(bits);
+ return getLastError();
+ }
+ /**
+ * Gets the CANifier sticky fault status
+ *
+ * @param toFill
+ * Container for sticky fault statuses.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode getStickyFaults(CANifierStickyFaults toFill) {
+ int bits = CANifierJNI.JNI_GetStickyFaults(m_handle);
+ toFill.update(bits);
+ return getLastError();
+ }
+ /**
+ * Clears the Sticky Faults
+ *
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ public ErrorCode clearStickyFaults(int timeoutMs) {
+ int retval = CANifierJNI.JNI_ClearStickyFaults(m_handle, timeoutMs);
+ return ErrorCode.valueOf(retval);
+ }
+
+ /**
+ * Gets the bus voltage seen by the device.
+ *
+ * @return The bus voltage value (in volts).
+ */
+ public double getBusVoltage() {
+ return CANifierJNI.JNI_GetBusVoltage(m_handle);
+ }
+
+ /**
+ * @return The Device Number
+ */
+ public int getDeviceID(){
+ return m_deviceNumber;
+ }
+}