Skip to content

Commit 82484cd

Browse files
committed
Merge branch 'master' of github.com:SukkoPera/PsxNewLib
2 parents ac02fea + b86400a commit 82484cd

File tree

2 files changed

+150
-2
lines changed

2 files changed

+150
-2
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include <PsxControllerHwSpi.h>
2+
#include <PsxNewLib.h>
3+
4+
PsxControllerHwSpi<4> psxCtrl;
5+
6+
boolean connected = false;
7+
boolean axisConfigPossible = true;
8+
boolean axisSticksEnabled = false;
9+
10+
void setup() {
11+
psxCtrl.begin();
12+
}
13+
14+
void loop() {
15+
if(connected && axisConfigPossible && !axisSticksEnabled){
16+
Serial.println("Attempting to enable axis sticks & rumble!");
17+
psxCtrl.setRumble(false, 0x00);
18+
if(psxCtrl.enterConfigMode() && psxCtrl.enableAnalogSticks(true, true)){
19+
psxCtrl.enableRumble();
20+
psxCtrl.exitConfigMode();
21+
Serial.println("Axis sticks enabled! Rumble enabled!");
22+
axisSticksEnabled = true;
23+
}
24+
else{
25+
Serial.println("Failed to enable axis sticks!");
26+
axisConfigPossible = false; // don't retry
27+
}
28+
}
29+
// put your main code here, to run repeatedly:
30+
if(psxCtrl.read()) {
31+
if(!connected && Serial) Serial.println("Found controller!");
32+
connected = true;
33+
if(axisSticksEnabled) {
34+
if(psxCtrl.buttonChanged(PSB_CROSS)) {
35+
if(psxCtrl.buttonPressed(PSB_CROSS)) {
36+
Serial.println("Rumbling...");
37+
psxCtrl.setRumble(true, 0xFF);
38+
}
39+
else {
40+
Serial.println("Ending rumble.");
41+
psxCtrl.setRumble(false, 0x00);
42+
}
43+
}
44+
}
45+
}
46+
else {
47+
if(connected && Serial) Serial.println("Lost controller!");
48+
connected = false;
49+
axisSticksEnabled = false;
50+
axisConfigPossible = true;
51+
}
52+
}

