blob: d45d5e4a5cf3d6d65869a0cac011871fa9e8ca79 [file] [log] [blame]
// 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.
#include "frc/AsynchronousInterrupt.h"
#include <frc/DigitalSource.h>
using namespace frc;
AsynchronousInterrupt::AsynchronousInterrupt(
DigitalSource& source, std::function<void(bool, bool)> callback)
: m_interrupt{source}, m_callback{std::move(callback)} {}
AsynchronousInterrupt::AsynchronousInterrupt(
DigitalSource* source, std::function<void(bool, bool)> callback)
: m_interrupt{source}, m_callback{std::move(callback)} {}
AsynchronousInterrupt::AsynchronousInterrupt(
std::shared_ptr<DigitalSource> source,
std::function<void(bool, bool)> callback)
: m_interrupt{source}, m_callback{std::move(callback)} {}
AsynchronousInterrupt::~AsynchronousInterrupt() {
Disable();
}
void AsynchronousInterrupt::ThreadMain() {
while (m_keepRunning) {
auto result = m_interrupt.WaitForInterrupt(10_s, false);
if (!m_keepRunning) {
break;
}
if (result == SynchronousInterrupt::WaitResult::kTimeout) {
continue;
}
m_callback((result & SynchronousInterrupt::WaitResult::kRisingEdge) != 0,
(result & SynchronousInterrupt::WaitResult::kFallingEdge) != 0);
}
}
void AsynchronousInterrupt::Enable() {
if (m_keepRunning) {
return;
}
m_keepRunning = true;
m_thread = std::thread([this] { this->ThreadMain(); });
}
void AsynchronousInterrupt::Disable() {
m_keepRunning = false;
m_interrupt.WakeupWaitingInterrupt();
if (m_thread.joinable()) {
m_thread.join();
}
}
void AsynchronousInterrupt::SetInterruptEdges(bool risingEdge,
bool fallingEdge) {
m_interrupt.SetInterruptEdges(risingEdge, fallingEdge);
}
units::second_t AsynchronousInterrupt::GetRisingTimestamp() {
return m_interrupt.GetRisingTimestamp();
}
units::second_t AsynchronousInterrupt::GetFallingTimestamp() {
return m_interrupt.GetFallingTimestamp();
}