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/cpp/src/CANifier.cpp b/cpp/src/CANifier.cpp
new file mode 100644
index 0000000..7b18849
--- /dev/null
+++ b/cpp/src/CANifier.cpp
@@ -0,0 +1,454 @@
+/*
+ * 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
+ */
+
+#ifndef CTR_EXCLUDE_WPILIB_CLASSES
+#include "ctre/phoenix/CANifier.h"
+#include "ctre/phoenix/CCI/CANifier_CCI.h"
+#include "ctre/phoenix/CTRLogger.h"
+#include "HAL/HAL.h"
+
+namespace ctre {
+namespace phoenix {
+ /**
+ * Constructor.
+ * @param deviceNumber The CAN Device ID of the CANifier.
+ */
+CANifier::CANifier(int deviceNumber): CANBusAddressable(deviceNumber)
+{
+ m_handle = c_CANifier_Create1(deviceNumber);
+ HAL_Report(HALUsageReporting::kResourceType_CANifier, deviceNumber + 1);
+}
+
+/**
+ * Sets the LED Output
+ * @param percentOutput Output duty cycle expressed as percentage.
+ * @param ledChannel Channel to set the output of.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ErrorCode CANifier::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]
+
+ return c_CANifier_SetLEDOutput(m_handle, dutyCycle, ledChannel);
+}
+
+/**
+ * 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.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ErrorCode CANifier::SetGeneralOutput(GeneralPin outputPin, bool outputValue,
+ bool outputEnable) {
+ return c_CANifier_SetGeneralOutput(m_handle, outputPin, outputValue,
+ outputEnable);
+}
+
+/**
+ * Sets the output of all General Pin
+ * @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.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ErrorCode CANifier::SetGeneralOutputs(int outputBits, int isOutputBits) {
+ return c_CANifier_SetGeneralOutputs(m_handle, outputBits, isOutputBits);
+}
+
+/**
+ * Sets the output of all General Pin
+ * @param allPins A structure to fill with the current state of all pins.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ErrorCode CANifier::GetGeneralInputs(CANifier::PinValues &allPins) {
+ ErrorCode err = c_CANifier_GetGeneralInputs(m_handle, _tempPins, sizeof(_tempPins));
+ allPins.LIMF = _tempPins[LIMF];
+ allPins.LIMR = _tempPins[LIMR];
+ allPins.QUAD_A = _tempPins[QUAD_A];
+ allPins.QUAD_B = _tempPins[QUAD_B];
+ allPins.QUAD_IDX = _tempPins[QUAD_IDX];
+ allPins.SCL = _tempPins[SCL];
+ allPins.SDA = _tempPins[SDA];
+ allPins.SPI_CLK_PWM0 = _tempPins[SPI_CLK_PWM0P];
+ allPins.SPI_MOSI_PWM1 = _tempPins[SPI_MOSI_PWM1P];
+ allPins.SPI_MISO_PWM2 = _tempPins[SPI_MISO_PWM2P];
+ allPins.SPI_CS_PWM3 = _tempPins[SPI_CS];
+ return err;
+}
+
+/**
+ * Gets the state of the specified pin
+ * @param inputPin The index of the pin.
+ * @return The state of the pin.
+ */
+bool CANifier::GetGeneralInput(GeneralPin inputPin) {
+ bool retval = false;
+ (void)c_CANifier_GetGeneralInput(m_handle, inputPin, &retval);
+ return retval;
+}
+
+/**
+ * Gets the position of the quadrature encoder.
+ * @return The Position of the encoder.
+ */
+int CANifier::GetQuadraturePosition() {
+ int retval = 0;
+ (void)c_CANifier_GetQuadraturePosition(m_handle, &retval);
+ return retval;
+}
+/**
+ * Sets the position of the quadrature encoder.
+ * @param newPosition
+ * @return ErrorCode generated by function. 0 indicates no error.
+ */
+ErrorCode CANifier::SetQuadraturePosition(int newPosition, int timeoutMs) {
+ return c_CANifier_SetQuadraturePosition(m_handle, newPosition, timeoutMs);
+}
+/**
+ * Gets the velocity of the quadrature encoder.
+ * @return The Velocity of the encoder.
+ */
+int CANifier::GetQuadratureVelocity() {
+ int retval = 0;
+ (void)c_CANifier_GetQuadratureVelocity(m_handle, &retval);
+ return retval;
+}
+/**
+ * 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.
+ */
+ErrorCode CANifier::ConfigVelocityMeasurementPeriod(CANifierVelocityMeasPeriod period, int timeoutMs) {
+ return c_CANifier_ConfigVelocityMeasurementPeriod(m_handle, period, timeoutMs);
+}
+/**
+ * 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.
+ */
+ErrorCode CANifier::ConfigVelocityMeasurementWindow(int windowSize, int timeoutMs) {
+ return c_CANifier_ConfigVelocityMeasurementWindow(m_handle, windowSize, timeoutMs);
+}
+/**
+ * Gets the bus voltage seen by the device.
+ *
+ * @return The bus voltage value (in volts).
+ */
+double CANifier::GetBusVoltage() {
+ double param = 0;
+ c_CANifier_GetBusVoltage(m_handle, ¶m);
+ return param;
+}
+
+/**
+ * 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.
+ */
+ErrorCode CANifier::GetLastError() {
+ return c_CANifier_GetLastError(m_handle);
+}
+
+/**
+ * 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.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ErrorCode CANifier::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);
+
+ return c_CANifier_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.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ErrorCode CANifier::EnablePWMOutput(int pwmChannel, bool bEnable) {
+ if (pwmChannel < 0) {
+ pwmChannel = 0;
+ }
+
+ return c_CANifier_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].
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ErrorCode CANifier::GetPWMInput(PWMChannel pwmChannel, double dutyCycleAndPeriod[]) {
+ return c_CANifier_GetPWMInput(m_handle, pwmChannel,
+ dutyCycleAndPeriod);
+}
+
+//------ Custom Persistent Params ----------//
+
+/**
+ * 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.
+ */
+ErrorCode CANifier::ConfigSetCustomParam(int newValue,
+ int paramIndex, int timeoutMs) {
+ return c_CANifier_ConfigSetCustomParam(m_handle, newValue, paramIndex, timeoutMs);
+}
+/**
+ * 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 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 the custom param.
+ */
+int CANifier::ConfigGetCustomParam(
+ int paramIndex, int timeoutMs) {
+ int readValue;
+ c_CANifier_ConfigGetCustomParam(m_handle, &readValue, paramIndex, timeoutMs);
+ return readValue;
+}
+
+//------ Generic Param API, typically not used ----------//
+/**
+ * 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.
+ */
+ErrorCode CANifier::ConfigSetParameter(ParamEnum param, double value,
+ uint8_t subValue, int ordinal, int timeoutMs) {
+ return c_CANifier_ConfigSetParameter(m_handle, param, value, subValue, ordinal, timeoutMs);
+
+}
+/**
+ * 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.
+ */
+double CANifier::ConfigGetParameter(ParamEnum param, int ordinal, int timeoutMs) {
+ double value = 0;
+ c_CANifier_ConfigGetParameter(m_handle, param, &value, ordinal, timeoutMs);
+ return value;
+}
+
+//------ Frames ----------//
+/**
+ * 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.
+ */
+ErrorCode CANifier::SetStatusFramePeriod(CANifierStatusFrame statusFrame, int periodMs,
+ int timeoutMs) {
+ return c_CANifier_SetStatusFramePeriod(m_handle, statusFrame, periodMs,
+ timeoutMs);
+}
+/**
+ * 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.
+ */
+int CANifier::GetStatusFramePeriod(CANifierStatusFrame frame,
+ int timeoutMs) {
+ int periodMs = 0;
+ c_CANifier_GetStatusFramePeriod(m_handle, frame, &periodMs, timeoutMs);
+ return periodMs;
+}
+/**
+ * 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.
+ */
+ErrorCode CANifier::SetControlFramePeriod(CANifierControlFrame frame,
+ int periodMs) {
+ return c_CANifier_SetControlFramePeriod(m_handle, frame, periodMs);
+}
+//------ Firmware ----------//
+/**
+ * Gets the firmware version of the device.
+ *
+ * @return Firmware version of device.
+ */
+int CANifier::GetFirmwareVersion() {
+ int retval = -1;
+ c_CANifier_GetFirmwareVersion(m_handle, &retval);
+ return retval;
+}
+/**
+ * Returns true if the device has reset since last call.
+ *
+ * @return Has a Device Reset Occurred?
+ */
+bool CANifier::HasResetOccurred() {
+ bool retval = false;
+ c_CANifier_HasResetOccurred(m_handle, &retval);
+ return retval;
+}
+//------ Faults ----------//
+/**
+ * Gets the CANifier fault status
+ *
+ * @param toFill
+ * Container for fault statuses.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ErrorCode CANifier::GetFaults(CANifierFaults & toFill) {
+ int faultBits;
+ ErrorCode retval = c_CANifier_GetFaults(m_handle, &faultBits);
+ toFill = CANifierFaults(faultBits);
+ return retval;
+}
+/**
+ * Gets the CANifier sticky fault status
+ *
+ * @param toFill
+ * Container for sticky fault statuses.
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ErrorCode CANifier::GetStickyFaults(CANifierStickyFaults & toFill) {
+ int faultBits;
+ ErrorCode retval = c_CANifier_GetFaults(m_handle, &faultBits);
+ toFill = CANifierStickyFaults(faultBits);
+ return retval;
+}
+/**
+ * Clears the Sticky Faults
+ *
+ * @return Error Code generated by function. 0 indicates no error.
+ */
+ErrorCode CANifier::ClearStickyFaults(int timeoutMs) {
+ return c_CANifier_ClearStickyFaults(m_handle, timeoutMs);
+}
+
+} // phoenix
+} // ctre
+#endif // CTR_EXCLUDE_WPILIB_CLASSES