Note: The mercurial server is disabled at the moment while I investigate whether it can run with an acceptably low CPU load – Mike.
Notes on the XBox360 chatpad
These notes come from the website of Cliff L. Biffle, with a few additions from me. The "I" referred to throughout is Cliff, not me!
Pinout
The internal connector:
The external connector:
Signals:
Internal pin | External pin | Test point | Wire colour | Signal |
---|---|---|---|---|
1 | A | 5 | Red | +3.3V |
2 | B | — | Brown | RX in |
3 | C | 9 | Black | TX out |
4 | D | 8 | Orange | Gnd |
5 | Tip | 6 | Yellow | Tip (audio) |
6 | Ring | 7 | Blue | Ring (audio) |
7 | Shield | — | White | Shield (audio) |
Protocol
The chatpad communicates using standard 19.2kbps serial.
Initialization sequence
Greg Porter’s Propeller driver gives some basic information about the protocol, but much of it is implicit in assembly comments. In Greg’s driver I noticed two unexplained binary messages:
- "InitMessage" (87 02 8C 1F CC), and
- "AwakeMessage" (87 02 8C 1B D0).
I tried sending just one or the other to confirm that both are necessary, and they are:
- Sending just “InitMessage” causes the chatpad to send some sort of status report message (8 bytes) at about 10Hz. The message doesn’t change as keys are pressed, and it eventually stops coming.
- Sending just “AwakeMessage” gets no response.
- Sending “AwakeMessage” after “InitMessage” causes the chatpad to start sending messages when keys are pressed.
It seems necessary to continue to send AwakeMessage periodicially to keep the chatpad awake. Once every 500ms seems to be enough.
Message Framing
Messages from the Chatpad appear to always be eight bytes in length and begin with specific bytes, except that just after initialisation there are two bursts of data that doesn't seem to fit in with this scheme. They can easily be rejected by discarding bytes that are not a known beginning for an 8-byte frame, then reading the whole frame each time.
Status Messages
Status messages are sent every 78 milliseconds and start with byte A5. Here’s an example:
- A5 45 F0 04 00 04 04 1A
I currently have no idea what these messages mean.
Key Messages
Key messages are sent when a key is pressed or released. Oddly, the chatpad sends up to four such messages at each press/release event. Key messages start with byte B4.
Here are the press and release messages (respectively) for the A key:
- B4 C5 00 00 37 00 00 50
- B4 C5 00 00 00 00 00 87
Byte 4 in the press message (37 above) appears to be a keycode that uniquely identifies the key.
The chatpad can detect up to two simultaneous keys. When two keys are down, the keycode of the second key pressed appears in byte 5. For example, here is the sequence of messages generated by pressing A, pressing S, releasing A, then releasing S:
- B4 C5 00 00 37 00 00 50
- B4 C5 00 00 37 36 00 1A
- B4 C5 00 00 36 00 00 51
- B4 C5 00 00 00 00 00 87
From this we can see that Byte 7 is a checksum, computed by summing bytes 0-6 (modulo 256) and negating the result (two’s-complement).
Modifiers are transmitted in Byte 3, using a four-bit mask to represent the four modifier keys. Here is the sequence produced for shift-A:
- B4 C5 00 01 00 00 00 86
- B4 C5 00 01 37 00 00 4F
- B4 C5 00 01 00 00 00 86
- B4 C5 00 00 00 00 00 87
Do not be deceived by the use of a four-bit mask: the chatpad can’t detect more than two simultaneous keys, so there will never be more than two modifier bits set — and if two modifier bits are set, no non-modifier keycode can follow.
Key Map
In the table below, "M1" means the modifier mask (byte 3) is set to 1.
As you can see, the engineer responsible for the key map went insane before completing the right edge, where the keycodes become random.
C1 | C2 | C3 | C4 | C5 | C6 | C7 | C8 | C9 | C10 |
---|---|---|---|---|---|---|---|---|---|
17 | 16 | 15 | 14 | 13 | 12 | 11 | 67 | 66 | 65 |
27 | 26 | 25 | 24 | 23 | 22 | 21 | 76 | 75 | 64 |
37 | 36 | 35 | 34 | 33 | 32 | 31 | 77 | 72 | 62 |
M1 | 46 | 45 | 44 | 43 | 42 | 41 | 52 | 53 | 63 |
M2 | M8 | 55 | 54 | 51 | 71 | M4 |
In case you don’t have a chatpad handy to interpret the table above, here’s the same data phrased differently.
1 | 2 | 3 | 4 | 5 | 6 | 7 | |
---|---|---|---|---|---|---|---|
0x10 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
0x20 | U | Y | T | R | E | W | Q |
0x30 | J | H | G | F | D | S | A |
0x40 | N | B | V | C | X | Z | |
0x50 | Right | M | . | Space | Left | ||
0x60 | , | Enter | P | 0 | 9 | 8 | |
0x70 | Backsp | L | O | I | K |
Modifiers: Shift = 1, Green Square = 2, Orange Circle = 4, People = 8.