Keyboard firmwares for Atmel AVR and Cortex-M
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

XBOXRECV.h 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
  2. This software may be distributed and modified under the terms of the GNU
  3. General Public License version 2 (GPL2) as published by the Free Software
  4. Foundation and appearing in the file GPL2.TXT included in the packaging of
  5. this file. Please note that GPL2 Section 2[b] requires that all works based
  6. on this software must also be made publicly available under the terms of
  7. the GPL2 ("Copyleft").
  8. Contact information
  9. -------------------
  10. Kristian Lauszus, TKJ Electronics
  11. Web : http://www.tkjelectronics.com
  12. e-mail : [email protected]
  13. getBatteryLevel and checkStatus functions made by timstamp.co.uk found using BusHound from Perisoft.net
  14. */
  15. #ifndef _xboxrecv_h_
  16. #define _xboxrecv_h_
  17. #include "Usb.h"
  18. #include "xboxEnums.h"
  19. /* Data Xbox 360 taken from descriptors */
  20. #define EP_MAXPKTSIZE 32 // max size for data via USB
  21. /* Names we give to the 9 Xbox360 pipes */
  22. #define XBOX_CONTROL_PIPE 0
  23. #define XBOX_INPUT_PIPE_1 1
  24. #define XBOX_OUTPUT_PIPE_1 2
  25. #define XBOX_INPUT_PIPE_2 3
  26. #define XBOX_OUTPUT_PIPE_2 4
  27. #define XBOX_INPUT_PIPE_3 5
  28. #define XBOX_OUTPUT_PIPE_3 6
  29. #define XBOX_INPUT_PIPE_4 7
  30. #define XBOX_OUTPUT_PIPE_4 8
  31. // PID and VID of the different devices
  32. #define XBOX_VID 0x045E // Microsoft Corporation
  33. #define MADCATZ_VID 0x1BAD // For unofficial Mad Catz receivers
  34. #define JOYTECH_VID 0x162E // For unofficial Joytech controllers
  35. #define XBOX_WIRELESS_RECEIVER_PID 0x0719 // Microsoft Wireless Gaming Receiver
  36. #define XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID 0x0291 // Third party Wireless Gaming Receiver
  37. #define XBOX_MAX_ENDPOINTS 9
  38. /**
  39. * This class implements support for a Xbox Wireless receiver.
  40. *
  41. * Up to four controllers can connect to one receiver, if more is needed one can use a second receiver via the USBHub class.
  42. */
  43. class XBOXRECV : public USBDeviceConfig {
  44. public:
  45. /**
  46. * Constructor for the XBOXRECV class.
  47. * @param pUsb Pointer to USB class instance.
  48. */
  49. XBOXRECV(USB *pUsb);
  50. /** @name USBDeviceConfig implementation */
  51. /**
  52. * Address assignment and basic initilization is done here.
  53. * @param parent Hub number.
  54. * @param port Port number on the hub.
  55. * @param lowspeed Speed of the device.
  56. * @return 0 on success.
  57. */
  58. uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed);
  59. /**
  60. * Initialize the Xbox wireless receiver.
  61. * @param parent Hub number.
  62. * @param port Port number on the hub.
  63. * @param lowspeed Speed of the device.
  64. * @return 0 on success.
  65. */
  66. uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
  67. /**
  68. * Release the USB device.
  69. * @return 0 on success.
  70. */
  71. uint8_t Release();
  72. /**
  73. * Poll the USB Input endpoins and run the state machines.
  74. * @return 0 on success.
  75. */
  76. uint8_t Poll();
  77. /**
  78. * Get the device address.
  79. * @return The device address.
  80. */
  81. virtual uint8_t GetAddress() {
  82. return bAddress;
  83. };
  84. /**
  85. * Used to check if the controller has been initialized.
  86. * @return True if it's ready.
  87. */
  88. virtual bool isReady() {
  89. return bPollEnable;
  90. };
  91. /**
  92. * Used by the USB core to check what this driver support.
  93. * @param vid The device's VID.
  94. * @param pid The device's PID.
  95. * @return Returns true if the device's VID and PID matches this driver.
  96. */
  97. virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
  98. return ((vid == XBOX_VID || vid == MADCATZ_VID || vid == JOYTECH_VID) && (pid == XBOX_WIRELESS_RECEIVER_PID || pid == XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID));
  99. };
  100. /**@}*/
  101. /** @name Xbox Controller functions */
  102. /**
  103. * getButtonPress(uint8_t controller, ButtonEnum b) will return true as long as the button is held down.
  104. *
  105. * While getButtonClick(uint8_t controller, ButtonEnum b) will only return it once.
  106. *
  107. * So you instance if you need to increase a variable once you would use getButtonClick(uint8_t controller, ButtonEnum b),
  108. * but if you need to drive a robot forward you would use getButtonPress(uint8_t controller, ButtonEnum b).
  109. * @param b ::ButtonEnum to read.
  110. * @param controller The controller to read from. Default to 0.
  111. * @return getButtonClick(uint8_t controller, ButtonEnum b) will return a bool, while getButtonPress(uint8_t controller, ButtonEnum b) will return a byte if reading ::L2 or ::R2.
  112. */
  113. uint8_t getButtonPress(ButtonEnum b, uint8_t controller = 0);
  114. bool getButtonClick(ButtonEnum b, uint8_t controller = 0);
  115. /**@}*/
  116. /** @name Xbox Controller functions */
  117. /**
  118. * Return the analog value from the joysticks on the controller.
  119. * @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
  120. * @param controller The controller to read from. Default to 0.
  121. * @return Returns a signed 16-bit integer.
  122. */
  123. int16_t getAnalogHat(AnalogHatEnum a, uint8_t controller = 0);
  124. /**
  125. * Used to disconnect any of the controllers.
  126. * @param controller The controller to disconnect. Default to 0.
  127. */
  128. void disconnect(uint8_t controller = 0);
  129. /**
  130. * Turn rumble off and all the LEDs on the specific controller.
  131. * @param controller The controller to write to. Default to 0.
  132. */
  133. void setAllOff(uint8_t controller = 0) {
  134. setRumbleOn(0, 0, controller);
  135. setLedOff(controller);
  136. };
  137. /**
  138. * Turn rumble off the specific controller.
  139. * @param controller The controller to write to. Default to 0.
  140. */
  141. void setRumbleOff(uint8_t controller = 0) {
  142. setRumbleOn(0, 0, controller);
  143. };
  144. /**
  145. * Turn rumble on.
  146. * @param lValue Left motor (big weight) inside the controller.
  147. * @param rValue Right motor (small weight) inside the controller.
  148. * @param controller The controller to write to. Default to 0.
  149. */
  150. void setRumbleOn(uint8_t lValue, uint8_t rValue, uint8_t controller = 0);
  151. /**
  152. * Set LED value. Without using the ::LEDEnum or ::LEDModeEnum.
  153. * @param value See:
  154. * setLedOff(uint8_t controller), setLedOn(uint8_t controller, LED l),
  155. * setLedBlink(uint8_t controller, LED l), and setLedMode(uint8_t controller, LEDMode lm).
  156. * @param controller The controller to write to. Default to 0.
  157. */
  158. void setLedRaw(uint8_t value, uint8_t controller = 0);
  159. /**
  160. * Turn all LEDs off the specific controller.
  161. * @param controller The controller to write to. Default to 0.
  162. */
  163. void setLedOff(uint8_t controller = 0) {
  164. setLedRaw(0, controller);
  165. };
  166. /**
  167. * Turn on a LED by using ::LEDEnum.
  168. * @param l ::OFF, ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
  169. * @param controller The controller to write to. Default to 0.
  170. */
  171. void setLedOn(LEDEnum l, uint8_t controller = 0);
  172. /**
  173. * Turn on a LED by using ::LEDEnum.
  174. * @param l ::ALL, ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
  175. * @param controller The controller to write to. Default to 0.
  176. */
  177. void setLedBlink(LEDEnum l, uint8_t controller = 0);
  178. /**
  179. * Used to set special LED modes supported by the Xbox controller.
  180. * @param lm See ::LEDModeEnum.
  181. * @param controller The controller to write to. Default to 0.
  182. */
  183. void setLedMode(LEDModeEnum lm, uint8_t controller = 0);
  184. /**
  185. * Used to get the battery level from the controller.
  186. * @param controller The controller to read from. Default to 0.
  187. * @return Returns the battery level as an integer in the range of 0-3.
  188. */
  189. uint8_t getBatteryLevel(uint8_t controller = 0);
  190. /**
  191. * Used to check if a button has changed.
  192. * @param controller The controller to read from. Default to 0.
  193. * @return True if a button has changed.
  194. */
  195. bool buttonChanged(uint8_t controller = 0);
  196. /**
  197. * Used to call your own function when the controller is successfully initialized.
  198. * @param funcOnInit Function to call.
  199. */
  200. void attachOnInit(void (*funcOnInit)(void)) {
  201. pFuncOnInit = funcOnInit;
  202. };
  203. /**@}*/
  204. /** True if a wireless receiver is connected. */
  205. bool XboxReceiverConnected;
  206. /** Variable used to indicate if the XBOX 360 controller is successfully connected. */
  207. uint8_t Xbox360Connected[4];
  208. protected:
  209. /** Pointer to USB class instance. */
  210. USB *pUsb;
  211. /** Device address. */
  212. uint8_t bAddress;
  213. /** Endpoint info structure. */
  214. EpInfo epInfo[XBOX_MAX_ENDPOINTS];
  215. private:
  216. /**
  217. * Called when the controller is successfully initialized.
  218. * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
  219. * This is useful for instance if you want to set the LEDs in a specific way.
  220. * @param controller The initialized controller.
  221. */
  222. void onInit(uint8_t controller);
  223. void (*pFuncOnInit)(void); // Pointer to function called in onInit()
  224. bool bPollEnable;
  225. /* Variables to store the buttons */
  226. uint32_t ButtonState[4];
  227. uint32_t OldButtonState[4];
  228. uint16_t ButtonClickState[4];
  229. int16_t hatValue[4][4];
  230. uint16_t controllerStatus[4];
  231. bool buttonStateChanged[4]; // True if a button has changed
  232. bool L2Clicked[4]; // These buttons are analog, so we use we use these bools to check if they where clicked or not
  233. bool R2Clicked[4];
  234. uint32_t checkStatusTimer; // Timing for checkStatus() signals
  235. uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
  236. uint8_t writeBuf[7]; // General purpose buffer for output data
  237. void readReport(uint8_t controller); // read incoming data
  238. void printReport(uint8_t controller, uint8_t nBytes); // print incoming date - Uncomment for debugging
  239. /* Private commands */
  240. void XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes);
  241. void checkStatus();
  242. };
  243. #endif