diff --git a/hal/include/HAL/Interrupts.h b/hal/include/HAL/Interrupts.h index 52cf652498..ea845eeb0e 100644 --- a/hal/include/HAL/Interrupts.h +++ b/hal/include/HAL/Interrupts.h @@ -9,26 +9,32 @@ #include +#include "Handles.h" + +typedef HalHandle HalInterruptHandle; + extern "C" { typedef void (*InterruptHandlerFunction)(uint32_t interruptAssertedMask, void* param); -void* initializeInterrupts(uint32_t interruptIndex, bool watcher, - int32_t* status); -void cleanInterrupts(void* interrupt_pointer, int32_t* status); +HalInterruptHandle initializeInterrupts(bool watcher, int32_t* status); +void cleanInterrupts(HalInterruptHandle interrupt_handle, int32_t* status); -uint32_t waitForInterrupt(void* interrupt_pointer, double timeout, +uint32_t waitForInterrupt(HalInterruptHandle interrupt_handle, double timeout, bool ignorePrevious, int32_t* status); -void enableInterrupts(void* interrupt_pointer, int32_t* status); -void disableInterrupts(void* interrupt_pointer, int32_t* status); -double readRisingTimestamp(void* interrupt_pointer, int32_t* status); -double readFallingTimestamp(void* interrupt_pointer, int32_t* status); -void requestInterrupts(void* interrupt_pointer, uint8_t routing_module, - uint32_t routing_pin, bool routing_analog_trigger, - int32_t* status); -void attachInterruptHandler(void* interrupt_pointer, +void enableInterrupts(HalInterruptHandle interrupt_handle, int32_t* status); +void disableInterrupts(HalInterruptHandle interrupt_handle, int32_t* status); +double readRisingTimestamp(HalInterruptHandle interrupt_handle, + int32_t* status); +double readFallingTimestamp(HalInterruptHandle interrupt_handle, + int32_t* status); +void requestInterrupts(HalInterruptHandle interrupt_handle, + uint8_t routing_module, uint32_t routing_pin, + bool routing_analog_trigger, int32_t* status); +void attachInterruptHandler(HalInterruptHandle interrupt_handle, InterruptHandlerFunction handler, void* param, int32_t* status); -void setInterruptUpSourceEdge(void* interrupt_pointer, bool risingEdge, - bool fallingEdge, int32_t* status); +void setInterruptUpSourceEdge(HalInterruptHandle interrupt_handle, + bool risingEdge, bool fallingEdge, + int32_t* status); } diff --git a/hal/lib/athena/Interrupts.cpp b/hal/lib/athena/Interrupts.cpp index 5c33f4f6fe..afd1aeafd1 100644 --- a/hal/lib/athena/Interrupts.cpp +++ b/hal/lib/athena/Interrupts.cpp @@ -7,37 +7,55 @@ #include "HAL/Interrupts.h" +#include + #include "ChipObject.h" #include "DigitalInternal.h" +#include "HAL/Errors.h" +#include "handles/LimitedHandleResource.h" using namespace hal; +namespace { struct Interrupt // FIXME: why is this internal? { tInterrupt* anInterrupt; tInterruptManager* manager; }; +} + +static LimitedHandleResource + interruptHandles; extern "C" { -void* initializeInterrupts(uint32_t interruptIndex, bool watcher, - int32_t* status) { - Interrupt* anInterrupt = new Interrupt(); +HalInterruptHandle initializeInterrupts(bool watcher, int32_t* status) { + HalInterruptHandle handle = interruptHandles.Allocate(); + if (handle == HAL_INVALID_HANDLE) { + *status = NO_AVAILABLE_RESOURCES; + return HAL_INVALID_HANDLE; + } + auto anInterrupt = interruptHandles.Get(handle); + uint32_t interruptIndex = static_cast(getHandleIndex(handle)); // Expects the calling leaf class to allocate an interrupt index. anInterrupt->anInterrupt = tInterrupt::create(interruptIndex, status); anInterrupt->anInterrupt->writeConfig_WaitForAck(false, status); anInterrupt->manager = new tInterruptManager( (1 << interruptIndex) | (1 << (interruptIndex + 8)), watcher, status); - return anInterrupt; + return handle; } -void cleanInterrupts(void* interrupt_pointer, int32_t* status) { - Interrupt* anInterrupt = (Interrupt*)interrupt_pointer; +void cleanInterrupts(HalInterruptHandle interrupt_handle, int32_t* status) { + auto anInterrupt = interruptHandles.Get(interrupt_handle); + if (anInterrupt == nullptr) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } + interruptHandles.Free(interrupt_handle); delete anInterrupt->anInterrupt; delete anInterrupt->manager; - anInterrupt->anInterrupt = nullptr; - anInterrupt->manager = nullptr; } /** @@ -47,10 +65,14 @@ void cleanInterrupts(void* interrupt_pointer, int32_t* status) { * waitForInterrupt was called. * @return The mask of interrupts that fired. */ -uint32_t waitForInterrupt(void* interrupt_pointer, double timeout, +uint32_t waitForInterrupt(HalInterruptHandle interrupt_handle, double timeout, bool ignorePrevious, int32_t* status) { uint32_t result; - Interrupt* anInterrupt = (Interrupt*)interrupt_pointer; + auto anInterrupt = interruptHandles.Get(interrupt_handle); + if (anInterrupt == nullptr) { + *status = PARAMETER_OUT_OF_RANGE; + return 0; + } result = anInterrupt->manager->watch((int32_t)(timeout * 1e3), ignorePrevious, status); @@ -70,16 +92,24 @@ uint32_t waitForInterrupt(void* interrupt_pointer, double timeout, * time to do the setup of the other options before starting to field * interrupts. */ -void enableInterrupts(void* interrupt_pointer, int32_t* status) { - Interrupt* anInterrupt = (Interrupt*)interrupt_pointer; +void enableInterrupts(HalInterruptHandle interrupt_handle, int32_t* status) { + auto anInterrupt = interruptHandles.Get(interrupt_handle); + if (anInterrupt == nullptr) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } anInterrupt->manager->enable(status); } /** * Disable Interrupts without without deallocating structures. */ -void disableInterrupts(void* interrupt_pointer, int32_t* status) { - Interrupt* anInterrupt = (Interrupt*)interrupt_pointer; +void disableInterrupts(HalInterruptHandle interrupt_handle, int32_t* status) { + auto anInterrupt = interruptHandles.Get(interrupt_handle); + if (anInterrupt == nullptr) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } anInterrupt->manager->disable(status); } @@ -88,8 +118,13 @@ void disableInterrupts(void* interrupt_pointer, int32_t* status) { * This is in the same time domain as GetClock(). * @return Timestamp in seconds since boot. */ -double readRisingTimestamp(void* interrupt_pointer, int32_t* status) { - Interrupt* anInterrupt = (Interrupt*)interrupt_pointer; +double readRisingTimestamp(HalInterruptHandle interrupt_handle, + int32_t* status) { + auto anInterrupt = interruptHandles.Get(interrupt_handle); + if (anInterrupt == nullptr) { + *status = PARAMETER_OUT_OF_RANGE; + return 0; + } uint32_t timestamp = anInterrupt->anInterrupt->readRisingTimeStamp(status); return timestamp * 1e-6; } @@ -99,16 +134,25 @@ double readRisingTimestamp(void* interrupt_pointer, int32_t* status) { * This is in the same time domain as GetClock(). * @return Timestamp in seconds since boot. */ -double readFallingTimestamp(void* interrupt_pointer, int32_t* status) { - Interrupt* anInterrupt = (Interrupt*)interrupt_pointer; +double readFallingTimestamp(HalInterruptHandle interrupt_handle, + int32_t* status) { + auto anInterrupt = interruptHandles.Get(interrupt_handle); + if (anInterrupt == nullptr) { + *status = PARAMETER_OUT_OF_RANGE; + return 0; + } uint32_t timestamp = anInterrupt->anInterrupt->readFallingTimeStamp(status); return timestamp * 1e-6; } -void requestInterrupts(void* interrupt_pointer, uint8_t routing_module, - uint32_t routing_pin, bool routing_analog_trigger, - int32_t* status) { - Interrupt* anInterrupt = (Interrupt*)interrupt_pointer; +void requestInterrupts(HalInterruptHandle interrupt_handle, + uint8_t routing_module, uint32_t routing_pin, + bool routing_analog_trigger, int32_t* status) { + auto anInterrupt = interruptHandles.Get(interrupt_handle); + if (anInterrupt == nullptr) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } anInterrupt->anInterrupt->writeConfig_WaitForAck(false, status); remapDigitalSource(routing_analog_trigger, routing_pin, routing_module); anInterrupt->anInterrupt->writeConfig_Source_AnalogTrigger( @@ -117,16 +161,25 @@ void requestInterrupts(void* interrupt_pointer, uint8_t routing_module, anInterrupt->anInterrupt->writeConfig_Source_Module(routing_module, status); } -void attachInterruptHandler(void* interrupt_pointer, +void attachInterruptHandler(HalInterruptHandle interrupt_handle, InterruptHandlerFunction handler, void* param, int32_t* status) { - Interrupt* anInterrupt = (Interrupt*)interrupt_pointer; + auto anInterrupt = interruptHandles.Get(interrupt_handle); + if (anInterrupt == nullptr) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } anInterrupt->manager->registerHandler(handler, param, status); } -void setInterruptUpSourceEdge(void* interrupt_pointer, bool risingEdge, - bool fallingEdge, int32_t* status) { - Interrupt* anInterrupt = (Interrupt*)interrupt_pointer; +void setInterruptUpSourceEdge(HalInterruptHandle interrupt_handle, + bool risingEdge, bool fallingEdge, + int32_t* status) { + auto anInterrupt = interruptHandles.Get(interrupt_handle); + if (anInterrupt == nullptr) { + *status = PARAMETER_OUT_OF_RANGE; + return; + } anInterrupt->anInterrupt->writeConfig_RisingEdge(risingEdge, status); anInterrupt->anInterrupt->writeConfig_FallingEdge(fallingEdge, status); } diff --git a/hal/lib/athena/handles/HandlesInternal.h b/hal/lib/athena/handles/HandlesInternal.h index a4f266d7b3..e668ca1424 100644 --- a/hal/lib/athena/handles/HandlesInternal.h +++ b/hal/lib/athena/handles/HandlesInternal.h @@ -25,7 +25,13 @@ namespace hal { constexpr int16_t InvalidHandleIndex = -1; -enum class HalHandleEnum { Undefined = 0, DIO = 1, Port = 2, Notifier = 3 }; +enum class HalHandleEnum { + Undefined = 0, + DIO = 1, + Port = 2, + Notifier = 3, + Interrupt = 4 +}; static inline int16_t getHandleIndex(HalHandle handle) { // mask and return last 16 bits diff --git a/wpilibc/athena/include/InterruptableSensorBase.h b/wpilibc/athena/include/InterruptableSensorBase.h index 1ca4549c6b..dfb19932f0 100644 --- a/wpilibc/athena/include/InterruptableSensorBase.h +++ b/wpilibc/athena/include/InterruptableSensorBase.h @@ -46,9 +46,6 @@ class InterruptableSensorBase : public SensorBase { virtual void SetUpSourceEdge(bool risingEdge, bool fallingEdge); protected: - void* m_interrupt = nullptr; - uint32_t m_interruptIndex = std::numeric_limits::max(); + HalInterruptHandle m_interrupt = HAL_INVALID_HANDLE; void AllocateInterrupts(bool watcher); - - static std::unique_ptr m_interrupts; }; diff --git a/wpilibc/athena/src/AnalogTriggerOutput.cpp b/wpilibc/athena/src/AnalogTriggerOutput.cpp index 1f90fb1357..791bf3f574 100644 --- a/wpilibc/athena/src/AnalogTriggerOutput.cpp +++ b/wpilibc/athena/src/AnalogTriggerOutput.cpp @@ -29,12 +29,11 @@ AnalogTriggerOutput::AnalogTriggerOutput(const AnalogTrigger& trigger, } AnalogTriggerOutput::~AnalogTriggerOutput() { - if (m_interrupt != nullptr) { + if (m_interrupt != HAL_INVALID_HANDLE) { int32_t status = 0; cleanInterrupts(m_interrupt, &status); - wpi_setErrorWithContext(status, getHALErrorMessage(status)); - m_interrupt = nullptr; - m_interrupts->Free(m_interruptIndex); + // ignore status, as an invalid handle just needs to be ignored. + m_interrupt = HAL_INVALID_HANDLE; } } diff --git a/wpilibc/athena/src/DigitalInput.cpp b/wpilibc/athena/src/DigitalInput.cpp index 1e2e4ae1b9..9b2b15206c 100644 --- a/wpilibc/athena/src/DigitalInput.cpp +++ b/wpilibc/athena/src/DigitalInput.cpp @@ -46,12 +46,11 @@ DigitalInput::DigitalInput(uint32_t channel) { */ DigitalInput::~DigitalInput() { if (StatusIsFatal()) return; - if (m_interrupt != nullptr) { + if (m_interrupt != HAL_INVALID_HANDLE) { int32_t status = 0; cleanInterrupts(m_interrupt, &status); - wpi_setErrorWithContext(status, getHALErrorMessage(status)); - m_interrupt = nullptr; - m_interrupts->Free(m_interruptIndex); + // ignore status, as an invalid handle just needs to be ignored. + m_interrupt = HAL_INVALID_HANDLE; } int32_t status = 0; diff --git a/wpilibc/athena/src/InterruptableSensorBase.cpp b/wpilibc/athena/src/InterruptableSensorBase.cpp index ce391a2529..be43dab229 100644 --- a/wpilibc/athena/src/InterruptableSensorBase.cpp +++ b/wpilibc/athena/src/InterruptableSensorBase.cpp @@ -11,9 +11,6 @@ #include "Utility.h" #include "WPIErrors.h" -std::unique_ptr InterruptableSensorBase::m_interrupts = - std::make_unique(interrupt_kNumSystems); - InterruptableSensorBase::InterruptableSensorBase() {} /** @@ -27,15 +24,10 @@ InterruptableSensorBase::InterruptableSensorBase() {} void InterruptableSensorBase::RequestInterrupts( InterruptHandlerFunction handler, void* param) { if (StatusIsFatal()) return; - uint32_t index = m_interrupts->Allocate("Async Interrupt"); - if (index == std::numeric_limits::max()) { - CloneError(*m_interrupts); - return; - } - m_interruptIndex = index; - // Creates a manager too + wpi_assert(m_interrupt == HAL_INVALID_HANDLE); AllocateInterrupts(false); + if (StatusIsFatal()) return; // if allocate failed, out of interrupts int32_t status = 0; requestInterrupts(m_interrupt, GetModuleForRouting(), GetChannelForRouting(), @@ -54,14 +46,10 @@ void InterruptableSensorBase::RequestInterrupts( */ void InterruptableSensorBase::RequestInterrupts() { if (StatusIsFatal()) return; - uint32_t index = m_interrupts->Allocate("Sync Interrupt"); - if (index == std::numeric_limits::max()) { - CloneError(*m_interrupts); - return; - } - m_interruptIndex = index; + wpi_assert(m_interrupt == HAL_INVALID_HANDLE); AllocateInterrupts(true); + if (StatusIsFatal()) return; // if allocate failed, out of interrupts int32_t status = 0; requestInterrupts(m_interrupt, GetModuleForRouting(), GetChannelForRouting(), @@ -71,10 +59,10 @@ void InterruptableSensorBase::RequestInterrupts() { } void InterruptableSensorBase::AllocateInterrupts(bool watcher) { - wpi_assert(m_interrupt == nullptr); + wpi_assert(m_interrupt == HAL_INVALID_HANDLE); // Expects the calling leaf class to allocate an interrupt index. int32_t status = 0; - m_interrupt = initializeInterrupts(m_interruptIndex, watcher, &status); + m_interrupt = initializeInterrupts(watcher, &status); wpi_setErrorWithContext(status, getHALErrorMessage(status)); } @@ -85,12 +73,11 @@ void InterruptableSensorBase::AllocateInterrupts(bool watcher) { */ void InterruptableSensorBase::CancelInterrupts() { if (StatusIsFatal()) return; - wpi_assert(m_interrupt != nullptr); + wpi_assert(m_interrupt != HAL_INVALID_HANDLE); int32_t status = 0; cleanInterrupts(m_interrupt, &status); - wpi_setErrorWithContext(status, getHALErrorMessage(status)); - m_interrupt = nullptr; - m_interrupts->Free(m_interruptIndex); + // ignore status, as an invalid handle just needs to be ignored. + m_interrupt = HAL_INVALID_HANDLE; } /** @@ -108,7 +95,7 @@ void InterruptableSensorBase::CancelInterrupts() { InterruptableSensorBase::WaitResult InterruptableSensorBase::WaitForInterrupt( float timeout, bool ignorePrevious) { if (StatusIsFatal()) return InterruptableSensorBase::kTimeout; - wpi_assert(m_interrupt != nullptr); + wpi_assert(m_interrupt != HAL_INVALID_HANDLE); int32_t status = 0; uint32_t result; @@ -127,7 +114,7 @@ InterruptableSensorBase::WaitResult InterruptableSensorBase::WaitForInterrupt( */ void InterruptableSensorBase::EnableInterrupts() { if (StatusIsFatal()) return; - wpi_assert(m_interrupt != nullptr); + wpi_assert(m_interrupt != HAL_INVALID_HANDLE); int32_t status = 0; enableInterrupts(m_interrupt, &status); wpi_setErrorWithContext(status, getHALErrorMessage(status)); @@ -138,7 +125,7 @@ void InterruptableSensorBase::EnableInterrupts() { */ void InterruptableSensorBase::DisableInterrupts() { if (StatusIsFatal()) return; - wpi_assert(m_interrupt != nullptr); + wpi_assert(m_interrupt != HAL_INVALID_HANDLE); int32_t status = 0; disableInterrupts(m_interrupt, &status); wpi_setErrorWithContext(status, getHALErrorMessage(status)); @@ -155,7 +142,7 @@ void InterruptableSensorBase::DisableInterrupts() { */ double InterruptableSensorBase::ReadRisingTimestamp() { if (StatusIsFatal()) return 0.0; - wpi_assert(m_interrupt != nullptr); + wpi_assert(m_interrupt != HAL_INVALID_HANDLE); int32_t status = 0; double timestamp = readRisingTimestamp(m_interrupt, &status); wpi_setErrorWithContext(status, getHALErrorMessage(status)); @@ -173,7 +160,7 @@ double InterruptableSensorBase::ReadRisingTimestamp() { */ double InterruptableSensorBase::ReadFallingTimestamp() { if (StatusIsFatal()) return 0.0; - wpi_assert(m_interrupt != nullptr); + wpi_assert(m_interrupt != HAL_INVALID_HANDLE); int32_t status = 0; double timestamp = readFallingTimestamp(m_interrupt, &status); wpi_setErrorWithContext(status, getHALErrorMessage(status)); @@ -189,13 +176,13 @@ double InterruptableSensorBase::ReadFallingTimestamp() { void InterruptableSensorBase::SetUpSourceEdge(bool risingEdge, bool fallingEdge) { if (StatusIsFatal()) return; - if (m_interrupt == nullptr) { + if (m_interrupt == HAL_INVALID_HANDLE) { wpi_setWPIErrorWithContext( NullParameter, "You must call RequestInterrupts before SetUpSourceEdge"); return; } - if (m_interrupt != nullptr) { + if (m_interrupt != HAL_INVALID_HANDLE) { int32_t status = 0; setInterruptUpSourceEdge(m_interrupt, risingEdge, fallingEdge, &status); wpi_setErrorWithContext(status, getHALErrorMessage(status)); diff --git a/wpilibj/src/athena/cpp/lib/InterruptJNI.cpp b/wpilibj/src/athena/cpp/lib/InterruptJNI.cpp index a357a5fc9e..8845f9364c 100644 --- a/wpilibj/src/athena/cpp/lib/InterruptJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/InterruptJNI.cpp @@ -119,23 +119,22 @@ extern "C" { /* * Class: edu_wpi_first_wpilibj_hal_InterruptJNI * Method: initializeInterrupts - * Signature: (IZ)J + * Signature: (Z)I */ -JNIEXPORT jlong JNICALL +JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_InterruptJNI_initializeInterrupts( - JNIEnv* env, jclass, jint interruptIndex, jboolean watcher) { + JNIEnv* env, jclass, jboolean watcher) { INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI initializeInterrupts"; - INTERRUPTJNI_LOG(logDEBUG) << "interruptIndex = " << interruptIndex; INTERRUPTJNI_LOG(logDEBUG) << "watcher = " << (bool)watcher; int32_t status = 0; - void* interrupt = initializeInterrupts(interruptIndex, watcher, &status); + HalInterruptHandle interrupt = initializeInterrupts(watcher, &status); - INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Ptr = " << interrupt; + INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Handle = " << interrupt; INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status; CheckStatus(env, status); - return (jlong)interrupt; + return (jint)interrupt; } /* @@ -145,16 +144,16 @@ Java_edu_wpi_first_wpilibj_hal_InterruptJNI_initializeInterrupts( */ JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_InterruptJNI_cleanInterrupts( - JNIEnv* env, jclass, jlong interrupt_pointer) { + JNIEnv* env, jclass, jint interrupt_handle) { INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI cleanInterrupts"; - INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Ptr = " << (void*)interrupt_pointer; + INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Handle = " << (HalInterruptHandle)interrupt_handle; int32_t status = 0; - cleanInterrupts((void*)interrupt_pointer, &status); + cleanInterrupts((HalInterruptHandle)interrupt_handle, &status); INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status; - CheckStatus(env, status); + // ignore status, as an invalid handle just needs to be ignored. } /* @@ -164,13 +163,13 @@ Java_edu_wpi_first_wpilibj_hal_InterruptJNI_cleanInterrupts( */ JNIEXPORT int JNICALL Java_edu_wpi_first_wpilibj_hal_InterruptJNI_waitForInterrupt( - JNIEnv* env, jclass, jlong interrupt_pointer, jdouble timeout, + JNIEnv* env, jclass, jint interrupt_handle, jdouble timeout, jboolean ignorePrevious) { INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI waitForInterrupt"; - INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Ptr = " << (void*)interrupt_pointer; + INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Handle = " << (HalInterruptHandle)interrupt_handle; int32_t status = 0; - int result = waitForInterrupt((void*)interrupt_pointer, timeout, + int result = waitForInterrupt((HalInterruptHandle)interrupt_handle, timeout, ignorePrevious, &status); INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status; @@ -186,12 +185,12 @@ Java_edu_wpi_first_wpilibj_hal_InterruptJNI_waitForInterrupt( */ JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_InterruptJNI_enableInterrupts( - JNIEnv* env, jclass, jlong interrupt_pointer) { + JNIEnv* env, jclass, jint interrupt_handle) { INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI enableInterrupts"; - INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Ptr = " << (void*)interrupt_pointer; + INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Handle = " << (HalInterruptHandle)interrupt_handle; int32_t status = 0; - enableInterrupts((void*)interrupt_pointer, &status); + enableInterrupts((HalInterruptHandle)interrupt_handle, &status); INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status; @@ -205,12 +204,12 @@ Java_edu_wpi_first_wpilibj_hal_InterruptJNI_enableInterrupts( */ JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_InterruptJNI_disableInterrupts( - JNIEnv* env, jclass, jlong interrupt_pointer) { + JNIEnv* env, jclass, jint interrupt_handle) { INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI disableInterrupts"; - INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Ptr = " << (void*)interrupt_pointer; + INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Handle = " << (HalInterruptHandle)interrupt_handle; int32_t status = 0; - disableInterrupts((void*)interrupt_pointer, &status); + disableInterrupts((HalInterruptHandle)interrupt_handle, &status); INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status; @@ -224,12 +223,12 @@ Java_edu_wpi_first_wpilibj_hal_InterruptJNI_disableInterrupts( */ JNIEXPORT jdouble JNICALL Java_edu_wpi_first_wpilibj_hal_InterruptJNI_readRisingTimestamp( - JNIEnv* env, jclass, jlong interrupt_pointer) { + JNIEnv* env, jclass, jint interrupt_handle) { INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI readRisingTimestamp"; - INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Ptr = " << (void*)interrupt_pointer; + INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Handle = " << (HalInterruptHandle)interrupt_handle; int32_t status = 0; - jdouble timeStamp = readRisingTimestamp((void*)interrupt_pointer, &status); + jdouble timeStamp = readRisingTimestamp((HalInterruptHandle)interrupt_handle, &status); INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status; CheckStatus(env, status); @@ -243,12 +242,12 @@ Java_edu_wpi_first_wpilibj_hal_InterruptJNI_readRisingTimestamp( */ JNIEXPORT jdouble JNICALL Java_edu_wpi_first_wpilibj_hal_InterruptJNI_readFallingTimestamp( - JNIEnv* env, jclass, jlong interrupt_pointer) { + JNIEnv* env, jclass, jint interrupt_handle) { INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI readFallingTimestamp"; - INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Ptr = " << (void*)interrupt_pointer; + INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Handle = " << (HalInterruptHandle)interrupt_handle; int32_t status = 0; - jdouble timeStamp = readFallingTimestamp((void*)interrupt_pointer, &status); + jdouble timeStamp = readFallingTimestamp((HalInterruptHandle)interrupt_handle, &status); INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status; CheckStatus(env, status); @@ -262,17 +261,17 @@ Java_edu_wpi_first_wpilibj_hal_InterruptJNI_readFallingTimestamp( */ JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_InterruptJNI_requestInterrupts( - JNIEnv* env, jclass, jlong interrupt_pointer, jbyte routing_module, + JNIEnv* env, jclass, jint interrupt_handle, jbyte routing_module, jint routing_pin, jboolean routing_analog_trigger) { INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI requestInterrupts"; - INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Ptr = " << (void*)interrupt_pointer; + INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Handle = " << (HalInterruptHandle)interrupt_handle; INTERRUPTJNI_LOG(logDEBUG) << "routing module = " << (jint)routing_module; INTERRUPTJNI_LOG(logDEBUG) << "routing pin = " << routing_pin; INTERRUPTJNI_LOG(logDEBUG) << "routing analog trigger = " << (jint)routing_analog_trigger; int32_t status = 0; - requestInterrupts((void*)interrupt_pointer, (uint8_t)routing_module, + requestInterrupts((HalInterruptHandle)interrupt_handle, (uint8_t)routing_module, (uint32_t)routing_pin, routing_analog_trigger, &status); INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status; @@ -287,10 +286,10 @@ Java_edu_wpi_first_wpilibj_hal_InterruptJNI_requestInterrupts( */ JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_InterruptJNI_attachInterruptHandler( - JNIEnv* env, jclass, jlong interrupt_pointer, jobject handler, + JNIEnv* env, jclass, jint interrupt_handle, jobject handler, jobject param) { INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI attachInterruptHandler"; - INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Ptr = " << (void*)interrupt_pointer; + INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Handle = " << (HalInterruptHandle)interrupt_handle; jclass cls = env->GetObjectClass(handler); INTERRUPTJNI_LOG(logDEBUG) << "class = " << cls; @@ -314,7 +313,7 @@ Java_edu_wpi_first_wpilibj_hal_InterruptJNI_attachInterruptHandler( INTERRUPTJNI_LOG(logDEBUG) << "InterruptThreadJNI Ptr = " << intr; int32_t status = 0; - attachInterruptHandler((void*)interrupt_pointer, interruptHandler, intr, + attachInterruptHandler((HalInterruptHandle)interrupt_handle, interruptHandler, intr, &status); INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status; @@ -328,15 +327,15 @@ Java_edu_wpi_first_wpilibj_hal_InterruptJNI_attachInterruptHandler( */ JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_InterruptJNI_setInterruptUpSourceEdge( - JNIEnv* env, jclass, jlong interrupt_pointer, jboolean risingEdge, + JNIEnv* env, jclass, jint interrupt_handle, jboolean risingEdge, jboolean fallingEdge) { INTERRUPTJNI_LOG(logDEBUG) << "Calling INTERRUPTJNI setInterruptUpSourceEdge"; - INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Ptr = " << (void*)interrupt_pointer; + INTERRUPTJNI_LOG(logDEBUG) << "Interrupt Handle = " << (HalInterruptHandle)interrupt_handle; INTERRUPTJNI_LOG(logDEBUG) << "Rising Edge = " << (bool)risingEdge; INTERRUPTJNI_LOG(logDEBUG) << "Falling Edge = " << (bool)fallingEdge; int32_t status = 0; - setInterruptUpSourceEdge((void*)interrupt_pointer, risingEdge, fallingEdge, + setInterruptUpSourceEdge((HalInterruptHandle)interrupt_handle, risingEdge, fallingEdge, &status); INTERRUPTJNI_LOG(logDEBUG) << "Status = " << status; diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/InterruptableSensorBase.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/InterruptableSensorBase.java index 8d543a6201..5655019027 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/InterruptableSensorBase.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/InterruptableSensorBase.java @@ -9,7 +9,7 @@ package edu.wpi.first.wpilibj; import edu.wpi.first.wpilibj.hal.InterruptJNI; import edu.wpi.first.wpilibj.util.AllocationException; -import edu.wpi.first.wpilibj.util.CheckedAllocationException; + /** * Base for sensors to be used with interrupts. @@ -42,22 +42,13 @@ public abstract class InterruptableSensorBase extends SensorBase { /** * The interrupt resource. */ - protected long m_interrupt = 0; + protected int m_interrupt = InterruptJNI.HalInvalidHandle; /** * Flags if the interrupt being allocated is synchronous. */ protected boolean m_isSynchronousInterrupt = false; - /** - * The index of the interrupt. - */ - protected int m_interruptIndex; - /** - * Resource manager. - */ - protected static Resource m_interrupts = new Resource(8); - /** * Create a new InterrupatableSensorBase. */ @@ -138,15 +129,9 @@ public abstract class InterruptableSensorBase extends SensorBase { * have to explicitly wait for the interrupt to occur. */ protected void allocateInterrupts(boolean watcher) { - try { - m_interruptIndex = m_interrupts.allocate(); - } catch (CheckedAllocationException ex) { - throw new AllocationException("No interrupts are left to be allocated"); - } m_isSynchronousInterrupt = watcher; - - m_interrupt = - InterruptJNI.initializeInterrupts(m_interruptIndex, watcher); + + m_interrupt = InterruptJNI.initializeInterrupts(watcher); } /** @@ -159,7 +144,6 @@ public abstract class InterruptableSensorBase extends SensorBase { } InterruptJNI.cleanInterrupts(m_interrupt); m_interrupt = 0; - m_interrupts.free(m_interruptIndex); } /** diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/InterruptJNI.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/InterruptJNI.java index dbe630f541..fd4e60b31a 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/InterruptJNI.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/InterruptJNI.java @@ -8,32 +8,34 @@ package edu.wpi.first.wpilibj.hal; public class InterruptJNI extends JNIWrapper { + public static final int HalInvalidHandle = 0; + public interface InterruptJNIHandlerFunction { void apply(int interruptAssertedMask, Object param); } - public static native long initializeInterrupts(int interruptIndex, boolean watcher); + public static native int initializeInterrupts(boolean watcher); - public static native void cleanInterrupts(long interruptPointer); + public static native void cleanInterrupts(int interruptHandle); - public static native int waitForInterrupt(long interruptPointer, double timeout, + public static native int waitForInterrupt(int interruptHandle, double timeout, boolean ignorePrevious); - public static native void enableInterrupts(long interruptPointer); + public static native void enableInterrupts(int interruptHandle); - public static native void disableInterrupts(long interruptPointer); + public static native void disableInterrupts(int interruptHandle); - public static native double readRisingTimestamp(long interruptPointer); + public static native double readRisingTimestamp(int interruptHandle); - public static native double readFallingTimestamp(long interruptPointer); + public static native double readFallingTimestamp(int interruptHandle); - public static native void requestInterrupts(long interruptPointer, byte routingModule, + public static native void requestInterrupts(int interruptHandle, byte routingModule, int routingPin, boolean routingAnalogTrigger); - public static native void attachInterruptHandler(long interruptPointer, + public static native void attachInterruptHandler(int interruptHandle, InterruptJNIHandlerFunction handler, Object param); - public static native void setInterruptUpSourceEdge(long interruptPointer, boolean risingEdge, + public static native void setInterruptUpSourceEdge(int interruptHandle, boolean risingEdge, boolean fallingEdge); }