mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Minor revision
This commit is contained in:
parent
a90c2ab4da
commit
da6eb99a2f
3 changed files with 217 additions and 183 deletions
202
PS3BT.cpp
202
PS3BT.cpp
|
@ -37,7 +37,7 @@ prog_char OUTPUT_REPORT_BUFFER[] PROGMEM =
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
PS3BT::PS3BT(USB *p):
|
||||
PS3BT::PS3BT(USB *p, uint8_t btadr5 = 0, uint8_t btadr4 = 0, uint8_t btadr3 = 0, uint8_t btadr2 = 0, uint8_t btadr1 = 0, uint8_t btadr0 = 0):
|
||||
pUsb(p), // pointer to USB class instance - mandatory
|
||||
bAddress(0), // device address - mandatory
|
||||
bNumEP(1), // if config descriptor needs to be parsed
|
||||
|
@ -55,12 +55,31 @@ PS3BT::PS3BT(USB *p):
|
|||
if (pUsb) // register in USB subsystem
|
||||
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
|
||||
|
||||
my_bdaddr[5] = 0x00; // Change to your dongle's Bluetooth address instead
|
||||
my_bdaddr[4] = 0x1F;
|
||||
my_bdaddr[3] = 0x81;
|
||||
my_bdaddr[2] = 0x00;
|
||||
my_bdaddr[1] = 0x08;
|
||||
my_bdaddr[0] = 0x30;
|
||||
my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
|
||||
my_bdaddr[4] = btadr4;
|
||||
my_bdaddr[3] = btadr3;
|
||||
my_bdaddr[2] = btadr2;
|
||||
my_bdaddr[1] = btadr1;
|
||||
my_bdaddr[0] = btadr0;
|
||||
}
|
||||
|
||||
PS3BT::PS3BT(USB *p):
|
||||
pUsb(p), // pointer to USB class instance - mandatory
|
||||
bAddress(0), // device address - mandatory
|
||||
bNumEP(1), // if config descriptor needs to be parsed
|
||||
qNextPollTime(0),
|
||||
bPollEnable(false) // don't start polling before dongle is connected
|
||||
{
|
||||
for(uint8_t i=0; i<PS3_MAX_ENDPOINTS; i++)
|
||||
{
|
||||
epInfo[i].epAddr = 0;
|
||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||
epInfo[i].epAttribs = 0;
|
||||
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
||||
}
|
||||
|
||||
if (pUsb) // register in USB subsystem
|
||||
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
|
||||
}
|
||||
|
||||
uint8_t PS3BT::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
||||
|
@ -167,73 +186,7 @@ uint8_t PS3BT::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
|
||||
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
|
||||
|
||||
if((VID == CSR_VID || VID == ISSC_VID) && (PID == CSR_PID || PID == ISSC_PID))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nBluetooth Dongle Connected"));
|
||||
#endif
|
||||
|
||||
//Needed for PS3 Dualshock Controller commands to work via bluetooth
|
||||
for (uint8_t i = 0; i < OUTPUT_REPORT_BUFFER_SIZE; i++)
|
||||
HIDBuffer[i + 2] = pgm_read_byte(&OUTPUT_REPORT_BUFFER[i]);//First two bytes reserved for report type and ID
|
||||
|
||||
HIDBuffer[0] = 0x52;// HID BT Set_report (0x50) | Report Type (Output 0x02)
|
||||
HIDBuffer[1] = 0x01;// Report ID
|
||||
|
||||
//Needed for PS3 Move Controller commands to work via bluetooth
|
||||
HIDMoveBuffer[0] = 0xA2;// HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
||||
HIDMoveBuffer[1] = 0x02;// Report ID
|
||||
|
||||
/* Set device cid for the control and intterrupt channelse - LSB */
|
||||
control_dcid[0] = 0x40;//0x0040
|
||||
control_dcid[1] = 0x00;
|
||||
interrupt_dcid[0] = 0x41;//0x0041
|
||||
interrupt_dcid[1] = 0x00;
|
||||
|
||||
//check if attached device is a Bluetooth dongle and fill endpoint data structure
|
||||
//first interface in the configuration must have Bluetooth assigned Class/Subclass/Protocol
|
||||
//and 3 endpoints - interrupt-IN, bulk-IN, bulk-OUT,
|
||||
//not necessarily in this order
|
||||
for (uint8_t i=0; i<num_of_conf; i++) {
|
||||
ConfigDescParser<USB_CLASS_WIRELESS_CTRL, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this);
|
||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||
if(rcode)
|
||||
goto FailGetConfDescr;
|
||||
if( bNumEP > 3 ) //all endpoints extracted
|
||||
break;
|
||||
} // for (uint8_t i=0; i<num_of_conf; i++...
|
||||
|
||||
if (bNumEP < PS3_MAX_ENDPOINTS) {
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nBluetooth dongle is not supported"));
|
||||
#endif
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
// Assign epInfo to epinfo pointer - this time all 3 endpoins
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
|
||||
if( rcode )
|
||||
goto FailSetDevTblEntry;
|
||||
|
||||
delay(200); // Give time for address change
|
||||
|
||||
// Set Configuration Value
|
||||
rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, bConfNum);
|
||||
if( rcode )
|
||||
goto FailSetConf;
|
||||
|
||||
hci_state = HCI_INIT_STATE;
|
||||
hci_counter = 0;
|
||||
l2cap_state = L2CAP_EV_WAIT;
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nCSR Initialized"));
|
||||
#endif
|
||||
|
||||
watingForConnection = false;
|
||||
bPollEnable = true;
|
||||
}
|
||||
else if((VID == PS3_VID || VID == PS3NAVIGATION_VID || VID == PS3MOVE_VID) && (PID == PS3_PID || PID == PS3NAVIGATION_PID || PID == PS3MOVE_PID))
|
||||
{
|
||||
if(VID == PS3_VID && (PID == PS3_PID || PID == PS3NAVIGATION_PID || PID == PS3MOVE_PID)) {
|
||||
/* The application will work in reduced host mode, so we can save program and data
|
||||
memory space. After verifying the PID and VID we will use known values for the
|
||||
configuration values for device, interface, endpoints and HID for the PS3 Controllers */
|
||||
|
@ -262,9 +215,9 @@ uint8_t PS3BT::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
if( rcode )
|
||||
goto FailSetConf;
|
||||
|
||||
if((VID == PS3_VID || VID == PS3NAVIGATION_VID) && (PID == PS3_PID || PID == PS3NAVIGATION_PID))
|
||||
if(PID == PS3_PID || PID == PS3NAVIGATION_PID)
|
||||
{
|
||||
if(VID == PS3_VID && PID == PS3_PID) {
|
||||
if(PID == PS3_PID) {
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nDualshock 3 Controller Connected"));
|
||||
#endif
|
||||
|
@ -285,8 +238,74 @@ uint8_t PS3BT::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//check if attached device is a Bluetooth dongle and fill endpoint data structure
|
||||
//first interface in the configuration must have Bluetooth assigned Class/Subclass/Protocol
|
||||
//and 3 endpoints - interrupt-IN, bulk-IN, bulk-OUT,
|
||||
//not necessarily in this order
|
||||
for (uint8_t i=0; i<num_of_conf; i++) {
|
||||
ConfigDescParser<USB_CLASS_WIRELESS_CTRL, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this);
|
||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||
if(rcode)
|
||||
goto FailGetConfDescr;
|
||||
if(bNumEP > 3) //all endpoints extracted
|
||||
break;
|
||||
} // for (uint8_t i=0; i<num_of_conf; i++...
|
||||
|
||||
if (bNumEP < PS3_MAX_ENDPOINTS)
|
||||
goto FailUnknownDevice;
|
||||
|
||||
// Assign epInfo to epinfo pointer - this time all 3 endpoins
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
|
||||
if(rcode)
|
||||
goto FailSetDevTblEntry;
|
||||
|
||||
delay(200); // Give time for address change
|
||||
|
||||
// Set Configuration Value
|
||||
rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, bConfNum);
|
||||
if(rcode)
|
||||
goto FailSetConf;
|
||||
|
||||
if(VID == CSR_VID && PID == CSR_PID) {
|
||||
if((uint16_t)((USB_DEVICE_DESCRIPTOR*)buf)->bcdDevice < 0x1915) { // I don't know the exact number, plese let me know if you do
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour Revision ID is: 0x"));
|
||||
PrintHex<uint16_t>((uint16_t)((USB_DEVICE_DESCRIPTOR*)buf)->bcdDevice);
|
||||
Notify(PSTR("\r\nBut should be at least 0x1915\r\nThis usually means that it doesn't support Bluetooth Version 2.0+EDR"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//Needed for PS3 Dualshock Controller commands to work via bluetooth
|
||||
for (uint8_t i = 0; i < OUTPUT_REPORT_BUFFER_SIZE; i++)
|
||||
HIDBuffer[i + 2] = pgm_read_byte(&OUTPUT_REPORT_BUFFER[i]);//First two bytes reserved for report type and ID
|
||||
|
||||
HIDBuffer[0] = 0x52;// HID BT Set_report (0x50) | Report Type (Output 0x02)
|
||||
HIDBuffer[1] = 0x01;// Report ID
|
||||
|
||||
//Needed for PS3 Move Controller commands to work via bluetooth
|
||||
HIDMoveBuffer[0] = 0xA2;// HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
||||
HIDMoveBuffer[1] = 0x02;// Report ID
|
||||
|
||||
/* Set device cid for the control and intterrupt channelse - LSB */
|
||||
control_dcid[0] = 0x40;//0x0040
|
||||
control_dcid[1] = 0x00;
|
||||
interrupt_dcid[0] = 0x41;//0x0041
|
||||
interrupt_dcid[1] = 0x00;
|
||||
|
||||
hci_num_reset_loops = 10; // only loop 10 times before trying to send the hci reset command
|
||||
|
||||
hci_state = HCI_INIT_STATE;
|
||||
hci_counter = 0;
|
||||
l2cap_state = L2CAP_EV_WAIT;
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nBluetooth Dongle Initialized"));
|
||||
#endif
|
||||
|
||||
watingForConnection = false;
|
||||
bPollEnable = true;
|
||||
}
|
||||
return 0; //successful configuration
|
||||
|
||||
/* diagnostic messages */
|
||||
|
@ -511,11 +530,11 @@ double PS3BT::getAngle(Angle a, boolean resolution) // Boolean indicate if 360-d
|
|||
{
|
||||
double accXin;
|
||||
double accXval;
|
||||
double Pitch;
|
||||
double angleX;
|
||||
|
||||
double accYin;
|
||||
double accYval;
|
||||
double Roll;
|
||||
double angleY;
|
||||
|
||||
double accZin;
|
||||
double accZval;
|
||||
|
@ -543,36 +562,36 @@ double PS3BT::getAngle(Angle a, boolean resolution) // Boolean indicate if 360-d
|
|||
{
|
||||
//the result will come out as radians, so it is multiplied by 180/pi, to convert to degrees
|
||||
//In the end it is minus by 90, so its 0 degrees when in horizontal postion
|
||||
Pitch = acos(accXval / R) * 180 / PI - 90;
|
||||
angleX = acos(accXval / R) * 180 / PI - 90;
|
||||
if(resolution)
|
||||
{
|
||||
if (accZval < 0)//Convert to 360 degrees resolution - set resolution false if you need both pitch and roll
|
||||
{
|
||||
if (Pitch < 0)
|
||||
Pitch = -180 - Pitch;
|
||||
if (angleX < 0)
|
||||
angleX = -180 - angleX;
|
||||
else
|
||||
Pitch = 180 - Pitch;
|
||||
angleX = 180 - angleX;
|
||||
}
|
||||
}
|
||||
return Pitch;
|
||||
return angleX;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//the result will come out as radians, so it is multiplied by 180/pi, to convert to degrees
|
||||
//In the end it is minus by 90, so its 0 degrees when in horizontal postion
|
||||
Roll = acos(accYval / R) * 180 / PI - 90;
|
||||
angleY = acos(accYval / R) * 180 / PI - 90;
|
||||
if(resolution)
|
||||
{
|
||||
if (accZval < 0)//Convert to 360 degrees resolution - set resolution false if you need both pitch and roll
|
||||
{
|
||||
if (Roll < 0)
|
||||
Roll = -180 - Roll;
|
||||
if (angleY < 0)
|
||||
angleY = -180 - angleY;
|
||||
else
|
||||
Roll = 180 - Roll;
|
||||
angleY = 180 - angleY;
|
||||
}
|
||||
}
|
||||
return Roll;
|
||||
return angleY;
|
||||
}
|
||||
}
|
||||
bool PS3BT::getStatus(Status c)
|
||||
|
@ -764,7 +783,7 @@ void PS3BT::HCI_task()
|
|||
switch (hci_state){
|
||||
case HCI_INIT_STATE:
|
||||
hci_counter++;
|
||||
if (hci_counter > 1000) // wait until we have looped 1000 times to clear any old events
|
||||
if (hci_counter > hci_num_reset_loops) // wait until we have looped x times to clear any old events
|
||||
{
|
||||
hci_reset();
|
||||
hci_state = HCI_RESET_STATE;
|
||||
|
@ -782,8 +801,11 @@ void PS3BT::HCI_task()
|
|||
hci_state = HCI_BDADDR_STATE;
|
||||
hci_read_bdaddr();
|
||||
}
|
||||
else if (hci_counter > 1000)
|
||||
else if (hci_counter > hci_num_reset_loops)
|
||||
{
|
||||
hci_num_reset_loops *= 10;
|
||||
if(hci_num_reset_loops > 2000)
|
||||
hci_num_reset_loops = 2000;
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nNo response to HCI Reset"));
|
||||
#endif
|
||||
|
|
10
PS3BT.h
10
PS3BT.h
|
@ -45,13 +45,9 @@
|
|||
//PID and VID of the different devices
|
||||
#define CSR_VID 0x0A12 // Cambridge Silicon Radio Ltd.
|
||||
#define CSR_PID 0x0001 // Bluetooth HCI Device
|
||||
#define ISSC_VID 0x1131 // Integrated System Solution Corp.
|
||||
#define ISSC_PID 0x1004 // Bluetooth Device
|
||||
#define PS3_VID 0x054C // Sony Corporation
|
||||
#define PS3_PID 0x0268 // PS3 Controller DualShock 3
|
||||
#define PS3NAVIGATION_VID 0x054C // Sony Corporation
|
||||
#define PS3NAVIGATION_PID 0x042F // Navigation controller
|
||||
#define PS3MOVE_VID 0x054C // Sony Corporation
|
||||
#define PS3MOVE_PID 0x03D5 // Motion controller
|
||||
|
||||
#define HID_BUFFERSIZE 50 // size of the buffer for the Playstation Motion Controller
|
||||
|
@ -157,10 +153,12 @@
|
|||
#define PENDING 0x01
|
||||
#define SUCCESSFUL 0x00
|
||||
|
||||
#define PS3_MAX_ENDPOINTS 4
|
||||
// Used to determine if it is a Bluetooth dongle
|
||||
#define WI_SUBCLASS_RF 0x01
|
||||
#define WI_PROTOCOL_BT 0x01
|
||||
|
||||
#define PS3_MAX_ENDPOINTS 4
|
||||
|
||||
enum LED
|
||||
{
|
||||
LED1 = 0x01,
|
||||
|
@ -319,6 +317,7 @@ enum Rumble
|
|||
class PS3BT : public USBDeviceConfig, public UsbConfigXtracter
|
||||
{
|
||||
public:
|
||||
PS3BT(USB *pUsb, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0);
|
||||
PS3BT(USB *pUsb);
|
||||
|
||||
// USBDeviceConfig implementation
|
||||
|
@ -395,6 +394,7 @@ private:
|
|||
/* variables used by high level HCI task */
|
||||
uint8_t hci_state; //current state of bluetooth hci connection
|
||||
uint16_t hci_counter; // counter used for bluetooth hci reset loops
|
||||
uint8_t hci_num_reset_loops; // this value indicate how many times it should read before trying to reset
|
||||
uint16_t hci_event_flag;// hci flags of received bluetooth events
|
||||
|
||||
/* variables used by high level L2CAP task */
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
|
||||
#include <PS3BT.h>
|
||||
USB Usb;
|
||||
PS3BT BT(&Usb);
|
||||
/* You can create the instance of the class in two ways */
|
||||
PS3BT BT(&Usb); // This will just create the instance
|
||||
//PS3BT BT(&Usb,0x00,0x15,0x83,0x3D,0x0A,0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch
|
||||
|
||||
boolean printTemperature;
|
||||
boolean printAngle;
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
@ -28,19 +31,19 @@ void loop()
|
|||
if(BT.getAnalogHat(LeftHatX) > 137 || BT.getAnalogHat(LeftHatX) < 117 || BT.getAnalogHat(LeftHatY) > 137 || BT.getAnalogHat(LeftHatY) < 117 || BT.getAnalogHat(RightHatX) > 137 || BT.getAnalogHat(RightHatX) < 117 || BT.getAnalogHat(RightHatY) > 137 || BT.getAnalogHat(RightHatY) < 117) {
|
||||
if(BT.getAnalogHat(LeftHatX) > 137 || BT.getAnalogHat(LeftHatX) < 117) {
|
||||
Serial.print(F("LeftHatX: "));
|
||||
Serial.print(BT.getAnalogHat(LeftHatX), DEC);
|
||||
Serial.print(BT.getAnalogHat(LeftHatX));
|
||||
Serial.print("\t");
|
||||
} if(BT.getAnalogHat(LeftHatY) > 137 || BT.getAnalogHat(LeftHatY) < 117) {
|
||||
Serial.print(F("LeftHatY: "));
|
||||
Serial.print(BT.getAnalogHat(LeftHatY), DEC);
|
||||
Serial.print(BT.getAnalogHat(LeftHatY));
|
||||
Serial.print("\t");
|
||||
} if(BT.getAnalogHat(RightHatX) > 137 || BT.getAnalogHat(RightHatX) < 117) {
|
||||
Serial.print(F("RightHatX: "));
|
||||
Serial.print(BT.getAnalogHat(RightHatX), DEC);
|
||||
Serial.print(BT.getAnalogHat(RightHatX));
|
||||
Serial.print("\t");
|
||||
} if(BT.getAnalogHat(RightHatY) > 137 || BT.getAnalogHat(RightHatY) < 117) {
|
||||
Serial.print(F("RightHatY: "));
|
||||
Serial.print(BT.getAnalogHat(RightHatY), DEC);
|
||||
Serial.print(BT.getAnalogHat(RightHatY));
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
@ -49,11 +52,11 @@ void loop()
|
|||
if(BT.getAnalogButton(L2_ANALOG) > 0 || BT.getAnalogButton(R2_ANALOG) > 0) {
|
||||
if(BT.getAnalogButton(L2_ANALOG) > 0) {
|
||||
Serial.print(F("L2: "));
|
||||
Serial.print(BT.getAnalogButton(L2_ANALOG), DEC);
|
||||
Serial.print(BT.getAnalogButton(L2_ANALOG));
|
||||
Serial.print("\t");
|
||||
} if(BT.getAnalogButton(R2_ANALOG) > 0) {
|
||||
Serial.print(F("R2: "));
|
||||
Serial.print(BT.getAnalogButton(R2_ANALOG), DEC);
|
||||
Serial.print(BT.getAnalogButton(R2_ANALOG));
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
@ -109,18 +112,27 @@ void loop()
|
|||
if(BT.getButton(SELECT)) {
|
||||
Serial.print(F(" - Select - "));
|
||||
Serial.print(BT.getStatusString());
|
||||
} if(BT.getButton(START))
|
||||
} if(BT.getButton(START)) {
|
||||
Serial.print(F(" - Start"));
|
||||
|
||||
printAngle = !printAngle;
|
||||
while(BT.getButton(START))
|
||||
Usb.Task();
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
}
|
||||
if(printAngle) {
|
||||
Serial.print(F("Pitch: "));
|
||||
Serial.print(BT.getAngle(Pitch,false));
|
||||
Serial.print(F("\tRoll: "));
|
||||
Serial.println(BT.getAngle(Roll,false));
|
||||
}
|
||||
}
|
||||
else if(BT.PS3MoveBTConnected)
|
||||
{
|
||||
if(BT.getAnalogButton(T_MOVE_ANALOG) > 0) {
|
||||
Serial.print(F("T: "));
|
||||
Serial.println(BT.getAnalogButton(T_MOVE_ANALOG), DEC);
|
||||
Serial.println(BT.getAnalogButton(T_MOVE_ANALOG));
|
||||
} if(BT.buttonPressed) {
|
||||
Serial.print(F("PS3 Move Controller"));
|
||||
|
||||
|
@ -161,7 +173,7 @@ void loop()
|
|||
if(printTemperature) {
|
||||
String templow;
|
||||
String temphigh;
|
||||
String input = String(BT.getSensor(tempMove), DEC);
|
||||
String input = String(BT.getSensor(tempMove));
|
||||
|
||||
if (input.length() > 3) {
|
||||
temphigh = input.substring(0, 2);
|
||||
|
|
Loading…
Reference in a new issue