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