// Please note that automatic in-circuit verification is not working yet ;)
#include <stdint.h>

// Expected outputs (7 bits as hex values)
uint8_t expected[32] = {0x7D, 0x77, 0x1F, 0x0D, 0x3D, 0x4F, 0x47, 0x5E, 0x17, 0x06, 0x3C, 0x57, 0x0E, 0x54, 0x15, 0x7E, 0x67, 0x73, 0x05, 0x5B, 0x0F, 0x3E, 0x2A, 0x2B, 0x37, 0x3B, 0x6C, 0x4E, 0x12, 0x78, 0x40, 0x08};

void setup() {
  bool tests_passed = true;
  Serial.begin(230400);

  // initialize digital pin LED_BUILTIN as an output
  // note that pins 1 and 0 are used for Serial (UART) and should not be used
  // as GPIO pins
  pinMode(14, OUTPUT); // input a
  pinMode(15, OUTPUT); // input b
  pinMode(2, OUTPUT); // input c
  pinMode(3, OUTPUT); // input d
  pinMode(4, OUTPUT); // input e
  // TODO: - add one LED to signal test is running
  //       - add another two LEDs to signal if 
  //         ALL tests have passed or ANY test has failed

  pinMode(6, INPUT); // output A
  pinMode(7, INPUT); // output B
  pinMode(8, INPUT); // output C
  pinMode(9, INPUT); // output D
  pinMode(10, INPUT); // output E
  pinMode(11, INPUT); // output F
  pinMode(12, INPUT); // output G

  Serial.println("Testing all input combinations.");

  /* cycle from '@' / 0x40 to '_' / 0x5F */
  for(uint8_t character = '@'; character <= '_'; character++)
  {
    set_character(character);

    // wait some time before checking outputs
    delay(300);

    tests_passed &= verify_outputs(character);

    delay(400);
  }

  Serial.println();
  if(tests_passed)
  {
    Serial.println("[PASSED]");
  }
  else
  {
    Serial.println("[FAILED]");
  }
}

void set_character(uint8_t character)
{
  // set logic design inputs at Arduino's output pins
  digitalWrite(15, character & (1 << 0));
  digitalWrite(14, character & (1 << 1));
  digitalWrite(2, character & (1 << 2));
  digitalWrite(3, character & (1 << 3));
  digitalWrite(4, character & (1 << 4));

  Serial.print("Wrote character '");
  Serial.write(character);
  Serial.println("'");
}

bool verify_outputs(uint8_t character)
{
  // read value from logic design outputs at Arduino's input pins
 
  uint8_t outputs = 0; 
  outputs |= digitalRead(6);
  outputs <<= 1;
  outputs |= digitalRead(7);
  outputs <<= 1;
  outputs |= digitalRead(8);
  outputs <<= 1;
  outputs |= digitalRead(9);
  outputs <<= 1;
  outputs |= digitalRead(10);
  outputs <<= 1;
  outputs |= digitalRead(11);
  outputs <<= 1;
  outputs |= digitalRead(12);
  // 8 bit variable; so MSB is not set
  Serial.print("  Read back ");

  // print single bits to make sure that no preceeding zeros are cut off
  //Serial.print(outputs, BIN);
  Serial.print((outputs >> 6) & 1, BIN);
  Serial.print((outputs >> 5) & 1, BIN);
  Serial.print((outputs >> 4) & 1, BIN);
  Serial.print((outputs >> 3) & 1, BIN);
  Serial.print((outputs >> 2) & 1, BIN);
  Serial.print((outputs >> 1) & 1, BIN);
  Serial.print((outputs >> 0) & 1, BIN);

  Serial.print("b / 0x");
  Serial.print(outputs, HEX);

  Serial.print(" == 0x");
  Serial.print(expected[character & 0x1F], HEX);

  if( outputs == expected[character & 0x1F] )
  {
    Serial.println("? [PASS]");
    return true;
  }
  else
  {
    Serial.println("? [FAIL]");
    return false;
  }
}

