ปัญหาการจำลองคีย์บอร์ด Arduino PS / 2


10

ใช่ฉันได้ค้นหาฟอรัม Arduino.cc แล้วและที่นี่ ใช่ฉันได้พบบทความเกี่ยวกับห้องสมุด ps2dev แล้ว ใช่ฉันอ่านแล้ว (ได้บ้างฉันอ่านบางส่วน) บทความอินเตอร์เฟซ PS / 2 ที่ชัดเจนที่เว็บไซต์นี้ ใช่ฉันทำงานได้แล้ว ฉันต้องการความคิดบางอย่างเพื่อทำให้การก้าวกระโดดทำงานได้อย่างเต็มที่ :)

ไม่ฉันไม่สามารถจำลอง USB HID Keyboard และปล่อยให้เป็นแบบนั้นได้มันต้องเป็นแบบจำลอง PS / 2 Keyboard ใช่ฉันกำลังส่งสัญญาณยี่ห้อและตัวแบ่งสัญญาณที่เหมาะสม - มันจัดการกับชุดแป้นพิมพ์ที่ซับซ้อนมาก ตามที่เป็นอยู่ตอนนี้ฉันมีโค้ดที่เขียนขึ้นสำหรับ Arduino ของฉันตามที่โพสต์ด้านล่าง (ในทางเทคนิคคือ Freeduino 1.22) และฉันได้ส่งการกดแป้นผ่านทาง Serial Monitor หรือเทอร์มินัล PuTTY เช่นเดียวกับ ข้อมูลการสแกน PS / 2 - และโดยทั่วไปทำให้ชีวิตของฉันง่ายขึ้นมาก - รวมถึงการโหลดบางอย่างออกจาก Arduino

ตอนนี้ฉันมีร่างที่ทำงานบน Arduino ซึ่งเลียนแบบแป้น PS / 2 โดยธรรมชาติฉันต้องบูตเครื่อง "เป้าหมาย" ของฉัน (เครื่องที่เสียบ PS / 2 เข้าไป) และฉันเห็น "การจับมือกัน" เกิดขึ้น Boot to WinDoze, เปิด notepad, และกดแป้นไดรฟ์ไปที่หน้าจอ (สำเร็จ) โดยใช้ Python "ไดร์เวอร์" ของฉัน (ไดรเวอร์นั้นใช้แทน Terminal Monitor / PuTTY และอ่าน / เขียนไปยังพอร์ตอนุกรมโดยใช้โมดูลที่เรียกว่า PySerial) ทั้งหมดนี้ทำบน AMD ใน "เป้าหมาย" ของเมนบอร์ด ASUS

ตอนนี้เป้าหมายคือให้มันทำงานกับ Intel ในเมนบอร์ดมาเธอร์บอร์ดตาม "เป้าหมาย" ของฉันฉันเสียบมันบูตและไม่มีลูกเต๋า ดังนั้นฉันจึงปรับเปลี่ยนภาพร่างเล็กน้อยเพื่อลองและให้ตัวเองดูว่าเกิดอะไรขึ้นกับเพื่อน Ardy ตัวน้อยของฉัน เวอร์ชั่นหลังจากตัวดัดแปลงแสดงขึ้นด้านล่าง ตามที่ฉันเข้าใจ (โค้ดคือ "ยืม" จากโพสต์ฟอรัม Arduino.cc อีกตัวที่นี่ ) มันจะพยายามสร้างการเชื่อมต่อกับ "เป้าหมาย" บน PS / 2 ก่อนจากนั้นจึงกะพริบ LED ออนบอร์ดที่ระยะเวลา 0.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);
    }
  }
}

คำถามสองสามข้อ: "ร่าง" เป็น Arduino-lingo สำหรับ "โปรแกรม"? สิ่งไดรเวอร์หลามนี้เป็นอิสระจากเครื่องเป้าหมายใช่ไหม ปัญหาของคุณคือมันใช้งานได้กับเครื่องเป้าหมายเครื่องหนึ่งไม่ใช่เครื่องอื่นใช่มั้ย คุณลองบูทเป้าหมายที่ไม่ทำงานด้วยคีย์บอร์ด PS / 2 แล้วต่อกับ Arduino หรือไม่
AndreKR

ใช่ Sketch == โปรแกรมใน Ardu-lingo ฉันลองสิ่งนี้และดูเหมือนจะไม่ทำงาน (แต่ฉันต้องแก้ไขภาพร่างดังนั้นจึงไม่รอ ACK จากเป้าหมายก่อนส่งตัวอักษร) ฉันจะแจ้งให้คุณทราบเมื่อฉันมีโอกาสทดสอบ ต่อมาวันนี้
chisaipete

ดังนั้นฉันทดสอบโปรแกรมตามที่คุณแนะนำและใช้งานได้! ในที่สุดฉันก็สามารถที่จะใช้พลังงานรอบเป้าหมายด้วยการติดตั้งแป้นพิมพ์จำลองและสามารถเปลี่ยนการตั้งค่า BIOS ด้วย ดังนั้นฉันคิดว่าการจับมือเริ่มต้นทำงานไม่ได้หรือ
chisaipete

ใช่อาจจะ คุณเห็นลำดับการเริ่มต้นที่ด้านล่างสุดของcomputer-engineering.org/ps2keyboardหรือไม่ ฉันจะเริ่มต้นด้วยการเปรียบเทียบลำดับของฉันกับที่
AndreKR

1
ขออภัยฉันปล่อยให้กระทู้นี้ค้าง - ฉันไม่มีเวลาลองวิธีแก้ปัญหาของ AndreKR นอกจากนี้ฉันไม่ได้ใช้ตัวต้านทาน pullup ดังนั้นจึงเป็นเรื่องยากที่จะตรวจสอบว่าจุดสิ้นสุดไม่ได้มี pullup ต้านทาน :)
chisaipete

