diff --git a/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/cstimer.cpp b/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/cstimer.cpp
index dde3b92463f58a4caf48f9a01989125086e9ca4f..3f64b521ef6edc4d9fcb8abc4ccc4073b3794d84 100644
--- a/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/cstimer.cpp
+++ b/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/cstimer.cpp
@@ -4,111 +4,39 @@
 #include "kernel/kernel.h"
 #include "kernel/logging.h"
 #include <cstdlib>
+
 using namespace miosix;
-namespace miosix{
+
+namespace miosix {
 void IRQaddToSleepingList(SleepData *x);
 extern SleepData *sleeping_list;
 }
 
+namespace miosix_private {
+void ISR_preempt();
+}
+
 static long long cst_ms32time = 0; //most significant 32 bits of counter
 static long long cst_ms32chkp = 0; //most significant 32 bits of check point
 static bool lateIrq=false;
 static SleepData csRecord;
 
-#define CST_QUANTOM 84000*4
-#define CST_ROLLOVER_INT (TIM2->SR & TIM_SR_UIF) && (TIM2->SR & TIM_SR_CC2IF)
-
-namespace miosix_private{
-    void ISR_preempt();
-}
-ContextSwitchTimer& ContextSwitchTimer::instance() {
-    static ContextSwitchTimer _instance;
-    return _instance;
-}
-
-ContextSwitchTimer::ContextSwitchTimer() {
-    /*
-     *  TIM2 Source Clock (from APB1) Enable
-     */
-    {
-        InterruptDisableLock idl;
-        RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
-        RCC_SYNC();
-        DBGMCU->APB1FZ|=DBGMCU_APB1_FZ_DBG_TIM2_STOP; //Tim2 stops while debugging
-    }
-    /*
-     * Setup TIM2 base configuration
-     * Mode: Up-counter
-     * Interrupts: counter overflow, Compare/Capture on channel 1
-     */
-    TIM2->CR1=TIM_CR1_URS;
-    TIM2->DIER=TIM_DIER_UIE | TIM_DIER_CC1IE;
-    NVIC_SetPriority(TIM2_IRQn,3);
-    NVIC_EnableIRQ(TIM2_IRQn);
-    /*
-     * Configure channel 1 as:
-     * Output channel (CC1S=0)
-     * No preload(OC1PE=0), hence TIM2_CCR1 can be written at anytime
-     * No effect on the output signal on match (OC1M = 0)
-     */
-    TIM2->CCMR1 = 0;
-    TIM2->CCR1 = 0;
-    /*
-     * TIM2 Operation Frequency Configuration: Max Freq. and longest period
-     */
-    TIM2->PSC = 0;
-    TIM2->ARR = 0xFFFFFFFF;
-    //printf("PSCFreq: %lu  PCS: %lu   ARR: %lu  CCR1: %lu  SR: %lu CNT: %lu\n",pcsfreq,TIM2->PSC,TIM2->ARR,TIM2->CCR1,TIM2->SR,TIM2->CNT);
-    /*
-     * Other initializations
-     */
-    // Set the first checkpoint interrupt
-    csRecord.p = 0;
-    csRecord.wakeup_time = CST_QUANTOM;
-    csRecord.next = sleeping_list;
-    sleeping_list = &csRecord;
-    setNextInterrupt(CST_QUANTOM);
-    //IRQaddToSleepingList(&csRecord); //Recursive Initialization error
-    // Enable TIM2 Counter
-    cst_ms32time = 0;
-    TIM2->EGR = TIM_EGR_UG; //To enforce the timer to apply PSC (and other non-immediate settings)
-    TIM2->CR1 |= TIM_CR1_CEN;
-}
-
-long long ContextSwitchTimer::getCurrentTick() {
-    bool interrupts=areInterruptsEnabled();
-    if(interrupts) disableInterrupts();
-    //If overflow occurs while interrupts disabled
-    /*
-     * counter should be checked before rollover interrupt flag
-     *
-     */
-    uint32_t counter = TIM2->CNT;
-    if (CST_ROLLOVER_INT && counter < 0x80000000){
-        long long result=(cst_ms32time | counter) + 0x100000000ll;
-        if(interrupts) enableInterrupts();
-        return result;
-    }
-    long long result=cst_ms32time | counter;
-    if(interrupts) enableInterrupts();
-    return result;
+static inline long long nextInterrupt()
+{
+    return cst_ms32chkp | TIM2->CCR1;
 }
 
-void ContextSwitchTimer::setNextInterrupt(long long tick) {
-    cst_ms32chkp = tick & 0xFFFFFFFF00000000;
-    TIM2->CCR1 = (uint32_t)(tick & 0xFFFFFFFF);
-    if (getCurrentTick() > getNextInterrupt())
-    {
-        NVIC_SetPendingIRQ(TIM2_IRQn);
-        lateIrq=true;
-    }
-}
+#define CST_ROLLOVER_INT (TIM2->SR & TIM_SR_UIF) && (TIM2->SR & TIM_SR_CC2IF)
 
-long long ContextSwitchTimer::getNextInterrupt(){
-    return cst_ms32chkp | TIM2->CCR1;
+void __attribute__((naked)) TIM2_IRQHandler()
+{
+    saveContext();
+    asm volatile ("bl _Z9cstirqhndv");
+    restoreContext();
 }
 
-void __attribute__((used)) cstirqhnd(){
+void __attribute__((used)) cstirqhnd()
+{
     //IRQbootlog("TIM2-IRQ\r\n");
     if (TIM2->SR & TIM_SR_CC1IF || lateIrq){
         //Checkpoint met
@@ -119,16 +47,11 @@ void __attribute__((used)) cstirqhnd(){
         if(cst_ms32time==cst_ms32chkp || lateIrq){
             lateIrq=false;
             long long tick = ContextSwitchTimer::instance().getCurrentTick();
-            //Set next checkpoint interrupt
-            ////cst_prevChk += CST_QUANTOM;
-            ////ContextSwitchTimer::instance().setNextInterrupt(cst_prevChk);
-            //ContextSwitchTimer::instance().setNextInterrupt(
-            //    ContextSwitchTimer::instance().getCurrentTick() + CST_QUANTOM);
             
             //Add next context switch time to the sleeping list iff this is a
             //context switch
             
-            if (tick > csRecord.wakeup_time){
+            if (tick >= csRecord.wakeup_time){
                 //Remove the cs item from the sleeping list manually
                 if (sleeping_list==&csRecord)
                     sleeping_list=sleeping_list->next;
@@ -143,14 +66,14 @@ void __attribute__((used)) cstirqhnd(){
                 //Add next cs item to the list via IRQaddToSleepingList
                 //Note that the next timer interrupt is set by IRQaddToSleepingList
                 //according to the head of the list!
-                csRecord.wakeup_time += CST_QUANTOM;
+                csRecord.wakeup_time += CST_QUANTUM;
                 IRQaddToSleepingList(&csRecord); //It would also set the next timer interrupt
             }
             miosix_private::ISR_preempt();
         }
 
     }
-    //Rollover (Update and CC2 that is always set on zero)
+    //Rollover
     //On the initial update SR = UIF (ONLY)
     if (TIM2->SR & TIM_SR_UIF){
         TIM2->SR = ~TIM_SR_UIF; //w0 clear
@@ -158,12 +81,116 @@ void __attribute__((used)) cstirqhnd(){
     }
 }
 
-void __attribute__((naked)) TIM2_IRQHandler(){
-    saveContext();
-    asm volatile ("bl _Z9cstirqhndv");
-    restoreContext();
+//
+// class ContextSwitchTimer
+//
+
+namespace miosix {
+
+ContextSwitchTimer& ContextSwitchTimer::instance()
+{
+    static ContextSwitchTimer instance;
+    return instance;
+}
+
+void ContextSwitchTimer::IRQsetNextInterrupt(long long tick)
+{
+    cst_ms32chkp = tick & 0xFFFFFFFF00000000;
+    TIM2->CCR1 = static_cast<unsigned int>(tick & 0xFFFFFFFF);
+    if(getCurrentTick() > nextInterrupt())
+    {
+        NVIC_SetPendingIRQ(TIM2_IRQn);
+        lateIrq=true;
+    }
+}
+
+long long ContextSwitchTimer::getNextInterrupt() const
+{
+    return nextInterrupt();
 }
 
-ContextSwitchTimer::~ContextSwitchTimer() {
+long long ContextSwitchTimer::getCurrentTick() const
+{
+    bool interrupts=areInterruptsEnabled();
+    if(interrupts) disableInterrupts();
+    //If overflow occurs while interrupts disabled
+    /*
+     * counter should be checked before rollover interrupt flag
+     *
+     */
+    uint32_t counter = TIM2->CNT;
+    if (CST_ROLLOVER_INT && counter < 0x80000000){
+        long long result=(cst_ms32time | counter) + 0x100000000ll;
+        if(interrupts) enableInterrupts();
+        return result;
+    }
+    long long result=cst_ms32time | counter;
+    if(interrupts) enableInterrupts();
+    return result;
+}
+
+ContextSwitchTimer::~ContextSwitchTimer() {}
+
+ContextSwitchTimer::ContextSwitchTimer()
+{
+    /*
+     *  TIM2 Source Clock (from APB1) Enable
+     */
+    {
+        InterruptDisableLock idl;
+        RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
+        RCC_SYNC();
+        DBGMCU->APB1FZ|=DBGMCU_APB1_FZ_DBG_TIM2_STOP; //Tim2 stops while debugging
+    }
+    /*
+     * Setup TIM2 base configuration
+     * Mode: Up-counter
+     * Interrupts: counter overflow, Compare/Capture on channel 1
+     */
+    TIM2->CR1=TIM_CR1_URS;
+    TIM2->DIER=TIM_DIER_UIE | TIM_DIER_CC1IE;
+    NVIC_SetPriority(TIM2_IRQn,3); //High priority for TIM2 (Max=0, min=15)
+    NVIC_EnableIRQ(TIM2_IRQn);
+    /*
+     * Configure channel 1 as:
+     * Output channel (CC1S=0)
+     * No preload(OC1PE=0), hence TIM2_CCR1 can be written at anytime
+     * No effect on the output signal on match (OC1M = 0)
+     */
+    TIM2->CCMR1 = 0;
+    TIM2->CCR1 = 0;
+    /*
+     * TIM2 Operation Frequency Configuration: Max Freq. and longest period
+     */
+    TIM2->PSC = 0;
+    TIM2->ARR = 0xFFFFFFFF;
+    
+    /*
+     * Other initializations
+     */
+    // Set the first checkpoint interrupt
+    csRecord.p = 0;
+    csRecord.wakeup_time = CST_QUANTUM;
+    csRecord.next = sleeping_list;
+    sleeping_list = &csRecord;
+    //IRQaddToSleepingList(&csRecord); //Recursive Initialization error
+    // Enable TIM2 Counter
+    cst_ms32time = 0;
+    TIM2->EGR = TIM_EGR_UG; //To enforce the timer to apply PSC (and other non-immediate settings)
+    TIM2->CR1 |= TIM_CR1_CEN;
+    
+    // The global variable SystemCoreClock from ARM's CMSIS allows to know
+    // the CPU frequency.
+    timerFreq=SystemCoreClock;
 
+    // The timer frequency may however be a submultiple of the CPU frequency,
+    // due to the bus at whch the periheral is connected being slower. The
+    // RCC->CFGR register tells us how slower the APB1 bus is running.
+    // This formula takes into account that if the APB1 clock is divided by a
+    // factor of two or greater, the timer is clocked at twice the bus
+    // interface. After this, the freq variable contains the frequency in Hz
+    // at which the timer prescaler is clocked.
+    if(RCC->CFGR & RCC_CFGR_PPRE1_2) timerFreq/=1<<((RCC->CFGR>>10) & 0x3);
 }
+
+} //namespace miosix
diff --git a/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp b/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp
index 9f1884b856f0c7eb3d19da9295dbc2f9523cbc72..3b6155cdf105b2391e3f7ac7cdaba1825b53e6e5 100644
--- a/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp
+++ b/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp
@@ -313,7 +313,7 @@ void IRQportableStartKernel()
     SysTick->CTRL=SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk |
             SysTick_CTRL_CLKSOURCE_Msk;
 #else //USE ContextSwitchTimer class (TIM2)
-    miosix::ContextSwitchTimer::instance();
+    miosix::ContextSwitchTimer::instance().IRQsetNextInterrupt(CST_QUANTUM);
 #endif
     #ifdef WITH_PROCESSES
     miosix::IRQenableMPUatBoot();
diff --git a/miosix/interfaces/cstimer.h b/miosix/interfaces/cstimer.h
index 3da5d860a272c26f8fce73af7865db3a4e74c579..0e4ded1800680763cb1847c797319edf5b95c7a5 100644
--- a/miosix/interfaces/cstimer.h
+++ b/miosix/interfaces/cstimer.h
@@ -1,21 +1,64 @@
 #ifndef CSTIMER_H
 #define	CSTIMER_H
 
-namespace miosix{
-    class ContextSwitchTimer{
-    public:
-        static ContextSwitchTimer& instance();
-        void setNextInterrupt(long long tick); //timer tick
-        long long getNextInterrupt();
-        /**
-         * Could be call both when the interrupts are enabled/disabled!
-         * @return the current tick count of the timer
-         */
-        long long getCurrentTick();
-        virtual ~ContextSwitchTimer();
-    private:
-        ContextSwitchTimer();
-    };
-}
-#endif	/* TIMER_H */
+namespace miosix {
 
+#define CST_QUANTUM 42000//84000 ///FIXME: remove
+
+/**
+ * This class is a low level interface to a hardware timer, that is used as
+ * the basis for the Miosix timing infrastructure. In detail, it allows to
+ * set interrupts used both for thread wakeup from sleep, and for preemption. 
+ */
+class ContextSwitchTimer
+{
+public:
+    /**
+     * \return an instance of this class (singleton)
+     */
+    static ContextSwitchTimer& instance();
+    
+    /**
+     * Set the next interrupt.
+     * Can be called with interrupts disabled or within an interrupt.
+     * \param tick the time when the interrupt will be fired, in timer ticks
+     */
+    void IRQsetNextInterrupt(long long tick);
+    
+    /**
+     * \return the time when the next interrupt will be fired.
+     * That is, the last value passed to setNextInterrupt().
+     */
+    long long getNextInterrupt() const;
+    
+    /**
+     * Could be call both when the interrupts are enabled/disabled!
+     * \return the current tick count of the timer
+     */
+    long long getCurrentTick() const;
+    
+    /**
+     * \return the timer frequency in Hz
+     */
+    unsigned int getTimerFrequency() const
+    {
+        return timerFreq;
+    }
+    
+    /**
+     * Destructor
+     */
+    virtual ~ContextSwitchTimer();
+    
+private:
+    /**
+     * Constructor, private because it's a singleton
+     */
+    ContextSwitchTimer();
+    
+    unsigned int timerFreq;
+};
+
+} //namespace miosix
+
+#endif //TIMER_H
diff --git a/miosix/kernel/kernel.cpp b/miosix/kernel/kernel.cpp
index c897e2aad07375c73ccd4fa2741913d8d3f3243e..7df5ed20951e13224117509771e20d690985ce67 100644
--- a/miosix/kernel/kernel.cpp
+++ b/miosix/kernel/kernel.cpp
@@ -260,7 +260,7 @@ void IRQaddToSleepingList(SleepData *x)
     //Upon any change to the sleeping_list the ContextSwitchTimer should have
     //its interrupt set to the head of the list in order to keep it sync with
     //the list
-    ContextSwitchTimer::instance().setNextInterrupt(sleeping_list->wakeup_time);
+    ContextSwitchTimer::instance().IRQsetNextInterrupt(sleeping_list->wakeup_time);
 }
 
 /**
@@ -287,7 +287,7 @@ bool IRQwakeThreads()
         sleeping_list=sleeping_list->next;//Remove from list
         result=true;
         //update interrupt of context switch timer
-        ContextSwitchTimer::instance().setNextInterrupt(sleeping_list->wakeup_time);
+        ContextSwitchTimer::instance().IRQsetNextInterrupt(sleeping_list->wakeup_time);
     }
     return result;
 }