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/SolenoidBase.cpp b/azaleasource/WPILibCProgramming/trunk/WPILib/SolenoidBase.cpp
new file mode 100644
index 0000000..ea87505
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/SolenoidBase.cpp
@@ -0,0 +1,88 @@
+/*----------------------------------------------------------------------------*/
+/* 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 "SolenoidBase.h"
+
+// Needs to be global since the protected resource spans all Solenoid objects.
+ReentrantSemaphore SolenoidBase::m_semaphore;
+Resource *SolenoidBase::m_allocated = NULL;
+
+tSolenoid *SolenoidBase::m_fpgaSolenoidModule = NULL;
+UINT32 SolenoidBase::m_refCount = 0;
+
+
+/**
+ * Constructor
+ *
+ * @param moduleNumber The solenoid module (1 or 2).
+ */
+SolenoidBase::SolenoidBase(UINT8 moduleNumber)
+ : m_moduleNumber (moduleNumber)
+{
+ Synchronized sync(m_semaphore);
+ m_refCount++;
+ if (m_refCount == 1)
+ {
+ tRioStatusCode localStatus = NiFpga_Status_Success;
+ m_fpgaSolenoidModule = tSolenoid::create(&localStatus);
+ wpi_setError(localStatus);
+ }
+}
+
+/**
+ * Destructor.
+ */
+SolenoidBase::~SolenoidBase()
+{
+ Synchronized sync(m_semaphore);
+ if (CheckSolenoidModule(m_moduleNumber))
+ {
+ if (m_refCount == 1)
+ {
+ delete m_fpgaSolenoidModule;
+ m_fpgaSolenoidModule = NULL;
+ }
+ m_refCount--;
+ }
+}
+
+/**
+ * Set the value of a solenoid.
+ *
+ * @param value The value you want to set on the module.
+ * @param mask The channels you want to be affected.
+ */
+void SolenoidBase::Set(UINT8 value, UINT8 mask)
+{
+ tRioStatusCode localStatus = NiFpga_Status_Success;
+ if (CheckSolenoidModule(m_moduleNumber))
+ {
+ Synchronized sync(m_semaphore);
+ UINT8 currentValue = m_fpgaSolenoidModule->readDO7_0(m_moduleNumber - 1, &localStatus);
+ // Zero out the values to change
+ currentValue = currentValue & ~mask;
+ currentValue = currentValue | (value & mask);
+ m_fpgaSolenoidModule->writeDO7_0(m_moduleNumber - 1, currentValue, &localStatus);
+ }
+ wpi_setError(localStatus);
+}
+
+/**
+ * Read all 8 solenoids as a single byte
+ *
+ * @return The current value of all 8 solenoids on the module.
+ */
+UINT8 SolenoidBase::GetAll()
+{
+ if (CheckSolenoidModule(m_moduleNumber))
+ {
+ tRioStatusCode localStatus = NiFpga_Status_Success;
+ UINT8 solenoids = m_fpgaSolenoidModule->readDO7_0(m_moduleNumber - 1, &localStatus);
+ wpi_setError(localStatus);
+ return solenoids;
+ }
+ return 0;
+}