diff --git a/terminal_keyboard_emulator.ino b/terminal_keyboard_emulator.ino index 364863e..5d8cf7d 100644 --- a/terminal_keyboard_emulator.ino +++ b/terminal_keyboard_emulator.ino @@ -1,27 +1,39 @@ +// Resources: +// [Consul 262.4 Converter] https://deskthority.net/viewtopic.php?t=26908 +// [Consul 262.5 manual in CS] http://www.sapi.cz/prislusenstvi/c262-5.php#odkazp4 + #include -// config: +// pinout config const int pinData = 6; const int pinStatus = 7; +const int clockPin = 5; +const int dataPin = 3; +const int outPin = 4; +const int speakerPin = 6; -// fixed values -const int timerDelay = 530; +// constant config +const int slaveClockDivider = 16; +const int timerDelay = 530 / slaveClockDivider; -void setup(void) -{ - pinMode(pinData, OUTPUT); - digitalWrite(pinData, HIGH); - - Timer1.initialize(timerDelay); - Timer1.attachInterrupt(clockCycle); - Timer1.stop(); - - pinMode(pinStatus, INPUT_PULLUP); - attachInterrupt(digitalPinToInterrupt(pinStatus), statusCycle, CHANGE); - - Serial.begin(9600); -} +// variables +volatile int slaveClockStep = 0; +char m[255]; +volatile int data = 0; +int test = 0; +volatile int counter = 0; +int numbits = 10; +// MODS >>> +// [1] send debug scancode information to serial port +bool modConsoleLog = true; +// [2] play speaker sounds of keys +bool modKeySounds = true; +// <<< MODS + +// ---------- +// KBD Output +// ---------- volatile long lastChange = 0; volatile int x = 0; volatile int dataWord = 0; @@ -34,25 +46,21 @@ volatile bool nextKeyReady = false; volatile byte nextKey = 0; void typeKey(byte key) { - //noInterrupts(); nextKey = key; nextKeyReady = true; - //interrupts(); } void sendKey(byte key) { - //noInterrupts(); dataWord = key; dataState = 8; dataDelay = 0; packetDelay = 0; packetTail = 15; - //interrupts(); - Timer1.initialize(timerDelay); - Timer1.start(); + //Timer1.initialize(timerDelay); + //Timer1.start(); } -void statusCycle() { +void onHostStatusChange() { long timeNow = millis(); long changeDiff = timeNow - lastChange; lastChange = timeNow; @@ -62,7 +70,7 @@ void statusCycle() { } } -void clockCycle(void) +void onHostClockCycle(void) { int dataBit = HIGH; if (packetDelay > 0) { @@ -78,22 +86,150 @@ void clockCycle(void) packetTail--; dataBit = LOW; } else { - Timer1.stop(); + //Timer1.stop(); } digitalWrite(pinData, dataBit); } -int xx = 0; + +// --------- +// KBD Input +// --------- +const int receivingSteps = 16; +volatile int clockStep = 0; +volatile int receivingStep = 0; +volatile int receivingData = 0; +volatile int receivingBit = 0; + +void onSlaveClockInterrupt() { + clockStep = (clockStep + 1) % 2; + int clockValue = (clockStep % 2) ? HIGH : LOW; + digitalWrite(clockPin, clockValue); + int dataBit = digitalRead(dataPin); + if (clockValue == LOW) { + if (receivingData == 0 && dataBit == LOW) { + receivingData = 1; + receivingStep = 0; + receivingBit = 0; + test = 0; + digitalWrite(outPin, HIGH); + } else if (receivingData == 1) { + receivingStep++; + digitalWrite(outPin, HIGH); + } + if (receivingData == 1 && test == 0) { + test = 1; + receivingBit += dataBit == HIGH ? 1 : 0; + if (receivingStep >= receivingSteps) { + if (counter <= 8) { + data = data >> 1; + if (receivingBit > receivingSteps / 2) { + bitSet(data, 7); + } + } + counter++; + receivingStep = 0; + receivingBit = 0; + digitalWrite(outPin, LOW); + if (counter >= numbits) { + receivingData = 0; + } + } + } + } + if (clockValue == HIGH && test == 1) { + test = 0; + } +} + +void setupKeyMapping() { +} + +char translateKeyToChar(int key) { + if (sizeof(m) <= key) { + return 0; + } + return m[key]; +} + +void printChar(char keyChar) { + Serial.print("'"); Serial.print(keyChar); Serial.print("' ("); Serial.print(int(keyChar)); Serial.println(")"); +} + +void processKbdByte(int data) { + int key = data; + if (modConsoleLog) { + Serial.print("Key: <"); Serial.print(int(key)); Serial.print("> "); + } + char keyChar = translateKeyToChar(key); + + #ifdef KEYBOARD + Keyboard.press(keyChar); + delay(10); + Keyboard.release(keyChar); + #endif + + if (modConsoleLog) { + Serial.print("Press: "); + printChar(keyChar); + } +} + +// ---------------------- +// Input and Output Merge +// ---------------------- +void onTimerInterrupt() +{ + onSlaveClockInterrupt(); + + slaveClockStep = (slaveClockStep + 1) % slaveClockDivider; + if (slaveClockStep == 0) { + onHostClockCycle(); + } +} + +// ---- +// Main +// ---- +void setup(void) +{ + Serial.begin(9600); + + setupKeyMapping(); + + pinMode(pinData, OUTPUT); + pinMode(dataPin, INPUT); + pinMode(outPin, OUTPUT); + pinMode(clockPin, OUTPUT); + pinMode(pinStatus, INPUT_PULLUP); + + digitalWrite(pinData, HIGH); + digitalWrite(outPin, LOW); + + attachInterrupt(digitalPinToInterrupt(pinStatus), onHostStatusChange, CHANGE); + + Timer1.initialize(timerDelay); + Timer1.attachInterrupt(onTimerInterrupt); + //Timer1.stop(); + + Serial.println("Keyboard ready"); + tone(speakerPin, 80, 50); +} + void loop(void) { - delay(500); - typeKey(44 + xx); - xx = (xx+1) % 20; - - /*if (!nextKeyReady && Serial.available() > 0) { + // type key from serial + if (!nextKeyReady && Serial.available() > 0) { long key = Serial.parseInt(SKIP_ALL); if (key != 0) { typeKey(key); } - }*/ + } + // type key from keyboard + if (counter >= numbits) { + processKbdByte(data); + if (modKeySounds) tone(speakerPin, 60 + int(data), 25); + data = B0; + counter = 0; + } }