mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-24 01:31:46 +00:00
Moves Interrupts over to Handles instead of pointers (#99)
This commit is contained in:
committed by
Peter Johnson
parent
74fc10999b
commit
046e043c4e
@@ -9,26 +9,32 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
@@ -7,37 +7,55 @@
|
||||
|
||||
#include "HAL/Interrupts.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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<HalInterruptHandle, Interrupt,
|
||||
tInterrupt::kNumSystems, HalHandleEnum::Interrupt>
|
||||
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<uint32_t>(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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<uint32_t>::max();
|
||||
HalInterruptHandle m_interrupt = HAL_INVALID_HANDLE;
|
||||
void AllocateInterrupts(bool watcher);
|
||||
|
||||
static std::unique_ptr<Resource> m_interrupts;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
#include "Utility.h"
|
||||
#include "WPIErrors.h"
|
||||
|
||||
std::unique_ptr<Resource> InterruptableSensorBase::m_interrupts =
|
||||
std::make_unique<Resource>(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<uint32_t>::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<uint32_t>::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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user