diff --git a/fpga/include/villas/fpga/ips/timer.hpp b/fpga/include/villas/fpga/ips/timer.hpp index 49354052d..771d2723b 100644 --- a/fpga/include/villas/fpga/ips/timer.hpp +++ b/fpga/include/villas/fpga/ips/timer.hpp @@ -29,9 +29,13 @@ #pragma once -#include "fpga/ip.hpp" +#include #include +#include "config.h" +#include "fpga/ip.hpp" +#include "fpga/ips/intc.hpp" + namespace villas { namespace fpga { namespace ip { @@ -42,8 +46,24 @@ class Timer : public IpCore public: bool init(); + + bool start(uint32_t ticks); + bool wait(); + uint32_t remaining(); + + inline bool isRunning() + { return remaining() != 0; } + + inline bool isFinished() + { return remaining() == 0; } + + static constexpr uint32_t + getFrequency() + { return FPGA_AXI_HZ; } + private: XTmrCtr xTmr; + InterruptController* intc; }; diff --git a/fpga/lib/ips/timer.cpp b/fpga/lib/ips/timer.cpp index fbd0219fd..5e0c56e4c 100644 --- a/fpga/lib/ips/timer.cpp +++ b/fpga/lib/ips/timer.cpp @@ -23,11 +23,11 @@ * along with this program. If not, see . *********************************************************************************/ - -#include "config.h" +#include #include "log.hpp" #include "fpga/ips/timer.hpp" +#include "fpga/ips/intc.hpp" namespace villas { namespace fpga { @@ -40,14 +40,41 @@ static TimerFactory factory; bool Timer::init() { XTmrCtr_Config xtmr_cfg; - xtmr_cfg.SysClockFreqHz = FPGA_AXI_HZ; + xtmr_cfg.SysClockFreqHz = getFrequency(); XTmrCtr_CfgInitialize(&xTmr, &xtmr_cfg, getBaseaddr()); XTmrCtr_InitHw(&xTmr); + intc = reinterpret_cast(dependencies["intc"]); + intc->disableInterrupt(irqs[0]); + return true; } +bool Timer::start(uint32_t ticks) +{ + intc->enableInterrupt(irqs[0], false); + + XTmrCtr_SetOptions(&xTmr, 0, XTC_EXT_COMPARE_OPTION | XTC_DOWN_COUNT_OPTION); + XTmrCtr_SetResetValue(&xTmr, 0, ticks); + XTmrCtr_Start(&xTmr, 0); + + return true; +} + +bool Timer::wait() +{ + int count = intc->waitForInterrupt(irqs[0]); + intc->disableInterrupt(irqs[0]); + + return (count == 1); +} + +uint32_t Timer::remaining() +{ + return XTmrCtr_GetValue(&xTmr, 0); +} + } // namespace ip } // namespace fpga