blob: 8fe387f4dec1458137675997ef0af9b67463132a [file] [log] [blame]
Brian Silverman8fce7482020-01-05 13:18:21 -08001/*----------------------------------------------------------------------------*/
Austin Schuh1e69f942020-11-14 15:06:14 -08002/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
Brian Silverman8fce7482020-01-05 13:18:21 -08003/* 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
Austin Schuh1e69f942020-11-14 15:06:14 -08008#include <algorithm>
Brian Silverman8fce7482020-01-05 13:18:21 -08009#include <atomic>
10#include <chrono>
11#include <cstdio>
12#include <thread>
13
14#include <wpi/timestamp.h>
15
16#include "MockHooksInternal.h"
17#include "NotifierInternal.h"
Austin Schuh1e69f942020-11-14 15:06:14 -080018#include "hal/simulation/NotifierData.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080019
20static std::atomic<bool> programStarted{false};
21
22static std::atomic<uint64_t> programStartTime{0};
23static std::atomic<uint64_t> programPauseTime{0};
Austin Schuh1e69f942020-11-14 15:06:14 -080024static std::atomic<uint64_t> programStepTime{0};
Brian Silverman8fce7482020-01-05 13:18:21 -080025
26namespace hal {
27namespace init {
Austin Schuh1e69f942020-11-14 15:06:14 -080028void InitializeMockHooks() { wpi::SetNowImpl(GetFPGATime); }
Brian Silverman8fce7482020-01-05 13:18:21 -080029} // namespace init
30} // namespace hal
31
32namespace hal {
33void RestartTiming() {
Austin Schuh1e69f942020-11-14 15:06:14 -080034 programStartTime = wpi::NowDefault();
35 programStepTime = 0;
Brian Silverman8fce7482020-01-05 13:18:21 -080036 if (programPauseTime != 0) programPauseTime = programStartTime.load();
37}
38
39void PauseTiming() {
Austin Schuh1e69f942020-11-14 15:06:14 -080040 if (programPauseTime == 0) programPauseTime = wpi::NowDefault();
Brian Silverman8fce7482020-01-05 13:18:21 -080041}
42
43void ResumeTiming() {
44 if (programPauseTime != 0) {
Austin Schuh1e69f942020-11-14 15:06:14 -080045 programStartTime += wpi::NowDefault() - programPauseTime;
Brian Silverman8fce7482020-01-05 13:18:21 -080046 programPauseTime = 0;
47 }
48}
49
50bool IsTimingPaused() { return programPauseTime != 0; }
51
Austin Schuh1e69f942020-11-14 15:06:14 -080052void StepTiming(uint64_t delta) { programStepTime += delta; }
Brian Silverman8fce7482020-01-05 13:18:21 -080053
Austin Schuh1e69f942020-11-14 15:06:14 -080054uint64_t GetFPGATime() {
Brian Silverman8fce7482020-01-05 13:18:21 -080055 uint64_t curTime = programPauseTime;
Austin Schuh1e69f942020-11-14 15:06:14 -080056 if (curTime == 0) curTime = wpi::NowDefault();
57 return curTime + programStepTime - programStartTime;
Brian Silverman8fce7482020-01-05 13:18:21 -080058}
59
60double GetFPGATimestamp() { return GetFPGATime() * 1.0e-6; }
61
62void SetProgramStarted() { programStarted = true; }
63bool GetProgramStarted() { return programStarted; }
64} // namespace hal
65
66using namespace hal;
67
68extern "C" {
69void HALSIM_WaitForProgramStart(void) {
70 int count = 0;
71 while (!programStarted) {
72 count++;
73 std::printf("Waiting for program start signal: %d\n", count);
74 std::this_thread::sleep_for(std::chrono::milliseconds(500));
75 }
76}
77
78void HALSIM_SetProgramStarted(void) { SetProgramStarted(); }
79
80HAL_Bool HALSIM_GetProgramStarted(void) { return GetProgramStarted(); }
81
82void HALSIM_RestartTiming(void) { RestartTiming(); }
83
84void HALSIM_PauseTiming(void) {
85 PauseTiming();
86 PauseNotifiers();
87}
88
89void HALSIM_ResumeTiming(void) {
90 ResumeTiming();
91 ResumeNotifiers();
92}
93
94HAL_Bool HALSIM_IsTimingPaused(void) { return IsTimingPaused(); }
95
96void HALSIM_StepTiming(uint64_t delta) {
Austin Schuh1e69f942020-11-14 15:06:14 -080097 WaitNotifiers();
98
99 while (delta > 0) {
100 int32_t status = 0;
101 uint64_t curTime = HAL_GetFPGATime(&status);
102 uint64_t nextTimeout = HALSIM_GetNextNotifierTimeout();
103 uint64_t step = std::min(delta, nextTimeout - curTime);
104
105 StepTiming(step);
106 delta -= step;
107
108 WakeupWaitNotifiers();
109 }
110}
111
112void HALSIM_StepTimingAsync(uint64_t delta) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800113 StepTiming(delta);
114 WakeupNotifiers();
115}
116} // extern "C"