Да, я искал форумы Arduino.cc и здесь. Да, я нашел статьи, касающиеся библиотеки ps2dev. Да, я прочитал (хорошо, некоторые я просмотрел) статью об интерфейсе PS / 2 на этом сайте . Да, у меня это работает, вроде. Мне нужны идеи, чтобы сделать прыжок на полную мощность. :)
Нет, я не могу просто эмулировать USB HID Keyboard и оставить все как есть - это должна быть эмуляция PS / 2 Keyboard. Да, я посылаю правильные сигналы «сделай и сломай» - он даже обрабатывает очень сложные комбинации клавиш. На данный момент у меня есть код, написанный для моего Arduino, как указано ниже (технически это Freeduino 1.22), и я отправлял нажатия клавиш через терминал Serial Monitor или PuTTY, а также с помощью удобной оболочки / драйвера Python, которая отправляет фактические Информация о скан-коде PS / 2 - и вообще делает мою жизнь намного проще - также снимает часть нагрузки с Arduino.
Прямо сейчас у меня на Arduino работает эскиз, который имитирует клавиатуру PS / 2. Естественно, я должен загрузить свою «целевую» машину (машину, в которую входит PS / 2 Plug), и я вижу, что происходит «рукопожатие». Загрузитесь в WinDoze, откройте блокнот и нажмите на клавишу (успешно), используя мой «драйвер» Python. (Драйвер просто размещается на терминале Serial Monitor / PuTTY и читает / записывает в последовательный порт, используя модуль под названием PySerial.) Все это делается на материнской плате AMD in ASUS «target».
Теперь цель состоит в том, чтобы заставить его работать на моей «мишени» на материнской плате Intel, я подключаю его, загружаюсь и не играю в кости. Итак, я немного изменил эскиз, чтобы попытаться понять, что на самом деле происходит с моим маленьким другом Арди. Версия после модов отображается ниже. Насколько я понимаю (код был «заимствован» из другого поста на форуме Arduino.cc, здесь ) Он попытается установить соединение с «целью» через PS / 2 в первую очередь, мигая встроенным светодиодом в течение 0,5 секунды до тех пор, пока соединение установлено. Цель Intel не проходит через 5 секунд мигания, и последовательное соединение никогда не устанавливается с «хостом».
У меня такой вопрос: есть ли существенное различие в том, как клавиатуры ps / 2 устанавливают связь с целевым компьютером? Это действительно разница в дизайне, или я должен искать что-то более основное, что проблема здесь? Я слышал кое-что о необходимости подтягивающих резисторов на входах данных / тактовых импульсов, но это должно быть обработано в коде, особенно потому, что он РАБОТАЕТ на другой цели, но не на той, с которой мне нужно работать.
Есть идеи? Я бы хотел, чтобы это работало КАК МОЖНО СКОРЕЕ - я буду продолжать делать отладку, любые указания или предложения будут с благодарностью. Всем им будет уделено полное внимание, потому что мне нужно по-новому взглянуть на эту проблему. Возможно, нужна лучшая реализация в библиотеке ps2dev?
#include "ps2dev.h" // to emulate a PS/2 device
// Orange = 2
// Blue = 3
// Red = 5V (3 in)
// Black = GND (4 in)
// EXT Power, USB for COM only
PS2dev keyboard(3,2); // PS2dev object (2:data, 3:clock)
int enabled = 0; // pseudo variable for state of "keyboard"
boolean serialConnected = false;
int incomingByte = 0;
void ack() {
//acknowledge commands
while(keyboard.write(0xFA));
}
int kbdCmd(int command) {
unsigned char val;
switch (command) {
case 0xFF: //reset
ack();
//the while loop lets us wait for the host to be ready
while(keyboard.write(0xAA)!=0);
break;
case 0xFE: //resend
ack();
break;
case 0xF6: //set defaults
//enter stream mode
ack();
break;
case 0xF5: //disable data reporting
//FM
enabled = 0;
ack();
break;
case 0xF4: //enable data reporting
//FM
enabled = 1;
ack();
break;
case 0xF3: //set typematic rate
ack();
keyboard.read(&val); //do nothing with the rate
ack();
break;
case 0xF2: //get device id
ack();
keyboard.write(0xAB);
keyboard.write(0x83);
break;
case 0xF0: //set scan code set
ack();
keyboard.read(&val); //do nothing with the rate
ack();
break;
case 0xEE: //echo
//ack();
keyboard.write(0xEE);
break;
case 0xED: //set/reset LEDs
ack();
keyboard.read(&val); //do nothing with the rate
ack();
break;
}
}
void connectHost() {
while (Serial.available() <= 0) {
Serial.print('A'); // send a capital A
delay(300);
}
}
void setup() {
pinMode(13, OUTPUT);
//establish serial connection with host
Serial.begin(9600);
// establish ps/2 connection with target
while(keyboard.write(0xAA)!=0){
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(500);
}
delay(100);
connectHost();
Serial.println("\nSerial Host Connected");
Serial.flush();
}
void loop() {
unsigned char c;
if( (digitalRead(3)==LOW) || (digitalRead(2) == LOW)) {
if(digitalRead(3)==LOW){
Serial.println("pin 3 is LOW");
} else {
Serial.println("pin 2 is LOW");
}
while(keyboard.read(&c));
kbdCmd(c);
Serial.print("Target: 0x");
Serial.println(c, HEX);
}
else {//if host device wants to send a command:
//echo ASCII code from terminal and write to ps/2
if(Serial.available() > 0) {
incomingByte = Serial.read();
keyboard.write(incomingByte);
Serial.print("Host: 0x");
Serial.print(incomingByte, HEX);
Serial.print(" ");
Serial.print(incomingByte);
Serial.print(" ");
Serial.println(incomingByte, BIN);
}
}
}