/* Copyright 2025 by COG9 Enterprises LLC
 * All rights reserved.
 * Title: cterm.ino
 * Author: Jed Marti KI7NNP
 * Description: Dump collected data using the cterm protocol.
 * Created: Mon Oct 13 09:08:26 2025
 * Revision History:
 *   Sat Dec 20 11:35:47 2025 - JBM update for 4 different outputs.
 */

#include <I2C_24LC1025.h>

#include "powerard.h"

// The EEPROM.
extern I2C_24LC1025 seeprom;
extern eePROMValues E;

// Use the buffer from record.ino
extern recordAmperage            rA;
extern recordAmperageVoltage     rAV;
extern recordAmperageTemperature rAT;
extern recordAll                 rAVT;
extern uint32_t recordByte;

// CSV headers for the various file formats.
static char *hrAmps = "month,day,year,hour,minute,second,maA,maB,maC\n";
static char *hrAmpsVolts = "month,day,year,hour,minute,second,maA,maB,maC,bat,vA,vB,vC\n";
static char *hrAmpsTemps = "month,day,year,hour,minute,second,maA,maB,maC,bat,tA,tB,tC,tX\n";
static char *hrAll = "month,day,year,hour,minute,second,maA,maB,maC,bat,vA,vB,vC,tA,tB,tC,tX\n";


static void header(void)
{
  uint8_t obuf[3];
  obuf[0] = 27,
    obuf[1] = 'u';
  switch (E.whichRecord) {
  case rAmps:
    obuf[2] = strlen(hrAmps);
    Serial.write(obuf, 3);
    Serial.write(hrAmps, strlen(hrAmps));
    break;
    
  case rAmpsVolts:
    obuf[2] = strlen(hrAmpsVolts);
    Serial.write(obuf, 3);
    Serial.write(hrAmpsVolts, strlen(hrAmpsVolts));
    break;
    
  case rAmpsTemps:
    obuf[2] = strlen(hrAmpsTemps);
    Serial.write(obuf, 3);
    Serial.write(hrAmpsTemps, strlen(hrAmpsTemps));
    break;
    
  case rAll:
    obuf[2] = strlen(hrAll);
    Serial.write(obuf, 3);
    Serial.write(hrAll, strlen(hrAll));
    break;

  default:
    break;
  }
}
    


