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.
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, min((uint8_t)(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, min((uint8_t)(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 00154
Generated on Thu Jul 14 2022 08:33:41 by
1.7.2