/** * \addtogroup mbxxx-platform * * @{ */ /* * Copyright (c) 2010, STMicroelectronics. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * \file * Real-timer specific implementation for STM32W. * \author * Salvatore Pitrulli */ #include "sys/energest.h" #include "sys/rtimer.h" #define DEBUG 0 #if DEBUG #include #define PRINTF(...) printf(__VA_ARGS__) #else #define PRINTF(...) #endif static uint16_t saved_TIM1CFG; static uint32_t time_msb = 0; /* Most significant bits of the current time. */ /* time of the next rtimer event. Initially is set to the max value. */ static rtimer_clock_t next_rtimer_time = 0; /*---------------------------------------------------------------------------*/ void halTimer1Isr(void) { if(INT_TIM1FLAG & INT_TIMUIF) { rtimer_clock_t now, clock_to_wait; /* Overflow event. */ /* PRINTF("O %4x.\r\n", TIM1_CNT); */ /* printf("OV "); */ time_msb++; now = ((rtimer_clock_t) time_msb << 16) | TIM1_CNT; clock_to_wait = next_rtimer_time - now; if(clock_to_wait <= 0x10000 && clock_to_wait > 0) { /* We must now set the Timer Compare Register. */ TIM1_CCR1 = (uint16_t) clock_to_wait; INT_TIM1FLAG = INT_TIMCC1IF; INT_TIM1CFG |= INT_TIMCC1IF; /* Compare 1 interrupt enable. */ } INT_TIM1FLAG = INT_TIMUIF; } else { if(INT_TIM1FLAG & INT_TIMCC1IF) { /* Compare event. */ INT_TIM1CFG &= ~INT_TIMCC1IF; /* Disable the next compare interrupt */ PRINTF("\nCompare event %4x\r\n", TIM1_CNT); PRINTF("INT_TIM1FLAG %2x\r\n", INT_TIM1FLAG); ENERGEST_ON(ENERGEST_TYPE_IRQ); rtimer_run_next(); ENERGEST_OFF(ENERGEST_TYPE_IRQ); INT_TIM1FLAG = INT_TIMCC1IF; } } } /*---------------------------------------------------------------------------*/ void rtimer_arch_init(void) { TIM1_CR1 = 0; TIM1_PSC = RTIMER_ARCH_PRESCALER; /* Counting from 0 to the maximum value. */ TIM1_ARR = 0xffff; /* Bits of TIMx_CCMR1 as default. */ /* Update Generation. */ TIM1_EGR = TIM_UG; INT_TIM1FLAG = 0xffff; /* Update interrupt enable (interrupt on overflow).*/ INT_TIM1CFG = INT_TIMUIF; /* Counter enable. */ TIM1_CR1 = TIM_CEN; /* Enable top level interrupt. */ INT_CFGSET = INT_TIM1; } /*---------------------------------------------------------------------------*/ void rtimer_arch_disable_irq(void) { ATOMIC(saved_TIM1CFG = INT_TIM1CFG; INT_TIM1CFG = 0;) } /*---------------------------------------------------------------------------*/ void rtimer_arch_enable_irq(void) { INT_TIM1CFG = saved_TIM1CFG; } /*---------------------------------------------------------------------------*/ rtimer_clock_t rtimer_arch_now(void) { rtimer_clock_t t; ATOMIC(t = ((rtimer_clock_t) time_msb << 16) | TIM1_CNT;) return t; } /*---------------------------------------------------------------------------*/ void rtimer_arch_schedule(rtimer_clock_t t) { rtimer_clock_t now, clock_to_wait; PRINTF("rtimer_arch_schedule time %4x\r\n", /*((uint32_t*)&t)+1, */ (uint32_t)t); next_rtimer_time = t; now = rtimer_arch_now(); clock_to_wait = t - now; PRINTF("now %2x\r\n", TIM1_CNT); PRINTF("clock_to_wait %4x\r\n", clock_to_wait); if(clock_to_wait <= 0x10000) { /* We must now set the Timer Compare Register. */ TIM1_CCR1 = (uint16_t)now + (uint16_t)clock_to_wait; INT_TIM1FLAG = INT_TIMCC1IF; INT_TIM1CFG |= INT_TIMCC1IF; /* Compare 1 interrupt enable. */ PRINTF("2-INT_TIM1FLAG %2x\r\n", INT_TIM1FLAG); } /* else compare register will be set at overflow interrupt closer to the rtimer event. */ } /*---------------------------------------------------------------------------*/ /** @} */