This is the latest WPILib src, VisionSample2013, cRIO image, ... pulled down from firstforge.wpi.edu.
There might be risks in using the top of tree rather than an official release, but the commit messages do mention fixes for some deadlocks and race conditions.
git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4066 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/azaleasource/WPILibCProgramming/trunk/WPILib/AnalogTrigger.cpp b/azaleasource/WPILibCProgramming/trunk/WPILib/AnalogTrigger.cpp
new file mode 100644
index 0000000..a3420d5
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/AnalogTrigger.cpp
@@ -0,0 +1,200 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
+/*----------------------------------------------------------------------------*/
+
+#include "AnalogTrigger.h"
+
+#include "AnalogChannel.h"
+#include "AnalogModule.h"
+#include "NetworkCommunication/UsageReporting.h"
+#include "Resource.h"
+#include "WPIErrors.h"
+
+static Resource *triggers = NULL;
+
+/**
+ * Initialize an analog trigger from a slot and channel.
+ * This is the common code for the two constructors that use a slot and channel.
+ */
+void AnalogTrigger::InitTrigger(UINT8 moduleNumber, UINT32 channel)
+{
+ Resource::CreateResourceObject(&triggers, tAnalogTrigger::kNumSystems);
+ UINT32 index = triggers->Allocate("Analog Trigger");
+ if (index == ~0ul)
+ {
+ CloneError(triggers);
+ return;
+ }
+ m_index = (UINT8)index;
+ m_channel = channel;
+ m_analogModule = AnalogModule::GetInstance(moduleNumber);
+
+ tRioStatusCode localStatus = NiFpga_Status_Success;
+ m_trigger = tAnalogTrigger::create(m_index, &localStatus);
+ m_trigger->writeSourceSelect_Channel(m_channel - 1, &localStatus);
+ m_trigger->writeSourceSelect_Module(moduleNumber - 1, &localStatus);
+ wpi_setError(localStatus);
+
+ nUsageReporting::report(nUsageReporting::kResourceType_AnalogTrigger, m_channel, moduleNumber - 1);
+}
+
+/**
+ * Constructor for an analog trigger given a channel number.
+ * The default module is used in this case.
+ *
+ * @param channel The analog channel (1..8).
+ */
+AnalogTrigger::AnalogTrigger(UINT32 channel)
+{
+ InitTrigger(GetDefaultAnalogModule(), channel);
+}
+
+/**
+ * Constructor for an analog trigger given both the slot and channel.
+ *
+ * @param moduleNumber The analog module (1 or 2).
+ * @param channel The analog channel (1..8).
+ */
+AnalogTrigger::AnalogTrigger(UINT8 moduleNumber, UINT32 channel)
+{
+ InitTrigger(moduleNumber, channel);
+}
+
+/**
+ * Construct an analog trigger given an analog channel.
+ * This should be used in the case of sharing an analog channel between the trigger
+ * and an analog input object.
+ */
+AnalogTrigger::AnalogTrigger(AnalogChannel *channel)
+{
+ InitTrigger(channel->GetModuleNumber(), channel->GetChannel());
+}
+
+AnalogTrigger::~AnalogTrigger()
+{
+ triggers->Free(m_index);
+ delete m_trigger;
+}
+
+/**
+ * Set the upper and lower limits of the analog trigger.
+ * The limits are given in ADC codes. If oversampling is used, the units must be scaled
+ * appropriately.
+ */
+void AnalogTrigger::SetLimitsRaw(INT32 lower, INT32 upper)
+{
+ if (StatusIsFatal()) return;
+ if (lower > upper)
+ {
+ wpi_setWPIError(AnalogTriggerLimitOrderError);
+ }
+ tRioStatusCode localStatus = NiFpga_Status_Success;
+ m_trigger->writeLowerLimit(lower, &localStatus);
+ m_trigger->writeUpperLimit(upper, &localStatus);
+ wpi_setError(localStatus);
+}
+
+/**
+ * Set the upper and lower limits of the analog trigger.
+ * The limits are given as floating point voltage values.
+ */
+void AnalogTrigger::SetLimitsVoltage(float lower, float upper)
+{
+ if (StatusIsFatal()) return;
+ if (lower > upper)
+ {
+ wpi_setWPIError(AnalogTriggerLimitOrderError);
+ }
+ // TODO: This depends on the averaged setting. Only raw values will work as is.
+ tRioStatusCode localStatus = NiFpga_Status_Success;
+ m_trigger->writeLowerLimit(m_analogModule->VoltsToValue(m_channel, lower), &localStatus);
+ m_trigger->writeUpperLimit(m_analogModule->VoltsToValue(m_channel, upper), &localStatus);
+ wpi_setError(localStatus);
+}
+
+/**
+ * Configure the analog trigger to use the averaged vs. raw values.
+ * If the value is true, then the averaged value is selected for the analog trigger, otherwise
+ * the immediate value is used.
+ */
+void AnalogTrigger::SetAveraged(bool useAveragedValue)
+{
+ if (StatusIsFatal()) return;
+ tRioStatusCode localStatus = NiFpga_Status_Success;
+ if (m_trigger->readSourceSelect_Filter(&localStatus) != 0)
+ wpi_setWPIErrorWithContext(IncompatibleMode, "Hardware does not support average and filtering at the same time.");
+ m_trigger->writeSourceSelect_Averaged(useAveragedValue, &localStatus);
+ wpi_setError(localStatus);
+}
+
+/**
+ * Configure the analog trigger to use a filtered value.
+ * The analog trigger will operate with a 3 point average rejection filter. This is designed to
+ * help with 360 degree pot applications for the period where the pot crosses through zero.
+ */
+void AnalogTrigger::SetFiltered(bool useFilteredValue)
+{
+ if (StatusIsFatal()) return;
+ tRioStatusCode localStatus = NiFpga_Status_Success;
+ if (m_trigger->readSourceSelect_Averaged(&localStatus) != 0)
+ wpi_setWPIErrorWithContext(IncompatibleMode, "Hardware does not support average and filtering at the same time.");
+ m_trigger->writeSourceSelect_Filter(useFilteredValue, &localStatus);
+ wpi_setError(localStatus);
+}
+
+/**
+ * Return the index of the analog trigger.
+ * This is the FPGA index of this analog trigger instance.
+ * @return The index of the analog trigger.
+ */
+UINT32 AnalogTrigger::GetIndex()
+{
+ if (StatusIsFatal()) return ~0ul;
+ return m_index;
+}
+
+/**
+ * Return the InWindow output of the analog trigger.
+ * True if the analog input is between the upper and lower limits.
+ * @return The InWindow output of the analog trigger.
+ */
+bool AnalogTrigger::GetInWindow()
+{
+ if (StatusIsFatal()) return false;
+ tRioStatusCode localStatus = NiFpga_Status_Success;
+ bool result = m_trigger->readOutput_InHysteresis(m_index, &localStatus) != 0;
+ wpi_setError(localStatus);
+ return result;
+}
+
+/**
+ * Return the TriggerState output of the analog trigger.
+ * True if above upper limit.
+ * False if below lower limit.
+ * If in Hysteresis, maintain previous state.
+ * @return The TriggerState output of the analog trigger.
+ */
+bool AnalogTrigger::GetTriggerState()
+{
+ if (StatusIsFatal()) return false;
+ tRioStatusCode localStatus = NiFpga_Status_Success;
+ bool result = m_trigger->readOutput_OverLimit(m_index, &localStatus) != 0;
+ wpi_setError(localStatus);
+ return result;
+}
+
+/**
+ * Creates an AnalogTriggerOutput object.
+ * Gets an output object that can be used for routing.
+ * Caller is responsible for deleting the AnalogTriggerOutput object.
+ * @param type An enum of the type of output object to create.
+ * @return A pointer to a new AnalogTriggerOutput object.
+ */
+AnalogTriggerOutput *AnalogTrigger::CreateOutput(AnalogTriggerOutput::Type type)
+{
+ if (StatusIsFatal()) return NULL;
+ return new AnalogTriggerOutput(this, type);
+}
+