Converter for Consul 262.5 terminal keyboard and VDX 52600 terminal.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
5.1 KiB

  1. // Resources:
  2. // [Consul 262.4 Converter] https://deskthority.net/viewtopic.php?t=26908
  3. // [Consul 262.5 manual in CS] http://www.sapi.cz/prislusenstvi/c262-5.php#odkazp4
  4. #include <TimerOne.h>
  5. // pinout config
  6. const int pinData = 6; // out, host data
  7. const int pinStatus = 7; // in, host status
  8. const int clockPin = 5; // out, kbd clock
  9. const int dataPin = 3; // in, kbd data
  10. const int outPin = 4; // out, kbd led
  11. // constant config
  12. const int slaveClockDivider = 4;
  13. const int timerDelay = 528 / slaveClockDivider;
  14. // variables
  15. volatile int slaveClockStep = 0;
  16. char m[255];
  17. volatile int data = 0;
  18. int test = 0;
  19. volatile int counter = 0;
  20. int numbits = 10;
  21. // MODS >>>
  22. // [1] send debug scancode information to serial port
  23. bool modConsoleLog = true;
  24. // <<< MODS
  25. // ----------
  26. // KBD Output
  27. // ----------
  28. volatile long lastChange = 0;
  29. volatile int x = 0;
  30. volatile int dataWord = 0;
  31. volatile int dataState = 0;
  32. volatile int dataDelay = 0;
  33. volatile int packetDelay = 0;
  34. volatile int packetTail = 0;
  35. volatile bool nextKeyReady = false;
  36. volatile byte nextKey = 0;
  37. void typeKey(byte key) {
  38. nextKey = key;
  39. nextKeyReady = true;
  40. Serial.print("Typing key "); Serial.println((int) key);
  41. }
  42. void sendKey(byte key) {
  43. dataWord = key;
  44. dataState = 8;
  45. dataDelay = 0;
  46. packetDelay = 0;
  47. packetTail = 15;
  48. Serial.print("Sending key "); Serial.println((int) key);
  49. //Timer1.initialize(timerDelay);
  50. //Timer1.start();
  51. }
  52. void onHostStatusChange() {
  53. long timeNow = millis();
  54. long changeDiff = timeNow - lastChange;
  55. lastChange = timeNow;
  56. digitalWrite(pinData, digitalRead(pinStatus));
  57. if (changeDiff >= 10 && nextKeyReady) {
  58. nextKeyReady = false;
  59. Serial.println("Status change with key");
  60. sendKey(nextKey);
  61. }
  62. }
  63. void onHostClockCycle(void)
  64. {
  65. int dataBit = HIGH;
  66. if (packetDelay > 0) {
  67. packetDelay--;
  68. } else if (dataDelay > 0) {
  69. dataDelay--;
  70. dataBit = LOW;
  71. } else if (dataState > 0) {
  72. int bitToSend = (dataWord >> (dataState - 1)) & 1;
  73. dataBit = !bitToSend ? LOW : HIGH;
  74. dataState--;
  75. } else if (packetTail > 0) {
  76. packetTail--;
  77. dataBit = LOW;
  78. } else {
  79. //Timer1.stop();
  80. }
  81. digitalWrite(pinData, dataBit);
  82. }
  83. // ---------
  84. // KBD Input
  85. // ---------
  86. const int receivingSteps = 16;
  87. volatile int clockStep = 0;
  88. volatile int receivingStep = 0;
  89. volatile int receivingData = 0;
  90. volatile int receivingBit = 0;
  91. void onSlaveClockInterrupt() {
  92. clockStep = (clockStep + 1) % 2;
  93. int clockValue = (clockStep % 2) ? HIGH : LOW;
  94. digitalWrite(clockPin, clockValue);
  95. int dataBit = digitalRead(dataPin);
  96. if (clockValue == LOW) {
  97. if (receivingData == 0 && dataBit == LOW) {
  98. receivingData = 1;
  99. receivingStep = 0;
  100. receivingBit = 0;
  101. test = 0;
  102. digitalWrite(outPin, HIGH);
  103. } else if (receivingData == 1) {
  104. receivingStep++;
  105. digitalWrite(outPin, HIGH);
  106. }
  107. if (receivingData == 1 && test == 0) {
  108. test = 1;
  109. receivingBit += dataBit == HIGH ? 1 : 0;
  110. if (receivingStep >= receivingSteps) {
  111. if (counter <= 8) {
  112. data = data >> 1;
  113. if (receivingBit > receivingSteps / 2) {
  114. bitSet(data, 7);
  115. }
  116. }
  117. counter++;
  118. receivingStep = 0;
  119. receivingBit = 0;
  120. digitalWrite(outPin, LOW);
  121. if (counter >= numbits) {
  122. receivingData = 0;
  123. }
  124. }
  125. }
  126. }
  127. if (clockValue == HIGH && test == 1) {
  128. test = 0;
  129. }
  130. }
  131. void setupKeyMapping() {
  132. }
  133. char translateKeyToChar(int key) {
  134. if (sizeof(m) <= key) {
  135. return 0;
  136. }
  137. return key; //m[key];
  138. }
  139. void printChar(char keyChar) {
  140. Serial.print("'"); Serial.print(keyChar); Serial.print("' ("); Serial.print(int(keyChar)); Serial.println(")");
  141. }
  142. void processKbdByte(int data) {
  143. int key = data;
  144. if (modConsoleLog) {
  145. Serial.print("Key: <"); Serial.print(int(key)); Serial.print("> ");
  146. }
  147. char keyChar = translateKeyToChar(key);
  148. #ifdef KEYBOARD
  149. Keyboard.press(keyChar);
  150. delay(10);
  151. Keyboard.release(keyChar);
  152. #endif
  153. typeKey(keyChar);
  154. if (modConsoleLog) {
  155. Serial.print("Press: ");
  156. printChar(keyChar);
  157. }
  158. }
  159. // ----------------------
  160. // Input and Output Merge
  161. // ----------------------
  162. void onTimerInterrupt()
  163. {
  164. onSlaveClockInterrupt();
  165. slaveClockStep = (slaveClockStep + 1) % slaveClockDivider;
  166. if (slaveClockStep == 0) {
  167. onHostClockCycle();
  168. }
  169. }
  170. // ----
  171. // Main
  172. // ----
  173. void setup(void)
  174. {
  175. Serial.begin(9600);
  176. setupKeyMapping();
  177. pinMode(pinData, OUTPUT);
  178. pinMode(dataPin, INPUT);
  179. pinMode(outPin, OUTPUT);
  180. pinMode(clockPin, OUTPUT);
  181. pinMode(pinStatus, INPUT_PULLUP);
  182. digitalWrite(pinData, HIGH);
  183. digitalWrite(outPin, LOW);
  184. attachInterrupt(digitalPinToInterrupt(pinStatus), onHostStatusChange, CHANGE);
  185. Timer1.initialize(timerDelay);
  186. Timer1.attachInterrupt(onTimerInterrupt);
  187. //Timer1.stop();
  188. Serial.println("Keyboard ready");
  189. }
  190. void loop(void)
  191. {
  192. // type key from serial
  193. if (!nextKeyReady && Serial.available() > 0) {
  194. long key = Serial.parseInt(SKIP_ALL);
  195. if (key != 0) {
  196. typeKey(key);
  197. }
  198. }
  199. // type key from keyboard
  200. if (counter >= numbits) {
  201. processKbdByte(data);
  202. data = B0;
  203. counter = 0;
  204. }
  205. }