Sì, ho cercato nei forum Arduino.cc e qui. Sì, ho trovato gli articoli riguardanti la libreria ps2dev. Sì, ho letto (ok, alcuni ho scremato) l'articolo di interfaccia PS / 2 definitivo su questo sito . Sì, ho questo lavoro, un po '. Ho bisogno di alcune idee per fare il salto per funzionare pienamente. :)
No, non posso semplicemente emulare una tastiera HID USB e lasciarla lì - deve essere un'emulazione della tastiera PS / 2. Sì, sto inviando segnali di creazione e interruzione adeguati: gestisce anche combinazioni di tasti molto complicate. Allo stato attuale, ho il codice scritto per il mio Arduino come pubblicato di seguito (tecnicamente un Freeduino 1.22) e ho inviato sequenze di tasti tramite il monitor Serial Monitor o il terminale PuTTY, nonché con un pratico wrapper / driver Python che invia Informazioni su scancode PS / 2 - e in generale mi semplificano molto la vita - anche togliendo un po 'di carico dall'Arduino.
In questo momento, ho uno schizzo in esecuzione su Arduino che emula una tastiera PS / 2. Ovviamente, devo avviare la mia macchina "target" (macchina su cui va inserita la PS / 2 Plug) e vedo che si verifica la "stretta di mano". Avvia su WinDoze, apri il blocco note e guida i tasti sullo schermo (con successo) usando il mio "driver" Python. (Il driver prende semplicemente posto sul terminale Serial Monitor / PuTTY e legge / scrive sulla porta seriale usando un modulo chiamato PySerial.) Tutto questo viene fatto su un AMD nella "scheda" della scheda madre ASUS.
Ora, l'obiettivo è farlo funzionare sul mio Intel in "target" basato su scheda madre Intel, lo collego, avvio e nessun dado. Quindi, ho modificato un po 'lo schizzo per provare a darmi un'idea di ciò che sta realmente accadendo sul mio piccolo amico Ardy. La versione dopo le mod è visualizzata di seguito. A quanto ho capito (il codice è stato "preso in prestito" da un altro post del forum Arduino.cc, qui ) Proverà prima a stabilire una connessione con il "target" su PS / 2, facendo lampeggiare il LED di bordo in un periodo di 0,5 secondi fino a quando il connessione stabilita. Il target Intel non supera il secondo periodo di 5 lampeggi e la connessione seriale non viene mai stabilita con l '"host".
La mia domanda è questa: c'è una grande differenza nel modo in cui le tastiere ps / 2 stabiliscono la comunicazione con la loro macchina target? È davvero una differenza di design o dovrei cercare qualcosa di più basilare che è il problema qui? Ho sentito parlare della necessità di resistori di pull-up sugli ingressi dati / clock, ma questo dovrebbe essere gestito nel codice, soprattutto perché FUNZIONA su un altro target, non quello su cui ho bisogno per lavorare.
Qualche idea? Mi piacerebbe farlo funzionare al più presto - Continuerò a fare il debug, qualsiasi suggerimento o suggerimento sarebbe molto apprezzato. Saranno tutti presi in piena considerazione perché ho bisogno di alcuni nuovi occhi su questo problema. Forse è necessaria una migliore implementazione nella libreria 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);
}
}
}