Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2010, Loughborough University - Computer Science 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 */ 00031 00032 /** 00033 * \file 00034 * Random number generator routines exploiting the cc2430 hardware 00035 * capabilities. 00036 * 00037 * This file overrides core/lib/random.c. 00038 * 00039 * \author 00040 * George Oikonomou - <oikonomou@users.sourceforge.net> 00041 */ 00042 #include "cc2430_sfr.h" 00043 #include "dev/cc2430_rf.h" 00044 /*---------------------------------------------------------------------------*/ 00045 /** 00046 * \brief Generates a new random number using the cc2430 RNG. 00047 * \return The random number. 00048 */ 00049 unsigned short 00050 random_rand(void) 00051 { 00052 /* Clock the RNG LSFR once */ 00053 ADCCON1 |= ADRCTRL0; 00054 00055 return (RNDL | (RNDH << 8)); 00056 } 00057 /*---------------------------------------------------------------------------*/ 00058 /** 00059 * \brief Seed the cc2430 random number generator. 00060 * \param seed Seed value for the RNG. 00061 * 00062 * If the SEED argument is 0, seed the RNG with IF_ADC as 00063 * discussed in the cc2430 datasheet (rev. 2.1), section 13.11.2.2, 00064 * page 134. Seeding with this method should not be done during 00065 * normal radio operation. Thus, use this function before 00066 * initialising the network. 00067 * 00068 * If the SEED is provided, seed with this value instead. This will 00069 * result in the same sequence of random numbers each time the node 00070 * reboots. So, don't use it unless you have a reason (e.g. tests) 00071 */ 00072 void 00073 random_init(unsigned short seed) 00074 { 00075 int i; 00076 00077 /* Comment out this if() block to save a nice 16 bytes of code size */ 00078 if(seed) { 00079 /* If the caller provides a seed, write the high-byte first and then 00080 * write the low byte */ 00081 RNDL = seed >> 8; /* High byte first */ 00082 RNDL = seed & 0xFF; 00083 return; 00084 } 00085 00086 /* 00087 * cc2430 Datasheet: 00088 * "When a true random value is required, the LFSR should be seeded by 00089 * writing RNDL with random values from the IF_ADC in the RF receive path." 00090 * 00091 * "To use this seeding method, the radio must first be powered on by 00092 * enabling the voltage regulator" 00093 */ 00094 RFPWR &= ~RREG_RADIO_PD; /* Turn on the voltage regulator */ 00095 while(!(RFIF & IRQ_RREG_ON)); /* Wait for power up*/ 00096 00097 /* OK, it's powered. The respective interrupt flag has been set, clear it */ 00098 RFIF &= ~IRQ_RREG_ON; 00099 00100 /* 00101 * "The radio should be placed in infinite TX state, to avoid possible sync 00102 * detect in RX state." 00103 * 00104 * Judging by old chipcon cc2430 code examples as well as by the way cc2530 00105 * works, this is very likely to be "RX state" (i.e. a typo in the datasheet) 00106 * 00107 * With infinite TX, ADCTSTx always read as 0 so we'll use infinite RX 00108 */ 00109 MDMCTRL1L = 0x02; /* RX mode 10 - RX_INFINITE state */ 00110 00111 /* "Enter RX State - Immediate" command strobe */ 00112 cc2430_rf_command(ISRXON); 00113 00114 /* Make sure the RNG is on */ 00115 ADCCON1 &= ~(ADRCTRL1 | ADRCTRL0); 00116 00117 /* Wait for IF_ADC I-branch and Q-branch values */ 00118 while(!(ADCTSTH & ADCTSTL)); 00119 00120 /* 32 times as per the chipcon example. This seems to increase randomness */ 00121 for(i = 0; i < 32; i++) { 00122 /* Seed the RNG by writing into RNDL twice with values from ADCTSTx */ 00123 RNDL = ADCTSTH; 00124 RNDL = ADCTSTL; 00125 00126 /* Clock the RNG LSFR once */ 00127 ADCCON1 |= ADRCTRL0; 00128 } 00129 00130 /* 00131 * Exit RX state. Just shut down, network initialisation will take care of 00132 * properly starting the radio for us. 00133 */ 00134 RFPWR |= RREG_RADIO_PD; 00135 }