Squashed 'third_party/allwpilib/' content from commit b0167e633
Change-Id: I5653017a690eec1917e8fff9017195d8af307926
git-subtree-dir: third_party/allwpilib
git-subtree-split: b0167e6337135545e7053acb89dd5726accc7dec
diff --git a/wpilibc/src/main/native/cpp/Relay.cpp b/wpilibc/src/main/native/cpp/Relay.cpp
new file mode 100644
index 0000000..cb95223
--- /dev/null
+++ b/wpilibc/src/main/native/cpp/Relay.cpp
@@ -0,0 +1,212 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2008-2019 FIRST. 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 the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#include "frc/Relay.h"
+
+#include <utility>
+
+#include <hal/FRCUsageReporting.h>
+#include <hal/HALBase.h>
+#include <hal/Ports.h>
+#include <hal/Relay.h>
+#include <wpi/raw_ostream.h>
+
+#include "frc/SensorUtil.h"
+#include "frc/WPIErrors.h"
+#include "frc/smartdashboard/SendableBuilder.h"
+#include "frc/smartdashboard/SendableRegistry.h"
+
+using namespace frc;
+
+Relay::Relay(int channel, Relay::Direction direction)
+ : m_channel(channel), m_direction(direction) {
+ if (!SensorUtil::CheckRelayChannel(m_channel)) {
+ wpi_setWPIErrorWithContext(ChannelIndexOutOfRange,
+ "Relay Channel " + wpi::Twine(m_channel));
+ return;
+ }
+
+ HAL_PortHandle portHandle = HAL_GetPort(channel);
+
+ if (m_direction == kBothDirections || m_direction == kForwardOnly) {
+ int32_t status = 0;
+ m_forwardHandle = HAL_InitializeRelayPort(portHandle, true, &status);
+ if (status != 0) {
+ wpi_setHALErrorWithRange(status, 0, HAL_GetNumRelayChannels(), channel);
+ m_forwardHandle = HAL_kInvalidHandle;
+ m_reverseHandle = HAL_kInvalidHandle;
+ return;
+ }
+ HAL_Report(HALUsageReporting::kResourceType_Relay, m_channel + 1);
+ }
+ if (m_direction == kBothDirections || m_direction == kReverseOnly) {
+ int32_t status = 0;
+ m_reverseHandle = HAL_InitializeRelayPort(portHandle, false, &status);
+ if (status != 0) {
+ wpi_setHALErrorWithRange(status, 0, HAL_GetNumRelayChannels(), channel);
+ m_forwardHandle = HAL_kInvalidHandle;
+ m_reverseHandle = HAL_kInvalidHandle;
+ return;
+ }
+
+ HAL_Report(HALUsageReporting::kResourceType_Relay, m_channel + 128);
+ }
+
+ int32_t status = 0;
+ if (m_forwardHandle != HAL_kInvalidHandle) {
+ HAL_SetRelay(m_forwardHandle, false, &status);
+ if (status != 0) {
+ wpi_setHALError(status);
+ m_forwardHandle = HAL_kInvalidHandle;
+ m_reverseHandle = HAL_kInvalidHandle;
+ return;
+ }
+ }
+ if (m_reverseHandle != HAL_kInvalidHandle) {
+ HAL_SetRelay(m_reverseHandle, false, &status);
+ if (status != 0) {
+ wpi_setHALError(status);
+ m_forwardHandle = HAL_kInvalidHandle;
+ m_reverseHandle = HAL_kInvalidHandle;
+ return;
+ }
+ }
+
+ SendableRegistry::GetInstance().AddLW(this, "Relay", m_channel);
+}
+
+Relay::~Relay() {
+ int32_t status = 0;
+ HAL_SetRelay(m_forwardHandle, false, &status);
+ HAL_SetRelay(m_reverseHandle, false, &status);
+ // ignore errors, as we want to make sure a free happens.
+ if (m_forwardHandle != HAL_kInvalidHandle) HAL_FreeRelayPort(m_forwardHandle);
+ if (m_reverseHandle != HAL_kInvalidHandle) HAL_FreeRelayPort(m_reverseHandle);
+}
+
+void Relay::Set(Relay::Value value) {
+ if (StatusIsFatal()) return;
+
+ int32_t status = 0;
+
+ switch (value) {
+ case kOff:
+ if (m_direction == kBothDirections || m_direction == kForwardOnly) {
+ HAL_SetRelay(m_forwardHandle, false, &status);
+ }
+ if (m_direction == kBothDirections || m_direction == kReverseOnly) {
+ HAL_SetRelay(m_reverseHandle, false, &status);
+ }
+ break;
+ case kOn:
+ if (m_direction == kBothDirections || m_direction == kForwardOnly) {
+ HAL_SetRelay(m_forwardHandle, true, &status);
+ }
+ if (m_direction == kBothDirections || m_direction == kReverseOnly) {
+ HAL_SetRelay(m_reverseHandle, true, &status);
+ }
+ break;
+ case kForward:
+ if (m_direction == kReverseOnly) {
+ wpi_setWPIError(IncompatibleMode);
+ break;
+ }
+ if (m_direction == kBothDirections || m_direction == kForwardOnly) {
+ HAL_SetRelay(m_forwardHandle, true, &status);
+ }
+ if (m_direction == kBothDirections) {
+ HAL_SetRelay(m_reverseHandle, false, &status);
+ }
+ break;
+ case kReverse:
+ if (m_direction == kForwardOnly) {
+ wpi_setWPIError(IncompatibleMode);
+ break;
+ }
+ if (m_direction == kBothDirections) {
+ HAL_SetRelay(m_forwardHandle, false, &status);
+ }
+ if (m_direction == kBothDirections || m_direction == kReverseOnly) {
+ HAL_SetRelay(m_reverseHandle, true, &status);
+ }
+ break;
+ }
+
+ wpi_setHALError(status);
+}
+
+Relay::Value Relay::Get() const {
+ int32_t status;
+
+ if (m_direction == kForwardOnly) {
+ if (HAL_GetRelay(m_forwardHandle, &status)) {
+ return kOn;
+ } else {
+ return kOff;
+ }
+ } else if (m_direction == kReverseOnly) {
+ if (HAL_GetRelay(m_reverseHandle, &status)) {
+ return kOn;
+ } else {
+ return kOff;
+ }
+ } else {
+ if (HAL_GetRelay(m_forwardHandle, &status)) {
+ if (HAL_GetRelay(m_reverseHandle, &status)) {
+ return kOn;
+ } else {
+ return kForward;
+ }
+ } else {
+ if (HAL_GetRelay(m_reverseHandle, &status)) {
+ return kReverse;
+ } else {
+ return kOff;
+ }
+ }
+ }
+
+ wpi_setHALError(status);
+}
+
+int Relay::GetChannel() const { return m_channel; }
+
+void Relay::StopMotor() { Set(kOff); }
+
+void Relay::GetDescription(wpi::raw_ostream& desc) const {
+ desc << "Relay " << GetChannel();
+}
+
+void Relay::InitSendable(SendableBuilder& builder) {
+ builder.SetSmartDashboardType("Relay");
+ builder.SetActuator(true);
+ builder.SetSafeState([=]() { Set(kOff); });
+ builder.AddSmallStringProperty(
+ "Value",
+ [=](wpi::SmallVectorImpl<char>& buf) -> wpi::StringRef {
+ switch (Get()) {
+ case kOn:
+ return "On";
+ case kForward:
+ return "Forward";
+ case kReverse:
+ return "Reverse";
+ default:
+ return "Off";
+ }
+ },
+ [=](wpi::StringRef value) {
+ if (value == "Off")
+ Set(kOff);
+ else if (value == "Forward")
+ Set(kForward);
+ else if (value == "Reverse")
+ Set(kReverse);
+ else if (value == "On")
+ Set(kOn);
+ });
+}