Contiki 3.x
rtimer-arch.c
Go to the documentation of this file.
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 /**
37  * \file
38  * mc1322x-specific rtimer code
39  * \author
40  * Mariano Alvira <mar@devl.org>
41  */
42 
43 #include <signal.h>
44 
45 /* contiki */
46 #include "sys/energest.h"
47 #include "sys/rtimer.h"
48 
49 /* mc1322x */
50 #include "utils.h"
51 
52 #define DEBUG 0
53 #if DEBUG
54 #include <stdio.h>
55 #define PRINTF(...) printf(__VA_ARGS__)
56 #else
57 #define PRINTF(...)
58 #endif
59 
60 static uint32_t last_rtc;
61 
62 void
63 rtc_isr(void)
64 {
65  /* see note in table 5-13 of the reference manual: it takes at least two RTC clocks for the EVT bit to clear */
66  if ((CRM->RTC_COUNT - last_rtc) <= 2) {
67  CRM->STATUS = ~0; /* Clear all events */
68 
69 // CRM->STATUSbits.RTC_WU_EVT = 1;
70  return;
71  }
72 
73  last_rtc = CRM->RTC_COUNT;
74 
75  /* Clear all events (for paranoia) */
76  /* clear RTC event flag (for paranoia)*/
77 // CRM->STATUSbits.RTC_WU_EVT = 1;
78  CRM->STATUS = ~0;
79 
81 
82 }
83 
84 void
86 {
87  last_rtc = CRM->RTC_COUNT;
88  /* enable timeout interrupts */
89  /* RTC WU is the periodic RTC timer */
90  /* TIMER WU is the wakeup timers (clocked from the RTC source) */
91  /* it does not appear you can have both enabled at the same time */
92  CRM->WU_CNTLbits.RTC_WU_EN = 1;
93  CRM->WU_CNTLbits.RTC_WU_IEN = 1;
94  enable_irq(CRM);
95 }
96 
97 void
98 rtimer_arch_schedule(rtimer_clock_t t)
99 {
100  volatile uint32_t now;
101  now = rtimer_arch_now();
102  PRINTF("rtimer_arch_schedule time %u; now is %u\n", t, now);
103 
104 /* Immediate interrupt if specified time is before current time. This may also
105  happen on counter overflow. */
106  if(now > t) {
107  CRM->RTC_TIMEOUT = 1;
108  } else {
109  CRM->RTC_TIMEOUT = t - now;
110  }
111 }
112 
113 void
114 rtimer_arch_sleep(rtimer_clock_t howlong)
115 {
116  CRM->WU_CNTLbits.TIMER_WU_EN = 1;
117  CRM->WU_CNTLbits.RTC_WU_EN = 0;
118  CRM->WU_TIMEOUT = howlong;
119 
120  /* the maca must be off before going to sleep */
121  /* otherwise the mcu will reboot on wakeup */
122  maca_off();
123 
124  CRM->SLEEP_CNTLbits.DOZE = 0;
125  CRM->SLEEP_CNTLbits.RAM_RET = 3;
126  CRM->SLEEP_CNTLbits.MCU_RET = 1;
127  CRM->SLEEP_CNTLbits.DIG_PAD_EN = 1;
128  CRM->SLEEP_CNTLbits.HIB = 1;
129 
130  /* wait for the sleep cycle to complete */
131  while((*CRM_STATUS & 0x1) == 0) { continue; }
132  /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and powers down */
133  *CRM_STATUS = 1;
134 
135  /* asleep */
136 
137  /* wait for the awake cycle to complete */
138  while((*CRM_STATUS & 0x1) == 0) { continue; }
139  /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and finishes wakeup */
140  *CRM_STATUS = 1;
141 
142  CRM->WU_CNTLbits.TIMER_WU_EN = 0;
143  CRM->WU_CNTLbits.RTC_WU_EN = 1;
144 
145  /* reschedule clock ticks */
146  clock_init();
147  clock_adjust_ticks((CRM->WU_COUNT*CLOCK_CONF_SECOND)/rtc_freq);
148 }
149 
150 
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
void clock_init(void)
Initialize the clock library.
Definition: clock.c:76
#define rtimer_arch_now()
Definition: rtimer-arch.h:40
Header file for the energy estimation mechanism
void clock_adjust_ticks(clock_time_t howmany)
Adjust the system current clock time.
Definition: clock.c:289
Header file for the real-time timer module.
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