Contiki 2.6

clock.c

00001 /*
00002  * Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
00003  * to the MC1322x project (http://mc1322x.devl.org) and Contiki.
00004  *
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  * 2. Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in the
00014  *    documentation and/or other materials provided with the distribution.
00015  * 3. Neither the name of the Institute nor the names of its contributors
00016  *    may be used to endorse or promote products derived from this software
00017  *    without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00020  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00023  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00024  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00025  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00026  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00027  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00028  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00029  * SUCH DAMAGE.
00030  *
00031  * This file is part of the Contiki OS.
00032  *
00033  *
00034  */
00035 
00036 #include <sys/clock.h>
00037 #include <sys/cc.h>
00038 #include <sys/etimer.h>
00039 #include "dev/leds.h"
00040 
00041 #include "contiki-conf.h"
00042 #include "mc1322x.h"
00043 
00044 #include "contiki-conf.h"
00045 
00046 #define MAX_TICKS (~((clock_time_t)0) / 2)
00047 
00048 static volatile clock_time_t current_clock = 0;
00049 
00050 volatile unsigned long seconds = 0;
00051 
00052 #define TCF  15
00053 #define TCF1 4
00054 #define TCF2 5
00055 
00056 void
00057 clock_init()
00058 {
00059         /* timer setup */
00060         /* CTRL */
00061 #define COUNT_MODE 1      /* use rising edge of primary source */
00062 #define PRIME_SRC  0xf    /* Perip. clock with 128 prescale (for 24Mhz = 187500Hz)*/
00063 #define SEC_SRC    0      /* don't need this */
00064 #define ONCE       0      /* keep counting */
00065 #define LEN        1      /* count until compare then reload with value in LOAD */
00066 #define DIR        0      /* count up */
00067 #define CO_INIT    0      /* other counters cannot force a re-initialization of this counter */
00068 #define OUT_MODE   0      /* OFLAG is asserted while counter is active */
00069 
00070         *TMR_ENBL = 0;                     /* tmrs reset to enabled */
00071         *TMR0_SCTRL = 0;
00072         *TMR0_CSCTRL =0x0040;
00073         *TMR0_LOAD = 0;                    /* reload to zero */
00074         *TMR0_COMP_UP = 1875;             /* trigger a reload at the end */
00075         *TMR0_CMPLD1 = 1875;              /* compare 1 triggered reload level, 10HZ maybe? */
00076         *TMR0_CNTR = 0;                    /* reset count register */
00077         *TMR0_CTRL = (COUNT_MODE<<13) | (PRIME_SRC<<9) | (SEC_SRC<<7) | (ONCE<<6) | (LEN<<5) | (DIR<<4) | (CO_INIT<<3) | (OUT_MODE);
00078         *TMR_ENBL = 0xf;                   /* enable all the timers --- why not? */
00079 
00080         enable_irq(TMR);
00081 /* Do startup scan of the ADC */
00082 #if CLOCK_CONF_SAMPLEADC
00083         adc_reading[8]=0;
00084         adc_init();
00085         while (adc_reading[8]==0) adc_service();
00086 #endif
00087 }
00088 
00089 void tmr0_isr(void) {
00090         if(bit_is_set(*TMR(0,CSCTRL),TCF1)) {
00091                 current_clock++;
00092                 if((current_clock % CLOCK_CONF_SECOND) == 0) {
00093                         seconds++;
00094 #if BLINK_SECONDS
00095                         leds_toggle(LEDS_GREEN);
00096 #endif
00097 /* ADC can be serviced every tick or every second */
00098 #if CLOCK_CONF_SAMPLEADC > 1
00099                         adc_service();
00100 #endif
00101                 }
00102 #if CLOCK_CONF_SAMPLEADC == 1
00103                 adc_service();
00104 #endif
00105                 if(etimer_pending() &&
00106                    (etimer_next_expiration_time() - current_clock - 1) > MAX_TICKS) {
00107                         etimer_request_poll();
00108                 }
00109 
00110 
00111                 /* clear the compare flags */
00112                 clear_bit(*TMR(0,SCTRL),TCF);
00113                 clear_bit(*TMR(0,CSCTRL),TCF1);
00114                 clear_bit(*TMR(0,CSCTRL),TCF2);
00115                 return;
00116         } else {
00117                 /* this timer didn't create an interrupt condition */
00118                 return;
00119         }
00120 }
00121 
00122 clock_time_t
00123 clock_time(void)
00124 {
00125   return current_clock;
00126 }
00127 
00128 unsigned long
00129 clock_seconds(void)
00130 {
00131         return seconds;
00132 }
00133 
00134 void
00135 clock_wait(clock_time_t t)
00136 {
00137   clock_time_t endticks = current_clock + t;
00138   while ((signed long)(current_clock - endticks) < 0) {;}
00139 }
00140 /*---------------------------------------------------------------------------*/
00141 /**
00142  * Delay the CPU for up to 65535 microseconds.
00143  * Use the 250KHz MACA clock for longer delays to avoid interrupt effects.
00144  * However that can't be used if the radio is being power cycled!
00145  */
00146 void
00147 clock_delay_usec(uint16_t howlong)
00148 {
00149   if(howlong<2) return;
00150 #if 0
00151   if(howlong>400) {
00152     volatile register uint32_t i=*MACA_CLK+howlong/4;
00153     while (i > *MACA_CLK) ;
00154     return;
00155   }
00156 #endif
00157    /* These numbers at 25MHz, gcc -Os */
00158     volatile register uint32_t i=4000*howlong/2301;
00159     while(--i);
00160 }
00161 /*---------------------------------------------------------------------------*/
00162 /**
00163  * Delay the CPU for up to 65535 milliseconds. The watchdog is NOT disabled.
00164  */
00165 void
00166 clock_delay_msec(uint16_t howlong)
00167 {
00168   while(howlong--) clock_delay_usec(1000);
00169 }
00170 /*---------------------------------------------------------------------------*/
00171 /**
00172  * Legacy delay. The original clock_delay for the msp430 used a granularity
00173  * of 2.83 usec. This approximates that delay for values up to 1456 usec.
00174  * (The largest core call in leds.c uses 400).
00175  */
00176 void
00177 clock_delay(unsigned int howlong)
00178 {
00179   if(howlong--) return;
00180   clock_delay_usec((283*howlong)/100);
00181 }
00182 /*---------------------------------------------------------------------------*/
00183 /**
00184  * Adjust clock ticks after a cpu sleep.
00185  */
00186 void clock_adjust_ticks(clock_time_t howmany) {
00187 /* Add seconds */
00188         seconds+=howmany/CLOCK_CONF_SECOND;
00189 /* Handle tick overflow */
00190         if(((current_clock % CLOCK_CONF_SECOND) + (howmany % CLOCK_CONF_SECOND)) >= CLOCK_CONF_SECOND) seconds++;
00191 /* Add ticks */
00192         current_clock+=howmany;
00193 }