Skip to content

Commit b2dae57

Browse files
committed
Merge branch 'master' into SPPClient
Conflicts: BTD.cpp
2 parents 53a4ea6 + 6a9e574 commit b2dae57

25 files changed

+688
-269
lines changed

BTD.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ uint8_t BTD::Release() {
373373
uint8_t BTD::Poll() {
374374
if(!bPollEnable)
375375
return 0;
376-
if(qNextPollTime <= millis()) { // Don't poll if shorter than polling interval
376+
if((long)(millis() - qNextPollTime) >= 0L) { // Don't poll if shorter than polling interval
377377
qNextPollTime = millis() + pollInterval; // Set new poll time
378378
HCI_event_task(); // Poll the HCI event pipe
379379
HCI_task(); // HCI state machine
@@ -470,6 +470,7 @@ void BTD::HCI_event_task() {
470470
disc_bdaddr[j] = hcibuf[j + 3 + 6 * i];
471471

472472
hci_set_flag(HCI_FLAG_DEVICE_FOUND);
473+
break;
473474
} else {
474475
#ifdef EXTRADEBUG
475476
Notify(PSTR("\r\nClass of device: "), 0x80);
@@ -497,6 +498,7 @@ void BTD::HCI_event_task() {
497498
Notify(PSTR(" has been found"), 0x80);
498499
#endif
499500
hci_set_flag(HCI_FLAG_DEVICE_FOUND);
501+
break;
500502
}
501503

502504
}

PS4BT.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ class PS4BT : public BTHID, public PS4Parser {
5858
/** @name BTHID implementation */
5959
/**
6060
* Used to parse Bluetooth HID data.
61-
* @param bthid Pointer to the BTHID class.
6261
* @param len The length of the incoming data.
6362
* @param buf Pointer to the data buffer.
6463
*/

PS4USB.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,18 @@ class PS4USB : public HIDUniversal, public PS4Parser {
112112
};
113113
/**@}*/
114114

115+
/** @name USBDeviceConfig implementation */
116+
/**
117+
* Used by the USB core to check what this driver support.
118+
* @param vid The device's VID.
119+
* @param pid The device's PID.
120+
* @return Returns true if the device's VID and PID matches this driver.
121+
*/
122+
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) {
123+
return (vid == PS4_VID && pid == PS4_PID);
124+
};
125+
/**@}*/
126+
115127
private:
116128
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
117129
};

PSBuzz.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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 "PSBuzz.h"
19+
20+
// To enable serial debugging see "settings.h"
21+
//#define PRINTREPORT // Uncomment to print the report send by the PS Buzz Controllers
22+
23+
void PSBuzz::ParseHIDData(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
24+
if (HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID && len > 0 && buf) {
25+
#ifdef PRINTREPORT
26+
Notify(PSTR("\r\n"), 0x80);
27+
for (uint8_t i = 0; i < len; i++) {
28+
D_PrintHex<uint8_t > (buf[i], 0x80);
29+
Notify(PSTR(" "), 0x80);
30+
}
31+
#endif
32+
memcpy(&psbuzzButtons, buf + 2, min(len - 2, sizeof(psbuzzButtons)));
33+
34+
if (psbuzzButtons.val != oldButtonState.val) { // Check if anything has changed
35+
buttonClickState.val = psbuzzButtons.val & ~oldButtonState.val; // Update click state variable
36+
oldButtonState.val = psbuzzButtons.val;
37+
}
38+
}
39+
};
40+
41+
uint8_t PSBuzz::OnInitSuccessful() {
42+
if (HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID) {
43+
Reset();
44+
if (pFuncOnInit)
45+
pFuncOnInit(); // Call the user function
46+
else
47+
setLedOnAll(); // Turn the LED on, on all four controllers
48+
};
49+
return 0;
50+
};
51+
52+
bool PSBuzz::getButtonPress(ButtonEnum b, uint8_t controller) {
53+
return psbuzzButtons.val & (1UL << (b + 5 * controller)); // Each controller uses 5 bits, so the value is shifted 5 for each controller
54+
};
55+
56+
bool PSBuzz::getButtonClick(ButtonEnum b, uint8_t controller) {
57+
uint32_t mask = (1UL << (b + 5 * controller)); // Each controller uses 5 bits, so the value is shifted 5 for each controller
58+
bool click = buttonClickState.val & mask;
59+
buttonClickState.val &= ~mask; // Clear "click" event
60+
return click;
61+
};
62+
63+
// Source: http://www.developerfusion.com/article/84338/making-usb-c-friendly/ and https://github.com/torvalds/linux/blob/master/drivers/hid/hid-sony.c
64+
void PSBuzz::setLedRaw(bool value, uint8_t controller) {
65+
ledState[controller] = value; // Save value for next time it is called
66+
67+
uint8_t buf[7];
68+
buf[0] = 0x00;
69+
buf[1] = ledState[0] ? 0xFF : 0x00;
70+
buf[2] = ledState[1] ? 0xFF : 0x00;
71+
buf[3] = ledState[2] ? 0xFF : 0x00;
72+
buf[4] = ledState[3] ? 0xFF : 0x00;
73+
buf[5] = 0x00;
74+
buf[6] = 0x00;
75+
76+
PSBuzz_Command(buf, sizeof(buf));
77+
};
78+
79+
void PSBuzz::PSBuzz_Command(uint8_t *data, uint16_t nbytes) {
80+
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x00), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
81+
pUsb->ctrlReq(bAddress, epInfo[0].epAddr, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
82+
};

PSBuzz.h

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
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 _psbuzz_h_
19+
#define _psbuzz_h_
20+
21+
#include "hiduniversal.h"
22+
#include "controllerEnums.h"
23+
24+
#define PSBUZZ_VID 0x054C // Sony Corporation
25+
#define PSBUZZ_PID 0x1000 // PS Buzz Controller
26+
27+
/** Struct used to easily read the different buttons on the controllers */
28+
union PSBUZZButtons {
29+
struct {
30+
uint8_t red : 1;
31+
uint8_t yellow : 1;
32+
uint8_t green : 1;
33+
uint8_t orange : 1;
34+
uint8_t blue : 1;
35+
} __attribute__((packed)) btn[4];
36+
uint32_t val : 20;
37+
} __attribute__((packed));
38+
39+
/**
40+
* This class implements support for the PS Buzz controllers via USB.
41+
* It uses the HIDUniversal class for all the USB communication.
42+
*/
43+
class PSBuzz : public HIDUniversal {
44+
public:
45+
/**
46+
* Constructor for the PSBuzz class.
47+
* @param p Pointer to the USB class instance.
48+
*/
49+
PSBuzz(USB *p) :
50+
HIDUniversal(p) {
51+
Reset();
52+
};
53+
54+
/**
55+
* Used to check if a PS Buzz controller is connected.
56+
* @return Returns true if it is connected.
57+
*/
58+
bool connected() {
59+
return HIDUniversal::isReady() && HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID;
60+
};
61+
62+
/**
63+
* Used to call your own function when the device is successfully initialized.
64+
* @param funcOnInit Function to call.
65+
*/
66+
void attachOnInit(void (*funcOnInit)(void)) {
67+
pFuncOnInit = funcOnInit;
68+
};
69+
70+
/** @name PS Buzzer Controller functions */
71+
/**
72+
* getButtonPress(ButtonEnum b) will return true as long as the button is held down.
73+
*
74+
* While getButtonClick(ButtonEnum b) will only return it once.
75+
*
76+
* So you instance if you need to increase a variable once you would use getButtonClick(ButtonEnum b),
77+
* but if you need to drive a robot forward you would use getButtonPress(ButtonEnum b).
78+
* @param b ::ButtonEnum to read.
79+
* @param controller The controller to read from. Default to 0.
80+
* @return getButtonPress(ButtonEnum b) will return a true as long as a button is held down, while getButtonClick(ButtonEnum b) will return true once for each button press.
81+
*/
82+
bool getButtonPress(ButtonEnum b, uint8_t controller = 0);
83+
bool getButtonClick(ButtonEnum b, uint8_t controller = 0);
84+
/**@}*/
85+
/** @name PS Buzzer Controller functions */
86+
/**
87+
* Set LED value without using ::LEDEnum.
88+
* @param value See: ::LEDEnum.
89+
*/
90+
/**
91+
* Set LED values directly.
92+
* @param value Used to set whenever the LED should be on or off
93+
* @param controller The controller to control. Defaults to 0.
94+
*/
95+
void setLedRaw(bool value, uint8_t controller = 0);
96+
97+
/** Turn all LEDs off. */
98+
void setLedOffAll() {
99+
for (uint8_t i = 1; i < 4; i++) // Skip first as it will be set in setLedRaw
100+
ledState[i] = false; // Just an easy way to set all four off at the same time
101+
setLedRaw(false); // Turn the LED off, on all four controllers
102+
};
103+
104+
/**
105+
* Turn the LED off on a specific controller.
106+
* @param controller The controller to turn off. Defaults to 0.
107+
*/
108+
void setLedOff(uint8_t controller = 0) {
109+
setLedRaw(false, controller);
110+
};
111+
112+
113+
/** Turn all LEDs on. */
114+
void setLedOnAll() {
115+
for (uint8_t i = 1; i < 4; i++) // Skip first as it will be set in setLedRaw
116+
ledState[i] = true; // Just an easy way to set all four off at the same time
117+
setLedRaw(true); // Turn the LED on, on all four controllers
118+
};
119+
120+
/**
121+
* Turn the LED on on a specific controller.
122+
* @param controller The controller to turn off. Defaults to 0.
123+
*/
124+
void setLedOn(uint8_t controller = 0) {
125+
setLedRaw(true, controller);
126+
};
127+
128+
/**
129+
* Toggle the LED on a specific controller.
130+
* @param controller The controller to turn off. Defaults to 0.
131+
*/
132+
void setLedToggle(uint8_t controller = 0) {
133+
setLedRaw(!ledState[controller], controller);
134+
};
135+
/**@}*/
136+
137+
protected:
138+
/** @name HIDUniversal implementation */
139+
/**
140+
* Used to parse USB HID data.
141+
* @param hid Pointer to the HID class.
142+
* @param is_rpt_id Only used for Hubs.
143+
* @param len The length of the incoming data.
144+
* @param buf Pointer to the data buffer.
145+
*/
146+
virtual void ParseHIDData(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
147+
148+
/**
149+
* Called when a device is successfully initialized.
150+
* Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
151+
* This is useful for instance if you want to set the LEDs in a specific way.
152+
*/
153+
virtual uint8_t OnInitSuccessful();
154+
/**@}*/
155+
156+
/** Used to reset the different buffers to their default values */
157+
void Reset() {
158+
psbuzzButtons.val = 0;
159+
oldButtonState.val = 0;
160+
buttonClickState.val = 0;
161+
for (uint8_t i = 0; i < sizeof(ledState); i++)
162+
ledState[i] = 0;
163+
};
164+
165+
/** @name USBDeviceConfig implementation */
166+
/**
167+
* Used by the USB core to check what this driver support.
168+
* @param vid The device's VID.
169+
* @param pid The device's PID.
170+
* @return Returns true if the device's VID and PID matches this driver.
171+
*/
172+
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) {
173+
return (vid == PSBUZZ_VID && pid == PSBUZZ_PID);
174+
};
175+
/**@}*/
176+
177+
private:
178+
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
179+
180+
void PSBuzz_Command(uint8_t *data, uint16_t nbytes);
181+
182+
PSBUZZButtons psbuzzButtons, oldButtonState, buttonClickState;
183+
bool ledState[4];
184+
};
185+
#endif

README.md

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,30 @@ For more information about the hardware see the [Hardware Manual](http://www.cir
2222
* __Alexei Glushchenko, Circuits@Home__ - <alex-gl@mail.ru>
2323
* Developers of the USB Core, HID, FTDI, ADK, ACM, and PL2303 libraries
2424
* __Kristian Lauszus, TKJ Electronics__ - <kristianl@tkjelectronics.com>
25-
* Developer of the [BTD](#bluetooth-libraries), [BTHID](#bthid-library), [SPP](#spp-library), [PS4](#ps4-library), [PS3](#ps3-library), [Wii](#wii-library), and [Xbox](#xbox-library) libraries
25+
* Developer of the [BTD](#bluetooth-libraries), [BTHID](#bthid-library), [SPP](#spp-library), [PS4](#ps4-library), [PS3](#ps3-library), [Wii](#wii-library), [Xbox](#xbox-library), and [PSBuzz](#ps-buzz-library) libraries
2626
* __Andrew Kroll__ - <xxxajk@gmail.com>
2727
* Major contributor to mass storage code
2828

29+
# Table of Contents
30+
31+
* [How to include the library](#how-to-include-the-library)
32+
* [How to use the library](#how-to-use-the-library)
33+
* [Documentation](#documentation)
34+
* [Enable debugging](#enable-debugging)
35+
* [Boards](#boards)
36+
* [Bluetooth libraries](#bluetooth-libraries)
37+
* [BTHID library](#bthid-library)
38+
* [SPP library](#spp-library)
39+
* [PS4 Library](#ps4-library)
40+
* [PS3 Library](#ps3-library)
41+
* [Xbox Libraries](#xbox-libraries)
42+
* [Xbox library](#xbox-library)
43+
* [Xbox 360 Library](#xbox-360-library)
44+
* [Wii library](#wii-library)
45+
* [PS Buzz Library](#ps-buzz-library)
46+
* [Interface modifications](#interface-modifications)
47+
* [FAQ](#faq)
48+
2949
# How to include the library
3050

3151
First download the library by clicking on the following link: <https://github.com/felis/USB_Host_Shield_2.0/archive/master.zip>.
@@ -241,6 +261,39 @@ All the information about the Wii controllers are from these sites:
241261
* <http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Wii_Motion_Plus>
242262
* The old library created by _Tomoyuki Tanaka_: <https://github.com/moyuchin/WiiRemote_on_Arduino> also helped a lot.
243263
264+
### [PS Buzz Library](PSBuzz.cpp)
265+
266+
This library implements support for the Playstation Buzz controllers via USB.
267+
268+
It is essentially just a wrapper around the [HIDUniversal](hiduniversal.cpp) which takes care of the initializing and reading of the controllers. The [PSBuzz](PSBuzz.cpp) class simply inherits this and parses the data, so it is easy for users to read the buttons and turn the big red button on the controllers on and off.
269+
270+
The example [PSBuzz.ino](examples/PSBuzz/PSBuzz.ino) shows how one can do this with just a few lines of code.
271+
272+
More information about the controller can be found at the following sites:
273+
274+
* http://www.developerfusion.com/article/84338/making-usb-c-friendly/
275+
* https://github.com/torvalds/linux/blob/master/drivers/hid/hid-sony.c
276+
277+
# Interface modifications
278+
279+
The shield is using SPI for communicating with the MAX3421E USB host controller. It uses the SCK, MISO and MOSI pins via the ICSP on your board.
280+
281+
Furthermore it uses one pin as SS and one INT pin. These are by default located on pin 10 and 9 respectively. They can easily be reconfigured in case you need to use them for something else by cutting the jumper on the shield and then solder a wire from the pad to the new pin.
282+
283+
After that you need modify the following entry in [UsbCore.h](UsbCore.h):
284+
285+
```C++
286+
typedef MAX3421e<P10, P9> MAX3421E;
287+
```
288+
289+
For instance if you have rerouted SS to pin 7 it should read:
290+
291+
```C++
292+
typedef MAX3421e<P7, P9> MAX3421E;
293+
```
294+
295+
See the "Interface modifications" section in the [hardware manual](https://www.circuitsathome.com/usb-host-shield-hardware-manual) for more information.
296+
244297
# FAQ
245298

246299
> When I plug my device into the USB connector nothing happens?

0 commit comments

Comments
 (0)