blob: 7b188499feefc78b40c1170b3ee79eff3c1dbf00 [file] [log] [blame]
/*
* 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, &param);
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