// Generate three phase square wave using lookup table
// and direct port manipulation

// Change direction (phase sequence) with pushbutton

const byte fwdTable[] {5, 1, 3, 2, 6, 4}; // output bit pattern
const byte revTable[] {3, 1, 5, 4, 6, 2}; // output bit pattern
const byte revSwitch = 11;
unsigned long tickInterval = 400;

// Using analog pins since they're uncommitted
const byte phaseO = A0;
const byte phaseY = A1;
const byte phaseB = A2;

void setup() {
  Serial.begin(115200);

  pinMode(phaseO, OUTPUT);
  pinMode(phaseY, OUTPUT);
  pinMode(phaseB, OUTPUT);
  pinMode(revSwitch, INPUT_PULLUP);
}

void loop() {
  static byte portData, phaseIndex;
  static unsigned long currentMillis;
  int channelO, channelY, channelB;
  
  if (millis() - currentMillis >= tickInterval) { // time to update
    byte fwdRev = digitalRead(revSwitch);
    // read port, clear low three bits
    portData = PINC & 0xf8;

    if (fwdRev) {
      portData |= fwdTable[phaseIndex++];  // Mask in the table data by OR'ing
    }
    else {
      portData |= revTable[phaseIndex++];  // and increment the index for next time
    }

    PORTC = portData; // Write the new data back out to the port
    currentMillis = millis(); // reset timer

    //    Serial.print(phaseIndex);
    //    Serial.print("\t");
    //    Serial.print(portData, BIN);
    //    Serial.println();

    //  Serial plotter code

    //  control analog values to simulate 'scope presentation on serial plotter
    if (portData & 0x1) channelO = 250;
    else channelO = 240;
    if (portData & 0x2) channelY = 230;
    else channelY = 220;
    if (portData & 0x4) channelB = 210;
    else channelB = 200;

  }

  if (phaseIndex > 5) phaseIndex = 0; // start over at index zero

  if (millis() % 800) {

    Serial.print("R: "); Serial.print(channelO); Serial.print("  ");
    Serial.print("G: "); Serial.print(channelY); Serial.print("  ");
    Serial.print("B: "); Serial.print(channelB); Serial.println("");
  }

}
FWD/REV