การเชื่อมต่อเม้าส์ PS/2 Mouse Interface
รูปแบบการเชื่อมต่อเม้าส์ที่เป็นชนิด PS/2
16 November, 2019 by
การเชื่อมต่อเม้าส์ PS/2 Mouse Interface
Liew Wuttipat
| No comments yet

        เม้าส์มาตรฐาน PS/2 ใช้โปรโตคอลเดียวกับคีย์บอร์ด โดยมาตราฐานนี้ถูกพัฒนาโดยทีมนักวิจัย IBM แต่ผมก็ยังหา Official publication ของมาตรฐานอันนี้ไม่เจอ แต่ไม่เป็นไร ผมได้หาข้อมูลจากหลายๆแหล่งมาสรุปรวมให้เข้าใจกันในบทความนี้

Inputs and Resolution: 
        เม้าส์ PS/2 ส่วนใหญ่จะมี inputs เป็นการเคลื่อนที่ในแกน X (ขวา/ซ้าย), แกน Y (ขึ้น/ลง), ปุ่มเม้าส์ซ้าย, ปุ่มเม้าส์กลาง และปุ่มเม้าส์ขวา ตัวเม้าส์จะทำการอ่านค่าพวกนี้ด้วยความถี่คงที่และเก็บค่าไว้ เป็น counters กับ flags สำหรับดูการเคลื่อนที่ และ button states สำหรับการกดปุ่ม นอกจากนี้เม้าส์บางตัวอาจจะมีมากกว่านี้แต่ขอไม่พูดถึงแล้วกัน จะพูดเพียงแค่ Microsoft Intellimouse ซึ่งจะมีค่าเพิ่มเติมขึ้นมาคือ การหมุน Scolling wheel หรือตัวล้อลูกกลิ้งๆ และเพิ่มปุ่มให้กดอีก 2 ตัว

        เม้าส์โดยปกติแล้วจะมีตัว movement counter อยู่ 2 ตัวที่คอยนับและเก็บการเคลื่อนที่ในแนวแกน X และแนวแกน Y ค่าที่เก็บแต่ละแกนนั้นจะเป็นแบบ 9-bit 2's complement คือสามารถมีค่าได้ตั้งแต่ -256 ~ +256 และมี overflow flag ในแต่ละแกนด้วย นอกจากนั้นยังมีค่าที่เก็บการกดเม้าส์อยู่ 3 ปุ่ม ซึ่งทั้งหมดนี้จะส่งไปยัง Host ในรูปของ 3-Byte data packet (เดียวจะอธิบายต่อไป) ค่า movement counter จะนับและเริ่มเก็บตั้งแต่หลังจากส่งไปยัง Host ครั้งล่าสุด

         กระบวนการที่เกิดขึ้นในเม้าส์ เมื่อเม้าส์อ่านค่าจากเซนเซอร์ได้ หากมีการกดปุ่มมันจะเก็บค่าเอาไว้ใน state of buttons หากมีเคลื่อนที่มันก็จะเพิ่มหรือลดค่าใน movement counter ทั้งแกน X และ Y แต่หากตัว counter นั้นเกิด overflowed มันก็จะไปเซ็ท overflow flag

        ต่อไปจะมาอธิบายตัว Parameter ที่ใช้บอกว่าตัว movement counter จะต้องนับเพิ่มขึ้นเท่าไหร่ นับลดลงเท่าไหร่ ตัวนั้นก็เรียกว่า Resolution เปรียบเสมือนตัวปรับความละเอียดของเม้าส์นั่นเอง โดยค่า default resolution จะอยู่ที่ 4 counts/mm ซึ่งโฮส สามารถเปลี่ยนได้ โดยการสั่งคำสั่ง "Set Resolution" (0xE8)

