blob: e0bde3cd5720951a5164b05e842960931c8362f6 [file] [log] [blame]
Brian Silverman8fce7482020-01-05 13:18:21 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) 2008-2019 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/FRCUsageReporting.h>
13#include <hal/HALBase.h>
14#include <hal/Ports.h>
15#include <hal/Solenoid.h>
16
17#include "frc/SensorUtil.h"
18#include "frc/WPIErrors.h"
19#include "frc/smartdashboard/SendableBuilder.h"
20#include "frc/smartdashboard/SendableRegistry.h"
21
22using namespace frc;
23
24Solenoid::Solenoid(int channel)
25 : Solenoid(SensorUtil::GetDefaultSolenoidModule(), channel) {}
26
27Solenoid::Solenoid(int moduleNumber, int channel)
28 : SolenoidBase(moduleNumber), m_channel(channel) {
29 if (!SensorUtil::CheckSolenoidModule(m_moduleNumber)) {
30 wpi_setWPIErrorWithContext(ModuleIndexOutOfRange,
31 "Solenoid Module " + wpi::Twine(m_moduleNumber));
32 return;
33 }
34 if (!SensorUtil::CheckSolenoidChannel(m_channel)) {
35 wpi_setWPIErrorWithContext(ChannelIndexOutOfRange,
36 "Solenoid Channel " + wpi::Twine(m_channel));
37 return;
38 }
39
40 int32_t status = 0;
41 m_solenoidHandle = HAL_InitializeSolenoidPort(
42 HAL_GetPortWithModule(moduleNumber, channel), &status);
43 if (status != 0) {
44 wpi_setHALErrorWithRange(status, 0, HAL_GetNumSolenoidChannels(), channel);
45 m_solenoidHandle = HAL_kInvalidHandle;
46 return;
47 }
48
49 HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_channel + 1,
50 m_moduleNumber + 1);
51 SendableRegistry::GetInstance().AddLW(this, "Solenoid", m_moduleNumber,
52 m_channel);
53}
54
55Solenoid::~Solenoid() { HAL_FreeSolenoidPort(m_solenoidHandle); }
56
57void Solenoid::Set(bool on) {
58 if (StatusIsFatal()) return;
59 int32_t status = 0;
60 HAL_SetSolenoid(m_solenoidHandle, on, &status);
61 wpi_setHALError(status);
62}
63
64bool Solenoid::Get() const {
65 if (StatusIsFatal()) return false;
66 int32_t status = 0;
67 bool value = HAL_GetSolenoid(m_solenoidHandle, &status);
68 wpi_setHALError(status);
69 return value;
70}
71
72bool Solenoid::IsBlackListed() const {
73 int value = GetPCMSolenoidBlackList(m_moduleNumber) & (1 << m_channel);
74 return (value != 0);
75}
76
77void Solenoid::SetPulseDuration(double durationSeconds) {
78 int32_t durationMS = durationSeconds * 1000;
79 if (StatusIsFatal()) return;
80 int32_t status = 0;
81 HAL_SetOneShotDuration(m_solenoidHandle, durationMS, &status);
82 wpi_setHALError(status);
83}
84
85void Solenoid::StartPulse() {
86 if (StatusIsFatal()) return;
87 int32_t status = 0;
88 HAL_FireOneShot(m_solenoidHandle, &status);
89 wpi_setHALError(status);
90}
91
92void Solenoid::InitSendable(SendableBuilder& builder) {
93 builder.SetSmartDashboardType("Solenoid");
94 builder.SetActuator(true);
95 builder.SetSafeState([=]() { Set(false); });
96 builder.AddBooleanProperty("Value", [=]() { return Get(); },
97 [=](bool value) { Set(value); });
98}