blob: 393accc799464e588f63a49b06b71987ecc8e3a3 [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
Brian Silverman8fce7482020-01-05 13:18:21 -08004
5#include "frc/PWM.h"
6
7#include <utility>
8
9#include <hal/FRCUsageReporting.h>
10#include <hal/HALBase.h>
11#include <hal/PWM.h>
12#include <hal/Ports.h>
Austin Schuh812d0d12021-11-04 20:16:48 -070013#include <wpi/StackTrace.h>
14#include <wpi/sendable/SendableBuilder.h>
15#include <wpi/sendable/SendableRegistry.h>
Brian Silverman8fce7482020-01-05 13:18:21 -080016
Austin Schuh812d0d12021-11-04 20:16:48 -070017#include "frc/Errors.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080018#include "frc/SensorUtil.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080019
20using namespace frc;
21
Austin Schuh812d0d12021-11-04 20:16:48 -070022PWM::PWM(int channel, bool registerSendable) {
Brian Silverman8fce7482020-01-05 13:18:21 -080023 if (!SensorUtil::CheckPWMChannel(channel)) {
Austin Schuh812d0d12021-11-04 20:16:48 -070024 throw FRC_MakeError(err::ChannelIndexOutOfRange, "Channel {}", channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080025 }
26
Austin Schuh812d0d12021-11-04 20:16:48 -070027 auto stack = wpi::GetStackTrace(1);
Brian Silverman8fce7482020-01-05 13:18:21 -080028 int32_t status = 0;
Austin Schuh812d0d12021-11-04 20:16:48 -070029 m_handle =
30 HAL_InitializePWMPort(HAL_GetPort(channel), stack.c_str(), &status);
31 FRC_CheckErrorStatus(status, "Channel {}", channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080032
33 m_channel = channel;
34
35 HAL_SetPWMDisabled(m_handle, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070036 FRC_CheckErrorStatus(status, "Channel {}", channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080037 status = 0;
38 HAL_SetPWMEliminateDeadband(m_handle, false, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070039 FRC_CheckErrorStatus(status, "Channel {}", channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080040
41 HAL_Report(HALUsageReporting::kResourceType_PWM, channel + 1);
Austin Schuh812d0d12021-11-04 20:16:48 -070042 if (registerSendable) {
43 wpi::SendableRegistry::AddLW(this, "PWM", channel);
44 }
Brian Silverman8fce7482020-01-05 13:18:21 -080045}
46
47PWM::~PWM() {
48 int32_t status = 0;
49
50 HAL_SetPWMDisabled(m_handle, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070051 FRC_ReportError(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080052
53 HAL_FreePWMPort(m_handle, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070054 FRC_ReportError(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080055}
56
57void PWM::SetRaw(uint16_t value) {
Brian Silverman8fce7482020-01-05 13:18:21 -080058 int32_t status = 0;
59 HAL_SetPWMRaw(m_handle, value, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070060 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080061}
62
63uint16_t PWM::GetRaw() const {
Brian Silverman8fce7482020-01-05 13:18:21 -080064 int32_t status = 0;
65 uint16_t value = HAL_GetPWMRaw(m_handle, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070066 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080067
68 return value;
69}
70
71void PWM::SetPosition(double pos) {
Brian Silverman8fce7482020-01-05 13:18:21 -080072 int32_t status = 0;
73 HAL_SetPWMPosition(m_handle, pos, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070074 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080075}
76
77double PWM::GetPosition() const {
Brian Silverman8fce7482020-01-05 13:18:21 -080078 int32_t status = 0;
79 double position = HAL_GetPWMPosition(m_handle, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070080 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080081 return position;
82}
83
84void PWM::SetSpeed(double speed) {
Brian Silverman8fce7482020-01-05 13:18:21 -080085 int32_t status = 0;
86 HAL_SetPWMSpeed(m_handle, speed, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070087 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080088}
89
90double PWM::GetSpeed() const {
Brian Silverman8fce7482020-01-05 13:18:21 -080091 int32_t status = 0;
92 double speed = HAL_GetPWMSpeed(m_handle, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070093 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080094 return speed;
95}
96
97void PWM::SetDisabled() {
Brian Silverman8fce7482020-01-05 13:18:21 -080098 int32_t status = 0;
Brian Silverman8fce7482020-01-05 13:18:21 -080099 HAL_SetPWMDisabled(m_handle, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -0700100 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -0800101}
102
103void PWM::SetPeriodMultiplier(PeriodMultiplier mult) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800104 int32_t status = 0;
105
106 switch (mult) {
107 case kPeriodMultiplier_4X:
108 HAL_SetPWMPeriodScale(m_handle, 3,
109 &status); // Squelch 3 out of 4 outputs
110 break;
111 case kPeriodMultiplier_2X:
112 HAL_SetPWMPeriodScale(m_handle, 1,
113 &status); // Squelch 1 out of 2 outputs
114 break;
115 case kPeriodMultiplier_1X:
116 HAL_SetPWMPeriodScale(m_handle, 0, &status); // Don't squelch any outputs
117 break;
118 default:
Austin Schuh812d0d12021-11-04 20:16:48 -0700119 throw FRC_MakeError(err::InvalidParameter, "PeriodMultiplier value {}",
120 mult);
Brian Silverman8fce7482020-01-05 13:18:21 -0800121 }
122
Austin Schuh812d0d12021-11-04 20:16:48 -0700123 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -0800124}
125
126void PWM::SetZeroLatch() {
Brian Silverman8fce7482020-01-05 13:18:21 -0800127 int32_t status = 0;
Brian Silverman8fce7482020-01-05 13:18:21 -0800128 HAL_LatchPWMZero(m_handle, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -0700129 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -0800130}
131
132void PWM::EnableDeadbandElimination(bool eliminateDeadband) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800133 int32_t status = 0;
134 HAL_SetPWMEliminateDeadband(m_handle, eliminateDeadband, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -0700135 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -0800136}
137
138void PWM::SetBounds(double max, double deadbandMax, double center,
139 double deadbandMin, double min) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800140 int32_t status = 0;
141 HAL_SetPWMConfig(m_handle, max, deadbandMax, center, deadbandMin, min,
142 &status);
Austin Schuh812d0d12021-11-04 20:16:48 -0700143 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -0800144}
145
146void PWM::SetRawBounds(int max, int deadbandMax, int center, int deadbandMin,
147 int min) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800148 int32_t status = 0;
149 HAL_SetPWMConfigRaw(m_handle, max, deadbandMax, center, deadbandMin, min,
150 &status);
Austin Schuh812d0d12021-11-04 20:16:48 -0700151 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -0800152}
153
154void PWM::GetRawBounds(int* max, int* deadbandMax, int* center,
155 int* deadbandMin, int* min) {
156 int32_t status = 0;
157 HAL_GetPWMConfigRaw(m_handle, max, deadbandMax, center, deadbandMin, min,
158 &status);
Austin Schuh812d0d12021-11-04 20:16:48 -0700159 FRC_CheckErrorStatus(status, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -0800160}
161
Austin Schuh812d0d12021-11-04 20:16:48 -0700162int PWM::GetChannel() const {
163 return m_channel;
164}
Brian Silverman8fce7482020-01-05 13:18:21 -0800165
Austin Schuh812d0d12021-11-04 20:16:48 -0700166void PWM::InitSendable(wpi::SendableBuilder& builder) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800167 builder.SetSmartDashboardType("PWM");
168 builder.SetActuator(true);
Austin Schuh812d0d12021-11-04 20:16:48 -0700169 builder.SetSafeState([=] { SetDisabled(); });
Austin Schuh1e69f942020-11-14 15:06:14 -0800170 builder.AddDoubleProperty(
Austin Schuh812d0d12021-11-04 20:16:48 -0700171 "Value", [=] { return GetRaw(); }, [=](double value) { SetRaw(value); });
Brian Silverman8fce7482020-01-05 13:18:21 -0800172}