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 e4fbff900485c7ac0bd9080273878f7a1294692e..690ee254744aa29d96cc17a59b9a60a5f6ba78ae 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 35f287316ed76cdacbc243d4f266934e8a36bc30..3ce195c677b8f953b7b1d8f9d4e8c59716599025 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 289434b268754fea5e6f2bbc897502b8149b7fcd..105c44ec5b1181df184de7f6e3338647a6286609 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 1aaf6bb98b25e556f7372f630c38efa8bce990d3..1e0302c338592444d2550f41f8e111afaf8f38dc 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 09b5616acc2b07e86680252f9f1173bb99c4bb73..0e511496790dac2c5bc269729c8ba7056ce10a25 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 b81d97da2ce2a609f2bbe9f5ee880ea64b6fb404..ed7245f058067a2d260603a028b1d50ef2367df1 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;