|
|
@@ -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 <TimerOne.h> |
|
|
|
|
|
|
|
// 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; |
|
|
|
void loop(void) |
|
|
|
|
|
|
|
// --------- |
|
|
|
// 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) |
|
|
|
{ |
|
|
|
delay(500); |
|
|
|
typeKey(44 + xx); |
|
|
|
xx = (xx+1) % 20; |
|
|
|
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); |
|
|
|
} |
|
|
|
|
|
|
|
/*if (!nextKeyReady && Serial.available() > 0) { |
|
|
|
void loop(void) |
|
|
|
{ |
|
|
|
// 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; |
|
|
|
} |
|
|
|
} |
|
|
|
|