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()
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.
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.