00001 /* 00002 * Copyright (c) 2007, Swedish Institute of Computer Science. 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 copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 * $Id: rtimer-arch.c,v 1.10 2010/02/28 21:29:19 dak664 Exp $ 00032 */ 00033 00034 /** 00035 * \file 00036 * AVR-specific rtimer code 00037 * Currently only works on ATMEGAs that have Timer 3. 00038 * \author 00039 * Fredrik Osterlind <fros@sics.se> 00040 * Joakim Eriksson <joakime@sics.se> 00041 */ 00042 00043 /* OBS: 8 seconds maximum time! */ 00044 00045 #include <avr/io.h> 00046 #include <avr/interrupt.h> 00047 #include <stdio.h> 00048 00049 #include "sys/energest.h" 00050 #include "sys/rtimer.h" 00051 #include "rtimer-arch.h" 00052 00053 #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284P__) 00054 //#error FTH081029 test timer 3 00055 #define ETIMSK TIMSK3 00056 #define ETIFR TIFR3 00057 #define TICIE3 ICIE3 00058 00059 //Has no 'C', so we just set it to B. The code doesn't really use C so this 00060 //is safe to do but lets it compile. Probably should enable the warning if 00061 //it is ever used on other platforms. 00062 //#warning no OCIE3C in timer3 architecture, hopefully it won't be needed! 00063 00064 #define OCIE3C OCIE3B 00065 #define OCF3C OCF3B 00066 #endif 00067 00068 #if defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega128RFA1__) 00069 #define ETIMSK TIMSK3 00070 #define ETIFR TIFR3 00071 #define TICIE3 ICIE3 00072 #endif 00073 /*---------------------------------------------------------------------------*/ 00074 #ifdef TCNT3 00075 ISR (TIMER3_COMPA_vect) { 00076 ENERGEST_ON(ENERGEST_TYPE_IRQ); 00077 00078 ETIMSK &= ~((1 << OCIE3A) | (1 << OCIE3B) | (1 << TOIE3) | 00079 (1 << TICIE3) | (1 << OCIE3C)); 00080 00081 /* Call rtimer callback */ 00082 rtimer_run_next(); 00083 00084 ENERGEST_OFF(ENERGEST_TYPE_IRQ); 00085 } 00086 00087 #else 00088 #error "No Timer3 in rtimer-arch.c" 00089 00090 #endif 00091 /*---------------------------------------------------------------------------*/ 00092 void 00093 rtimer_arch_init(void) 00094 { 00095 /* Disable interrupts (store old state) */ 00096 uint8_t sreg; 00097 sreg = SREG; 00098 cli (); 00099 00100 #ifdef TCNT3 00101 /* Disable all timer functions */ 00102 ETIMSK &= ~((1 << OCIE3A) | (1 << OCIE3B) | (1 << TOIE3) | 00103 (1 << TICIE3) | (1 << OCIE3C)); 00104 /* Write 1s to clear existing timer function flags */ 00105 ETIFR |= (1 << ICF3) | (1 << OCF3A) | (1 << OCF3B) | (1 << TOV3) | 00106 (1 << OCF3C); 00107 00108 /* Default timer behaviour */ 00109 TCCR3A = 0; 00110 TCCR3B = 0; 00111 TCCR3C = 0; 00112 00113 /* Reset counter */ 00114 TCNT3 = 0; 00115 00116 /* Start clock, maximum prescaler */ 00117 TCCR3B |= 5; 00118 00119 #else 00120 #error "No Timer3 in rtimer-arch.c" 00121 00122 #endif 00123 00124 /* Restore interrupt state */ 00125 SREG = sreg; 00126 } 00127 /*---------------------------------------------------------------------------*/ 00128 void 00129 rtimer_arch_schedule(rtimer_clock_t t) 00130 { 00131 /* Disable interrupts (store old state) */ 00132 uint8_t sreg; 00133 sreg = SREG; 00134 cli (); 00135 00136 #ifdef TCNT3 00137 /* Set compare register */ 00138 OCR3A = t; 00139 /* Write 1s to clear all timer function flags */ 00140 ETIFR |= (1 << ICF3) | (1 << OCF3A) | (1 << OCF3B) | (1 << TOV3) | 00141 (1 << OCF3C); 00142 /* Enable interrupt on OCR3A match */ 00143 ETIMSK |= (1 << OCIE3A); 00144 00145 #else 00146 #error "No Timer3 in rtimer-arch.c" 00147 00148 #endif 00149 00150 /* Restore interrupt state */ 00151 SREG = sreg; 00152 }