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