Проблеми емулятора клавіатури Arduino PS / 2


10

Так, я шукав форуми Arduino.cc і тут. Так, я знайшов статті про бібліотеку ps2dev. Так, я прочитав (добре, на деяких я зняв) остаточну статтю інтерфейсу PS / 2 на цьому веб-сайті . Так, у мене це працює, свого роду. Мені потрібні кілька ідей, щоб зробити стрибок до повноцінної роботи. :)

Ні, я не можу просто імітувати USB HID-клавіатуру і залишити її при цьому - це повинна бути емуляція клавіатури PS / 2. Так, я надсилаю належні сигнали створення і перерви - він обробляє навіть дуже складні комбінації натискань клавіш. Як зараз, я маю код, написаний для мого Arduino, як розміщено нижче (технічно Freeduino 1.22), і я надіслав натискання клавіш через серійний монітор або термінал PuTTY, а також за допомогою зручної обгортки / драйвера Python, який надсилає фактичну Інформація про код коду PS / 2 - і, як правило, значно полегшує моє життя - також знімає частину навантаження з Arduino.

Зараз у мене на ескізі Arduino працює ескіз, який імітує клавіатуру PS / 2. Звичайно, я повинен завантажувати свою "цільову" машину (машину, в яку йде PS / 2 Plug), і я бачу, як відбувається "рукостискання". Завантажте програму WinDoze, відкрийте блокнот та натисніть клавіші на екран (успішно) за допомогою мого "драйвера" Python. (Драйвер просто займає термінал Serial Monitor / PuTTY і читає / записує в послідовний порт за допомогою модуля під назвою PySerial.) Це все робиться на AMD в "цілі" материнської плати ASUS.

Тепер мета полягає в тому, щоб він працював на моїй Intel на материнській платі Intel, орієнтованої на "ціль", я підключаю її, завантажую і не маю кісток. Отже, я трохи змінив ескіз, щоб спробувати дати собі уявлення про те, що відбувається насправді на моєму маленькому другові Арді. Версія після модів відображається нижче. Як я розумію (код був "запозичений" з іншого повідомлення на форумі Arduino.cc, тут ) він спробує встановити зв'язок із "ціллю" над PS / 2 спочатку, блимаючи бортовий світлодіод на .5 секунди до моменту зв’язок встановлюється. Ціль Intel не минає .5 секунди періоду миготить, і послідовне з'єднання ніколи не встановлюється з "хостом".

Моє запитання таке: чи є значна різниця в тому, як клавіатури ps / 2 встановлюють зв'язок зі своєю цільовою машиною? Це дійсно різниця в дизайні чи я повинен шукати щось більш базове, в чому полягає тут проблема? Я чув щось про необхідність підтягуючих резисторів на входах даних / тактових годин, але це слід вирішувати в коді, тим більше, що це працює на іншій цілі, тільки не над тією, над якою мені це потрібно працювати.

Будь-які ідеї? Я б хотів, щоб це працювало якнайшвидше - я буду продовжувати робити налагодження, будь-які вказівки чи пропозиції будуть дуже вдячні. Всі вони будуть уважно розглядатися, тому що мені потрібні нові погляди на це питання. Можливо, потрібна краща реалізація в бібліотеці 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);
    }
  }
}

Кілька питань: "Ескіз" - це "Ардуїно-лінго" для "програми"? Цей матеріал драйвера python не залежить від цільової машини, правда? Ваша проблема полягає в тому, що вона працює на одній цільовій машині, а не на іншій, правда? Ви спробували завантажувати неробочу ціль із приєднаною клавіатурою PS / 2, а потім поміняти її на Arduino?
AndreKR

Так, програма Sketch == в Арду-лінго. Я спробував це, і, схоже, це не спрацювало (але мені потрібно змінити ескіз, щоб він не чекав ACK від цілі, перш ніж надсилати символи.) Я дам вам знати, коли отримаю можливість перевірити його пізніше сьогодні.
chisaipete

