/* Copyright 2025 by COG9 Enterprises LLC
 * All rights reserved.
 * Title: ds1340.ino
 * Author: Jed Marti KI7NNP
 * Description: RTC functions.
 * Created: Sun Oct  5 08:35:35 2025
 * Revision History:
 */

#include <Wire.h>
#include "ds1340.h"
#include "powerard.h"

/*
 * init_rtc(...) -
 *     Initialize the real time clock. This sends out the command to start
 *   charging the battery.
 * Parameters: none
 * External references:
 *   DS1340Z: I2C address of chip.
 * Returned values: none
 * Errors detected:
 */
void initDateTime(void)
{
  uint8_t ibuf[2];
  ibuf[0] = 0x08;                // Writing to address register 8.
  ibuf[1] = 0xAB;                // Charger on, 4k resister.
  Wire.beginTransmission(DS1340Z);
  Wire.write(ibuf, 2);
  if (Wire.endTransmission())
  {
    Serial.println(F("**RTC fails to start"));
    return;
  }
}

/*     Get the current date from the real time clock chip.
 *   Get the binary date/time into the buffer.
 */
void getDateTime(uint8_t *obuf)
{
  uint8_t i;
  
  // Tell chip to start reading register 0.
  Wire.beginTransmission(DS1340Z);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1340Z, 7);
  i = 0;
  while (Wire.available())
    obuf[i++] = Wire.read();
}




void ctimec(uint8_t *obuf, uint8_t *dt)
/*     20 characters output (includes terminating 0).
 * mm/dd/yyyy hh:mm:ss
 */
{
  obuf[0] = ((dt[5] >> 4) & 0x01) + '0';
  obuf[1] = (dt[5] & 0x0F) + '0';
  obuf[2] = obuf[5] = '/';
  obuf[3] = ((dt[4] >> 4) & 0x03) + '0';
  obuf[4] = (dt[4] & 0x0F) + '0';
  obuf[6] = '2';
  obuf[7] = '0';
  obuf[8] = (dt[6] >> 4) + '0';
  obuf[9] = (dt[6] & 0x0F) + '0';
  obuf[10] = ' ';
  obuf[11] = ((dt[2] >> 4) & 0x03) + '0';
  obuf[12] = (dt[2] & 0x0F) + '0';
  obuf[13] = ':';
  obuf[14] = ((dt[1] >> 4) & 0x07) + '0';
  obuf[15] = (dt[1] & 0x0F) + '0';
  obuf[16] = ':';
  obuf[17] = ((dt[0] >> 4) & 0x07) + '0';
  obuf[18] = (dt[0] & 0x0F) + '0';
  obuf[19] = 0;
}


void ctime(uint8_t *obuf)
{
  uint8_t dt[7];
  getDateTime(dt);
  ctimec(obuf, dt);
}



static uint8_t b2d(uint8_t b)
{
  return  ((b / 10) << 4) + (b % 10);
}


// Alterative looks Linuxy
void setDateTime(void)
/*
 *    dayname  month day year hours:minutes:seconds
 */
{
  char    *tok;
  int16_t n;
  uint8_t dbuf[7];
  uint8_t obuf[22];


  // Day name, only first 3 characters for the day.
  Serial.println("");
  tok = strtok(NULL, " ");
  if (tok == NULL)
  {
    ctime(obuf);
    Serial.println((char*) obuf);
    return;
  }
  if (strncasecmp(tok, "monday", 3) == 0) dbuf[4] = 1;
  else if (strncasecmp(tok, "tuesday", 3) == 0) dbuf[4] = 2;
  else if (strncasecmp(tok, "wednesday", 3) == 0) dbuf[4] = 3;
  else if (strncasecmp(tok, "thursday", 3) == 0) dbuf[4] = 4;
  else if (strncasecmp(tok, "friday", 3) == 0) dbuf[4] = 5;
  else if (strncasecmp(tok, "saturday", 3) == 0) dbuf[4] = 6;
  else if (strncasecmp(tok, "sunday", 3) == 0) dbuf[4] = 7;
  else
  {
    Serial.print(F("Day of week? "));
    Serial.println(tok);
    return;
  }

  // Month by name.
  tok = strtok(NULL, " ");
  if (tok == NULL)
  {
    Serial.println("Missing month");
    return;
  }
  if (strncasecmp(tok, "january", 3) == 0) dbuf[6] = 1;
  else if (strncasecmp(tok, "february", 3) == 0) dbuf[6] = 2;
  else if (strncasecmp(tok, "march", 3) == 0) dbuf[6] = 3;
  else if (strncasecmp(tok, "april", 3) == 0) dbuf[6] = 4;
  else if (strcasecmp(tok, "may") == 0) dbuf[6] = 5;
  else if (strncasecmp(tok, "june", 3) == 0) dbuf[6] = 6;
  else if (strncasecmp(tok, "july", 3) == 0) dbuf[6] = 7;
  else if (strncasecmp(tok, "august", 3) == 0) dbuf[6] = 8;
  else if (strncasecmp(tok, "september", 3) == 0) dbuf[6] = 9;
  else if (strncasecmp(tok, "october", 3) == 0) dbuf[6] = 0x10;
  else if (strncasecmp(tok, "november", 3) == 0) dbuf[6] = 0x11;
  else if (strncasecmp(tok, "december", 3) == 0) dbuf[6] = 0x12;
  else
  {
    Serial.print(F("Month? "));
    Serial.println(tok);
  }

  // day of month.
  tok = strtok(NULL, " ");
  n = atoi(tok);
  if (n < 1 || n > 31)
  {
    Serial.print(F("Day? "));
    Serial.println(n);
    return;
  }
  dbuf[5] = b2d(n);

  // Year
  tok = strtok(NULL, " ");
  n = atoi(tok);
  if (n < 2025 || n > 2050)
  {
    Serial.print(F("Year? "));
    Serial.println(n);
    return;
  }
  dbuf[7] = b2d(n - 2000);

  // Hour.
  tok = strtok(NULL, ":");
  n = atoi(tok);
  if (n < 0 || n >= 24)
  {
    Serial.print(F("Hour? "));
    Serial.println(n);
    return;
  };
  dbuf[3] = b2d(n);

  // Minutes.
  tok = strtok(NULL, ":");
  n = atoi(tok);
  if (n < 0 || n >= 60)
  {
    Serial.print(F("Minutes? "));
    Serial.println(n);
    return;
  };
  dbuf[2] = b2d(n);

  // Seconds
  tok = strtok(NULL, " ");
  n = atoi(tok);
  if (n < 0 || n >= 60)
  {
    Serial.print(F("Seconds? "));
    Serial.println(n);
    return;
  };
  dbuf[1] = b2d(n);

  // Start writing to register 0.
  dbuf[0] = 0;
  Wire.beginTransmission(DS1340Z);
  Wire.write(dbuf, 8);
  Wire.endTransmission();
  Serial.println("\nDate set");
}



// EOF