void loop() {
  /* no need to loop */
}
mega:SCL
mega:SDA
mega:AREF
mega:GND.1
mega:13
mega:12
mega:11
mega:10
mega:9
mega:8
mega:7
mega:6
mega:5
mega:4
mega:3
mega:2
mega:1
mega:0
mega:14
mega:15
mega:16
mega:17
mega:18
mega:19
mega:20
mega:21
mega:5V.1
mega:5V.2
mega:22
mega:23
mega:24
mega:25
mega:26
mega:27
mega:28
mega:29
mega:30
mega:31
mega:32
mega:33
mega:34
mega:35
mega:36
mega:37
mega:38
mega:39
mega:40
mega:41
mega:42
mega:43
mega:44
mega:45
mega:46
mega:47
mega:48
mega:49
mega:50
mega:51
mega:52
mega:53
mega:GND.4
mega:GND.5
mega:IOREF
mega:RESET
mega:3.3V
mega:5V
mega:GND.2
mega:GND.3
mega:VIN
mega:A0
mega:A1
mega:A2
mega:A3
mega:A4
mega:A5
mega:A6
mega:A7
mega:A8
mega:A9
mega:A10
mega:A11
mega:A12
mega:A13
mega:A14
mega:A15
input_a:IN
input_a:OUT
input_not_a:IN
input_not_a:OUT
input_b:IN
input_b:OUT
input_not_b:IN
input_not_b:OUT
input_c:IN
input_c:OUT
input_not_c:IN
input_not_c:OUT
input_d:IN
input_d:OUT
input_not_d:IN
input_not_d:OUT
input_e:IN
input_e:OUT
input_not_e:IN
input_not_e:OUT
gate_and_0:A
gate_and_0:B
gate_and_0:OUT
gate_and_1:A
gate_and_1:B
gate_and_1:OUT
gate_and_2:A
gate_and_2:B
gate_and_2:OUT
gate_and_3:A
gate_and_3:B
gate_and_3:OUT
gate_and_4:A
gate_and_4:B
gate_and_4:OUT
gate_and_5:A
gate_and_5:B
gate_and_5:OUT
gate_and_6:A
gate_and_6:B
gate_and_6:OUT
gate_and_7:A
gate_and_7:B
gate_and_7:OUT
gate_and_8:A
gate_and_8:B
gate_and_8:OUT
gate_and_9:A
gate_and_9:B
gate_and_9:OUT
gate_and_10:A
gate_and_10:B
gate_and_10:OUT
gate_and_11:A
gate_and_11:B
gate_and_11:OUT
gate_and_12:A
gate_and_12:B
gate_and_12:OUT
gate_and_13:A
gate_and_13:B
gate_and_13:OUT
gate_and_14:A
gate_and_14:B
gate_and_14:OUT
gate_and_15:A
gate_and_15:B
gate_and_15:OUT
gate_and_16:A
gate_and_16:B
gate_and_16:OUT
gate_and_17:A
gate_and_17:B
gate_and_17:OUT
gate_and_18:A
gate_and_18:B
gate_and_18:OUT
gate_and_19:A
gate_and_19:B
gate_and_19:OUT
gate_and_20:A
gate_and_20:B
gate_and_20:OUT
gate_and_21:A
gate_and_21:B
gate_and_21:OUT
gate_and_22:A
gate_and_22:B
gate_and_22:OUT
gate_and_23:A
gate_and_23:B
gate_and_23:OUT
gate_and_24:A
gate_and_24:B
gate_and_24:OUT
gate_and_25:A
gate_and_25:B
gate_and_25:OUT
gate_and_26:A
gate_and_26:B
gate_and_26:OUT
gate_and_27:A
gate_and_27:B
gate_and_27:OUT
gate_and_28:A
gate_and_28:B
gate_and_28:OUT
gate_and_29:A
gate_and_29:B
gate_and_29:OUT
gate_and_30:A
gate_and_30:B
gate_and_30:OUT
gate_and_31:A
gate_and_31:B
gate_and_31:OUT
gate_and_32:A
gate_and_32:B
gate_and_32:OUT
gate_and_33:A
gate_and_33:B
gate_and_33:OUT
gate_and_34:A
gate_and_34:B
gate_and_34:OUT
gate_and_35:A
gate_and_35:B
gate_and_35:OUT
gate_and_36:A
gate_and_36:B
gate_and_36:OUT
gate_and_37:A
gate_and_37:B
gate_and_37:OUT
gate_and_38:A
gate_and_38:B
gate_and_38:OUT
gate_and_39:A
gate_and_39:B
gate_and_39:OUT
gate_and_40:A
gate_and_40:B
gate_and_40:OUT
gate_and_41:A
gate_and_41:B
gate_and_41:OUT
gate_and_42:A
gate_and_42:B
gate_and_42:OUT
gate_and_43:A
gate_and_43:B
gate_and_43:OUT
gate_and_44:A
gate_and_44:B
gate_and_44:OUT
gate_and_45:A
gate_and_45:B
gate_and_45:OUT
gate_and_46:A
gate_and_46:B
gate_and_46:OUT
gate_and_47:A
gate_and_47:B
gate_and_47:OUT
gate_and_48:A
gate_and_48:B
gate_and_48:OUT
gate_and_49:A
gate_and_49:B
gate_and_49:OUT
gate_and_50:A
gate_and_50:B
gate_and_50:OUT
gate_and_51:A
gate_and_51:B
gate_and_51:OUT
gate_and_52:A
gate_and_52:B
gate_and_52:OUT
gate_and_53:A
gate_and_53:B
gate_and_53:OUT
gate_and_54:A
gate_and_54:B
gate_and_54:OUT
gate_and_55:A
gate_and_55:B
gate_and_55:OUT
gate_and_56:A
gate_and_56:B
gate_and_56:OUT
gate_and_57:A
gate_and_57:B
gate_and_57:OUT
gate_and_58:A
gate_and_58:B
gate_and_58:OUT
gate_and_59:A
gate_and_59:B
gate_and_59:OUT
gate_and_60:A
gate_and_60:B
gate_and_60:OUT
gate_and_61:A
gate_and_61:B
gate_and_61:OUT
gate_and_62:A
gate_and_62:B
gate_and_62:OUT
gate_and_63:A
gate_and_63:B
gate_and_63:OUT
gate_and_64:A
gate_and_64:B
gate_and_64:OUT
gate_and_65:A
gate_and_65:B
gate_and_65:OUT
gate_and_66:A
gate_and_66:B
gate_and_66:OUT
gate_and_67:A
gate_and_67:B
gate_and_67:OUT
gate_and_68:A
gate_and_68:B
gate_and_68:OUT
gate_and_69:A
gate_and_69:B
gate_and_69:OUT
gate_and_70:A
gate_and_70:B
gate_and_70:OUT
gate_and_71:A
gate_and_71:B
gate_and_71:OUT
gate_and_72:A
gate_and_72:B
gate_and_72:OUT
gate_and_73:A
gate_and_73:B
gate_and_73:OUT
gate_and_74:A
gate_and_74:B
gate_and_74:OUT
gate_and_75:A
gate_and_75:B
gate_and_75:OUT
gate_and_76:A
gate_and_76:B
gate_and_76:OUT
gate_and_77:A
gate_and_77:B
gate_and_77:OUT
gate_and_78:A
gate_and_78:B
gate_and_78:OUT
gate_and_79:A
gate_and_79:B
gate_and_79:OUT
gate_and_80:A
gate_and_80:B
gate_and_80:OUT
gate_and_81:A
gate_and_81:B
gate_and_81:OUT
gate_and_82:A
gate_and_82:B
gate_and_82:OUT
gate_and_83:A
gate_and_83:B
gate_and_83:OUT
gate_and_84:A
gate_and_84:B
gate_and_84:OUT
gate_and_85:A
gate_and_85:B
gate_and_85:OUT
gate_and_86:A
gate_and_86:B
gate_and_86:OUT
gate_and_87:A
gate_and_87:B
gate_and_87:OUT
gate_and_88:A
gate_and_88:B
gate_and_88:OUT
gate_and_89:A
gate_and_89:B
gate_and_89:OUT
gate_and_90:A
gate_and_90:B
gate_and_90:OUT
gate_and_91:A
gate_and_91:B
gate_and_91:OUT
gate_and_92:A
gate_and_92:B
gate_and_92:OUT
gate_and_93:A
gate_and_93:B
gate_and_93:OUT
gate_and_94:A
gate_and_94:B
gate_and_94:OUT
gate_and_95:A
gate_and_95:B
gate_and_95:OUT
gate_and_96:A
gate_and_96:B
gate_and_96:OUT
gate_and_97:A
gate_and_97:B
gate_and_97:OUT
gate_and_98:A
gate_and_98:B
gate_and_98:OUT
gate_and_99:A
gate_and_99:B
gate_and_99:OUT
gate_and_100:A
gate_and_100:B
gate_and_100:OUT
gate_and_101:A
gate_and_101:B
gate_and_101:OUT
gate_and_102:A
gate_and_102:B
gate_and_102:OUT
gate_and_103:A
gate_and_103:B
gate_and_103:OUT
gate_and_104:A
gate_and_104:B
gate_and_104:OUT
gate_and_105:A
gate_and_105:B
gate_and_105:OUT
gate_and_106:A
gate_and_106:B
gate_and_106:OUT
gate_and_107:A
gate_and_107:B
gate_and_107:OUT
gate_and_108:A
gate_and_108:B
gate_and_108:OUT
gate_and_109:A
gate_and_109:B
gate_and_109:OUT
gate_and_110:A
gate_and_110:B
gate_and_110:OUT
gate_and_111:A
gate_and_111:B
gate_and_111:OUT
gate_and_112:A
gate_and_112:B
gate_and_112:OUT
gate_and_113:A
gate_and_113:B
gate_and_113:OUT
gate_and_114:A
gate_and_114:B
gate_and_114:OUT
gate_and_115:A
gate_and_115:B
gate_and_115:OUT
gate_and_116:A
gate_and_116:B
gate_and_116:OUT
gate_and_117:A
gate_and_117:B
gate_and_117:OUT
gate_and_118:A
gate_and_118:B
gate_and_118:OUT
gate_and_119:A
gate_and_119:B
gate_and_119:OUT
gate_and_120:A
gate_and_120:B
gate_and_120:OUT
gate_and_121:A
gate_and_121:B
gate_and_121:OUT
gate_and_122:A
gate_and_122:B
gate_and_122:OUT
gate_and_123:A
gate_and_123:B
gate_and_123:OUT
gate_and_124:A
gate_and_124:B
gate_and_124:OUT
gate_and_125:A
gate_and_125:B
gate_and_125:OUT
gate_and_126:A
gate_and_126:B
gate_and_126:OUT
gate_and_127:A
gate_and_127:B
gate_and_127:OUT
gate_and_128:A
gate_and_128:B
gate_and_128:OUT
gate_and_129:A
gate_and_129:B
gate_and_129:OUT
gate_and_130:A
gate_and_130:B
gate_and_130:OUT
gate_and_131:A
gate_and_131:B
gate_and_131:OUT
gate_and_132:A
gate_and_132:B
gate_and_132:OUT
gate_and_133:A
gate_and_133:B
gate_and_133:OUT
gate_and_134:A
gate_and_134:B
gate_and_134:OUT
gate_and_135:A
gate_and_135:B
gate_and_135:OUT
gate_and_136:A
gate_and_136:B
gate_and_136:OUT
gate_and_137:A
gate_and_137:B
gate_and_137:OUT
gate_and_138:A
gate_and_138:B
gate_and_138:OUT
gate_and_139:A
gate_and_139:B
gate_and_139:OUT
gate_and_140:A
gate_and_140:B
gate_and_140:OUT
gate_and_141:A
gate_and_141:B
gate_and_141:OUT
gate_and_142:A
gate_and_142:B
gate_and_142:OUT
gate_and_143:A
gate_and_143:B
gate_and_143:OUT
gate_and_144:A
gate_and_144:B
gate_and_144:OUT
gate_and_145:A
gate_and_145:B
gate_and_145:OUT
gate_and_146:A
gate_and_146:B
gate_and_146:OUT
gate_and_147:A
gate_and_147:B
gate_and_147:OUT
gate_and_148:A
gate_and_148:B
gate_and_148:OUT
gate_and_149:A
gate_and_149:B
gate_and_149:OUT
gate_and_150:A
gate_and_150:B
gate_and_150:OUT
gate_and_151:A
gate_and_151:B
gate_and_151:OUT
gate_and_152:A
gate_and_152:B
gate_and_152:OUT
gate_or_0:A
gate_or_0:B
gate_or_0:OUT
gate_or_1:A
gate_or_1:B
gate_or_1:OUT
gate_or_2:A
gate_or_2:B
gate_or_2:OUT
gate_or_3:A
gate_or_3:B
gate_or_3:OUT
gate_or_4:A
gate_or_4:B
gate_or_4:OUT
gate_or_5:A
gate_or_5:B
gate_or_5:OUT
gate_or_6:A
gate_or_6:B
gate_or_6:OUT
gate_or_7:A
gate_or_7:B
gate_or_7:OUT
gate_or_8:A
gate_or_8:B
gate_or_8:OUT
gate_or_9:A
gate_or_9:B
gate_or_9:OUT
gate_or_10:A
gate_or_10:B
gate_or_10:OUT
gate_or_11:A
gate_or_11:B
gate_or_11:OUT
gate_or_12:A
gate_or_12:B
gate_or_12:OUT
gate_or_13:A
gate_or_13:B
gate_or_13:OUT
gate_or_14:A
gate_or_14:B
gate_or_14:OUT
gate_or_15:A
gate_or_15:B
gate_or_15:OUT
gate_or_16:A
gate_or_16:B
gate_or_16:OUT
gate_or_17:A
gate_or_17:B
gate_or_17:OUT
gate_or_18:A
gate_or_18:B
gate_or_18:OUT
gate_or_19:A
gate_or_19:B
gate_or_19:OUT
gate_or_20:A
gate_or_20:B
gate_or_20:OUT
gate_or_21:A
gate_or_21:B
gate_or_21:OUT
gate_or_22:A
gate_or_22:B
gate_or_22:OUT
gate_or_23:A
gate_or_23:B
gate_or_23:OUT
gate_or_24:A
gate_or_24:B
gate_or_24:OUT
gate_or_25:A
gate_or_25:B
gate_or_25:OUT
gate_or_26:A
gate_or_26:B
gate_or_26:OUT
gate_or_27:A
gate_or_27:B
gate_or_27:OUT
gate_or_28:A
gate_or_28:B
gate_or_28:OUT
gate_or_29:A
gate_or_29:B
gate_or_29:OUT
gate_or_30:A
gate_or_30:B
gate_or_30:OUT
gate_or_31:A
gate_or_31:B
gate_or_31:OUT
gate_or_32:A
gate_or_32:B
gate_or_32:OUT
gate_or_33:A
gate_or_33:B
gate_or_33:OUT
gate_or_34:A
gate_or_34:B
gate_or_34:OUT
gate_or_35:A
gate_or_35:B
gate_or_35:OUT
gate_or_36:A
gate_or_36:B
gate_or_36:OUT
gate_or_37:A
gate_or_37:B
gate_or_37:OUT
gate_or_38:A
gate_or_38:B
gate_or_38:OUT
gate_or_39:A
gate_or_39:B
gate_or_39:OUT
gate_or_40:A
gate_or_40:B
gate_or_40:OUT
gate_or_41:A
gate_or_41:B
gate_or_41:OUT
gate_or_42:A
gate_or_42:B
gate_or_42:OUT
gate_or_43:A
gate_or_43:B
gate_or_43:OUT
gate_or_44:A
gate_or_44:B
gate_or_44:OUT
gate_or_45:A
gate_or_45:B
gate_or_45:OUT
gate_or_46:A
gate_or_46:B
gate_or_46:OUT
gate_or_47:A
gate_or_47:B
gate_or_47:OUT
gate_or_48:A
gate_or_48:B
gate_or_48:OUT
gate_or_49:A
gate_or_49:B
gate_or_49:OUT
gate_or_50:A
gate_or_50:B
gate_or_50:OUT
output_A:IN
output_A:OUT
output_B:IN
output_B:OUT
output_C:IN
output_C:OUT
output_D:IN
output_D:OUT
output_E:IN
output_E:OUT
output_F:IN
output_F:OUT
output_G:IN
output_G:OUT
sevseg1:COM.1
sevseg1:COM.2
sevseg1:A
sevseg1:B
sevseg1:C
sevseg1:D
sevseg1:E
sevseg1:F
sevseg1:G
sevseg1:DP
pwr1:GND