blob: b5abf2052ac7997a34dd4ff55fd609e35ac48e5f [file] [log] [blame]
Brian Silverman8fce7482020-01-05 13:18:21 -08001/*----------------------------------------------------------------------------*/
Austin Schuh1e69f942020-11-14 15:06:14 -08002/* Copyright (c) 2008-2020 FIRST. All Rights Reserved. */
Brian Silverman8fce7482020-01-05 13:18:21 -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/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;
Austin Schuh1e69f942020-11-14 15:06:14 -080059
Brian Silverman8fce7482020-01-05 13:18:21 -080060 int32_t status = 0;
61 HAL_SetSolenoid(m_solenoidHandle, on, &status);
62 wpi_setHALError(status);
63}
64
65bool Solenoid::Get() const {
66 if (StatusIsFatal()) return false;
Austin Schuh1e69f942020-11-14 15:06:14 -080067
Brian Silverman8fce7482020-01-05 13:18:21 -080068 int32_t status = 0;
69 bool value = HAL_GetSolenoid(m_solenoidHandle, &status);
70 wpi_setHALError(status);
Austin Schuh1e69f942020-11-14 15:06:14 -080071
Brian Silverman8fce7482020-01-05 13:18:21 -080072 return value;
73}
74
Austin Schuh1e69f942020-11-14 15:06:14 -080075void Solenoid::Toggle() { Set(!Get()); }
76
Brian Silverman8fce7482020-01-05 13:18:21 -080077bool Solenoid::IsBlackListed() const {
78 int value = GetPCMSolenoidBlackList(m_moduleNumber) & (1 << m_channel);
79 return (value != 0);
80}
81
82void Solenoid::SetPulseDuration(double durationSeconds) {
83 int32_t durationMS = durationSeconds * 1000;
84 if (StatusIsFatal()) return;
85 int32_t status = 0;
86 HAL_SetOneShotDuration(m_solenoidHandle, durationMS, &status);
87 wpi_setHALError(status);
88}
89
90void Solenoid::StartPulse() {
91 if (StatusIsFatal()) return;
92 int32_t status = 0;
93 HAL_FireOneShot(m_solenoidHandle, &status);
94 wpi_setHALError(status);
95}
96
97void Solenoid::InitSendable(SendableBuilder& builder) {
98 builder.SetSmartDashboardType("Solenoid");
99 builder.SetActuator(true);
100 builder.SetSafeState([=]() { Set(false); });
Austin Schuh1e69f942020-11-14 15:06:14 -0800101 builder.AddBooleanProperty(
102 "Value", [=]() { return Get(); }, [=](bool value) { Set(value); });
Brian Silverman8fce7482020-01-05 13:18:21 -0800103}