This shows you the differences between two versions of the page.
usb_protocol_information [2007/02/06 14:56] 84.9.60.50 |
usb_protocol_information [2010/05/10 19:05] (current) |
||
---|---|---|---|
Line 7: | Line 7: | ||
===== Overview ===== | ===== Overview ===== | ||
+ | Data is transferred to and from the Ergodex DX1's second interface in multiple of 16 bytes. We refer this second interface as the "Control" interface. The first interface is a HID USB Keyboard. | ||
- | Data is transferred two and from the Ergodex DX1's second interface (the first interface is a HID USB Keyboard) in multiple of 16 bytes. | + | After snooping the USB communications between the host machine and the Ergodex DX1 the following information has been compiled. |
- | After snooping the USB communications between the host machine and the Ergodex DX1 I've found out the following information (which is incomplete, please | + | We split up the information into requests and responses |
- | ===== Commands ===== | + | ===== Control Requests ===== |
- | 16 bytes per command. | + | 16 bytes per request. |
+ | |||
+ | * Byte 1: Request Code | ||
+ | |||
+ | * Bytes 2-16: Request Data | ||
+ | |||
+ | Request data is different for each request. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Set Device ==== | ||
+ | |||
+ | __Usage__ | ||
+ | |||
+ | Send when device is idle. | ||
+ | |||
+ | __Request Code__ | ||
+ | |||
+ | 0x02 | ||
+ | |||
+ | __Request Data__ | ||
+ | |||
+ | The 15 byes of request data is made up as follows: | ||
+ | |||
+ | * Byte 1: unknown, use 0x00 | ||
+ | |||
+ | * Byte 2: unknown (seen values 0x00 and 0x01, use 0x00 for now) | ||
+ | |||
+ | <code> | ||
+ | 0x01 - enable "Test" mode. | ||
+ | </code> | ||
+ | |||
+ | When the device is in this mode will cause a "Control" device "Key Test" event to be raised when pressing or releasing any key. There is something rather odd about test mode though. If the RED LED is OFF you will receive up to 6 keypresses in the "Key Test" reponse. However, if the RED LED is ON and you press and hold one key and then press and hold another key you'll get a "Key Test" event with no key press information. Thus, you'll never be able to check for more than one key pressed at a time when in "Test" mode and the RED LED is ON. Weird. | ||
+ | |||
+ | <code> | ||
+ | 0x00 - normal mode | ||
+ | </code> | ||
+ | |||
+ | * Byte 3: set leds - bitmask | ||
+ | |||
+ | <code> | ||
+ | 0x00 - 00000000 - all led's off | ||
+ | 0x01 - 00000001 - green led on, red led off | ||
+ | 0x02 - 00000010 - green led off, red led on | ||
+ | 0x03 - 00000011 - green led on, red led on | ||
+ | </code> | ||
+ | |||
+ | * Byte 4: unknown use 0x00 | ||
+ | |||
+ | * Byte 5: This byte seems to control whether the main keys on the erogodex send back any data when pressed | ||
+ | |||
+ | <code> | ||
+ | 0x00 - enable keymap, all programmed keys will now send back data when pressed | ||
+ | 0x01 - clear keymap, all previously programmed keys are cleared from the device's memory. | ||
+ | </code> | ||
+ | |||
+ | * Byte 6: unknown, ergodex and ryan's drivers set this to 0x01 before and after sending one or more "Program Keys" requests | ||
+ | |||
+ | If the pad has been previously sent a set device command with this set to 0x01 sending subsequently setting this to 0x00 has no apparent effect. | ||
+ | If it's never set to 0x01 the pad does not seem to send any data back. TODO: investigate more. | ||
+ | |||
+ | * Byte 7: unknown, ergodex and ryan's drivers set this to 0x01 before and after sending one or more "Program Keys" requests, if left set at 0x00 the device appears to work as expected. | ||
+ | |||
+ | If the pad has been previously sent a set device command with this set to 0x01 sending subsequently setting this to 0x00 has no apparent effect. | ||
+ | If it's never set to 0x01 the pad does not seem to send any data back. TODO: investigate more. | ||
+ | |||
+ | Examples: | ||
+ | |||
+ | * Sent by erogdex software each time it changes the keyboard layout, before the "Program Keys" requests | ||
+ | |||
+ | 00 00 01 00 01 01 01 00 00 00 00 00 00 00 00 | ||
+ | |||
+ | * Sent by erogdex software each time it changes the keyboard layout, after the "Program Keys" requests | ||
+ | |||
+ | 00 00 01 00 00 01 01 00 00 00 00 00 00 00 00 | ||
+ | |||
+ | * Sent by erogdex software when you focus the ergodex manager window | ||
+ | |||
+ | 00 01 01 00 01 01 01 00 00 00 00 00 00 00 00 | ||
+ | |||
+ | Contents unknown at present. | ||
- | Byte 1: Command Code | ||
- | Bytes 2-16: Command Data | ||
Line 25: | Line 105: | ||
__Usage__ | __Usage__ | ||
- | Program up to 4 keys per command | + | Program up to 5 keys per requests |
- | __Command Code__ | + | __Request Code__ |
0x03 | 0x03 | ||
- | __Command Data__ | + | __Request Data__ |
3 bytes per key (below) | 3 bytes per key (below) | ||
- | If a key is not to be programmed then pad the command with 0x00's | + | If a key is not to be programmed then pad the request with 0x00's |
Then for each key that has a single key macro assigned to it sends 3 bytes | Then for each key that has a single key macro assigned to it sends 3 bytes | ||
- | * Byte 1: key number in hex (corresponds to the number on the physical key itself) | + | * Byte 1: key number in hex (corresponds to the number on the physical key itself) 0x01 for Key 1, etc |
* Byte 2: "Key Type" | * Byte 2: "Key Type" | ||
Key types: | Key types: | ||
- | 0x01 - "Single Key" | + | 0x01 - "Single Key" |
- | 0x02 - "Modifier Key" | + | 0x02 - "Modifier Key" |
- | 0x03 - "Macro" | + | 0x03 - "Macro" |
* Byte 3: different depending on "Key Type" | * Byte 3: different depending on "Key Type" | ||
Line 53: | Line 133: | ||
* "Single Key" | * "Single Key" | ||
- | Byte 3: Keyboard Scan Code | + | Byte 3: Set to a valid Keyboard Scan Code |
See Keyboard Scan Code Specification [References 1,2] Appendix C: USB Keyboard/Keypad Page (0x07) | See Keyboard Scan Code Specification [References 1,2] Appendix C: USB Keyboard/Keypad Page (0x07) | ||
Line 59: | Line 139: | ||
* "Modifier Key" | * "Modifier Key" | ||
- | Byte 3: | + | Byte 3: Set as follows |
- | 0x01 LEFT CTRL | + | 0x01 LEFT CTRL |
- | 0x02 LEFT SHIFT | + | 0x02 LEFT SHIFT |
- | 0x04 LEFT ALT | + | 0x04 LEFT ALT |
- | 0x08 LEFT WIN KEY (Left GUI Key) | + | 0x08 LEFT WIN KEY (Left GUI Key) |
- | 0x10 RIGHT CTRL | + | 0x10 RIGHT CTRL |
- | 0x20 RIGHT SHIFT | + | 0x20 RIGHT SHIFT |
- | 0x40 RIGHT ALT | + | 0x40 RIGHT ALT |
- | 0x80 RIGHT WIN KEY (Right GUI Key) | + | 0x80 RIGHT WIN KEY (Right GUI Key) |
- | * "macro" | + | * "Macro Key" |
Byte 3: Empty Value (0x00) | Byte 3: Empty Value (0x00) | ||
- | TODO: Snoop what is sent by the HID interface when a key is assigned a macro | + | When keys are assigned "Single" or "Modifer" keys data is received by the HID interface for key up and key down events (8 bytes per event, see below) |
- | Example of command sent when switching to an application that has a profile enabled for it. | + | When keys are assigned "Macro" keys data is received by the "control" interface for key up and key down events (16 bytes per event) |
- | 000421: Bulk or Interrupt Transfer (UP), 05.02.2007 20:27:53.4687500 +0.1093750 | + | Example of data sent when switching to an application that has a profile enabled for it. |
- | Pipe Handle: 0x87ca8884 (Endpoint Address: 0x2) | + | |
- | Send 0x70 bytes to the device: | + | 000003: Bulk or Interrupt Transfer (UP), 06.02.2007 14:50:42.4375000 +5.0312500 |
- | 03 01 01 1E 02 01 1F 03 01 20 04 01 21 05 01 22 ......... ..!.." | + | Pipe Handle: 0x88094694 (Endpoint Address: 0x2) |
- | 03 06 01 23 07 01 24 08 01 25 09 01 26 0A 01 27 ...#..$..%..&..' | + | Send 0x10 bytes to the device: |
- | 03 0B 01 14 0C 01 1A 0D 01 08 0E 01 15 0F 01 17 ................ | + | 02 00 00 01 00 01 01 01 00 00 00 00 00 00 00 00 ................ |
- | 03 10 01 1C 11 01 18 12 01 0C 13 01 12 14 01 13 ................ | + | |
- | 03 15 01 04 16 01 16 17 01 07 18 01 09 19 01 0A ................ | + | |
- | 03 29 01 1D 2A 01 1B 2B 01 06 2C 01 19 00 00 00 .)..*..+..,..... | + | 000004: Bulk or Interrupt Transfer (UP), 06.02.2007 14:50:42.4843750 +0.0468750 |
+ | Pipe Handle: 0x88094694 (Endpoint Address: 0x2) | ||
+ | Send 0x30 bytes to the device: | ||
+ | 03 01 02 02 02 03 00 03 03 00 04 03 00 0E 03 00 ................ | ||
+ | 03 12 03 00 18 03 00 1B 03 00 29 03 00 2C 03 00 ..........)..,.. | ||
02 00 00 01 00 00 01 01 00 00 00 00 00 00 00 00 ................ | 02 00 00 01 00 00 01 01 00 00 00 00 00 00 00 00 ................ | ||
- | ==== Finish Programming ==== | + | ==== Status Inquiry ==== |
__Usage__ | __Usage__ | ||
- | Sent after one or more "Program Keys" commands. | + | Sent when device is idle. |
- | __Command Code__ | + | __Request Code__ |
- | 0x02 | + | 0x01 |
- | __Command Data__ | + | __Request Data__ |
- | 00 00 01 00 00 01 01 00 00 00 00 00 00 00 00 | + | Fill with 0x00's |
- | Contents unknown at present. | ||
- | Very similar (only one bit difference) to "Start Programming" | + | ==== Get Device Information ==== |
- | ==== Start Programming ==== | + | Use to request a "Device Information" response. |
__Usage__ | __Usage__ | ||
Sent when device is idle. | Sent when device is idle. | ||
- | Sent before one or more "Program Keys" commands. | ||
- | __Command Code__ | + | __Request Code__ |
- | 0x02 | + | 0x0A |
- | __Command Data__ | + | __Request Data__ |
- | 00 00 01 00 01 01 01 00 00 00 00 00 00 00 00 | + | Fill with 0x00's |
- | Contents unknown at present. | + | ==== Unknown Command 1 ==== |
- | ==== Get Device Status ==== | + | The Ergodex software sends this command when recording macros. It has the effect of momentarily turning of the red LED. The green LED remains on. The command it sent once a second and the red led blinks off once a second. |
__Usage__ | __Usage__ | ||
- | Sent when device is idle. | + | Only seen being sent when the device is in "Test" mode. |
- | __Command Code__ | + | __Request Code__ |
- | 0x0A | + | 0x08 |
- | __Command Data__ | + | __Request Data__ |
- | Fill with 0x00's | + | Unknown. |
+ | |||
+ | Here's what the ergodex software sends (complete request, including command code). | ||
+ | |||
+ | <code> | ||
+ | 08 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 | ||
+ | </code> | ||
+ | |||
+ | ===== Event and Response Data ===== | ||
+ | |||
+ | HID Events are triggered by the device when keys are pressed on it. Which events you receive depend upon the device's status. | ||
+ | |||
+ | ==== HID Events ==== | ||
+ | |||
+ | The HID interface receives the following events: | ||
+ | |||
+ | * Key pressed and released events for keys assigned to "Single Key" or "Modifier Key" by the "Program Keys" command. | ||
+ | |||
+ | Each HID event causes the device to send 8 bytes of data. | ||
+ | |||
+ | If a key assigned to a "Modifier Key" is pressed at the same time as one or more keys assigned to "Modifier Key" or a single key assigned to "Single Key" then only one event is received and the data is combined. | ||
+ | e.g. if you assign keys 1-Shift, 2-Control, 3-A, 4-B and press 1 2 and 3 at the same time you'll get one event, if you press keys 1-4 you'll get two events. (TODO: double check) | ||
+ | |||
+ | There's not much point going into further detail regarding the HID event data as it should be the same as any other standard USB keyboard. | ||
+ | |||
+ | One thing to note is if you program keys 1-3 with ctrl and alt and shift and press them all at the same time you receive the following data | ||
+ | |||
+ | 07 00 00 00 00 00 00 00 | ||
+ | |||
+ | This indicates the values are additive, it has been reported it's possible to assign a key to "Modifier Key" and use the value 0x07 which simulates pressing all the keys together. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Control Responses ==== | ||
+ | |||
+ | The ergodex pad sends the sends data to the control interface when: | ||
+ | |||
+ | * Hand button pressed or released | ||
+ | * Record button pressed or released | ||
+ | * Key pressed or released for keys assigned to "Macro Key" by a "Program Keys" request. | ||
+ | * Key pressed or released when the pad is in "Test" mode. | ||
+ | * Status Requested | ||
+ | * Serial Number Requested | ||
+ | |||
+ | Data is set to the control interface in 16 byte blocks. | ||
+ | |||
+ | * Byte 1: "Event Type" code. | ||
+ | * Bytes 2-16: 15 bytes which is different for each response. | ||
+ | |||
+ | === Status Changed === | ||
+ | |||
+ | Sent in response to a status inquiry request or because the device's status changed due to the "Hand" or "Record" buttons being pressed. | ||
+ | |||
+ | __Event Type Code__ | ||
+ | |||
+ | 0x01 | ||
+ | |||
+ | __Data__ | ||
+ | |||
+ | The remaining 15 bytes of data is made up as follows | ||
+ | |||
+ | * Byte 1: unknown (seen value 0x04 only) | ||
+ | * Byte 2: status of something (seen values 0x00 and 0x01) - whether keys are active? | ||
+ | * Byte 3: status of leds, the bitmask is the same as for the setting LED's using the "Set Device" request | ||
+ | * Byte 4: bit-mapped button status. | ||
+ | |||
+ | The first two bits indicate the current status of the buttons | ||
+ | |||
+ | 0x00 - 00 - both buttons pressed | ||
+ | 0x01 - 01 - record button pressed | ||
+ | 0x02 - 10 - hand button pressed | ||
+ | 0x03 - 11 - no buttons pressed | ||
+ | |||
+ | When these two bits are inverted they make up a bitmask of the button status. When inverted the first bit (lsb) is 1 when the hand button is pressed and the second bit is 1 when the record button is pressed. | ||
+ | |||
+ | example: | ||
+ | <code> | ||
+ | #define PRES_EROGODEXDX1_OFFSET_STATUS_BUTTONS 0x04 | ||
+ | |||
+ | #define PRES_EROGDEXDX1_BITMASK_BUTTON_HAND ( 1 << 0 ) | ||
+ | #define PRES_EROGDEXDX1_BITMASK_BUTTON_RECORD ( 1 << 1 ) | ||
+ | |||
+ | BOOL bRecordButtonPressed = !(*(pResponseData + PRES_EROGODEXDX1_OFFSET_STATUS_BUTTONS) & PRES_EROGDEXDX1_BITMASK_BUTTON_RECORD); | ||
+ | BOOL bHandButtonPressed = !(*(pResponseData + PRES_EROGODEXDX1_OFFSET_STATUS_BUTTONS) & PRES_EROGDEXDX1_BITMASK_BUTTON_HAND); | ||
+ | </code> | ||
+ | |||
+ | * Byte 5: keymap status | ||
+ | |||
+ | It looks like byte 5 is set as follows: | ||
+ | |||
+ | 0x01 - keys are enabled | ||
+ | 0x00 - keys are disabled | ||
+ | |||
+ | * Bytes 6-15: unknown (only seen filled with 0x00's) | ||
+ | |||
+ | |||
+ | === Macro Key Pressed === | ||
+ | |||
+ | Sent as soon as a key assigned to "Macro Key" is pressed or released. | ||
+ | |||
+ | __Event Type Code__ | ||
+ | |||
+ | 0x02 | ||
+ | |||
+ | __Data__ | ||
+ | |||
+ | The remaining 15 bytes of data is made up as follows | ||
+ | |||
+ | * Byte 1: unknown (seen value 0x01) | ||
+ | * Byte 2: unknown (seen value 0x01) | ||
+ | * Bytes 3-8: | ||
+ | |||
+ | When a key is pressed the values corresponds to number printed on the physical keys | ||
+ | |||
+ | If one key is pressed then byte 3 will be the number of the key pressed, bytes 4-8 will contain 0x00 | ||
+ | |||
+ | If two keys are pressed then byte 3 and 4 will contain the numbers of the key that are currently pressed in random order, bytes 5-8 will contain 0x00 | ||
+ | |||
+ | ... and so on, up to 6 keys. | ||
+ | |||
+ | When all keys are released bytes 3-8 will be filled with 0x00. | ||
+ | |||
+ | * Bytes 9-15: unknown (only seen filled with 0x00's) | ||
+ | |||
+ | |||
+ | === Test === | ||
+ | |||
+ | Sent as soon as a key is pressed or released when the device is in "Test" mode. | ||
+ | |||
+ | __Event Type Code__ | ||
+ | |||
+ | 0x03 | ||
+ | |||
+ | __Data__ | ||
+ | |||
+ | The data for this response appears to be the same as the "Macro Key Pressed" response, except that you will only ever receive information about 1 key being pressed instead of up to 6 when the RED LED is ON. If two keys are pressed Bytes 3-8 will be filled with 0x00. If the RED LED is OFF you'll receive information about multiple keys in bytes 3-8. See "Set Device", above. | ||
+ | |||
+ | === Device Information === | ||
+ | |||
+ | Sent in response to a "Get Device Information" request | ||
+ | |||
+ | __Event Type Code__ | ||
+ | |||
+ | 0x0A | ||
- | Command Response: | + | __Data__ |
- | 16 bytes | + | The remaining 15 bytes of data is made up as follows |
- | First byte: 0x0A | + | * Bytes 1-8: PCB serial number? - appears to always be different from serial number printed underneath each ergodex. The numbers seem to bear no relation, but this number always uniquely identifies a DX1 pad. |
- | Next 8 bytes: encoded serial number? | + | * Bytes 9-10: binary status flags? pcb and or firmware revision numbers? (seen value 0x0101 only) |
- | Next 2 bytes: binary status flags? | + | * Bytes 11-15: unknown (seen value 0x0000000000 only) |
- | Next 5 bytes: filled with 0x00, more status flags? | + | |
===== References ===== | ===== References ===== |