From 264b093da6c15a81c264e5954939bb5e165dc063 Mon Sep 17 00:00:00 2001 From: Fabiano Riccardi <fabiuz4@hotmail.it> Date: Wed, 12 Oct 2016 15:59:32 +0200 Subject: [PATCH] Added the first part of RadioTimer and improvement of GPIOtimer Signed-off-by: Fabiano Riccardi <fabiuz4@hotmail.it> --- .../interfaces-impl/gpio_timer.cpp | 9 +- .../interfaces-impl/gpio_timer.h | 1 + .../high_resolution_timer_base.cpp | 88 ++++++++++++------- .../interfaces-impl/radio_timer.cpp | 28 ++++++ .../interfaces-impl/radio_timer.h | 35 ++++++++ miosix/config/Makefile.inc | 4 +- 6 files changed, 128 insertions(+), 37 deletions(-) create mode 100644 miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/radio_timer.cpp create mode 100644 miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/radio_timer.h 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 ed9ca78a..fa4bcfe2 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 @@ -80,13 +80,11 @@ WaitResult GPIOtimer::waitTimeoutOrEvent(long long tick){ */ bool GPIOtimer::absoluteWaitTrigger(long long tick){ FastInterruptDisableLock dLock; - if(!b.IRQsetNextInterrupt2(tick)){ - return true; - } b.setModeGPIOTimer(false); //output timer setPinMode(false); //output pin - b.setCCInterrupt2Tim1(false); - b.setCCInterrupt2(true); //enable + if(b.IRQsetNextInterrupt2(tick)){ + return true; + } return false; } @@ -94,5 +92,6 @@ bool GPIOtimer::waitTrigger(long long tick){ return absoluteWaitTrigger(b.getCurrentTick()+tick); } +long long GPIOtimer::aux1=0; GPIOtimer::~GPIOtimer() {} 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 cfd19d25..4aae9c83 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 @@ -30,6 +30,7 @@ namespace miosix { class GPIOtimer{ public: static Thread *tWaitingGPIO; + static long long aux1; static GPIOtimer& instance(); virtual ~GPIOtimer(); WaitResult waitTimeoutOrEvent(long long value); 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 b01f15f5..03ad1119 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 @@ -49,6 +49,10 @@ static inline long long IRQgetTick(){ } inline void interruptGPIOTimerRoutine(){ + TIMER1->IEN &= ~TIMER_IEN_CC2; + TIMER3->IEN &= ~TIMER_IEN_CC2; + TIMER1->IFC = TIMER_IFC_CC2; + TIMER3->IFC = TIMER_IFC_CC2; if(TIMER1->CC[2].CTRL & TIMER_CC_CTRL_MODE_OUTPUTCOMPARE){ expansion::gpio10::high(); }else if(TIMER1->CC[2].CTRL & TIMER_CC_CTRL_MODE_INPUTCAPTURE){ @@ -94,6 +98,30 @@ static inline void setupTimers(){ // If the most significant 32bit aren't match wait for TIM3 to overflow! } +static inline void setupTimers2(){ + // We assume that this function is called only when the checkpoint is in future + if (ms32chkp[2] == ms32time){ + // If the most significant 32bit matches, enable TIM3 + TIMER3->IFC = TIMER_IFC_CC2; + TIMER3->IEN |= TIMER_IEN_CC2; + if (static_cast<unsigned short>(TIMER3->CNT) >= static_cast<unsigned short>(TIMER3->CC[2].CCV) + 1){ + // If TIM3 matches by the time it is being enabled, disable it right away + TIMER3->IFC = TIMER_IFC_CC2; + TIMER3->IEN &= ~TIMER_IEN_CC2; + // Enable TIM1 since TIM3 has been already matched + TIMER1->IFC = TIMER_IFC_CC2; + TIMER1->IEN |= TIMER_IEN_CC2; + if (TIMER1->CNT >= TIMER1->CC[2].CCV){ + // If TIM1 matches by the time it is being enabled, call the scheduler right away + interruptGPIOTimerRoutine(); + } + } + } + // If the most significant 32bit aren't match wait for TIM3 to overflow! +} + + + void __attribute__((naked)) TIMER3_IRQHandler() { saveContext(); @@ -114,6 +142,7 @@ void __attribute__((used)) cstirqhnd3(){ TIMER3->IFC = TIMER_IFC_OF; ms32time += overflowIncrement; setupTimers(); + setupTimers2(); } //Checkpoint if ((TIMER3->IEN & TIMER_IEN_CC1) && (TIMER3->IF & TIMER_IF_CC1)){ @@ -133,21 +162,20 @@ void __attribute__((used)) cstirqhnd3(){ } //This if is to manage the GPIOtimer in OUTPUT Mode - if((TIMER3->IEN & TIMER_IEN_CC2) && (TIMER3->IF & TIMER_IF_CC2)){ - if (ms32time == ms32chkp[2]){ - TIMER3->IFC = TIMER_IFC_CC2; - TIMER3->IEN &= ~TIMER_IEN_CC2; - greenLed::high(); - - TIMER1->IFC = TIMER_IFC_CC2; - TIMER1->IEN |= TIMER_IEN_CC2; - if (TIMER1->CNT >= TIMER1->CC[2].CCV){ - TIMER1->IEN &= ~TIMER_IEN_CC2; - TIMER1->IFC = TIMER_IFC_CC2; - interruptGPIOTimerRoutine(); - } - } - } + if ((TIMER3->IEN & TIMER_IEN_CC2) && (TIMER3->IF & TIMER_IF_CC2)){ + TIMER3->IFC = TIMER_IFC_CC2; + if (static_cast<unsigned short>(TIMER3->CNT) >= static_cast<unsigned short>(TIMER3->CC[2].CCV) + 1){ + // Should happen if and only if most significant 32 bits have been matched + TIMER3->IEN &= ~ TIMER_IEN_CC2; + // Enable TIM1 since TIM3 has been already matched + TIMER1->IFC = TIMER_IFC_CC2; + TIMER1->IEN |= TIMER_IEN_CC2; + if (TIMER1->CNT >= TIMER1->CC[2].CCV){ + // If TIM1 matches by the time it is being enabled, call the scheduler right away + interruptGPIOTimerRoutine(); + } + } + } } void __attribute__((used)) cstirqhnd1(){ if ((TIMER1->IEN & TIMER_IEN_CC1) && (TIMER1->IF & TIMER_IF_CC1)){ @@ -158,8 +186,6 @@ void __attribute__((used)) cstirqhnd1(){ //This if is used to manage the case of GPIOTimer, both INPUT and OUTPUT mode if ((TIMER1->IEN & TIMER_IEN_CC2) && (TIMER1->IF & TIMER_IF_CC2)){ - TIMER1->IEN &= ~TIMER_IEN_CC2; - TIMER1->IFC = TIMER_IFC_CC2; interruptGPIOTimerRoutine(); } } @@ -334,7 +360,7 @@ bool HighResolutionTimerBase::IRQsetNextInterrupt0(long long tick){ } bool HighResolutionTimerBase::IRQsetNextInterrupt1(long long tick){ - // First off, clear and disable timers to prevent unnecessary IRQ + // First off, disable timers to prevent unnecessary IRQ // when IRQsetNextInterrupt is called multiple times consecutively. TIMER1->IEN &= ~TIMER_IEN_CC1; TIMER3->IEN &= ~TIMER_IEN_CC1; @@ -356,21 +382,21 @@ bool HighResolutionTimerBase::IRQsetNextInterrupt1(long long tick){ } bool HighResolutionTimerBase::IRQsetNextInterrupt2(long long tick){ - ms32chkp[2] = tick & upperMask; - TIMER3->CC[2].CCV = static_cast<unsigned int>((tick & 0xFFFF0000)>>16)-1; - TIMER1->CC[2].CCV = static_cast<unsigned int>(tick & 0xFFFF); - /* - In order to prevent back to back interrupts due to a checkpoint - set in the past, raise lateIrq flag to indicate this IRQ should - be processed only once - */ - if(IRQgetCurrentTick() >= IRQgetSetTimeCCV2()) - { - //TIMER3->IFS=TIMER_IFS_CC2; - lateIrq=true; + TIMER1->IEN &= ~TIMER_IEN_CC2; + TIMER3->IEN &= ~TIMER_IEN_CC2; + + long long curTick = IRQgetTick(); + if(curTick >= tick){ + // The interrupt is in the past => call timerInt immediately + interruptGPIOTimerRoutine(); //TODO: It could cause multiple invocations of sched. return false; + }else{ + ms32chkp[2] = tick & upperMask; + TIMER3->CC[2].CCV = static_cast<unsigned int>((tick & 0xFFFF0000)>>16)-1; + TIMER1->CC[2].CCV = static_cast<unsigned int>(tick & 0xFFFF); + setupTimers2(); + return true; } - return true; } 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 new file mode 100644 index 00000000..2ee7f013 --- /dev/null +++ b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/radio_timer.cpp @@ -0,0 +1,28 @@ +/* + * 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: radio_timer.cpp + * Author: fabiuz + * + * Created on October 11, 2016, 11:17 AM + */ + +#include "radio_timer.h" + +using namespace miosix; + +Thread* RadioTimer::tWaitingGPIO=nullptr; + +RadioTimer::RadioTimer():b(HighResolutionTimerBase::instance()) {} + +RadioTimer& RadioTimer::instance(){ + static RadioTimer instance; + return instance; +} + +RadioTimer::~RadioTimer() {} + diff --git a/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/radio_timer.h b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/radio_timer.h new file mode 100644 index 00000000..aef3f89c --- /dev/null +++ b/miosix/arch/cortexM3_efm32gg/efm32gg332f1024_wandstem/interfaces-impl/radio_timer.h @@ -0,0 +1,35 @@ +/* + * 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: radio_timer.h + * Author: fabiuz + * + * Created on October 11, 2016, 11:17 AM + */ + +#include "high_resolution_timer_base.h" + + +#ifndef RADIO_TIMER_H +#define RADIO_TIMER_H + +namespace miosix{ + class RadioTimer { + public: + static Thread *tWaitingGPIO; + static RadioTimer& instance(); + virtual ~RadioTimer(); + private: + RadioTimer(); + HighResolutionTimerBase& b; + }; +} + + + +#endif /* RADIO_TIMER_H */ + diff --git a/miosix/config/Makefile.inc b/miosix/config/Makefile.inc index 2470bdb2..2ade3acd 100644 --- a/miosix/config/Makefile.inc +++ b/miosix/config/Makefile.inc @@ -2114,7 +2114,9 @@ else ifeq ($(ARCH),cortexM3_efm32gg) $(BOARD_INC)/interfaces-impl/gpioirq.cpp \ $(BOARD_INC)/interfaces-impl/hardware_timer.cpp \ $(BOARD_INC)/interfaces-impl/transceiver.cpp \ - $(BOARD_INC)/interfaces-impl/cstimer.cpp + $(BOARD_INC)/interfaces-impl/cstimer.cpp \ + $(BOARD_INC)/interfaces-impl/gpio_timer.cpp \ + $(BOARD_INC)/interfaces-impl/radio_timer.cpp ## Add a #define to allow querying board name CFLAGS_BASE += -DEFM32GG332F1024 -D_BOARD_WANDSTEM -- GitLab