Отже, я тестував програму, як ви запропонували, і вона працює! Врешті-решт, я хотів би мати можливість живити ціль за допомогою встановленого емулятора клавіатури та мати змогу змінювати налаштування BIOS за допомогою нього. Отже, я думаю, що рукостискання починається?
chisaipete

Так, певно. Ви бачили послідовність ініціалізації в самому дні комп'ютера- engineering.org/ ps2keyboard ? Я б почав з порівняння своєї послідовності з цією.
AndreKR

1
Вибачте, я відпустив цю тему, - я не встиг спробувати рішення AndreKR. Крім того, я не використовую резистори підтягування, тому важко визначити, у якому кінці немає резисторів :)
chisaipete

Відповіді:


5

Як я розумію, ви підключаєте свій Arduino до двох різних цільових машин, і на одній він працює, а на іншій - не.

Тому, схоже, існує різниця між вимогами ініціалізації двох машин. На цій сторінці в самому дні є перелік можливої ​​послідовності ініціалізації. Почніть з порівняння ініціалізації з тією.

Це буде набагато простіше за допомогою логічного аналізатора. Я використовую Intronix Logicport , але є і дешевші, і кращі, хоча і не одночасно.

Натискання на шину відкритого колектора трохи громіздке, оскільки ви не бачите, про який пристрій говорять. Тим НЕ менше, якщо ви поклали в резисторі в кінці , де підтяжка НЕ , ви можете сказати , за рівнем напруги , яке пристрій тримає вниз автобус. Кожна шина відкритого колектора (як PS / 2) потребує підтягуючих резисторів, як правило, вони вбудовані в ПК. Ви можете легко бачити різні рівні напруги на DSO. Маючи лише LA, ви повинні записувати двічі з різними пороговими напругами.


Тоді я очікував того, кому дати виграш, було важче, але ваша відповідь отримала найбільше голосів, і я трохи вважаю за краще. Я б волів нагороду всіх!
Кортук

3

Зважаючи на те, що ваш проект працює з однією материнською платою, а не з іншою, у вас, здається, є класичний випадок "часткової відповідності специфікаціям" - у вашому проекті, а може навіть і на одній із материнських плат. Але більшість клавіатур будуть працювати з будь-якою материнською платою, тому надійна реалізація повинна бути портативною. Завдання полягає в тому, що вам доведеться з’ясувати, чому ваше не так.

Ви можете зробити це, просто поглянувши на проблему і подумавши про те, як це має працювати (можливо, після перерви - або одного дня відповідь ударить вас в душ), але ви будете ефективнішими, якщо зможете контролювати що відбувається. Для електричних питань, що означають область, для протоколів - логічний аналізатор. У цій області є кілька дешевих варіантів, наприклад, "піратська шина", яка має певні можливості для клавіатурного протоколу або щось на базі FPGA, яке може мати довший буфер захоплення (див. Sump.org).

Інша річ, яку ви можете спробувати, - це використовувати інший пристрій, мікроконтролер або FPGA, щоб побудувати хост клавіатури і використовувати його для тестування вашого проекту на межі специфікації.


2

Я не переглянув бібліотеку ps2dev, щоб побачити, як саме вона працює, але одна річ на мене вискакує.

Наразі робиться одна спроба підключитися до "хост-комп'ютера". Коли це не вдається, очікується ціла секунда (світлодіод на 0,5, світлодіод вимикається на 0,5 с), перш ніж зробити іншу спробу.

Якщо материнська плата Intel не чекає досить довго для виявлення клавіатури, вона, можливо, ніколи не отримує спробу підключення до того, як вона продовжить послідовність завантаження.

Якщо ви скоротите час очікування, щоб сказати 0,1 секунди (змінити рядки затримки (500) на затримку (50)), можливо, вам пощастить.

Якщо ні, спробуйте ще швидше. Чорт, навіть спробуй це взагалі без зволікання і подивись, як це йде.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.