static uint8_t waitForcterm(char *fn)
{
  uint16_t resp;
  
  while (Serial.available() == 0);
  resp = Serial.read();
  if (resp == 0)
  {
    Serial.print(fn);
    Serial.print(" failed");
    return 0;
  }
  Serial.print(".");
  return 1;
}


  
void ctermDump(void)
{
  uint8_t upload[3];
  uint8_t resp;
  uint32_t readthem;
  char obuf[80];
  uint8_t sz;
  uint8_t mo, day;
  uint8_t hrs, mins, secs;
  uint16_t yr;
  char *tok;

  // Get file name from command line.
  tok = strtok(NULL, " ");

  // Send the upload sequence.
  Serial.println("\nStarting upload");
  snprintf(obuf, 50, "xU%s", tok);
  sz = strlen(obuf);
  obuf[0] = 27;
  obuf[sz] = 0;
  Serial.write(obuf, sz + 1);

  // Wait for OK.
  Serial.println("waiting");
  while (Serial.available() == 0);
  resp = Serial.read();
  if (resp == 0)
  {
    Serial.print(tok);
    Serial.println(" cannot be written");
    return;
  }

  Serial.print("\nSending ");
  Serial.println(tok);

  header();
  if (waitForcterm(tok) == 0) return;
  
  recordByte = 0;

 loop:
  switch (E.whichRecord) {
  case rAmps:
    readthem = seeprom.readBlock(recordByte, (uint8_t*) &rA, sizeof(rA) - sizeof(uint16_t));
    if (readthem != sizeof(rA) - sizeof(uint16_t)) goto done;

    // Some 0's indicate we're done.
    if (rA.dateTime[0] == 0 &&
        rA.dateTime[1] == 0 &&
        (rA.dateTime[2] == 0 || rA.dateTime[2] == 0xFF) &&
        (rA.dateTime[3] == 0 || rA.dateTime[3] == 0xFF)) goto done;

    mo = ((rA.dateTime[5] >> 4) & 0x01) * 10 + (rA.dateTime[5] & 0x0F);
    day = ((rA.dateTime[4] >> 4) & 0x03) * 10 + (rA.dateTime[4] & 0x0F);
    yr = (rA.dateTime[6] >> 4) * 10 + (rA.dateTime[6] & 0x0F);
    yr += 2000;
    hrs = ((rA.dateTime[2] >> 4) & 0x03) * 10 + (rA.dateTime[2] & 0x0F);
    mins = ((rA.dateTime[1] >> 4) & 0x07) * 10 + (rA.dateTime[1] & 0x0F);
    secs = ((rA.dateTime[0] >> 4) & 0x07) * 10 + (rA.dateTime[0] & 0x0F);
    snprintf(obuf, 80, "%d,%d,%d,%d,%d,%d,%u,%u,%u\n", mo, day, yr, hrs, mins, secs, rA.mampsA,
             rA.mampsB, rA.mampsC);
    recordByte += sizeof(recordAmperage) - sizeof(uint16_t);
    break;

  case rAmpsVolts:
     readthem = seeprom.readBlock(recordByte, (uint8_t*) &rAV, sizeof(rAV) - sizeof(uint16_t));
    if (readthem != sizeof(rAV) - sizeof(uint16_t)) goto done;

    // Some 0's indicate we're done.
    if (rAV.dateTime[0] == 0 &&
        rAV.dateTime[1] == 0 &&
        (rAV.dateTime[2] == 0 || rAV.dateTime[2] == 0xFF) &&
        (rAV.dateTime[3] == 0 || rAV.dateTime[3] == 0xFF)) goto done;

    mo = ((rAV.dateTime[5] >> 4) & 0x01) * 10 + (rAV.dateTime[5] & 0x0F);
    day = ((rAV.dateTime[4] >> 4) & 0x03) * 10 + (rAV.dateTime[4] & 0x0F);
    yr = (rAV.dateTime[6] >> 4) * 10 + (rAV.dateTime[6] & 0x0F);
    yr += 2000;
    hrs = ((rAV.dateTime[2] >> 4) & 0x03) * 10 + (rAV.dateTime[2] & 0x0F);
    mins = ((rAV.dateTime[1] >> 4) & 0x07) * 10 + (rAV.dateTime[1] & 0x0F);
    secs = ((rAV.dateTime[0] >> 4) & 0x07) * 10 + (rAV.dateTime[0] & 0x0F);
    snprintf(obuf, 80, "%d,%d,%d,%d,%d,%d,%u,%u,%u,%d.%02d,%d.%02d,%d.%02d,%d.%02d\n", mo, day, yr,
             hrs, mins, secs, rAV.mampsA, rAV.mampsB, rAV.mampsC,
             rAV.battery / 100, rAV.battery % 100,
             rAV.voltA / 100, rAV.voltA % 100,
             rAV.voltB / 100, rAV.voltB % 100,
             rAV.voltC / 100, rAV.voltC % 100);
    recordByte += sizeof(recordAmperageVoltage) - sizeof(uint16_t);
    break;
    
  case rAmpsTemps:
     readthem = seeprom.readBlock(recordByte, (uint8_t*) &rAT, sizeof(rAT) - sizeof(uint16_t));
    if (readthem != sizeof(rAT) - sizeof(uint16_t)) goto done;

    // Some 0's indicate we're done.
    if (rAT.dateTime[0] == 0 &&
        rAT.dateTime[1] == 0 &&
        (rAT.dateTime[2] == 0 || rAT.dateTime[2] == 0xFF) &&
        (rAT.dateTime[3] == 0 || rAT.dateTime[3] == 0xFF)) goto done;

    mo = ((rAT.dateTime[5] >> 4) & 0x01) * 10 + (rAT.dateTime[5] & 0x0F);
    day = ((rAT.dateTime[4] >> 4) & 0x03) * 10 + (rAT.dateTime[4] & 0x0F);
    yr = (rAT.dateTime[6] >> 4) * 10 + (rAT.dateTime[6] & 0x0F);
    yr += 2000;
    hrs = ((rAT.dateTime[2] >> 4) & 0x03) * 10 + (rAT.dateTime[2] & 0x0F);
    mins = ((rAT.dateTime[1] >> 4) & 0x07) * 10 + (rAT.dateTime[1] & 0x0F);
    secs = ((rAT.dateTime[0] >> 4) & 0x07) * 10 + (rAT.dateTime[0] & 0x0F);
    snprintf(obuf, 80, "%d,%d,%d,%d,%d,%d,%u,%u,%u,%u,%u,%u,%u\n", mo, day, yr,
             hrs, mins, secs, rAT.mampsA, rAT.mampsB, rAT.mampsC,
             rAT.tempA, rAT.tempB, rAT.tempC, rAT.tempX);
    recordByte += sizeof(recordAmperageTemperature) - sizeof(uint16_t);
    break;
    
  case rAll:
     readthem = seeprom.readBlock(recordByte, (uint8_t*) &rAVT, sizeof(rAT) - sizeof(uint16_t));
    if (readthem != sizeof(rAT) - sizeof(uint16_t)) goto done;

    // Some 0's indicate we're done.
    if (rAVT.dateTime[0] == 0 &&
        rAVT.dateTime[1] == 0 &&
        (rAVT.dateTime[2] == 0 || rAVT.dateTime[2] == 0xFF) &&
        (rAVT.dateTime[3] == 0 || rAVT.dateTime[3] == 0xFF)) goto done;

    mo = ((rAVT.dateTime[5] >> 4) & 0x01) * 10 + (rAVT.dateTime[5] & 0x0F);
    day = ((rAVT.dateTime[4] >> 4) & 0x03) * 10 + (rAVT.dateTime[4] & 0x0F);
    yr = (rAVT.dateTime[6] >> 4) * 10 + (rAVT.dateTime[6] & 0x0F);
    yr += 2000;
    hrs = ((rAVT.dateTime[2] >> 4) & 0x03) * 10 + (rAVT.dateTime[2] & 0x0F);
    mins = ((rAVT.dateTime[1] >> 4) & 0x07) * 10 + (rAVT.dateTime[1] & 0x0F);
    secs = ((rAVT.dateTime[0] >> 4) & 0x07) * 10 + (rAVT.dateTime[0] & 0x0F);
    snprintf(obuf, 80, "%d,%d,%d,%d,%d,%d,%u,%u,%u,%d.%02d,%d.%02d,%d.%02d,%d.%02d,%u,%u,%u,%u\n",
             mo, day, yr, hrs, mins, secs,
             rAVT.mampsA, rAVT.mampsB, rAVT.mampsC,
             rAVT.battery / 100, rAVT.battery % 100,
             rAVT.voltA / 100, rAVT.voltA % 100,
             rAVT.voltB / 100, rAVT.voltB % 100,
             rAVT.voltC / 100, rAVT.voltC % 100,
             rAVT.tempA, rAVT.tempB, rAVT.tempC, rAVT.tempX);
    recordByte += sizeof(recordAll) - sizeof(uint16_t);
    break;
    
   }

  upload[2] = strlen(obuf);
  Serial.write(upload, 3);
  Serial.write(obuf, strlen(obuf));
  while (Serial.available() == 0);
  resp = Serial.read();
  if (resp == 0)
  {
    Serial.print(tok);
    Serial.println(" failed");
    return;
  }
  Serial.print(".");
  goto loop;


 done:
  upload[2] = 0;
  Serial.write(upload, 3);
  Serial.print(tok);
  Serial.println(" sent");
}


// EOF
