Contiki 3.x
rtimer-arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
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  *
14  * 3. Neither the name of the copyright holder nor the names of its
15  * contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29  * OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 /**
32  * \addtogroup cc2538-rtimer
33  * @{
34  *
35  * \file
36  * Implementation of the arch-specific rtimer functions for the cc2538
37  *
38  */
39 #include "contiki.h"
40 #include "sys/energest.h"
41 #include "sys/rtimer.h"
42 #include "dev/nvic.h"
43 #include "dev/smwdthrosc.h"
44 #include "cpu.h"
45 #include "lpm.h"
46 
47 #include <stdint.h>
48 /*---------------------------------------------------------------------------*/
49 static volatile rtimer_clock_t next_trigger;
50 /*---------------------------------------------------------------------------*/
51 /**
52  * \brief We don't need to explicitly initialise anything but this
53  * routine is required by the API.
54  *
55  * The Sleep Timer starts ticking automatically as soon as the device
56  * turns on. We don't need to turn on interrupts before the first call
57  * to rtimer_arch_schedule()
58  */
59 void
61 {
62  return;
63 }
64 /*---------------------------------------------------------------------------*/
65 /**
66  * \brief Schedules an rtimer task to be triggered at time t
67  * \param t The time when the task will need executed. This is an absolute
68  * time, in other words the task will be executed AT time \e t,
69  * not IN \e t ticks
70  */
71 void
72 rtimer_arch_schedule(rtimer_clock_t t)
73 {
74  rtimer_clock_t now;
75 
76  /* STLOAD must be 1 */
77  while((REG(SMWDTHROSC_STLOAD) & SMWDTHROSC_STLOAD_STLOAD) != 1);
78 
80 
81  now = RTIMER_NOW();
82 
83  /*
84  * New value must be 5 ticks in the future. The ST may tick once while we're
85  * writing the registers. We play it safe here and we add a bit of leeway
86  */
87  if((int32_t)(t - now) < 7) {
88  t = now + 7;
89  }
90 
91  /* ST0 latches ST[1:3] and must be written last */
92  REG(SMWDTHROSC_ST3) = (t >> 24) & 0x000000FF;
93  REG(SMWDTHROSC_ST2) = (t >> 16) & 0x000000FF;
94  REG(SMWDTHROSC_ST1) = (t >> 8) & 0x000000FF;
95  REG(SMWDTHROSC_ST0) = t & 0x000000FF;
96 
98 
99  /* Store the value. The LPM module will query us for it */
100  next_trigger = t;
101 
103 }
104 /*---------------------------------------------------------------------------*/
105 rtimer_clock_t
107 {
108  return next_trigger;
109 }
110 /*---------------------------------------------------------------------------*/
111 /**
112  * \brief Returns the current real-time clock time
113  * \return The current rtimer time in ticks
114  */
115 rtimer_clock_t
117 {
118  rtimer_clock_t rv;
119 
120  /* SMWDTHROSC_ST0 latches ST[1:3] and must be read first */
121  rv = REG(SMWDTHROSC_ST0);
122  rv |= (REG(SMWDTHROSC_ST1) << 8);
123  rv |= (REG(SMWDTHROSC_ST2) << 16);
124  rv |= (REG(SMWDTHROSC_ST3) << 24);
125 
126  return rv;
127 }
128 /*---------------------------------------------------------------------------*/
129 /**
130  * \brief The rtimer ISR
131  *
132  * Interrupts are only turned on when we have an rtimer task to schedule
133  * Once the interrupt fires, the task is called and then interrupts no
134  * longer get acknowledged until the next task needs scheduled.
135  */
136 void
138 {
139  /*
140  * If we were in PM1+, call the wake-up sequence first. This will make sure
141  * that the 32MHz OSC is selected as the clock source. We need to do this
142  * before calling the next rtimer_task, since the task may need the RF.
143  */
144  lpm_exit();
145 
146  ENERGEST_ON(ENERGEST_TYPE_IRQ);
147 
148  next_trigger = 0;
149 
152 
153  rtimer_run_next();
154 
155  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
156 }
157 /*---------------------------------------------------------------------------*/
158 /** @} */
Header file for the ARM Nested Vectored Interrupt Controller.
void nvic_interrupt_disable(uint32_t intr)
Disables interrupt intr.
Definition: nvic.c:71
void rtimer_arch_init(void)
We don&#39;t need to explicitly initialise anything but this routine is required by the API...
Definition: rtimer-arch.c:78
#define SMWDTHROSC_STLOAD_STLOAD
STx upload status signal.
Definition: smwdthrosc.h:89
void rtimer_isr()
The rtimer ISR.
Definition: rtimer-arch.c:137
Header file with prototypes for interrupt control on the cc2538 Cortex-M3 micro.
#define SMWDTHROSC_ST3
ST count/compare value 3.
Definition: smwdthrosc.h:54
#define lpm_exit()
Perform an &#39;Exit Deep Sleep&#39; sequence.
Definition: lpm.h:213
void nvic_interrupt_enable(uint32_t intr)
Enables interrupt intr.
Definition: nvic.c:64
#define NVIC_INT_SM_TIMER
SM Timer.
Definition: nvic.h:104
#define SMWDTHROSC_ST0
ST count/compare value 0.
Definition: smwdthrosc.h:51
#define SMWDTHROSC_ST2
ST count/compare value 2.
Definition: smwdthrosc.h:53
#define rtimer_arch_now()
Definition: rtimer-arch.h:40
Header file for the energy estimation mechanism
#define INTERRUPTS_ENABLE()
Enables all CPU interrupts.
Definition: cpu.h:55
#define SMWDTHROSC_STLOAD
Compare value load status.
Definition: smwdthrosc.h:55
void nvic_interrupt_unpend(uint32_t intr)
Sets intr to no longer pending.
Definition: nvic.c:106
Header file for the real-time timer module.
#define SMWDTHROSC_ST1
ST count/compare value 1.
Definition: smwdthrosc.h:52
#define INTERRUPTS_DISABLE()
Disables all CPU interrupts.
Definition: cpu.h:58
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:133
rtimer_clock_t rtimer_arch_next_trigger()
Get the time of the next scheduled rtimer trigger.
Definition: rtimer-arch.c:106
Header file with register declarations and bit masks for the cc2538 Sleep Timer and Watchdog...
void rtimer_arch_schedule(rtimer_clock_t t)
Schedules an rtimer task to be triggered at time t.
Definition: rtimer-arch.c:115
void rtimer_run_next(void)
Execute the next real-time task and schedule the next task, if any.
Definition: rtimer.c:92