blob: d70c3c36d7c29727cdce8bfacb4e7b7695ddc369 [file] [log] [blame]
Brian Silvermanf7f267a2017-02-04 16:16:08 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2008-2017. 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 "HAL/Solenoid.h"
9#include "Solenoid.h"
10
11#include <sstream>
12
13#include "HAL/HAL.h"
14#include "HAL/Ports.h"
15#include "LiveWindow/LiveWindow.h"
16#include "WPIErrors.h"
17
18using namespace frc;
19
20/**
21 * Constructor using the default PCM ID (0).
22 *
23 * @param channel The channel on the PCM to control (0..7).
24 */
25Solenoid::Solenoid(int channel)
26 : Solenoid(GetDefaultSolenoidModule(), channel) {}
27
28/**
29 * Constructor.
30 *
31 * @param moduleNumber The CAN ID of the PCM the solenoid is attached to
32 * @param channel The channel on the PCM to control (0..7).
33 */
34Solenoid::Solenoid(int moduleNumber, int channel)
35 : SolenoidBase(moduleNumber), m_channel(channel) {
36 std::stringstream buf;
37 if (!CheckSolenoidModule(m_moduleNumber)) {
38 buf << "Solenoid Module " << m_moduleNumber;
39 wpi_setWPIErrorWithContext(ModuleIndexOutOfRange, buf.str());
40 return;
41 }
42 if (!CheckSolenoidChannel(m_channel)) {
43 buf << "Solenoid Module " << m_channel;
44 wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf.str());
45 return;
46 }
47
48 int32_t status = 0;
49 m_solenoidHandle = HAL_InitializeSolenoidPort(
50 HAL_GetPortWithModule(moduleNumber, channel), &status);
51 if (status != 0) {
52 wpi_setErrorWithContextRange(status, 0, HAL_GetNumSolenoidChannels(),
53 channel, HAL_GetErrorMessage(status));
54 m_solenoidHandle = HAL_kInvalidHandle;
55 return;
56 }
57
58 LiveWindow::GetInstance()->AddActuator("Solenoid", m_moduleNumber, m_channel,
59 this);
60 HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_channel,
61 m_moduleNumber);
62}
63
64/**
65 * Destructor.
66 */
67Solenoid::~Solenoid() {
68 HAL_FreeSolenoidPort(m_solenoidHandle);
69 if (m_table != nullptr) m_table->RemoveTableListener(this);
70}
71
72/**
73 * Set the value of a solenoid.
74 *
75 * @param on Turn the solenoid output off or on.
76 */
77void Solenoid::Set(bool on) {
78 if (StatusIsFatal()) return;
79 int32_t status = 0;
80 HAL_SetSolenoid(m_solenoidHandle, on, &status);
81 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
82}
83
84/**
85 * Read the current value of the solenoid.
86 *
87 * @return The current value of the solenoid.
88 */
89bool Solenoid::Get() const {
90 if (StatusIsFatal()) return false;
91 int32_t status = 0;
92 bool value = HAL_GetSolenoid(m_solenoidHandle, &status);
93 wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
94 return value;
95}
96
97/**
98 * Check if solenoid is blacklisted.
99 *
100 * If a solenoid is shorted, it is added to the blacklist and
101 * disabled until power cycle, or until faults are cleared.
102 *
103 * @see ClearAllPCMStickyFaults()
104 *
105 * @return If solenoid is disabled due to short.
106 */
107bool Solenoid::IsBlackListed() const {
108 int value = GetPCMSolenoidBlackList(m_moduleNumber) & (1 << m_channel);
109 return (value != 0);
110}
111
112void Solenoid::ValueChanged(ITable* source, llvm::StringRef key,
113 std::shared_ptr<nt::Value> value, bool isNew) {
114 if (!value->IsBoolean()) return;
115 Set(value->GetBoolean());
116}
117
118void Solenoid::UpdateTable() {
119 if (m_table != nullptr) {
120 m_table->PutBoolean("Value", Get());
121 }
122}
123
124void Solenoid::StartLiveWindowMode() {
125 Set(false);
126 if (m_table != nullptr) {
127 m_table->AddTableListener("Value", this, true);
128 }
129}
130
131void Solenoid::StopLiveWindowMode() {
132 Set(false);
133 if (m_table != nullptr) {
134 m_table->RemoveTableListener(this);
135 }
136}
137
138std::string Solenoid::GetSmartDashboardType() const { return "Solenoid"; }
139
140void Solenoid::InitTable(std::shared_ptr<ITable> subTable) {
141 m_table = subTable;
142 UpdateTable();
143}
144
145std::shared_ptr<ITable> Solenoid::GetTable() const { return m_table; }