src/PsxNewLib.h

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ static const byte exit_config[] = {0x01, 0x43, 0x00, 0x00, 0x5A, 0x5A, 0x5A, 0x5
155155
*/
156156
static const byte type_read[] = {0x01, 0x45, 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A};
157157
static const byte set_mode[] = {0x01, 0x44, 0x00, /* enabled */ 0x01, /* locked */ 0x03, 0x00, 0x00, 0x00, 0x00};
158+
static const byte enable_rumble[] = {0x01, 0x4D, 0x00, /* motor 1 on */ 0x00, /* motor 2 on*/ 0x01, 0xff, 0xff, 0xff, 0xff};
158159
static const byte set_pressures[] = {0x01, 0x4F, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00};
159-
//~ static byte enable_rumble[] = {0x01, 0x4D, 0x00, 0x00, 0x01};
160160

161161
/** \brief Poll all buttons
162162
*
@@ -355,6 +355,27 @@ class PsxController {
355355
* True if the #analogButtonData were valid in last call to read()
356356
*/
357357
boolean analogButtonDataValid;
358+
359+
/** \brief Rumble feature enabled or disabled.
360+
*
361+
* True if rumble has been turned on with command 0x4d, false otherwise.
362+
* Rumble must be enabled and 7.5v supplied to pin 3!
363+
*/
364+
boolean rumbleEnabled;
365+
366+
/** \brief requested left motor (motor 1) power.
367+
*
368+
* 0xff for on, 0x00 for off, motor does not support partial activation.
369+
* Rumble must be enabled and 7.5v supplied to pin 3!
370+
*/
371+
byte motor1Level;
372+
373+
/** \brief requested right motor (motor 2) power.
374+
*
375+
* 0x00 to 0xFF -> 0 to 100% power.
376+
* Rumble must be enabled and 7.5v supplied to pin 3!
377+
*/
378+
byte motor2Level;
358379

359380
/** \brief Assert the Attention line
360381
*
@@ -559,6 +580,10 @@ class PsxController {
559580
memset (analogButtonData, 0, sizeof (analogButtonData));
560581

561582
protocol = PSPROTO_UNKNOWN;
583+
584+
rumbleEnabled = false;
585+
motor1Level = 0x00;
586+
motor2Level = 0x00;
562587

563588
// Some disposable readings to let the controller know we are here
564589
for (byte i = 0; i < 5; ++i) {
@@ -661,6 +686,67 @@ class PsxController {
661686
return ret;
662687
}
663688

689+
/** \brief Enable (or disable) the vibration capability of the DualShock / DualShock 2
690+
*
691+
* This function enables or disables the rumble feature of the DualShock / DualShock 2 controllers.
692+
* NOTE that this function does nothing on its own - the vibration on/off must be set using
693+
* setRumble() and the controller will begin to vibrate when the read() function is
694+
* next called.
695+
*
696+
* This function will only work if when the controller is in Configuration
697+
* Mode.
698+
*
699+
* \param[in] enabled true to enable both motors, false to disable them.
700+
*
701+
* \return true if we got bytes back. Eventually we should wait for ACK from the controller.
702+
*/
703+
boolean enableRumble(bool enabled = true) {
704+
boolean ret = true;
705+
byte out[sizeof (enable_rumble)];
706+
707+
memcpy (out, enable_rumble, sizeof (enable_rumble));
708+
out[3] = enabled ? 0x00 : 0xff;
709+
out[4] = enabled ? 0x01 : 0xff;
710+
711+
unsigned long start = millis ();
712+
byte cnt = 0;
713+
do {
714+
attention ();
715+
byte *in = autoShift (out, 5);
716+
noAttention ();
717+
718+
/* The real way to check if the command was successful is to wait for ACK.
719+
* Currently the library doesn't support the pin, so I will just assume success.
720+
*/
721+
if (in != nullptr) {
722+
++cnt;
723+
}
724+
ret = cnt >= 3;
725+
726+
if (!ret) {
727+
delay (COMMAND_RETRY_INTERVAL);
728+
}
729+
} while (!ret && millis () - start <= COMMAND_TIMEOUT);
730+
delay (MODE_SWITCH_DELAY);
731+
732+
rumbleEnabled = true;
733+
return ret;
734+
}
735+
736+
/** \brief Set the requested power output of the rumble motors on DualShock / DualShock 2 controllers.
737+
*
738+
* This function sets internal variables that set the requested motor power of the rumble motors.
739+
* NOTE this does nothing if rumble has not been enabled with enableRumble(), rumble motors will
740+
* activate or deactivate to match the arguments of this function with the next call to read()
741+
*
742+
* \param[in] enabled true to activate motor 1, false to deactivate.
743+
* \param[in] requested motor power of motor 2, where 0x00 to 0xFF corresponds to 0 to 100%.
744+
*/
745+
void setRumble(bool motor1Active = true, byte motor2Power = 0xff) {
746+
motor1Level = motor1Active ? 0xff : 0x00;
747+
motor2Level = motor2Power;
748+
}
749+
664750
/** \brief Enable (or disable) analog buttons
665751
*
666752
* This function enables or disables the analog buttons that were introduced
@@ -811,7 +897,17 @@ class PsxController {
811897
analogButtonDataValid = false;
812898

813899
attention ();
814-
byte *in = autoShift (poll, 3);
900+
byte *in = nullptr;
901+
if(rumbleEnabled) {
902+
byte out[sizeof (poll)];
903+
memcpy(out, poll, sizeof(poll));
904+
out[3] = motor1Level;
905+
out[4] = motor2Level;
906+
in = autoShift (out, sizeof(poll));
907+
}
908+
else {
909+
in = autoShift (poll, 3);
910+
}
815911
noAttention ();
816912

817913
if (in != NULL) {

0 commit comments

Comments
 (0)