Contiki 2.6

random.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
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 cc2530 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 "cc253x.h"
00043 #include "sfr-bits.h"
00044 #include "dev/cc2530-rf.h"
00045 /*---------------------------------------------------------------------------*/
00046 /**
00047  * \brief      Generates a new random number using the cc253x RNG.
00048  * \return     The random number.
00049  */
00050 unsigned short
00051 random_rand(void)
00052 {
00053   /* Clock the RNG LSFR once */
00054   ADCCON1 |= ADCCON1_RCTRL0;
00055 
00056   return (RNDL | (RNDH << 8));
00057 }
00058 /*---------------------------------------------------------------------------*/
00059 /**
00060  * \brief      Seed the cc253x random number generator.
00061  * \param seed Ignored. It's here because the function prototype is in core.
00062  *
00063  *             We form a seed for the RNG by sampling IF_ADC as
00064  *             discussed in the user guide.
00065  *             Seeding with this method should not be done during
00066  *             normal radio operation. Thus, use this function before
00067  *             initialising the network.
00068  */
00069 void
00070 random_init(unsigned short seed)
00071 {
00072   int i;
00073 
00074   /* Make sure the RNG is on */
00075   ADCCON1 &= ~(ADCCON1_RCTRL1 | ADCCON1_RCTRL0);
00076 
00077   /* Infinite RX */
00078   FRMCTRL0 = FRMCTRL0_RX_MODE1;
00079 
00080   /* Turn RF on */
00081   CC2530_CSP_ISRXON();
00082 
00083   /* Wait until (user guide sec. 23.12, p 239) "the chip has been in RX long
00084    * enough for the transients to have died out. A convenient way to do this is
00085    * to wait for the RSSI-valid signal to go high." */
00086   while(!(RSSISTAT & RSSISTAT_RSSI_VALID));
00087 
00088   /*
00089    * Form the seed by concatenating bits from IF_ADC in the RF receive path.
00090    * Keep sampling until we have read at least 16 bits AND the seed is valid
00091    *
00092    * Invalid seeds are 0x0000 and 0x8003 - User Guide (sec. 14.2.2 p. 146):
00093    * "Note that a seed value of 0x0000 or 0x8003 always leads to an unchanged
00094    * value in the LFSR after clocking, as no values are pushed in via in_bit
00095    * (see Figure 14-1); hence, neither of these seed values should not be used
00096    * for random-number generation."
00097    */
00098   i = 0;
00099   while(i < 16 || (seed == 0x0000 || seed == 0x8003)) {
00100     seed = (seed << 1) | (RFRND & RFRND_IRND);
00101     seed <<= 1;
00102     i++;
00103   }
00104 
00105   /* High byte first */
00106   RNDL = seed >> 8;
00107   RNDL = seed & 0xFF;
00108 
00109   /* RF Off. NETSTACK_RADIO.init() will sort out normal RF operation */
00110   CC2530_CSP_ISRFOFF();
00111 }