BeRTOS
|
00001 00038 #include <sec/random_p.h> 00039 00040 #include <cpu/power.h> 00041 00042 #include <drv/clock_cm3.h> 00043 00044 #include <io/cm3.h> 00045 00046 struct stm32_adc *adc = (struct stm32_adc *)ADC1_BASE; 00047 00048 /* 00049 * Return the cpu core temperature in raw format 00050 */ 00051 INLINE uint16_t hw_readRawTemp(void) 00052 { 00053 /* We sample only from one channel */ 00054 adc->SQR1 |= BV(SQR1_SQ_LEN_SHIFT); 00055 adc->SQR3 = (ADC_TEMP_CH & SQR3_SQ_MASK); 00056 00057 /* Start convertion */ 00058 adc->CR2 |= CR2_EXTTRIG_SWSTRT_SET; 00059 00060 /* Wait in polling until conversion is done */ 00061 while (!(adc->SR & BV(SR_EOC))) 00062 cpu_relax(); 00063 00064 /* Return the last converted data */ 00065 return (uint16_t)adc->DR; 00066 } 00067 00068 INLINE void hw_initIntTemp(void) 00069 { 00070 RCC->APB2ENR |= RCC_APB2_ADC1; 00071 00072 /* Reset registry */ 00073 adc->CR1 = 0; 00074 adc->CR2 = 0; 00075 adc->SQR1 = 0; 00076 adc->SQR2 = 0; 00077 adc->SQR3 = 0; 00078 00079 /* 00080 * Configure ADC 00081 * - Regular mode 00082 * - Wake up adc 00083 * - Wake up temperature and Vrefint 00084 */ 00085 adc->CR2 |= BV(CR2_ADON) | ADC_EXTERNALTRIGCONV_NONE | BV(CR2_TSVREFE); 00086 00087 /* Set 17.1usec sampling time*/ 00088 adc->SMPR1 |= ((ADC_SAMPLETIME_239CYCLES5 << SMPR1_CH17) | (ADC_SAMPLETIME_239CYCLES5 << SMPR1_CH16)); 00089 } 00090 00091 00092 void random_pull_entropy(uint8_t *entropy, size_t len) 00093 { 00094 // We use the internal temperature sensor of LM3S as a source of entropy. 00095 // The last bit of the acquisition is very variable and with a decent distribution 00096 // to consider it "entropic". It does not really matter because it will 00097 // go through a randomness extractor anyway. 00098 hw_initIntTemp(); 00099 00100 for (size_t j=0; j<len; j++) 00101 { 00102 uint8_t accum = 0; 00103 for (int b=0; b<8; ++b) 00104 if (hw_readRawTemp() & 1) 00105 accum |= 1<<b; 00106 00107 *entropy++ = accum; 00108 } 00109 }