1 #include <catch.hpp> 2 #include "../src/timer.h" 3 4 struct TimerTestEnvironment { 5 Teakra::CoreTiming core_timing; 6 Teakra::Timer timer{core_timing}; 7 int interrupt_counter = 0; TimerTestEnvironmentTimerTestEnvironment8 TimerTestEnvironment() { 9 timer.SetInterruptHandler([&]() { interrupt_counter++; }); 10 } 11 }; 12 13 TEST_CASE("Single mode", "[timer]") { 14 TimerTestEnvironment env; 15 env.timer.count_mode = Teakra::Timer::CountMode::Single; 16 env.timer.update_mmio = 1; 17 env.timer.start_low = 5; 18 env.timer.start_high = 0; 19 env.timer.Restart(); 20 21 REQUIRE(env.timer.counter_low == 5); 22 REQUIRE(env.timer.counter_high == 0); 23 REQUIRE(env.interrupt_counter == 0); 24 REQUIRE(env.timer.GetMaxSkip() == 4); 25 26 env.timer.Tick(); 27 env.timer.Tick(); 28 29 REQUIRE(env.timer.counter_low == 3); 30 REQUIRE(env.timer.counter_high == 0); 31 REQUIRE(env.interrupt_counter == 0); 32 REQUIRE(env.timer.GetMaxSkip() == 2); 33 34 env.timer.Skip(2); 35 REQUIRE(env.timer.counter_low == 1); 36 REQUIRE(env.timer.counter_high == 0); 37 REQUIRE(env.interrupt_counter == 0); 38 REQUIRE(env.timer.GetMaxSkip() == 0); 39 40 env.timer.pause = 1; 41 env.timer.Tick(); 42 REQUIRE(env.timer.counter_low == 1); 43 REQUIRE(env.timer.counter_high == 0); 44 REQUIRE(env.interrupt_counter == 0); 45 REQUIRE(env.timer.GetMaxSkip() == Teakra::CoreTiming::Callbacks::Infinity); 46 47 env.timer.pause = 0; 48 env.timer.Tick(); 49 REQUIRE(env.timer.counter_low == 0); 50 REQUIRE(env.timer.counter_high == 0); 51 REQUIRE(env.interrupt_counter == 1); 52 REQUIRE(env.timer.GetMaxSkip() == Teakra::CoreTiming::Callbacks::Infinity); 53 54 env.timer.Tick(); 55 REQUIRE(env.timer.counter_low == 0); 56 REQUIRE(env.timer.counter_high == 0); 57 REQUIRE(env.interrupt_counter == 1); 58 REQUIRE(env.timer.GetMaxSkip() == Teakra::CoreTiming::Callbacks::Infinity); 59 } 60 61 TEST_CASE("Auto restart mode", "[timer]") { 62 TimerTestEnvironment env; 63 env.timer.count_mode = Teakra::Timer::CountMode::AutoRestart; 64 env.timer.update_mmio = 1; 65 env.timer.start_low = 5; 66 env.timer.start_high = 0x1234; 67 env.timer.Restart(); 68 69 REQUIRE(env.timer.counter_low == 5); 70 REQUIRE(env.timer.counter_high == 0x1234); 71 REQUIRE(env.interrupt_counter == 0); 72 REQUIRE(env.timer.GetMaxSkip() == 0x12340004); 73 74 env.timer.Tick(); 75 env.timer.Tick(); 76 77 REQUIRE(env.timer.counter_low == 3); 78 REQUIRE(env.timer.counter_high == 0x1234); 79 REQUIRE(env.interrupt_counter == 0); 80 REQUIRE(env.timer.GetMaxSkip() == 0x12340002); 81 82 env.timer.Skip(0x12340002); 83 REQUIRE(env.timer.counter_low == 1); 84 REQUIRE(env.timer.counter_high == 0); 85 REQUIRE(env.interrupt_counter == 0); 86 REQUIRE(env.timer.GetMaxSkip() == 0); 87 88 env.timer.pause = 1; 89 env.timer.Tick(); 90 REQUIRE(env.timer.counter_low == 1); 91 REQUIRE(env.timer.counter_high == 0); 92 REQUIRE(env.interrupt_counter == 0); 93 REQUIRE(env.timer.GetMaxSkip() == Teakra::CoreTiming::Callbacks::Infinity); 94 95 env.timer.pause = 0; 96 env.timer.Tick(); 97 REQUIRE(env.timer.counter_low == 0); 98 REQUIRE(env.timer.counter_high == 0); 99 REQUIRE(env.interrupt_counter == 1); 100 REQUIRE(env.timer.GetMaxSkip() == 0x12340005); 101 102 env.timer.Tick(); 103 REQUIRE(env.timer.counter_low == 5); 104 REQUIRE(env.timer.counter_high == 0x1234); 105 REQUIRE(env.interrupt_counter == 1); 106 REQUIRE(env.timer.GetMaxSkip() == 0x12340004); 107 } 108 109 TEST_CASE("Free running mode", "[timer]") { 110 TimerTestEnvironment env; 111 // Set to Single most first to reset counter 112 env.timer.count_mode = Teakra::Timer::CountMode::Single; 113 env.timer.update_mmio = 1; 114 env.timer.start_low = 5; 115 env.timer.start_high = 0x1234; 116 env.timer.Restart(); 117 env.timer.count_mode = Teakra::Timer::CountMode::FreeRunning; 118 119 REQUIRE(env.timer.counter_low == 5); 120 REQUIRE(env.timer.counter_high == 0x1234); 121 REQUIRE(env.interrupt_counter == 0); 122 REQUIRE(env.timer.GetMaxSkip() == 0x12340004); 123 124 env.timer.Restart(); 125 126 REQUIRE(env.timer.counter_low == 5); 127 REQUIRE(env.timer.counter_high == 0x1234); 128 REQUIRE(env.interrupt_counter == 0); 129 REQUIRE(env.timer.GetMaxSkip() == 0x12340004); 130 131 env.timer.Tick(); 132 env.timer.Tick(); 133 134 REQUIRE(env.timer.counter_low == 3); 135 REQUIRE(env.timer.counter_high == 0x1234); 136 REQUIRE(env.interrupt_counter == 0); 137 REQUIRE(env.timer.GetMaxSkip() == 0x12340002); 138 139 env.timer.Skip(0x12340002); 140 REQUIRE(env.timer.counter_low == 1); 141 REQUIRE(env.timer.counter_high == 0); 142 REQUIRE(env.interrupt_counter == 0); 143 REQUIRE(env.timer.GetMaxSkip() == 0); 144 145 env.timer.pause = 1; 146 env.timer.Tick(); 147 REQUIRE(env.timer.counter_low == 1); 148 REQUIRE(env.timer.counter_high == 0); 149 REQUIRE(env.interrupt_counter == 0); 150 REQUIRE(env.timer.GetMaxSkip() == Teakra::CoreTiming::Callbacks::Infinity); 151 152 env.timer.pause = 0; 153 env.timer.Tick(); 154 REQUIRE(env.timer.counter_low == 0); 155 REQUIRE(env.timer.counter_high == 0); 156 REQUIRE(env.interrupt_counter == 1); 157 REQUIRE(env.timer.GetMaxSkip() == 0xFFFFFFFF); 158 159 env.timer.Tick(); 160 REQUIRE(env.timer.counter_low == 0xFFFF); 161 REQUIRE(env.timer.counter_high == 0xFFFF); 162 REQUIRE(env.interrupt_counter == 1); 163 REQUIRE(env.timer.GetMaxSkip() == 0xFFFFFFFE); 164 } 165 166 TEST_CASE("Event counting restart mode", "[timer]") { 167 TimerTestEnvironment env; 168 env.timer.count_mode = Teakra::Timer::CountMode::EventCount; 169 env.timer.update_mmio = 1; 170 env.timer.start_low = 5; 171 env.timer.start_high = 0; 172 env.timer.Restart(); 173 174 REQUIRE(env.timer.counter_low == 5); 175 REQUIRE(env.timer.counter_high == 0); 176 REQUIRE(env.interrupt_counter == 0); 177 REQUIRE(env.timer.GetMaxSkip() == Teakra::CoreTiming::Callbacks::Infinity); 178 179 env.timer.Tick(); 180 181 REQUIRE(env.timer.counter_low == 5); 182 REQUIRE(env.timer.counter_high == 0); 183 REQUIRE(env.interrupt_counter == 0); 184 REQUIRE(env.timer.GetMaxSkip() == Teakra::CoreTiming::Callbacks::Infinity); 185 186 env.timer.TickEvent(); 187 188 REQUIRE(env.timer.counter_low == 4); 189 REQUIRE(env.timer.counter_high == 0); 190 REQUIRE(env.interrupt_counter == 0); 191 REQUIRE(env.timer.GetMaxSkip() == Teakra::CoreTiming::Callbacks::Infinity); 192 193 env.timer.pause = 1; 194 env.timer.TickEvent(); 195 196 REQUIRE(env.timer.counter_low == 4); 197 REQUIRE(env.timer.counter_high == 0); 198 REQUIRE(env.interrupt_counter == 0); 199 REQUIRE(env.timer.GetMaxSkip() == Teakra::CoreTiming::Callbacks::Infinity); 200 201 env.timer.pause = 0; 202 env.timer.TickEvent(); 203 env.timer.TickEvent(); 204 env.timer.TickEvent(); 205 206 REQUIRE(env.timer.counter_low == 1); 207 REQUIRE(env.timer.counter_high == 0); 208 REQUIRE(env.interrupt_counter == 0); 209 REQUIRE(env.timer.GetMaxSkip() == Teakra::CoreTiming::Callbacks::Infinity); 210 211 env.timer.TickEvent(); 212 213 REQUIRE(env.timer.counter_low == 0); 214 REQUIRE(env.timer.counter_high == 0); 215 REQUIRE(env.interrupt_counter == 1); 216 REQUIRE(env.timer.GetMaxSkip() == Teakra::CoreTiming::Callbacks::Infinity); 217 218 env.timer.TickEvent(); 219 220 REQUIRE(env.timer.counter_low == 0); 221 REQUIRE(env.timer.counter_high == 0); 222 REQUIRE(env.interrupt_counter == 1); 223 REQUIRE(env.timer.GetMaxSkip() == Teakra::CoreTiming::Callbacks::Infinity); 224 } 225