USB Host Shield 2.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 
20 // To enable serial debugging see "settings.h"
21 //#define PRINTREPORT // Uncomment to print the report send by the PS4 Controller
22 
23 bool PS4Parser::checkDpad(ButtonEnum b) {
24  switch (b) {
25  case UP:
26  return ps4Data.btn.dpad == DPAD_LEFT_UP || ps4Data.btn.dpad == DPAD_UP || ps4Data.btn.dpad == DPAD_UP_RIGHT;
27  case RIGHT:
28  return ps4Data.btn.dpad == DPAD_UP_RIGHT || ps4Data.btn.dpad == DPAD_RIGHT || ps4Data.btn.dpad == DPAD_RIGHT_DOWN;
29  case DOWN:
30  return ps4Data.btn.dpad == DPAD_RIGHT_DOWN || ps4Data.btn.dpad == DPAD_DOWN || ps4Data.btn.dpad == DPAD_DOWN_LEFT;
31  case LEFT:
32  return ps4Data.btn.dpad == DPAD_DOWN_LEFT || ps4Data.btn.dpad == DPAD_LEFT || ps4Data.btn.dpad == DPAD_LEFT_UP;
33  default:
34  return false;
35  }
36 }
37 
39  if (b <= LEFT) // Dpad
40  return checkDpad(b);
41  else {
42  uint8_t button = pgm_read_byte(&PS4_BUTTONS[(uint8_t)b]);
43  uint8_t index = button < 8 ? 0 : button < 16 ? 1 : 2;
44  uint8_t mask = 1 << (button - 8 * index);
45  return ps4Data.btn.val[index] & mask;
46  }
47 }
48 
50  uint8_t mask, index = 0;
51  if (b <= LEFT) // Dpad
52  mask = 1 << b;
53  else {
54  uint8_t button = pgm_read_byte(&PS4_BUTTONS[(uint8_t)b]);
55  index = button < 8 ? 0 : button < 16 ? 1 : 2;
56  mask = 1 << (button - 8 * index);
57  }
58 
59  bool click = buttonClickState.val[index] & mask;
60  buttonClickState.val[index] &= ~mask; // Clear "click" event
61  return click;
62 }
63 
65  if (b == L2) // These are the only analog buttons on the controller
66  return ps4Data.trigger[0];
67  else if (b == R2)
68  return ps4Data.trigger[1];
69  return 0;
70 }
71 
73  return ps4Data.hatValue[(uint8_t)a];
74 }
75 
76 void PS4Parser::Parse(uint8_t len, uint8_t *buf) {
77  if (len > 0 && buf) {
78 #ifdef PRINTREPORT
79  for (uint8_t i = 0; i < len; i++) {
80  D_PrintHex<uint8_t > (buf[i], 0x80);
81  Notify(PSTR(" "), 0x80);
82  }
83  Notify(PSTR("\r\n"), 0x80);
84 #endif
85 
86  memcpy(&ps4Data, buf, min(len, sizeof(ps4Data)));
87  if (ps4Data.reportId != 0x01) {
88 #ifdef DEBUG_USB_HOST
89  Notify(PSTR("\r\nUnknown report id"), 0x80);
90 #endif
91  return;
92  }
93 
94  for (uint8_t i = 0; i < sizeof(ps4Data.btn); i++) {
95  if (ps4Data.btn.val[i] != oldButtonState.val[i]) { // Check if anything has changed
96  buttonClickState.val[i] = ps4Data.btn.val[i] & ~oldButtonState.val[i]; // Update click state variable
97  oldButtonState.val[i] = ps4Data.btn.val[i];
98  if (i == 0) { // 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
99  uint8_t newDpad = 0;
100  if (checkDpad(UP))
101  newDpad |= 1 << UP;
102  if (checkDpad(RIGHT))
103  newDpad |= 1 << RIGHT;
104  if (checkDpad(DOWN))
105  newDpad |= 1 << DOWN;
106  if (checkDpad(LEFT))
107  newDpad |= 1 << LEFT;
108  if (newDpad != oldDpad) {
109  buttonClickState.dpad = newDpad & ~oldDpad; // Override values
110  oldDpad = newDpad;
111  }
112  }
113  }
114  }
115  }
116 }
uint8_t hatValue[4]
Definition: PS4Parser.h:91
bool getButtonPress(ButtonEnum b)
Definition: PS4Parser.cpp:38
AnalogHatEnum
#define Notify(...)
Definition: message.h:44
void Parse(uint8_t len, uint8_t *buf)
Definition: PS4Parser.cpp:76
uint8_t val[3]
Definition: PS4Parser.h:71
uint8_t trigger[2]
Definition: PS4Parser.h:93
const uint8_t PS4_BUTTONS[]
Definition: PS4Parser.h:25
ButtonEnum
uint8_t dpad
Definition: PS4Parser.h:52
uint8_t reportId
Definition: PS4Parser.h:90
uint8_t getAnalogButton(ButtonEnum b)
Definition: PS4Parser.cpp:64
PS4Buttons btn
Definition: PS4Parser.h:92
bool getButtonClick(ButtonEnum b)
Definition: PS4Parser.cpp:49
uint8_t getAnalogHat(AnalogHatEnum a)
Definition: PS4Parser.cpp:72