Contiki 2.6

contiki-crm.c

00001 /*
00002  * Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
00003  * to the MC1322x project (http://mc1322x.devl.org) and Contiki.
00004  *
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  * 2. Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in the
00014  *    documentation and/or other materials provided with the distribution.
00015  * 3. Neither the name of the Institute nor the names of its contributors
00016  *    may be used to endorse or promote products derived from this software
00017  *    without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00020  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00023  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00024  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00025  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00026  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00027  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00028  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00029  * SUCH DAMAGE.
00030  *
00031  * This file is part of the Contiki OS.
00032  *
00033  *
00034  */
00035 
00036 #include "mc1322x.h"
00037 
00038 #define CRM_DEBUG 1
00039 #if CRM_DEBUG
00040 #define PRINTF(...) printf(__VA_ARGS__)
00041 #else
00042 #define PRINTF(...)
00043 #endif
00044 
00045 uint32_t cal_rtc_secs;      /* calibrated 2khz rtc seconds */
00046 
00047 void sleep(uint32_t opts, uint32_t mode)
00048 {
00049 
00050         /* the maca must be off before going to sleep */
00051         /* otherwise the mcu will reboot on wakeup */
00052 //      maca_off();
00053         *CRM_SLEEP_CNTL = opts;
00054         *CRM_SLEEP_CNTL = (opts | mode);
00055 
00056         /* wait for the sleep cycle to complete */
00057         while(!bit_is_set(*CRM_STATUS,0)) { continue; }
00058         /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and powers down */
00059         set_bit(*CRM_STATUS,0);
00060 
00061         /* now we are asleep */
00062         /* and waiting for something to wake us up */
00063         /* you did tell us how to wake up right? */
00064 
00065         /* waking up */
00066         while(!bit_is_set(*CRM_STATUS,0)) { continue; }
00067         /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and finishes the wakeup */
00068         set_bit(*CRM_STATUS,0);
00069 
00070         /* you may also need to do other recovery */
00071         /* such as interrupt handling */
00072         /* peripheral init */
00073         /* and turning the radio back on */
00074 
00075 }
00076 
00077 /* turn on the 32kHz crystal */
00078 /* once you start the 32xHz crystal it can only be stopped with a reset (hard or soft) */
00079 void enable_32khz_xtal(void) 
00080 {
00081         static volatile uint32_t rtc_count;
00082         PRINTF("enabling 32kHz crystal\n\r");
00083         /* first, disable the ring osc */
00084         ring_osc_off();
00085         /* enable the 32kHZ crystal */
00086         xtal32_on();
00087 
00088         /* set the XTAL32_EXISTS bit */
00089         /* the datasheet says to do this after you've check that RTC_COUNT is changing */
00090         /* the datasheet is not correct */
00091         xtal32_exists();
00092 
00093         /* now check that the crystal starts */
00094         /* this blocks until it starts */
00095         /* it would be better to timeout and return an error */
00096         rtc_count = *CRM_RTC_COUNT;
00097         PRINTF("waiting for xtal\n\r");
00098         while(*CRM_RTC_COUNT == rtc_count) {
00099                 continue;
00100         }
00101         /* RTC has started up */
00102         PRINTF("32kHZ xtal started\n\r");
00103 
00104 }
00105 
00106 void cal_ring_osc(void)
00107 {
00108         uint32_t cal_factor;
00109         PRINTF("performing ring osc cal\n\r");
00110         PRINTF("crm_status: 0x%0x\n\r",*CRM_STATUS);
00111         PRINTF("sys_cntl: 0x%0x\n\r",*CRM_SYS_CNTL); 
00112         *CRM_CAL_CNTL = (1<<16) | (20000); 
00113         while((*CRM_STATUS & (1<<9)) == 0);
00114         PRINTF("ring osc cal complete\n\r");
00115         PRINTF("cal_count: 0x%0x\n\r",*CRM_CAL_COUNT); 
00116         cal_factor = (REF_OSC*1000) / *CRM_CAL_COUNT;
00117         cal_rtc_secs = (NOMINAL_RING_OSC_SEC * cal_factor)/100;
00118         PRINTF("cal factor: %d\n\r", cal_factor);
00119         PRINTF("hib_wake_secs: %d\n\r", cal_rtc_secs);      
00120         set_bit(*CRM_STATUS,9);
00121 }