Zoltan Hudak / UsbHostMAX3421E

Dependents:   UsbHostMAX3421E_Hello

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PS4USB.h Source File

PS4USB.h

00001 /* Copyright (C) 2014 Kristian Lauszus, TKJ Electronics. All rights reserved.
00002 
00003  This software may be distributed and modified under the terms of the GNU
00004  General Public License version 2 (GPL2) as published by the Free Software
00005  Foundation and appearing in the file GPL2.TXT included in the packaging of
00006  this file. Please note that GPL2 Section 2[b] requires that all works based
00007  on this software must also be made publicly available under the terms of
00008  the GPL2 ("Copyleft").
00009 
00010  Contact information
00011  -------------------
00012 
00013  Kristian Lauszus, TKJ Electronics
00014  Web      :  http://www.tkjelectronics.com
00015  e-mail   :  kristianl@tkjelectronics.com
00016  */
00017 
00018 #ifndef _ps4usb_h_
00019 #define _ps4usb_h_
00020 
00021 #include "hiduniversal.h"
00022 #include "PS4Parser.h"
00023 
00024 #define PS4_VID         0x054C // Sony Corporation
00025 #define PS4_PID         0x05C4 // PS4 Controller
00026 #define PS4_PID_SLIM    0x09CC // PS4 Slim Controller
00027 
00028 /**
00029  * This class implements support for the PS4 controller via USB.
00030  * It uses the HIDUniversal class for all the USB communication.
00031  */
00032 class PS4USB : public HIDUniversal, public PS4Parser {
00033 public:
00034         /**
00035          * Constructor for the PS4USB class.
00036          * @param  p   Pointer to the USB class instance.
00037          */
00038         PS4USB(Usb *p) :
00039         HIDUniversal(p) {
00040                 PS4Parser::Reset();
00041         };
00042 
00043         /**
00044          * Used to check if a PS4 controller is connected.
00045          * @return Returns true if it is connected.
00046          */
00047         bool connected() {
00048                 return HIDUniversal::isReady() && HIDUniversal::VID == PS4_VID && (HIDUniversal::PID == PS4_PID || HIDUniversal::PID == PS4_PID_SLIM);
00049         };
00050 
00051         /**
00052          * Used to call your own function when the device is successfully initialized.
00053          * @param funcOnInit Function to call.
00054          */
00055         void attachOnInit(void (*funcOnInit)(void)) {
00056                 pFuncOnInit = funcOnInit;
00057         };
00058 
00059 protected:
00060         /** @name HIDUniversal implementation */
00061         /**
00062          * Used to parse USB HID data.
00063          * @param hid       Pointer to the HID class.
00064          * @param is_rpt_id Only used for Hubs.
00065          * @param len       The length of the incoming data.
00066          * @param buf       Pointer to the data buffer.
00067          */
00068         virtual void ParseHIDData(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
00069                 if (HIDUniversal::VID == PS4_VID && (HIDUniversal::PID == PS4_PID || HIDUniversal::PID == PS4_PID_SLIM))
00070                         PS4Parser::Parse(len, buf);
00071         };
00072 
00073         /**
00074          * Called when a device is successfully initialized.
00075          * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
00076          * This is useful for instance if you want to set the LEDs in a specific way.
00077          */
00078         virtual uint8_t OnInitSuccessful() {
00079                 if (HIDUniversal::VID == PS4_VID && (HIDUniversal::PID == PS4_PID || HIDUniversal::PID == PS4_PID_SLIM)) {
00080                         PS4Parser::Reset();
00081                         if (pFuncOnInit)
00082                                 pFuncOnInit(); // Call the user function
00083                         else
00084                                 setLed(Blue);
00085                 };
00086                 return 0;
00087         };
00088         /**@}*/
00089 
00090         /** @name PS4Parser implementation */
00091         virtual void sendOutputReport(PS4Output *output) { // Source: https://github.com/chrippa/ds4drv
00092                 uint8_t buf[32];
00093                 memset(buf, 0, sizeof(buf));
00094 
00095                 buf[0] = 0x05; // Report ID
00096                 buf[1]= 0xFF;
00097 
00098                 buf[4] = output->smallRumble; // Small Rumble
00099                 buf[5] = output->bigRumble; // Big rumble
00100 
00101                 buf[6] = output->r; // Red
00102                 buf[7] = output->g; // Green
00103                 buf[8] = output->b; // Blue
00104 
00105                 buf[9] = output->flashOn; // Time to flash bright (255 = 2.5 seconds)
00106                 buf[10] = output->flashOff; // Time to flash dark (255 = 2.5 seconds)
00107 
00108                 output->reportChanged = false;
00109 
00110                 // The PS4 console actually set the four last bytes to a CRC32 checksum, but it seems like it is actually not needed
00111 
00112                 pUsb->outTransfer(bAddress, epInfo[epInterruptOutIndex].epAddr, sizeof(buf), buf);
00113         };
00114         /**@}*/
00115 
00116         /** @name USBDeviceConfig implementation */
00117         /**
00118          * Used by the USB core to check what this driver support.
00119          * @param  vid The device's VID.
00120          * @param  pid The device's PID.
00121          * @return     Returns true if the device's VID and PID matches this driver.
00122          */
00123         virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
00124                 return (vid == PS4_VID && (pid == PS4_PID || HIDUniversal::PID == PS4_PID_SLIM));
00125         };
00126         /**@}*/
00127 
00128 private:
00129         void (*pFuncOnInit)(void); // Pointer to function called in onInit()
00130 };
00131 #endif