blob: e8bc1e5810782ecebad5a3357aa327b121252e16 [file] [log] [blame]
Brian Silverman26e4e522015-12-17 01:56:40 -05001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2014. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include <AnalogInput.h>
9#include <AnalogOutput.h>
10#include <AnalogTrigger.h>
11#include <Counter.h>
12#include <Timer.h>
13#include "gtest/gtest.h"
14#include "TestBench.h"
15
16static const double kDelayTime = 0.01;
17
18/**
19 * A fixture with an analog input and an analog output wired together
20 */
21class AnalogLoopTest : public testing::Test {
22 protected:
23 AnalogInput *m_input;
24 AnalogOutput *m_output;
25
26 virtual void SetUp() override {
27 m_input = new AnalogInput(TestBench::kFakeAnalogOutputChannel);
28 m_output = new AnalogOutput(TestBench::kAnalogOutputChannel);
29 }
30
31 virtual void TearDown() override {
32 delete m_input;
33 delete m_output;
34 }
35};
36
37/**
38 * Test analog inputs and outputs by setting one and making sure the other
39 * matches.
40 */
41TEST_F(AnalogLoopTest, AnalogInputWorks) {
42 // Set the output voltage and check if the input measures the same voltage
43 for (int i = 0; i < 50; i++) {
44 m_output->SetVoltage(i / 10.0f);
45
46 Wait(kDelayTime);
47
48 EXPECT_NEAR(m_output->GetVoltage(), m_input->GetVoltage(), 0.01f);
49 }
50}
51
52/**
53 * Test if we can use an analog trigger to check if the output is within a
54 * range correctly.
55 */
56TEST_F(AnalogLoopTest, AnalogTriggerWorks) {
57 AnalogTrigger trigger(m_input);
58 trigger.SetLimitsVoltage(2.0f, 3.0f);
59
60 m_output->SetVoltage(1.0f);
61 Wait(kDelayTime);
62
63 EXPECT_FALSE(trigger.GetInWindow())
64 << "Analog trigger is in the window (2V, 3V)";
65 EXPECT_FALSE(trigger.GetTriggerState()) << "Analog trigger is on";
66
67 m_output->SetVoltage(2.5f);
68 Wait(kDelayTime);
69
70 EXPECT_TRUE(trigger.GetInWindow())
71 << "Analog trigger is not in the window (2V, 3V)";
72 EXPECT_FALSE(trigger.GetTriggerState()) << "Analog trigger is on";
73
74 m_output->SetVoltage(4.0f);
75 Wait(kDelayTime);
76
77 EXPECT_FALSE(trigger.GetInWindow())
78 << "Analog trigger is in the window (2V, 3V)";
79 EXPECT_TRUE(trigger.GetTriggerState()) << "Analog trigger is not on";
80}
81
82/**
83 * Test if we can count the right number of ticks from an analog trigger with
84 * a counter.
85 */
86TEST_F(AnalogLoopTest, AnalogTriggerCounterWorks) {
87 AnalogTrigger trigger(m_input);
88 trigger.SetLimitsVoltage(2.0f, 3.0f);
89
90 Counter counter(trigger);
91
92 // Turn the analog output low and high 50 times
93 for (int i = 0; i < 50; i++) {
94 m_output->SetVoltage(1.0);
95 Wait(kDelayTime);
96 m_output->SetVoltage(4.0);
97 Wait(kDelayTime);
98 }
99
100 // The counter should be 50
101 EXPECT_EQ(50, counter.Get())
102 << "Analog trigger counter did not count 50 ticks";
103}
104
105static void InterruptHandler(uint32_t interruptAssertedMask, void *param) {
106 *(int *)param = 12345;
107}
108
109TEST_F(AnalogLoopTest, AsynchronusInterruptWorks) {
110 int param = 0;
111 AnalogTrigger trigger(m_input);
112 trigger.SetLimitsVoltage(2.0f, 3.0f);
113
114 // Given an interrupt handler that sets an int to 12345
115 std::shared_ptr<AnalogTriggerOutput> triggerOutput = trigger.CreateOutput(kState);
116 triggerOutput->RequestInterrupts(InterruptHandler, &param);
117 triggerOutput->EnableInterrupts();
118
119 // If the analog output moves from below to above the window
120 m_output->SetVoltage(0.0);
121 Wait(kDelayTime);
122 m_output->SetVoltage(5.0);
123 triggerOutput->CancelInterrupts();
124
125 // Then the int should be 12345
126 Wait(kDelayTime);
127 EXPECT_EQ(12345, param) << "The interrupt did not run.";
128}