Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: UsbHostMAX3421E_Hello
PS4Parser.cpp
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 #include "PS4Parser.h" 00019 00020 enum DPADEnum { 00021 DPAD_UP = 0x0, 00022 DPAD_UP_RIGHT = 0x1, 00023 DPAD_RIGHT = 0x2, 00024 DPAD_RIGHT_DOWN = 0x3, 00025 DPAD_DOWN = 0x4, 00026 DPAD_DOWN_LEFT = 0x5, 00027 DPAD_LEFT = 0x6, 00028 DPAD_LEFT_UP = 0x7, 00029 DPAD_OFF = 0x8, 00030 }; 00031 00032 // To enable serial debugging see "settings.h" 00033 //#define PRINTREPORT // Uncomment to print the report send by the PS4 Controller 00034 00035 bool PS4Parser::checkDpad(ButtonEnum b) { 00036 switch (b) { 00037 case UP: 00038 return ps4Data.btn.dpad == DPAD_LEFT_UP || ps4Data.btn.dpad == DPAD_UP || ps4Data.btn.dpad == DPAD_UP_RIGHT; 00039 case RIGHT: 00040 return ps4Data.btn.dpad == DPAD_UP_RIGHT || ps4Data.btn.dpad == DPAD_RIGHT || ps4Data.btn.dpad == DPAD_RIGHT_DOWN; 00041 case DOWN: 00042 return ps4Data.btn.dpad == DPAD_RIGHT_DOWN || ps4Data.btn.dpad == DPAD_DOWN || ps4Data.btn.dpad == DPAD_DOWN_LEFT; 00043 case LEFT: 00044 return ps4Data.btn.dpad == DPAD_DOWN_LEFT || ps4Data.btn.dpad == DPAD_LEFT || ps4Data.btn.dpad == DPAD_LEFT_UP; 00045 default: 00046 return false; 00047 } 00048 } 00049 00050 bool PS4Parser::getButtonPress(ButtonEnum b) { 00051 if (b <= LEFT) // Dpad 00052 return checkDpad(b); 00053 else 00054 return ps4Data.btn.val & (1UL << pgm_read_byte(&PS4_BUTTONS[(uint8_t)b])); 00055 } 00056 00057 bool PS4Parser::getButtonClick(ButtonEnum b) { 00058 uint32_t mask = 1UL << pgm_read_byte(&PS4_BUTTONS[(uint8_t)b]); 00059 bool click = buttonClickState.val & mask; 00060 buttonClickState.val &= ~mask; // Clear "click" event 00061 return click; 00062 } 00063 00064 uint8_t PS4Parser::getAnalogButton(ButtonEnum b) { 00065 if (b == L2) // These are the only analog buttons on the controller 00066 return ps4Data.trigger[0]; 00067 else if (b == R2) 00068 return ps4Data.trigger[1]; 00069 return 0; 00070 } 00071 00072 uint8_t PS4Parser::getAnalogHat(AnalogHatEnum a) { 00073 return ps4Data.hatValue[(uint8_t)a]; 00074 } 00075 00076 void PS4Parser::Parse(uint8_t len, uint8_t *buf) { 00077 if (len > 1 && buf) { 00078 #ifdef PRINTREPORT 00079 Notify(PSTR("\r\n"), 0x80); 00080 for (uint8_t i = 0; i < len; i++) { 00081 D_PrintHex<uint8_t > (buf[i], 0x80); 00082 Notify(PSTR(" "), 0x80); 00083 } 00084 #endif 00085 00086 if (buf[0] == 0x01) // Check report ID 00087 memcpy(&ps4Data, buf + 1, std::min((unsigned int)(len - 1), MFK_CASTUINT8T sizeof(ps4Data))); 00088 else if (buf[0] == 0x11) { // This report is send via Bluetooth, it has an offset of 2 compared to the USB data 00089 if (len < 4) { 00090 #ifdef DEBUG_USB_HOST 00091 Notify(PSTR("\r\nReport is too short: "), 0x80); 00092 D_PrintHex<uint8_t > (len, 0x80); 00093 #endif 00094 return; 00095 } 00096 memcpy(&ps4Data, buf + 3, std::min((unsigned int)(len - 3), MFK_CASTUINT8T sizeof(ps4Data))); 00097 } else { 00098 #ifdef DEBUG_USB_HOST 00099 Notify(PSTR("\r\nUnknown report id: "), 0x80); 00100 D_PrintHex<uint8_t > (buf[0], 0x80); 00101 #endif 00102 return; 00103 } 00104 00105 if (ps4Data.btn.val != oldButtonState.val) { // Check if anything has changed 00106 buttonClickState.val = ps4Data.btn.val & ~oldButtonState.val; // Update click state variable 00107 oldButtonState.val = ps4Data.btn.val; 00108 00109 // The DPAD buttons does not set the different bits, but set a value corresponding to the buttons pressed, we will simply set the bits ourself 00110 uint8_t newDpad = 0; 00111 if (checkDpad(UP)) 00112 newDpad |= 1 << UP; 00113 if (checkDpad(RIGHT)) 00114 newDpad |= 1 << RIGHT; 00115 if (checkDpad(DOWN)) 00116 newDpad |= 1 << DOWN; 00117 if (checkDpad(LEFT)) 00118 newDpad |= 1 << LEFT; 00119 if (newDpad != oldDpad) { 00120 buttonClickState.dpad = newDpad & ~oldDpad; // Override values 00121 oldDpad = newDpad; 00122 } 00123 } 00124 } 00125 00126 if (ps4Output.reportChanged) 00127 sendOutputReport(&ps4Output); // Send output report 00128 } 00129 00130 void PS4Parser::Reset() { 00131 uint8_t i; 00132 for (i = 0; i < sizeof(ps4Data.hatValue); i++) 00133 ps4Data.hatValue[i] = 127; // Center value 00134 ps4Data.btn.val = 0; 00135 oldButtonState.val = 0; 00136 for (i = 0; i < sizeof(ps4Data.trigger); i++) 00137 ps4Data.trigger[i] = 0; 00138 for (i = 0; i < sizeof(ps4Data.xy)/sizeof(ps4Data.xy[0]); i++) { 00139 for (uint8_t j = 0; j < sizeof(ps4Data.xy[0].finger)/sizeof(ps4Data.xy[0].finger[0]); j++) 00140 ps4Data.xy[i].finger[j].touching = 1; // The bit is cleared if the finger is touching the touchpad 00141 } 00142 00143 ps4Data.btn.dpad = DPAD_OFF; 00144 oldButtonState.dpad = DPAD_OFF; 00145 buttonClickState.dpad = 0; 00146 oldDpad = 0; 00147 00148 ps4Output.bigRumble = ps4Output.smallRumble = 0; 00149 ps4Output.r = ps4Output.g = ps4Output.b = 0; 00150 ps4Output.flashOn = ps4Output.flashOff = 0; 00151 ps4Output.reportChanged = false; 00152 }; 00153
Generated on Tue Jul 12 2022 18:12:05 by
1.7.2