Movement Data Packet: 
        เม้าส์ปกติแล้วจะส่งแพ็กเก็ตข้อมูลค่าการกดปุ่มและค่าการเคลื่อนที่เป็นไปยังโฮส ทั้งหมด 3-byte ซึ่งแพ็กเก็ตจะเป็นตามรูปต่อไปนี้



        ค่า movement counters ของทั้ง X และ Y เป็น Integers โดยที่เครื่องหมาย บวกหรือลบให้ดูที่ Byte 1 ซึ่งค่าจะอัพเดตเมื่อเม้าส์เกิดการเคลื่อนที่ และค่าจะเก็บเอาไว้จนกว่าจะมีการส่งให้โฮสเสร็จ (หลังจากส่งแพ็กเก็ตไปยัง host แล้วค่าใน movement counter จะถูกรีเซ็ท) ช่วงของค่าจะอยู่ได้ตั้งแต่ -256 ~ +256 ถ้าเกินจะไปเซ็ท overflow bit และ counter จะไม่นับต่อจนกว่าจะมีการรีเซ็ท

        จากที่กล่าวไปแล้ว ตัว movement counter จะถูกรีเซ็ทหลังจากส่งแพ็กเก็ตไปยัง host สำเร็จ ซึ่งจริงๆแล้วจะรีเซ็ทหลังจากเม้าส์ได้รับคำสั่งอะไรก็ตามจากโฮส ที่ไม่ใช้คำสั่ง "Resend" (0xFE)

Mode of operating:
 
        ข้อมูลที่ส่งของเม้าส์นั้น จะขึ้นอยู่กับโหมดการทำงานด้วยว่าอยู่โหมดไหน โดยโหมดการทำงานจะแบ่งออกเป็น 4 โหมด

  • Reset - เม้าส์จะเข้าสู่ Reset mode เมื่อมีการจ่ายไฟเข้าระบบหรือมีการสั่งคำสั่ง "Reset" (0xFF)
  • Stream - โหมดนี้จะเป็น default mode (หลังจากทำการ Reset เสร็จแล้ว) และซอฟต์แวร์ส่วนใหญ่จะใช้โหมดนี้ ถ้าโฮสมีการสั่งเม้าส์เป็น Remote mode เราก็สามารถที่จะเปลี่ยนมายังโหมดนี้ได้ โดยใช้คำสั่ง "Set Stream Mode" (0xEA)
  • Remote - Remote mode เป็นโหมดที่เป็นประโยชน์มากในบางสถานการณ์ เราสามารถเปลี่ยนมาเข้าโหมดนี้ได้ โดยใช้คำสั่ง "Set Remote Mode" (0xF0)
  • Wrap - โหมดนี้ส่วนใหญ่จะใช้สำหรับในการทดสอบการเชื่อมต่อระหว่างตัวเม้าส์กับโฮส สามารถเข้าโหมดนี้ได้โดยการใช้คำสั่ง "Set Wrap Mode" (0xEE) ส่วนการออกจากโหมดนี้จะใช้คำสั่ง "Reset" (0xFF) หรือ "Reset Wrap Mode" (0xEC) ถ้าใช้คำสั่ง "Reset" (0xFF) จะเป็นการเปลี่ยนไปยัง Reset mode แต่ถ้าเป็น "Reset Wrap Mode" (0xEC) เม้าส์จะเปลี่ยนโหมดไปยังโหมดที่เราเข้ามาก่อน Wrap mode