คำตอบ:


5

ตามที่เข้าใจแล้วคุณเชื่อมต่อ Arduino ของคุณกับเครื่องเป้าหมายที่แตกต่างกันสองเครื่องและเครื่องหนึ่งใช้งานได้และเครื่องอื่นไม่ทำงาน

ดังนั้นจึงดูเหมือนว่ามีความแตกต่างระหว่างข้อกำหนดการเริ่มต้นของทั้งสองเครื่อง ในหน้านี้ที่ด้านล่างสุดจะมีรายชื่อของลำดับการเริ่มต้นที่เป็นไปได้ เริ่มต้นด้วยการเปรียบเทียบการเริ่มต้นของคุณกับสิ่งนั้น

มันจะง่ายขึ้นมากโดยใช้ตัววิเคราะห์เชิงตรรกะ ฉันใช้Intronix Logicportแต่มีทั้งที่ถูกกว่าและดีกว่าแม้ว่าจะไม่ใช่ในเวลาเดียวกัน

การแตะที่บัสสะสมเปิดนั้นค่อนข้างยุ่งยากเพราะคุณไม่เห็นว่าอุปกรณ์ใดกำลังพูดถึง อย่างไรก็ตามหากคุณใส่ตัวต้านทานแบบอนุกรมไว้ที่ส่วนท้ายซึ่งการดึงไม่ได้คุณสามารถบอกได้จากระดับแรงดันไฟฟ้าที่อุปกรณ์ค้างไว้ที่บัส บัส open-collector ทุกตัว (เช่น PS / 2) ต้องการตัวต้านทานแบบ pullup โดยปกติแล้วมันจะสร้างขึ้นในพีซี คุณสามารถดูระดับแรงดันไฟฟ้าที่แตกต่างได้อย่างง่ายดายบน DSO ด้วย LA เท่านั้นคุณต้องบันทึกสองครั้งด้วยแรงดันไฟฟ้าที่แตกต่างกัน


การตัดสินใจว่าจะให้รางวัลนั้นยากกว่ากัน แต่ฉันคิดว่าคำตอบของคุณจะได้รับการโหวตมากที่สุดและฉันก็ชอบเล็กน้อย ฉันจะให้รางวัลแก่ทุกคน!
Kortuk

3

เนื่องจากโปรเจ็กต์ของคุณทำงานร่วมกับมาเธอร์บอร์ดตัวหนึ่งและไม่ใช่อีกตัวคุณดูเหมือนจะมีกรณีคลาสสิกของ "การปฏิบัติตามข้อกำหนดบางส่วน" - ในโครงการของคุณและอาจเป็นแม้แต่ในหนึ่งในเมนบอร์ด แต่คีย์บอร์ดส่วนใหญ่จะใช้งานได้กับมาเธอร์บอร์ดทุกรุ่นดังนั้นการติดตั้งที่มีประสิทธิภาพจึงควรพกพาได้ ความท้าทายคือคุณจะต้องเข้าใจว่าทำไมคุณถึงไม่ใช่

คุณอาจสามารถทำสิ่งนี้ได้โดยเพียงแค่จ้องมองปัญหาและคิดว่ามันควรจะทำงานอย่างไร (บางทีหลังจากหยุดพัก - หรือวันหนึ่งคำตอบก็จะโดนคุณในห้องอาบน้ำ) แต่คุณจะมีประสิทธิภาพมากกว่าถ้าคุณสามารถตรวจสอบ เกิดอะไรขึ้น. สำหรับปัญหาทางไฟฟ้าที่หมายถึงขอบเขตสำหรับคนที่โปรโตคอลวิเคราะห์ตรรกะ มีตัวเลือกราคาถูกที่มีอยู่ในพื้นที่นั้นเช่นบอร์ด "bus pirate" ซึ่งมีความสามารถเฉพาะสำหรับโปรโตคอลแป้นพิมพ์หรือบางอย่างที่ใช้ FPGA ซึ่งอาจมีบัฟเฟอร์การจับภาพนานขึ้น (ดู sump.org)

อีกสิ่งหนึ่งที่คุณอาจลองใช้คืออุปกรณ์อื่นไม่ว่าจะเป็นไมโครคอนโทรลเลอร์หรือ FPGA เพื่อสร้างโฮสต์คีย์บอร์ดและใช้สิ่งนั้นเพื่อทดสอบโครงการของคุณตามข้อ จำกัด ของข้อกำหนด


2

ฉันไม่ได้ดูไลบรารี ps2dev เพื่อดูว่ามันทำงานอย่างไร แต่มีสิ่งหนึ่งที่กระโดดออกมาที่ฉัน

ในขณะนี้มีการพยายามเชื่อมต่อกับคอมพิวเตอร์ "โฮสต์" ครั้งเดียว เมื่อล้มเหลวจะมีการรอทั้งวินาที (LED ที่ 0.5 วินาที, LED off 0.5s) ก่อนที่จะลองอีกครั้ง

หากมาเธอร์บอร์ด Intel ไม่รอนานพอสำหรับการตรวจจับแป้นพิมพ์ก็อาจจะไม่ได้รับความพยายามในการเชื่อมต่อก่อนที่มันจะดำเนินการตามลำดับการบู๊ต

หากคุณลดเวลาการรอคอยที่จะพูดถึง 0.1 วินาที (เปลี่ยนความล่าช้า (500) สายเป็นความล่าช้า (50)) คุณอาจโชคดี

ถ้าไม่ลองเร็วขึ้น แม้แต่ลองเลยโดยไม่ชักช้าเลยและดูว่ามันจะไปอย่างไร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.