mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-24 01:31:46 +00:00
Switches relays to handles (#119)
This commit is contained in:
committed by
Peter Johnson
parent
e8e052712e
commit
9b2af0d090
@@ -24,3 +24,5 @@ typedef HalHandle HalAnalogOutputHandle;
|
||||
typedef HalHandle HalAnalogInputHandle;
|
||||
|
||||
typedef HalHandle HalAnalogTriggerHandle;
|
||||
|
||||
typedef HalHandle HalRelayHandle;
|
||||
|
||||
@@ -9,11 +9,15 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" {
|
||||
bool checkRelayChannel(void* digital_port_pointer);
|
||||
#include "Handles.h"
|
||||
|
||||
void setRelayForward(void* digital_port_pointer, bool on, int32_t* status);
|
||||
void setRelayReverse(void* digital_port_pointer, bool on, int32_t* status);
|
||||
bool getRelayForward(void* digital_port_pointer, int32_t* status);
|
||||
bool getRelayReverse(void* digital_port_pointer, int32_t* status);
|
||||
extern "C" {
|
||||
HalRelayHandle initializeRelayPort(HalPortHandle port_handle, uint8_t fwd,
|
||||
int32_t* status);
|
||||
void freeRelayPort(HalRelayHandle relay_port_handle);
|
||||
|
||||
bool checkRelayChannel(uint8_t pin);
|
||||
|
||||
void setRelay(HalRelayHandle relay_port_handle, bool on, int32_t* status);
|
||||
bool getRelay(HalRelayHandle relay_port_handle, int32_t* status);
|
||||
}
|
||||
|
||||
@@ -8,111 +8,125 @@
|
||||
#include "HAL/Relay.h"
|
||||
|
||||
#include "DigitalInternal.h"
|
||||
|
||||
static_assert(sizeof(uint32_t) <= sizeof(void*),
|
||||
"This file shoves uint32_ts into pointers.");
|
||||
#include "handles/IndexedHandleResource.h"
|
||||
|
||||
using namespace hal;
|
||||
|
||||
namespace {
|
||||
struct Relay {
|
||||
uint8_t pin;
|
||||
bool fwd;
|
||||
};
|
||||
}
|
||||
|
||||
constexpr uint32_t kRelayPins = 8;
|
||||
constexpr uint32_t kRelayHeaders = kRelayPins / 2; // Number of FPGA ID's
|
||||
|
||||
static IndexedHandleResource<HalRelayHandle, Relay, kRelayPins,
|
||||
HalHandleEnum::Relay>
|
||||
relayHandles;
|
||||
|
||||
// Create a mutex to protect changes to the relay values
|
||||
static priority_recursive_mutex digitalRelayMutex;
|
||||
|
||||
constexpr uint32_t kRelayPins = 8;
|
||||
|
||||
extern "C" {
|
||||
bool checkRelayChannel(void* digital_port_pointer) {
|
||||
DigitalPort* port = (DigitalPort*)digital_port_pointer;
|
||||
return port->pin < kRelayPins;
|
||||
HalRelayHandle initializeRelayPort(HalPortHandle port_handle, uint8_t fwd,
|
||||
int32_t* status) {
|
||||
initializeDigital(status);
|
||||
|
||||
if (*status != 0) return HAL_INVALID_HANDLE;
|
||||
|
||||
int16_t pin = getPortHandlePin(port_handle);
|
||||
if (pin == InvalidHandleIndex) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return HAL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (!fwd) pin += kRelayHeaders; // add 4 to reverse pins
|
||||
|
||||
auto handle = relayHandles.Allocate(pin, status);
|
||||
|
||||
if (*status != 0)
|
||||
return HAL_INVALID_HANDLE; // failed to allocate. Pass error back.
|
||||
|
||||
auto port = relayHandles.Get(handle);
|
||||
if (port == nullptr) { // would only occur on thread issue.
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return HAL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (!fwd) {
|
||||
pin -= kRelayHeaders; // subtract number of headers to put pin in range.
|
||||
port->fwd = false; // set to reverse
|
||||
} else {
|
||||
port->fwd = true; // set to forward
|
||||
}
|
||||
|
||||
port->pin = static_cast<uint8_t>(pin);
|
||||
return handle;
|
||||
}
|
||||
|
||||
void freeRelayPort(HalRelayHandle relay_port_handle) {
|
||||
// no status, so no need to check for a proper free.
|
||||
relayHandles.Free(relay_port_handle);
|
||||
}
|
||||
|
||||
bool checkRelayChannel(uint8_t pin) {
|
||||
return pin < kRelayHeaders; // roboRIO only has 4 headers, and the FPGA has
|
||||
// seperate functions for forward and reverse,
|
||||
// instead of seperate pin IDs
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a port to make sure that it is not nullptr and is a valid Relay port.
|
||||
*
|
||||
* Sets the status to contain the appropriate error.
|
||||
*
|
||||
* @return true if the port passed validation.
|
||||
* Set the state of a relay.
|
||||
* Set the state of a relay output.
|
||||
*/
|
||||
static bool verifyRelayChannel(DigitalPort* port, int32_t* status) {
|
||||
void setRelay(HalRelayHandle relay_port_handle, bool on, int32_t* status) {
|
||||
auto port = relayHandles.Get(relay_port_handle);
|
||||
if (port == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
std::lock_guard<priority_recursive_mutex> sync(digitalRelayMutex);
|
||||
uint8_t relays = 0;
|
||||
if (port->fwd) {
|
||||
relays = relaySystem->readValue_Forward(status);
|
||||
} else {
|
||||
relays = relaySystem->readValue_Reverse(status);
|
||||
}
|
||||
|
||||
if (*status != 0) return; // bad status read
|
||||
|
||||
if (on) {
|
||||
relays |= 1 << port->pin;
|
||||
} else {
|
||||
relays &= ~(1 << port->pin);
|
||||
}
|
||||
|
||||
if (port->fwd) {
|
||||
relaySystem->writeValue_Forward(relays, status);
|
||||
} else {
|
||||
relaySystem->writeValue_Reverse(relays, status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current state of the relay channel
|
||||
*/
|
||||
bool getRelay(HalRelayHandle relay_port_handle, int32_t* status) {
|
||||
auto port = relayHandles.Get(relay_port_handle);
|
||||
if (port == nullptr) {
|
||||
*status = NULL_PARAMETER;
|
||||
return false;
|
||||
} else if (!checkRelayChannel(port)) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t relays = 0;
|
||||
if (port->fwd) {
|
||||
relays = relaySystem->readValue_Forward(status);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the state of a relay.
|
||||
* Set the state of a relay output to be forward. Relays have two outputs and
|
||||
* each is
|
||||
* independently set to 0v or 12v.
|
||||
*/
|
||||
void setRelayForward(void* digital_port_pointer, bool on, int32_t* status) {
|
||||
DigitalPort* port = (DigitalPort*)digital_port_pointer;
|
||||
if (!verifyRelayChannel(port, status)) {
|
||||
return;
|
||||
relays = relaySystem->readValue_Reverse(status);
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<priority_recursive_mutex> sync(digitalRelayMutex);
|
||||
uint8_t forwardRelays = relaySystem->readValue_Forward(status);
|
||||
if (on)
|
||||
forwardRelays |= 1 << port->pin;
|
||||
else
|
||||
forwardRelays &= ~(1 << port->pin);
|
||||
relaySystem->writeValue_Forward(forwardRelays, status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the state of a relay.
|
||||
* Set the state of a relay output to be reverse. Relays have two outputs and
|
||||
* each is
|
||||
* independently set to 0v or 12v.
|
||||
*/
|
||||
void setRelayReverse(void* digital_port_pointer, bool on, int32_t* status) {
|
||||
DigitalPort* port = (DigitalPort*)digital_port_pointer;
|
||||
if (!verifyRelayChannel(port, status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<priority_recursive_mutex> sync(digitalRelayMutex);
|
||||
uint8_t reverseRelays = relaySystem->readValue_Reverse(status);
|
||||
if (on)
|
||||
reverseRelays |= 1 << port->pin;
|
||||
else
|
||||
reverseRelays &= ~(1 << port->pin);
|
||||
relaySystem->writeValue_Reverse(reverseRelays, status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current state of the forward relay channel
|
||||
*/
|
||||
bool getRelayForward(void* digital_port_pointer, int32_t* status) {
|
||||
DigitalPort* port = (DigitalPort*)digital_port_pointer;
|
||||
if (!verifyRelayChannel(port, status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t forwardRelays = relaySystem->readValue_Forward(status);
|
||||
return (forwardRelays & (1 << port->pin)) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current state of the reverse relay channel
|
||||
*/
|
||||
bool getRelayReverse(void* digital_port_pointer, int32_t* status) {
|
||||
DigitalPort* port = (DigitalPort*)digital_port_pointer;
|
||||
if (!verifyRelayChannel(port, status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t reverseRelays = relaySystem->readValue_Reverse(status);
|
||||
return (reverseRelays & (1 << port->pin)) != 0;
|
||||
return (relays & (1 << port->pin)) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ enum class HalHandleEnum {
|
||||
Interrupt = 4,
|
||||
AnalogOutput = 5,
|
||||
AnalogInput = 6,
|
||||
AnalogTrigger = 7
|
||||
AnalogTrigger = 7,
|
||||
Relay = 8
|
||||
};
|
||||
|
||||
static inline int16_t getHandleIndex(HalHandle handle) {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "HAL/Handles.h"
|
||||
#include "LiveWindow/LiveWindowSendable.h"
|
||||
#include "MotorSafety.h"
|
||||
#include "SensorBase.h"
|
||||
@@ -66,5 +67,8 @@ class Relay : public MotorSafety,
|
||||
uint32_t m_channel;
|
||||
Direction m_direction;
|
||||
|
||||
HalRelayHandle m_forwardHandle = HAL_INVALID_HANDLE;
|
||||
HalRelayHandle m_reverseHandle = HAL_INVALID_HANDLE;
|
||||
|
||||
std::unique_ptr<MotorSafetyHelper> m_safetyHelper;
|
||||
};
|
||||
|
||||
@@ -30,29 +30,32 @@ static std::unique_ptr<Resource> relayChannels;
|
||||
Relay::Relay(uint32_t channel, Relay::Direction direction)
|
||||
: m_channel(channel), m_direction(direction) {
|
||||
std::stringstream buf;
|
||||
Resource::CreateResourceObject(relayChannels,
|
||||
dio_kNumSystems * kRelayChannels * 2);
|
||||
if (!SensorBase::CheckRelayChannel(m_channel)) {
|
||||
buf << "Relay Channel " << m_channel;
|
||||
wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf.str());
|
||||
return;
|
||||
}
|
||||
|
||||
HalPortHandle portHandle = getPort(channel);
|
||||
|
||||
if (m_direction == kBothDirections || m_direction == kForwardOnly) {
|
||||
buf << "Forward Relay " << m_channel;
|
||||
if (relayChannels->Allocate(m_channel * 2, buf.str()) ==
|
||||
std::numeric_limits<uint32_t>::max()) {
|
||||
CloneError(*relayChannels);
|
||||
int32_t status = 0;
|
||||
m_forwardHandle = initializeRelayPort(portHandle, true, &status);
|
||||
if (status != 0) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
m_forwardHandle = HAL_INVALID_HANDLE;
|
||||
m_reverseHandle = HAL_INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
HALReport(HALUsageReporting::kResourceType_Relay, m_channel);
|
||||
}
|
||||
if (m_direction == kBothDirections || m_direction == kReverseOnly) {
|
||||
buf << "Reverse Relay " << m_channel;
|
||||
if (relayChannels->Allocate(m_channel * 2 + 1, buf.str()) ==
|
||||
std::numeric_limits<uint32_t>::max()) {
|
||||
CloneError(*relayChannels);
|
||||
int32_t status = 0;
|
||||
m_reverseHandle = initializeRelayPort(portHandle, false, &status);
|
||||
if (status != 0) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
m_forwardHandle = HAL_INVALID_HANDLE;
|
||||
m_reverseHandle = HAL_INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -60,9 +63,24 @@ Relay::Relay(uint32_t channel, Relay::Direction direction)
|
||||
}
|
||||
|
||||
int32_t status = 0;
|
||||
setRelayForward(m_relay_ports[m_channel], false, &status);
|
||||
setRelayReverse(m_relay_ports[m_channel], false, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
if (m_forwardHandle != HAL_INVALID_HANDLE) {
|
||||
setRelay(m_forwardHandle, false, &status);
|
||||
if (status != 0) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
m_forwardHandle = HAL_INVALID_HANDLE;
|
||||
m_reverseHandle = HAL_INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (m_reverseHandle != HAL_INVALID_HANDLE) {
|
||||
setRelay(m_reverseHandle, false, &status);
|
||||
if (status != 0) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
m_forwardHandle = HAL_INVALID_HANDLE;
|
||||
m_reverseHandle = HAL_INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_safetyHelper = std::make_unique<MotorSafetyHelper>(this);
|
||||
m_safetyHelper->SetSafetyEnabled(false);
|
||||
@@ -77,16 +95,12 @@ Relay::Relay(uint32_t channel, Relay::Direction direction)
|
||||
*/
|
||||
Relay::~Relay() {
|
||||
int32_t status = 0;
|
||||
setRelayForward(m_relay_ports[m_channel], false, &status);
|
||||
setRelayReverse(m_relay_ports[m_channel], false, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
setRelay(m_forwardHandle, false, &status);
|
||||
setRelay(m_reverseHandle, false, &status);
|
||||
// ignore errors, as we want to make sure a free happens.
|
||||
if (m_forwardHandle != HAL_INVALID_HANDLE) freeRelayPort(m_forwardHandle);
|
||||
if (m_reverseHandle != HAL_INVALID_HANDLE) freeRelayPort(m_reverseHandle);
|
||||
|
||||
if (m_direction == kBothDirections || m_direction == kForwardOnly) {
|
||||
relayChannels->Free(m_channel * 2);
|
||||
}
|
||||
if (m_direction == kBothDirections || m_direction == kReverseOnly) {
|
||||
relayChannels->Free(m_channel * 2 + 1);
|
||||
}
|
||||
if (m_table != nullptr) m_table->RemoveTableListener(this);
|
||||
}
|
||||
|
||||
@@ -113,18 +127,18 @@ void Relay::Set(Relay::Value value) {
|
||||
switch (value) {
|
||||
case kOff:
|
||||
if (m_direction == kBothDirections || m_direction == kForwardOnly) {
|
||||
setRelayForward(m_relay_ports[m_channel], false, &status);
|
||||
setRelay(m_forwardHandle, false, &status);
|
||||
}
|
||||
if (m_direction == kBothDirections || m_direction == kReverseOnly) {
|
||||
setRelayReverse(m_relay_ports[m_channel], false, &status);
|
||||
setRelay(m_reverseHandle, false, &status);
|
||||
}
|
||||
break;
|
||||
case kOn:
|
||||
if (m_direction == kBothDirections || m_direction == kForwardOnly) {
|
||||
setRelayForward(m_relay_ports[m_channel], true, &status);
|
||||
setRelay(m_forwardHandle, true, &status);
|
||||
}
|
||||
if (m_direction == kBothDirections || m_direction == kReverseOnly) {
|
||||
setRelayReverse(m_relay_ports[m_channel], true, &status);
|
||||
setRelay(m_reverseHandle, true, &status);
|
||||
}
|
||||
break;
|
||||
case kForward:
|
||||
@@ -133,10 +147,10 @@ void Relay::Set(Relay::Value value) {
|
||||
break;
|
||||
}
|
||||
if (m_direction == kBothDirections || m_direction == kForwardOnly) {
|
||||
setRelayForward(m_relay_ports[m_channel], true, &status);
|
||||
setRelay(m_forwardHandle, true, &status);
|
||||
}
|
||||
if (m_direction == kBothDirections) {
|
||||
setRelayReverse(m_relay_ports[m_channel], false, &status);
|
||||
setRelay(m_reverseHandle, false, &status);
|
||||
}
|
||||
break;
|
||||
case kReverse:
|
||||
@@ -145,10 +159,10 @@ void Relay::Set(Relay::Value value) {
|
||||
break;
|
||||
}
|
||||
if (m_direction == kBothDirections) {
|
||||
setRelayForward(m_relay_ports[m_channel], false, &status);
|
||||
setRelay(m_forwardHandle, false, &status);
|
||||
}
|
||||
if (m_direction == kBothDirections || m_direction == kReverseOnly) {
|
||||
setRelayReverse(m_relay_ports[m_channel], true, &status);
|
||||
setRelay(m_reverseHandle, true, &status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -169,8 +183,8 @@ void Relay::Set(Relay::Value value) {
|
||||
Relay::Value Relay::Get() const {
|
||||
int32_t status;
|
||||
|
||||
if (getRelayForward(m_relay_ports[m_channel], &status)) {
|
||||
if (getRelayReverse(m_relay_ports[m_channel], &status)) {
|
||||
if (getRelay(m_forwardHandle, &status)) {
|
||||
if (getRelay(m_reverseHandle, &status)) {
|
||||
return kOn;
|
||||
} else {
|
||||
if (m_direction == kForwardOnly) {
|
||||
@@ -180,7 +194,7 @@ Relay::Value Relay::Get() const {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (getRelayReverse(m_relay_ports[m_channel], &status)) {
|
||||
if (getRelay(m_reverseHandle, &status)) {
|
||||
if (m_direction == kReverseOnly) {
|
||||
return kOn;
|
||||
} else {
|
||||
|
||||
@@ -22,7 +22,6 @@ const uint32_t SensorBase::kChassisSlots;
|
||||
|
||||
static bool portsInitialized = false;
|
||||
void* SensorBase::m_digital_ports[kDigitalChannels];
|
||||
void* SensorBase::m_relay_ports[kRelayChannels];
|
||||
void* SensorBase::m_pwm_ports[kPwmChannels];
|
||||
|
||||
/**
|
||||
@@ -37,13 +36,6 @@ SensorBase::SensorBase() {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < kRelayChannels; i++) {
|
||||
HalPortHandle port = getPort(i);
|
||||
int32_t status = 0;
|
||||
m_relay_ports[i] = initializeDigitalPort(port, &status);
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < kPwmChannels; i++) {
|
||||
HalPortHandle port = getPort(i);
|
||||
int32_t status = 0;
|
||||
@@ -77,16 +69,15 @@ bool SensorBase::CheckDigitalChannel(uint32_t channel) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the digital channel number is valid.
|
||||
* Check that the relay channel number is valid.
|
||||
*
|
||||
* Verify that the channel number is one of the legal channel numbers. Channel
|
||||
* numbers are 1-based.
|
||||
* numbers are 0-based.
|
||||
*
|
||||
* @return Relay channel is valid
|
||||
*/
|
||||
bool SensorBase::CheckRelayChannel(uint32_t channel) {
|
||||
if (channel < kRelayChannels) return true;
|
||||
return false;
|
||||
return checkRelayChannel((uint8_t)channel);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,68 +27,75 @@ extern "C" {
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_RelayJNI
|
||||
* Method: setRelayForward
|
||||
* Signature: (JZ)V
|
||||
* Method: initializeRelayPort
|
||||
* Signature: (IZ)I;
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_RelayJNI_setRelayForward(
|
||||
JNIEnv* env, jclass, jlong id, jboolean value) {
|
||||
RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI setRelayForward";
|
||||
RELAYJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id;
|
||||
JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_RelayJNI_initializeRelayPort(
|
||||
JNIEnv* env, jclass, jint id, jboolean fwd) {
|
||||
RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI initializeRelayPort";
|
||||
RELAYJNI_LOG(logDEBUG) << "Port Handle = " << (HalPortHandle)id;
|
||||
RELAYJNI_LOG(logDEBUG) << "Forward = " << (jint)fwd;
|
||||
int32_t status = 0;
|
||||
HalRelayHandle handle = initializeRelayPort((HalPortHandle)id, (uint8_t) fwd, &status);
|
||||
RELAYJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
RELAYJNI_LOG(logDEBUG) << "Relay Handle = " << handle;
|
||||
return (jint) handle;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_RelayJNI
|
||||
* Method: freeRelayPort
|
||||
* Signature: (I)V;
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_RelayJNI_freeRelayPort(
|
||||
JNIEnv *env, jclass, jint id) {
|
||||
RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI freeRelayPort";
|
||||
RELAYJNI_LOG(logDEBUG) << "Port Handle = " << (HalRelayHandle)id;
|
||||
freeRelayPort((HalRelayHandle)id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_RelayJNI
|
||||
* Method: checkRelayChannel
|
||||
* Signature: (I)Z;
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_edu_wpi_first_wpilibj_hal_RelayJNI_checkRelayChannel(
|
||||
JNIEnv *env, jclass, jint channel) {
|
||||
RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI checkRelayChannel";
|
||||
RELAYJNI_LOG(logDEBUG) << "Channel = " << channel;
|
||||
return (jboolean)checkRelayChannel((uint8_t) channel);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_RelayJNI
|
||||
* Method: setRelay
|
||||
* Signature: (IZ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_RelayJNI_setRelay(
|
||||
JNIEnv* env, jclass, jint id, jboolean value) {
|
||||
RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI setRelay";
|
||||
RELAYJNI_LOG(logDEBUG) << "Port Handle = " << (HalRelayHandle)id;
|
||||
RELAYJNI_LOG(logDEBUG) << "Flag = " << (jint)value;
|
||||
int32_t status = 0;
|
||||
setRelayForward((void*)id, value, &status);
|
||||
setRelay((HalRelayHandle)id, value, &status);
|
||||
RELAYJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_RelayJNI
|
||||
* Method: setRelayReverse
|
||||
* Signature: (JZ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_RelayJNI_setRelayReverse(
|
||||
JNIEnv* env, jclass, jlong id, jboolean value) {
|
||||
RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI setRelayReverse";
|
||||
RELAYJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id;
|
||||
RELAYJNI_LOG(logDEBUG) << "Flag = " << (jint)value;
|
||||
int32_t status = 0;
|
||||
setRelayReverse((void*)id, value, &status);
|
||||
RELAYJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
CheckStatus(env, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_RelayJNI
|
||||
* Method: getRelayForward
|
||||
* Signature: (J)Z
|
||||
* Method: getRelay
|
||||
* Signature: (I)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_edu_wpi_first_wpilibj_hal_RelayJNI_getRelayForward(
|
||||
JNIEnv* env, jclass, jlong id) {
|
||||
RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI getRelayForward";
|
||||
RELAYJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id;
|
||||
Java_edu_wpi_first_wpilibj_hal_RelayJNI_getRelay(
|
||||
JNIEnv* env, jclass, jint id) {
|
||||
RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI getRelay";
|
||||
RELAYJNI_LOG(logDEBUG) << "Port Handle = " << (HalRelayHandle)id;
|
||||
int32_t status = 0;
|
||||
jboolean returnValue = getRelayForward((void*)id, &status);
|
||||
jboolean returnValue = getRelay((HalRelayHandle)id, &status);
|
||||
RELAYJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
RELAYJNI_LOG(logDEBUG) << "getRelayForwardResult = " << (jint)returnValue;
|
||||
CheckStatus(env, status);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_wpilibj_hal_RelayJNI
|
||||
* Method: getRelayReverse
|
||||
* Signature: (J)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_edu_wpi_first_wpilibj_hal_RelayJNI_getRelayReverse(
|
||||
JNIEnv* env, jclass, jlong id) {
|
||||
RELAYJNI_LOG(logDEBUG) << "Calling RELAYJNI getRelayReverse";
|
||||
RELAYJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id;
|
||||
int32_t status = 0;
|
||||
jboolean returnValue = getRelayReverse((void*)id, &status);
|
||||
RELAYJNI_LOG(logDEBUG) << "Status = " << status;
|
||||
RELAYJNI_LOG(logDEBUG) << "getRelayReverseResult = " << (jint)returnValue;
|
||||
RELAYJNI_LOG(logDEBUG) << "getRelayResult = " << (jint)returnValue;
|
||||
CheckStatus(env, status);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
|
||||
import edu.wpi.first.wpilibj.tables.ITable;
|
||||
import edu.wpi.first.wpilibj.tables.ITableListener;
|
||||
import edu.wpi.first.wpilibj.util.AllocationException;
|
||||
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
@@ -111,10 +110,12 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
|
||||
}
|
||||
|
||||
private final int m_channel;
|
||||
|
||||
private int m_forwardHandle = 0;
|
||||
private int m_reverseHandle = 0;
|
||||
private long m_port;
|
||||
|
||||
private Direction m_direction;
|
||||
private static Resource relayChannels = new Resource(kRelayChannels * 2);
|
||||
|
||||
/**
|
||||
* Common relay initialization method. This code is common to all Relay constructors and
|
||||
@@ -122,21 +123,18 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
|
||||
* set to both lines at 0v.
|
||||
*/
|
||||
private void initRelay() {
|
||||
SensorBase.checkRelayChannel(m_channel);
|
||||
try {
|
||||
if (m_direction == Direction.kBoth || m_direction == Direction.kForward) {
|
||||
relayChannels.allocate(m_channel * 2);
|
||||
UsageReporting.report(tResourceType.kResourceType_Relay, m_channel);
|
||||
}
|
||||
if (m_direction == Direction.kBoth || m_direction == Direction.kReverse) {
|
||||
relayChannels.allocate(m_channel * 2 + 1);
|
||||
UsageReporting.report(tResourceType.kResourceType_Relay, m_channel + 128);
|
||||
}
|
||||
} catch (CheckedAllocationException ex) {
|
||||
throw new AllocationException("Relay channel " + m_channel + " is already allocated");
|
||||
if (!RelayJNI.checkRelayChannel(m_channel)) {
|
||||
throw new IndexOutOfBoundsException("Requested relay channel number is out of range.");
|
||||
}
|
||||
int portHandle = RelayJNI.getPort((byte)m_channel);
|
||||
if (m_direction == Direction.kBoth || m_direction == Direction.kForward) {
|
||||
m_forwardHandle = RelayJNI.initializeRelayPort(portHandle, true);
|
||||
UsageReporting.report(tResourceType.kResourceType_Relay, m_channel);
|
||||
}
|
||||
if (m_direction == Direction.kBoth || m_direction == Direction.kReverse) {
|
||||
m_reverseHandle = RelayJNI.initializeRelayPort(portHandle, false);
|
||||
UsageReporting.report(tResourceType.kResourceType_Relay, m_channel + 128);
|
||||
}
|
||||
|
||||
m_port = DIOJNI.initializeDigitalPort(DIOJNI.getPort((byte) m_channel));
|
||||
|
||||
m_safetyHelper = new MotorSafetyHelper(this);
|
||||
m_safetyHelper.setSafetyEnabled(false);
|
||||
@@ -168,19 +166,22 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
|
||||
|
||||
@Override
|
||||
public void free() {
|
||||
if (m_direction == Direction.kBoth || m_direction == Direction.kForward) {
|
||||
relayChannels.free(m_channel * 2);
|
||||
try {
|
||||
RelayJNI.setRelay(m_forwardHandle, false);
|
||||
} catch (RuntimeException ex) {
|
||||
// do nothing. Ignore
|
||||
}
|
||||
if (m_direction == Direction.kBoth || m_direction == Direction.kReverse) {
|
||||
relayChannels.free(m_channel * 2 + 1);
|
||||
try {
|
||||
RelayJNI.setRelay(m_reverseHandle, false);
|
||||
} catch (RuntimeException ex) {
|
||||
// do nothing. Ignore
|
||||
}
|
||||
|
||||
RelayJNI.setRelayForward(m_port, false);
|
||||
RelayJNI.setRelayReverse(m_port, false);
|
||||
|
||||
DIOJNI.freeDIO(m_port);
|
||||
DIOJNI.freeDigitalPort(m_port);
|
||||
m_port = 0;
|
||||
|
||||
RelayJNI.freeRelayPort(m_forwardHandle);
|
||||
RelayJNI.freeRelayPort(m_reverseHandle);
|
||||
|
||||
m_forwardHandle = 0;
|
||||
m_reverseHandle = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,18 +201,18 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
|
||||
switch (value) {
|
||||
case kOff:
|
||||
if (m_direction == Direction.kBoth || m_direction == Direction.kForward) {
|
||||
RelayJNI.setRelayForward(m_port, false);
|
||||
RelayJNI.setRelay(m_forwardHandle, false);
|
||||
}
|
||||
if (m_direction == Direction.kBoth || m_direction == Direction.kReverse) {
|
||||
RelayJNI.setRelayReverse(m_port, false);
|
||||
RelayJNI.setRelay(m_reverseHandle, false);
|
||||
}
|
||||
break;
|
||||
case kOn:
|
||||
if (m_direction == Direction.kBoth || m_direction == Direction.kForward) {
|
||||
RelayJNI.setRelayForward(m_port, true);
|
||||
RelayJNI.setRelay(m_forwardHandle, true);
|
||||
}
|
||||
if (m_direction == Direction.kBoth || m_direction == Direction.kReverse) {
|
||||
RelayJNI.setRelayReverse(m_port, true);
|
||||
RelayJNI.setRelay(m_reverseHandle, true);
|
||||
}
|
||||
break;
|
||||
case kForward:
|
||||
@@ -220,10 +221,10 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
|
||||
+ "forward");
|
||||
}
|
||||
if (m_direction == Direction.kBoth || m_direction == Direction.kForward) {
|
||||
RelayJNI.setRelayForward(m_port, true);
|
||||
RelayJNI.setRelay(m_forwardHandle, true);
|
||||
}
|
||||
if (m_direction == Direction.kBoth) {
|
||||
RelayJNI.setRelayReverse(m_port, false);
|
||||
RelayJNI.setRelay(m_reverseHandle, false);
|
||||
}
|
||||
break;
|
||||
case kReverse:
|
||||
@@ -232,10 +233,10 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
|
||||
+ "reverse");
|
||||
}
|
||||
if (m_direction == Direction.kBoth) {
|
||||
RelayJNI.setRelayForward(m_port, false);
|
||||
RelayJNI.setRelay(m_forwardHandle, false);
|
||||
}
|
||||
if (m_direction == Direction.kBoth || m_direction == Direction.kReverse) {
|
||||
RelayJNI.setRelayReverse(m_port, true);
|
||||
RelayJNI.setRelay(m_reverseHandle, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -254,8 +255,8 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
|
||||
* @return The current state of the relay as a Relay::Value
|
||||
*/
|
||||
public Value get() {
|
||||
if (RelayJNI.getRelayForward(m_port)) {
|
||||
if (RelayJNI.getRelayReverse(m_port)) {
|
||||
if (RelayJNI.getRelay(m_forwardHandle)) {
|
||||
if (RelayJNI.getRelay(m_reverseHandle)) {
|
||||
return Value.kOn;
|
||||
} else {
|
||||
if (m_direction == Direction.kForward) {
|
||||
@@ -265,7 +266,7 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (RelayJNI.getRelayReverse(m_port)) {
|
||||
if (RelayJNI.getRelay(m_reverseHandle)) {
|
||||
if (m_direction == Direction.kReverse) {
|
||||
return Value.kOn;
|
||||
} else {
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
package edu.wpi.first.wpilibj.hal;
|
||||
|
||||
public class RelayJNI extends DIOJNI {
|
||||
public static native void setRelayForward(long digitalPortPointer, boolean on);
|
||||
public static native int initializeRelayPort(int halPortHandle, boolean forward);
|
||||
|
||||
public static native void freeRelayPort(int relayPortHandle);
|
||||
|
||||
public static native boolean checkRelayChannel(int pin);
|
||||
|
||||
public static native void setRelay(int relayPortHandle, boolean on);
|
||||
|
||||
public static native void setRelayReverse(long digitalPortPointer, boolean on);
|
||||
|
||||
public static native boolean getRelayForward(long digitalPortPointer);
|
||||
|
||||
public static native boolean getRelayReverse(long digitalPortPointer);
|
||||
public static native boolean getRelay(int relayPortHandle);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user