USB Host Shield 2.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
PS4Parser.h
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 #ifndef _ps4parser_h_
19 #define _ps4parser_h_
20 
21 #include "Usb.h"
22 #include "controllerEnums.h"
23 
25 const uint8_t PS4_BUTTONS[] PROGMEM = {
26  UP, // UP
27  RIGHT, // RIGHT
28  DOWN, // DOWN
29  LEFT, // LEFT
30 
31  0x0C, // SHARE
32  0x0D, // OPTIONS
33  0x0E, // L3
34  0x0F, // R3
35 
36  0x0A, // L2
37  0x0B, // R2
38  0x08, // L1
39  0x09, // R1
40 
41  0x07, // TRIANGLE
42  0x06, // CIRCLE
43  0x05, // CROSS
44  0x04, // SQUARE
45 
46  0x10, // PS
47  0x11, // TOUCHPAD
48 };
49 
50 union PS4Buttons {
51  struct {
52  uint8_t dpad : 4;
53  uint8_t square : 1;
54  uint8_t cross : 1;
55  uint8_t circle : 1;
56  uint8_t triangle : 1;
57 
58  uint8_t l1 : 1;
59  uint8_t r1 : 1;
60  uint8_t l2 : 1;
61  uint8_t r2 : 1;
62  uint8_t share : 1;
63  uint8_t options : 1;
64  uint8_t l3 : 1;
65  uint8_t r3 : 1;
66 
67  uint8_t ps : 1;
68  uint8_t touchpad : 1;
69  uint8_t timestamp : 6; // Only available via USB
70  };
71  uint8_t val[3];
72 };
73 
74 struct touchpadXY {
75  uint8_t dummy; // I can not figure out what this data is for, it seems to change randomly, maybe a timestamp?
76  struct {
77  struct {
78  uint8_t counter : 7; // Increments every time a finger is touching the touchpad
79  uint8_t touching : 1; // The top bit is cleared if the finger is touching the touchpad
80  };
81  struct {
82  uint16_t x : 12;
83  uint16_t y : 12;
84  };
85  } finger[2]; // 0 = first finger, 1 = second finger
86 };
87 
88 struct PS4Data {
89  /* Button and joystick values */
90  uint8_t reportId; // Always 0x01
91  uint8_t hatValue[4];
93  uint8_t trigger[2];
94 
95  // I still need to figure out how to make the PS4 controller send out the rest of the data via Bluetooth
96 
97  /* Gyro and accelerometer values */
98  uint8_t dummy[3]; // First two looks random, while the third one might be some kind of status - it increments once in a while
99  int16_t gyroY, gyroZ, gyroX;
100  int16_t accX, accZ, accY;
101 
102  /* The rest is data for the touchpad */
103  uint8_t dummy2[9]; // Byte 5 looks like some kind of status (maybe battery status), bit 1 of byte 8 is set every time a finger is moving around the touchpad
104  touchpadXY xy[3]; // It looks like it sends out three coordinates each time, this is possible because the microcontroller inside the PS4 controller is much faster than the Bluetooth connection.
105  // The last data is read from the last position in the array while the oldest measurement is from the first position.
106  // The first position will also keep it's value after the finger is released, while the other two will set them to zero.
107  // Note that if you read fast enough from the device, then only the first one will contain any data.
108 
109  // The last three bytes are always: 0x00, 0x80, 0x00
110 };
111 
112 enum DPADEnum {
113  DPAD_UP = 0x0,
115  DPAD_RIGHT = 0x2,
117  DPAD_DOWN = 0x4,
119  DPAD_LEFT = 0x6,
121  DPAD_OFF = 0x8,
122 };
123 
125 class PS4Parser {
126 public:
129  Reset();
130  };
131 
143  bool getButtonPress(ButtonEnum b);
144  bool getButtonClick(ButtonEnum b);
155  uint8_t getAnalogButton(ButtonEnum b);
156 
162  uint8_t getAnalogHat(AnalogHatEnum a);
174  uint16_t getX(uint8_t finger = 0, uint8_t xyId = 0) {
175  return ps4Data.xy[xyId].finger[finger].x;
176  };
177 
186  uint16_t getY(uint8_t finger = 0, uint8_t xyId = 0) {
187  return ps4Data.xy[xyId].finger[finger].y;
188  };
189 
198  bool isTouching(uint8_t finger = 0, uint8_t xyId = 0) {
199  return !(ps4Data.xy[xyId].finger[finger].touching); // The bit is cleared when a finger is touching the touchpad
200  };
201 
210  uint8_t getTouchCounter(uint8_t finger = 0, uint8_t xyId = 0) {
211  return ps4Data.xy[xyId].finger[finger].counter;
212  };
213 
219  double getAngle(AngleEnum a) {
220  if(a == Pitch)
221  return (atan2(ps4Data.accY, ps4Data.accZ) + PI) * RAD_TO_DEG;
222  else
223  return (atan2(ps4Data.accX, ps4Data.accZ) + PI) * RAD_TO_DEG;
224  };
225 
231  int16_t getSensor(SensorEnum s) {
232  switch(s) {
233  case gX:
234  return ps4Data.gyroX;
235  case gY:
236  return ps4Data.gyroY;
237  case gZ:
238  return ps4Data.gyroZ;
239  case aX:
240  return ps4Data.accX;
241  case aY:
242  return ps4Data.accY;
243  case aZ:
244  return ps4Data.accZ;
245  default:
246  return 0;
247  }
248  };
251 protected:
257  void Parse(uint8_t len, uint8_t *buf);
258 
260  void Reset() {
261  uint8_t i;
262  for (i = 0; i < sizeof(ps4Data.hatValue); i++)
263  ps4Data.hatValue[i] = 127;
264  for (i = 0; i < sizeof(PS4Buttons); i++) {
265  ps4Data.btn.val[i] = 0;
266  oldButtonState.val[i] = 0;
267  }
268  for (i = 0; i < sizeof(ps4Data.trigger); i++)
269  ps4Data.trigger[i] = 0;
270  for (i = 0; i < sizeof(ps4Data.xy)/sizeof(ps4Data.xy[0]); i++) {
271  for (uint8_t j = 0; j < sizeof(ps4Data.xy[0].finger)/sizeof(ps4Data.xy[0].finger[0]); j++)
272  ps4Data.xy[i].finger[j].touching = 1; // The bit is cleared if the finger is touching the touchpad
273  }
274 
275  ps4Data.btn.dpad = DPAD_OFF;
276  oldButtonState.dpad = DPAD_OFF;
277  buttonClickState.dpad = 0;
278  oldDpad = 0;
279  };
280 
281 private:
282  bool checkDpad(ButtonEnum b); // Used to check PS4 DPAD buttons
283 
284  PS4Data ps4Data;
285  PS4Buttons oldButtonState, buttonClickState;
286  uint8_t oldDpad;
287 };
288 #endif
DPADEnum
Definition: PS4Parser.h:112
void Reset()
Definition: PS4Parser.h:260
uint16_t getY(uint8_t finger=0, uint8_t xyId=0)
Definition: PS4Parser.h:186
int16_t gyroY
Definition: PS4Parser.h:99
uint8_t hatValue[4]
Definition: PS4Parser.h:91
uint8_t r1
Definition: PS4Parser.h:59
double getAngle(AngleEnum a)
Definition: PS4Parser.h:219
uint8_t dummy[3]
Definition: PS4Parser.h:98
int16_t accX
Definition: PS4Parser.h:100
bool getButtonPress(ButtonEnum b)
Definition: PS4Parser.cpp:38
AnalogHatEnum
uint8_t touching
Definition: PS4Parser.h:79
int16_t getSensor(SensorEnum s)
Definition: PS4Parser.h:231
int16_t accY
Definition: PS4Parser.h:100
uint8_t share
Definition: PS4Parser.h:62
uint8_t dummy
Definition: PS4Parser.h:75
int16_t gyroX
Definition: PS4Parser.h:99
uint8_t cross
Definition: PS4Parser.h:54
uint8_t l2
Definition: PS4Parser.h:60
uint8_t square
Definition: PS4Parser.h:53
uint8_t ps
Definition: PS4Parser.h:67
void Parse(uint8_t len, uint8_t *buf)
Definition: PS4Parser.cpp:76
bool isTouching(uint8_t finger=0, uint8_t xyId=0)
Definition: PS4Parser.h:198
uint8_t val[3]
Definition: PS4Parser.h:71
uint8_t counter
Definition: PS4Parser.h:78
uint16_t y
Definition: PS4Parser.h:83
uint8_t trigger[2]
Definition: PS4Parser.h:93
const uint8_t PS4_BUTTONS[]
Definition: PS4Parser.h:25
ButtonEnum
uint8_t dummy2[9]
Definition: PS4Parser.h:103
uint8_t l1
Definition: PS4Parser.h:58
uint8_t r3
Definition: PS4Parser.h:65
uint8_t dpad
Definition: PS4Parser.h:52
touchpadXY xy[3]
Definition: PS4Parser.h:104
uint8_t timestamp
Definition: PS4Parser.h:69
int16_t gyroZ
Definition: PS4Parser.h:99
AngleEnum
uint16_t getX(uint8_t finger=0, uint8_t xyId=0)
Definition: PS4Parser.h:174
uint8_t triangle
Definition: PS4Parser.h:56
uint8_t r2
Definition: PS4Parser.h:61
uint8_t reportId
Definition: PS4Parser.h:90
uint8_t getTouchCounter(uint8_t finger=0, uint8_t xyId=0)
Definition: PS4Parser.h:210
uint8_t options
Definition: PS4Parser.h:63
uint8_t touchpad
Definition: PS4Parser.h:68
uint8_t getAnalogButton(ButtonEnum b)
Definition: PS4Parser.cpp:64
uint8_t l3
Definition: PS4Parser.h:64
PS4Buttons btn
Definition: PS4Parser.h:92
bool getButtonClick(ButtonEnum b)
Definition: PS4Parser.cpp:49
SensorEnum
uint8_t circle
Definition: PS4Parser.h:55
uint16_t x
Definition: PS4Parser.h:82
int16_t accZ
Definition: PS4Parser.h:100
uint8_t getAnalogHat(AnalogHatEnum a)
Definition: PS4Parser.cpp:72
struct touchpadXY::@24 finger[2]