/* Copyright 2025 by COG9 Enterprises LLC
 * All rights reserved.
 * Title: eeprom.ino
 * Author: Jed Marti KI7NNP
 * Description: Calibration constants and others.
 * Created: Wed Oct 22 08:05:47 2025
 * Revision History:
 */


#include <EEPROM.h>
#include <string.h>
#include "eepromconst.h"

// A copy of what's there.
eePROMValues E;

// For when battery is set.
extern uint8_t remainingPercent;

void initEEPROM(void)
/*     Read the stored values and show the owner.
 * Parameters: none
 * External References:
 *   E: Where we store what's there.
 * Returned values: none
 * Errors detected: none
 */
{
  EEPROM.get(0x00, E);
  Serial.print(E.eeOwner[0]);
  terpri();
  remainingPercent = (uint8_t) ((E.lastWh / E.Wh) * 100.0);
}


void updateEEPROM(void)
/*     The user has updated something so store the current values.
 * Parameters: none
 * External References:
 *   E: Where we store what's there.
 * Returned values: none
 * Errors detected: none
 */
{
  EEPROM.put(0, E);
}



void dumpEEPROM(void)
/*     Show what's stored out there. Executed from the serial command line interpreter.
 * Parameters: none
 * External References:
 *   E: Where we store what's there.
 * Returned values: none
 * Errors detected: none
 */
{
  Serial.print(F("\nEEPROM configuration\n"));
  Serial.print(F(" Owner: ")); Serial.print(E.eeOwner); terpri();

  Serial.print(F(" Battery M=")); Serial.print(E.eeM, 3);
  Serial.print(F(" B=")); Serial.print(E.eeB, 3); terpri();

  Serial.print(F(" Battery overvoltage ")); Serial.print(E.eeBatOver, 1); 
  Serial.print(F(", low ")); Serial.print(E.eeBatLow, 1);
  Serial.print(F(", done ")); Serial.print(E.eeBatBad, 1);
  terpri();
  
  Serial.print(F(" Max temp ")); Serial.print(E.eeMaxTemp); Serial.print(F(" f")); terpri();
  
  Serial.print(F(" Sample Rate ")); Serial.print(1000 / E.eeSampleMS); Serial.print(F("/sec"));
  Serial.print(F(", Size ")); Serial.print(E.eeSampleSize); terpri();
  Serial.print(F(" Graph MS update ")); Serial.print(E.graphMS); terpri();
  Serial.print(F(" Battery ")); Serial.print(E.Wh, 1); Serial.print(F(" Wh\n"));
  Serial.print(F("    Last ")); Serial.print(E.lastWh, 1); Serial.print(F(" Wh\n"));

  switch (E.whichRecord) {
  case rAmps: Serial.print(F("Record currrents\n")); break;
  case rAmpsVolts: Serial.print(F("Record currents, voltages\n")); break;
  case rAmpsTemps: Serial.print(F("Record currents, temperatures\n")); break;
  case rAll: Serial.print(F("Record everything\n")); break;
  default: Serial.print(F("Unknown record\n")); break;
  }
  
}



void resetEEPROM(void)
/*     Reset the EEPROM to some "factory" settings. These are typical defaults.
 * Parameters: none
 * External References:
 *   E: Where we store what's there.
 * Returned values: none
 * Errors detected: none
 */
{
  Serial.print(F("Reset owner\n"));
  E.eeOwner[0] = 0;              // Empty owner.

  Serial.print(F("Redo batcalib\n"));
  E.eeM = E.eeB = 0.0f;          // Battery.

  E.eeMaxTemp = 125;             // Will almost burn fingers.


  Serial.print(F("10/second, 20/size\n"));
  E.eeSampleMS = 10,
    E.eeSampleSize = 20;

  Serial.print(F("Graph update 1000 ms\n"));
  E.graphMS = 1000;

  // Probably somethink like 8 Ah as watt hours.
  Serial.print(F("Battery 100 Wh\n"));
  E.Wh = 100.0f;

  // Recording everything.
  E.whichRecord = rAll;
	       
  updateEEPROM();
}



 static void eepromFloat(char *field, float *loc)
{
  char *tok;
  terpri();
  tok = strtok(NULL, " \n");
  if (tok == NULL)
  {
    Serial.print(field);
    Serial.printf(F(" = "));
    Serial.print(*loc, 2);

  }
  else
  {
    *loc = atof(tok);
    Serial.print(field);
    Serial.print(" now ");
    Serial.print(*loc, 2);
  }
  terpri();
}



