From 2c81d5c059104d8570a23caef7fc3fa0df456f7b Mon Sep 17 00:00:00 2001 From: Fabiano Riccardi <fabiuz4@hotmail.it> Date: Tue, 15 Nov 2016 11:22:41 +0100 Subject: [PATCH] Fixed the previuos commit, wrong file was updated. Add the timeout test for GPIO. It should be improved Signed-off-by: Fabiano Riccardi <fabiuz4@hotmail.it> --- .../high_resolution_timer_base.cpp | 95 +++++++++++++++++ .../high_resolution_timer_base.h | 32 +++++- .../virtual_high_resolution_timer_base.cpp | 100 ------------------ .../virtual_high_resolution_timer_base.h | 47 -------- 4 files changed, 124 insertions(+), 150 deletions(-) delete mode 100644 miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/virtual_high_resolution_timer_base.cpp delete mode 100644 miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/virtual_high_resolution_timer_base.h 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 e8289c73..420439f0 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 @@ -33,6 +33,7 @@ #include "gpio_timer.h" #include "transceiver_timer.h" #include "../../../../debugpin.h" +#include "rtc.h" using namespace miosix; @@ -162,6 +163,13 @@ void __attribute__((naked)) TIMER1_IRQHandler() restoreContext(); } +void __attribute__((naked)) CMU_IRQHandler() +{ + saveContext(); + asm volatile("bl _Z10cmuhandlerv"); + restoreContext(); +} + void __attribute__((used)) cstirqhnd3(){ //rollover if (TIMER3->IF & TIMER_IF_OF){ @@ -271,6 +279,8 @@ void __attribute__((used)) cstirqhnd1(){ } }else{ TIMER1->IEN &= ~TIMER_IEN_CC2; + TIMER1->IEN &= ~TIMER_IEN_CC0; + TIMER1->IFC = TIMER_IFC_CC0; interruptGPIOTimerRoutine(); } } @@ -293,6 +303,23 @@ void __attribute__((used)) cstirqhnd1(){ } } +void __attribute__((used)) cmuhandler(){ + static float y; + static bool first=true; + if(CMU->IF & CMU_IF_CALRDY){ + if(first){ + y=CMU->CALCNT; + first=false; + }else{ + y=0.8f*y+0.2f*CMU->CALCNT; + } + CMU->IFC=CMU_IFC_CALRDY; + bool hppw; + HighResolutionTimerBase::queue.IRQpost([&](){printf("%f\n",y);},hppw); + if(hppw) Scheduler::IRQfindNextThread(); + } +} + long long HighResolutionTimerBase::IRQgetSetTimeTransceiver() const{ return ms32chkp[0] | TIMER3->CC[0].CCV<<16 | TIMER2->CC[0].CCV; } @@ -567,12 +594,78 @@ WaitResult HighResolutionTimerBase::IRQsetTransceiverTimeout(long long tick){ } } +void HighResolutionTimerBase::resyncVht(){ + Rtc& rtc=Rtc::instance(); + long long rtcTime; + int a=0,b=0,c=0,d=0,e=0; + { + FastInterruptDisableLock dLock; + HighPin<debug1> x; + int prev=loopback32KHzIn::value(); +// a=RTC->CNT; + for(;;) + { + int curr=loopback32KHzIn::value(); + if(curr==0 && prev==1) break; + prev=curr; + } +// d=TIMER2->CNT; +// b=RTC->CNT; + TIMER2->CC[2].CTRL=TIMER_CC_CTRL_ICEDGE_RISING + | TIMER_CC_CTRL_FILT_DISABLE + | TIMER_CC_CTRL_INSEL_PIN + | TIMER_CC_CTRL_MODE_INPUTCAPTURE; + while((TIMER2->IF & TIMER_IF_CC2)==0) ; + TIMER2->CC[2].CTRL=0; + TIMER2->IFC=TIMER_IFC_CC2; + e=TIMER2->CC[2].CCV; + rtcTime=rtc.IRQgetValue(); +// c=RTC->CNT; + } + printf("a=%d b=%d c=%d d=%d e=%d e-d=%d\n",a,b,c,d,e,e>=d ? e-d : e+65536-d); +} + +void HighResolutionTimerBase::setAutoResyncVht(bool enable){ + if(enable){ + + }else{ + + } +} + +void HighResolutionTimerBase::resyncClock(){ + CMU->CMD = CMU_CMD_CALSTART; +} + +void HighResolutionTimerBase::setAutoResyncClocks(bool enable){ + if(enable){ + CMU->CTRL |= CMU_CALCTRL_CONT; + CMU->CMD = CMU_CMD_CALSTART; + }else{ + CMU->CTRL &= ~CMU_CALCTRL_CONT; + CMU->CMD = CMU_CMD_CALSTOP; + } +} + +void HighResolutionTimerBase::initResyncCmu(){ + CMU->CALCTRL=CMU_CALCTRL_DOWNSEL_LFXO|CMU_CALCTRL_UPSEL_HFXO|CMU_CALCTRL_CONT; + //due to hardware timer characteristic, the real counter trigger at value+1 + //tick of LFCO to yield the maximum from to up counter + CMU->CALCNT=700; + //enable interrupt + CMU->IEN=CMU_IEN_CALRDY; + NVIC_SetPriority(CMU_IRQn,3); + NVIC_ClearPendingIRQ(CMU_IRQn); + NVIC_EnableIRQ(CMU_IRQn); +} + HighResolutionTimerBase& HighResolutionTimerBase::instance(){ static HighResolutionTimerBase hrtb; return hrtb; } const unsigned int HighResolutionTimerBase::freq=48000000; +FixedEventQueue<100,12> HighResolutionTimerBase::queue; HighResolutionTimerBase::HighResolutionTimerBase() { //Power the timers up and PRS system @@ -632,6 +725,8 @@ HighResolutionTimerBase::HighResolutionTimerBase() { TIMER1->CTRL &= ~TIMER_CTRL_SYNC; TIMER2->CTRL &= ~TIMER_CTRL_SYNC; TIMER3->CTRL &= ~TIMER_CTRL_SYNC; + + initResyncCmu(); } HighResolutionTimerBase::~HighResolutionTimerBase() { 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 84eb4f34..a1099968 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 @@ -26,7 +26,7 @@ ***************************************************************************/ #include "miosix.h" - +#include "../../../../e20/e20.h" #ifndef HIGH_RESOLUTION_TIMER_BASE_H #define HIGH_RESOLUTION_TIMER_BASE_H @@ -110,10 +110,36 @@ class HighResolutionTimerBase { WaitResult IRQsetGPIOtimeout(long long tick); WaitResult IRQsetTransceiverTimeout(long long tick); - + + void resyncVht(); + void setAutoResyncVht(bool enable); + + /** + * These function are used to sync the HF and the LF clock. It requires + * few ms to trigger the interrupt that effectively compensate the 2 + * clocks. + * Of course, it's not busy waiting. + */ + void resyncClock(); + void setAutoResyncClocks(bool enable); + virtual ~HighResolutionTimerBase(); static int aux; - protected: + + /** + These 4 variables are used to manage the correction of the timers. + * vhtBase (high frequency): keeps the last sync point + * vhtSyncPointRtc (low frequency): keeps the last sync point, just a simple conversion from vhtBase + * vhtSyncPointVht (high frequency: keeps the precise value of last sync point + * vhtOffset (high frequency): keeps the difference between the actual time and the counter value + */ + static long long vhtBase; + static long long vhtSyncPointRtc; + static long long vhtSyncPointVht; + static long long vhtOffset; + static FixedEventQueue<100,12> queue; + private: + void initResyncCmu(); HighResolutionTimerBase(); static const unsigned int freq; diff --git a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/virtual_high_resolution_timer_base.cpp b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/virtual_high_resolution_timer_base.cpp deleted file mode 100644 index 2f1f23e7..00000000 --- a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/virtual_high_resolution_timer_base.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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: VirtualHighResolutionTimerBase.cpp - * Author: fabiuz - * - * Created on November 10, 2016, 9:28 PM - */ - -#include "virtual_high_resolution_timer_base.h" -#include "../../../../debugpin.h" - -namespace miosix{ - -long long VirtualHighResolutionTimerBase::getCurrentTick(){ - FastInterruptDisableLock dLock; - long long vhtCount=HighResolutionTimerBase::getCurrentTick(); - return vhtCount-vhtSyncPointVht+vhtBase+vhtOffset; -} - -void VirtualHighResolutionTimerBase::setCurrentTick(long long value) -{ - //We don't actually overwrite the RTC in this case, as the VHT - //is a bit complicated, so we translate between the two times at - //the boundary of this class. - FastInterruptDisableLock dLock; - long long vhtCount= HighResolutionTimerBase::getCurrentTick(); - //vhtOffset+=value - (vhtCount -vhtSyncPointVht+vhtBase+vhtOffset); - vhtOffset=value-vhtCount+vhtSyncPointVht-vhtBase; -} - -/** - * This takes 17us to 48us - */ -void VirtualHighResolutionTimerBase::resync(){ - { - FastInterruptDisableLock dLock; - HighPin<debug1> x; - int prev=loopback32KHzIn::value(); - for(;;){ - int curr=loopback32KHzIn::value(); - if(curr-prev==-1) break; - prev=curr; - } - int high=TIMER3->CNT; - TIMER2->CC[2].CTRL |= TIMER_CC_CTRL_MODE_INPUTCAPTURE; - - //Wait until we capture the first raising edge in the 32khz wave, - //it takes max half period, less than 16us -->732.4ticks @48000000Hz - while((TIMER2->IF & TIMER_IF_CC2)==0) ; - - //Creating the proper value of vhtSyncPointVht - int high2=TIMER3->CNT; - TIMER2->CC[2].CTRL &= ~_TIMER_CC_CTRL_MODE_MASK; - //This is the exact point when the rtc is incremented to the actual value - TIMER2->IFC =TIMER_IFC_CC2; - if(high==high2){ - vhtSyncPointVht = high<<16 | TIMER2->CC[2].CCV; //FIXME:: add the highest part - }else{ - // 10000 are really enough to be sure that we are in the new window - if(TIMER2->CC[2].CCV < 735){ - vhtSyncPointVht = high2<<16 | TIMER2->CC[2].CCV; - }else{ - vhtSyncPointVht = high<<16 | TIMER2->CC[2].CCV; - } - } - vhtSyncPointVht=TIMER3->CNT | TIMER2->CC[2].CCV; - - vhtSyncPointRtc=rtc.IRQgetValue(); - { - unsigned long long conversion=vhtSyncPointRtc; - conversion*=HighResolutionTimerBase::freq; - conversion+=HighResolutionTimerBase::freq/2; //Round to nearest - conversion/=HighResolutionTimerBase::freq; - vhtBase=conversion; - } - } -} - -VirtualHighResolutionTimerBase& VirtualHighResolutionTimerBase::instance(){ - static VirtualHighResolutionTimerBase vhrtb; - return vhrtb; -} - -VirtualHighResolutionTimerBase::VirtualHighResolutionTimerBase(): rtc(Rtc::instance()) { - //the base class is already started - - TIMER2->CC[2].CTRL=TIMER_CC_CTRL_ICEDGE_RISING - | TIMER_CC_CTRL_FILT_DISABLE - | TIMER_CC_CTRL_INSEL_PIN - | TIMER_CC_CTRL_MODE_OFF; -} - -}//namespace miosix - - diff --git a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/virtual_high_resolution_timer_base.h b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/virtual_high_resolution_timer_base.h deleted file mode 100644 index 5337918f..00000000 --- a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/virtual_high_resolution_timer_base.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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: VirtualHighResolutionTimerBase.h - * Author: fabiuz - * - * Created on November 10, 2016, 9:28 PM - */ - -#ifndef VIRTUALHIGHRESOLUTIONTIMERBASE_H -#define VIRTUALHIGHRESOLUTIONTIMERBASE_H - -#include "high_resolution_timer_base.h" -#include "rtc.h" - -namespace miosix{ - class VirtualHighResolutionTimerBase : public HighResolutionTimerBase{ - public: - static VirtualHighResolutionTimerBase& instance(); - /** - These 4 variables are used to manage the correction of the timers. - * vhtBase (high frequency): keeps the last sync point - * vhtSyncPointRtc (low frequency): keeps the last sync point, just a simple conversion from vhtBase - * vhtSyncPointVht (high frequency: keeps the precise value of last sync point - * vhtOffset (high frequency): keeps the difference between the actual time and the counter value - */ - static long long vhtBase; - static long long vhtSyncPointRtc; - static long long vhtSyncPointVht; - static long long vhtOffset; - long long getCurrentTick(); - void setCurrentTick(long long value); - void resync(); - private: - VirtualHighResolutionTimerBase(); - int syncVhtRtcPeriod; - Rtc& rtc; - }; -} - - -#endif /* VIRTUALHIGHRESOLUTIONTIMERBASE_H */ - -- GitLab