// https://wokwi.com/projects/413360859668438017
//
// Modified from https://wokwi.com/projects/379571891021837313
// Note -- the custom chip seems to have a bug in counting.
// Watch the Chips Console and see the thing tick over to 2020
// or the minutes tick over to 00 as seconds approaches 60
// For example:
// Date: 2024-11-02 01:31:25
// Date: 2024-11-02 01:31:26
// Date: 2024-11-02 01:31:27
// Date: 2024-11-02 01:31:28
// Date: 2024-11-02 01:31:00
// Date: 2024-11-02 01:00:00
// Date: 2024-11-02 00:00:01
// Date: 2024-11-02 00:00:02
// Date: 2024-11-00 00:00:03
// Date: 2024-00-00 00:00:04
// Date: 2000-00-00 00:00:05
// Date: 2006-00-00 01:00:00
// Date: 2007-00-00 01:00:00
// Date: 2000-00-00 00:00:08
// Date: 2000-00-00 00:00:09
// Date: 2000-00-00 00:00:10
// Date: 2000-00-00 00:00:11
// Date: 2000-00-00 00:00:12
// Date: 2000-00-00 00:00:13


#include <Wire.h>

#define ADDRESS 0x68

void setup() {
  Wire.begin(10, 8); // Inicia la comunicación I2C
  Serial.begin(115200);

  // Inicializa el módulo RTC DS1307 si es necesario
  if (!isDS1307Running()) {
    Serial.println("RTC is NOT running, let's set the time!");
    // Establece la hora y la fecha según tus necesidades
    setDS1307Time(2020, 10, 26, 12, 0, 0);
  }
  /* */
  //  setDS1307Time(2020, 10, 26, 21, 59, 0);
}

void loop() {
  // Leer la hora y fecha del RTC DS1307
  int year, month, day, hour, minute, second;
  getDS1307Time(year, month, day, hour, minute, second);
  char buff[50];
  snprintf(buff, 49, "Date: %4d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second);
  Serial.println(buff);
  // // Imprimir la hora y fecha
  // Serial.print("Date: ");
  // Serial.print(year);
  // Serial.print("-");
  // Serial.print(month);
  // Serial.print("-");
  // Serial.print(day);
  // Serial.print(" ");
  // Serial.print(hour);
  // Serial.print(":");
  // Serial.print(minute);
  // Serial.print(":");
  // Serial.println(second);

  // Retraso de 1 segundos
  delay(1000);
}

bool isDS1307Running() {
  Wire.beginTransmission(ADDRESS);
  Wire.write(0x00); // Registro de segundos
  Wire.endTransmission();

  Wire.requestFrom(ADDRESS, 1);
  uint8_t second = Wire.read();

  return !(second & 0x80); // El bit más alto indica si el reloj está detenido
}

void setDS1307Time(int year, int month, int day, int hour, int minute, int second) {

  Wire.beginTransmission(ADDRESS); // DS3231 I2C address
  Wire.write(0); // Start at the seconds register
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(0)); // Day of the week (not used)
  Wire.write(decToBcd(day));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year - 2000)); // Year as an offset from 2000
  Wire.endTransmission();

}

void getDS1307Time(int &year, int &month, int &day, int &hour, int &minute, int &second) {

  Wire.beginTransmission(ADDRESS);
  Wire.write(0x00); // Registro de segundos
  Wire.endTransmission();

  Wire.requestFrom(ADDRESS, 7);
  second = bcdToDec(Wire.read() & 0x7F); // Ignorar el bit más alto
  minute = bcdToDec(Wire.read());
  hour = bcdToDec(Wire.read());
  Wire.read(); // Ignorar el día de la semana
  day = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year = bcdToDec(Wire.read()) + 2000; // Recuperar el año en formato completo

}

//Convertir de decimal (base 10) a binario codificado en decimal (BCD) y viceversa.
uint8_t decToBcd(uint8_t val) {
  return ( (val / 10 * 16) + (val % 10) );
}

// Convert binary coded decimal to decimal numbers
uint8_t bcdToDec(uint8_t val) {
  return ( (val / 16 * 10) + (val % 16) );
}
ds3231Breakout