[hal, wpilib] Remove interrupt (#7724)

This commit is contained in:
Thad House
2025-01-23 21:45:18 -08:00
committed by GitHub
parent e2b6beb28a
commit 5898cdd5c3
18 changed files with 0 additions and 1970 deletions

View File

@@ -1,155 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.wpilibj;
import static edu.wpi.first.util.ErrorMessages.requireNonNullParam;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiConsumer;
/**
* Class for handling asynchronous interrupts using a callback thread.
*
* <p>By default, interrupts will occur on rising edge. Callbacks are disabled by default, and
* enable() must be called before they will occur.
*
* <p>Both rising and falling edges can be indicated in one callback if both a rising and falling
* edge occurred since the previous callback.
*
* <p>Synchronous (blocking) interrupts are handled by the SynchronousInterrupt class.
*/
public class AsynchronousInterrupt implements AutoCloseable {
private final BiConsumer<Boolean, Boolean> m_callback;
private final SynchronousInterrupt m_interrupt;
private final AtomicBoolean m_keepRunning = new AtomicBoolean(false);
private Thread m_thread;
/**
* Construct a new asynchronous interrupt using a Digital Source.
*
* <p>At construction, the interrupt will trigger on the rising edge.
*
* <p>Callbacks will not be triggered until enable() is called.
*
* <p>The first bool in the callback indicates the rising edge triggered the interrupt, the second
* bool is falling edge.
*
* @param source The digital source to use.
* @param callback The callback to call on an interrupt
*/
public AsynchronousInterrupt(DigitalSource source, BiConsumer<Boolean, Boolean> callback) {
m_callback = requireNonNullParam(callback, "callback", "AsynchronousInterrupt");
m_interrupt = new SynchronousInterrupt(source);
}
/**
* Closes the interrupt.
*
* <p>This does not close the associated digital source.
*
* <p>This will disable the interrupt if it is enabled.
*/
@Override
public void close() {
disable();
m_interrupt.close();
}
/**
* Enables interrupt callbacks. Before this, callbacks will not occur. Does nothing if already
* enabled.
*/
public void enable() {
if (m_keepRunning.get()) {
return;
}
m_keepRunning.set(true);
m_thread = new Thread(this::threadMain);
m_thread.start();
}
/** Disables interrupt callbacks. Does nothing if already disabled. */
public void disable() {
m_keepRunning.set(false);
m_interrupt.wakeupWaitingInterrupt();
if (m_thread != null) {
if (m_thread.isAlive()) {
try {
m_thread.interrupt();
m_thread.join();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
m_thread = null;
}
}
/**
* Set which edges to trigger the interrupt on.
*
* @param risingEdge Trigger on rising edge
* @param fallingEdge Trigger on falling edge
*/
public void setInterruptEdges(boolean risingEdge, boolean fallingEdge) {
m_interrupt.setInterruptEdges(risingEdge, fallingEdge);
}
/**
* Get the timestamp of the last rising edge.
*
* <p>This function does not require the interrupt to be enabled to work.
*
* <p>This only works if rising edge was configured using setInterruptEdges.
*
* @return the timestamp in seconds relative to getFPGATime
*/
public double getRisingTimestamp() {
return m_interrupt.getRisingTimestamp();
}
/**
* Get the timestamp of the last falling edge.
*
* <p>This function does not require the interrupt to be enabled to work.
*
* <p>This only works if falling edge was configured using setInterruptEdges.
*
* @return the timestamp in seconds relative to getFPGATime
*/
public double getFallingTimestamp() {
return m_interrupt.getFallingTimestamp();
}
private void threadMain() {
while (m_keepRunning.get()) {
var result = m_interrupt.waitForInterrupt(10, false);
if (!m_keepRunning.get()) {
break;
}
boolean rising = false;
boolean falling = false;
switch (result) {
case kBoth -> {
rising = true;
falling = true;
}
case kFallingEdge -> {
falling = true;
}
case kRisingEdge -> {
rising = true;
}
default -> {
continue;
}
}
m_callback.accept(rising, falling);
}
}
}

View File

@@ -1,154 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.wpilibj;
import static edu.wpi.first.util.ErrorMessages.requireNonNullParam;
import edu.wpi.first.hal.InterruptJNI;
/**
* Class for handling synchronous (blocking) interrupts.
*
* <p>By default, interrupts will occur on rising edge.
*
* <p>Asynchronous interrupts are handled by the AsynchronousInterrupt class.
*/
public class SynchronousInterrupt implements AutoCloseable {
@SuppressWarnings("PMD.SingularField")
private final DigitalSource m_source;
private final int m_handle;
/** Event trigger combinations for a synchronous interrupt. */
public enum WaitResult {
/** Timeout event. */
kTimeout(0x0),
/** Rising edge event. */
kRisingEdge(0x1),
/** Falling edge event. */
kFallingEdge(0x100),
/** Both rising and falling edge events. */
kBoth(0x101);
/** WaitResult value. */
public final int value;
WaitResult(int value) {
this.value = value;
}
/**
* Create a wait result enum.
*
* @param rising True if a rising edge occurred.
* @param falling True if a falling edge occurred.
* @return A wait result enum.
*/
public static WaitResult getValue(boolean rising, boolean falling) {
if (rising && falling) {
return kBoth;
} else if (rising) {
return kRisingEdge;
} else if (falling) {
return kFallingEdge;
} else {
return kTimeout;
}
}
}
/**
* Constructs a new synchronous interrupt using a DigitalSource.
*
* <p>At construction, the interrupt will trigger on the rising edge.
*
* @param source The digital source to use.
*/
public SynchronousInterrupt(DigitalSource source) {
m_source = requireNonNullParam(source, "source", "SynchronousInterrupt");
m_handle = InterruptJNI.initializeInterrupts();
InterruptJNI.requestInterrupts(
m_handle, m_source.getPortHandleForRouting(), m_source.getAnalogTriggerTypeForRouting());
InterruptJNI.setInterruptUpSourceEdge(m_handle, true, false);
}
/**
* Closes the interrupt.
*
* <p>This does not close the associated digital source.
*/
@Override
public void close() {
InterruptJNI.cleanInterrupts(m_handle);
}
/**
* Wait for an interrupt.
*
* @param timeoutSeconds The timeout in seconds. 0 or less will return immediately.
* @param ignorePrevious True to ignore if a previous interrupt has occurred, and only wait for a
* new trigger. False will consider if an interrupt has occurred since the last time the
* interrupt was read.
* @return Result of which edges were triggered, or if a timeout occurred.
*/
public WaitResult waitForInterrupt(double timeoutSeconds, boolean ignorePrevious) {
long result = InterruptJNI.waitForInterrupt(m_handle, timeoutSeconds, ignorePrevious);
// Rising edge result is the interrupt bit set in the byte 0xFF
// Falling edge result is the interrupt bit set in the byte 0xFF00
// Set any bit set to be true for that edge, and then conduct a logical AND on the 2 results
// together to match the existing enum for all interrupts
boolean rising = (result & 0xFF) != 0;
boolean falling = (result & 0xFF00) != 0;
return WaitResult.getValue(rising, falling);
}
/**
* Wait for an interrupt, ignoring any previously occurring interrupts.
*
* @param timeoutSeconds The timeout in seconds. 0 or less will return immediately.
* @return Result of which edges were triggered, or if a timeout occurred.
*/
public WaitResult waitForInterrupt(double timeoutSeconds) {
return waitForInterrupt(timeoutSeconds, true);
}
/**
* Set which edges to trigger the interrupt on.
*
* @param risingEdge Trigger on rising edge
* @param fallingEdge Trigger on falling edge
*/
public void setInterruptEdges(boolean risingEdge, boolean fallingEdge) {
InterruptJNI.setInterruptUpSourceEdge(m_handle, risingEdge, fallingEdge);
}
/**
* Get the timestamp of the last rising edge.
*
* <p>This only works if rising edge was configured using setInterruptEdges.
*
* @return the timestamp in seconds relative to getFPGATime
*/
public double getRisingTimestamp() {
return InterruptJNI.readInterruptRisingTimestamp(m_handle) * 1e-6;
}
/**
* Get the timestamp of the last falling edge.
*
* <p>This only works if falling edge was configured using setInterruptEdges.
*
* @return the timestamp in seconds relative to getFPGATime
*/
public double getFallingTimestamp() {
return InterruptJNI.readInterruptFallingTimestamp(m_handle) * 1e-6;
}
/** Force triggering of any waiting interrupt, which will be seen as a timeout. */
public void wakeupWaitingInterrupt() {
InterruptJNI.releaseWaitingInterrupt(m_handle);
}
}