Reset Mode:
        เมื่อเม้าส์เข้าสู่ reset mode เม้าส์จะทำการตรวจสอบตัวเอง self-test BAT (Basic Assurance Test) และเซ็ทค่าต่างๆดังนี้

        - Sample Rate - 100 samples/sec
        - Resolution - 4 counts/mm
        - Data Reporting Disabled

        เมื่อทำการทดสอบเสร็จเรียบร้อยแล้วเม้าส์จะส่งค่าตอบกลับไป ถ้าสำเร็จจะส่ง 0xAA (BAT successful) หรือถ้าไม่สำเร็จจะส่ง 0xFC (Error) ถ้าโฮสได้รับอะไรก็ตามที่ไม่ใช่ 0xAA อาจจะมีปัญหาเรื่องของไฟ ให้ตรวจสอบแล้วลองสั่ง "Reset" (0xFF) ใหม่ เมื่อได้รับแล้วเม้าส์ก็จะส่ง Device ID ไปเป็น 0x00 หลังจากนั้นเม้าส์ก็จะเข้าสู่โหมด Stream mode แต่ว่าค่าต่างๆก็จะเป็นตาม default "Data Reporting Disabled" หมายความว่าตัวเม้าส์จะไม่ส่งอะไรไปยังโฮสจนกว่าจะมีการรับคำสั่ง "Enable Data Reporting" (0xF4) จากโฮส

Stream Mode:
        โหมดนี้ เม้าส์จะส่งค่า movement data เมื่อมีการเคลื่อนที่เม้าส์ หรือว่ามีสถานะการกดปุ่มเปลี่ยน ซึ่งความถี่ของการส่งข้อมูลเราเรียกว่า Sample rate โดยพารามิเตอร์ตัวนี้จะอยู่ในช่วงตั้งแต่ 10 samples/sec ไปจนถึง 200 samples/sec แต่ค่า default จะอยู่ที่ 100 samples/sec เราสามารถเปลี่ยนได้โดยการใช้คำสั่ง "Set Sample Rate" (0xF3)

Remote Mode: 
        ในโหมดนี้ เม้าส์จะอ่านค่า inputs และอัพเดต counters / flags ที่เวลาปัจจุบัน แต่ค่านั้นจะส่งไปให้โฮสก็ต่อเมื่อมีการส่งคำสั่งขออ่านจากโฮส "Read Data" (0xEB) เมื่อเม้าส์ได้รับคำสั่งแล้วก็จะส่ง movement data packet ไปยังโฮส หลังจากนั้นก็ Reset counters

Wrap Mode: 
        โหมดนี้จะเรียกอีกชื่อว่า echo mode ซึ่งเม้าส์จะทำการตอบกลับทุกอย่างที่ได้รับมาจากโฮส ยกเว้นเป็นคำสั่งที่ถูกต้อง ตัวเม้าส์จะไม่ตอบกลับ

Intellimouse Extensions: 
        อันนี้เหมือนเป็นฟังก์ชั่นเสริมที่เพิ่มออกมาจากเม้าส์ปกติ โดยเริ่มมาจากที่สมัยนั้น Microsoft ได้ออกแบบเม้าส์ที่มีลูกกลิ้งหมุนๆ และมีปุ่มมาเพิ่ม ตั้งแต่ปี 1996 และได้ใช้ชื่อว่า Intellimouse ดังนั้นถ้าเม้าส์ไหนมีความสามารถนี้ก็จะรองรับปุ่มได้ 5 ปุ่ม และการเคลื่อนที่ได้ 3 แกน (ขวา-ซ้าย, ขึ้น-ลง และล้อลูกกลิ้งหมุนๆ) โดยแพ็กเก็ตจะส่งออกมาเป็น 4-byte movement data packet จากเดิมมีแค่ 3-byte แต่การจะเปิดการใช้งานโหมด scrolling wheel เราจะต้องส่งคำสั่งต่อเนื่องเป็นลำดับตามนี้

* Set sample rate 200
* Set sample rate 100
* Set sample rate 80

        ต่อจากนั้นให้ใช้คำสั่ง "Get device ID" (0xF2) และรอคำตอบ ถ้าเม้าส์ไม่รองรับการใช้งาน Intellimose จะตอบกลับมาเป็น 0x00 แต่หากใช้เม้าส์รองรับการใช้งานจะตอบกลับมาเป็น 0x03 ถ้าใช้งานได้เราจะต้องรับข้อมูลจาก 3-byte เป็น 4-byte แทน ข้อมูล 4-byte movement date packet จะเป็นตามรูปด้านล่างนี้


        ค่าของแกน Z นั้นจะเป็น 2's complement จะแสดงค่าได้อยู่ในช่วง -127 ถึง +128 นั่นหมายความว่าค่าจะอยู่แค่ 7bit ล่าง ส่วน ที่เหลืออีก 1bit จะเป็นการบอกเครื่องหมาย

