Contiki-NG
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/rtimer.h"
41 #include "dev/nvic.h"
42 #include "dev/smwdthrosc.h"
43 #include "cpu.h"
44 #include "lpm.h"
45 
46 #include <stdint.h>
47 /*---------------------------------------------------------------------------*/
48 static volatile rtimer_clock_t next_trigger;
49 /*---------------------------------------------------------------------------*/
50 /**
51  * \brief We don't need to explicitly initialise anything but this
52  * routine is required by the API.
53  *
54  * The Sleep Timer starts ticking automatically as soon as the device
55  * turns on. We don't need to turn on interrupts before the first call
56  * to rtimer_arch_schedule()
57  */
58 void
60 {
61  return;
62 }
63 /*---------------------------------------------------------------------------*/
64 /**
65  * \brief Schedules an rtimer task to be triggered at time t
66  * \param t The time when the task will need executed. This is an absolute
67  * time, in other words the task will be executed AT time \e t,
68  * not IN \e t ticks
69  */
70 void
71 rtimer_arch_schedule(rtimer_clock_t t)
72 {
73  rtimer_clock_t now;
74 
75  /* STLOAD must be 1 */
76  while((REG(SMWDTHROSC_STLOAD) & SMWDTHROSC_STLOAD_STLOAD) != 1);
77 
79 
80  now = RTIMER_NOW();
81 
82  /*
83  * New value must be 5 ticks in the future. The ST may tick once while we're
84  * writing the registers. We play it safe here and we add a bit of leeway
85  */
86  if((int32_t)(t - now) < 7) {
87  t = now + 7;
88  }
89 
90  /* ST0 latches ST[1:3] and must be written last */
91  REG(SMWDTHROSC_ST3) = (t >> 24) & 0x000000FF;
92  REG(SMWDTHROSC_ST2) = (t >> 16) & 0x000000FF;
93  REG(SMWDTHROSC_ST1) = (t >> 8) & 0x000000FF;
94  REG(SMWDTHROSC_ST0) = t & 0x000000FF;
95 
97 
98  /* Store the value. The LPM module will query us for it */
99  next_trigger = t;
100 
102 }
103 /*---------------------------------------------------------------------------*/
104 rtimer_clock_t
106 {
107  return next_trigger;
108 }
109 /*---------------------------------------------------------------------------*/
110 /**
111  * \brief Returns the current real-time clock time
112  * \return The current rtimer time in ticks
113  */
114 rtimer_clock_t
116 {
117  rtimer_clock_t rv;
118 
119  /* SMWDTHROSC_ST0 latches ST[1:3] and must be read first */
120  rv = REG(SMWDTHROSC_ST0);
121  rv |= (REG(SMWDTHROSC_ST1) << 8);
122  rv |= (REG(SMWDTHROSC_ST2) << 16);
123  rv |= (REG(SMWDTHROSC_ST3) << 24);
124 
125  return rv;
126 }
127 /*---------------------------------------------------------------------------*/
128 /**
129  * \brief The rtimer ISR
130  *
131  * Interrupts are only turned on when we have an rtimer task to schedule
132  * Once the interrupt fires, the task is called and then interrupts no
133  * longer get acknowledged until the next task needs scheduled.
134  */
135 void
137 {
138  /*
139  * If we were in PM1+, call the wake-up sequence first. This will make sure
140  * that the 32MHz OSC is selected as the clock source. We need to do this
141  * before calling the next rtimer_task, since the task may need the RF.
142  */
143  lpm_exit();
144 
145  next_trigger = 0;
146 
149 
150  rtimer_run_next();
151 }
152 /*---------------------------------------------------------------------------*/
153 /** @} */
#define SMWDTHROSC_STLOAD
Compare value load status.
Definition: smwdthrosc.h:55
Header file for the ARM Nested Vectored Interrupt Controller.
#define SMWDTHROSC_STLOAD_STLOAD
STx upload status signal.
Definition: smwdthrosc.h:89
rtimer_clock_t rtimer_arch_now()
Returns the current real-time clock time.
Definition: rtimer-arch.c:115
SM Timer Interrupt.
Definition: cc2538_cm3.h:113
#define SMWDTHROSC_ST0
ST count/compare value 0.
Definition: smwdthrosc.h:51
Header file with register, macro and function declarations for the cc2538 low power module...
#define INTERRUPTS_DISABLE()
Disables all CPU interrupts.
Definition: cpu.h:54
#define SMWDTHROSC_ST2
ST count/compare value 2.
Definition: smwdthrosc.h:53
void rtimer_arch_schedule(rtimer_clock_t t)
Schedules an rtimer task to be triggered at time t.
Definition: rtimer-arch.c:71
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
Disable External Interrupt.
Definition: core_cm0.h:653
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:59
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:160
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
Enable External Interrupt.
Definition: core_cm0.h:642
void rtimer_run_next(void)
Execute the next real-time task and schedule the next task, if any.
Definition: rtimer.c:92
#define INTERRUPTS_ENABLE()
Enables all CPU interrupts.
Definition: cpu.h:51
rtimer_clock_t rtimer_arch_next_trigger()
Get the time of the next scheduled rtimer trigger.
Definition: rtimer-arch.c:105
Header file for the real-time timer module.
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
Clear Pending Interrupt.
Definition: core_cm0.h:688
void rtimer_isr()
The rtimer ISR.
Definition: rtimer-arch.c:136
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
Header file with register declarations and bit masks for the cc2538 Sleep Timer and Watchdog...
#define SMWDTHROSC_ST1
ST count/compare value 1.
Definition: smwdthrosc.h:52