# P.I. Engineering SDK Help

## X-keys XK-16 Stick Android Data Report

### General Information

VID | 05f3h
XK-16 Stick Android PID #1 | 04BDh or 1213
XK-16 Stick Android PID #2 | 04BEh or 1214
XK-16 Stick Android PID #3 | 04BFh or 1215
XK-16 Stick Android PID #4 | 04C0h or 1216
Consumer Usage Page | 1
Usage Page | 000Ch or 12

PID #1 Endpoints: Consumer Usge Page Input and Output (Hid Usage Page 12, Hid Usage 1), Mouse (Hid Usage Page 1, Hid Usage 2), Joystick (Hid Usage Page 1, Hid Usage 4).
PID #2 Endpoints: Consumer Usge Page Output (Hid Usage Page 12, Hid Usage 1), Mouse (Hid Usage Page 1, Hid Usage 2), Keyboard (Hid Usage Page 1, Hid Usage 6) and Multimedia (Hid Usage Page 12 and 1, Hid Usage 1 and 128). The use of this PID is mainly for Hardware Mode. Hardware Mode allows users to store macros to the device itself using the MacroWorks 3.1 programming utility or the X-keys Android app. Once the macros are stored they will work on any computer or OS that supports HID.
PID #3 Endpoints: Consumer Usge Page Output (Hid Usage Page 12, Hid Usage 1), Mouse (Hid Usage Page 1, Hid Usage 2), Joystick (Hid Usage Page 1, Hid Usage 4) and Multimedia (Hid Usage Page 12 and 1, Hid Usage 1 and 128). The use of this PID is mainly for Hardware Mode. Hardware Mode allows users to store macros to the device itself using the MacroWorks 3.1 programming utility or the X-keys Android app. Once the macros are stored they will work on any computer or OS that supports HID.
PID #4 Endpoints: Consumer Usge Page Input and Output (Hid Usage Page 12, Hid Usage 1), Boot Mouse (Hid Usage Page 1, Hid Usage 2), Boot Keyboard (Hid Usage Page 1, Hid Usage 6).

The XK-16 Stick Android is an Android enabled device in PIDs #1, #2 or #3. This means the device can be enumerated, read (if input report available), and written to on Android OS that support host USB, generally 3.1 or higher. Android OS is not able to enumerate a device with a boot keyboard and thus if the XK-16 Stick Android is in PID #4 it will appear to the Android OS as only a hardware keyboard/mouse, you will not be able to get a handle to it but it will work as a keyboard/mouse assuming there are hardware macros recorded on the keys.

XK-16 Stick Android is supported by P.I. Engineering Macroworks 3.1 for PC users, X-keys Android for Android users, P.I. Engineering SDK samples for Microsoft C# Express, VB Express, Microsoft C++ 2010 and Eclipse and Linux.

### X-keys XK-16 Stick Android Input Report

###

Figure 1: X-keys XK-16 Stick Android key reference.

Report Length: 37 bytes (PC), 36 (Android)

1. General Incoming Data

This data is returned when new data is detected such as button presses, unit id change. This report can be manually stimulated by sending an output report: Generate Data which is very useful for obtaining the initial state of the device immediately after enumeration.

Byte 1* | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | Byte 8 | Bytes 9-32 | Bytes 33-36 | Byte 37
Constant | Unit ID | Data Type | Keys | Keys | Keys | Keys | NumLck, CapsLck, ScrLck | Reserved | Time Stamp | # of times rebooted
ID | <data> | DT | D1 | D2 | D3 | D4 | DS | value | Time | Reboot

ID: The report ID=0 and is not present on Android OS which is the reason for the differeing report lengths between the PC and Android.
DT: Data Type value of 0 or 2 indicates the following data is a General Incoming Data report, 2 if generated by the output report: Generate Data. Data Type value of 214 indicates a Descriptor Data Report, see below. Data Type value of 224 indicates a Custom Data Report, see below.
D1: For all bits 0 for key up, 1 for key down. Bit 1=Key 0, bit 2=Key 4, bit 3=Key 8, bit 4=Key 12, bits 5-8=0 always.
D2: For all bits 0 for key up, 1 for key down. Bit 1=Key 1, bit 2=Key 5, bit 3=Key 9, bit 4=Key 13, bits 5-8=0 always.
D3: For all bits 0 for key up, 1 for key down. Bit 1=Key 2, bit 2=Key 6, bit 3=Key 10, bit 4=Key 14, bits 5-8=0 always.
D4: For all bits 0 for key up, 1 for key down. Bit 1=Key 3, bit 2=Key 7, bit 3=Key 11, bit 4=Key 15, bits 5-8=0 always.
DS: Bit 1=NumLock, bit 2=CapsLock, bit 3=ScrLock, bit 4=On Boot (sets the bit when device is booted up by the usb then sets it back to 0), bit 5=program switch.
Time: If enabled using output report: Enable Time Stamp gives a time in ms starting from when the device was plugged into a port in 4 bytes where byte 36 is the LSB or low byte and byte 33 is the MSB or high byte.
Reboot: This is a number that indicates how many times the device has been rebooted by the USB.

