23 #include "RingOscillatorNoiseSource.h"
101 #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
105 #define RING_CAPT_vect TIMER4_CAPT_vect
106 #define RING_ICR ICR4
107 #elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
111 #define RING_CAPT_vect TIMER1_CAPT_vect
112 #define RING_ICR ICR1
117 #define RING_CAPT_vect TIMER1_CAPT_vect
118 #define RING_ICR ICR1
122 #define NOISE_NOT_CALIBRATING 0
123 #define NOISE_CALIBRATING 1
127 #define RING_DISCONNECT_TIME 200
129 RingOscillatorNoiseSource::RingOscillatorNoiseSource()
130 : calState(NOISE_CALIBRATING)
131 , lastSignal(millis())
137 pinMode(RING_PIN, INPUT);
138 digitalWrite(RING_PIN, LOW);
146 TCCR1B |= (1 << ICES1);
147 TIMSK1 |= (1 << ICIE1);
150 TCCR1B |= (1 << CS10);
151 #elif RING_TIMER == 4
157 TCCR4B |= (1 << ICES4);
158 TIMSK4 |= (1 << ICIE4);
161 TCCR4B |= (1 << CS10);
165 RingOscillatorNoiseSource::~RingOscillatorNoiseSource()
170 #elif RING_TIMER == 4
180 return calState == NOISE_CALIBRATING;
183 static uint16_t
volatile out = 0;
184 static uint8_t
volatile outBits = 0;
194 static uint16_t prev = 0;
195 uint16_t next = RING_ICR;
196 out = (out << 1) | ((next - prev) & 1);
205 unsigned long now = millis();
211 for (uint8_t index = 0; index < 8; ++index) {
217 if ((bits ^ (bits << 1)) & 0x8000) {
219 if (posn <
sizeof(buffer)) {
220 buffer[posn] = (buffer[posn] >> 1) |
221 (((uint8_t)(bits >> 8)) & (uint8_t)0x80);
237 if (calState == NOISE_NOT_CALIBRATING) {
238 if ((now - lastSignal) >= RING_DISCONNECT_TIME) {
240 calState = NOISE_CALIBRATING;
249 if (posn >=
sizeof(buffer)) {
250 output(buffer, posn, posn);
252 calState = NOISE_NOT_CALIBRATING;
257 void RingOscillatorNoiseSource::restart()
void stir()
Stirs entropy from this noise source into the global random number pool.
bool calibrating() const
Determine if the noise source is still calibrating itself.
virtual void output(const uint8_t *data, size_t len, unsigned int credit)
Called from subclasses to output noise to the global random number pool.