Contiki 3.x
clock.c
1 /*
2  * Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
3  * to the MC1322x project (http://mc1322x.devl.org) and Contiki.
4  *
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the Institute nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * This file is part of the Contiki OS.
32  *
33  *
34  */
35 
36 #include <sys/clock.h>
37 #include <sys/cc.h>
38 #include <sys/etimer.h>
39 #include <sys/rtimer.h>
40 
41 #include "contiki-conf.h"
42 #include "mc1322x.h"
43 
44 #define MAX_TICKS (~((clock_time_t)0) / 2)
45 
46 static volatile clock_time_t current_clock = 0;
47 
48 volatile unsigned long seconds = 0;
49 
50 static struct rtimer rt_clock;
51 
52 /* the typical clock things like incrementing current_clock and etimer checks */
53 /* are performed as a periodically scheduled rtimer */
54 void
55 rt_do_clock(struct rtimer *t, void *ptr)
56 {
57  rtimer_set(t, RTIMER_TIME(t) + (rtc_freq/CLOCK_CONF_SECOND) , 1,
58  (rtimer_callback_t)rt_do_clock, ptr);
59 
60  current_clock++;
61 
62  if((current_clock % CLOCK_CONF_SECOND) == 0) {
63  seconds++;
64  }
65 
66  if(etimer_pending() &&
67  (etimer_next_expiration_time() - current_clock - 1) > MAX_TICKS) {
69  }
70 
71 }
72 
73 
74 /* RTC MUST have been already setup by mc1322x init */
75 void
77 {
78  rtimer_set(&rt_clock, RTIMER_NOW() + rtc_freq/CLOCK_CONF_SECOND, 1, (rtimer_callback_t)rt_do_clock, NULL);
79 }
80 
81 clock_time_t
83 {
84  return current_clock;
85 }
86 
87 unsigned long
89 {
90  return seconds;
91 }
92 
93 void
94 clock_set_seconds(unsigned long sec)
95 {
96  seconds = sec;
97 }
98 
99 void
100 clock_wait(clock_time_t t)
101 {
102  clock_time_t endticks = current_clock + t;
103  while ((signed long)(current_clock - endticks) < 0) {;}
104 }
105 /*---------------------------------------------------------------------------*/
106 /*
107  * Delay the CPU for up to 65535 microseconds.
108  * Use the 250KHz MACA clock for longer delays to avoid interrupt effects.
109  * However that can't be used if the radio is being power cycled!
110  */
111 void
112 clock_delay_usec(uint16_t howlong)
113 {
114  if(howlong<2) return;
115 #if 0
116  if(howlong>400) {
117  volatile register uint32_t i=*MACA_CLK+howlong/4;
118  while (i > *MACA_CLK) ;
119  return;
120  }
121 #endif
122  /* These numbers at 25MHz, gcc -Os */
123  volatile register uint32_t i=4000*howlong/2301;
124  while(--i);
125 }
126 /*---------------------------------------------------------------------------*/
127 /*
128  * Delay the CPU for up to 65535 milliseconds. The watchdog is NOT disabled.
129  */
130 void
131 clock_delay_msec(uint16_t howlong)
132 {
133  while(howlong--) clock_delay_usec(1000);
134 }
135 /*---------------------------------------------------------------------------*/
136 /*
137  * Legacy delay. The original clock_delay for the msp430 used a granularity
138  * of 2.83 usec. This approximates that delay for values up to 1456 usec.
139  * (The largest core call in leds.c uses 400).
140  */
141 void
142 clock_delay(unsigned int howlong)
143 {
144  if(howlong--) return;
145  clock_delay_usec((283*howlong)/100);
146 }
147 /*---------------------------------------------------------------------------*/
148 /*
149  * Adjust clock ticks after a cpu sleep.
150  */
151 void clock_adjust_ticks(clock_time_t howmany) {
152 /* Add seconds */
153  seconds+=howmany/CLOCK_CONF_SECOND;
154 /* Handle tick overflow */
155  if(((current_clock % CLOCK_CONF_SECOND) + (howmany % CLOCK_CONF_SECOND)) >= CLOCK_CONF_SECOND) seconds++;
156 /* Add ticks */
157  current_clock+=howmany;
158 }
Header file for the real-time timer module.
clock_time_t etimer_next_expiration_time(void)
Get next event timer expiration time.
Definition: etimer.c:237
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:135
void etimer_request_poll(void)
Make the event timer aware that the clock has changed.
Definition: etimer.c:145
int etimer_pending(void)
Check if there are any non-expired event timers.
Definition: etimer.c:231
clock_time_t clock_time(void)
Get the current clock time.
Definition: clock.c:41
Default definitions of C compiler quirk work-arounds.
void clock_init()
Initialize the clock library.
Definition: clock.c:76
void clock_delay_msec(uint16_t howlong)
Delay up to 65535 milliseconds.
Definition: clock.c:260
#define NULL
The null pointer.
int rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, rtimer_callback_t func, void *ptr)
Post a real-time task.
Definition: rtimer.c:67
void clock_delay(unsigned int i)
Obsolete delay function but we implement it here since some code still uses it.
Definition: clock.c:170
Event timer header file.
void clock_wait(clock_time_t i)
Wait for a given number of ticks.
Definition: clock.c:162
unsigned long clock_seconds(void)
Get the current value of the platform seconds.
Definition: clock.c:54
void clock_adjust_ticks(clock_time_t howmany)
Adjust the system current clock time.
Definition: clock.c:289
Representation of a real-time task.
Definition: rtimer.h:86
void clock_delay_usec(uint16_t usec)
Delay a given number of microseconds.
Definition: clock.c:94
#define RTIMER_TIME(task)
Get the time that a task last was executed.
Definition: rtimer.h:148
void clock_set_seconds(unsigned long sec)
Set the value of the platform seconds.
Definition: clock.c:147