static void eepromUint16(char *field, uint16_t *loc)
{
  char *tok;
  tok = strtok(NULL, " \n");
  terpri();
  if (tok == NULL)
  {
    Serial.print(field);
    Serial.printf(F(" = "));
    Serial.print(*loc);
  }
  else
  {
    *loc = strtol(tok, NULL, 0);
    Serial.print(field);
    Serial.print(F(" now "));
    Serial.print(*loc);
  }
  terpri();
}



static void eepromInt16(char *field, int16_t *loc)
{
  char *tok;
  tok = strtok(NULL, " \n");
  terpri();
  if (tok == NULL)
  {
    Serial.print(field);
    Serial.printf(F(" = "));
    Serial.print(*loc);
  }
  else
  {
    *loc = strtol(tok, NULL, 0);
    Serial.print(field);
    Serial.print(F(" now "));
    Serial.print(*loc);
  }
  terpri();
}



void setEEPROM(void)
/*     Set individual fields of the EEPROM.
 * Syntax:
 *   eeprom [field = value].
 */
{
  char *tok;

  // Just command? Then dump current contents.
  tok = strtok(NULL, " \n");
  if (tok == NULL)
  {
    dumpEEPROM();
    return;
  }

  // Should be a name.
  if (strcasecmp(tok, "m") == 0) eepromFloat("M", &E.eeM);
  else if (strcasecmp(tok, "b") == 0) eepromFloat("B", &E.eeB);
  else if (strcasecmp(tok, "low") == 0) eepromFloat("low", &E.eeBatLow);
  else if (strcasecmp(tok, "over") == 0) eepromFloat("over", &E.eeBatOver);
  else if (strcasecmp(tok, "dead") == 0) eepromFloat("dead", &E.eeBatBad);
  else if (strcasecmp(tok, "maxtemp") == 0) eepromInt16("maxtemp", &E.eeMaxTemp);
  else if (strcasecmp(tok, "rate") == 0) eepromUint16("rate", &E.eeSampleMS);
  else if (strcasecmp(tok, "samples") == 0) eepromUint16("samples", &E.eeSampleSize);
  else if (strcasecmp(tok, "graph") == 0) eepromUint16("graph", &E.graphMS);
  else if (strcasecmp(tok, "battery") == 0) eepromFloat("Wh", &E.Wh);
  else if (strcasecmp(tok, "last") == 0)
  {
    eepromFloat("last Wh", &E.lastWh);
    remainingPercent = (uint8_t) ((E.lastWh / E.Wh) * 100.0f);
  }
  else if (strcmp(tok, "?") == 0)
  {
    Serial.println(F("\n  m <float>      battery slope"));
    Serial.println(F("  b <float>        battery zero intercept"));
    Serial.println(F("  low <float>      battery low voltage"));
    Serial.println(F("  over <float>     battery over voltage"));
    Serial.println(F("  dead <float>     battery dead"));
    Serial.println(F("  maxtemp <float>  maximum operating Fahrenheit"));
    Serial.println(F("  rate <int>       milliseconds/sample"));
    Serial.println(F("  graph <int>      milliseconds/graph"));
    Serial.println(F("  battery <float>  Battery watt hours"));
    Serial.println(F("  last <float>     Battery last watt hours"));
  }
  else
  {
    Serial.print(tok);
    Serial.print(F(" unknown quantity\n"));
    return;
  }
  updateEEPROM();
}
  

// EOF
