00001 /* 00002 * Copyright (c) 2009, University of Colombo School of Computing 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 * @(#)$$ 00032 */ 00033 00034 #include "sys/clock.h" 00035 #include "sys/etimer.h" 00036 00037 #include <avr/io.h> 00038 #include <avr/interrupt.h> 00039 00040 static volatile clock_time_t count, scount; 00041 static volatile unsigned long seconds; 00042 00043 /*---------------------------------------------------------------------------*/ 00044 ISR(TIMER0_COMP_vect) 00045 { 00046 count++; 00047 if(++scount == CLOCK_SECOND) { 00048 scount = 0; 00049 seconds++; 00050 } 00051 if(etimer_pending()) { 00052 etimer_request_poll(); 00053 } 00054 } 00055 00056 /*---------------------------------------------------------------------------*/ 00057 void 00058 clock_init(void) 00059 { 00060 /* Disable interrupts*/ 00061 cli(); 00062 00063 /* Disable compare match interrupts and overflow interrupts. */ 00064 TIMSK &= ~( _BV(TOIE0) | _BV(OCIE0) ); 00065 00066 /** 00067 * set Timer/Counter0 to be asynchronous 00068 * from the CPU clock with a second external 00069 * clock(32,768kHz) driving it. 00070 */ 00071 ASSR |= _BV(AS0); 00072 00073 /* 00074 * Set timer control register: 00075 * - prescale: 32 (CS00 and CS01) 00076 * - counter reset via comparison register (WGM01) 00077 */ 00078 TCCR0 = _BV(CS00) | _BV(CS01) | _BV(WGM01); 00079 00080 /* Set counter to zero */ 00081 TCNT0 = 0; 00082 00083 /* 00084 * 128 clock ticks per second. 00085 * 32,768 = 32 * 8 * 128 00086 */ 00087 OCR0 = 8; 00088 00089 /* Clear interrupt flag register */ 00090 TIFR = 0x00; 00091 00092 /** 00093 * Wait for TCN0UB, OCR0UB, and TCR0UB. 00094 * 00095 */ 00096 while(ASSR & 0x07); 00097 00098 /* Raise interrupt when value in OCR0 is reached. */ 00099 TIMSK |= _BV(OCIE0); 00100 00101 count = 0; 00102 00103 /* enable all interrupts*/ 00104 sei(); 00105 00106 } 00107 /*---------------------------------------------------------------------------*/ 00108 clock_time_t 00109 clock_time(void) 00110 { 00111 clock_time_t tmp; 00112 do { 00113 tmp = count; 00114 } while(tmp != count); 00115 return tmp; 00116 } 00117 /*---------------------------------------------------------------------------*/ 00118 /** 00119 * Delay the CPU for a multiple of TODO 00120 */ 00121 void 00122 clock_delay(unsigned int i) 00123 { 00124 for (; i > 0; i--) { /* Needs fixing XXX */ 00125 unsigned j; 00126 for (j = 50; j > 0; j--) 00127 asm volatile("nop"); 00128 } 00129 } 00130 00131 /*---------------------------------------------------------------------------*/ 00132 /** 00133 * Wait for a multiple of 1 / 128 sec = 7.8125 ms. 00134 * 00135 */ 00136 void 00137 clock_wait(int i) 00138 { 00139 clock_time_t start; 00140 00141 start = clock_time(); 00142 while(clock_time() - start < (clock_time_t)i); 00143 } 00144 /*---------------------------------------------------------------------------*/ 00145 void 00146 clock_set_seconds(unsigned long sec) 00147 { 00148 // TODO 00149 } 00150 /*---------------------------------------------------------------------------*/ 00151 unsigned long 00152 clock_seconds(void) 00153 { 00154 unsigned long tmp; 00155 do { 00156 tmp = seconds; 00157 } while(tmp != seconds); 00158 return tmp; 00159 } 00160 /*---------------------------------------------------------------------------*/