blob: b49d6a0fd9189a739d42bdadfdcfb8cfbb3595c4 [file] [log] [blame]
Brian Silverman26e4e522015-12-17 01:56:40 -05001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2008. All Rights Reserved.
3 */
4/* Open Source Software - may be modified and shared by FRC teams. The code */
5/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
6/*----------------------------------------------------------------------------*/
7
8#include "AnalogTrigger.h"
9
10#include "AnalogInput.h"
11#include "Resource.h"
12#include "WPIErrors.h"
13#include "HAL/Port.h"
14
15#include <memory>
16
17/**
18 * Constructor for an analog trigger given a channel number.
19 *
20 * @param channel The channel number on the roboRIO to represent. 0-3 are
21 * on-board 4-7 are on the MXP port.
22 */
23AnalogTrigger::AnalogTrigger(int32_t channel) {
24 void* port = getPort(channel);
25 int32_t status = 0;
26 uint32_t index = 0;
27 m_trigger = initializeAnalogTrigger(port, &index, &status);
28 wpi_setErrorWithContext(status, getHALErrorMessage(status));
29 freePort(port);
30 m_index = index;
31
32 HALReport(HALUsageReporting::kResourceType_AnalogTrigger, channel);
33}
34
35/**
36 * Construct an analog trigger given an analog input.
37 * This should be used in the case of sharing an analog channel between the
38 * trigger and an analog input object.
39 * @param channel The pointer to the existing AnalogInput object
40 */
41AnalogTrigger::AnalogTrigger(AnalogInput *input) :
42 AnalogTrigger(input->GetChannel()) {
43}
44
45AnalogTrigger::~AnalogTrigger() {
46 int32_t status = 0;
47 cleanAnalogTrigger(m_trigger, &status);
48 wpi_setErrorWithContext(status, getHALErrorMessage(status));
49}
50
51/**
52 * Set the upper and lower limits of the analog trigger.
53 * The limits are given in ADC codes. If oversampling is used, the units must
54 * be scaled
55 * appropriately.
56 * @param lower The lower limit of the trigger in ADC codes (12-bit values).
57 * @param upper The upper limit of the trigger in ADC codes (12-bit values).
58 */
59void AnalogTrigger::SetLimitsRaw(int32_t lower, int32_t upper) {
60 if (StatusIsFatal()) return;
61 int32_t status = 0;
62 setAnalogTriggerLimitsRaw(m_trigger, lower, upper, &status);
63 wpi_setErrorWithContext(status, getHALErrorMessage(status));
64}
65
66/**
67 * Set the upper and lower limits of the analog trigger.
68 * The limits are given as floating point voltage values.
69 * @param lower The lower limit of the trigger in Volts.
70 * @param upper The upper limit of the trigger in Volts.
71 */
72void AnalogTrigger::SetLimitsVoltage(float lower, float upper) {
73 if (StatusIsFatal()) return;
74 int32_t status = 0;
75 setAnalogTriggerLimitsVoltage(m_trigger, lower, upper, &status);
76 wpi_setErrorWithContext(status, getHALErrorMessage(status));
77}
78
79/**
80 * Configure the analog trigger to use the averaged vs. raw values.
81 * If the value is true, then the averaged value is selected for the analog
82 * trigger, otherwise
83 * the immediate value is used.
84 * @param useAveragedValue If true, use the Averaged value, otherwise use the
85 * instantaneous reading
86 */
87void AnalogTrigger::SetAveraged(bool useAveragedValue) {
88 if (StatusIsFatal()) return;
89 int32_t status = 0;
90 setAnalogTriggerAveraged(m_trigger, useAveragedValue, &status);
91 wpi_setErrorWithContext(status, getHALErrorMessage(status));
92}
93
94/**
95 * Configure the analog trigger to use a filtered value.
96 * The analog trigger will operate with a 3 point average rejection filter. This
97 * is designed to
98 * help with 360 degree pot applications for the period where the pot crosses
99 * through zero.
100 * @param useFilteredValue If true, use the 3 point rejection filter, otherwise
101 * use the unfiltered value
102 */
103void AnalogTrigger::SetFiltered(bool useFilteredValue) {
104 if (StatusIsFatal()) return;
105 int32_t status = 0;
106 setAnalogTriggerFiltered(m_trigger, useFilteredValue, &status);
107 wpi_setErrorWithContext(status, getHALErrorMessage(status));
108}
109
110/**
111 * Return the index of the analog trigger.
112 * This is the FPGA index of this analog trigger instance.
113 * @return The index of the analog trigger.
114 */
115uint32_t AnalogTrigger::GetIndex() const {
116 if (StatusIsFatal()) return std::numeric_limits<uint32_t>::max();
117 return m_index;
118}
119
120/**
121 * Return the InWindow output of the analog trigger.
122 * True if the analog input is between the upper and lower limits.
123 * @return True if the analog input is between the upper and lower limits.
124 */
125bool AnalogTrigger::GetInWindow() {
126 if (StatusIsFatal()) return false;
127 int32_t status = 0;
128 bool result = getAnalogTriggerInWindow(m_trigger, &status);
129 wpi_setErrorWithContext(status, getHALErrorMessage(status));
130 return result;
131}
132
133/**
134 * Return the TriggerState output of the analog trigger.
135 * True if above upper limit.
136 * False if below lower limit.
137 * If in Hysteresis, maintain previous state.
138 * @return True if above upper limit. False if below lower limit. If in
139 * Hysteresis, maintain previous state.
140 */
141bool AnalogTrigger::GetTriggerState() {
142 if (StatusIsFatal()) return false;
143 int32_t status = 0;
144 bool result = getAnalogTriggerTriggerState(m_trigger, &status);
145 wpi_setErrorWithContext(status, getHALErrorMessage(status));
146 return result;
147}
148
149/**
150 * Creates an AnalogTriggerOutput object.
151 * Gets an output object that can be used for routing.
152 * Caller is responsible for deleting the AnalogTriggerOutput object.
153 * @param type An enum of the type of output object to create.
154 * @return A pointer to a new AnalogTriggerOutput object.
155 */
156std::shared_ptr<AnalogTriggerOutput> AnalogTrigger::CreateOutput(
157 AnalogTriggerType type) const {
158 if (StatusIsFatal()) return nullptr;
159 return std::shared_ptr<AnalogTriggerOutput>(
160 new AnalogTriggerOutput(*this, type), NullDeleter<AnalogTriggerOutput>());
161}