Contiki 2.6

rtimer-arch.c

Go to the documentation of this file.
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 uint32_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 uint16_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", /*((uint32_t*)&t)+1,*/(uint32_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 }