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