blob: 194537c37a8a9b7f2f026363aab080df8c7f1907 [file] [log] [blame]
Parker Schuhd3b7a8872018-02-19 16:42:27 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "frc971/wpilib/ahal/AnalogTrigger.h"
9
10#include <memory>
11
Austin Schuhf6b94632019-02-02 22:11:27 -080012#include <hal/HAL.h>
Parker Schuhd3b7a8872018-02-19 16:42:27 -080013
14#include "frc971/wpilib/ahal/AnalogInput.h"
15#include "frc971/wpilib/ahal/WPIErrors.h"
16
17using namespace frc;
18
19/**
20 * Constructor for an analog trigger given a channel number.
21 *
22 * @param channel The channel number on the roboRIO to represent. 0-3 are
23 * on-board 4-7 are on the MXP port.
24 */
25AnalogTrigger::AnalogTrigger(int channel)
26 : AnalogTrigger(new AnalogInput(channel)) {
27 m_ownsAnalog = true;
28}
29
30/**
31 * Construct an analog trigger given an analog input.
32 *
33 * This should be used in the case of sharing an analog channel between the
34 * trigger and an analog input object.
35 *
36 * @param channel The pointer to the existing AnalogInput object
37 */
38AnalogTrigger::AnalogTrigger(AnalogInput *input) {
39 m_analogInput = input;
40 int32_t status = 0;
41 int index = 0;
42 m_trigger = HAL_InitializeAnalogTrigger(input->m_port, &index, &status);
43 if (status != 0) {
44 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
45 m_index = std::numeric_limits<int>::max();
46 m_trigger = HAL_kInvalidHandle;
47 return;
48 }
49 m_index = index;
50
51 HAL_Report(HALUsageReporting::kResourceType_AnalogTrigger, input->m_channel);
52}
53
54AnalogTrigger::~AnalogTrigger() {
55 int32_t status = 0;
56 HAL_CleanAnalogTrigger(m_trigger, &status);
57
58 if (m_ownsAnalog && m_analogInput != nullptr) {
59 delete m_analogInput;
60 }
61}
62
63/**
64 * Set the upper and lower limits of the analog trigger.
65 *
66 * The limits are given in ADC codes. If oversampling is used, the units must
67 * be scaled appropriately.
68 *
69 * @param lower The lower limit of the trigger in ADC codes (12-bit values).
70 * @param upper The upper limit of the trigger in ADC codes (12-bit values).
71 */
72void AnalogTrigger::SetLimitsRaw(int lower, int upper) {
73 if (StatusIsFatal()) return;
74 int32_t status = 0;
75 HAL_SetAnalogTriggerLimitsRaw(m_trigger, lower, upper, &status);
76 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
77}
78
79/**
80 * Set the upper and lower limits of the analog trigger.
81 *
82 * The limits are given as floating point voltage values.
83 *
84 * @param lower The lower limit of the trigger in Volts.
85 * @param upper The upper limit of the trigger in Volts.
86 */
87void AnalogTrigger::SetLimitsVoltage(double lower, double upper) {
88 if (StatusIsFatal()) return;
89 int32_t status = 0;
90 HAL_SetAnalogTriggerLimitsVoltage(m_trigger, lower, upper, &status);
91 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
92}
93
94/**
95 * Configure the analog trigger to use the averaged vs. raw values.
96 *
97 * If the value is true, then the averaged value is selected for the analog
98 * trigger, otherwise the immediate value is used.
99 *
100 * @param useAveragedValue If true, use the Averaged value, otherwise use the
101 * instantaneous reading
102 */
103void AnalogTrigger::SetAveraged(bool useAveragedValue) {
104 if (StatusIsFatal()) return;
105 int32_t status = 0;
106 HAL_SetAnalogTriggerAveraged(m_trigger, useAveragedValue, &status);
107 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
108}
109
110/**
111 * Configure the analog trigger to use a filtered value.
112 *
113 * The analog trigger will operate with a 3 point average rejection filter. This
114 * is designed to help with 360 degree pot applications for the period where
115 * the pot crosses through zero.
116 *
117 * @param useFilteredValue If true, use the 3 point rejection filter, otherwise
118 * use the unfiltered value
119 */
120void AnalogTrigger::SetFiltered(bool useFilteredValue) {
121 if (StatusIsFatal()) return;
122 int32_t status = 0;
123 HAL_SetAnalogTriggerFiltered(m_trigger, useFilteredValue, &status);
124 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
125}
126
127/**
128 * Return the index of the analog trigger.
129 *
130 * This is the FPGA index of this analog trigger instance.
131 *
132 * @return The index of the analog trigger.
133 */
134int AnalogTrigger::GetIndex() const {
135 if (StatusIsFatal()) return -1;
136 return m_index;
137}
138
139/**
140 * Return the InWindow output of the analog trigger.
141 *
142 * True if the analog input is between the upper and lower limits.
143 *
144 * @return True if the analog input is between the upper and lower limits.
145 */
146bool AnalogTrigger::GetInWindow() {
147 if (StatusIsFatal()) return false;
148 int32_t status = 0;
149 bool result = HAL_GetAnalogTriggerInWindow(m_trigger, &status);
150 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
151 return result;
152}
153
154/**
155 * Return the TriggerState output of the analog trigger.
156 *
157 * True if above upper limit.
158 * False if below lower limit.
159 * If in Hysteresis, maintain previous state.
160 *
161 * @return True if above upper limit. False if below lower limit. If in
162 * Hysteresis, maintain previous state.
163 */
164bool AnalogTrigger::GetTriggerState() {
165 if (StatusIsFatal()) return false;
166 int32_t status = 0;
167 bool result = HAL_GetAnalogTriggerTriggerState(m_trigger, &status);
168 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
169 return result;
170}
171
172/**
173 * Creates an AnalogTriggerOutput object.
174 *
175 * Gets an output object that can be used for routing.
176 * Caller is responsible for deleting the AnalogTriggerOutput object.
177 *
178 * @param type An enum of the type of output object to create.
179 * @return A pointer to a new AnalogTriggerOutput object.
180 */
181std::shared_ptr<AnalogTriggerOutput> AnalogTrigger::CreateOutput(
182 AnalogTriggerType type) const {
183 if (StatusIsFatal()) return nullptr;
184 return std::shared_ptr<AnalogTriggerOutput>(
185 new AnalogTriggerOutput(*this, type), NullDeleter<AnalogTriggerOutput>());
186}