2. Descriptor Data

This data is returned after an output report: Request for Descriptor is sent. This report is available only in PID #1 and PID #4.

Byte 1* | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | Byte 8 | Byte 9 | Byte 10 | Byte 11 | Byte 12 | Byte 13 | Byte 14 | Byte 15 | Byte 16 | Byte 17 | Bytes 18-37
Constant | Unit ID | Data Type | Mode | Key mapstart | Layer2 Offset | Constant | Constant | Max Columns | Max Rows | LED State | Version | PID Low | PID Hi | Keymapstart Hi | Max Macro Address Lo | Max Macro Address Hi | Reserved
ID | <data> | 214 | Mode | 32 | 130 | 12 | 128 | 4 | 6 | LEDs | <data> | PIDL | PIDH | 0 | MMAL | MMAH | value

ID: The report ID=0 and is not present on Android OS which is the reason for the differeing report lengths between the PC and Android.
Mode: 0 means device is in PID #1, 1 = PID #2, 2 = PID #3, 3 = PID #4.
LEDs: Bit 7 set means Green LED is on, bit 8 set means Red LED is on.
PIDL: LSB of the Product Identification number or PID.
PIDH: MSB of the Product Identification number or PID.
MMAL: LSB of the maximum macro address, for internal use only.
MMAH: MSB of the maximum macro address, for internal use only.

3. Custom Data

This data is returned after an output report: Generate Custom Data is sent. This report is available only in PID #1 and PID #4.

Byte 1* | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | Bytes Count+5 to 36 | Byte 37
Constant | Unit ID | Data Type | Count of custom bytes to follow | Custom byte 1 | Custom byte 2 | Custom byte 3... | Reserved | Increment
ID | <data> | 224 | Count | B1 | B2 | B3... | value | Increment

ID: The report ID=0 and is not present on Android OS which is the reason for the differeing report lengths between the PC and Android.
Count: Number of custom bytes to follow.
B1: 1st custom byte.
B2: 2nd custom byte.
B3: 3rd custom byte and so on for as many bytes as specified in Count.
Increment: This byte is incremented each time a Custom Data report is sent thus even if 2 identical reports are sent they will both come in even if SuppressDuplicate reports is on.

### X-keys XK-16 Stick Android Output Report

The following types of output reports are shown in the summary below. Note, the first byte listed in this documentation is 0 and represents the report ID. This is not present on some non-PC operating systems. So when sending an output report on Android for example, eliminate this byte.

