Oui, j'ai cherché sur les forums Arduino.cc et ici. Oui, j'ai trouvé les articles concernant la bibliothèque ps2dev. Oui, j'ai lu (d'accord, certains j'ai survolé) l'article définitif sur l'interface PS / 2 sur ce site . Oui, j'ai ce travail, un peu. J'ai besoin de quelques idées pour franchir le pas pour travailler pleinement. :)
Non, je ne peux pas simplement émuler un clavier USB HID et en rester là - il doit s'agir d'une émulation de clavier PS / 2. Oui, j'envoie des signaux corrects de création et de rupture - il gère même des combinaisons de touches très compliquées. Dans l'état actuel des choses, j'ai du code écrit pour mon Arduino comme indiqué ci-dessous (techniquement un Freeduino 1.22), et j'ai envoyé des touches via le moniteur série ou le terminal PuTTY, ainsi qu'avec un wrapper / pilote Python pratique qui envoie des données réelles Les informations de scancode PS / 2 - et me facilitent généralement la vie - allégeant également une partie de la charge de l'Arduino.
En ce moment, j'ai un croquis en cours d'exécution sur l'Arduino qui émule un clavier PS / 2. Naturellement, je dois démarrer ma machine "cible" (machine dans laquelle la prise PS / 2 entre), et je vois la "prise de contact" avoir lieu. Démarrez sur WinDoze, ouvrez le bloc-notes et appuyez sur les touches à l'écran (avec succès) en utilisant mon "pilote" Python. (Le pilote prend simplement la place du terminal Serial Monitor / PuTTY et lit / écrit sur le port série à l'aide d'un module appelé PySerial.) Tout cela se fait sur un AMD dans la carte mère ASUS "target".
Maintenant, le but est de le faire fonctionner sur ma "cible" basée sur la carte mère Intel dans Intel, je la branche, je démarre et aucun dé. J'ai donc un peu modifié le croquis pour essayer de me donner un aperçu de ce qui se passe réellement avec mon petit ami Ardy. La version après les mods est affichée ci-dessous. Si je comprends bien (le code a été "emprunté" à un autre message du forum Arduino.cc, ici ). la connexion est établie. La cible Intel ne dépasse pas les clignotements de la seconde période de 0,5 et la connexion série n'est jamais établie avec "l'hôte".
Ma question est la suivante: y a-t-il une différence majeure dans la façon dont les claviers ps / 2 établissent la communication avec leur machine cible? Est-ce vraiment une différence de conception ou devrais-je rechercher quelque chose de plus basique qui est le problème ici? J'ai entendu parler de la nécessité d'avoir des résistances de rappel sur les entrées données / horloge, mais cela devrait être géré dans le code, surtout parce qu'il FONCTIONNE sur une autre cible, mais pas sur celle sur laquelle je veux travailler.
Des idées? J'adorerais que cela fonctionne dès que possible - je vais continuer à faire le débogage, tous les pointeurs ou suggestions seraient grandement appréciés. Ils seront tous pris en considération car j'ai besoin d'un regard neuf sur cette question. Peut-être qu'une meilleure implémentation dans la bibliothèque ps2dev est nécessaire?
#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);
}
}
}