Now you can download a copy of these docs so you can use them offline! Download now
DigitalOutput.cpp
1 /*----------------------------------------------------------------------------*/
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 "DigitalOutput.h"
8 #include "DigitalModule.h"
9 #include "NetworkCommunication/UsageReporting.h"
10 #include "Resource.h"
11 #include "WPIErrors.h"
12 
13 extern Resource *interruptsResource;
14 
20 void DigitalOutput::InitDigitalOutput(uint8_t moduleNumber, uint32_t channel)
21 {
22  m_table = NULL;
23  char buf[64];
24  if (!CheckDigitalModule(moduleNumber))
25  {
26  snprintf(buf, 64, "Digital Module %d", moduleNumber);
27  wpi_setWPIErrorWithContext(ModuleIndexOutOfRange, buf);
28  return;
29  }
30  if (!CheckDigitalChannel(channel))
31  {
32  snprintf(buf, 64, "Digital Channel %d", channel);
33  wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf);
34  return;
35  }
36  m_channel = channel;
37  m_pwmGenerator = ~0ul;
38  m_module = DigitalModule::GetInstance(moduleNumber);
39  m_module->AllocateDIO(m_channel, false);
40 
41  nUsageReporting::report(nUsageReporting::kResourceType_DigitalOutput, channel, moduleNumber - 1);
42 }
43 
51 {
52  InitDigitalOutput(GetDefaultDigitalModule(), channel);
53 }
54 
62 DigitalOutput::DigitalOutput(uint8_t moduleNumber, uint32_t channel)
63 {
64  InitDigitalOutput(moduleNumber, channel);
65 }
66 
71 {
72  if (StatusIsFatal()) return;
73  // Disable the PWM in case it was running.
74  DisablePWM();
75  m_module->FreeDIO(m_channel);
76 }
77 
82 void DigitalOutput::Set(uint32_t value)
83 {
84  if (StatusIsFatal()) return;
85  m_module->SetDIO(m_channel, value);
86 }
87 
92 {
93  return m_channel;
94 }
95 
102 void DigitalOutput::Pulse(float length)
103 {
104  if (StatusIsFatal()) return;
105  m_module->Pulse(m_channel, length);
106 }
107 
113 {
114  if (StatusIsFatal()) return false;
115  return m_module->IsPulsing(m_channel);
116 }
117 
128 {
129  if (StatusIsFatal()) return;
130  m_module->SetDO_PWMRate(rate);
131 }
132 
145 void DigitalOutput::EnablePWM(float initialDutyCycle)
146 {
147  if (StatusIsFatal()) return;
148  if (m_pwmGenerator != ~0ul) return;
149  m_pwmGenerator = m_module->AllocateDO_PWM();
150  m_module->SetDO_PWMDutyCycle(m_pwmGenerator, initialDutyCycle);
151  m_module->SetDO_PWMOutputChannel(m_pwmGenerator, m_channel);
152 }
153 
160 {
161  if (StatusIsFatal()) return;
162  // Disable the output by routing to a dead bit.
163  m_module->SetDO_PWMOutputChannel(m_pwmGenerator, kDigitalChannels);
164  m_module->FreeDO_PWM(m_pwmGenerator);
165  m_pwmGenerator = ~0ul;
166 }
167 
176 void DigitalOutput::UpdateDutyCycle(float dutyCycle)
177 {
178  if (StatusIsFatal()) return;
179  m_module->SetDO_PWMDutyCycle(m_pwmGenerator, dutyCycle);
180 }
181 
186 {
187  return DigitalModule::RemapDigitalChannel(GetChannel() - 1);
188 }
189 
194 {
195  if (StatusIsFatal()) return 0;
196  return m_module->GetNumber() - 1;
197 }
198 
203 {
204  return false;
205 }
206 
215 void DigitalOutput::RequestInterrupts(tInterruptHandler handler, void *param)
216 {
217  if (StatusIsFatal()) return;
218  uint32_t index = interruptsResource->Allocate("Sync Interrupt");
219  if (index == ~0ul)
220  {
221  CloneError(interruptsResource);
222  return;
223  }
224  m_interruptIndex = index;
225 
226  // Creates a manager too
227  AllocateInterrupts(false);
228 
229  tRioStatusCode localStatus = NiFpga_Status_Success;
230  m_interrupt->writeConfig_WaitForAck(false, &localStatus);
231  m_interrupt->writeConfig_Source_AnalogTrigger(GetAnalogTriggerForRouting(), &localStatus);
232  m_interrupt->writeConfig_Source_Channel(GetChannelForRouting(), &localStatus);
233  m_interrupt->writeConfig_Source_Module(GetModuleForRouting(), &localStatus);
234  SetUpSourceEdge(true, false);
235 
236  m_manager->registerHandler(handler, param, &localStatus);
237  wpi_setError(localStatus);
238 }
239 
247 {
248  if (StatusIsFatal()) return;
249  uint32_t index = interruptsResource->Allocate("Sync Interrupt");
250  if (index == ~0ul)
251  {
252  CloneError(interruptsResource);
253  return;
254  }
255  m_interruptIndex = index;
256 
257  AllocateInterrupts(true);
258 
259  tRioStatusCode localStatus = NiFpga_Status_Success;
260  m_interrupt->writeConfig_Source_AnalogTrigger(GetAnalogTriggerForRouting(), &localStatus);
261  m_interrupt->writeConfig_Source_Channel(GetChannelForRouting(), &localStatus);
262  m_interrupt->writeConfig_Source_Module(GetModuleForRouting(), &localStatus);
263  SetUpSourceEdge(true, false);
264  wpi_setError(localStatus);
265 }
266 
267 void DigitalOutput::SetUpSourceEdge(bool risingEdge, bool fallingEdge)
268 {
269  if (StatusIsFatal()) return;
270  if (m_interrupt == NULL)
271  {
272  wpi_setWPIErrorWithContext(NullParameter, "You must call RequestInterrupts before SetUpSourceEdge");
273  return;
274  }
275  tRioStatusCode localStatus = NiFpga_Status_Success;
276  if (m_interrupt != NULL)
277  {
278  m_interrupt->writeConfig_RisingEdge(risingEdge, &localStatus);
279  m_interrupt->writeConfig_FallingEdge(fallingEdge, &localStatus);
280  }
281  wpi_setError(localStatus);
282 }
283 
284 void DigitalOutput::ValueChanged(ITable* source, const std::string& key, EntryValue value, bool isNew) {
285  Set(value.b);
286 }
287 
289 }
290 
292  if (m_table != NULL) {
293  m_table->AddTableListener("Value", this, true);
294  }
295 }
296 
298  if (m_table != NULL) {
299  m_table->RemoveTableListener(this);
300  }
301 }
302 
304  return "Digital Output";
305 }
306 
308  m_table = subTable;
309  UpdateTable();
310 }
311 
313  return m_table;
314 }
315 
316 
virtual void ValueChanged(ITable *source, const std::string &key, EntryValue value, bool isNew)
virtual void RequestInterrupts()
static bool CheckDigitalChannel(uint32_t channel)
Definition: SensorBase.cpp:132
virtual void RemoveTableListener(ITableListener *listener)=0
bool IsPulsing(uint32_t channel)
Definition: ITable.h:26
virtual void AddTableListener(ITableListener *listener)=0
ITable * GetTable()
void SetDIO(uint32_t channel, short value)
void StartLiveWindowMode()
void EnablePWM(float initialDutyCycle)
void InitTable(ITable *subTable)
void Pulse(uint32_t channel, float pulseLength)
void SetDO_PWMOutputChannel(uint32_t pwmGenerator, uint32_t channel)
virtual uint32_t GetModuleForRouting()
void FreeDIO(uint32_t channel)
void SetDO_PWMDutyCycle(uint32_t pwmGenerator, float dutyCycle)
bool AllocateDIO(uint32_t channel, bool input)
void SetDO_PWMRate(float rate)
std::string GetSmartDashboardType()
uint32_t Allocate(const char *resourceDesc)
Definition: Resource.cpp:62
virtual ~DigitalOutput()
uint32_t AllocateDO_PWM()
void Pulse(float length)
DigitalOutput(uint32_t channel)
void UpdateDutyCycle(float dutyCycle)
void StopLiveWindowMode()
virtual bool GetAnalogTriggerForRouting()
virtual bool StatusIsFatal() const
Check if the current error code represents a fatal error.
Definition: ErrorBase.cpp:178
static bool CheckDigitalModule(uint8_t moduleNumber)
Definition: SensorBase.cpp:86
virtual uint32_t GetChannelForRouting()
static DigitalModule * GetInstance(uint8_t moduleNumber)
void SetPWMRate(float rate)
void Set(uint32_t value)
Definition: ITable.h:13
uint32_t GetChannel()
void FreeDO_PWM(uint32_t pwmGenerator)

Generated on Sat Apr 26 2014 12:26:45 for WPILibC++ by doxygen 1.8.6