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