Now you can download a copy of these docs so you can use them offline! Download now
DriverStationEnhancedIO.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 "DriverStationEnhancedIO.h"
8 #include "NetworkCommunication/UsageReporting.h"
9 #include "Synchronized.h"
10 #include "WPIErrors.h"
11 #include <strLib.h>
12 
18 DriverStationEnhancedIO::DriverStationEnhancedIO()
19  : m_inputValid (false)
20  , m_outputValid (false)
21  , m_configChanged (false)
22  , m_requestEnhancedEnable (false)
23 {
24  bzero((char*)&m_inputData, sizeof(m_inputData));
25  bzero((char*)&m_outputData, sizeof(m_outputData));
26  m_outputData.size = sizeof(m_outputData) - 1;
27  m_outputData.id = kOutputBlockID;
28  // Expected to be active low, so initialize inactive.
29  m_outputData.data.fixed_digital_out = 0x3;
30  m_inputDataSemaphore = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
31  m_outputDataSemaphore = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
32  m_encoderOffsets[0] = 0;
33  m_encoderOffsets[1] = 0;
34 }
35 
41 DriverStationEnhancedIO::~DriverStationEnhancedIO()
42 {
43  semDelete(m_outputDataSemaphore);
44  semDelete(m_inputDataSemaphore);
45 }
46 
52 void DriverStationEnhancedIO::UpdateData()
53 {
54  int32_t retVal;
55  {
56  status_block_t tempOutputData;
57  Synchronized sync(m_outputDataSemaphore);
58  if (m_outputValid || m_configChanged || m_requestEnhancedEnable)
59  {
60  m_outputData.flags = kStatusValid;
61  if (m_requestEnhancedEnable)
62  {
63  // Someone called one of the get config APIs, but we are not in enhanced mode.
64  m_outputData.flags |= kForceEnhancedMode;
65  }
66  if (m_configChanged)
67  {
68  if (!m_outputValid)
69  {
70  // Someone called one of the set config APIs, but we are not in enhanced mode.
71  m_outputData.flags |= kForceEnhancedMode;
72  }
73  m_outputData.flags |= kStatusConfigChanged;
74  }
75  overrideIOConfig((char*)&m_outputData, 5);
76  }
77  retVal = getDynamicControlData(kOutputBlockID, (char*)&tempOutputData, sizeof(status_block_t), 5);
78  if (retVal == 0)
79  {
80  if (m_outputValid)
81  {
82  if (m_configChanged)
83  {
84  // If our config change made the round trip then clear the flag.
85  if (IsConfigEqual(tempOutputData, m_outputData))
86  {
87  m_configChanged = false;
88  }
89  }
90  else
91  {
92  // TODO: This won't work until artf1128 is fixed
93  //if (tempOutputData.flags & kStatusConfigChanged)
94  {
95  // Configuration was updated on the DS, so update our local cache.
96  MergeConfigIntoOutput(tempOutputData, m_outputData);
97  }
98  }
99  }
100  else
101  {
102  // Initialize the local cache.
103  MergeConfigIntoOutput(tempOutputData, m_outputData);
104  }
105  m_requestEnhancedEnable = false;
106  m_outputValid = true;
107  }
108  else
109  {
110  m_outputValid = false;
111  m_inputValid = false;
112  }
113  }
114  {
115  Synchronized sync(m_inputDataSemaphore);
116  control_block_t tempInputData;
117  retVal = getDynamicControlData(kInputBlockID, (char*)&tempInputData, sizeof(control_block_t), 5);
118  if (retVal == 0 && tempInputData.data.api_version == kSupportedAPIVersion)
119  {
120  m_inputData = tempInputData;
121  m_inputValid = true;
122  }
123  else
124  {
125  m_outputValid = false;
126  m_inputValid = false;
127  }
128  }
129 }
130 
134 void DriverStationEnhancedIO::MergeConfigIntoOutput(const status_block_t &dsOutputBlock, status_block_t &localCache)
135 {
136  localCache.data.digital = (localCache.data.digital & dsOutputBlock.data.digital_oe) |
137  (dsOutputBlock.data.digital & ~dsOutputBlock.data.digital_oe);
138  localCache.data.digital_oe = dsOutputBlock.data.digital_oe;
139  localCache.data.digital_pe = dsOutputBlock.data.digital_pe;
140  localCache.data.pwm_period[0] = dsOutputBlock.data.pwm_period[0];
141  localCache.data.pwm_period[1] = dsOutputBlock.data.pwm_period[1];
142  localCache.data.enables = dsOutputBlock.data.enables;
143 }
144 
148 bool DriverStationEnhancedIO::IsConfigEqual(const status_block_t &dsOutputBlock, const status_block_t &localCache)
149 {
150  if (localCache.data.digital_oe != dsOutputBlock.data.digital_oe) return false;
151  if ((localCache.data.digital & ~dsOutputBlock.data.digital) !=
152  (dsOutputBlock.data.digital & ~dsOutputBlock.data.digital)) return false;
153  if (localCache.data.digital_pe != dsOutputBlock.data.digital_pe) return false;
154  if (localCache.data.pwm_period[0] != dsOutputBlock.data.pwm_period[0]) return false;
155  if (localCache.data.pwm_period[1] != dsOutputBlock.data.pwm_period[1]) return false;
156  if (localCache.data.enables != dsOutputBlock.data.enables) return false;
157  return true;
158 }
159 
166 double DriverStationEnhancedIO::GetAcceleration(tAccelChannel channel)
167 {
168  if (channel < 1 || channel > 2)
169  {
170  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 2");
171  return 0.0;
172  }
173  if (!m_inputValid)
174  {
175  wpi_setWPIError(EnhancedIOMissing);
176  return 0.0;
177  }
178 
179  static uint8_t reported_mask = 0;
180  if (!(reported_mask & (1 >> channel)))
181  {
182  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, channel, nUsageReporting::kDriverStationEIO_Acceleration);
183  reported_mask |= (1 >> channel);
184  }
185 
186  Synchronized sync(m_inputDataSemaphore);
187  return (m_inputData.data.accel[channel] - kAccelOffset) / kAccelScale;
188 }
189 
196 double DriverStationEnhancedIO::GetAnalogIn(uint32_t channel)
197 {
198  // 3.3V is the analog reference voltage
199  return GetAnalogInRatio(channel) * kAnalogInputReference;
200 }
201 
209 {
210  if (channel < 1 || channel > 8)
211  {
212  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 8");
213  return 0.0;
214  }
215  if (!m_inputValid)
216  {
217  wpi_setWPIError(EnhancedIOMissing);
218  return 0.0;
219  }
220 
221  static uint16_t reported_mask = 0;
222  if (!(reported_mask & (1 >> channel)))
223  {
224  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, channel, nUsageReporting::kDriverStationEIO_AnalogIn);
225  reported_mask |= (1 >> channel);
226  }
227 
228  Synchronized sync(m_inputDataSemaphore);
229  return m_inputData.data.analog[channel-1] / kAnalogInputResolution;
230 }
231 
242 {
243  if (channel < 1 || channel > 2)
244  {
245  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 2");
246  return 0.0;
247  }
248  if (!m_outputValid)
249  {
250  wpi_setWPIError(EnhancedIOMissing);
251  return 0.0;
252  }
253 
254  Synchronized sync(m_outputDataSemaphore);
255  return m_outputData.data.dac[channel-1] * kAnalogOutputReference / kAnalogOutputResolution;
256 }
257 
271 void DriverStationEnhancedIO::SetAnalogOut(uint32_t channel, double value)
272 {
273  if (channel < 1 || channel > 2)
274  {
275  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 2");
276  return;
277  }
278  if (!m_outputValid)
279  {
280  wpi_setWPIError(EnhancedIOMissing);
281  return;
282  }
283  if (value < 0.0) value = 0.0;
284  if (value > kAnalogOutputReference) value = kAnalogOutputReference;
285 
286  static uint8_t reported_mask = 0;
287  if (!(reported_mask & (1 >> channel)))
288  {
289  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, channel, nUsageReporting::kDriverStationEIO_AnalogOut);
290  reported_mask |= (1 >> channel);
291  }
292 
293  Synchronized sync(m_outputDataSemaphore);
294  m_outputData.data.dac[channel-1] = (uint8_t)(value / kAnalogOutputReference * kAnalogOutputResolution);
295 }
296 
313 {
314  if (channel < 1 || channel > 6)
315  {
316  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 6");
317  return false;
318  }
319 
320  static uint8_t reported_mask = 0;
321  if (!(reported_mask & (1 >> channel)))
322  {
323  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, channel, nUsageReporting::kDriverStationEIO_Button);
324  reported_mask |= (1 >> channel);
325  }
326 
327  return ((GetButtons() >> (channel-1)) & 1) != 0;
328 }
329 
336 {
337  if (!m_inputValid)
338  {
339  wpi_setWPIError(EnhancedIOMissing);
340  return 0;
341  }
342  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, 0, nUsageReporting::kDriverStationEIO_Button);
343  Synchronized sync(m_inputDataSemaphore);
344  return m_inputData.data.buttons;
345 }
346 
353 void DriverStationEnhancedIO::SetLED(uint32_t channel, bool value)
354 {
355  if (channel < 1 || channel > 8)
356  {
357  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 8");
358  return;
359  }
360  if (!m_outputValid)
361  {
362  wpi_setWPIError(EnhancedIOMissing);
363  return;
364  }
365 
366  static uint16_t reported_mask = 0;
367  if (!(reported_mask & (1 >> channel)))
368  {
369  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, channel, nUsageReporting::kDriverStationEIO_LED);
370  reported_mask |= (1 >> channel);
371  }
372 
373  uint8_t leds;
374  Synchronized sync(m_outputDataSemaphore);
375  leds = m_outputData.data.leds;
376 
377  leds &= ~(1 << (channel-1));
378  if (value) leds |= 1 << (channel-1);
379 
380  m_outputData.data.leds = leds;
381 }
382 
389 {
390  if (!m_outputValid)
391  {
392  wpi_setWPIError(EnhancedIOMissing);
393  return;
394  }
395  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, 0, nUsageReporting::kDriverStationEIO_LED);
396  Synchronized sync(m_outputDataSemaphore);
397  m_outputData.data.leds = value;
398 }
399 
407 {
408  if (channel < 1 || channel > 16)
409  {
410  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 16");
411  return false;
412  }
413 
414  static uint32_t reported_mask = 0;
415  if (!(reported_mask & (1 >> channel)))
416  {
417  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, channel, nUsageReporting::kDriverStationEIO_DigitalIn);
418  reported_mask |= (1 >> channel);
419  }
420 
421  return ((GetDigitals() >> (channel-1)) & 1) != 0;
422 }
423 
430 {
431  if (!m_inputValid)
432  {
433  wpi_setWPIError(EnhancedIOMissing);
434  return 0;
435  }
436  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, 0, nUsageReporting::kDriverStationEIO_DigitalIn);
437  Synchronized sync(m_inputDataSemaphore);
438  return m_inputData.data.digital;
439 }
440 
447 void DriverStationEnhancedIO::SetDigitalOutput(uint32_t channel, bool value)
448 {
449  if (channel < 1 || channel > 16)
450  {
451  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 16");
452  return;
453  }
454  if (!m_outputValid)
455  {
456  wpi_setWPIError(EnhancedIOMissing);
457  return;
458  }
459 
460  static uint32_t reported_mask = 0;
461  if (!(reported_mask & (1 >> channel)))
462  {
463  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, channel, nUsageReporting::kDriverStationEIO_DigitalOut);
464  reported_mask |= (1 >> channel);
465  }
466 
467  uint16_t digital;
468  Synchronized sync(m_outputDataSemaphore);
469 
470  if (m_outputData.data.digital_oe & (1 << (channel-1)))
471  {
472  digital = m_outputData.data.digital;
473 
474  digital &= ~(1 << (channel-1));
475  if (value) digital |= 1 << (channel-1);
476 
477  m_outputData.data.digital = digital;
478  }
479  else
480  {
481  wpi_setWPIError(LineNotOutput);
482  }
483 }
484 
494 DriverStationEnhancedIO::tDigitalConfig DriverStationEnhancedIO::GetDigitalConfig(uint32_t channel)
495 {
496  if (channel < 1 || channel > 16)
497  {
498  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 16");
499  return kUnknown;
500  }
501  if (!m_outputValid)
502  {
503  m_requestEnhancedEnable = true;
504  wpi_setWPIError(EnhancedIOMissing);
505  return kUnknown;
506  }
507  Synchronized sync(m_outputDataSemaphore);
508  if ((channel >= 1) && (channel <= 4))
509  {
510  if (m_outputData.data.pwm_enable & (1 << (channel - 1)))
511  {
512  return kPWM;
513  }
514  }
515  if ((channel >= 15) && (channel <= 16))
516  {
517  if (m_outputData.data.comparator_enable & (1 << (channel - 15)))
518  {
519  return kAnalogComparator;
520  }
521  }
522  if (m_outputData.data.digital_oe & (1 << (channel - 1)))
523  {
524  return kOutput;
525  }
526  if (!(m_outputData.data.digital_pe & (1 << (channel - 1))))
527  {
528  return kInputFloating;
529  }
530  if (m_outputData.data.digital & (1 << (channel - 1)))
531  {
532  return kInputPullUp;
533  }
534  else
535  {
536  return kInputPullDown;
537  }
538 }
539 
563 void DriverStationEnhancedIO::SetDigitalConfig(uint32_t channel, tDigitalConfig config)
564 {
565  if (channel < 1 || channel > 16)
566  {
567  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 16");
568  return;
569  }
570  if (config == kPWM && (channel < 1 || channel > 4))
571  {
572  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel in PWM mode must be between 1 and 4");
573  return;
574  }
575  if (config == kAnalogComparator && (channel < 15 || channel > 16))
576  {
577  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel in Analog Comparator mode must be between 15 and 16");
578  return;
579  }
580 
581  Synchronized sync(m_outputDataSemaphore);
582  m_configChanged = true;
583 
584  if ((channel >= 1) && (channel <= 4))
585  {
586  if (config == kPWM)
587  {
588  m_outputData.data.pwm_enable |= 1 << (channel - 1);
589  m_outputData.data.digital &= ~(1 << (channel - 1));
590  m_outputData.data.digital_oe |= 1 << (channel - 1);
591  m_outputData.data.digital_pe &= ~(1 << (channel - 1));
592  return;
593  }
594  else
595  {
596  m_outputData.data.pwm_enable &= ~(1 << (channel - 1));
597  }
598  }
599  else if ((channel >= 15) && (channel <= 16))
600  {
601  if (config == kAnalogComparator)
602  {
603  m_outputData.data.comparator_enable |= 1 << (channel - 15);
604  m_outputData.data.digital &= ~(1 << (channel - 1));
605  m_outputData.data.digital_oe &= ~(1 << (channel - 1));
606  m_outputData.data.digital_pe &= ~(1 << (channel - 1));
607  return;
608  }
609  else
610  {
611  m_outputData.data.comparator_enable &= ~(1 << (channel - 15));
612  }
613  }
614  if (config == kInputFloating)
615  {
616  m_outputData.data.digital &= ~(1 << (channel - 1));
617  m_outputData.data.digital_oe &= ~(1 << (channel - 1));
618  m_outputData.data.digital_pe &= ~(1 << (channel - 1));
619  }
620  else if (config == kInputPullUp)
621  {
622  m_outputData.data.digital |= 1 << (channel - 1);
623  m_outputData.data.digital_oe &= ~(1 << (channel - 1));
624  m_outputData.data.digital_pe |= 1 << (channel - 1);
625  }
626  else if (config == kInputPullDown)
627  {
628  m_outputData.data.digital &= ~(1 << (channel - 1));
629  m_outputData.data.digital_oe &= ~(1 << (channel - 1));
630  m_outputData.data.digital_pe |= 1 << (channel - 1);
631  }
632  else if (config == kOutput)
633  {
634  m_outputData.data.digital_oe |= 1 << (channel - 1);
635  m_outputData.data.digital_pe &= ~(1 << (channel - 1));
636  }
637  else
638  {
639  // Something went wrong.
640  }
641 }
642 
652 double DriverStationEnhancedIO::GetPWMPeriod(tPWMPeriodChannels channels)
653 {
654  if (channels < kPWMChannels1and2 || channels > kPWMChannels3and4)
655  {
656  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channels must be kPWMChannels1and2 or kPWMChannels3and4");
657  return 0.0;
658  }
659  if (!m_outputValid)
660  {
661  m_requestEnhancedEnable = true;
662  wpi_setWPIError(EnhancedIOMissing);
663  return 0.0;
664  }
665 
666  Synchronized sync(m_outputDataSemaphore);
667  return m_outputData.data.pwm_period[channels] / 24000000.0;
668 }
669 
680 void DriverStationEnhancedIO::SetPWMPeriod(tPWMPeriodChannels channels, double period)
681 {
682  if (channels < kPWMChannels1and2 || channels > kPWMChannels3and4)
683  {
684  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channels must be kPWMChannels1and2 or kPWMChannels3and4");
685  return;
686  }
687 
688  // Convert to ticks based on the IO board's 24MHz clock
689  double ticks = period * 24000000.0;
690  // Limit the range of the ticks... warn if too big.
691  if (ticks > 65534.0)
692  {
693  wpi_setWPIError(EnhancedIOPWMPeriodOutOfRange);
694  ticks = 65534.0;
695  }
696  else if (ticks < 0.0) ticks = 0.0;
697  // Preserve the duty cycles.
698  double dutyCycles[2];
699  dutyCycles[0] = GetPWMOutput((channels << 1) + 1);
700  dutyCycles[1] = GetPWMOutput((channels << 1) + 2);
701  {
702  Synchronized sync(m_outputDataSemaphore);
703  // Update the period
704  m_outputData.data.pwm_period[channels] = (uint16_t)ticks;
705  m_configChanged = true;
706  }
707  // Restore the duty cycles
708  SetPWMOutput((channels << 1) + 1, dutyCycles[0]);
709  SetPWMOutput((channels << 1) + 2, dutyCycles[1]);
710 }
711 
719 {
720  if (channel < 1 || channel > 2)
721  {
722  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 2");
723  return 0;
724  }
725  if (!m_outputValid)
726  {
727  wpi_setWPIError(EnhancedIOMissing);
728  return 0;
729  }
730 
731  Synchronized sync(m_outputDataSemaphore);
732  return ((m_outputData.data.fixed_digital_out >> (channel-1)) & 1) != 0;
733 }
734 
749 void DriverStationEnhancedIO::SetFixedDigitalOutput(uint32_t channel, bool value)
750 {
751  if (channel < 1 || channel > 2)
752  {
753  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 2");
754  return;
755  }
756  if (!m_outputValid)
757  {
758  wpi_setWPIError(EnhancedIOMissing);
759  return;
760  }
761 
762  static uint8_t reported_mask = 0;
763  if (!(reported_mask & (1 >> channel)))
764  {
765  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, channel, nUsageReporting::kDriverStationEIO_FixedDigitalOut);
766  reported_mask |= (1 >> channel);
767  }
768 
769  uint8_t digital;
770  Synchronized sync(m_outputDataSemaphore);
771  digital = m_outputData.data.fixed_digital_out;
772 
773  digital &= ~(1 << (channel-1));
774  if (value) digital |= 1 << (channel-1);
775 
776  m_outputData.data.fixed_digital_out = digital;
777 }
778 
793 int16_t DriverStationEnhancedIO::GetEncoder(uint32_t encoderNumber)
794 {
795  if (encoderNumber < 1 || encoderNumber > 2)
796  {
797  wpi_setWPIErrorWithContext(ParameterOutOfRange, "encoderNumber must be between 1 and 2");
798  return 0;
799  }
800  if (!m_inputValid)
801  {
802  wpi_setWPIError(EnhancedIOMissing);
803  return 0;
804  }
805 
806  static uint8_t reported_mask = 0;
807  if (!(reported_mask & (1 >> encoderNumber)))
808  {
809  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, encoderNumber, nUsageReporting::kDriverStationEIO_Encoder);
810  reported_mask |= (1 >> encoderNumber);
811  }
812 
813  Synchronized sync(m_inputDataSemaphore);
814  return m_inputData.data.quad[encoderNumber - 1] - m_encoderOffsets[encoderNumber - 1];
815 }
816 
825 void DriverStationEnhancedIO::ResetEncoder(uint32_t encoderNumber)
826 {
827  if (encoderNumber < 1 || encoderNumber > 2)
828  {
829  wpi_setWPIErrorWithContext(ParameterOutOfRange, "encoderNumber must be between 1 and 2");
830  return;
831  }
832  if (!m_inputValid)
833  {
834  wpi_setWPIError(EnhancedIOMissing);
835  return;
836  }
837 
838  Synchronized sync(m_inputDataSemaphore);
839  m_encoderOffsets[encoderNumber - 1] = m_inputData.data.quad[encoderNumber - 1];
840 }
841 
852 {
853  if (encoderNumber < 1 || encoderNumber > 2)
854  {
855  wpi_setWPIErrorWithContext(ParameterOutOfRange, "encoderNumber must be between 1 and 2");
856  return false;
857  }
858  if (!m_outputValid)
859  {
860  m_requestEnhancedEnable = true;
861  wpi_setWPIError(EnhancedIOMissing);
862  return false;
863  }
864 
865  Synchronized sync(m_outputDataSemaphore);
866  return ((m_outputData.data.quad_index_enable >> (encoderNumber - 1)) & 1) != 0;
867 }
868 
882 void DriverStationEnhancedIO::SetEncoderIndexEnable(uint32_t encoderNumber, bool enable)
883 {
884  if (encoderNumber < 1 || encoderNumber > 2)
885  {
886  wpi_setWPIErrorWithContext(ParameterOutOfRange, "encoderNumber must be between 1 and 2");
887  return;
888  }
889 
890  Synchronized sync(m_outputDataSemaphore);
891  m_outputData.data.quad_index_enable &= ~(1 << (encoderNumber - 1));
892  if (enable) m_outputData.data.quad_index_enable |= 1 << (encoderNumber - 1);
893  m_configChanged = true;
894 }
895 
902 {
903  if (!m_inputValid)
904  {
905  wpi_setWPIError(EnhancedIOMissing);
906  return 0.0;
907  }
908 
909  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, 1, nUsageReporting::kDriverStationEIO_TouchSlider);
910 
911  Synchronized sync(m_inputDataSemaphore);
912  uint8_t value = m_inputData.data.capsense_slider;
913  return value == 255 ? -1.0 : value / 254.0;
914 }
915 
923 {
924  if (channel < 1 || channel > 4)
925  {
926  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 4");
927  return 0.0;
928  }
929  if (!m_outputValid)
930  {
931  wpi_setWPIError(EnhancedIOMissing);
932  return 0.0;
933  }
934 
935  Synchronized sync(m_outputDataSemaphore);
936  return (double)m_outputData.data.pwm_compare[channel - 1] / (double)m_outputData.data.pwm_period[(channel - 1) >> 1];
937 }
938 
948 void DriverStationEnhancedIO::SetPWMOutput(uint32_t channel, double value)
949 {
950  if (channel < 1 || channel > 4)
951  {
952  wpi_setWPIErrorWithContext(ParameterOutOfRange, "channel must be between 1 and 4");
953  return;
954  }
955  if (!m_outputValid)
956  {
957  wpi_setWPIError(EnhancedIOMissing);
958  return;
959  }
960 
961  static uint8_t reported_mask = 0;
962  if (!(reported_mask & (1 >> channel)))
963  {
964  nUsageReporting::report(nUsageReporting::kResourceType_DriverStationEIO, channel, nUsageReporting::kDriverStationEIO_PWM);
965  reported_mask |= (1 >> channel);
966  }
967 
968  if (value > 1.0) value = 1.0;
969  else if (value < 0.0) value = 0.0;
970  Synchronized sync(m_outputDataSemaphore);
971  m_outputData.data.pwm_compare[channel - 1] = (uint16_t)(value * (double)m_outputData.data.pwm_period[(channel - 1) >> 1]);
972 }
973 
984 {
985  if (!m_inputValid)
986  {
987  m_requestEnhancedEnable = true;
988  wpi_setWPIError(EnhancedIOMissing);
989  return 0;
990  }
991 
992  Synchronized sync(m_inputDataSemaphore);
993  return m_inputData.data.fw_version;
994 }
995 
void SetLED(uint32_t channel, bool value)
double GetPWMPeriod(tPWMPeriodChannels channels)
void SetEncoderIndexEnable(uint32_t encoderNumber, bool enable)
double GetAnalogOut(uint32_t channel)
void SetDigitalConfig(uint32_t channel, tDigitalConfig config)
double GetAnalogInRatio(uint32_t channel)
double GetAcceleration(tAccelChannel channel)
double GetPWMOutput(uint32_t channel)
bool GetButton(uint32_t channel)
void SetFixedDigitalOutput(uint32_t channel, bool value)
void SetDigitalOutput(uint32_t channel, bool value)
bool GetDigital(uint32_t channel)
void SetPWMPeriod(tPWMPeriodChannels channels, double period)
double GetAnalogIn(uint32_t channel)
void SetPWMOutput(uint32_t channel, double value)
void SetAnalogOut(uint32_t channel, double value)
void ResetEncoder(uint32_t encoderNumber)
int16_t GetEncoder(uint32_t encoderNumber)
tDigitalConfig GetDigitalConfig(uint32_t channel)
bool GetFixedDigitalOutput(uint32_t channel)
bool GetEncoderIndexEnable(uint32_t encoderNumber)

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