Sí, he buscado en los foros Arduino.cc y aquí. Sí, he encontrado los artículos sobre la biblioteca ps2dev. Sí, he leído (bueno, algunos lo he leído) el artículo definitivo de la interfaz PS / 2 en este sitio web . Sí, tengo esto funcionando, un poco. Necesito algunas ideas para dar el salto al pleno funcionamiento. :)
No, no puedo simplemente emular un teclado USB HID y dejarlo así: debe ser una emulación de teclado PS / 2. Sí, estoy enviando señales adecuadas de hacer y romper, incluso maneja combinaciones de teclas muy complicadas. Tal como está ahora, tengo un código escrito para mi Arduino como se publica a continuación (técnicamente un Freeduino 1.22), y he enviado pulsaciones de teclas a través del monitor serie o terminal PuTTY, así como con un práctico envoltorio / controlador Python que envía La información del código de escaneo PS / 2, y en general me hace la vida mucho más fácil, también quita parte de la carga del Arduino.
En este momento, tengo un boceto ejecutándose en el Arduino que emula un teclado PS / 2. Naturalmente, tengo que arrancar mi máquina "objetivo" (máquina en la que se conecta PS / 2 Plug), y veo que tiene lugar el "apretón de manos". Arrancar en WinDoze, abrir el bloc de notas y conducir pulsaciones de teclas a la pantalla (con éxito) utilizando mi "controlador" de Python. (El controlador simplemente tiene 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 el "objetivo" de la placa base ASUS.
Ahora, el objetivo es hacer que funcione en mi Intel en el "objetivo" basado en la placa base Intel, lo enchufo, arranco y no tengo dados. Entonces, modifiqué un poco el boceto para intentar tener una idea de lo que realmente está sucediendo con mi pequeño amigo Ardy. La versión después de las modificaciones se muestra a continuación. Según tengo entendido (el código fue "prestado" de otra publicación en el foro de Arduino.cc, aquí ) Intentará establecer una conexión con el "objetivo" a través de PS / 2 primero, parpadeando el LED a bordo en un período de .5 segundos hasta el Se establece la conexión. El objetivo de Intel no supera el parpadeo de 0,5 segundos y la conexión en serie nunca se establece con el "host".
Mi pregunta es esta: ¿hay una diferencia importante en la forma en que los teclados ps / 2 establecen comunicación con su máquina de destino? ¿Es realmente una diferencia de diseño o debería buscar algo más básico que es el problema aquí? Escuché algo sobre la necesidad de resistencias pull-up en las entradas de datos / reloj, pero eso debería manejarse en el código, especialmente porque FUNCIONA en otro objetivo, solo que no es en el que necesito trabajar.
¿Algunas ideas? Me encantaría que esto funcione lo antes posible: voy a seguir depurando, cualquier sugerencia o sugerencia sería muy apreciada. A todos se les dará una consideración completa 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);
}
}
}