blob: 3445f5dfa464c0258efabac9cb45e24eca9fe760 [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/Solenoid.h"
9
10#include <utility>
11
12#include <hal/HAL.h>
13#include <hal/Ports.h>
14#include <hal/Solenoid.h>
15
16#include "frc/SensorUtil.h"
17#include "frc/WPIErrors.h"
18#include "frc/smartdashboard/SendableBuilder.h"
19
20using namespace frc;
21
22Solenoid::Solenoid(int channel)
23 : Solenoid(SensorUtil::GetDefaultSolenoidModule(), channel) {}
24
25Solenoid::Solenoid(int moduleNumber, int channel)
26 : SolenoidBase(moduleNumber), m_channel(channel) {
27 if (!SensorUtil::CheckSolenoidModule(m_moduleNumber)) {
28 wpi_setWPIErrorWithContext(ModuleIndexOutOfRange,
29 "Solenoid Module " + wpi::Twine(m_moduleNumber));
30 return;
31 }
32 if (!SensorUtil::CheckSolenoidChannel(m_channel)) {
33 wpi_setWPIErrorWithContext(ChannelIndexOutOfRange,
34 "Solenoid Channel " + wpi::Twine(m_channel));
35 return;
36 }
37
38 int32_t status = 0;
39 m_solenoidHandle = HAL_InitializeSolenoidPort(
40 HAL_GetPortWithModule(moduleNumber, channel), &status);
41 if (status != 0) {
42 wpi_setErrorWithContextRange(status, 0, HAL_GetNumSolenoidChannels(),
43 channel, HAL_GetErrorMessage(status));
44 m_solenoidHandle = HAL_kInvalidHandle;
45 return;
46 }
47
48 HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_channel,
49 m_moduleNumber);
50 SetName("Solenoid", m_moduleNumber, m_channel);
51}
52
53Solenoid::~Solenoid() { HAL_FreeSolenoidPort(m_solenoidHandle); }
54
55Solenoid::Solenoid(Solenoid&& rhs)
56 : SolenoidBase(std::move(rhs)), m_channel(std::move(rhs.m_channel)) {
57 std::swap(m_solenoidHandle, rhs.m_solenoidHandle);
58}
59
60Solenoid& Solenoid::operator=(Solenoid&& rhs) {
61 SolenoidBase::operator=(std::move(rhs));
62
63 std::swap(m_solenoidHandle, rhs.m_solenoidHandle);
64 m_channel = std::move(rhs.m_channel);
65
66 return *this;
67}
68
69void Solenoid::Set(bool on) {
70 if (StatusIsFatal()) return;
71 int32_t status = 0;
72 HAL_SetSolenoid(m_solenoidHandle, on, &status);
73 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
74}
75
76bool Solenoid::Get() const {
77 if (StatusIsFatal()) return false;
78 int32_t status = 0;
79 bool value = HAL_GetSolenoid(m_solenoidHandle, &status);
80 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
81 return value;
82}
83
84bool Solenoid::IsBlackListed() const {
85 int value = GetPCMSolenoidBlackList(m_moduleNumber) & (1 << m_channel);
86 return (value != 0);
87}
88
89void Solenoid::SetPulseDuration(double durationSeconds) {
90 int32_t durationMS = durationSeconds * 1000;
91 if (StatusIsFatal()) return;
92 int32_t status = 0;
93 HAL_SetOneShotDuration(m_solenoidHandle, durationMS, &status);
94 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
95}
96
97void Solenoid::StartPulse() {
98 if (StatusIsFatal()) return;
99 int32_t status = 0;
100 HAL_FireOneShot(m_solenoidHandle, &status);
101 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
102}
103
104void Solenoid::InitSendable(SendableBuilder& builder) {
105 builder.SetSmartDashboardType("Solenoid");
106 builder.SetActuator(true);
107 builder.SetSafeState([=]() { Set(false); });
108 builder.AddBooleanProperty("Value", [=]() { return Get(); },
109 [=](bool value) { Set(value); });
110}