Contiki-NG
Toggle main menu visibility
Loading...
Searching...
No Matches
clock.c
1
/*
2
* Copyright (c) 2011, Swedish Institute of Computer Science
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. Neither the name of the Institute nor the names of its contributors
14
* may be used to endorse or promote products derived from this software
15
* without specific prior written permission.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*
29
* This file is part of the Contiki operating system.
30
*/
31
32
#include "contiki.h"
33
#include "sys/clock.h"
34
#include "
sys/etimer.h
"
35
#include "
sys/energest.h
"
36
#include "rtimer-arch.h"
37
#include "dev/watchdog.h"
38
#include "isr_compat.h"
39
40
#define INTERVAL (RTIMER_ARCH_SECOND / CLOCK_SECOND)
41
42
#define MAX_TICKS (~((clock_time_t)0) / 2)
43
44
#define HW_CLOCK_LT(a, b) ((int16_t)((a)-(b)) < 0)
45
46
static
volatile
unsigned
long
seconds;
47
48
static
volatile
clock_time_t
count
= 0;
49
/* last_tar is used for calculating clock_fine, last_ccr might be better? */
50
static
volatile
uint16_t last_tar = 0;
51
/*---------------------------------------------------------------------------*/
52
static
inline
uint16_t
53
read_tar(
void
)
54
{
55
/* Same as clock_counter(), but can be inlined */
56
uint16_t t1, t2;
57
do
{
58
t1 = TA1R;
59
t2 = TA1R;
60
}
while
(t1 != t2);
61
return
t1;
62
}
63
/*---------------------------------------------------------------------------*/
64
ISR(TIMER1_A1, timera1)
65
{
66
/* watchdog_start(); */
67
68
if
(TA1IV == 2) {
69
70
/* HW timer bug fix: Interrupt handler called before TR==CCR.
71
* Occurs when timer state is toggled between STOP and CONT. */
72
while
(TA1CTL & MC1 && TA1CCR1 - TA1R == 1);
73
74
last_tar = read_tar();
75
/* Make sure interrupt time is future */
76
while
(!HW_CLOCK_LT(last_tar, TA1CCR1)) {
77
TA1CCR1 += INTERVAL;
78
++
count
;
79
80
/* Make sure the CLOCK_CONF_SECOND is a power of two, to ensure
81
that the modulo operation below becomes a logical and and not
82
an expensive divide. Algorithm from Wikipedia:
83
http://en.wikipedia.org/wiki/Power_of_two */
84
#if (CLOCK_CONF_SECOND & (CLOCK_CONF_SECOND - 1)) != 0
85
#error CLOCK_CONF_SECOND must be a power of two (i.e., 1, 2, 4, 8, 16, 32, 64, ...).
86
#error Change CLOCK_CONF_SECOND in contiki-conf.h.
87
#endif
88
if
(
count
% CLOCK_CONF_SECOND == 0) {
89
++seconds;
90
energest_flush();
91
}
92
last_tar = read_tar();
93
}
94
95
if
(
etimer_pending
() &&
96
(
etimer_next_expiration_time
() -
count
- 1) > MAX_TICKS) {
97
etimer_request_poll
();
98
LPM4_EXIT;
99
}
100
101
}
102
/* if(process_nevents() >= 0) {
103
LPM4_EXIT;
104
}*/
105
106
/* watchdog_stop(); */
107
}
108
/*---------------------------------------------------------------------------*/
109
clock_time_t
110
clock_time
(
void
)
111
{
112
clock_time_t t1, t2;
113
do
{
114
t1 =
count
;
115
t2 =
count
;
116
}
while
(t1 != t2);
117
return
t1;
118
}
119
/*---------------------------------------------------------------------------*/
120
void
121
clock_set(clock_time_t clock, clock_time_t fclock)
122
{
123
TA1R = fclock;
124
TA1CCR1 = fclock + INTERVAL;
125
count
= clock;
126
}
127
/*---------------------------------------------------------------------------*/
128
int
129
clock_fine_max
(
void
)
130
{
131
return
INTERVAL;
132
}
133
/*---------------------------------------------------------------------------*/
134
unsigned
short
135
clock_fine(
void
)
136
{
137
unsigned
short
t;
138
/* Assign last_tar to local varible that can not be changed by interrupt */
139
t = last_tar;
140
/* perform calc based on t, TAR will not be changed during interrupt */
141
return
(
unsigned
short
) (TA1R - t);
142
}
143
/*---------------------------------------------------------------------------*/
144
void
145
clock_init
(
void
)
146
{
147
dint();
148
149
/* Select SMCLK (2.4576MHz), clear TAR */
150
/* TACTL = TASSEL1 | TACLR | ID_3; */
151
152
/* Select ACLK 32768Hz clock, divide by 2 */
153
/* TA1CTL = TASSEL0 | TACLR | ID_1; */
154
155
#if INTERVAL==32768/CLOCK_SECOND
156
TA1CTL = TASSEL0 | TACLR;
157
#elif INTERVAL==16384/CLOCK_SECOND
158
TA1CTL = TASSEL0 | TACLR | ID_1;
159
#else
160
#error NEED TO UPDATE clock.c to match interval!
161
#endif
162
163
/* Initialize ccr1 to create the X ms interval. */
164
/* CCR1 interrupt enabled, interrupt occurs when timer equals CCR1. */
165
TA1CCTL1 = CCIE;
166
167
/* Interrupt after X ms. */
168
TA1CCR1 = INTERVAL;
169
170
/* Start Timer_A in continuous mode. */
171
TA1CTL |= MC1;
172
173
count
= 0;
174
175
/* Enable interrupts. */
176
eint();
177
178
}
179
/*---------------------------------------------------------------------------*/
180
/**
181
* Delay the CPU for a multiple of 2.83 us.
182
*/
183
void
184
clock_delay
(
unsigned
int
i)
185
{
186
while
(i--) {
187
_NOP();
188
}
189
}
190
/*---------------------------------------------------------------------------*/
191
/*
192
* Wait for a multiple of 10 ms.
193
*
194
*/
195
void
196
clock_wait
(clock_time_t i)
197
{
198
clock_time_t
start
;
199
200
start
=
clock_time
();
201
while
(
clock_time
() -
start
< (clock_time_t)i);
202
}
203
/*---------------------------------------------------------------------------*/
204
void
205
clock_set_seconds
(
unsigned
long
sec)
206
{
207
int
s;
208
s = splhigh();
209
seconds = sec;
210
splx(s);
211
}
212
/*---------------------------------------------------------------------------*/
213
unsigned
long
214
clock_seconds
(
void
)
215
{
216
unsigned
long
t1, t2;
217
do
{
218
t1 = seconds;
219
t2 = seconds;
220
}
while
(t1 != t2);
221
return
t1;
222
}
223
/*---------------------------------------------------------------------------*/
224
rtimer_clock_t
225
clock_counter(
void
)
226
{
227
rtimer_clock_t t1, t2;
228
do
{
229
t1 = TA1R;
230
t2 = TA1R;
231
}
while
(t1 != t2);
232
return
t1;
233
}
234
/*---------------------------------------------------------------------------*/
energest.h
Header file for the energy estimation mechanism.
etimer.h
Event timer header file.
clock_set_seconds
void clock_set_seconds(unsigned long sec)
Set the value of the platform seconds.
Definition
clock.c:124
clock_seconds
unsigned long clock_seconds(void)
Get the current value of the platform seconds.
Definition
clock.c:130
clock_init
void clock_init(void)
Arch-specific implementation of clock_init for the cc2538.
Definition
clock.c:93
clock_wait
void clock_wait(clock_time_t i)
Wait for a given number of ticks.
Definition
clock.c:136
clock_time
clock_time_t clock_time(void)
Get the current clock time.
Definition
clock.c:118
clock_delay
void clock_delay(unsigned int i)
Obsolete delay function but we implement it here since some code still uses it.
Definition
clock.c:164
count
static volatile uint64_t count
Num.
Definition
clock.c:50
clock_fine_max
int clock_fine_max(void)
Deprecated platform-specific routines.
Definition
clock.c:129
etimer_pending
int etimer_pending(void)
Check if there are any non-expired event timers.
Definition
etimer.c:225
etimer_request_poll
void etimer_request_poll(void)
Make the event timer aware that the clock has changed.
Definition
etimer.c:145
etimer_next_expiration_time
clock_time_t etimer_next_expiration_time(void)
Get next event timer expiration time.
Definition
etimer.c:231
start
static void start(void)
Start measurement.
Definition
hdc-1000-sensor.c:142
arch
cpu
msp430
f5xxx
clock.c
Generated on
for Contiki-NG by
1.17.0