// 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. #pragma once #include #include #include #include #include #include namespace frc { /** * Class for handling asynchronous interrupts. * *

By default, interrupts will occur on rising edge. Callbacks are disabled * by default, and Enable() must be called before they will occur. * *

Both rising and falling edge can be indiciated if both a rising and * falling happen between callbacks. * *

Synchronous interrupts are handled by the SynchronousInterrupt class. */ class AsynchronousInterrupt { public: /** * Construct an Asynchronous Interrupt from a Digital Source. * *

At construction, the interrupt will trigger on the rising edge. * *

The first bool in the callback is rising, the 2nd is falling. */ AsynchronousInterrupt(DigitalSource& source, std::function callback); /** * Construct an Asynchronous Interrupt from a Digital Source. * *

At construction, the interrupt will trigger on the rising edge. * *

The first bool in the callback is rising, the 2nd is falling. */ AsynchronousInterrupt(DigitalSource* source, std::function callback); /** * Construct an Asynchronous Interrupt from a Digital Source. * *

At construction, the interrupt will trigger on the rising edge. * *

The first bool in the callback is rising, the 2nd is falling. */ AsynchronousInterrupt(std::shared_ptr source, std::function callback); /** * Construct an Asynchronous Interrupt from a Digital Source. * *

At construction, the interrupt will trigger on the rising edge. * *

The first bool in the callback is rising, the 2nd is falling. */ template AsynchronousInterrupt(DigitalSource& source, Callable&& f, Arg&& arg, Args&&... args) : AsynchronousInterrupt( source, std::bind(std::forward(f), std::forward(arg), std::forward(args)...)) {} /** * Construct an Asynchronous Interrupt from a Digital Source. * *

At construction, the interrupt will trigger on the rising edge. * *

The first bool in the callback is rising, the 2nd is falling. */ template AsynchronousInterrupt(DigitalSource* source, Callable&& f, Arg&& arg, Args&&... args) : AsynchronousInterrupt( source, std::bind(std::forward(f), std::forward(arg), std::forward(args)...)) {} /** * Construct an Asynchronous Interrupt from a Digital Source. * *

At construction, the interrupt will trigger on the rising edge. * *

The first bool in the callback is rising, the 2nd is falling. */ template AsynchronousInterrupt(std::shared_ptr source, Callable&& f, Arg&& arg, Args&&... args) : AsynchronousInterrupt( source, std::bind(std::forward(f), std::forward(arg), std::forward(args)...)) {} ~AsynchronousInterrupt(); /** * Enables interrupt callbacks. Before this, callbacks will not occur. Does * nothing if already enabled. */ void Enable(); /** * Disables interrupt callbacks. Does nothing if already disabled. */ void Disable(); /** * Set which edges to trigger the interrupt on. * * @param risingEdge Trigger on rising edge * @param fallingEdge Trigger on falling edge */ void SetInterruptEdges(bool risingEdge, bool fallingEdge); /** * Get the timestamp of the last rising edge. * *

This function does not require the interrupt to be enabled to work. * *

This only works if rising edge was configured using SetInterruptEdges. * @return the timestamp in seconds relative to getFPGATime */ units::second_t GetRisingTimestamp(); /** * Get the timestamp of the last falling edge. * *

This function does not require the interrupt to be enabled to work. * *

This only works if falling edge was configured using SetInterruptEdges. * @return the timestamp in seconds relative to getFPGATime */ units::second_t GetFallingTimestamp(); private: void ThreadMain(); std::atomic_bool m_keepRunning{false}; std::thread m_thread; SynchronousInterrupt m_interrupt; std::function m_callback; }; } // namespace frc