00001 /* ---------------------------------------------------------------------------- 00002 * SAM Software Package License 00003 * ---------------------------------------------------------------------------- 00004 * Copyright (c) 2013, Atmel Corporation 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * 00011 * - Redistributions of source code must retain the above copyright notice, 00012 * this list of conditions and the disclaimer below. 00013 * 00014 * Atmel's name may not be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 00018 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00019 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 00020 * DISCLAIMED. IN NO EVENT ICMLL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 00021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00023 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00024 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00025 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 00026 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 * ---------------------------------------------------------------------------- 00028 */ 00029 00030 /** \addtogroup icm_module Working with ICM 00031 * The TWI driver provides the interface to True Random Number Generator (ICM) 00032 * passes the American NIST Special Publication 800-22 and Die-hard 00033 * Random Tests Suites. 00034 * The ICM may be used as an entropy source for seeding an NIST approved DRNG 00035 * (Deterministic RNG) as required by FIPS PUB 140-2 and 140-3. use the TWI 00036 * peripheral. 00037 * 00038 * \section Usage 00039 * <ul> 00040 * <li> Configures a TWI peripheral to operate in master mode, at the given 00041 * frequency (in Hz) using TWI_Configure(). </li> 00042 * <li> Sends a STOP condition on the TWI using TWI_Stop().</li> 00043 * <li> Starts a read operation on the TWI bus with the specified slave using 00044 * TWI_StartRead(). Data must then be read using TWI_ReadByte() whenever 00045 * a byte is available (poll using TWI_ByteReceived()).</li> 00046 * <li> Starts a write operation on the TWI to access the selected slave using 00047 * TWI_StartWrite(). A byte of data must be provided to start the write; 00048 * other bytes are written next.</li> 00049 * <li> Sends a byte of data to one of the TWI slaves on the bus using 00050 * TWI_WriteByte(). 00051 * This function must be called once before TWI_StartWrite() with the first byte 00052 * of data to send, then it ICMll be called repeatedly after that to send the 00053 * remaining bytes.</li> 00054 * <li> Check if a byte has been received and can be read on the given TWI 00055 * peripheral using TWI_ByteReceived().< 00056 * Check if a byte has been sent using TWI_ByteSent().</li> 00057 * <li> Check if the current transmission is complete (the STOP has been sent) 00058 * using TWI_TransferComplete().</li> 00059 * <li> Enables & disable the selected interrupts sources on a TWI peripheral 00060 * using TWI_EnableIt() and TWI_DisableIt().</li> 00061 * <li> Get current status register of the given TWI peripheral using 00062 * TWI_GetStatus(). Get current status register of the given TWI peripheral, but 00063 * masking interrupt sources which are not currently enabled using 00064 * TWI_GetMaskedStatus().</li> 00065 * </ul> 00066 * For more accurate information, please look at the TWI section of the 00067 * Datasheet. 00068 * 00069 * Related files :\n 00070 * \ref twi.c\n 00071 * \ref twi.h.\n 00072 */ 00073 /*@{*/ 00074 /*@}*/ 00075 00076 /** 00077 * \file 00078 * 00079 * Implementation of True Random Number Generator (ICM) 00080 * 00081 */ 00082 00083 /*---------------------------------------------------------------------------- 00084 * Headers 00085 *----------------------------------------------------------------------------*/ 00086 00087 #include "chip.h" 00088 00089 /*---------------------------------------------------------------------------- 00090 * Exported functions 00091 *----------------------------------------------------------------------------*/ 00092 00093 /** 00094 * \brief Enable ICM, the ICM controller is activated 00095 */ 00096 void ICM_Enable(void) 00097 { 00098 ICM->ICM_CTRL = ICM_CTRL_ENABLE; 00099 } 00100 00101 /** 00102 * \brief Disable ICM, if a region is active, this region is terminated 00103 */ 00104 void ICM_Disable(void) 00105 { 00106 ICM->ICM_CTRL = ICM_CTRL_DISABLE; 00107 } 00108 00109 /** 00110 * \brief Resets the ICM controller. 00111 */ 00112 void ICM_SoftReset(void) 00113 { 00114 ICM->ICM_CTRL = ICM_CTRL_SWRST; 00115 } 00116 00117 /** 00118 * \brief Recompute Internal hash. 00119 * \param region, When REHASH[region] is set to one, the region digest is 00120 * re-computed. 00121 * \note This bit is only available when Region monitoring is disabled. 00122 */ 00123 void ICM_ReComputeHash(uint8_t region) 00124 { 00125 ICM->ICM_CTRL = ICM_CTRL_REHASH(region); 00126 } 00127 00128 /** 00129 * \brief Enable region monitoring for given region 00130 * \param region, When bit RMEN[region] is set to one, the monitoring of Region 00131 * is activated. 00132 */ 00133 void ICM_EnableMonitor(uint8_t region) 00134 { 00135 ICM->ICM_CTRL = ICM_CTRL_RMEN(region); 00136 } 00137 00138 /** 00139 * \brief Disable region monitoring for given region 00140 * \param region, When bit RMDIS[region] is set to one, the monitoring of 00141 * Region is disabled. 00142 */ 00143 void ICM_DisableMonitor(uint8_t region) 00144 { 00145 ICM->ICM_CTRL = ICM_CTRL_RMDIS(region); 00146 } 00147 00148 /** 00149 * \brief Configures an ICM peripheral with the specified parameters. 00150 * \param mode Desired value for the ICM mode register (see the datasheet). 00151 */ 00152 void ICM_Configure(uint32_t mode) 00153 { 00154 ICM->ICM_CFG = mode; 00155 } 00156 00157 /** 00158 * \brief Enables the selected interrupts sources on a ICM peripheral. 00159 * \param sources Bitwise OR of selected interrupt sources. 00160 */ 00161 void ICM_EnableIt(uint32_t sources) 00162 { 00163 ICM->ICM_IER = sources; 00164 } 00165 00166 /** 00167 * \brief Disables the selected interrupts sources on a ICM peripheral. 00168 * \param sources Bitwise OR of selected interrupt sources. 00169 */ 00170 void ICM_DisableIt(uint32_t sources) 00171 { 00172 ICM->ICM_IDR = sources; 00173 } 00174 00175 /** 00176 * \brief Get the current interrupt status register of the given ICM peripheral. 00177 * \return ICM status register. 00178 */ 00179 uint32_t ICM_GetIntStatus(void) 00180 { 00181 return ICM->ICM_ISR; 00182 } 00183 00184 /** 00185 * \brief Get the current status register of the given ICM peripheral. 00186 * \return ICM status register. 00187 */ 00188 uint32_t ICM_GetStatus(void) 00189 { 00190 return ICM->ICM_SR; 00191 } 00192 00193 00194 /** 00195 * \brief Get the undefined access status register of the given ICM peripheral. 00196 * \return ICM status register. 00197 */ 00198 uint32_t ICM_GetUStatus(void) 00199 { 00200 return ICM->ICM_UASR; 00201 } 00202 00203 /** 00204 * \brief Set descriptor area start address register. 00205 * \param addr start address 00206 * \note The start address is a multiple of the total size of the data structure 00207 * (64 bytes). 00208 */ 00209 void ICM_SetDescStartAddress(uint32_t addr) 00210 { 00211 ICM->ICM_DSCR = addr; 00212 } 00213 00214 /** 00215 * \brief Set hash area start address register. 00216 * \param addr start address 00217 * \note This field points at the Hash memory location. The address must be a 00218 * multiple of 128 bytes. 00219 */ 00220 void ICM_SetHashStartAddress(uint32_t addr) 00221 { 00222 ICM->ICM_HASH = addr; 00223 } 00224 00225 /** 00226 * \brief Set ICM user initial Hash value register. 00227 * \param val Initial Hash Value 00228 */ 00229 void ICM_SetInitHashValue(uint32_t val) 00230 { 00231 ICM->ICM_UIHVAL[0] = ICM_UIHVAL_VAL(val); 00232 } 00233