RNG90 and watchdog timer - Arduino Uno code
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <avr/wdt.h> // needed for watchdog
#include <avr/interrupt.h>
unsigned char rng90Bytes[32];
unsigned char watchdogBytes[32];
boolean status = false;
const int chipSelect = 4;
byte tcnt1_lowbyte = 0;
boolean go_watchdog = false;
boolean go_rng90 = false;
int index = 0;
File dataFile;
void wd_setup() {
/*registers known as WDTCSR
WDIF - Sets an interrupt flag
WDIE - Enables Interrupts
WDCE - This is a safety to enable a configuration
mode that will last 4 clock cycles. Set this bit and
WDE high before attempting any changes to the watchdog register
WDE - Enables system reset on time-out
WDP0/WDP1/WDP2/WDP3 - These four bits
determine how long the timer will count for before
resetting.
*/
cli();
//10.9.1 MCUSR – MCU Status Register is reset when writing a logic zero to it
MCUSR = 0;
WDTCSR |= (1<<WDCE) | (1<<WDE); // enter configuration mode
WDTCSR = (1<<WDIE); // interrupt enable bit
sei();
}
// Watchdog Timer Interrupt Service Routine
ISR(WDT_vect){
tcnt1_lowbyte = TCNT1L; // Timer/Counter1 low byte
go_watchdog = true;
}
void setup() {
Wire.begin(0x40); // Initialize I2C communication
for (int i=0; i< 32; i++) {
rng90Bytes[i] = 0;
watchdogBytes[i]=0;
}
Wire.setClock(100000); // was 400K
pinMode(8, OUTPUT);
if (!SD.begin(chipSelect)) {
digitalWrite(8, HIGH);
while (1);
}
digitalWrite(8, HIGH);
wd_setup(); //setting up the watchdog timer
delay(1000);
digitalWrite(8, LOW);
dataFile = SD.open("rnd_xor.txt", FILE_WRITE);
delay(1000); //500
}
void loop() {
go_rng90 = false;
if (go_watchdog) {
watchdogBytes[index] = tcnt1_lowbyte;
index++;
if (index == 32) { // done collecting rnd bytes
go_rng90 = true;
}
go_watchdog = false; //so that the loop() runs only once and after ISR
}
if (go_rng90) {
Wire.beginTransmission(0x40); // Start communication with RNG90
if (status) {
Wire.write(0x40); // i2c address
}
Wire.write(0x03); // word address value
Wire.write(0x1b); // count (N+1) = 27
Wire.write(0x16); // Request the random number register
Wire.write(0x00); // 1st parameter
Wire.write(0x00); // 2nd parameter
Wire.write(0x00);
for (int k = 0; k < 20; k++) {
Wire.write(0x00); // 20 data bytes
}
Wire.write(0x7d); // crc
Wire.write(0xe0);
Wire.endTransmission();
Wire.requestFrom(0x40, 1); // Request 1 byte (0x23)
index=0;
while (Wire.available()) {
rng90Bytes[index] = Wire.read();
}
Wire.requestFrom(0x40, 32); // Request 32 bytes (32-bites random number)
index = 0;
while (Wire.available()) {
rng90Bytes[index] = Wire.read();
index++;
} //while
if (status) { // ready to write
if (dataFile) {
for (int k=0; k < 32; k++) {
rng90Bytes[k] ^= watchdogBytes[k];
dataFile.print(rng90Bytes[k]);
dataFile.print(",");
}
dataFile.println();
dataFile.flush();
digitalWrite(8, HIGH);
}
delay(30); //300
digitalWrite(8, LOW);
status = false;
} else {
status = true;
}
index = 0;
delay(20); //200
} // go_rng90
} // loop