blob: dfcf7e758842696825e60d96cdedb31b055acadc [file] [log] [blame]
jerrymf1579332013-02-07 01:56:28 +00001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2008. 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 $(WIND_BASE)/WPILib. */
5/*----------------------------------------------------------------------------*/
6
7#include "DoubleSolenoid.h"
8#include "NetworkCommunication/UsageReporting.h"
9#include "WPIErrors.h"
10#include <string.h>
11#include "LiveWindow/LiveWindow.h"
12
13/**
14 * Common function to implement constructor behavior.
15 */
16void DoubleSolenoid::InitSolenoid()
17{
jerrym37afdca2013-03-03 01:17:57 +000018 m_table = NULL;
jerrymf1579332013-02-07 01:56:28 +000019 char buf[64];
20 if (!CheckSolenoidModule(m_moduleNumber))
21 {
22 snprintf(buf, 64, "Solenoid Module %d", m_moduleNumber);
23 wpi_setWPIErrorWithContext(ModuleIndexOutOfRange, buf);
24 return;
25 }
26 if (!CheckSolenoidChannel(m_forwardChannel))
27 {
28 snprintf(buf, 64, "Solenoid Channel %d", m_forwardChannel);
29 wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf);
30 return;
31 }
32 if (!CheckSolenoidChannel(m_reverseChannel))
33 {
34 snprintf(buf, 64, "Solenoid Channel %d", m_reverseChannel);
35 wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf);
36 return;
37 }
38 Resource::CreateResourceObject(&m_allocated, tSolenoid::kNumDO7_0Elements * kSolenoidChannels);
39
40 snprintf(buf, 64, "Solenoid %d (Module %d)", m_forwardChannel, m_moduleNumber);
41 if (m_allocated->Allocate((m_moduleNumber - 1) * kSolenoidChannels + m_forwardChannel - 1, buf) == ~0ul)
42 {
43 CloneError(m_allocated);
44 return;
45 }
46 snprintf(buf, 64, "Solenoid %d (Module %d)", m_reverseChannel, m_moduleNumber);
47 if (m_allocated->Allocate((m_moduleNumber - 1) * kSolenoidChannels + m_reverseChannel - 1, buf) == ~0ul)
48 {
49 CloneError(m_allocated);
50 return;
51 }
52 m_forwardMask = 1 << (m_forwardChannel - 1);
53 m_reverseMask = 1 << (m_reverseChannel - 1);
54
55 nUsageReporting::report(nUsageReporting::kResourceType_Solenoid, m_forwardChannel, m_moduleNumber - 1);
56 nUsageReporting::report(nUsageReporting::kResourceType_Solenoid, m_reverseChannel, m_moduleNumber - 1);
57 LiveWindow::GetInstance()->AddSensor("DoubleSolenoid", m_moduleNumber, m_forwardChannel, this);
58}
59
60/**
61 * Constructor.
62 *
63 * @param forwardChannel The forward channel on the module to control.
64 * @param reverseChannel The reverse channel on the module to control.
65 */
66DoubleSolenoid::DoubleSolenoid(UINT32 forwardChannel, UINT32 reverseChannel)
67 : SolenoidBase (GetDefaultSolenoidModule())
68 , m_forwardChannel (forwardChannel)
69 , m_reverseChannel (reverseChannel)
70{
71 InitSolenoid();
72}
73
74/**
75 * Constructor.
76 *
77 * @param moduleNumber The solenoid module (1 or 2).
78 * @param forwardChannel The forward channel on the module to control.
79 * @param reverseChannel The reverse channel on the module to control.
80 */
81DoubleSolenoid::DoubleSolenoid(UINT8 moduleNumber, UINT32 forwardChannel, UINT32 reverseChannel)
82 : SolenoidBase (moduleNumber)
83 , m_forwardChannel (forwardChannel)
84 , m_reverseChannel (reverseChannel)
85{
86 InitSolenoid();
87}
88
89/**
90 * Destructor.
91 */
92DoubleSolenoid::~DoubleSolenoid()
93{
94 if (CheckSolenoidModule(m_moduleNumber))
95 {
96 m_allocated->Free((m_moduleNumber - 1) * kSolenoidChannels + m_forwardChannel - 1);
97 m_allocated->Free((m_moduleNumber - 1) * kSolenoidChannels + m_reverseChannel - 1);
98 }
99}
100
101/**
102 * Set the value of a solenoid.
103 *
104 * @param value Move the solenoid to forward, reverse, or don't move it.
105 */
106void DoubleSolenoid::Set(Value value)
107{
108 if (StatusIsFatal()) return;
109 UINT8 rawValue = 0x00;
110
111 switch(value)
112 {
113 case kOff:
114 rawValue = 0x00;
115 break;
116 case kForward:
117 rawValue = m_forwardMask;
118 break;
119 case kReverse:
120 rawValue = m_reverseMask;
121 break;
122 }
123
124 SolenoidBase::Set(rawValue, m_forwardMask | m_reverseMask);
125}
126
127/**
128 * Read the current value of the solenoid.
129 *
130 * @return The current value of the solenoid.
131 */
132DoubleSolenoid::Value DoubleSolenoid::Get()
133{
134 if (StatusIsFatal()) return kOff;
135 UINT8 value = GetAll();
136
137 if (value & m_forwardMask) return kForward;
138 if (value & m_reverseMask) return kReverse;
139 return kOff;
140}
141
142
143
144
145void DoubleSolenoid::ValueChanged(ITable* source, const std::string& key, EntryValue value, bool isNew) {
146 Value lvalue = kOff;
147 if (strcmp((char*)value.ptr, "Forward") == 0)
148 lvalue = kForward;
149 else if (strcmp((char*)value.ptr, "Reverse") == 0)
150 lvalue = kReverse;
151 Set(lvalue);
152}
153
154void DoubleSolenoid::UpdateTable() {
155 if (m_table != NULL) {
156 m_table->PutString("Value", (Get() == kForward ? "Forward" : (Get() == kReverse ? "Reverse" : "Off")));
157 }
158}
159
160void DoubleSolenoid::StartLiveWindowMode() {
161 Set(kOff);
jerrym37afdca2013-03-03 01:17:57 +0000162 if (m_table != NULL) {
163 m_table->AddTableListener("Value", this, true);
164 }
jerrymf1579332013-02-07 01:56:28 +0000165}
166
167void DoubleSolenoid::StopLiveWindowMode() {
168 Set(kOff);
jerrym37afdca2013-03-03 01:17:57 +0000169 if (m_table != NULL) {
170 m_table->RemoveTableListener(this);
171 }
jerrymf1579332013-02-07 01:56:28 +0000172}
173
174std::string DoubleSolenoid::GetSmartDashboardType() {
175 return "Double Solenoid";
176}
177
178void DoubleSolenoid::InitTable(ITable *subTable) {
179 m_table = subTable;
180 UpdateTable();
181}
182
183ITable * DoubleSolenoid::GetTable() {
184 return m_table;
185}
186