2014-01-10 17:44:51 +01:00
/* Copyright (C) 2014 Kristian Lauszus, TKJ Electronics. All rights reserved.
This software may be distributed and modified under the terms of the GNU
General Public License version 2 ( GPL2 ) as published by the Free Software
Foundation and appearing in the file GPL2 . TXT included in the packaging of
this file . Please note that GPL2 Section 2 [ b ] requires that all works based
on this software must also be made publicly available under the terms of
the GPL2 ( " Copyleft " ) .
Contact information
- - - - - - - - - - - - - - - - - - -
Kristian Lauszus , TKJ Electronics
Web : http : //www.tkjelectronics.com
e - mail : kristianl @ tkjelectronics . com
*/
2014-01-18 22:36:01 +01:00
# include "PS4Parser.h"
2014-01-10 17:44:51 +01:00
// To enable serial debugging see "settings.h"
//#define PRINTREPORT // Uncomment to print the report send by the PS4 Controller
2014-01-18 22:36:01 +01:00
bool PS4Parser : : checkDpad ( ButtonEnum b ) {
switch ( b ) {
case UP :
return ps4Data . btn . dpad = = DPAD_LEFT_UP | | ps4Data . btn . dpad = = DPAD_UP | | ps4Data . btn . dpad = = DPAD_UP_RIGHT ;
case RIGHT :
return ps4Data . btn . dpad = = DPAD_UP_RIGHT | | ps4Data . btn . dpad = = DPAD_RIGHT | | ps4Data . btn . dpad = = DPAD_RIGHT_DOWN ;
case DOWN :
return ps4Data . btn . dpad = = DPAD_RIGHT_DOWN | | ps4Data . btn . dpad = = DPAD_DOWN | | ps4Data . btn . dpad = = DPAD_DOWN_LEFT ;
case LEFT :
return ps4Data . btn . dpad = = DPAD_DOWN_LEFT | | ps4Data . btn . dpad = = DPAD_LEFT | | ps4Data . btn . dpad = = DPAD_LEFT_UP ;
default :
return false ;
}
2014-01-10 17:44:51 +01:00
}
2014-01-18 22:36:01 +01:00
bool PS4Parser : : getButtonPress ( ButtonEnum b ) {
2014-01-12 16:31:47 +01:00
if ( b < = LEFT ) // Dpad
2014-01-18 22:36:01 +01:00
return checkDpad ( b ) ;
2014-01-10 17:44:51 +01:00
else {
2014-01-18 22:36:01 +01:00
uint8_t button = pgm_read_byte ( & PS4_BUTTONS [ ( uint8_t ) b ] ) ;
2014-01-10 17:44:51 +01:00
uint8_t index = button < 8 ? 0 : button < 16 ? 1 : 2 ;
2014-01-18 22:36:01 +01:00
uint8_t mask = 1 < < ( button - 8 * index ) ;
2014-01-10 17:44:51 +01:00
return ps4Data . btn . val [ index ] & mask ;
}
}
2014-01-18 22:36:01 +01:00
bool PS4Parser : : getButtonClick ( ButtonEnum b ) {
2014-01-12 18:15:13 +01:00
uint8_t mask , index = 0 ;
if ( b < = LEFT ) // Dpad
mask = 1 < < b ;
else {
uint8_t button = pgm_read_byte ( & PS4_BUTTONS [ ( uint8_t ) b ] ) ;
index = button < 8 ? 0 : button < 16 ? 1 : 2 ;
2014-01-18 22:36:01 +01:00
mask = 1 < < ( button - 8 * index ) ;
2014-01-10 17:44:51 +01:00
}
2014-01-12 18:15:13 +01:00
bool click = buttonClickState . val [ index ] & mask ;
buttonClickState . val [ index ] & = ~ mask ; // Clear "click" event
return click ;
2014-01-10 17:44:51 +01:00
}
2014-01-19 16:58:29 +01:00
uint8_t PS4Parser : : getAnalogButton ( ButtonEnum b ) {
if ( b = = L2 ) // These are the only analog buttons on the controller
2014-01-18 22:36:01 +01:00
return ps4Data . trigger [ 0 ] ;
2014-01-19 16:58:29 +01:00
else if ( b = = R2 )
2014-01-18 22:36:01 +01:00
return ps4Data . trigger [ 1 ] ;
return 0 ;
2014-01-10 17:44:51 +01:00
}
2014-01-18 22:36:01 +01:00
uint8_t PS4Parser : : getAnalogHat ( AnalogHatEnum a ) {
2014-01-10 17:44:51 +01:00
return ps4Data . hatValue [ ( uint8_t ) a ] ;
}
2014-01-18 22:36:01 +01:00
void PS4Parser : : Parse ( uint8_t len , uint8_t * buf ) {
if ( len > 0 & & buf ) {
2014-01-19 16:58:29 +01:00
# ifdef PRINTREPORT
2014-01-22 05:13:49 +01:00
Notify ( PSTR ( " \r \n " ) , 0x80 ) ;
2014-01-19 16:58:29 +01:00
for ( uint8_t i = 0 ; i < len ; i + + ) {
D_PrintHex < uint8_t > ( buf [ i ] , 0x80 ) ;
Notify ( PSTR ( " " ) , 0x80 ) ;
}
# endif
2014-01-22 05:13:49 +01:00
if ( buf [ 0 ] = = 0x01 ) // Check report ID
memcpy ( & ps4Data , buf + 1 , min ( len - 1 , sizeof ( ps4Data ) ) ) ;
else if ( buf [ 0 ] = = 0x11 ) // This report is send via Bluetooth, it has an offset of 2 compared to the USB data
memcpy ( & ps4Data , buf + 3 , min ( len - 3 , sizeof ( ps4Data ) ) ) ;
else {
2014-01-19 16:58:29 +01:00
# ifdef DEBUG_USB_HOST
2014-01-22 05:13:49 +01:00
Notify ( PSTR ( " \r \n Unknown report id: " ) , 0x80 ) ;
D_PrintHex < uint8_t > ( buf [ 0 ] , 0x80 ) ;
2014-01-19 16:58:29 +01:00
# endif
return ;
}
2014-01-10 17:44:51 +01:00
for ( uint8_t i = 0 ; i < sizeof ( ps4Data . btn ) ; i + + ) {
2014-01-12 18:15:13 +01:00
if ( ps4Data . btn . val [ i ] ! = oldButtonState . val [ i ] ) { // Check if anything has changed
2014-01-10 17:44:51 +01:00
buttonClickState . val [ i ] = ps4Data . btn . val [ i ] & ~ oldButtonState . val [ i ] ; // Update click state variable
oldButtonState . val [ i ] = ps4Data . btn . val [ i ] ;
2014-01-12 18:15:13 +01:00
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
uint8_t newDpad = 0 ;
2014-01-18 22:36:01 +01:00
if ( checkDpad ( UP ) )
2014-01-12 18:15:13 +01:00
newDpad | = 1 < < UP ;
2014-01-18 22:36:01 +01:00
if ( checkDpad ( RIGHT ) )
2014-01-12 18:15:13 +01:00
newDpad | = 1 < < RIGHT ;
2014-01-18 22:36:01 +01:00
if ( checkDpad ( DOWN ) )
2014-01-12 18:15:13 +01:00
newDpad | = 1 < < DOWN ;
2014-01-18 22:36:01 +01:00
if ( checkDpad ( LEFT ) )
2014-01-12 18:15:13 +01:00
newDpad | = 1 < < LEFT ;
if ( newDpad ! = oldDpad ) {
buttonClickState . dpad = newDpad & ~ oldDpad ; // Override values
oldDpad = newDpad ;
}
}
2014-01-10 17:44:51 +01:00
}
}
}
}