 
 #ifndef TESTING
   // TTY is 110 baud, 8-bit-word, two stop bits, no parity
-  HWSERIAL.begin(110, SERIAL_8N2);
-#endif
+  HWSERIAL.begin(BAUDRATE); //, SERIAL_8N2);
+#endif
+
+  millisSinceActivity = 0;
+  
+  delay(100);
+  readOptions();
 }
 
 


/**
 * Teletype Model 33 USB driver using Teensy 3
 *
 * ASR33 teletype connects to the hardware serial port, via 20mA current-loop.
 * USB serial connects to the host system.
 * This driver performs character translation and other functions.
 */


// TODO 'esc' may be codepoint 126, check & send as modern ESC


// The teletype's serial interface is a 20mA current loop:
//   110 baud
//   One start bit
//   7 data bits
//   Even parity (one bit)
//   Two stop bits
// So the total frame size is 11 bits.
//
// The UART does not have direct support for even parity plus two stop bits.

void loop() {
  int incomingByte;

  if (isTestMode) {
    // print a test sequence
    digitalWrite(PIN_INTERNAL_LED, HIGH);
    selfTest();
  }
  digitalWrite(PIN_INTERNAL_LED, LOW);

  if (HWSERIAL.available() > 0) {
    millisSinceActivity = 0;
    waitAlign();
    incomingByte = HWSERIAL.read();
    incomingByte = processTTYByte(incomingByte);
  }

  if (Serial.available() > 0) {
    millisSinceActivity = 0;
    waitAlign();
    incomingByte = Serial.read();
    incomingByte = processUSBByte(incomingByte);
  } 

  if (millisSinceActivity > 1000) {
    waitAlign();
    HWSERIAL.setBreak();
  }

}


void waitAlign() {
  // align to 10th of a second to spare the clutch
  while ((millisSinceActivity % 100) != 0) {}
}


void readOptions() {
  isTestMode     = !digitalRead(PIN_PUSH_TEST);
  isTxUCLC       = !digitalRead(PIN_TX_UCLC);
  isTxFoldSlash  = !digitalRead(PIN_TX_FOLDSLASH);
  isTxUtf8Arrows = !digitalRead(PIN_TX_UTF8ARROWS);
  isTx8BitClean  = !digitalRead(PIN_TX_8BITCLEAN);
  isRxNLCR       = !digitalRead(PIN_RX_NLCR);
  isRxEvenParity = !digitalRead(PIN_RX_EVENPARITY);
  isRxDelays     = !digitalRead(PIN_RX_DELAYS);
  isRx8BitClean  = !digitalRead(PIN_RX_8BITCLEAN);

#ifdef DEBUG_ALL
  Serial.print("Tx 8-bit clean? ");  Serial.println(yesno(isTx8BitClean));
  if (!isTx8BitClean) {
    Serial.print("Tx UC->LC fold? ");  Serial.println(yesno(isTxUCLC));
    Serial.print("Tx Fold escape? ");  Serial.println(yesno(isTxFoldSlash));
    Serial.print("Tx UTF8 arrows? ");  Serial.println(yesno(isTxUtf8Arrows));
  }
  Serial.print("Rx LF -> CR+LF? ");  Serial.println(yesno(isRxNLCR));
  Serial.print("Rx Even Parity? ");  Serial.println(yesno(isRxEvenParity));
  Serial.print("Rx CRLF Delays? ");  Serial.println(yesno(isRxDelays));
  Serial.print("Rx 8-bit clean? ");  Serial.println(yesno(isRx8BitClean));
#endif
}


// ---- Bytes from TTY to USB

void printTTY(const char *s) {
  for(uint i=0; i<strlen(s); s++) {
    sendToTTY(s[i]);
  }
}


int processUSBByte(int b)
{
#ifdef DEBUG_ALL
  Serial.print("Received from USB: ");
  Serial.write(b);
  Serial.print(" = 0x");
  Serial.println(b, HEX);
#endif

  if (!isRx8BitClean) {
    if (isRxNLCR) {
      // TODO linefeed conversion, LF => CR+LF
      if ((b==LF) && (prevUSBByte!=CR)) {
        // write a CR first
        sendToTTY(CR);
      }
    }
  }

  prevUSBByte = b;
  sendToTTY(b);
  return b;
}


void sendToTTY(int b) {

  if (!isRx8BitClean) {
    // When sending to the tty, normally the parity bit will be set '1'
    // Optionally can set even-parity
    bool pbit = 1;
    if (isRxEvenParity) {
      pbit = parity(b);
#ifdef DEBUG_ALL
//    Serial.print("Parity ");
//    Serial.println(pbit, DEC);
#endif
    }
    // TODO set the parity bit
  }

#ifdef DEBUG_ALL
  Serial.print("Sending to TTY: ");
  Serial.write(b);
  Serial.print(" = 0x");
  Serial.println(b, HEX);
#endif

  // Print the received byte at the teletype
  // HWSERIAL.flush();
  while (HWSERIAL.isReading()) {}
  HWSERIAL.write((uint8_t)0);
  digitalWrite(PIN_INTERNAL_LED, HIGH);
  HWSERIAL.write(b);
  while (HWSERIAL.isWriting()) {}
  digitalWrite(PIN_INTERNAL_LED, LOW);
  delay(1);

  // CR/LF delays apply even on the 8-bit-clean path
  if (isRxDelays) {
    if (b==CR) {
      // Add delay after carriage return (200m or more)
      sendToTTY(0);
      sendToTTY(0);
      //sendToTTY(0);
    }
    if (b==LF) {
      // Add delay after line feed
      sendToTTY(0);
      //sendToTTY(0);
    }
  }

