Contiki 2.5
contiki-crm.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 "mc1322x.h"
37 
38 #define CRM_DEBUG 1
39 #if CRM_DEBUG
40 #define PRINTF(...) printf(__VA_ARGS__)
41 #else
42 #define PRINTF(...)
43 #endif
44 
45 uint32_t cal_rtc_secs; /* calibrated 2khz rtc seconds */
46 
47 void sleep(uint32_t opts, uint32_t mode)
48 {
49 
50  /* the maca must be off before going to sleep */
51  /* otherwise the mcu will reboot on wakeup */
52 // maca_off();
53  *CRM_SLEEP_CNTL = opts;
54  *CRM_SLEEP_CNTL = (opts | mode);
55 
56  /* wait for the sleep cycle to complete */
57  while(!bit_is_set(*CRM_STATUS,0)) { continue; }
58  /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and powers down */
59  set_bit(*CRM_STATUS,0);
60 
61  /* now we are asleep */
62  /* and waiting for something to wake us up */
63  /* you did tell us how to wake up right? */
64 
65  /* waking up */
66  while(!bit_is_set(*CRM_STATUS,0)) { continue; }
67  /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and finishes the wakeup */
68  set_bit(*CRM_STATUS,0);
69 
70  /* you may also need to do other recovery */
71  /* such as interrupt handling */
72  /* peripheral init */
73  /* and turning the radio back on */
74 
75 }
76 
77 /* turn on the 32kHz crystal */
78 /* once you start the 32xHz crystal it can only be stopped with a reset (hard or soft) */
79 void enable_32khz_xtal(void)
80 {
81  static volatile uint32_t rtc_count;
82  PRINTF("enabling 32kHz crystal\n\r");
83  /* first, disable the ring osc */
84  ring_osc_off();
85  /* enable the 32kHZ crystal */
86  xtal32_on();
87 
88  /* set the XTAL32_EXISTS bit */
89  /* the datasheet says to do this after you've check that RTC_COUNT is changing */
90  /* the datasheet is not correct */
91  xtal32_exists();
92 
93  /* now check that the crystal starts */
94  /* this blocks until it starts */
95  /* it would be better to timeout and return an error */
96  rtc_count = *CRM_RTC_COUNT;
97  PRINTF("waiting for xtal\n\r");
98  while(*CRM_RTC_COUNT == rtc_count) {
99  continue;
100  }
101  /* RTC has started up */
102  PRINTF("32kHZ xtal started\n\r");
103 
104 }
105 
106 void cal_ring_osc(void)
107 {
108  uint32_t cal_factor;
109  PRINTF("performing ring osc cal\n\r");
110  PRINTF("crm_status: 0x%0x\n\r",*CRM_STATUS);
111  PRINTF("sys_cntl: 0x%0x\n\r",*CRM_SYS_CNTL);
112  *CRM_CAL_CNTL = (1<<16) | (20000);
113  while((*CRM_STATUS & (1<<9)) == 0);
114  PRINTF("ring osc cal complete\n\r");
115  PRINTF("cal_count: 0x%0x\n\r",*CRM_CAL_COUNT);
116  cal_factor = (REF_OSC*1000) / *CRM_CAL_COUNT;
117  cal_rtc_secs = (NOMINAL_RING_OSC_SEC * cal_factor)/100;
118  PRINTF("cal factor: %d\n\r", cal_factor);
119  PRINTF("hib_wake_secs: %d\n\r", cal_rtc_secs);
120  set_bit(*CRM_STATUS,9);
121 }