blob: d45d5e4a5cf3d6d65869a0cac011871fa9e8ca79 [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#include "frc/AsynchronousInterrupt.h"
6
7#include <frc/DigitalSource.h>
8
9using namespace frc;
10
11AsynchronousInterrupt::AsynchronousInterrupt(
12 DigitalSource& source, std::function<void(bool, bool)> callback)
13 : m_interrupt{source}, m_callback{std::move(callback)} {}
14AsynchronousInterrupt::AsynchronousInterrupt(
15 DigitalSource* source, std::function<void(bool, bool)> callback)
16 : m_interrupt{source}, m_callback{std::move(callback)} {}
17AsynchronousInterrupt::AsynchronousInterrupt(
18 std::shared_ptr<DigitalSource> source,
19 std::function<void(bool, bool)> callback)
20 : m_interrupt{source}, m_callback{std::move(callback)} {}
21
22AsynchronousInterrupt::~AsynchronousInterrupt() {
23 Disable();
24}
25
26void AsynchronousInterrupt::ThreadMain() {
27 while (m_keepRunning) {
28 auto result = m_interrupt.WaitForInterrupt(10_s, false);
29 if (!m_keepRunning) {
30 break;
31 }
32 if (result == SynchronousInterrupt::WaitResult::kTimeout) {
33 continue;
34 }
35 m_callback((result & SynchronousInterrupt::WaitResult::kRisingEdge) != 0,
36 (result & SynchronousInterrupt::WaitResult::kFallingEdge) != 0);
37 }
38}
39
40void AsynchronousInterrupt::Enable() {
41 if (m_keepRunning) {
42 return;
43 }
44
45 m_keepRunning = true;
46 m_thread = std::thread([this] { this->ThreadMain(); });
47}
48
49void AsynchronousInterrupt::Disable() {
50 m_keepRunning = false;
51 m_interrupt.WakeupWaitingInterrupt();
52 if (m_thread.joinable()) {
53 m_thread.join();
54 }
55}
56
57void AsynchronousInterrupt::SetInterruptEdges(bool risingEdge,
58 bool fallingEdge) {
59 m_interrupt.SetInterruptEdges(risingEdge, fallingEdge);
60}
61
62units::second_t AsynchronousInterrupt::GetRisingTimestamp() {
63 return m_interrupt.GetRisingTimestamp();
64}
65units::second_t AsynchronousInterrupt::GetFallingTimestamp() {
66 return m_interrupt.GetFallingTimestamp();
67}