mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
parent
5776195523
commit
25117ab926
6 changed files with 362 additions and 3 deletions
82
PSBuzz.cpp
Normal file
82
PSBuzz.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* 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
|
||||
*/
|
||||
|
||||
#include "PSBuzz.h"
|
||||
|
||||
// To enable serial debugging see "settings.h"
|
||||
//#define PRINTREPORT // Uncomment to print the report send by the PS Buzz Controllers
|
||||
|
||||
void PSBuzz::ParseHIDData(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
|
||||
if (HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID && len > 0 && buf) {
|
||||
#ifdef PRINTREPORT
|
||||
Notify(PSTR("\r\n"), 0x80);
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
D_PrintHex<uint8_t > (buf[i], 0x80);
|
||||
Notify(PSTR(" "), 0x80);
|
||||
}
|
||||
#endif
|
||||
memcpy(&psbuzzButtons, buf + 2, min(len - 2, sizeof(psbuzzButtons)));
|
||||
|
||||
if (psbuzzButtons.val != oldButtonState.val) { // Check if anything has changed
|
||||
buttonClickState.val = psbuzzButtons.val & ~oldButtonState.val; // Update click state variable
|
||||
oldButtonState.val = psbuzzButtons.val;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
uint8_t PSBuzz::OnInitSuccessful() {
|
||||
if (HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID) {
|
||||
Reset();
|
||||
if (pFuncOnInit)
|
||||
pFuncOnInit(); // Call the user function
|
||||
else
|
||||
setLedOnAll(); // Turn the LED on, on all four controllers
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
bool PSBuzz::getButtonPress(ButtonEnum b, uint8_t controller) {
|
||||
return psbuzzButtons.val & (1UL << (b + 5 * controller)); // Each controller uses 5 bits, so the value is shifted 5 for each controller
|
||||
};
|
||||
|
||||
bool PSBuzz::getButtonClick(ButtonEnum b, uint8_t controller) {
|
||||
uint32_t mask = (1UL << (b + 5 * controller)); // Each controller uses 5 bits, so the value is shifted 5 for each controller
|
||||
bool click = buttonClickState.val & mask;
|
||||
buttonClickState.val &= ~mask; // Clear "click" event
|
||||
return click;
|
||||
};
|
||||
|
||||
// Source: http://www.developerfusion.com/article/84338/making-usb-c-friendly/ and https://github.com/torvalds/linux/blob/master/drivers/hid/hid-sony.c
|
||||
void PSBuzz::setLedRaw(bool value, uint8_t controller) {
|
||||
ledState[controller] = value; // Save value for next time it is called
|
||||
|
||||
uint8_t buf[7];
|
||||
buf[0] = 0x00;
|
||||
buf[1] = ledState[0] ? 0xFF : 0x00;
|
||||
buf[2] = ledState[1] ? 0xFF : 0x00;
|
||||
buf[3] = ledState[2] ? 0xFF : 0x00;
|
||||
buf[4] = ledState[3] ? 0xFF : 0x00;
|
||||
buf[5] = 0x00;
|
||||
buf[6] = 0x00;
|
||||
|
||||
PSBuzz_Command(buf, sizeof(buf));
|
||||
};
|
||||
|
||||
void PSBuzz::PSBuzz_Command(uint8_t *data, uint16_t nbytes) {
|
||||
// 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)
|
||||
pUsb->ctrlReq(bAddress, epInfo[0].epAddr, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
|
||||
};
|
185
PSBuzz.h
Normal file
185
PSBuzz.h
Normal file
|
@ -0,0 +1,185 @@
|
|||
/* 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
|
||||
*/
|
||||
|
||||
#ifndef _psbuzz_h_
|
||||
#define _psbuzz_h_
|
||||
|
||||
#include "hiduniversal.h"
|
||||
#include "controllerEnums.h"
|
||||
|
||||
#define PSBUZZ_VID 0x054C // Sony Corporation
|
||||
#define PSBUZZ_PID 0x1000 // PS Buzz Controller
|
||||
|
||||
/** Struct used to easily read the different buttons on the controllers */
|
||||
union PSBUZZButtons {
|
||||
struct {
|
||||
uint8_t red : 1;
|
||||
uint8_t yellow : 1;
|
||||
uint8_t green : 1;
|
||||
uint8_t orange : 1;
|
||||
uint8_t blue : 1;
|
||||
} __attribute__((packed)) btn[4];
|
||||
uint32_t val : 20;
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
* This class implements support for the PS Buzz controllers via USB.
|
||||
* It uses the HIDUniversal class for all the USB communication.
|
||||
*/
|
||||
class PSBuzz : public HIDUniversal {
|
||||
public:
|
||||
/**
|
||||
* Constructor for the PSBuzz class.
|
||||
* @param p Pointer to the USB class instance.
|
||||
*/
|
||||
PSBuzz(USB *p) :
|
||||
HIDUniversal(p) {
|
||||
Reset();
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to check if a PS Buzz controller is connected.
|
||||
* @return Returns true if it is connected.
|
||||
*/
|
||||
bool connected() {
|
||||
return HIDUniversal::isReady() && HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to call your own function when the device is successfully initialized.
|
||||
* @param funcOnInit Function to call.
|
||||
*/
|
||||
void attachOnInit(void (*funcOnInit)(void)) {
|
||||
pFuncOnInit = funcOnInit;
|
||||
};
|
||||
|
||||
/** @name PS Buzzer Controller functions */
|
||||
/**
|
||||
* getButtonPress(ButtonEnum b) will return true as long as the button is held down.
|
||||
*
|
||||
* While getButtonClick(ButtonEnum b) will only return it once.
|
||||
*
|
||||
* So you instance if you need to increase a variable once you would use getButtonClick(ButtonEnum b),
|
||||
* but if you need to drive a robot forward you would use getButtonPress(ButtonEnum b).
|
||||
* @param b ::ButtonEnum to read.
|
||||
* @param controller The controller to read from. Default to 0.
|
||||
* @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.
|
||||
*/
|
||||
bool getButtonPress(ButtonEnum b, uint8_t controller = 0);
|
||||
bool getButtonClick(ButtonEnum b, uint8_t controller = 0);
|
||||
/**@}*/
|
||||
/** @name PS Buzzer Controller functions */
|
||||
/**
|
||||
* Set LED value without using ::LEDEnum.
|
||||
* @param value See: ::LEDEnum.
|
||||
*/
|
||||
/**
|
||||
* Set LED values directly.
|
||||
* @param value Used to set whenever the LED should be on or off
|
||||
* @param controller The controller to control. Defaults to 0.
|
||||
*/
|
||||
void setLedRaw(bool value, uint8_t controller = 0);
|
||||
|
||||
/** Turn all LEDs off. */
|
||||
void setLedOffAll() {
|
||||
for (uint8_t i = 1; i < 4; i++) // Skip first as it will be set in setLedRaw
|
||||
ledState[i] = false; // Just an easy way to set all four off at the same time
|
||||
setLedRaw(false); // Turn the LED off, on all four controllers
|
||||
};
|
||||
|
||||
/**
|
||||
* Turn the LED off on a specific controller.
|
||||
* @param controller The controller to turn off. Defaults to 0.
|
||||
*/
|
||||
void setLedOff(uint8_t controller = 0) {
|
||||
setLedRaw(false, controller);
|
||||
};
|
||||
|
||||
|
||||
/** Turn all LEDs on. */
|
||||
void setLedOnAll() {
|
||||
for (uint8_t i = 1; i < 4; i++) // Skip first as it will be set in setLedRaw
|
||||
ledState[i] = true; // Just an easy way to set all four off at the same time
|
||||
setLedRaw(true); // Turn the LED on, on all four controllers
|
||||
};
|
||||
|
||||
/**
|
||||
* Turn the LED on on a specific controller.
|
||||
* @param controller The controller to turn off. Defaults to 0.
|
||||
*/
|
||||
void setLedOn(uint8_t controller = 0) {
|
||||
setLedRaw(true, controller);
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggle the LED on a specific controller.
|
||||
* @param controller The controller to turn off. Defaults to 0.
|
||||
*/
|
||||
void setLedToggle(uint8_t controller = 0) {
|
||||
setLedRaw(!ledState[controller], controller);
|
||||
};
|
||||
/**@}*/
|
||||
|
||||
protected:
|
||||
/** @name HIDUniversal implementation */
|
||||
/**
|
||||
* Used to parse USB HID data.
|
||||
* @param hid Pointer to the HID class.
|
||||
* @param is_rpt_id Only used for Hubs.
|
||||
* @param len The length of the incoming data.
|
||||
* @param buf Pointer to the data buffer.
|
||||
*/
|
||||
virtual void ParseHIDData(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
|
||||
|
||||
/**
|
||||
* Called when a device is successfully initialized.
|
||||
* Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
|
||||
* This is useful for instance if you want to set the LEDs in a specific way.
|
||||
*/
|
||||
virtual uint8_t OnInitSuccessful();
|
||||
/**@}*/
|
||||
|
||||
/** Used to reset the different buffers to their default values */
|
||||
void Reset() {
|
||||
psbuzzButtons.val = 0;
|
||||
oldButtonState.val = 0;
|
||||
buttonClickState.val = 0;
|
||||
for (uint8_t i = 0; i < sizeof(ledState); i++)
|
||||
ledState[i] = 0;
|
||||
};
|
||||
|
||||
/** @name USBDeviceConfig implementation */
|
||||
/**
|
||||
* Used by the USB core to check what this driver support.
|
||||
* @param vid The device's VID.
|
||||
* @param pid The device's PID.
|
||||
* @return Returns true if the device's VID and PID matches this driver.
|
||||
*/
|
||||
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) {
|
||||
return (vid == PSBUZZ_VID && pid == PSBUZZ_PID);
|
||||
};
|
||||
/**@}*/
|
||||
|
||||
private:
|
||||
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
||||
|
||||
void PSBuzz_Command(uint8_t *data, uint16_t nbytes);
|
||||
|
||||
PSBUZZButtons psbuzzButtons, oldButtonState, buttonClickState;
|
||||
bool ledState[4];
|
||||
};
|
||||
#endif
|
13
README.md
13
README.md
|
@ -22,7 +22,7 @@ For more information about the hardware see the [Hardware Manual](http://www.cir
|
|||
* __Alexei Glushchenko, Circuits@Home__ - <alex-gl@mail.ru>
|
||||
* Developers of the USB Core, HID, FTDI, ADK, ACM, and PL2303 libraries
|
||||
* __Kristian Lauszus, TKJ Electronics__ - <kristianl@tkjelectronics.com>
|
||||
* 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
|
||||
* 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
|
||||
* __Andrew Kroll__ - <xxxajk@gmail.com>
|
||||
* Major contributor to mass storage code
|
||||
|
||||
|
@ -240,6 +240,17 @@ All the information about the Wii controllers are from these sites:
|
|||
* <http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Wii_Motion_Plus>
|
||||
* The old library created by _Tomoyuki Tanaka_: <https://github.com/moyuchin/WiiRemote_on_Arduino> also helped a lot.
|
||||
|
||||
### [PS Buzz Library](PSBuzz.cpp)
|
||||
|
||||
This library implements support for the Playstation Buzz controllers via USB.
|
||||
|
||||
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.
|
||||
|
||||
More information about the controller can be found at the following sites:
|
||||
|
||||
* http://www.developerfusion.com/article/84338/making-usb-c-friendly/
|
||||
* https://github.com/torvalds/linux/blob/master/drivers/hid/hid-sony.c
|
||||
|
||||
# FAQ
|
||||
|
||||
> When I plug my device into the USB connector nothing happens?
|
||||
|
|
|
@ -137,6 +137,14 @@ enum ButtonEnum {
|
|||
BLACK = 8, // Available on the original Xbox controller
|
||||
WHITE = 9, // Available on the original Xbox controller
|
||||
/**@}*/
|
||||
|
||||
/** PS Buzz controllers */
|
||||
RED = 0,
|
||||
YELLOW = 1,
|
||||
GREEN = 2,
|
||||
ORANGE = 3,
|
||||
BLUE = 4,
|
||||
/**@}*/
|
||||
};
|
||||
|
||||
/** Joysticks on the PS3 and Xbox controllers. */
|
||||
|
|
46
examples/PSBuzz/PSBuzz.ino
Normal file
46
examples/PSBuzz/PSBuzz.ino
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Example sketch for the Playstation Buzz library - developed by Kristian Lauszus
|
||||
For more information visit my blog: http://blog.tkjelectronics.dk/ or
|
||||
send me an e-mail: kristianl@tkjelectronics.com
|
||||
*/
|
||||
|
||||
#include <PSBuzz.h>
|
||||
|
||||
// Satisfy IDE, which only needs to see the include statment in the ino.
|
||||
#ifdef dobogusinclude
|
||||
#include <spi4teensy3.h>
|
||||
#endif
|
||||
|
||||
USB Usb;
|
||||
PSBuzz Buzz(&Usb);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
|
||||
if (Usb.Init() == -1) {
|
||||
Serial.print(F("\r\nOSC did not start"));
|
||||
while (1); // Halt
|
||||
}
|
||||
Serial.println(F("\r\nPS Buzz Library Started"));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Usb.Task();
|
||||
|
||||
if (Buzz.connected()) {
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
if (Buzz.getButtonClick(RED, i)) {
|
||||
Buzz.setLedToggle(i); // Toggle the LED
|
||||
Serial.println(F("RED"));
|
||||
}
|
||||
if (Buzz.getButtonClick(YELLOW, i))
|
||||
Serial.println(F("YELLOW"));
|
||||
if (Buzz.getButtonClick(GREEN, i))
|
||||
Serial.println(F("GREEN"));
|
||||
if (Buzz.getButtonClick(ORANGE, i))
|
||||
Serial.println(F("ORANGE"));
|
||||
if (Buzz.getButtonClick(BLUE, i))
|
||||
Serial.println(F("BLUE"));
|
||||
}
|
||||
}
|
||||
}
|
31
keywords.txt
31
keywords.txt
|
@ -318,7 +318,7 @@ getIRy4 KEYWORD2
|
|||
getIRs4 KEYWORD2
|
||||
|
||||
####################################################
|
||||
# Syntax Coloring Map For RFCOMM/SPP Library
|
||||
# Syntax Coloring Map For BTHID Library
|
||||
####################################################
|
||||
|
||||
####################################################
|
||||
|
@ -331,4 +331,31 @@ BTHID KEYWORD1
|
|||
# Methods and Functions (KEYWORD2)
|
||||
####################################################
|
||||
SetReportParser KEYWORD2
|
||||
setProtocolMode KEYWORD2
|
||||
setProtocolMode KEYWORD2
|
||||
|
||||
####################################################
|
||||
# Syntax Coloring Map For PS Buzz Library
|
||||
####################################################
|
||||
|
||||
####################################################
|
||||
# Datatypes (KEYWORD1)
|
||||
####################################################
|
||||
|
||||
PSBuzz KEYWORD1
|
||||
|
||||
####################################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
####################################################
|
||||
|
||||
setLedOnAll KEYWORD2
|
||||
setLedOffAll KEYWORD2
|
||||
|
||||
####################################################
|
||||
# Constants and enums (LITERAL1)
|
||||
####################################################
|
||||
|
||||
RED LITERAL1
|
||||
YELLOW LITERAL1
|
||||
GREEN LITERAL1
|
||||
ORANGE LITERAL1
|
||||
BLUE LITERAL1
|
Loading…
Reference in a new issue