ในการเข้า scrolling wheel + 5 button mode โฮสจะต้องสั่งคำสั่งตามลำดับต่อไปนี้

* Set sample rate 200
* Set sample rate 200
* Set sample rate 80
        แล้วก็เหมือนเดิม ใช้คำสั่ง "Get device ID" (0xF2) แล้วรอคำตอบจากเม้าส์หากใช้งานได้จะให้ค่า device ID เป็น 0x04 และใช้ค่าข้อมูล 4-byte ตามรูปต่อไปนี้


        ตำแหน่ง 4 bit แรก Z0-Z3 เป็นค่า 2's complement ที่แสดงการหมุนของลูกกลิ้ง โดยค่าจะอยู่ในช่วง -8 ถึง +7
bit ถัดมา 4th Btn หากเป็น 1 แสดงว่ามีการกดปุ่ม 4 และ 0 หากไม่มีการกด
bit ถัดมา 5th Btn หากเป็น 1 แสดงว่ามีการกดปุ่ม 4 และ 0 หากไม่มีการกด
ส่วนอีก 2 bit ที่เหลือไม่ได้ใช้งาน

Command Set: 
        ต่อไปเป็นคำสั่งที่ใช้สำหรับส่งไปยังเม้าส์ แต่ถ้าเม้าส์ยังอยู่ใน Stream mode ตัวโฮสจะต้องต้องสั่งคำสั่ง "Disable data reporting" (0xF5) ก่อน ถึงจะสั่งคำสั่งอื่นๆได้

    * Reset (0xFF) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจึงเข้าสู่ Reset mode
    * Resend (0xFE) - คำสั่งนี้จะเป็นการขอคำตอบล่าสุดที่เม้าส์ส่งมายังโฮส
    * Set Defaults (0xF6) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจะทำการเซ็ทค่า Sampling rate = 100, Resolution = 4 counts/mm, Scaling = 1:1, Disable Data Reporting จากนั้นเม้าส์จะเคลียร์ค่า movement counters และเข้าสู่โหมด Stream mode
    * Disable Data Reporting (0xF5) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจะหยุดการส่งค่าออกมาและรีเซทค่า movement counters
    * Enable Data Reporting (0xF4) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจะส่งค่าออกมาและรีเซทค่า movement counters หากใช้ใน Remote mode อาจจะเกิดปัญหาได้
    * Set Sample Rate (0xF3) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจะอ่านค่าอีก 1 Byte จากโฮส แล้วบันทึกค่า Sample rate จากนั้นจะตอบกลับ "Acknowledge" (0xFA) อีกรอบ และรีเซ็ทค่า movement counters ค่า Sampling rate ที่ใส่ได้ก็คือ 10, 20, 40, 60, 80, 100 และ 200 samples/sec
    * Get Device ID (0xF2) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจะส่งค่า ID ออกมา (0x00 ถ้าเป็นเม้าส์ PS/2 ปกติ) แล้วก็รีเซ็ท movement counter
    * Set Remote Mode (0xF0) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจะรีเซทค่า movement counters แล้วเข้าสู่ remote mode
    * Set Wrap Mode (0xEE) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจะรีเซทค่า movement counters แล้วเข้าสู่ wrap mode
    * Reset Wrap Mode (0xEC) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจะรีเซทค่า movement counters แล้วเข้าสู่โหมดที่เข้ามาก่อน wrap mode
    * Read Data (0xEB) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจะส่งค่า movement data packet ออกมา หากอยู่ในโหมด remote mode จะต้องใช้คำสั่งนี้อ่านเท่านั้น หลังจากส่งค่าเสร็จจะรีเซ็ท movement counters
    * Set Stream Mode (0xEA) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจะรีเซทค่า movement counters แล้วเข้าสู่ stream mode
    * Status Request (0xE9) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจะส่ง 3-byte status packet ออกมาให้แล้วจึงรีเซทค่า movement counters โดยแพ็กเก็ตสถานะที่ส่งออกมาจะเป็น

    Right, Middle, Left Btn ถ้ากดจะเป็น 1 แต่ถ้าไม่ได้กดจะเป็น 0
    Enable จะเป็น 1 ถ้า Data reporting ถูก Enable และเป็น 0 หากถูก Disable
    Mode จะเป็น 1 ถ้าอยู่ในโหมด Remote และเป็น 0 หากอยู่ในโหมด Stream
    * Set Resolution (0xE8) - เม้าส์จะตอบกลับมาด้วย "Acknowledge" (0xFA) จากนั้นจะอ่านค่าอีก 1 Byte จากโฮส จากนั้นจะตอบกลับ "Acknowledge" (0xFA) อีกรอบ และรีเซ็ทค่า movement counters ค่า Resolution ที่ใส่ได้ก็คือ 1 count/mm (0x00), 2 count/mm (0x01), 4 count/mm (0x02) และ 8 count/mm (0x03)

