blob: 603c94b88bb9e4a31d11190e6ff5c42bfa75a492 [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -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 "frc/PWM.h"
9
10#include <utility>
11
12#include <hal/HAL.h>
13#include <hal/PWM.h>
14#include <hal/Ports.h>
15
16#include "frc/SensorUtil.h"
17#include "frc/Utility.h"
18#include "frc/WPIErrors.h"
19#include "frc/smartdashboard/SendableBuilder.h"
20
21using namespace frc;
22
23PWM::PWM(int channel) {
24 if (!SensorUtil::CheckPWMChannel(channel)) {
25 wpi_setWPIErrorWithContext(ChannelIndexOutOfRange,
26 "PWM Channel " + wpi::Twine(channel));
27 return;
28 }
29
30 int32_t status = 0;
31 m_handle = HAL_InitializePWMPort(HAL_GetPort(channel), &status);
32 if (status != 0) {
33 wpi_setErrorWithContextRange(status, 0, HAL_GetNumPWMChannels(), channel,
34 HAL_GetErrorMessage(status));
35 m_channel = std::numeric_limits<int>::max();
36 m_handle = HAL_kInvalidHandle;
37 return;
38 }
39
40 m_channel = channel;
41
42 HAL_SetPWMDisabled(m_handle, &status);
43 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
44 status = 0;
45 HAL_SetPWMEliminateDeadband(m_handle, false, &status);
46 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
47
48 HAL_Report(HALUsageReporting::kResourceType_PWM, channel);
49 SetName("PWM", channel);
50
51 SetSafetyEnabled(false);
52}
53
54PWM::~PWM() {
55 int32_t status = 0;
56
57 HAL_SetPWMDisabled(m_handle, &status);
58 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
59
60 HAL_FreePWMPort(m_handle, &status);
61 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
62}
63
64PWM::PWM(PWM&& rhs)
65 : MotorSafety(std::move(rhs)),
66 SendableBase(std::move(rhs)),
67 m_channel(std::move(rhs.m_channel)) {
68 std::swap(m_handle, rhs.m_handle);
69}
70
71PWM& PWM::operator=(PWM&& rhs) {
72 ErrorBase::operator=(std::move(rhs));
73 SendableBase::operator=(std::move(rhs));
74
75 m_channel = std::move(rhs.m_channel);
76 std::swap(m_handle, rhs.m_handle);
77
78 return *this;
79}
80
81void PWM::StopMotor() { SetDisabled(); }
82
83void PWM::GetDescription(wpi::raw_ostream& desc) const {
84 desc << "PWM " << GetChannel();
85}
86
87void PWM::SetRaw(uint16_t value) {
88 if (StatusIsFatal()) return;
89
90 int32_t status = 0;
91 HAL_SetPWMRaw(m_handle, value, &status);
92 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
93}
94
95uint16_t PWM::GetRaw() const {
96 if (StatusIsFatal()) return 0;
97
98 int32_t status = 0;
99 uint16_t value = HAL_GetPWMRaw(m_handle, &status);
100 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
101
102 return value;
103}
104
105void PWM::SetPosition(double pos) {
106 if (StatusIsFatal()) return;
107 int32_t status = 0;
108 HAL_SetPWMPosition(m_handle, pos, &status);
109 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
110}
111
112double PWM::GetPosition() const {
113 if (StatusIsFatal()) return 0.0;
114 int32_t status = 0;
115 double position = HAL_GetPWMPosition(m_handle, &status);
116 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
117 return position;
118}
119
120void PWM::SetSpeed(double speed) {
121 if (StatusIsFatal()) return;
122 int32_t status = 0;
123 HAL_SetPWMSpeed(m_handle, speed, &status);
124 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
125
126 Feed();
127}
128
129double PWM::GetSpeed() const {
130 if (StatusIsFatal()) return 0.0;
131 int32_t status = 0;
132 double speed = HAL_GetPWMSpeed(m_handle, &status);
133 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
134 return speed;
135}
136
137void PWM::SetDisabled() {
138 if (StatusIsFatal()) return;
139
140 int32_t status = 0;
141
142 HAL_SetPWMDisabled(m_handle, &status);
143 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
144}
145
146void PWM::SetPeriodMultiplier(PeriodMultiplier mult) {
147 if (StatusIsFatal()) return;
148
149 int32_t status = 0;
150
151 switch (mult) {
152 case kPeriodMultiplier_4X:
153 HAL_SetPWMPeriodScale(m_handle, 3,
154 &status); // Squelch 3 out of 4 outputs
155 break;
156 case kPeriodMultiplier_2X:
157 HAL_SetPWMPeriodScale(m_handle, 1,
158 &status); // Squelch 1 out of 2 outputs
159 break;
160 case kPeriodMultiplier_1X:
161 HAL_SetPWMPeriodScale(m_handle, 0, &status); // Don't squelch any outputs
162 break;
163 default:
164 wpi_assert(false);
165 }
166
167 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
168}
169
170void PWM::SetZeroLatch() {
171 if (StatusIsFatal()) return;
172
173 int32_t status = 0;
174
175 HAL_LatchPWMZero(m_handle, &status);
176 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
177}
178
179void PWM::EnableDeadbandElimination(bool eliminateDeadband) {
180 if (StatusIsFatal()) return;
181 int32_t status = 0;
182 HAL_SetPWMEliminateDeadband(m_handle, eliminateDeadband, &status);
183 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
184}
185
186void PWM::SetBounds(double max, double deadbandMax, double center,
187 double deadbandMin, double min) {
188 if (StatusIsFatal()) return;
189 int32_t status = 0;
190 HAL_SetPWMConfig(m_handle, max, deadbandMax, center, deadbandMin, min,
191 &status);
192 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
193}
194
195void PWM::SetRawBounds(int max, int deadbandMax, int center, int deadbandMin,
196 int min) {
197 if (StatusIsFatal()) return;
198 int32_t status = 0;
199 HAL_SetPWMConfigRaw(m_handle, max, deadbandMax, center, deadbandMin, min,
200 &status);
201 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
202}
203
204void PWM::GetRawBounds(int* max, int* deadbandMax, int* center,
205 int* deadbandMin, int* min) {
206 int32_t status = 0;
207 HAL_GetPWMConfigRaw(m_handle, max, deadbandMax, center, deadbandMin, min,
208 &status);
209 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
210}
211
212int PWM::GetChannel() const { return m_channel; }
213
214void PWM::InitSendable(SendableBuilder& builder) {
215 builder.SetSmartDashboardType("PWM");
216 builder.SetActuator(true);
217 builder.SetSafeState([=]() { SetDisabled(); });
218 builder.AddDoubleProperty("Value", [=]() { return GetRaw(); },
219 [=](double value) { SetRaw(value); });
220}