// HC3 base station

#include "H:\application-specific\generic C compiler\DateFile.c"
// defines WhenCompiled

#include "G:\source code\Teensy\Teensy 3.5 pins.inc"
// ************ pin assignments ************************
#define WindowsSerial Serial
#define serialXBee Serial1
#define wireDS1307   Wire
// XBee uses                      pin00Serial1RX_MOSI1
// XBee uses                      pin01Serial1TX_MISO1
const int pinConnectedToWindows = pin02Generic;
const int pinJogClockPlus       = pin03SCL2;      // not used
const int pinJogClockMinus      = pin04SDA2;      // not used
const int pinTVDC               = pin05TV;
const int pinuSD                = pin06Generic;
const int pinGND_SetClock       = pin07RX3;       // not used
const int pinTVCS               = pin10TX2CS0TV;
const int pinTVData             = pin11MOSI0TV;
const int pinTVSCLK             = pin13SCK0TV;
const int pinTVReset            = pin15A01CS0TV;
const int pinGNDInIDE           = pin16A02;
const int pinGNDDebug           = pin17A03;
  // DS1307                       pin18A04SDA0;
  // DS1307                       pin19A05SCL0;
const int pinGNDShutDown        = pin22A08;

const int pinBlink              = pinuSD;  // Blink routine used only in boot 
// ************ end pin assignments ************************

// routine IDs 2xxx
#include "G:\source code\Teensy\home control\HC3\BaseStation\include files\enumerations.inc"
#include "G:\source code\Teensy\home control\HC3\BaseStation\include files\infrastructure.inc"

//                                                                                                  TeensyView
#include "G:\source code\Teensy\home control\HC3\shared\TeensyView.inc"
tTeensyView TV;
//                                                                                                  infrastructure2
#include "G:\source code\Teensy\home control\HC3\BaseStation\include files\infrastructure2.inc"
//                                                                                                  DS1307
#include "G:\source code\Teensy\home control\HC3\shared\DS1307.inc"
tDS1307 DS1307;
//                                                                                                  file system
#include <SD.h>
#include "G:\source code\Teensy\home control\HC3\BaseStation\include files\FS3.inc"
tFileSystem FileSystem;
//                                                                                                  XBee
#include "G:\source code\Teensy\home control\HC3\BaseStation\include files\BaseXBee2.inc"
tXBee XBee;
//                                                                                                  Windows
#include "G:\source code\Teensy\home control\HC3\BaseStation\include files\Windows2.inc"
tWindows Windows;
//                                                                                                  statistics
unsigned long NLoops;
elapsedMillis msLoopingTime;
const unsigned long LoopReportModulus = 10000000;

void setup()
  { Infrastructure.setup();                            // deep state
    Infrastructure.Blink(1);                           // .. blink 1
    WindowsSerial.begin(38400);                        // .. Serial
    delay(2 * msOneSecond);                            // .. ..
    Infrastructure.SayInIDE("setup begun");            // .. ..
    Infrastructure.Blink(2);                           // .. blink 2
    DS1307.setup(DisallowTimeSetting);                 // DS1307
    // DS1307.SetDS1307(2020, 12, 17,                  // ..
    //                  4,                             // .. day of week, Monday = 1
    //                  23, 13, 0);                    // ..
    Infrastructure.Blink(3);                           // .. blink 3
    Infrastructure.SayInIDE("DS1307 OK");              // ..
    TV.setup();                                        // Teensyview
    TV.msMaxInactivity = 30 * msOneSecond;             // ..
    Infrastructure.Blink(1);                           // .. blink 1
    Infrastructure.SayInIDE("TeensyView OK");          // ..
    Infrastructure.TellWindows(btwStartingFileSystem); // file system
    const int chipSelect = BUILTIN_SDCARD;             // Teensy 3.5 & 3.6 on-board
    if (not SD.begin(chipSelect))                      // ..
      { Hang("couldn't start SD package."); }          // ..
    FileSystem.setup();                                // ..
    Infrastructure.SayInIDE("file system OK");         // ..
    Infrastructure.Blink(2);                           // .. blink 2
    Infrastructure.TellWindows(btwStartingXBee);       // XBee
    if (not XBee.Begin())                              // ..
       { Hang("XBee inoperative"); }                   // ..
    Infrastructure.SayInIDE("XBee OK");                // ..
    Infrastructure.Blink(3);                           // .. blink 3
    Windows.Clear();                                   // input buffers
    NLoops = 0;                                        // instrumentation
    msLoopingTime = 0;                                 // ..
    elmsSinceTickled = 0;                              // timeout if this > limit
    Infrastructure.TellWindows(btwSetupComplete);      // done
    Infrastructure.SayInIDE("setup complete");         // ..
    Infrastructure.Blink(5);                           // .. blink 5
  } // setup


const bool TimingTheLoop = false; // typically 2.1 us/loop

void loop()
  { char Message[50];
    
    TV.InactivityCheck();
      
    if (Infrastructure.ShutDownRequested)
      { Serial.println("shutdown requested");
        Infrastructure.BadNews("disconnected", btwDisconnectedRQ);
        Infrastructure.SetGlobalStatus(gsNotConnected);
        FileSystem.ShutDown();
        Hang("shutdown requested in loop");
      }

    else if (WindowsSerial.available())
      { // process as many characters as possible
        Windows.GetChars();
      } // process as many characters as possible

    else if (serialXBee.available())
      { // process as many characters as possible
        XBee.GetChars();
      } // process as many characters as possible

    else // no input to deal with
      { switch (Infrastructure.GlobalStatus)
        { case  gsJustConnected: if (GrossDumpSize > 0)
                                   { digitalWrite(pinuSD, HIGH);
                                     FileSystem.StartDump();
                                   }
                                 else
                                   { digitalWrite(pinuSD, LOW);
                                     Infrastructure.SetGlobalStatus(gsPassThrough);
                                   }
                                 Infrastructure.CheckWindowsConnection();
                                 break;

          case gsDumpInProgress: if (Infrastructure.Interrupting)
                                   { Infrastructure.TellWindows(btwInterrupted);
                                     Infrastructure.SetGlobalStatus(gsJustConnected);
                                     Infrastructure.TellWindows(btwDumpEnded);
                                   }
                                 else if (not FileSystem.DumpedALine())
                                   { FileSystem.DumpFinished(); } // FALL-THROUGH

          case    gsPassThrough: Infrastructure.CheckWindowsConnection();        // FALL-THROUGH

          case   gsNotConnected: break;
        } // switch
      } // no input to deal with

    if (TimingTheLoop)
      { // timing the loop
        NLoops++;
        if ((NLoops % LoopReportModulus) == (LoopReportModulus -1))
          { // speed gauge
            sprintf(Message, "%d loops in %.2fs (%.1f us / loop)",
                             (int)NLoops,
                             (float)msLoopingTime / 1000.0,
                             1000 * (float)msLoopingTime / (float)NLoops);
            Infrastructure.SayInIDE(Message);
            //TellWindows(Message, btwLoopTiming);
            NLoops = 0;
            msLoopingTime = 0;
          } // speed gauge
      } // timing the loop
      
    if (Infrastructure.InIDE)
      { Infrastructure.Blink(1); }
  } // loop
