Sí, he buscado en los foros de Arduino.cc y aquí. Sí, he encontrado los artículos sobre la biblioteca ps2dev. Sí, he leído (bueno, algunos he leído) el artículo de la interfaz PS / 2 definitiva en este sitio web . Sí, tengo este trabajo, un poco. Necesito algunas ideas para dar el salto para trabajar plenamente. :)
No, no puedo simplemente emular un teclado USB HID y dejarlo así: tiene que ser una emulación de teclado PS / 2. Sí, estoy enviando señales correctas de marca y corte, incluso maneja combinaciones de teclas muy complicadas. Tal como está ahora, tengo un código escrito para mi Arduino como se muestra a continuación (técnicamente es un Freeduino 1.22), y he enviado pulsaciones de teclas a través del monitor Serial o el terminal PuTTY, así como con un envoltorio / controlador Python práctico que envía datos reales. La información de PS / 2 scancode, y en general hace que mi vida sea mucho más fácil, también quita algo de la carga del Arduino.
Ahora mismo, tengo un boceto en ejecución en el Arduino que emula un teclado PS / 2. Naturalmente, tengo que arrancar mi máquina "objetivo" (la máquina en la que se conecta el enchufe PS / 2), y veo que tiene lugar el "apretón de manos". Arranque en WinDoze, abra el bloc de notas y dirija las pulsaciones a la pantalla (con éxito) usando mi "controlador" de Python. (El controlador simplemente toma lugar en el terminal Serial Monitor / PuTTY y lee / escribe en el puerto serie usando un módulo llamado PySerial). Todo esto se hace en un AMD en la placa base de ASUS "target".
Ahora, el objetivo es hacer que funcione en mi Intel en el "objetivo" basado en la placa base de Intel, lo enchufo, arranco y no doy. Entonces, modifiqué un poco el boceto para intentar hacerme una idea de lo que realmente está pasando con mi pequeño amigo Ardy. La versión después de los mods se muestra a continuación. Como lo entiendo (el código fue "tomado prestado" de otra publicación del foro Arduino.cc, aquí ) Intentará establecer una conexión con el "objetivo" a través de PS / 2 primero, parpadeando el LED de a bordo durante un período de 0,5 segundos hasta que se establezca la conexión. El objetivo de Intel no pasa el parpadeo de .5 segundos y la conexión en serie nunca se establece con el "host".
Mi pregunta es la siguiente: ¿existe una diferencia importante en la forma en que los teclados ps / 2 establecen la comunicación con su máquina de destino? ¿Es realmente una diferencia de diseño o debería estar buscando algo más básico que es el problema aquí? He escuchado algo sobre la necesidad de resistencias de pull-up en las entradas de datos / reloj, pero eso debería manejarse en el código, especialmente porque está TRABAJANDO en otro objetivo, pero no en el que necesito que funcione.
¿Alguna idea? Me encantaría que esto funcione lo antes posible. Voy a seguir haciendo la depuración, cualquier sugerencia o sugerencia sería muy apreciada. A todos se les dará plena consideración porque necesito algunos ojos nuevos sobre este tema. Quizás se necesita una mejor implementación en la biblioteca 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);
}
}
}