00001 /* 00002 * Copyright (c) 2010, STMicroelectronics. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above 00011 * copyright notice, this list of conditions and the following 00012 * disclaimer in the documentation and/or other materials provided 00013 * with the distribution. 00014 * 3. The name of the author may not be used to endorse or promote 00015 * products derived from this software without specific prior 00016 * written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 00019 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00020 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00022 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00023 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00024 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00026 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00027 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * This file is part of the Contiki OS 00031 * 00032 * $Id: rtimer-arch.c,v 1.1 2010/10/25 09:03:39 salvopitru Exp $ 00033 */ 00034 /*---------------------------------------------------------------------------*/ 00035 /** 00036 * \file 00037 * Real-timer specific implementation for STM32W. 00038 * \author 00039 * Salvatore Pitrulli <salvopitru@users.sourceforge.net> 00040 */ 00041 /*---------------------------------------------------------------------------*/ 00042 00043 00044 #include "sys/energest.h" 00045 #include "sys/rtimer.h" 00046 00047 00048 #define DEBUG 0 00049 #if DEBUG 00050 #include <stdio.h> 00051 #define PRINTF(...) printf(__VA_ARGS__) 00052 #else 00053 #define PRINTF(...) 00054 #endif 00055 00056 00057 00058 static u32_t time_msb = 0; // Most significant bits of the current time. 00059 00060 // time of the next rtimer event. Initially is set to the max value. 00061 static rtimer_clock_t next_rtimer_time = 0; 00062 00063 static u16_t saved_TIM1CFG; 00064 00065 00066 /*---------------------------------------------------------------------------*/ 00067 void halTimer1Isr(void){ 00068 00069 00070 if(INT_TIM1FLAG & INT_TIMUIF){ // Overflow event. 00071 00072 //PRINTF("O %4x.\r\n", TIM1_CNT); 00073 //printf("OV "); 00074 00075 time_msb++; 00076 rtimer_clock_t now = ((rtimer_clock_t)time_msb << 16)|TIM1_CNT; 00077 00078 rtimer_clock_t clock_to_wait = next_rtimer_time - now; 00079 00080 if(clock_to_wait <= 0x10000 && clock_to_wait > 0){ // We must set now the Timer Compare Register. 00081 00082 TIM1_CCR1 = (int16u)clock_to_wait; 00083 INT_TIM1FLAG = INT_TIMCC1IF; 00084 INT_TIM1CFG |= INT_TIMCC1IF; // Compare 1 interrupt enable. 00085 } 00086 00087 INT_TIM1FLAG = INT_TIMUIF; 00088 00089 } 00090 00091 else if(INT_TIM1FLAG & INT_TIMCC1IF){ // Compare event. 00092 00093 INT_TIM1CFG &= ~INT_TIMCC1IF; // Disable the next compare interrupt 00094 00095 PRINTF("\nCompare event %4x\r\n", TIM1_CNT); 00096 PRINTF("INT_TIM1FLAG %2x\r\n", INT_TIM1FLAG); 00097 ENERGEST_ON(ENERGEST_TYPE_IRQ); 00098 rtimer_run_next(); 00099 ENERGEST_OFF(ENERGEST_TYPE_IRQ); 00100 INT_TIM1FLAG = INT_TIMCC1IF; 00101 00102 } 00103 00104 } 00105 /*---------------------------------------------------------------------------*/ 00106 void 00107 rtimer_arch_init(void) 00108 { 00109 TIM1_CR1 = 0; 00110 00111 TIM1_PSC = RT_PRESCALER; 00112 00113 TIM1_ARR = 0xffff; // Counting from 0 to the maximum value. 00114 00115 // Bits of TIMx_CCMR1 as default. 00116 00117 TIM1_EGR = TIM_UG; // Update Generation. 00118 00119 INT_TIM1FLAG = 0xffff; 00120 00121 INT_TIM1CFG = INT_TIMUIF; // Update interrupt enable (interrupt on overflow). 00122 00123 TIM1_CR1 = TIM_CEN; // Counter enable. 00124 00125 INT_CFGSET = INT_TIM1; // Enable top level interrupt. 00126 00127 } 00128 /*---------------------------------------------------------------------------*/ 00129 void rtimer_arch_disable_irq(void) 00130 { 00131 ATOMIC( 00132 saved_TIM1CFG = INT_TIM1CFG; 00133 INT_TIM1CFG = 0; 00134 ) 00135 } 00136 /*---------------------------------------------------------------------------*/ 00137 void rtimer_arch_enable_irq(void) 00138 { 00139 INT_TIM1CFG = saved_TIM1CFG; 00140 } 00141 /*---------------------------------------------------------------------------*/ 00142 rtimer_clock_t rtimer_arch_now(void) 00143 { 00144 return ((rtimer_clock_t)time_msb << 16)|TIM1_CNT; 00145 } 00146 00147 /*---------------------------------------------------------------------------*/ 00148 00149 void 00150 rtimer_arch_schedule(rtimer_clock_t t) 00151 { 00152 00153 PRINTF("rtimer_arch_schedule time %4x\r\n", /*((u32_t*)&t)+1,*/(u32_t)t); 00154 00155 next_rtimer_time = t; 00156 00157 rtimer_clock_t now = rtimer_arch_now(); 00158 00159 rtimer_clock_t clock_to_wait = t - now; 00160 00161 PRINTF("now %2x\r\n", TIM1_CNT); 00162 PRINTF("clock_to_wait %4x\r\n", clock_to_wait); 00163 00164 if(clock_to_wait <= 0x10000){ // We must set now the Timer Compare Register. 00165 00166 TIM1_CCR1 = (int16u)now + (int16u)clock_to_wait; 00167 INT_TIM1FLAG = INT_TIMCC1IF; 00168 INT_TIM1CFG |= INT_TIMCC1IF; // Compare 1 interrupt enable. 00169 00170 PRINTF("2-INT_TIM1FLAG %2x\r\n", INT_TIM1FLAG); 00171 00172 } 00173 // else compare register will be set at overflow interrupt closer to the rtimer event. 00174 00175 }