blob: e0bde3cd5720951a5164b05e842960931c8362f6 [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
James Kuszmaul4b81d302019-12-14 20:53:14 -080012#include <hal/FRCUsageReporting.h>
13#include <hal/HALBase.h>
Brian Silverman41cdd3e2019-01-19 19:48:58 -080014#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"
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
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) {
James Kuszmaul4b81d302019-12-14 20:53:14 -080044 wpi_setHALErrorWithRange(status, 0, HAL_GetNumSolenoidChannels(), channel);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080045 m_solenoidHandle = HAL_kInvalidHandle;
46 return;
47 }
48
James Kuszmaul4b81d302019-12-14 20:53:14 -080049 HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_channel + 1,
50 m_moduleNumber + 1);
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);
James Kuszmaul4b81d302019-12-14 20:53:14 -080061 wpi_setHALError(status);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080062}
63
64bool Solenoid::Get() const {
65 if (StatusIsFatal()) return false;
66 int32_t status = 0;
67 bool value = HAL_GetSolenoid(m_solenoidHandle, &status);
James Kuszmaul4b81d302019-12-14 20:53:14 -080068 wpi_setHALError(status);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080069 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);
James Kuszmaul4b81d302019-12-14 20:53:14 -080082 wpi_setHALError(status);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080083}
84
85void Solenoid::StartPulse() {
86 if (StatusIsFatal()) return;
87 int32_t status = 0;
88 HAL_FireOneShot(m_solenoidHandle, &status);
James Kuszmaul4b81d302019-12-14 20:53:14 -080089 wpi_setHALError(status);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080090}
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}