blob: c860c44106cf9e7bf96d4927d1b6680144c86f85 [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/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"
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080019#include "frc/smartdashboard/SendableRegistry.h"
Brian Silverman41cdd3e2019-01-19 19:48:58 -080020
21using namespace frc;
22
23Solenoid::Solenoid(int channel)
24 : Solenoid(SensorUtil::GetDefaultSolenoidModule(), channel) {}
25
26Solenoid::Solenoid(int moduleNumber, int channel)
27 : SolenoidBase(moduleNumber), m_channel(channel) {
28 if (!SensorUtil::CheckSolenoidModule(m_moduleNumber)) {
29 wpi_setWPIErrorWithContext(ModuleIndexOutOfRange,
30 "Solenoid Module " + wpi::Twine(m_moduleNumber));
31 return;
32 }
33 if (!SensorUtil::CheckSolenoidChannel(m_channel)) {
34 wpi_setWPIErrorWithContext(ChannelIndexOutOfRange,
35 "Solenoid Channel " + wpi::Twine(m_channel));
36 return;
37 }
38
39 int32_t status = 0;
40 m_solenoidHandle = HAL_InitializeSolenoidPort(
41 HAL_GetPortWithModule(moduleNumber, channel), &status);
42 if (status != 0) {
43 wpi_setErrorWithContextRange(status, 0, HAL_GetNumSolenoidChannels(),
44 channel, HAL_GetErrorMessage(status));
45 m_solenoidHandle = HAL_kInvalidHandle;
46 return;
47 }
48
49 HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_channel,
50 m_moduleNumber);
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080051 SendableRegistry::GetInstance().AddLW(this, "Solenoid", m_moduleNumber,
52 m_channel);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080053}
54
55Solenoid::~Solenoid() { HAL_FreeSolenoidPort(m_solenoidHandle); }
56
Brian Silverman41cdd3e2019-01-19 19:48:58 -080057void Solenoid::Set(bool on) {
58 if (StatusIsFatal()) return;
59 int32_t status = 0;
60 HAL_SetSolenoid(m_solenoidHandle, on, &status);
61 wpi_setErrorWithContext(status, HAL_GetErrorMessage(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_setErrorWithContext(status, HAL_GetErrorMessage(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_setErrorWithContext(status, HAL_GetErrorMessage(status));
83}
84
85void Solenoid::StartPulse() {
86 if (StatusIsFatal()) return;
87 int32_t status = 0;
88 HAL_FireOneShot(m_solenoidHandle, &status);
89 wpi_setErrorWithContext(status, HAL_GetErrorMessage(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}