Report | Format | Description
--- | --- | ---
1 | 0, 186, LEDs, 0... | Set LEDs
2 | 0, 179, LEDIndex, State, 0... | Index Based Set LED (Flash)
3 | 0, 189, UnitID, 0... | Set Unit IDe
4 | 0, 214, 0... | Request Descriptor
5 | 0, 210, Enable, 0... | Enable Time Stamp
6 | 0, 177, 0... | Generate Data
7 | 0, 187, Bank 1 Intensity, 0... | Set Backlight Intensity
8 | 0, 184, 0... | Toggle Backlights
9 | 0, 182, Bank, OnOff, 0... | Turn On/Off Rows of Backlights
10 | 0, 181, Index, State, 0... | Index Based Set Backlights (Flash)
11 | 0, 180, Freq, 0... | Set Frequency of Flash
12 | 0, 199, Save, 0... | Save Backlight State to EEPROMe
13 | 0, 204, Mode, 0... | Change PIDe
14 | 0, 201, Modifier, 0, HC1, HC2, HC3, HC4, HC5, HC6, 0... | Keyboard Reflector (PID #2 and #4 only)
15 | 0, 203, Buttons, Mouse X, Mouse Y, Wheel X, Wheel Y, 0... | Mouse Reflector
16 | 0, 202, Joystick X, Joystick Y, Joystick Z rot., Joystick Z, Joystick Slider, Game Buttons 1, Game Buttons 2, Game Buttons 3, Game Buttons 4, 0, Point of View Hat, 0... | Joystick Reflector (PID #1 and #3 only)
17 | 0, 225, Usage ID LSB, Usage ID MSB, 0... | Multimedia Reflector (PID #2 and #3 only)
18 | 0, 195, Version LSB, Version MSB, 0... | Set Version Numbere
19 | 0, 238, 0... | Reboot Device

eCommand writes to EEPROM, do not perform this command excessively, do not exceed 50,000 writes to EEPROM.

Endpoint: 4, Vendor Defined Usage Page.

Report Length: 36 bytes.

1. Set LEDs

One of two methods for controlling the LEDs.

Byte 1* | Byte 2 | Byte 3 | Bytes 4-36
Constant | Command | LED Control | Constant
0 | 186 | LEDs | 0

LEDs: Bits 1-6=0, bit 7=1 to turn on Green LED or 0 to turn off Green LED, bit 8=1 to turn on Red LED or 0 to turn off Red LED.

2. Index Based Set LED (Flash)

One of two methods for controlling the LEDs. If flashing of LEDs is desired this method must be used.

Byte 1* | Byte 2 | Byte 3 | Byte 4 | Bytes 5-36
Constant | Command | LED Index | LED State | Constant
0 | 179 | LEDIndex | LEDState | 0

LEDIndex: 6 = green, 7 = red.
LEDState: 0 = off, 1 = on and 2 = flash. Set the frequency of the flash with output report: Set Frequency of Flash.

3. Set Unit ID

Send this output report to set the Unit ID of the device. This is useful if connecting more than one of the same device to the a computer.

Byte 1* | Byte 2 | Byte 3 | Bytes 4-36
Constant | Command | Unit ID (0-255) | Constant
0 | 189 | value | 0

4. Request Descriptor

After sending this output report a Descriptor input report will be generated.

Byte 1* | Byte 2 | Bytes 3-36
Constant | Command | Constant
0 | 214 | 0

5. Enable Time Stamp

By default the Time Stamp feature is enabled. To turn off send this command with Byte 3=0.

Byte 1* | Byte 2 | Byte 3 | Bytes 4-36
Constant | Command | Enable | Constant
0 | 210 | 0=off, 1=on | 0

6. Generate Data

After sending this output report a General Incoming Data input report will be generated with bit 2 of PS set (see General Incoming Data). This is useful in determining the initial state of the device before any data has changed.

Byte 1* | Byte 2 | Bytes 3-36
Constant | Command | Constant
0 | 177 | 0

7. Set Backlight Intensity

Byte 1* | Byte 2 | Byte 3 | Bytes 4-36
Constant | Command | Bank 1 Intensity | Constant
0 | 187 | Intensity | 0

Intensity: 0-255 where 0 is no intensity for that color or off, and 255 is the brightest. Usabe range is actually much narrower.

8. Toggle Backlights

Byte 1* | Byte 2 | Bytes 3-36
Constant | Command | Constant
0 | 184 | 0

9. Turn On/Off Rows of Backlights

Send this output report to either turn on or off rows of the backlights.

Byte 1* | Byte 2 | Byte 3 | Byte 4 | Bytes 5-36
Constant | Command | Bank # | State | Constant
0 | 182 | Bank | OnOff | 0

Bank: 0 = bank 1.
OnOff: For all bits 0 for no backlighting, 1 for backlighting. Bit 0 = 1st row, bit 1=2nd row, bit 2=3rd row, bit 3=4th row, bit 4=5th row, bit 5=6th row. Note the intensities are not affected by this command.

10. Index Based Set Backlights (Flash)

Control of individual backlights.

Byte 1* | Byte 2 | Byte 3 | Byte 4 | Bytes 5-36
Constant | Command | Key Index | State | Constant
0 | 181 | Index | State | 0

Index: The index for each key is as follows: Key0=0, Key 1=1, Key 2=2, Key 3=3, Key 4=4, Key 5=5, Key 6=8, Key 7=9, Key 8=10, Key 9=11, Key 10=12, Key 11=13, Key 12=16, Key 13=17, Key 14=18, Key 15=19.
State: 0 = off, 1 = on and 2 = flash. Set the frequency of the flash with output report: Set Frequency of Flash.

11. Set Frequency of Flash

Use this output report to control the frequency of the flashing of both the indicator LEDs and the backlights, same frequency is used for both.

Byte 1* | Byte 2 | Byte 3 | Bytes 4-36
Constant | Command | Frequency | Constant
0 | 180 | Freq | 0

Freq: 1-255 where 1 is the fastest flash and 255 is the slowest. 255 is approximately 4 seconds between flashes.

12. Save Backlight State to EEPROM

Send this output report to change the default backlighting on startup of device to the current backlight state, ie, what ever backlights are on or off at the time this report is sent will be the new default.

Byte 1* | Byte 2 | Byte 3 | Bytes 4-36
Constant | Command | Save | Constant
0 | 199 | Save | 0

Save: Any value other than 0 will save the current backlight state to the EEPROM so when the device is replugged it will display this save backlighting. Note because there is a limited number of times the EEProm can be written to, it is not a good idea to do this often.

13. Change PID

Send this output report to change between the 4 PIDs.

Byte 1* | Byte 2 | Byte 3 | Bytes 4-36
Constant | Command | Mode | Constant
0 | 204 | Mode | 0

Mode: 0 for PID #1, 1 for PID #2, 2 for PID #3 and 3 for PID #4.
PID #1 Endpoints: Consumer Usge Page Input and Output (Hid Usage Page 12, Hid Usage 1), Mouse (Hid Usage Page 1, Hid Usage 2), Joystick (Hid Usage Page 1, Hid Usage 4).
PID #2 Endpoints: Consumer Usge Page Output (Hid Usage Page 12, Hid Usage 1), Mouse (Hid Usage Page 1, Hid Usage 2), Keyboard (Hid Usage Page 1, Hid Usage 6) and Multimedia (Hid Usage Page 12 and 1, Hid Usage 1 and 128). The use of this PID is mainly for Hardware Mode. Hardware Mode allows users to store macros to the device itself using the MacroWorks 3.1 programming utility or the X-keys Android app. Once the macros are stored they will work on any computer or OS that supports HID.
PID #3 Endpoints: Consumer Usge Page Output (Hid Usage Page 12, Hid Usage 1), Mouse (Hid Usage Page 1, Hid Usage 2), Joystick (Hid Usage Page 1, Hid Usage 4) and Multimedia (Hid Usage Page 12 and 1, Hid Usage 1 and 128). The use of this PID is mainly for Hardware Mode. Hardware Mode allows users to store macros to the device itself using the MacroWorks 3.1 programming utility or the X-keys Android app. Once the macros are stored they will work on any computer or OS that supports HID.
PID #4 Endpoints: Consumer Usge Page Input and Output (Hid Usage Page 12, Hid Usage 1), Boot Mouse (Hid Usage Page 1, Hid Usage 2), Boot Keyboard (Hid Usage Page 1, Hid Usage 6).

14. Keyboard Reflector

Sends native keyboard messages.

Byte 1* | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | Byte 8 | Byte 9 | Byte 10 | Bytes 11-36
Constant | Command | Modifier | Constant | Hid Code 1 | Hid Code 2 | Hid Code 3 | Hid Code 4 | Hid Code 5 | Hid Code 6 | Constant
0 | 201 | Modifier | 0 | HC1 | HC2 | HC3 | HC4 | HC5 | HC6 | 0

Modifier: Bit 1=Left Ctrl, bit 2=Left Shift, bit 3=Left Alt, bit 4=Left Gui, bit 5=Right Ctrl, bit 6=Right Shift, bit 7=Right Alt, bit 8=Right Gui.
HC1=Hid Code for 1st key down, or 0 to release previous key press in this byte position.
HC2=Hid Code for 2nd key down, or 0 to release previous key press in this byte position.
HC3=Hid Code for 3rd key down, or 0 to release previous key press in this byte position.
HC4=Hid Code for 4th key down, or 0 to release previous key press in this byte position.
HC5=Hid Code for 5th key down, or 0 to release previous key press in this byte position.
HC6=Hid Code for 6th key down, or 0 to release previous key press in this byte position.

15. Mouse Reflector

Sends native mouse messages.

Byte 1* | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | Bytes 8-36
Constant | Command | Buttons | Mouse X | Mouse Y | Constant | Wheel Y | Constant
0 | 203 | Buttons | X | Y | 0 | WY | 0

Buttons: Bit 1=Left, bit 2=Right, bit 3=Center, bit 4=XButton1, bit 5=XButton2.
X=Mouse X motion. 128=0 no motion, 1-127 is right, 255-129=left, finest inc (1 and 255) to coarsest (127 and 129).
Y=Mouse Y motion. 128=0 no motion, 1-127 is down, 255-129=up, finest inc (1 and 255) to coarsest (127 and 129).
WY=Wheel Y. 128=0 no motion, 1-127 is up, 255-129=down, finest inc (1 and 255) to coarsest (127 and 129).
Example 1: Move mouse 1 mickey, the finest increment.
x+: 0, 203, 0, 1, 0, 0, 0
x-: 0, 203, 0, 255, 0, 0, 0
y+: 0, 203, 0, 0, 1, 0, 0
y-: 0, 203, 0, 0, 255, 0, 0
Example 2: Wheel Y with increment of 5.
+ motion: 0, 203, 0, 0, 0, 0, 5
- motion: 0, 203, 0, 0, 0, 0, 250 where 250=255-5
Example 3: Left button click.
left button down: 0, 203, 1, 0, 0, 0, 0
left button up: 0, 203, 0, 0, 0, 0, 0
Example 4: Left button down and drag
with mouse at starting position: 0, 203, 1, 0, 0, 0, 0
move mouse with button down: 0, 203, 1, 30, 30, 0, 0
release button: 0, 203, 0, 0, 0, 0, 0

16. Joystick Reflector

Sends native joystick messages. Must have the device set to a PID with a joystick endpoint; PID #1 or PID #3.

Byte 1* | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | Byte 8 | Byte 9 | Byte 10 | Byte 11 | Byte 12 | Byte 13 | Bytes 14-36
Constant | Command | Joystick X | Joystick Y | Joystick Z rot. | Joystick Z | Joystick Slider | Game Buttons | Game Buttons | Game Buttons | Game Buttons | Constant | Point of View Hat | Constant
0 | 202 | X | Y | Z rot. | Z | Slider | GB1 | GB2 | GB3 | GB4 | 0 | Hat | 0

X: Joystick X, 0-127 is from center to full right, 255-128 is from center to full left.
Y: Joystick Y, 0-127 is from center to bottom, 255-128 is from center to top.
Z rot.: Joystick Z rot., 0-127 is from center to bottom, 255-128 is from center to top.
Z.: Joystick Z, 0-127 is from center to bottom, 255-128 is from center to top.
Slider: Joystick Slider, 0-127 is from center to bottom, 255-128 is from center to top.
GB1: Game buttons 1-8, bit 1= game button 1, bit 2=game button 2, etc.
GB2: Game buttons 9-16, bit 1= game button 9, bit 2=game button 10, etc.
GB3: Game buttons 17-24, bit 1= game button 17, bit 2=game button 18, etc.
GB4: Game buttons 25-32, bit 1= game button 25, bit 2=game button 26, etc.
Hat: 0 to 7 clockwise, 8 is no hat.

17. Multimedia Reflector

Sends 2 byte multimedia messages. Must have the device set to a PID with a multimedia endpoint; PID #2 or PID #3. When in this PID there is no input data report available thus users of this feature will not be able to read any data, only write output reports. If desiring this feature users are instructed to use MacroWorks 3.1 programming utility for programming of the buttons and converting to a multimedia PID. This command must be followed with an "up" command with ULo and UHi =0.

Byte 1* | Byte 2 | Byte 3 | Byte 4 | Bytes 8-36
Constant | Command | Usage ID Lo | Usage ID Hi | Constant
0 | 225 | ULo | UHi | 0

ULo=Usage ID low byte see hut1_12.pdf, pages 75-85 Consumer Page.
UHi=Usage ID high byte see hut1_12.pdf, pages 75-85 Consumer Page.

Example: My Computer - 0, 225, 94, 01, 0... and send report using WriteData. Then 0, 225, 0, 0, 0... and send report using WriteData. In this example 0194 is the Usage ID for My Computer.

18. Set Version Number

Send this output report to set the Version of the device. This is not the firmware version given in the descriptor but a 2 byte number available on enumeration. The value is "remembered" so if it is changed, using this report, the device must be rebooted. The device can be rebooted by replugging it or by sending the output report : Reboot Device. The device is also rebooted when changing pids using output report: Change PID.

Byte 1* | Byte 2 | Byte 3 | Byte 4 | Bytes 5-36
Constant | Command | Version LB (0-255) | Version HB (0-255) | Constant
0 | 195 | value | value | 0

19. Reboot Device

Send this output report to reboot the device without having to unplug it. After sending this report the device must be re-enumerated.

Byte 1* | Byte 2 | Bytes 3-36
Constant | Command | Constant
0 | 238 | 0

*This first byte may be omitted on some non-PC operating systems. On these systems the read and write lengths will be 1 byte smaller.

Back to top