Sim, procurei nos fóruns do Arduino.cc e aqui. Sim, encontrei os artigos relacionados à biblioteca ps2dev. Sim, li (ok, alguns foram os que li) o artigo definitivo da interface PS / 2 neste site . Sim, eu tenho esse trabalho, meio. Preciso de algumas idéias para dar o salto para o pleno funcionamento. :)
Não, não posso simplesmente emular um teclado USB HID e deixá-lo assim - ele precisa ser uma emulação de teclado PS / 2. Sim, estou enviando sinais adequados de fabricação e interrupção - ele até lida com combinações de teclas muito complicadas. Como está agora, tenho um código escrito para o meu Arduino, como publicado abaixo (tecnicamente um Freeduino 1.22), e enviei pressionamentos de tecla pelo Serial Monitor ou pelo terminal PuTTY, além de um prático wrapper / driver Python que envia mensagens reais. As informações do scancode do PS / 2 - e geralmente facilitam minha vida - também diminuindo parte da carga do Arduino.
No momento, tenho um esboço em execução no Arduino que emula um teclado PS / 2. Naturalmente, tenho que inicializar minha máquina "alvo" (máquina na qual o PS / 2 Plug entra) e vejo o "aperto de mão". Inicialize no WinDoze, abra o bloco de notas e pressione as teclas pressionadas na tela (com sucesso) usando o meu "driver" do Python. (O driver simplesmente ocorre no terminal Serial Monitor / PuTTY e lê / grava na porta serial usando um módulo chamado PySerial.) Isso tudo é feito em um "destino" da placa-mãe AMD na ASUS.
Agora, o objetivo é fazê-lo funcionar na minha Intel na placa-mãe Intel "target", eu conecto, inicializo e não dou dados. Então, modifiquei um pouco o esboço para tentar me informar do que realmente está acontecendo com meu pequeno amigo Ardy. A versão após os mods é exibida abaixo. Pelo que entendi (o código foi "emprestado" de outra postagem no fórum do Arduino.cc, aqui ) Ele tentará estabelecer uma conexão com o "destino" no PS / 2 primeiro, piscando o LED integrado em um período de 0,5 segundo até o conexão estabelecida. O destino da Intel não passa dos 0,5 segundo período piscando e a conexão serial nunca é estabelecida com o "host".
Minha pergunta é a seguinte: existe uma grande diferença na maneira como os teclados ps / 2 estabelecem comunicação com a máquina de destino? É realmente uma diferença de design ou devo procurar algo mais básico que seja o problema aqui? Ouvi algo sobre a necessidade de resistores pull-up nas entradas de dados / relógio, mas isso deve ser tratado no código, especialmente porque está FUNCIONANDO em outro alvo, mas não no que eu preciso trabalhar.
Alguma ideia? Eu adoraria fazer isso funcionar o mais rápido possível - continuarei fazendo a depuração, quaisquer sugestões ou sugestões serão muito apreciadas. Todos serão levados em consideração porque preciso de novos olhos sobre esse assunto. Talvez seja necessária uma melhor implementação na 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);
}
}
}