USB Host Shield 2.0
Loading...
Searching...
No Matches
PS4Parser.cpp
Go to the documentation of this file.
1/* Copyright (C) 2014 Kristian Lauszus, TKJ Electronics. All rights reserved.
2
3 This software may be distributed and modified under the terms of the GNU
4 General Public License version 2 (GPL2) as published by the Free Software
5 Foundation and appearing in the file GPL2.TXT included in the packaging of
6 this file. Please note that GPL2 Section 2[b] requires that all works based
7 on this software must also be made publicly available under the terms of
8 the GPL2 ("Copyleft").
9
10 Contact information
11 -------------------
12
13 Kristian Lauszus, TKJ Electronics
14 Web : http://www.tkjelectronics.com
15 e-mail : kristianl@tkjelectronics.com
16 */
17
18#include "PS4Parser.h"
19
31
32// To enable serial debugging see "settings.h"
33//#define PRINTREPORT // Uncomment to print the report send by the PS4 Controller
34
35int8_t PS4Parser::getButtonIndexPS4(ButtonEnum b) {
36 const int8_t index = ButtonIndex(b);
37 if ((uint8_t) index >= (sizeof(PS4_BUTTONS) / sizeof(PS4_BUTTONS[0]))) return -1;
38 return index;
39}
40
41bool PS4Parser::checkDpad(ButtonEnum b) {
42 switch (b) {
43 case UP:
44 return ps4Data.btn.dpad == DPAD_LEFT_UP || ps4Data.btn.dpad == DPAD_UP || ps4Data.btn.dpad == DPAD_UP_RIGHT;
45 case RIGHT:
46 return ps4Data.btn.dpad == DPAD_UP_RIGHT || ps4Data.btn.dpad == DPAD_RIGHT || ps4Data.btn.dpad == DPAD_RIGHT_DOWN;
47 case DOWN:
48 return ps4Data.btn.dpad == DPAD_RIGHT_DOWN || ps4Data.btn.dpad == DPAD_DOWN || ps4Data.btn.dpad == DPAD_DOWN_LEFT;
49 case LEFT:
50 return ps4Data.btn.dpad == DPAD_DOWN_LEFT || ps4Data.btn.dpad == DPAD_LEFT || ps4Data.btn.dpad == DPAD_LEFT_UP;
51 default:
52 return false;
53 }
54}
55
57 const int8_t index = getButtonIndexPS4(b); if (index < 0) return 0;
58 if (index <= LEFT) // Dpad
59 return checkDpad(b);
60 else
61 return ps4Data.btn.val & (1UL << pgm_read_byte(&PS4_BUTTONS[index]));
62}
63
65 const int8_t index = getButtonIndexPS4(b); if (index < 0) return 0;
66 uint32_t mask = 1UL << pgm_read_byte(&PS4_BUTTONS[index]);
67 bool click = buttonClickState.val & mask;
68 buttonClickState.val &= ~mask; // Clear "click" event
69 return click;
70}
71
73 const int8_t index = getButtonIndexPS4(b); if (index < 0) return 0;
74 if (index == ButtonIndex(L2)) // These are the only analog buttons on the controller
75 return ps4Data.trigger[0];
76 else if (index == ButtonIndex(R2))
77 return ps4Data.trigger[1];
78 return 0;
79}
80
84
86 if (len > 1 && buf) {
87#ifdef PRINTREPORT
88 Notify(PSTR("\r\n"), 0x80);
89 for (uint8_t i = 0; i < len; i++) {
90 D_PrintHex<uint8_t > (buf[i], 0x80);
91 Notify(PSTR(" "), 0x80);
92 }
93#endif
94
95 if (buf[0] == 0x01) // Check report ID
96 memcpy(&ps4Data, buf + 1, min((uint8_t)(len - 1), MFK_CASTUINT8T sizeof(ps4Data)));
97 else if (buf[0] == 0x11) { // This report is send via Bluetooth, it has an offset of 2 compared to the USB data
98 if (len < 4) {
99#ifdef DEBUG_USB_HOST
100 Notify(PSTR("\r\nReport is too short: "), 0x80);
102#endif
103 return;
104 }
105 memcpy(&ps4Data, buf + 3, min((uint8_t)(len - 3), MFK_CASTUINT8T sizeof(ps4Data)));
106 } else {
107#ifdef DEBUG_USB_HOST
108 Notify(PSTR("\r\nUnknown report id: "), 0x80);
109 D_PrintHex<uint8_t > (buf[0], 0x80);
110#endif
111 return;
112 }
113
114 if (ps4Data.btn.val != oldButtonState.val) { // Check if anything has changed
115 buttonClickState.val = ps4Data.btn.val & ~oldButtonState.val; // Update click state variable
116 oldButtonState.val = ps4Data.btn.val;
117
118 // 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
119 uint8_t newDpad = 0;
120 if (checkDpad(UP))
121 newDpad |= 1 << UP;
122 if (checkDpad(RIGHT))
123 newDpad |= 1 << RIGHT;
124 if (checkDpad(DOWN))
125 newDpad |= 1 << DOWN;
126 if (checkDpad(LEFT))
127 newDpad |= 1 << LEFT;
128 if (newDpad != oldDpad) {
129 buttonClickState.dpad = newDpad & ~oldDpad; // Override values
130 oldDpad = newDpad;
131 }
132 }
133 }
134
135 if (ps4Output.reportChanged)
136 sendOutputReport(&ps4Output); // Send output report
137}
138
140 uint8_t i;
141 for (i = 0; i < sizeof(ps4Data.hatValue); i++)
142 ps4Data.hatValue[i] = 127; // Center value
143 ps4Data.btn.val = 0;
144 oldButtonState.val = 0;
145 for (i = 0; i < sizeof(ps4Data.trigger); i++)
146 ps4Data.trigger[i] = 0;
147 for (i = 0; i < sizeof(ps4Data.xy)/sizeof(ps4Data.xy[0]); i++) {
148 for (uint8_t j = 0; j < sizeof(ps4Data.xy[0].finger)/sizeof(ps4Data.xy[0].finger[0]); j++)
149 ps4Data.xy[i].finger[j].touching = 1; // The bit is cleared if the finger is touching the touchpad
150 }
151
152 ps4Data.btn.dpad = DPAD_OFF;
153 oldButtonState.dpad = DPAD_OFF;
154 buttonClickState.dpad = 0;
155 oldDpad = 0;
156
157 ps4Output.bigRumble = ps4Output.smallRumble = 0;
158 ps4Output.r = ps4Output.g = ps4Output.b = 0;
159 ps4Output.flashOn = ps4Output.flashOff = 0;
160 ps4Output.reportChanged = false;
161};
162
DPADEnum
Definition PS4Parser.cpp:20
@ DPAD_DOWN_LEFT
Definition PS4Parser.cpp:26
@ DPAD_RIGHT_DOWN
Definition PS4Parser.cpp:24
@ DPAD_UP
Definition PS4Parser.cpp:21
@ DPAD_DOWN
Definition PS4Parser.cpp:25
@ DPAD_UP_RIGHT
Definition PS4Parser.cpp:22
@ DPAD_LEFT_UP
Definition PS4Parser.cpp:28
@ DPAD_OFF
Definition PS4Parser.cpp:29
@ DPAD_RIGHT
Definition PS4Parser.cpp:23
@ DPAD_LEFT
Definition PS4Parser.cpp:27
const uint8_t PS4_BUTTONS[]
Definition PS4Parser.h:25
void Reset()
void Parse(uint8_t len, uint8_t *buf)
Definition PS4Parser.cpp:85
uint8_t getAnalogButton(ButtonEnum b)
Definition PS4Parser.cpp:72
virtual void sendOutputReport(PS4Output *output)=0
bool getButtonClick(ButtonEnum b)
Definition PS4Parser.cpp:64
uint8_t getAnalogHat(AnalogHatEnum a)
Definition PS4Parser.cpp:81
bool getButtonPress(ButtonEnum b)
Definition PS4Parser.cpp:56
constexpr int8_t ButtonIndex(ButtonEnum key)
AnalogHatEnum
ButtonEnum
@ DOWN
@ UP
@ LEFT
@ RIGHT
#define Notify(...)
Definition message.h:51
#define MFK_CASTUINT8T
Definition settings.h:200
touchpadXY xy[3]
Definition PS4Parser.h:108
PS4Buttons btn
Definition PS4Parser.h:95
uint8_t hatValue[4]
Definition PS4Parser.h:94
uint8_t trigger[2]
Definition PS4Parser.h:96
uint8_t b
Definition PS4Parser.h:118
uint8_t flashOff
Definition PS4Parser.h:119
uint8_t flashOn
Definition PS4Parser.h:119
uint8_t r
Definition PS4Parser.h:118
uint8_t smallRumble
Definition PS4Parser.h:117
uint8_t bigRumble
Definition PS4Parser.h:117
uint8_t g
Definition PS4Parser.h:118
bool reportChanged
Definition PS4Parser.h:120
struct touchpadXY::@28 finger[2]
uint8_t dpad
Definition PS4Parser.h:52
uint32_t val
Definition PS4Parser.h:71
#define pgm_read_byte(addr)
#define PSTR(str)