Skip to content
Snippets Groups Projects
Commit b0b5c729 authored by Fabiano Riccardi's avatar Fabiano Riccardi Committed by Federico
Browse files

Improvement in Timers interfaces, the bug of overflow rounding in the timer is still there

parent 7d622095
Branches
No related tags found
2 merge requests!40Update to Miosix 2.7,!17Draft: Improved miosix build system and fixed cmake scripts
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
*/ */
#include "gpio_timer.h" #include "gpio_timer.h"
#include "high_resolution_timer_base.h"
#include "hwmapping.h" #include "hwmapping.h"
#include "miosix.h" #include "miosix.h"
#include <cstdlib> #include <cstdlib>
...@@ -19,13 +18,34 @@ GPIOtimer& GPIOtimer::instance(){ ...@@ -19,13 +18,34 @@ GPIOtimer& GPIOtimer::instance(){
return instance; return instance;
} }
GPIOtimer::GPIOtimer(): b(HighResolutionTimerBase::instance()) { GPIOtimer::GPIOtimer(): b(HighResolutionTimerBase::instance()),tc(b.getTimerFrequency()) {
setPinMode(false); setPinMode(false);
isInput=true; isInput=true;
} }
Thread* GPIOtimer::tWaitingGPIO=nullptr; Thread* GPIOtimer::tWaitingGPIO=nullptr;
long long GPIOtimer::getValue() const{
return b.getCurrentTick();
}
unsigned int GPIOtimer::getTickFrequency() const{
return b.getTimerFrequency();
}
void GPIOtimer::wait(long long tick){
Thread::nanoSleep(tc.tick2ns(tick));
}
bool GPIOtimer::absoluteWait(long long tick){
if(b.getCurrentTick()>=tick){
return true;
}
Thread::nanoSleepUntil(tc.tick2ns(tick));
return false;
}
void GPIOtimer::setPinMode(bool inputMode){ void GPIOtimer::setPinMode(bool inputMode){
if(inputMode){ if(inputMode){
expansion::gpio10::mode(Mode::INPUT); expansion::gpio10::mode(Mode::INPUT);
...@@ -44,17 +64,16 @@ long long GPIOtimer::getExtEventTimestamp() const{ ...@@ -44,17 +64,16 @@ long long GPIOtimer::getExtEventTimestamp() const{
return b.IRQgetSetTimeCCV2(); return b.IRQgetSetTimeCCV2();
} }
WaitResult GPIOtimer::absoluteWaitTimeoutOrEvent(long long tick){ bool GPIOtimer::absoluteWaitTimeoutOrEvent(long long tick){
FastInterruptDisableLock dLock; FastInterruptDisableLock dLock;
if(tick<b.getCurrentTick()){ if(tick<b.getCurrentTick()){
return WaitResult::WAKEUP_IN_THE_PAST; return true;
} }
b.setModeGPIOTimer(true); b.setModeGPIOTimer(true);
setPinMode(true); setPinMode(true);
b.setCCInterrupt2(false); b.setCCInterrupt2(false);
b.setCCInterrupt2Tim1(true); b.setCCInterrupt2Tim1(true);
long long ctick=0;
do { do {
tWaitingGPIO=Thread::IRQgetCurrentThread(); tWaitingGPIO=Thread::IRQgetCurrentThread();
Thread::IRQwait(); Thread::IRQwait();
...@@ -62,17 +81,16 @@ WaitResult GPIOtimer::absoluteWaitTimeoutOrEvent(long long tick){ ...@@ -62,17 +81,16 @@ WaitResult GPIOtimer::absoluteWaitTimeoutOrEvent(long long tick){
FastInterruptEnableLock eLock(dLock); FastInterruptEnableLock eLock(dLock);
Thread::yield(); Thread::yield();
} }
ctick = b.getCurrentTick(); } while(tWaitingGPIO && tick>b.getCurrentTick());
} while(tWaitingGPIO && tick>ctick);
if(tWaitingGPIO==nullptr){ if(tWaitingGPIO==nullptr){
return WaitResult::EVENT; return false;
}else{ }else{
return WaitResult::WAIT_COMPLETED; return true;
} }
} }
WaitResult GPIOtimer::waitTimeoutOrEvent(long long tick){ bool GPIOtimer::waitTimeoutOrEvent(long long tick){
return absoluteWaitTimeoutOrEvent(b.getCurrentTick()+tick); return absoluteWaitTimeoutOrEvent(b.getCurrentTick()+tick);
} }
...@@ -83,11 +101,11 @@ bool GPIOtimer::absoluteWaitTrigger(long long tick){ ...@@ -83,11 +101,11 @@ bool GPIOtimer::absoluteWaitTrigger(long long tick){
FastInterruptDisableLock dLock; FastInterruptDisableLock dLock;
b.setModeGPIOTimer(false); //output timer b.setModeGPIOTimer(false); //output timer
setPinMode(false); //output pin setPinMode(false); //output pin
if(!b.IRQsetNextInterrupt2(tick)){ if(b.IRQsetNextInterrupt2(tick)==WaitResult::WAKEUP_IN_THE_PAST){
return false;
}
return true; return true;
} }
return false;
}
bool GPIOtimer::waitTrigger(long long tick){ bool GPIOtimer::waitTrigger(long long tick){
return absoluteWaitTrigger(b.getCurrentTick()+tick); return absoluteWaitTrigger(b.getCurrentTick()+tick);
...@@ -98,8 +116,8 @@ bool GPIOtimer::absoluteSyncWaitTrigger(long long tick){ ...@@ -98,8 +116,8 @@ bool GPIOtimer::absoluteSyncWaitTrigger(long long tick){
FastInterruptDisableLock dLock; FastInterruptDisableLock dLock;
b.setModeGPIOTimer(false); //output timer b.setModeGPIOTimer(false); //output timer
setPinMode(false); //output pin setPinMode(false); //output pin
if(!b.IRQsetNextInterrupt2(tick)){ if(b.IRQsetNextInterrupt2(tick)==WaitResult::WAKEUP_IN_THE_PAST){
return false; return true;
} }
do { do {
...@@ -111,13 +129,21 @@ bool GPIOtimer::absoluteSyncWaitTrigger(long long tick){ ...@@ -111,13 +129,21 @@ bool GPIOtimer::absoluteSyncWaitTrigger(long long tick){
} }
} while(tWaitingGPIO && tick>b.getCurrentTick()); } while(tWaitingGPIO && tick>b.getCurrentTick());
} }
return true; return false;
} }
bool GPIOtimer::syncWaitTrigger(long long tick){ bool GPIOtimer::syncWaitTrigger(long long tick){
return absoluteSyncWaitTrigger(b.getCurrentTick()+tick); return absoluteSyncWaitTrigger(b.getCurrentTick()+tick);
} }
long long GPIOtimer::tick2ns(long long tick){
return tc.tick2ns(tick);
}
long long GPIOtimer::ns2tick(long long ns){
return tc.ns2tick(ns);
}
long long GPIOtimer::aux1=0; long long GPIOtimer::aux1=0;
GPIOtimer::~GPIOtimer() {} GPIOtimer::~GPIOtimer() {}
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "high_resolution_timer_base.h" #include "high_resolution_timer_base.h"
#include "hwmapping.h" #include "hwmapping.h"
#include "timer.h"
#ifndef GPIO_TIMER_H #ifndef GPIO_TIMER_H
#define GPIO_TIMER_H #define GPIO_TIMER_H
...@@ -20,21 +21,21 @@ ...@@ -20,21 +21,21 @@
static volatile int aux=0; static volatile int aux=0;
namespace miosix { namespace miosix {
enum class WaitResult
{
WAKEUP_IN_THE_PAST,
WAIT_COMPLETED,
EVENT
};
class GPIOtimer{ class GPIOtimer : public TimerInterface{
public: public:
static Thread *tWaitingGPIO; static Thread *tWaitingGPIO;
static long long aux1; static long long aux1;
long long getValue() const;
void wait(long long value);
bool absoluteWait(long long value);
static GPIOtimer& instance(); static GPIOtimer& instance();
virtual ~GPIOtimer(); virtual ~GPIOtimer();
WaitResult waitTimeoutOrEvent(long long value); bool waitTimeoutOrEvent(long long value);
WaitResult absoluteWaitTimeoutOrEvent(long long value); bool absoluteWaitTimeoutOrEvent(long long value);
/** /**
* Set the timer interrupt to occur at an absolute value and put the * Set the timer interrupt to occur at an absolute value and put the
...@@ -54,10 +55,13 @@ namespace miosix { ...@@ -54,10 +55,13 @@ namespace miosix {
bool absoluteSyncWaitTrigger(long long tick); bool absoluteSyncWaitTrigger(long long tick);
bool syncWaitTrigger(long long tick); bool syncWaitTrigger(long long tick);
unsigned int getTickFrequency() const;
long long getExtEventTimestamp() const; long long getExtEventTimestamp() const;
long long tick2ns(long long tick);
long long ns2tick(long long ns);
bool getMode(); bool getMode();
private: private:
...@@ -65,6 +69,7 @@ namespace miosix { ...@@ -65,6 +69,7 @@ namespace miosix {
void setPinMode(bool inputMode); void setPinMode(bool inputMode);
HighResolutionTimerBase& b; HighResolutionTimerBase& b;
bool isInput; bool isInput;
TimeConversion tc;
}; };
} }
......
...@@ -28,7 +28,6 @@ const unsigned long long upperMask=0xFFFFFFFFFFFFFFFFLL-lowerMask; ...@@ -28,7 +28,6 @@ const unsigned long long upperMask=0xFFFFFFFFFFFFFFFFLL-lowerMask;
static long long ms32time = 0; //most significant 32 bits of counter static long long ms32time = 0; //most significant 32 bits of counter
static long long ms32chkp[3] = {0,0,0}; //most significant 32 bits of check point static long long ms32chkp[3] = {0,0,0}; //most significant 32 bits of check point
static bool lateIrq=false;
static TimeConversion* tc; static TimeConversion* tc;
static inline unsigned int IRQread32Timer(){ static inline unsigned int IRQread32Timer(){
...@@ -72,7 +71,7 @@ inline void interruptGPIOTimerRoutine(){ ...@@ -72,7 +71,7 @@ inline void interruptGPIOTimerRoutine(){
} }
static inline void callScheduler(){ static __attribute__((noinline)) void callScheduler(){
TIMER1->IEN &= ~TIMER_IEN_CC1; TIMER1->IEN &= ~TIMER_IEN_CC1;
TIMER3->IEN &= ~TIMER_IEN_CC1; TIMER3->IEN &= ~TIMER_IEN_CC1;
TIMER1->IFC = TIMER_IFC_CC1; TIMER1->IFC = TIMER_IFC_CC1;
...@@ -81,13 +80,14 @@ static inline void callScheduler(){ ...@@ -81,13 +80,14 @@ static inline void callScheduler(){
IRQtimerInterrupt(tick); IRQtimerInterrupt(tick);
} }
static inline void setupTimers(){ static void setupTimers(){
// We assume that this function is called only when the checkpoint is in future // We assume that this function is called only when the checkpoint is in future
if (ms32chkp[1] == ms32time){ if (ms32chkp[1] == ms32time){
// If the most significant 32bit matches, enable TIM3 // If the most significant 32bit matches, enable TIM3
TIMER3->IFC = TIMER_IFC_CC1; TIMER3->IFC = TIMER_IFC_CC1;
TIMER3->IEN |= TIMER_IEN_CC1; TIMER3->IEN |= TIMER_IEN_CC1;
if (static_cast<unsigned short>(TIMER3->CNT) >= static_cast<unsigned short>(TIMER3->CC[1].CCV) + 1){ unsigned short temp=static_cast<unsigned short>(TIMER3->CC[1].CCV) + 1;
if (static_cast<unsigned short>(TIMER3->CNT) >= temp){
// If TIM3 matches by the time it is being enabled, disable it right away // If TIM3 matches by the time it is being enabled, disable it right away
TIMER3->IFC = TIMER_IFC_CC1; TIMER3->IFC = TIMER_IFC_CC1;
TIMER3->IEN &= ~TIMER_IEN_CC1; TIMER3->IEN &= ~TIMER_IEN_CC1;
...@@ -103,7 +103,10 @@ static inline void setupTimers(){ ...@@ -103,7 +103,10 @@ static inline void setupTimers(){
// If the most significant 32bit aren't match wait for TIM3 to overflow! // If the most significant 32bit aren't match wait for TIM3 to overflow!
} }
static inline bool setupTimers2(){ /*
Return EVENT if the timer triggers in this routine, otherwise the timer is set and returns WAITING
*/
static WaitResult setupTimers2(){
// We assume that this function is called only when the checkpoint is in future // We assume that this function is called only when the checkpoint is in future
if (ms32chkp[2] == ms32time){ if (ms32chkp[2] == ms32time){
// If the most significant 32bit matches, enable TIM3 // If the most significant 32bit matches, enable TIM3
...@@ -123,11 +126,11 @@ static inline bool setupTimers2(){ ...@@ -123,11 +126,11 @@ static inline bool setupTimers2(){
TIMER1->CC[2].CCV = static_cast<unsigned int>(10+TIMER1->CNT); TIMER1->CC[2].CCV = static_cast<unsigned int>(10+TIMER1->CNT);
// If TIM1 matches by the time it is being enabled, call the scheduler right away // If TIM1 matches by the time it is being enabled, call the scheduler right away
interruptGPIOTimerRoutine(); interruptGPIOTimerRoutine();
return false; return WaitResult::EVENT;
} }
} }
} }
return true; return WaitResult::WAITING;
// If the most significant 32bit aren't match wait for TIM3 to overflow! // If the most significant 32bit aren't match wait for TIM3 to overflow!
} }
...@@ -158,7 +161,8 @@ void __attribute__((used)) cstirqhnd3(){ ...@@ -158,7 +161,8 @@ void __attribute__((used)) cstirqhnd3(){
//Checkpoint //Checkpoint
if ((TIMER3->IEN & TIMER_IEN_CC1) && (TIMER3->IF & TIMER_IF_CC1)){ if ((TIMER3->IEN & TIMER_IEN_CC1) && (TIMER3->IF & TIMER_IF_CC1)){
TIMER3->IFC = TIMER_IFC_CC1; TIMER3->IFC = TIMER_IFC_CC1;
if (static_cast<unsigned short>(TIMER3->CNT) >= static_cast<unsigned short>(TIMER3->CC[1].CCV) + 1){ unsigned short temp=static_cast<unsigned short>(TIMER3->CC[1].CCV) + 1;
if (static_cast<unsigned short>(TIMER3->CNT) >= temp){
// Should happen if and only if most significant 32 bits have been matched // Should happen if and only if most significant 32 bits have been matched
TIMER3->IEN &= ~ TIMER_IEN_CC1; TIMER3->IEN &= ~ TIMER_IEN_CC1;
// Enable TIM1 since TIM3 has been already matched // Enable TIM1 since TIM3 has been already matched
...@@ -211,13 +215,13 @@ HighResolutionTimerBase& HighResolutionTimerBase::instance(){ ...@@ -211,13 +215,13 @@ HighResolutionTimerBase& HighResolutionTimerBase::instance(){
return hrtb; return hrtb;
} }
inline long long HighResolutionTimerBase::IRQgetSetTimeCCV0(){ long long HighResolutionTimerBase::IRQgetSetTimeCCV0() const{
return ms32chkp[0] | TIMER3->CC[0].CCV<<16 | TIMER1->CC[0].CCV; return ms32chkp[0] | TIMER3->CC[0].CCV<<16 | TIMER1->CC[0].CCV;
} }
inline long long HighResolutionTimerBase::IRQgetSetTimeCCV1(){ long long HighResolutionTimerBase::IRQgetSetTimeCCV1() const{
return ms32chkp[1] | TIMER3->CC[1].CCV<<16 | TIMER1->CC[1].CCV; return ms32chkp[1] | TIMER3->CC[1].CCV<<16 | TIMER1->CC[1].CCV;
} }
inline long long HighResolutionTimerBase::IRQgetSetTimeCCV2(){ long long HighResolutionTimerBase::IRQgetSetTimeCCV2() const{
return ms32chkp[2] | TIMER3->CC[2].CCV<<16 | TIMER1->CC[2].CCV; return ms32chkp[2] | TIMER3->CC[2].CCV<<16 | TIMER1->CC[2].CCV;
} }
...@@ -352,7 +356,7 @@ void HighResolutionTimerBase::IRQsetNextInterrupt1(long long tick){ ...@@ -352,7 +356,7 @@ void HighResolutionTimerBase::IRQsetNextInterrupt1(long long tick){
/* /*
Return true if the pin is going to raise, otherwise false, the pin remain low because the command arrived too late Return true if the pin is going to raise, otherwise false, the pin remain low because the command arrived too late
*/ */
bool HighResolutionTimerBase::IRQsetNextInterrupt2(long long tick){ WaitResult HighResolutionTimerBase::IRQsetNextInterrupt2(long long tick){
TIMER1->IEN &= ~TIMER_IEN_CC2; TIMER1->IEN &= ~TIMER_IEN_CC2;
TIMER3->IEN &= ~TIMER_IEN_CC2; TIMER3->IEN &= ~TIMER_IEN_CC2;
...@@ -360,7 +364,7 @@ bool HighResolutionTimerBase::IRQsetNextInterrupt2(long long tick){ ...@@ -360,7 +364,7 @@ bool HighResolutionTimerBase::IRQsetNextInterrupt2(long long tick){
if(curTick >= tick){ if(curTick >= tick){
// The interrupt is in the past => call timerInt immediately // The interrupt is in the past => call timerInt immediately
interruptGPIOTimerRoutine(); //TODO: It could cause multiple invocations of sched. interruptGPIOTimerRoutine(); //TODO: It could cause multiple invocations of sched.
return false; return WaitResult::WAKEUP_IN_THE_PAST;
}else{ }else{
ms32chkp[2] = tick & upperMask; ms32chkp[2] = tick & upperMask;
TIMER3->CC[2].CCV = static_cast<unsigned int>((tick & 0xFFFF0000)>>16)-1; TIMER3->CC[2].CCV = static_cast<unsigned int>((tick & 0xFFFF0000)>>16)-1;
......
...@@ -18,6 +18,14 @@ ...@@ -18,6 +18,14 @@
namespace miosix { namespace miosix {
enum class WaitResult
{
WAKEUP_IN_THE_PAST,
WAIT_COMPLETED,
EVENT,
WAITING
};
class HighResolutionTimerBase { class HighResolutionTimerBase {
public: public:
...@@ -26,8 +34,7 @@ public: ...@@ -26,8 +34,7 @@ public:
/** /**
* \return the timer frequency in Hz * \return the timer frequency in Hz
*/ */
unsigned int getTimerFrequency() const unsigned int getTimerFrequency() const{
{
return timerFreq; return timerFreq;
} }
...@@ -38,15 +45,15 @@ public: ...@@ -38,15 +45,15 @@ public:
*/ */
bool IRQsetNextInterrupt0(long long tick); bool IRQsetNextInterrupt0(long long tick);
void IRQsetNextInterrupt1(long long tick); void IRQsetNextInterrupt1(long long tick);
bool IRQsetNextInterrupt2(long long tick); WaitResult IRQsetNextInterrupt2(long long tick);
/** /**
* \return the time when the next interrupt will be fired. * \return the time when the next interrupt will be fired.
* That is, the last value passed to setNextInterrupt(). * That is, the last value passed to setNextInterrupt().
*/ */
long long IRQgetSetTimeCCV0(); long long IRQgetSetTimeCCV0() const;
long long IRQgetSetTimeCCV1(); long long IRQgetSetTimeCCV1() const;
long long IRQgetSetTimeCCV2(); long long IRQgetSetTimeCCV2() const;
/** /**
* Could be call both when the interrupts are enabled/disabled! * Could be call both when the interrupts are enabled/disabled!
* TODO: investigate if it's possible to remove the possibility to call * TODO: investigate if it's possible to remove the possibility to call
......
...@@ -15,9 +15,53 @@ ...@@ -15,9 +15,53 @@
using namespace miosix; using namespace miosix;
Thread* RadioTimer::tWaitingGPIO=nullptr; Thread* RadioTimer::tWaitingRadio=nullptr;
RadioTimer::RadioTimer():b(HighResolutionTimerBase::instance()) {} long long RadioTimer::getValue() const{
return b.getCurrentTick();
}
void RadioTimer::wait(long long tick){
Thread::nanoSleep(tc.tick2ns(tick));
}
bool RadioTimer::absoluteWait(long long tick){
if(b.getCurrentTick()>=tick){
return true;
}
Thread::nanoSleepUntil(tc.tick2ns(tick));
return false;
}
bool RadioTimer::absoluteWaitTrigger(long long tick){
return 0;
}
bool RadioTimer::waitTimeoutOrEvent(long long tick){
return 0;
}
bool RadioTimer::absoluteWaitTimeoutOrEvent(long long tick){
return 0;
}
long long RadioTimer::tick2ns(long long tick){
return tc.tick2ns(tick);
}
long long RadioTimer::ns2tick(long long ns){
return tc.ns2tick(ns);
}
unsigned int RadioTimer::getTickFrequency() const{
return b.getTimerFrequency();
}
long long RadioTimer::getExtEventTimestamp() const{
return b.IRQgetSetTimeCCV0();
}
RadioTimer::RadioTimer():b(HighResolutionTimerBase::instance()),tc(b.getTimerFrequency()) {}
RadioTimer& RadioTimer::instance(){ RadioTimer& RadioTimer::instance(){
static RadioTimer instance; static RadioTimer instance;
......
...@@ -12,20 +12,43 @@ ...@@ -12,20 +12,43 @@
*/ */
#include "high_resolution_timer_base.h" #include "high_resolution_timer_base.h"
#include "timer.h"
#ifndef RADIO_TIMER_H #ifndef RADIO_TIMER_H
#define RADIO_TIMER_H #define RADIO_TIMER_H
namespace miosix{ namespace miosix{
class RadioTimer { class RadioTimer : public TimerInterface {
public: public:
static Thread *tWaitingGPIO; //transceiver::excChB //usato per la ricezione INPUT_CAPTURE
//transceiver::stxon //usato per attivare la trasmissione OUTPUTCOMPARE
static Thread *tWaitingRadio;
static RadioTimer& instance(); static RadioTimer& instance();
virtual ~RadioTimer(); virtual ~RadioTimer();
long long getValue() const;
void wait(long long tick);
bool absoluteWait(long long tick);
bool absoluteWaitTrigger(long long tick);
bool waitTimeoutOrEvent(long long tick);
bool absoluteWaitTimeoutOrEvent(long long tick);
long long tick2ns(long long tick);
long long ns2tick(long long ns);
unsigned int getTickFrequency() const;
long long getExtEventTimestamp() const;
private: private:
RadioTimer(); RadioTimer();
HighResolutionTimerBase& b; HighResolutionTimerBase& b;
TimeConversion tc;
}; };
} }
......
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: timer.h
* Author: fabiuz
*
* Created on October 17, 2016, 10:27 AM
*/
#ifndef TIMER_H
#define TIMER_H
#include <kernel/timeconversion.h>
namespace miosix {
/**
* Pure virtual class defining the HardwareTimer interface.
* This interface includes support for an input capture module, used by the
* Transceiver driver to timestamp packet reception, and an output compare
* module, used again by the Transceiver to send packets deterministically.
*/
class TimerInterface{
public:
/**
* \return the timer counter value in ticks
*/
virtual long long getValue() const=0;
/**
* Put thread in wait for the specified relative time.
* This function wait for a relative time passed as parameter.
* \param value relative time to wait, expressed in ticks
*/
virtual void wait(long long value)=0;
/**
* Puts the thread in wait for the specified absolute time.
* \param value absolute wait time in ticks
* If value of absolute time is in the past no waiting will be set
* and function return immediately.
* \return true if the wait time was in the past
*/
virtual bool absoluteWait(long long value)=0;
/**
* Set the timer interrupt to occur at an absolute value and put the
* thread in wait of this.
* When the timer interrupt will occur, the associated GPIO passes
* from a low logic level to a high logic level for few us.
* \param value absolute value when the interrupt will occur, expressed in
* ticks
* If value of absolute time is in the past no waiting will be set
* and function return immediately. In this case, the GPIO will not be
* pulsed
* \return true if the wait time was in the past, in this case the GPIO
* has not been pulsed
*/
virtual bool absoluteWaitTrigger(long long value)=0;
/**
* Put thread in waiting of timeout or extern event.
* \param value timeout expressed in ticks
* \return true in case of timeout
*/
virtual bool waitTimeoutOrEvent(long long value)=0;
/**
* Put thread in waiting of timeout or extern event.
* \param value absolute timeout expressed in ticks
* If value of absolute time is in the past no waiting will be set
* and function return immediately.
* \return true in case of timeout, or if the wait time is in the past.
* In the corner case where both the timeout and the event are in the past,
* return false.
*/
virtual bool absoluteWaitTimeoutOrEvent(long long value)=0;
/**
* \return the precise time in ticks when the IRQ signal of the event was
* asserted
*/
virtual long long getExtEventTimestamp() const=0;
/**
* Althought the interface to the timer is in ticks to be able to do
* computations that are exact and use the timer resolution fully,
* these member functions are provided to convert to nanoseconds
*
* \param tick time point in timer ticks
* \return the equivalent time point in the nanosecond timescale
*/
virtual long long tick2ns(long long tick)=0;
/**
* Althought the interface to the timer is in ticks to be able to do
* computations that are exact and use the timer resolution fully,
* these member functions are provided to convert to nanoseconds
*
* \param ns time point in nanoseconds
* \return the equivalent time point in the timer tick timescale
*/
virtual long long ns2tick(long long ns)=0;
/**
* \return the timer frequency in Hz
*/
virtual unsigned int getTickFrequency() const=0;
};
}
#endif /* TIMER_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment