blob: 7b188499feefc78b40c1170b3ee79eff3c1dbf00 [file] [log] [blame]
Brian Silverman890a32a2018-03-11 15:41:56 -07001/*
2 * Software License Agreement
3 *
4 * Copyright (C) Cross The Road Electronics. All rights
5 * reserved.
6 *
7 * Cross The Road Electronics (CTRE) licenses to you the right to
8 * use, publish, and distribute copies of CRF (Cross The Road) firmware files (*.crf) and Software
9 * API Libraries ONLY when in use with Cross The Road Electronics hardware products.
10 *
11 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
12 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
14 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
15 * CROSS THE ROAD ELECTRONICS BE LIABLE FOR ANY INCIDENTAL, SPECIAL,
16 * INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
17 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
18 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
19 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
20 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
21 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE
22 */
23
24#ifndef CTR_EXCLUDE_WPILIB_CLASSES
25#include "ctre/phoenix/CANifier.h"
26#include "ctre/phoenix/CCI/CANifier_CCI.h"
27#include "ctre/phoenix/CTRLogger.h"
28#include "HAL/HAL.h"
29
30namespace ctre {
31namespace phoenix {
32 /**
33 * Constructor.
34 * @param deviceNumber The CAN Device ID of the CANifier.
35 */
36CANifier::CANifier(int deviceNumber): CANBusAddressable(deviceNumber)
37{
38 m_handle = c_CANifier_Create1(deviceNumber);
39 HAL_Report(HALUsageReporting::kResourceType_CANifier, deviceNumber + 1);
40}
41
42/**
43 * Sets the LED Output
44 * @param percentOutput Output duty cycle expressed as percentage.
45 * @param ledChannel Channel to set the output of.
46 * @return Error Code generated by function. 0 indicates no error.
47 */
48ErrorCode CANifier::SetLEDOutput(double percentOutput, LEDChannel ledChannel) {
49 /* convert float to integral fixed pt */
50 if (percentOutput > 1) {
51 percentOutput = 1;
52 }
53 if (percentOutput < 0) {
54 percentOutput = 0;
55 }
56 int dutyCycle = (int) (percentOutput * 1023); // [0,1023]
57
58 return c_CANifier_SetLEDOutput(m_handle, dutyCycle, ledChannel);
59}
60
61/**
62 * Sets the output of a General Pin
63 * @param outputPin The pin to use as output.
64 * @param outputValue The desired output state.
65 * @param outputEnable Whether this pin is an output. "True" enables output.
66 * @return Error Code generated by function. 0 indicates no error.
67 */
68ErrorCode CANifier::SetGeneralOutput(GeneralPin outputPin, bool outputValue,
69 bool outputEnable) {
70 return c_CANifier_SetGeneralOutput(m_handle, outputPin, outputValue,
71 outputEnable);
72}
73
74/**
75 * Sets the output of all General Pin
76 * @param outputBits A bit mask of all the output states. LSB->MSB is in the order of the #GeneralPin enum.
77 * @param isOutputBits A boolean bit mask that sets the pins to be outputs or inputs. A bit of 1 enables output.
78 * @return Error Code generated by function. 0 indicates no error.
79 */
80ErrorCode CANifier::SetGeneralOutputs(int outputBits, int isOutputBits) {
81 return c_CANifier_SetGeneralOutputs(m_handle, outputBits, isOutputBits);
82}
83
84/**
85 * Sets the output of all General Pin
86 * @param allPins A structure to fill with the current state of all pins.
87 * @return Error Code generated by function. 0 indicates no error.
88 */
89ErrorCode CANifier::GetGeneralInputs(CANifier::PinValues &allPins) {
90 ErrorCode err = c_CANifier_GetGeneralInputs(m_handle, _tempPins, sizeof(_tempPins));
91 allPins.LIMF = _tempPins[LIMF];
92 allPins.LIMR = _tempPins[LIMR];
93 allPins.QUAD_A = _tempPins[QUAD_A];
94 allPins.QUAD_B = _tempPins[QUAD_B];
95 allPins.QUAD_IDX = _tempPins[QUAD_IDX];
96 allPins.SCL = _tempPins[SCL];
97 allPins.SDA = _tempPins[SDA];
98 allPins.SPI_CLK_PWM0 = _tempPins[SPI_CLK_PWM0P];
99 allPins.SPI_MOSI_PWM1 = _tempPins[SPI_MOSI_PWM1P];
100 allPins.SPI_MISO_PWM2 = _tempPins[SPI_MISO_PWM2P];
101 allPins.SPI_CS_PWM3 = _tempPins[SPI_CS];
102 return err;
103}
104
105/**
106 * Gets the state of the specified pin
107 * @param inputPin The index of the pin.
108 * @return The state of the pin.
109 */
110bool CANifier::GetGeneralInput(GeneralPin inputPin) {
111 bool retval = false;
112 (void)c_CANifier_GetGeneralInput(m_handle, inputPin, &retval);
113 return retval;
114}
115
116/**
117 * Gets the position of the quadrature encoder.
118 * @return The Position of the encoder.
119 */
120int CANifier::GetQuadraturePosition() {
121 int retval = 0;
122 (void)c_CANifier_GetQuadraturePosition(m_handle, &retval);
123 return retval;
124}
125/**
126 * Sets the position of the quadrature encoder.
127 * @param newPosition
128 * @return ErrorCode generated by function. 0 indicates no error.
129 */
130ErrorCode CANifier::SetQuadraturePosition(int newPosition, int timeoutMs) {
131 return c_CANifier_SetQuadraturePosition(m_handle, newPosition, timeoutMs);
132}
133/**
134 * Gets the velocity of the quadrature encoder.
135 * @return The Velocity of the encoder.
136 */
137int CANifier::GetQuadratureVelocity() {
138 int retval = 0;
139 (void)c_CANifier_GetQuadratureVelocity(m_handle, &retval);
140 return retval;
141}
142/**
143 * Configures the period of each velocity sample.
144 * Every 1ms a position value is sampled, and the delta between that sample
145 * and the position sampled kPeriod ms ago is inserted into a filter.
146 * kPeriod is configured with this function.
147 *
148 * @param period
149 * Desired period for the velocity measurement. @see
150 * #VelocityMeasPeriod
151 * @param timeoutMs
152 * Timeout value in ms. If nonzero, function will wait for
153 * config success and report an error if it times out.
154 * If zero, no blocking or checking is performed.
155 * @return Error Code generated by function. 0 indicates no error.
156 */
157ErrorCode CANifier::ConfigVelocityMeasurementPeriod(CANifierVelocityMeasPeriod period, int timeoutMs) {
158 return c_CANifier_ConfigVelocityMeasurementPeriod(m_handle, period, timeoutMs);
159}
160/**
161 * Sets the number of velocity samples used in the rolling average velocity
162 * measurement.
163 *
164 * @param windowSize
165 * Number of samples in the rolling average of velocity
166 * measurement. Valid values are 1,2,4,8,16,32. If another
167 * value is specified, it will truncate to nearest support value.
168 * @param timeoutMs
169 * Timeout value in ms. If nonzero, function will wait for
170 * config success and report an error if it times out.
171 * If zero, no blocking or checking is performed.
172 * @return Error Code generated by function. 0 indicates no error.
173 */
174ErrorCode CANifier::ConfigVelocityMeasurementWindow(int windowSize, int timeoutMs) {
175 return c_CANifier_ConfigVelocityMeasurementWindow(m_handle, windowSize, timeoutMs);
176}
177/**
178 * Gets the bus voltage seen by the device.
179 *
180 * @return The bus voltage value (in volts).
181 */
182double CANifier::GetBusVoltage() {
183 double param = 0;
184 c_CANifier_GetBusVoltage(m_handle, &param);
185 return param;
186}
187
188/**
189 * Call GetLastError() generated by this object.
190 * Not all functions return an error code but can
191 * potentially report errors.
192 *
193 * This function can be used to retrieve those error codes.
194 *
195 * @return The last ErrorCode generated.
196 */
197ErrorCode CANifier::GetLastError() {
198 return c_CANifier_GetLastError(m_handle);
199}
200
201/**
202 * Sets the PWM Output
203 * Currently supports PWM 0, PWM 1, and PWM 2
204 * @param pwmChannel Index of the PWM channel to output.
205 * @param dutyCycle Duty Cycle (0 to 1) to output. Default period of the signal is 4.2 ms.
206 * @return Error Code generated by function. 0 indicates no error.
207 */
208ErrorCode CANifier::SetPWMOutput(int pwmChannel, double dutyCycle) {
209 if (dutyCycle < 0) {
210 dutyCycle = 0;
211 } else if (dutyCycle > 1) {
212 dutyCycle = 1;
213 }
214 if (pwmChannel < 0) {
215 pwmChannel = 0;
216 }
217
218 int dutyCyc10bit = (int) (1023 * dutyCycle);
219
220 return c_CANifier_SetPWMOutput(m_handle, (int) pwmChannel,
221 dutyCyc10bit);
222}
223
224/**
225 * Enables PWM Outputs
226 * Currently supports PWM 0, PWM 1, and PWM 2
227 * @param pwmChannel Index of the PWM channel to enable.
228 * @param bEnable "True" enables output on the pwm channel.
229 * @return Error Code generated by function. 0 indicates no error.
230 */
231ErrorCode CANifier::EnablePWMOutput(int pwmChannel, bool bEnable) {
232 if (pwmChannel < 0) {
233 pwmChannel = 0;
234 }
235
236 return c_CANifier_EnablePWMOutput(m_handle, (int) pwmChannel,
237 bEnable);
238}
239
240/**
241 * Gets the PWM Input
242 * @param pwmChannel PWM channel to get.
243 * @param dutyCycleAndPeriod Double array to hold Duty Cycle [0] and Period [1].
244 * @return Error Code generated by function. 0 indicates no error.
245 */
246ErrorCode CANifier::GetPWMInput(PWMChannel pwmChannel, double dutyCycleAndPeriod[]) {
247 return c_CANifier_GetPWMInput(m_handle, pwmChannel,
248 dutyCycleAndPeriod);
249}
250
251//------ Custom Persistent Params ----------//
252
253/**
254 * Sets the value of a custom parameter. This is for arbitrary use.
255 *
256 * Sometimes it is necessary to save calibration/duty cycle/output
257 * information in the device. Particularly if the
258 * device is part of a subsystem that can be replaced.
259 *
260 * @param newValue
261 * Value for custom parameter.
262 * @param paramIndex
263 * Index of custom parameter. [0-1]
264 * @param timeoutMs
265 * Timeout value in ms. If nonzero, function will wait for
266 * config success and report an error if it times out.
267 * If zero, no blocking or checking is performed.
268 * @return Error Code generated by function. 0 indicates no error.
269 */
270ErrorCode CANifier::ConfigSetCustomParam(int newValue,
271 int paramIndex, int timeoutMs) {
272 return c_CANifier_ConfigSetCustomParam(m_handle, newValue, paramIndex, timeoutMs);
273}
274/**
275 * Gets the value of a custom parameter. This is for arbitrary use.
276 *
277 * Sometimes it is necessary to save calibration/duty cycle/output
278 * information in the device. Particularly if the
279 * device is part of a subsystem that can be replaced.
280 *
281 * @param paramIndex
282 * Index of custom parameter. [0-1]
283 * @param timeoutMs
284 * Timeout value in ms. If nonzero, function will wait for
285 * config success and report an error if it times out.
286 * If zero, no blocking or checking is performed.
287 * @return Value of the custom param.
288 */
289int CANifier::ConfigGetCustomParam(
290 int paramIndex, int timeoutMs) {
291 int readValue;
292 c_CANifier_ConfigGetCustomParam(m_handle, &readValue, paramIndex, timeoutMs);
293 return readValue;
294}
295
296//------ Generic Param API, typically not used ----------//
297/**
298 * Sets a parameter. Generally this is not used.
299 * This can be utilized in
300 * - Using new features without updating API installation.
301 * - Errata workarounds to circumvent API implementation.
302 * - Allows for rapid testing / unit testing of firmware.
303 *
304 * @param param
305 * Parameter enumeration.
306 * @param value
307 * Value of parameter.
308 * @param subValue
309 * Subvalue for parameter. Maximum value of 255.
310 * @param ordinal
311 * Ordinal of parameter.
312 * @param timeoutMs
313 * Timeout value in ms. If nonzero, function will wait for
314 * config success and report an error if it times out.
315 * If zero, no blocking or checking is performed.
316 * @return Error Code generated by function. 0 indicates no error.
317 */
318ErrorCode CANifier::ConfigSetParameter(ParamEnum param, double value,
319 uint8_t subValue, int ordinal, int timeoutMs) {
320 return c_CANifier_ConfigSetParameter(m_handle, param, value, subValue, ordinal, timeoutMs);
321
322}
323/**
324 * Gets a parameter. Generally this is not used.
325 * This can be utilized in
326 * - Using new features without updating API installation.
327 * - Errata workarounds to circumvent API implementation.
328 * - Allows for rapid testing / unit testing of firmware.
329 *
330 * @param param
331 * Parameter enumeration.
332 * @param ordinal
333 * Ordinal of parameter.
334 * @param timeoutMs
335 * Timeout value in ms. If nonzero, function will wait for
336 * config success and report an error if it times out.
337 * If zero, no blocking or checking is performed.
338 * @return Value of parameter.
339 */
340double CANifier::ConfigGetParameter(ParamEnum param, int ordinal, int timeoutMs) {
341 double value = 0;
342 c_CANifier_ConfigGetParameter(m_handle, param, &value, ordinal, timeoutMs);
343 return value;
344}
345
346//------ Frames ----------//
347/**
348 * Sets the period of the given status frame.
349 *
350 * @param statusFrame
351 * Frame whose period is to be changed.
352 * @param periodMs
353 * Period in ms for the given frame.
354 * @param timeoutMs
355 * Timeout value in ms. If nonzero, function will wait for
356 * config success and report an error if it times out.
357 * If zero, no blocking or checking is performed.
358 * @return Error Code generated by function. 0 indicates no error.
359 */
360ErrorCode CANifier::SetStatusFramePeriod(CANifierStatusFrame statusFrame, int periodMs,
361 int timeoutMs) {
362 return c_CANifier_SetStatusFramePeriod(m_handle, statusFrame, periodMs,
363 timeoutMs);
364}
365/**
366 * Gets the period of the given status frame.
367 *
368 * @param frame
369 * Frame to get the period of.
370 * @param timeoutMs
371 * Timeout value in ms. If nonzero, function will wait for
372 * config success and report an error if it times out.
373 * If zero, no blocking or checking is performed.
374 * @return Period of the given status frame.
375 */
376int CANifier::GetStatusFramePeriod(CANifierStatusFrame frame,
377 int timeoutMs) {
378 int periodMs = 0;
379 c_CANifier_GetStatusFramePeriod(m_handle, frame, &periodMs, timeoutMs);
380 return periodMs;
381}
382/**
383 * Sets the period of the given control frame.
384 *
385 * @param frame
386 * Frame whose period is to be changed.
387 * @param periodMs
388 * Period in ms for the given frame.
389 * @return Error Code generated by function. 0 indicates no error.
390 */
391ErrorCode CANifier::SetControlFramePeriod(CANifierControlFrame frame,
392 int periodMs) {
393 return c_CANifier_SetControlFramePeriod(m_handle, frame, periodMs);
394}
395//------ Firmware ----------//
396/**
397 * Gets the firmware version of the device.
398 *
399 * @return Firmware version of device.
400 */
401int CANifier::GetFirmwareVersion() {
402 int retval = -1;
403 c_CANifier_GetFirmwareVersion(m_handle, &retval);
404 return retval;
405}
406/**
407 * Returns true if the device has reset since last call.
408 *
409 * @return Has a Device Reset Occurred?
410 */
411bool CANifier::HasResetOccurred() {
412 bool retval = false;
413 c_CANifier_HasResetOccurred(m_handle, &retval);
414 return retval;
415}
416//------ Faults ----------//
417/**
418 * Gets the CANifier fault status
419 *
420 * @param toFill
421 * Container for fault statuses.
422 * @return Error Code generated by function. 0 indicates no error.
423 */
424ErrorCode CANifier::GetFaults(CANifierFaults & toFill) {
425 int faultBits;
426 ErrorCode retval = c_CANifier_GetFaults(m_handle, &faultBits);
427 toFill = CANifierFaults(faultBits);
428 return retval;
429}
430/**
431 * Gets the CANifier sticky fault status
432 *
433 * @param toFill
434 * Container for sticky fault statuses.
435 * @return Error Code generated by function. 0 indicates no error.
436 */
437ErrorCode CANifier::GetStickyFaults(CANifierStickyFaults & toFill) {
438 int faultBits;
439 ErrorCode retval = c_CANifier_GetFaults(m_handle, &faultBits);
440 toFill = CANifierStickyFaults(faultBits);
441 return retval;
442}
443/**
444 * Clears the Sticky Faults
445 *
446 * @return Error Code generated by function. 0 indicates no error.
447 */
448ErrorCode CANifier::ClearStickyFaults(int timeoutMs) {
449 return c_CANifier_ClearStickyFaults(m_handle, timeoutMs);
450}
451
452} // phoenix
453} // ctre
454#endif // CTR_EXCLUDE_WPILIB_CLASSES