From 5c6dc23a28be0d7c2b3d45037deeee184ff5e71d Mon Sep 17 00:00:00 2001 From: Fabiano Riccardi <fabiuz4@hotmail.it> Date: Tue, 25 Oct 2016 18:24:43 +0200 Subject: [PATCH] Discovered and solved a couple of bugs in GPIOtimer, refactoring of same inconsistent function names, started to write the code for ping-pong test for GPIOtimer Signed-off-by: Fabiano Riccardi <fabiuz4@hotmail.it> --- .../interfaces-impl/cstimer.cpp | 4 +- .../interfaces-impl/gpio_timer.cpp | 19 +++++---- .../interfaces-impl/gpio_timer.h | 2 - .../high_resolution_timer_base.cpp | 40 ++++++++++++++----- .../high_resolution_timer_base.h | 17 +++++--- .../interfaces-impl/radio_timer.cpp | 10 ++--- 6 files changed, 59 insertions(+), 33 deletions(-) diff --git a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/cstimer.cpp b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/cstimer.cpp index e4fbff90..690ee254 100644 --- a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/cstimer.cpp +++ b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/cstimer.cpp @@ -23,11 +23,11 @@ namespace miosix { } long long ContextSwitchTimer::getCurrentTime() const{ - return tc->tick2ns(pImpl->b.getCurrentTime()); + return tc->tick2ns(pImpl->b.getCurrentTick()); } long long ContextSwitchTimer::IRQgetCurrentTime() const{ - return tc->tick2ns(pImpl->b.IRQgetCurrentTime()); + return tc->tick2ns(pImpl->b.IRQgetCurrentTick()); } ContextSwitchTimer::~ContextSwitchTimer(){} diff --git a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/gpio_timer.cpp b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/gpio_timer.cpp index 35f28731..3ce195c6 100644 --- a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/gpio_timer.cpp +++ b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/gpio_timer.cpp @@ -17,7 +17,7 @@ using namespace miosix; Thread* GPIOtimer::tWaitingGPIO=nullptr; long long GPIOtimer::getValue() const{ - return b.getCurrentTime(); + return b.getCurrentTick(); } unsigned int GPIOtimer::getTickFrequency() const{ @@ -29,7 +29,7 @@ void GPIOtimer::wait(long long tick){ } bool GPIOtimer::absoluteWait(long long tick){ - if(b.getCurrentTime()>=tick){ + if(b.getCurrentTick()>=tick){ return true; } Thread::nanoSleepUntil(tc.tick2ns(tick)); @@ -47,7 +47,7 @@ long long GPIOtimer::getExtEventTimestamp() const{ bool GPIOtimer::absoluteWaitTimeoutOrEvent(long long tick){ FastInterruptDisableLock dLock; - if(tick<b.getCurrentTime()){ + if(tick<b.getCurrentTick()){ return true; } if(!isInput){ @@ -55,6 +55,7 @@ bool GPIOtimer::absoluteWaitTimeoutOrEvent(long long tick){ expansion::gpio10::mode(Mode::INPUT); isInput=true; } + b.cleanBufferGPIO(); b.setCCInterrupt2(false); b.setCCInterrupt2Tim1(true); @@ -65,7 +66,7 @@ bool GPIOtimer::absoluteWaitTimeoutOrEvent(long long tick){ FastInterruptEnableLock eLock(dLock); Thread::yield(); } - } while(tWaitingGPIO && tick>b.getCurrentTime()); + } while(tWaitingGPIO && tick>b.getCurrentTick()); if(tWaitingGPIO==nullptr){ return false; @@ -75,7 +76,7 @@ bool GPIOtimer::absoluteWaitTimeoutOrEvent(long long tick){ } bool GPIOtimer::waitTimeoutOrEvent(long long tick){ - return absoluteWaitTimeoutOrEvent(b.getCurrentTime()+tick); + return absoluteWaitTimeoutOrEvent(b.getCurrentTick()+tick); } /* @@ -86,6 +87,7 @@ bool GPIOtimer::absoluteWaitTrigger(long long tick){ if(isInput){ b.setModeGPIOTimer(false); //output timer expansion::gpio10::mode(Mode::OUTPUT); //output pin + expansion::gpio10::low(); isInput=false; } if(b.IRQsetNextGPIOInterrupt(tick)==WaitResult::WAKEUP_IN_THE_PAST){ @@ -95,7 +97,7 @@ bool GPIOtimer::absoluteWaitTrigger(long long tick){ } bool GPIOtimer::waitTrigger(long long tick){ - return absoluteWaitTrigger(b.getCurrentTime()+tick); + return absoluteWaitTrigger(b.getCurrentTick()+tick); } /* @@ -108,6 +110,7 @@ bool GPIOtimer::absoluteSyncWaitTrigger(long long tick){ if(isInput){ b.setModeGPIOTimer(false); //output timer expansion::gpio10::mode(Mode::OUTPUT); //output pin + expansion::gpio10::low(); isInput=false; } if(b.IRQsetNextGPIOInterrupt(tick)==WaitResult::WAKEUP_IN_THE_PAST){ @@ -121,13 +124,13 @@ bool GPIOtimer::absoluteSyncWaitTrigger(long long tick){ FastInterruptEnableLock eLock(dLock); Thread::yield(); } - } while(tWaitingGPIO && tick>b.getCurrentTime()); + } while(tWaitingGPIO && tick>b.getCurrentTick()); } return false; } bool GPIOtimer::syncWaitTrigger(long long tick){ - return absoluteSyncWaitTrigger(b.getCurrentTime()+tick); + return absoluteSyncWaitTrigger(b.getCurrentTick()+tick); } long long GPIOtimer::tick2ns(long long tick){ diff --git a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/gpio_timer.h b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/gpio_timer.h index 289434b2..105c44ec 100644 --- a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/gpio_timer.h +++ b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/gpio_timer.h @@ -18,8 +18,6 @@ #ifndef GPIO_TIMER_H #define GPIO_TIMER_H -static volatile int aux=0; - namespace miosix { class GPIOtimer : public HardwareTimer{ diff --git a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/high_resolution_timer_base.cpp b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/high_resolution_timer_base.cpp index 1aaf6bb9..1e0302c3 100644 --- a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/high_resolution_timer_base.cpp +++ b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/high_resolution_timer_base.cpp @@ -55,11 +55,24 @@ static inline long long IRQgetTick(){ return ms32time | static_cast<long long>(counter); } +void falseRead(volatile uint32_t *p){ + *p; +} + inline void interruptGPIOTimerRoutine(){ if(TIMER1->CC[2].CTRL & TIMER_CC_CTRL_MODE_OUTPUTCOMPARE){ TIMER1->CC[2].CTRL = (TIMER1->CC[2].CTRL & ~_TIMER_CC_CTRL_CMOA_MASK) | TIMER_CC_CTRL_CMOA_CLEAR; //10 tick are enough to execute this line TIMER1->CC[2].CCV = static_cast<unsigned short>(TIMER1->CNT+10);//static_cast<unsigned int>(tick & 0xFFFF); + }else if(TIMER1->CC[2].CTRL & TIMER_CC_CTRL_MODE_INPUTCAPTURE){ + ms32chkp[2]=ms32time; + HighResolutionTimerBase& b=HighResolutionTimerBase::instance(); + //really in the past, the overflow of TIMER3 is occurred but the timer wasn't updated + long long a=b.IRQgetSetTimeCCV2(); + long long c=b.getCurrentTick(); + if(a-c< -48000000){ + ms32chkp[2]+=overflowIncrement; + } } //Reactivating the thread that is waiting for the event. if(GPIOtimer::tWaitingGPIO){ @@ -165,6 +178,7 @@ void __attribute__((used)) cstirqhnd3(){ } } + void __attribute__((used)) cstirqhnd2(){ //CC0 listening for received packet if ((TIMER2->IEN & TIMER_IEN_CC0) && (TIMER2->IF & TIMER_IF_CC0) ){ @@ -172,7 +186,7 @@ void __attribute__((used)) cstirqhnd2(){ TIMER2->IFC = TIMER_IFC_CC0; interruptRadioTimerRoutine(); } - //CC1 for output/trigger + //CC1 for output/trigger the sending packet event if ((TIMER2->IEN & TIMER_IEN_CC1) && (TIMER2->IF & TIMER_IF_CC1) ){ TIMER2->IEN &= ~ TIMER_IEN_CC1; TIMER2->IFC = TIMER_IFC_CC1; @@ -198,7 +212,7 @@ void __attribute__((used)) cstirqhnd1(){ //get nextInterrupt long long t=ms32chkp[2]|TIMER1->CC[2].CCV; - long long diff=t-b.IRQgetCurrentTime(); + long long diff=t-b.IRQgetCurrentTick(); if(diff<=0xFFFF){ TIMER1->CC[2].CTRL = (TIMER1->CC[2].CTRL & ~_TIMER_CC_CTRL_CMOA_MASK) | TIMER_CC_CTRL_CMOA_SET; faseGPIO=1; @@ -220,7 +234,7 @@ long long HighResolutionTimerBase::IRQgetSetTimeCCV2() const{ return ms32chkp[2] | TIMER3->CC[2].CCV<<16 | TIMER1->CC[2].CCV; } -long long HighResolutionTimerBase::IRQgetCurrentTime(){ +long long HighResolutionTimerBase::IRQgetCurrentTick(){ return IRQgetTick(); } @@ -245,9 +259,10 @@ void HighResolutionTimerBase::setCCInterrupt2(bool enable){ } void HighResolutionTimerBase::setCCInterrupt2Tim1(bool enable){ - if(enable) + if(enable){ + TIMER1->IFC= TIMER_IF_CC2; TIMER1->IEN|=TIMER_IEN_CC2; - else + }else TIMER1->IEN&=~TIMER_IEN_CC2; } @@ -258,13 +273,13 @@ void HighResolutionTimerBase::setCCInterrupt0Tim2(bool enable){ TIMER2->IEN&=~TIMER_IEN_CC0; } -long long HighResolutionTimerBase::getCurrentTime(){ +long long HighResolutionTimerBase::getCurrentTick(){ bool interrupts=areInterruptsEnabled(); //TODO: optimization opportunity, if we can guarantee that no call to this //function occurs before kernel is started, then we can use //fastInterruptDisable()) if(interrupts) disableInterrupts(); - long long result=IRQgetCurrentTime(); + long long result=IRQgetCurrentTick(); if(interrupts) enableInterrupts(); return result; @@ -332,8 +347,7 @@ WaitResult HighResolutionTimerBase::IRQsetNextGPIOInterrupt(long long tick){ ms32chkp[2] = tick & (upperMask | 0xFFFF0000); TIMER1->CC[2].CCV = t1; - TIMER1->IFC = TIMER_IFC_CC2; - TIMER1->IEN |= TIMER_IEN_CC2; + setCCInterrupt2Tim1(true); //0xFFFF because it's the roundtrip of timer if(diff<=0xFFFF){ TIMER1->CC[2].CTRL = (TIMER1->CC[2].CTRL & ~_TIMER_CC_CTRL_CMOA_MASK) | TIMER_CC_CTRL_CMOA_SET; @@ -366,7 +380,7 @@ void HighResolutionTimerBase::setModeGPIOTimer(bool input){ //TIMER3->CC2 as consumer TIMER3->CC[2].CTRL= TIMER_CC_CTRL_PRSSEL_PRSCH0 | TIMER_CC_CTRL_INSEL_PRS - | TIMER_CC_CTRL_ICEDGE_BOTH + | TIMER_CC_CTRL_ICEDGE_RISING //NOTE: when does the output get low? | TIMER_CC_CTRL_MODE_INPUTCAPTURE; faseGPIO=1; }else{ @@ -375,6 +389,12 @@ void HighResolutionTimerBase::setModeGPIOTimer(bool input){ } } +void HighResolutionTimerBase::cleanBufferGPIO(){ + falseRead(&TIMER3->CC[2].CCV); + falseRead(&TIMER1->CC[2].CCV); + falseRead(&TIMER3->CC[2].CCV); + falseRead(&TIMER1->CC[2].CCV); +} void HighResolutionTimerBase::setModeRadioTimer(bool input){ //Connect TIMER2->CC0/1 to pin PA8 and PA9 diff --git a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/high_resolution_timer_base.h b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/high_resolution_timer_base.h index 09b5616a..0e511496 100644 --- a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/high_resolution_timer_base.h +++ b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/high_resolution_timer_base.h @@ -54,13 +54,23 @@ public: long long IRQgetSetTimeCCV0() const; long long IRQgetSetTimeCCV1() const; long long IRQgetSetTimeCCV2() const; + + /* + * Clean buffer in TIMER used by GPIOTimer + */ + void cleanBufferGPIO(); /** * Could be call both when the interrupts are enabled/disabled! * TODO: investigate if it's possible to remove the possibility to call * this with IRQ disabled and use IRQgetCurrentTime() instead * \return the current tick count of the timer */ - long long getCurrentTime(); + long long getCurrentTick(); + /** + * \return the current tick count of the timer. + * Can only be called with interrupts disabled or within an IRQ + */ + long long IRQgetCurrentTick(); void setCCInterrupt0(bool enable); void setCCInterrupt1(bool enable); @@ -69,11 +79,6 @@ public: void setCCInterrupt0Tim2(bool enable); void setModeGPIOTimer(bool input); void setModeRadioTimer(bool input); - /** - * \return the current tick count of the timer. - * Can only be called with interrupts disabled or within an IRQ - */ - long long IRQgetCurrentTime(); virtual ~HighResolutionTimerBase(); diff --git a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/radio_timer.cpp b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/radio_timer.cpp index b81d97da..ed7245f0 100644 --- a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/radio_timer.cpp +++ b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/radio_timer.cpp @@ -18,7 +18,7 @@ using namespace miosix; Thread* RadioTimer::tWaiting=nullptr; long long RadioTimer::getValue() const{ - return b.getCurrentTime(); + return b.getCurrentTick(); } void RadioTimer::wait(long long tick){ @@ -26,7 +26,7 @@ void RadioTimer::wait(long long tick){ } bool RadioTimer::absoluteWait(long long tick){ - if(b.getCurrentTime()>=tick){ + if(b.getCurrentTick()>=tick){ return true; } Thread::nanoSleepUntil(tc.tick2ns(tick)); @@ -46,13 +46,13 @@ bool RadioTimer::absoluteWaitTrigger(long long tick){ FastInterruptEnableLock eLock(dLock); Thread::yield(); } - } while(tWaiting && tick>b.getCurrentTime()); + } while(tWaiting && tick>b.getCurrentTick()); return false; } bool RadioTimer::absoluteWaitTimeoutOrEvent(long long tick){ FastInterruptDisableLock dLock; - if(tick<b.getCurrentTime()){ + if(tick<b.getCurrentTick()){ return true; } @@ -66,7 +66,7 @@ bool RadioTimer::absoluteWaitTimeoutOrEvent(long long tick){ FastInterruptEnableLock eLock(dLock); Thread::yield(); } - } while(tWaiting && tick>b.getCurrentTime()); + } while(tWaiting && tick>b.getCurrentTick()); if(tWaiting==nullptr){ return false; -- GitLab