ต่อไปเป็นตัวอย่างการเชื่อมต่อคุยกันระหว่างคอมพิวเตอร์กับเม้าส์

Power-on Reset:
Mouse: AA Self-test passed
Mouse: 00 Mouse ID
Host: FF Reset command
Mouse: FA Acknowledge
Mouse: AA Self-test passed
Mouse: 00 Mouse ID
Host: FF Reset command
Mouse: FA Acknowledge
Mouse: AA Self-test passed
Mouse: 00 Mouse ID
Host: FF Reset command
Mouse: FA Acknowledge
Mouse: AA Self-test passed
Mouse: 00 Mouse ID
Host: F3 Set Sample Rate : Attempt to Enter Microsoft
Mouse: FA Acknowledge : Scrolling Mouse mode
Host: C8 decimal 200 :
Mouse: FA Acknowledge :
Host: F3 Set Sample Rate :
Mouse: FA Acknowledge :
Host: 64 decimal 100 :
Mouse: FA Acknowledge :
Host: F3 Set Sample Rate :
Mouse: FA Acknowledge :
Host: 50 decimal 80 :
Mouse: FA Acknowledge :
Host: F2 Read Device Type :
Mouse: FA Acknowledge :
Mouse: 00 Mouse ID : Response 03 if microsoft scrolling mouse
Host: F3 Set Sample Rate
Mouse: FA Acknowledge
Host: 0A decimal 10
Mouse: FA Acknowledge
Host: F2 Read Device Type
Mouse: FA Acknowledge
Mouse: 00 Mouse ID
Host: E8 Set resolution
Mouse: FA Acknowledge
Host: 03 8 Counts/mm
Mouse: FA Acknowledge
Host: E6 Set Scaling 1:1
Mouse: FA Acknowledge
Host: F3 Set Sample Rate
Mouse: FA Acknowledge
Host: 28 decimal 40
Mouse: FA Acknowledge
Host: F4 Enable
Mouse: FA Acknowledge
Initialization complete...

If I then press the Left Button...
Mouse: 09 1 1 00001001; bit0 = Left button state; bit3 = always 1
Mouse: 00 1 1 No X-movement
Mouse: 00 1 1 No Y-movement
... and release the Left Button:
Mouse: 08 0 1 00001000 bit0 = Left button state; bit3 = always 1
Mouse: 00 1 1 No X-movement

Mouse: 00 1 1 No Y-movement

สำหรับใครอยากอ่านเพิ่มเติมให้โหลดไฟล์นี้ไปอ่าน

Sign in to leave a comment