mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
manual merge
This commit is contained in:
commit
bc8000f782
27 changed files with 461 additions and 442 deletions
7
BTD.cpp
7
BTD.cpp
|
@ -380,6 +380,12 @@ uint8_t BTD::Poll() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void BTD::disconnect() {
|
||||
for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++)
|
||||
if(btService[i])
|
||||
btService[i]->disconnect();
|
||||
};
|
||||
|
||||
void BTD::HCI_event_task() {
|
||||
uint16_t length = BULK_MAXPKTSIZE; // Request more than 16 bytes anyway, the inTransfer routine will take care of this
|
||||
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_EVENT_PIPE ].epAddr, &length, hcibuf); // Input on endpoint 1
|
||||
|
@ -511,6 +517,7 @@ void BTD::HCI_event_task() {
|
|||
if(remote_name[i] == '\0') // End of string
|
||||
break;
|
||||
}
|
||||
// TODO: Altid sæt '\0' i remote name!
|
||||
hci_set_flag(HCI_FLAG_REMOTE_NAME_COMPLETE);
|
||||
}
|
||||
break;
|
||||
|
|
151
BTD.h
151
BTD.h
|
@ -19,6 +19,7 @@
|
|||
#define _btd_h_
|
||||
|
||||
#include "Usb.h"
|
||||
#include "Hid.h"
|
||||
|
||||
//PID and VID of the Sony PS3 devices
|
||||
#define PS3_VID 0x054C // Sony Corporation
|
||||
|
@ -34,9 +35,6 @@
|
|||
|
||||
// Used in control endpoint header for HCI Commands
|
||||
#define bmREQ_HCI_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
|
||||
// Used in control endpoint header for HID Commands
|
||||
#define bmREQ_HID_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||
#define HID_REQUEST_SET_REPORT 0x09
|
||||
|
||||
/* Bluetooth HCI states for hci_task() */
|
||||
#define HCI_INIT_STATE 0
|
||||
|
@ -60,15 +58,15 @@
|
|||
#define HCI_DISCONNECT_STATE 16
|
||||
|
||||
/* HCI event flags*/
|
||||
#define HCI_FLAG_CMD_COMPLETE 0x01
|
||||
#define HCI_FLAG_CONNECT_COMPLETE 0x02
|
||||
#define HCI_FLAG_DISCONNECT_COMPLETE 0x04
|
||||
#define HCI_FLAG_REMOTE_NAME_COMPLETE 0x08
|
||||
#define HCI_FLAG_INCOMING_REQUEST 0x10
|
||||
#define HCI_FLAG_READ_BDADDR 0x20
|
||||
#define HCI_FLAG_READ_VERSION 0x40
|
||||
#define HCI_FLAG_DEVICE_FOUND 0x80
|
||||
#define HCI_FLAG_CONNECT_EVENT 0x100
|
||||
#define HCI_FLAG_CMD_COMPLETE (1UL << 0)
|
||||
#define HCI_FLAG_CONNECT_COMPLETE (1UL << 1)
|
||||
#define HCI_FLAG_DISCONNECT_COMPLETE (1UL << 2)
|
||||
#define HCI_FLAG_REMOTE_NAME_COMPLETE (1UL << 3)
|
||||
#define HCI_FLAG_INCOMING_REQUEST (1UL << 4)
|
||||
#define HCI_FLAG_READ_BDADDR (1UL << 5)
|
||||
#define HCI_FLAG_READ_VERSION (1UL << 6)
|
||||
#define HCI_FLAG_DEVICE_FOUND (1UL << 7)
|
||||
#define HCI_FLAG_CONNECT_EVENT (1UL << 8)
|
||||
|
||||
/* Macros for HCI event flag tests */
|
||||
#define hci_check_flag(flag) (hci_event_flag & (flag))
|
||||
|
@ -133,28 +131,28 @@
|
|||
#define WII_INIT_MOTION_PLUS_STATE 21
|
||||
|
||||
/* L2CAP event flags for HID Control channel */
|
||||
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST 0x00000001
|
||||
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS 0x00000002
|
||||
#define L2CAP_FLAG_CONTROL_CONNECTED 0x00000004
|
||||
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE 0x00000008
|
||||
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST (1UL << 0)
|
||||
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS (1UL << 1)
|
||||
#define L2CAP_FLAG_CONTROL_CONNECTED (1UL << 2)
|
||||
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE (1UL << 3)
|
||||
|
||||
/* L2CAP event flags for HID Interrupt channel */
|
||||
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST 0x00000010
|
||||
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS 0x00000020
|
||||
#define L2CAP_FLAG_INTERRUPT_CONNECTED 0x00000040
|
||||
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE 0x00000080
|
||||
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST (1UL << 4)
|
||||
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS (1UL << 5)
|
||||
#define L2CAP_FLAG_INTERRUPT_CONNECTED (1UL << 6)
|
||||
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE (1UL << 7)
|
||||
|
||||
/* L2CAP event flags for SDP channel */
|
||||
#define L2CAP_FLAG_CONNECTION_SDP_REQUEST 0x00000100
|
||||
#define L2CAP_FLAG_CONFIG_SDP_SUCCESS 0x00000200
|
||||
#define L2CAP_FLAG_DISCONNECT_SDP_REQUEST 0x00000400
|
||||
#define L2CAP_FLAG_CONNECTION_SDP_REQUEST (1UL << 8)
|
||||
#define L2CAP_FLAG_CONFIG_SDP_SUCCESS (1UL << 9)
|
||||
#define L2CAP_FLAG_DISCONNECT_SDP_REQUEST (1UL << 10)
|
||||
|
||||
/* L2CAP event flags for RFCOMM channel */
|
||||
#define L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST 0x00000800
|
||||
#define L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS 0x00001000
|
||||
#define L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST 0x00002000
|
||||
#define L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST (1UL << 11)
|
||||
#define L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS (1UL << 12)
|
||||
#define L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST (1UL << 13)
|
||||
|
||||
#define L2CAP_FLAG_DISCONNECT_RESPONSE 0x00004000
|
||||
#define L2CAP_FLAG_DISCONNECT_RESPONSE (1UL << 14)
|
||||
|
||||
/* Macros for L2CAP event flag tests */
|
||||
#define l2cap_check_flag(flag) (l2cap_event_flag & (flag))
|
||||
|
@ -191,37 +189,7 @@
|
|||
|
||||
#define PAIR 1
|
||||
|
||||
/* acl_handle_ok or it's a new connection */
|
||||
#if 0
|
||||
#define UHS_ACL_HANDLE_OK(x, y) ((uint16_t)(x[0]) | (uint16_t)(x[1] << 8)) == (y | 0x2000U)
|
||||
#else
|
||||
/*
|
||||
* Better implementation.
|
||||
* o One place for this code, it is reused four times in the source.
|
||||
* Perhaps it is better as a function.
|
||||
* o This should be faster since the && operation can early exit, this means
|
||||
* the shift would only be performed if the first byte matches.
|
||||
* o Casting is eliminated.
|
||||
* o How does this compare in code size? No difference. It is a free optimization.
|
||||
*/
|
||||
#define UHS_ACL_HANDLE_OK(x, y) ((x[0] == (y & 0xff)) && (x[1] == ((y >> 8) | 0x20)))
|
||||
#endif
|
||||
|
||||
/** All Bluetooth services should inherit this class. */
|
||||
class BluetoothService {
|
||||
public:
|
||||
/**
|
||||
* Used to pass acldata to the Bluetooth service.
|
||||
* @param ACLData Pointer to the incoming acldata.
|
||||
*/
|
||||
virtual void ACLData(uint8_t* ACLData){};
|
||||
/** Used to run the different state machines in the Bluetooth service. */
|
||||
virtual void Run(){};
|
||||
/** Used to reset the Bluetooth service. */
|
||||
virtual void Reset(){};
|
||||
/** Used to disconnect both the L2CAP Channel and the HCI Connection for the Bluetooth service. */
|
||||
virtual void disconnect(){};
|
||||
};
|
||||
class BluetoothService;
|
||||
|
||||
/**
|
||||
* The Bluetooth Dongle class will take care of all the USB communication
|
||||
|
@ -319,25 +287,21 @@ public:
|
|||
/**@}*/
|
||||
|
||||
/** Disconnects both the L2CAP Channel and the HCI Connection for all Bluetooth services. */
|
||||
void disconnect() {
|
||||
for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++)
|
||||
if(btService[i])
|
||||
btService[i]->disconnect();
|
||||
};
|
||||
void disconnect();
|
||||
|
||||
/**
|
||||
* Register Bluetooth dongle members/services.
|
||||
* @param pService Pointer to BluetoothService class instance.
|
||||
* @return The service ID on success or -1 on fail.
|
||||
*/
|
||||
int8_t registerServiceClass(BluetoothService *pService) {
|
||||
int8_t registerBluetoothService(BluetoothService *pService) {
|
||||
for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++) {
|
||||
if(!btService[i]) {
|
||||
btService[i] = pService;
|
||||
return i; // Return ID
|
||||
}
|
||||
}
|
||||
return -1; // ErrorregisterServiceClass
|
||||
return -1; // Error registering BluetoothService
|
||||
};
|
||||
|
||||
/** @name HCI Commands */
|
||||
|
@ -594,4 +558,61 @@ private:
|
|||
void setBdaddr(uint8_t* BDADDR);
|
||||
void setMoveBdaddr(uint8_t* BDADDR);
|
||||
};
|
||||
|
||||
/** All Bluetooth services should inherit this class. */
|
||||
class BluetoothService {
|
||||
public:
|
||||
BluetoothService(BTD *p) : pBtd(p) {
|
||||
if(pBtd)
|
||||
pBtd->registerBluetoothService(this); // Register it as a Bluetooth service
|
||||
};
|
||||
/**
|
||||
* Used to pass acldata to the Bluetooth service.
|
||||
* @param ACLData Pointer to the incoming acldata.
|
||||
*/
|
||||
virtual void ACLData(uint8_t* ACLData) = 0;
|
||||
/** Used to run the different state machines in the Bluetooth service. */
|
||||
virtual void Run() = 0;
|
||||
/** Used to reset the Bluetooth service. */
|
||||
virtual void Reset() = 0;
|
||||
/** Used to disconnect both the L2CAP Channel and the HCI Connection for the Bluetooth service. */
|
||||
virtual void disconnect() = 0;
|
||||
|
||||
/**
|
||||
* Used to call your own function when the device is successfully initialized.
|
||||
* @param funcOnInit Function to call.
|
||||
*/
|
||||
void attachOnInit(void (*funcOnInit)(void)) {
|
||||
pFuncOnInit = funcOnInit; // TODO: This really belong in a class of it's own as it is repeated several times
|
||||
};
|
||||
|
||||
protected:
|
||||
/**
|
||||
* 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 void onInit() = 0;
|
||||
|
||||
/** Used to check if the incoming L2CAP data matches the HCI Handle */
|
||||
bool checkHciHandle(uint8_t *buf, uint16_t handle) {
|
||||
return (buf[0] == (handle & 0xFF)) && (buf[1] == ((handle >> 8) | 0x20));
|
||||
}
|
||||
|
||||
/** Pointer to function called in onInit(). */
|
||||
void (*pFuncOnInit)(void);
|
||||
|
||||
/** Pointer to BTD instance. */
|
||||
BTD *pBtd;
|
||||
|
||||
/** The HCI Handle for the connection. */
|
||||
uint16_t hci_handle;
|
||||
|
||||
/** L2CAP flags of received Bluetooth events. */
|
||||
uint32_t l2cap_event_flag;
|
||||
|
||||
/** Identifier for L2CAP commands. */
|
||||
uint8_t identifier;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,14 +21,11 @@
|
|||
//#define PRINTREPORT // Uncomment to print the report send by the HID device
|
||||
|
||||
BTHID::BTHID(BTD *p, bool pair, const char *pin) :
|
||||
pBtd(p), // pointer to USB class instance - mandatory
|
||||
BluetoothService(p), // Pointer to USB class instance - mandatory
|
||||
protocolMode(HID_BOOT_PROTOCOL) {
|
||||
for(uint8_t i = 0; i < NUM_PARSERS; i++)
|
||||
pRptParser[i] = NULL;
|
||||
|
||||
if(pBtd)
|
||||
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
||||
|
||||
pBtd->pairWithHIDDevice = pair;
|
||||
pBtd->btdPin = pin;
|
||||
|
||||
|
@ -68,8 +65,8 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
|
|||
}
|
||||
}
|
||||
}
|
||||
//if((l2capinbuf[0] | (uint16_t)l2capinbuf[1] << 8) == (hci_handle | 0x2000U)) { // acl_handle_ok or it's a new connection
|
||||
if(UHS_ACL_HANDLE_OK(l2capinbuf, hci_handle)) { // acl_handle_ok or it's a new connection
|
||||
|
||||
if(checkHciHandle(l2capinbuf, hci_handle)) { // acl_handle_ok
|
||||
if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // l2cap_control - Channel ID for ACL-U
|
||||
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||
#ifdef DEBUG_USB_HOST
|
||||
|
|
60
BTHID.h
60
BTHID.h
|
@ -37,15 +37,6 @@ public:
|
|||
BTHID(BTD *p, bool pair = false, const char *pin = "0000");
|
||||
|
||||
/** @name BluetoothService implementation */
|
||||
/**
|
||||
* Used to pass acldata to the services.
|
||||
* @param ACLData Incoming acldata.
|
||||
*/
|
||||
void ACLData(uint8_t* ACLData);
|
||||
/** Used to run part of the state machine. */
|
||||
void Run();
|
||||
/** Use this to reset the service. */
|
||||
void Reset();
|
||||
/** Used this to disconnect the devices. */
|
||||
void disconnect();
|
||||
/**@}*/
|
||||
|
@ -97,15 +88,29 @@ public:
|
|||
pBtd->pairWithHID();
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to call your own function when the device is successfully initialized.
|
||||
* @param funcOnInit Function to call.
|
||||
*/
|
||||
void attachOnInit(void (*funcOnInit)(void)) {
|
||||
pFuncOnInit = funcOnInit;
|
||||
};
|
||||
|
||||
protected:
|
||||
/** @name BluetoothService implementation */
|
||||
/**
|
||||
* Used to pass acldata to the services.
|
||||
* @param ACLData Incoming acldata.
|
||||
*/
|
||||
void ACLData(uint8_t* ACLData);
|
||||
/** Used to run part of the state machine. */
|
||||
void Run();
|
||||
/** Use this to reset the service. */
|
||||
void Reset();
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void onInit() {
|
||||
if(pFuncOnInit)
|
||||
pFuncOnInit(); // Call the user function
|
||||
OnInitBTHID();
|
||||
};
|
||||
/**@}*/
|
||||
|
||||
/** @name Overridable functions */
|
||||
/**
|
||||
* Used to parse Bluetooth HID data to any class that inherits this class.
|
||||
|
@ -125,14 +130,7 @@ protected:
|
|||
}
|
||||
/**@}*/
|
||||
|
||||
/** Pointer to BTD instance */
|
||||
BTD *pBtd;
|
||||
|
||||
/** HCI Handle for connection */
|
||||
uint16_t hci_handle;
|
||||
|
||||
/** L2CAP source CID for HID_Control */
|
||||
|
||||
uint8_t control_scid[2];
|
||||
|
||||
/** L2CAP source CID for HID_Interrupt */
|
||||
|
@ -145,18 +143,6 @@ private:
|
|||
void setProtocol();
|
||||
uint8_t protocolMode;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void onInit() {
|
||||
if(pFuncOnInit)
|
||||
pFuncOnInit(); // Call the user function
|
||||
OnInitBTHID();
|
||||
};
|
||||
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
||||
|
||||
void L2CAP_task(); // L2CAP state machine
|
||||
|
||||
bool activeConnection; // Used to indicate if it already has established a connection
|
||||
|
@ -164,8 +150,6 @@ private:
|
|||
/* Variables used for L2CAP communication */
|
||||
uint8_t control_dcid[2]; // L2CAP device CID for HID_Control - Always 0x0070
|
||||
uint8_t interrupt_dcid[2]; // L2CAP device CID for HID_Interrupt - Always 0x0071
|
||||
uint8_t identifier; // Identifier for connection
|
||||
uint8_t l2cap_state;
|
||||
uint32_t l2cap_event_flag; // l2cap flags of received Bluetooth events
|
||||
};
|
||||
#endif
|
||||
|
|
30
PS3BT.cpp
30
PS3BT.cpp
|
@ -21,11 +21,8 @@
|
|||
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
|
||||
|
||||
PS3BT::PS3BT(BTD *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0) :
|
||||
pBtd(p) // pointer to USB class instance - mandatory
|
||||
BluetoothService(p) // Pointer to USB class instance - mandatory
|
||||
{
|
||||
if(pBtd)
|
||||
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
||||
|
||||
pBtd->my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
|
||||
pBtd->my_bdaddr[4] = btadr4;
|
||||
pBtd->my_bdaddr[3] = btadr3;
|
||||
|
@ -232,8 +229,7 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
|||
activeConnection = true;
|
||||
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
||||
l2cap_state = L2CAP_WAIT;
|
||||
for(uint8_t i = 0; i < 30; i++)
|
||||
remote_name[i] = pBtd->remote_name[i]; // Store the remote name for the connection
|
||||
remote_name_first = pBtd->remote_name[0]; // Store the first letter in remote name for the connection
|
||||
#ifdef DEBUG_USB_HOST
|
||||
if(pBtd->hci_version < 3) { // Check the HCI Version of the Bluetooth dongle
|
||||
Notify(PSTR("\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour HCI Version is: "), 0x80);
|
||||
|
@ -244,10 +240,10 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
|||
}
|
||||
}
|
||||
}
|
||||
//if((ACLData[0] | (uint16_t)ACLData[1] << 8) == (hci_handle | 0x2000U)) { //acl_handle_ok
|
||||
if(UHS_ACL_HANDLE_OK(ACLData, hci_handle)) { //acl_handle_ok
|
||||
|
||||
if(checkHciHandle(ACLData, hci_handle)) { // acl_handle_ok
|
||||
memcpy(l2capinbuf, ACLData, BULK_MAXPKTSIZE);
|
||||
if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
|
||||
if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // l2cap_control - Channel ID for ACL-U
|
||||
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
||||
|
@ -419,7 +415,7 @@ void PS3BT::L2CAP_task() {
|
|||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nHID Interrupt Successfully Configured"), 0x80);
|
||||
#endif
|
||||
if(remote_name[0] == 'M') { // First letter in Motion Controller ('M')
|
||||
if(remote_name_first == 'M') { // First letter in Motion Controller ('M')
|
||||
memset(l2capinbuf, 0, BULK_MAXPKTSIZE); // Reset l2cap in buffer as it sometimes read it as a button has been pressed
|
||||
l2cap_state = TURN_ON_LED;
|
||||
} else
|
||||
|
@ -470,18 +466,18 @@ void PS3BT::Run() {
|
|||
|
||||
case TURN_ON_LED:
|
||||
if(millis() - timer > 1000) { // loop 1 second before sending the command
|
||||
if(remote_name[0] == 'P') { // First letter in PLAYSTATION(R)3 Controller ('P')
|
||||
if(remote_name_first == 'P') { // First letter in PLAYSTATION(R)3 Controller ('P')
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n"), 0x80);
|
||||
#endif
|
||||
PS3Connected = true;
|
||||
} else if(remote_name[0] == 'N') { // First letter in Navigation Controller ('N')
|
||||
} else if(remote_name_first == 'N') { // First letter in Navigation Controller ('N')
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nNavigation Controller Enabled\r\n"), 0x80);
|
||||
#endif
|
||||
PS3NavigationConnected = true;
|
||||
} else if(remote_name[0] == 'M') { // First letter in Motion Controller ('M')
|
||||
timerBulbRumble = millis();
|
||||
} else if(remote_name_first == 'M') { // First letter in Motion Controller ('M')
|
||||
timer = millis();
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nMotion Controller Enabled\r\n"), 0x80);
|
||||
#endif
|
||||
|
@ -497,10 +493,10 @@ void PS3BT::Run() {
|
|||
break;
|
||||
|
||||
case L2CAP_DONE:
|
||||
if(PS3MoveConnected) { // The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on
|
||||
if(millis() - timerBulbRumble > 4000) { // Send at least every 4th second
|
||||
if(PS3MoveConnected) { // The Bulb and rumble values, has to be send at approximately every 5th second for it to stay on
|
||||
if(millis() - timer > 4000) { // Send at least every 4th second
|
||||
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on
|
||||
timerBulbRumble = millis();
|
||||
timer = millis();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
45
PS3BT.h
45
PS3BT.h
|
@ -41,15 +41,6 @@ public:
|
|||
PS3BT(BTD *pBtd, uint8_t btadr5 = 0, uint8_t btadr4 = 0, uint8_t btadr3 = 0, uint8_t btadr2 = 0, uint8_t btadr1 = 0, uint8_t btadr0 = 0);
|
||||
|
||||
/** @name BluetoothService implementation */
|
||||
/**
|
||||
* Used to pass acldata to the services.
|
||||
* @param ACLData Incoming acldata.
|
||||
*/
|
||||
void ACLData(uint8_t* ACLData);
|
||||
/** Used to run part of the state machine. */
|
||||
void Run();
|
||||
/** Use this to reset the service. */
|
||||
void Reset();
|
||||
/** Used this to disconnect any of the controllers. */
|
||||
void disconnect();
|
||||
/**@}*/
|
||||
|
@ -183,14 +174,6 @@ public:
|
|||
uint32_t getLastMessageTime() {
|
||||
return lastMessageTime;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to call your own function when the controller is successfully initialized.
|
||||
* @param funcOnInit Function to call.
|
||||
*/
|
||||
void attachOnInit(void (*funcOnInit)(void)) {
|
||||
pFuncOnInit = funcOnInit;
|
||||
};
|
||||
/**@}*/
|
||||
|
||||
/** Variable used to indicate if the normal Playstation controller is successfully connected. */
|
||||
|
@ -200,39 +183,44 @@ public:
|
|||
/** Variable used to indicate if the Navigation controller is successfully connected. */
|
||||
bool PS3NavigationConnected;
|
||||
|
||||
private:
|
||||
/* Mandatory members */
|
||||
BTD *pBtd;
|
||||
|
||||
protected:
|
||||
/** @name BluetoothService implementation */
|
||||
/**
|
||||
* Used to pass acldata to the services.
|
||||
* @param ACLData Incoming acldata.
|
||||
*/
|
||||
void ACLData(uint8_t* ACLData);
|
||||
/** Used to run part of the state machine. */
|
||||
void Run();
|
||||
/** Use this to reset the service. */
|
||||
void Reset();
|
||||
/**
|
||||
* Called when the controller 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.
|
||||
*/
|
||||
void onInit();
|
||||
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
||||
/**@}*/
|
||||
|
||||
private:
|
||||
|
||||
void L2CAP_task(); // L2CAP state machine
|
||||
|
||||
/* Variables filled from HCI event management */
|
||||
int16_t hci_handle;
|
||||
uint8_t remote_name[30]; // First 30 chars of remote name
|
||||
char remote_name_first; // First letter in remote name
|
||||
bool activeConnection; // Used to indicate if it's already has established a connection
|
||||
|
||||
/* Variables used by high level L2CAP task */
|
||||
uint8_t l2cap_state;
|
||||
uint32_t l2cap_event_flag; // L2CAP flags of received Bluetooth events
|
||||
|
||||
uint32_t lastMessageTime; // Variable used to store the millis value of the last message.
|
||||
|
||||
unsigned long timer;
|
||||
|
||||
uint32_t ButtonState;
|
||||
uint32_t OldButtonState;
|
||||
uint32_t ButtonClickState;
|
||||
|
||||
uint32_t timer; // Timer used to limit time between messages and also used to continuously set PS3 Move controller Bulb and rumble values
|
||||
uint32_t timerHID; // Timer used see if there has to be a delay before a new HID command
|
||||
uint32_t timerBulbRumble; // used to continuously set PS3 Move controller Bulb and rumble values
|
||||
|
||||
uint8_t l2capinbuf[BULK_MAXPKTSIZE]; // General purpose buffer for L2CAP in data
|
||||
uint8_t HIDBuffer[HID_BUFFERSIZE]; // Used to store HID commands
|
||||
|
@ -243,7 +231,6 @@ private:
|
|||
uint8_t control_dcid[2]; // 0x0040
|
||||
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
|
||||
uint8_t interrupt_dcid[2]; // 0x0041
|
||||
uint8_t identifier; // Identifier for connection
|
||||
|
||||
/* HID Commands */
|
||||
void HID_Command(uint8_t* data, uint8_t nbytes);
|
||||
|
|
|
@ -152,13 +152,13 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
|||
|
||||
/* Initialize data structures for endpoints of device */
|
||||
epInfo[ PS3_OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint
|
||||
epInfo[ PS3_OUTPUT_PIPE ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ PS3_OUTPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ PS3_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ PS3_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ PS3_OUTPUT_PIPE ].bmSndToggle = 0;
|
||||
epInfo[ PS3_OUTPUT_PIPE ].bmRcvToggle = 0;
|
||||
epInfo[ PS3_INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint
|
||||
epInfo[ PS3_INPUT_PIPE ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ PS3_INPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ PS3_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ PS3_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ PS3_INPUT_PIPE ].bmSndToggle = 0;
|
||||
|
|
11
PS3USB.h
11
PS3USB.h
|
@ -19,14 +19,12 @@
|
|||
#define _ps3usb_h_
|
||||
|
||||
#include "Usb.h"
|
||||
#include "Hid.h"
|
||||
#include "PS3Enums.h"
|
||||
|
||||
/* PS3 data taken from descriptors */
|
||||
#define EP_MAXPKTSIZE 64 // max size for data via USB
|
||||
|
||||
/* Endpoint types */
|
||||
#define EP_INTERRUPT 0x03
|
||||
|
||||
/* Names we give to the 3 ps3 pipes - this is only used for setting the bluetooth address into the ps3 controllers */
|
||||
#define PS3_CONTROL_PIPE 0
|
||||
#define PS3_OUTPUT_PIPE 1
|
||||
|
@ -38,13 +36,6 @@
|
|||
#define PS3NAVIGATION_PID 0x042F // Navigation controller
|
||||
#define PS3MOVE_PID 0x03D5 // Motion controller
|
||||
|
||||
// Used in control endpoint header for HID Commands
|
||||
#define bmREQ_HID_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||
#define bmREQ_HID_IN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||
|
||||
#define HID_REQUEST_GET_REPORT 0x01
|
||||
#define HID_REQUEST_SET_REPORT 0x09
|
||||
|
||||
#define PS3_MAX_ENDPOINTS 3
|
||||
|
||||
/**
|
||||
|
|
10
PS4BT.h
10
PS4BT.h
|
@ -46,14 +46,6 @@ public:
|
|||
return BTHID::connected;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to call your own function when the device is successfully initialized.
|
||||
* @param funcOnInit Function to call.
|
||||
*/
|
||||
void attachOnInit(void (*funcOnInit)(void)) {
|
||||
pFuncOnInit = funcOnInit;
|
||||
};
|
||||
|
||||
protected:
|
||||
/** @name BTHID implementation */
|
||||
/**
|
||||
|
@ -125,7 +117,5 @@ private:
|
|||
void HID_Command(uint8_t *data, uint8_t nbytes) {
|
||||
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
|
||||
};
|
||||
|
||||
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -78,5 +78,10 @@ void PSBuzz::setLedRaw(bool value, uint8_t controller) {
|
|||
|
||||
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)
|
||||
<<<<<<< HEAD
|
||||
pUsb->ctrlReq(bAddress, epInfo[0].epAddr, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
|
||||
};
|
||||
=======
|
||||
pUsb->ctrlReq(bAddress, epInfo[0].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
|
||||
};
|
||||
>>>>>>> master
|
||||
|
|
26
README.md
26
README.md
|
@ -20,11 +20,17 @@ For more information about the hardware see the [Hardware Manual](http://www.cir
|
|||
|
||||
* __Oleg Mazurov, Circuits@Home__ - <mazurov@circuitsathome.com>
|
||||
* __Alexei Glushchenko, Circuits@Home__ - <alex-gl@mail.ru>
|
||||
* Developers of the USB Core, HID, FTDI, ADK, ACM, and PL2303 libraries
|
||||
* 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), [Xbox](#xbox-library), and [PSBuzz](#ps-buzz-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
|
||||
* Major contributor to mass storage code
|
||||
|
||||
# Donate
|
||||
|
||||
Help yourself by helping us support you! Many thousands of hours have been spent developing the USB Host Shield library. Since you find it useful, please consider donating via the button below. Donations will allow us to support you by ensuring hardware that you have can be acquired in order to add support for your microcontroller board.
|
||||
|
||||
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=donate@circuitsathome.com&lc=US&item_name=Donate%20to%20the%20USB%20Host%20Library%20project&no_note=0&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHostedGuest"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" alt="PayPal - The safer, easier way to pay online!" /></a>
|
||||
|
||||
# Table of Contents
|
||||
|
||||
|
@ -58,14 +64,14 @@ Now move the "USB\_Host\_Shield\_20" directory to the "libraries" directory.
|
|||
The final structure should look like this:
|
||||
|
||||
* Arduino/
|
||||
* libraries/
|
||||
* USB\_Host\_Shield\_20/
|
||||
* libraries/
|
||||
* USB\_Host\_Shield\_20/
|
||||
|
||||
Now quit the Arduino IDE and reopen it.
|
||||
|
||||
Now you should be able to go open all the examples codes by navigating to "File>Examples>USB\_Host\_Shield\_20" and then select the example you will like to open.
|
||||
|
||||
For more information visit the following site: <http://arduino.cc/en/Guide/Libraries>.
|
||||
For more information visit the following sites: <http://arduino.cc/en/Guide/Libraries> and <https://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use>.
|
||||
|
||||
# How to use the library
|
||||
|
||||
|
@ -89,15 +95,17 @@ Currently the following boards are supported by the library:
|
|||
* Arduino Due
|
||||
* If you are using the Arduino Due, then you must include the Arduino SPI library like so: ```#include <SPI.h>``` in your .ino file.
|
||||
* Teensy (Teensy++ 1.0, Teensy 2.0, Teensy++ 2.0, and Teensy 3.x)
|
||||
* Note if you are using the Teensy 3.x you should download this SPI library as well: <https://github.com/xxxajk/spi4teensy3>. You should then add ```#include <spi4teensy3.h>``` to your .ino file.
|
||||
* Note if you are using the Teensy 3.x you should download this SPI library as well: <https://github.com/xxxajk/spi4teensy3>. You should then add ```#include <spi4teensy3.h>``` to your .ino file.
|
||||
* Balanduino
|
||||
* Sanguino
|
||||
* Black Widdow
|
||||
* RedBearLab nRF51822
|
||||
* If you are using the RedBearLab nRF51822, then you must include the RedBearLab SPI library like so: ```#include <SPI.h>``` in your .ino file.
|
||||
|
||||
The following boards need to be activated manually in [settings.h](settings.h):
|
||||
|
||||
* Arduino Mega ADK
|
||||
* If you are using Arduino 1.5.5 or newer there is no need to activate the Arduino Mega ADK manually
|
||||
* If you are using Arduino 1.5.5 or newer there is no need to activate the Arduino Mega ADK manually
|
||||
* Black Widdow
|
||||
|
||||
Simply set the corresponding value to 1 instead of 0.
|
||||
|
@ -277,6 +285,8 @@ More information about the controller can be found at the following sites:
|
|||
|
||||
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.
|
||||
|
||||
Note this means that it uses pin 13, 12, 11 on an Arduino Uno, so these pins can not be used for anything else!
|
||||
|
||||
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.
|
||||
|
||||
After that you need modify the following entry in [UsbCore.h](UsbCore.h):
|
||||
|
|
31
SPP.cpp
31
SPP.cpp
|
@ -43,11 +43,8 @@ const uint8_t rfcomm_crc_table[256] PROGMEM = {/* reversed, 8-bit, poly=0x07 */
|
|||
};
|
||||
|
||||
SPP::SPP(BTD *p, const char* name, const char* pin) :
|
||||
pBtd(p) // Pointer to BTD class instance - mandatory
|
||||
BluetoothService(p) // Pointer to BTD class instance - mandatory
|
||||
{
|
||||
if(pBtd)
|
||||
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
||||
|
||||
pBtd->btdName = name;
|
||||
pBtd->btdPin = pin;
|
||||
|
||||
|
@ -69,6 +66,7 @@ void SPP::Reset() {
|
|||
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT;
|
||||
l2cap_event_flag = 0;
|
||||
sppIndex = 0;
|
||||
creditSent = false;
|
||||
}
|
||||
|
||||
void SPP::disconnect() {
|
||||
|
@ -97,9 +95,9 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
|||
}
|
||||
}
|
||||
}
|
||||
//if((l2capinbuf[0] | (uint16_t)l2capinbuf[1] << 8) == (hci_handle | 0x2000U)) { // acl_handle_ok
|
||||
if(UHS_ACL_HANDLE_OK(l2capinbuf, hci_handle)) { // acl_handle_ok
|
||||
if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
|
||||
|
||||
if(checkHciHandle(l2capinbuf, hci_handle)) { // acl_handle_ok
|
||||
if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // l2cap_control - Channel ID for ACL-U
|
||||
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
||||
|
@ -397,10 +395,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
|||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nRFCOMM Connection is now established\r\n"), 0x80);
|
||||
#endif
|
||||
waitForLastCommand = false;
|
||||
creditSent = false;
|
||||
connected = true; // The RFCOMM channel is now established
|
||||
sppIndex = 0;
|
||||
onInit();
|
||||
}
|
||||
#ifdef EXTRADEBUG
|
||||
else if(rfcommChannelType != RFCOMM_DISC) {
|
||||
|
@ -430,14 +425,20 @@ void SPP::Run() {
|
|||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"), 0x80);
|
||||
#endif
|
||||
creditSent = false;
|
||||
waitForLastCommand = false;
|
||||
connected = true; // The RFCOMM channel is now established
|
||||
sppIndex = 0;
|
||||
onInit();
|
||||
}
|
||||
send(); // Send all bytes currently in the buffer
|
||||
}
|
||||
|
||||
void SPP::onInit() {
|
||||
creditSent = false;
|
||||
waitForLastCommand = false;
|
||||
connected = true; // The RFCOMM channel is now established
|
||||
sppIndex = 0;
|
||||
if(pFuncOnInit)
|
||||
pFuncOnInit(); // Call the user function
|
||||
};
|
||||
|
||||
void SPP::SDP_task() {
|
||||
switch(l2cap_sdp_state) {
|
||||
case L2CAP_SDP_WAIT:
|
||||
|
|
49
SPP.h
49
SPP.h
|
@ -68,6 +68,11 @@ public:
|
|||
*/
|
||||
SPP(BTD *p, const char *name = "Arduino", const char *pin = "0000");
|
||||
|
||||
/** @name BluetoothService implementation */
|
||||
/** Used this to disconnect the virtual serial port. */
|
||||
void disconnect();
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* Used to provide Boolean tests for the class.
|
||||
* @return Return true if SPP communication is connected.
|
||||
|
@ -78,20 +83,6 @@ public:
|
|||
/** Variable used to indicate if the connection is established. */
|
||||
bool connected;
|
||||
|
||||
/** @name BluetoothService implementation */
|
||||
/**
|
||||
* Used to pass acldata to the services.
|
||||
* @param ACLData Incoming acldata.
|
||||
*/
|
||||
void ACLData(uint8_t* ACLData);
|
||||
/** Used to establish the connection automatically. */
|
||||
void Run();
|
||||
/** Use this to reset the service. */
|
||||
void Reset();
|
||||
/** Used this to disconnect the virtual serial port. */
|
||||
void disconnect();
|
||||
/**@}*/
|
||||
|
||||
/** @name Serial port profile (SPP) Print functions */
|
||||
/**
|
||||
* Get number of bytes waiting to be read.
|
||||
|
@ -100,7 +91,7 @@ public:
|
|||
int available(void);
|
||||
|
||||
/** Send out all bytes in the buffer. */
|
||||
virtual void flush(void) {
|
||||
void flush(void) {
|
||||
send();
|
||||
};
|
||||
/**
|
||||
|
@ -154,20 +145,33 @@ public:
|
|||
void send(void);
|
||||
/**@}*/
|
||||
|
||||
private:
|
||||
/* Bluetooth dongle library pointer */
|
||||
BTD *pBtd;
|
||||
protected:
|
||||
/** @name BluetoothService implementation */
|
||||
/**
|
||||
* Used to pass acldata to the services.
|
||||
* @param ACLData Incoming acldata.
|
||||
*/
|
||||
void ACLData(uint8_t* ACLData);
|
||||
/** Used to establish the connection automatically. */
|
||||
void Run();
|
||||
/** Use this to reset the service. */
|
||||
void Reset();
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void onInit();
|
||||
/**@}*/
|
||||
|
||||
private:
|
||||
/* Set true when a channel is created */
|
||||
bool SDPConnected;
|
||||
bool RFCOMMConnected;
|
||||
|
||||
uint16_t hci_handle; // The HCI Handle for the connection
|
||||
|
||||
/* Variables used by L2CAP state machines */
|
||||
uint8_t l2cap_sdp_state;
|
||||
uint8_t l2cap_rfcomm_state;
|
||||
uint32_t l2cap_event_flag; // l2cap flags of received Bluetooth events
|
||||
|
||||
uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
|
||||
uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
|
||||
|
@ -177,7 +181,6 @@ private:
|
|||
uint8_t sdp_dcid[2]; // 0x0050
|
||||
uint8_t rfcomm_scid[2]; // L2CAP source CID for RFCOMM
|
||||
uint8_t rfcomm_dcid[2]; // 0x0051
|
||||
uint8_t identifier; // Identifier for command
|
||||
|
||||
/* RFCOMM Variables */
|
||||
uint8_t rfcommChannel;
|
||||
|
@ -187,7 +190,7 @@ private:
|
|||
uint8_t rfcommChannelType;
|
||||
uint8_t rfcommPfBit;
|
||||
|
||||
unsigned long timer;
|
||||
uint32_t timer;
|
||||
bool waitForLastCommand;
|
||||
bool creditSent;
|
||||
|
||||
|
|
15
Wii.cpp
15
Wii.cpp
|
@ -83,19 +83,16 @@ const uint32_t WII_PROCONTROLLER_BUTTONS[] PROGMEM = {
|
|||
};
|
||||
|
||||
WII::WII(BTD *p, bool pair) :
|
||||
pBtd(p) // pointer to USB class instance - mandatory
|
||||
BluetoothService(p) // Pointer to USB class instance - mandatory
|
||||
{
|
||||
if(pBtd)
|
||||
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
||||
|
||||
pBtd->pairWithWii = pair;
|
||||
|
||||
HIDBuffer[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
||||
|
||||
/* Set device cid for the control and intterrupt channelse - LSB */
|
||||
control_dcid[0] = 0x60; //0x0060
|
||||
control_dcid[0] = 0x60; // 0x0060
|
||||
control_dcid[1] = 0x00;
|
||||
interrupt_dcid[0] = 0x61; //0x0061
|
||||
interrupt_dcid[0] = 0x61; // 0x0061
|
||||
interrupt_dcid[1] = 0x00;
|
||||
|
||||
Reset();
|
||||
|
@ -145,9 +142,9 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
|||
}
|
||||
}
|
||||
}
|
||||
//if((l2capinbuf[0] | (uint16_t)l2capinbuf[1] << 8) == (hci_handle | 0x2000U)) { // acl_handle_ok or it's a new connection
|
||||
if(UHS_ACL_HANDLE_OK(l2capinbuf, hci_handle)) { // acl_handle_ok or it's a new connection
|
||||
if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
|
||||
|
||||
if(checkHciHandle(l2capinbuf, hci_handle)) { // acl_handle_ok
|
||||
if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // l2cap_control - Channel ID for ACL-U
|
||||
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
||||
|
|
40
Wii.h
40
Wii.h
|
@ -55,15 +55,6 @@ public:
|
|||
WII(BTD *p, bool pair = false);
|
||||
|
||||
/** @name BluetoothService implementation */
|
||||
/**
|
||||
* Used to pass acldata to the services.
|
||||
* @param ACLData Incoming acldata.
|
||||
*/
|
||||
void ACLData(uint8_t* ACLData);
|
||||
/** Used to run part of the state machine. */
|
||||
void Run();
|
||||
/** Use this to reset the service. */
|
||||
void Reset();
|
||||
/** Used this to disconnect any of the controllers. */
|
||||
void disconnect();
|
||||
/**@}*/
|
||||
|
@ -189,14 +180,6 @@ public:
|
|||
uint8_t getWiiState() {
|
||||
return wiiState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to call your own function when the controller is successfully initialized.
|
||||
* @param funcOnInit Function to call.
|
||||
*/
|
||||
void attachOnInit(void (*funcOnInit)(void)) {
|
||||
pFuncOnInit = funcOnInit;
|
||||
};
|
||||
/**@}*/
|
||||
|
||||
/**@{*/
|
||||
|
@ -392,26 +375,34 @@ public:
|
|||
/**@}*/
|
||||
#endif
|
||||
|
||||
private:
|
||||
BTD *pBtd; // Pointer to BTD instance
|
||||
|
||||
protected:
|
||||
/** @name BluetoothService implementation */
|
||||
/**
|
||||
* Used to pass acldata to the services.
|
||||
* @param ACLData Incoming acldata.
|
||||
*/
|
||||
void ACLData(uint8_t* ACLData);
|
||||
/** Used to run part of the state machine. */
|
||||
void Run();
|
||||
/** Use this to reset the service. */
|
||||
void Reset();
|
||||
/**
|
||||
* Called when the controller 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.
|
||||
*/
|
||||
void onInit();
|
||||
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
||||
/**@}*/
|
||||
|
||||
private:
|
||||
|
||||
void L2CAP_task(); // L2CAP state machine
|
||||
|
||||
/* Variables filled from HCI event management */
|
||||
uint16_t hci_handle;
|
||||
bool activeConnection; // Used to indicate if it's already has established a connection
|
||||
|
||||
/* Variables used by high level L2CAP task */
|
||||
uint8_t l2cap_state;
|
||||
uint32_t l2cap_event_flag; // L2CAP flags of received Bluetooth events
|
||||
uint8_t wii_event_flag; // Used for Wii flags
|
||||
|
||||
uint32_t ButtonState;
|
||||
|
@ -432,7 +423,6 @@ private:
|
|||
uint8_t control_dcid[2]; // 0x0060
|
||||
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
|
||||
uint8_t interrupt_dcid[2]; // 0x0061
|
||||
uint8_t identifier; // Identifier for connection
|
||||
|
||||
/* HID Commands */
|
||||
void HID_Command(uint8_t* data, uint8_t nbytes);
|
||||
|
@ -457,7 +447,7 @@ private:
|
|||
|
||||
bool activateNunchuck;
|
||||
bool motionValuesReset; // This bool is true when the gyro values has been reset
|
||||
unsigned long timer;
|
||||
uint32_t timer;
|
||||
|
||||
uint8_t wiiState; // Stores the value in l2capinbuf[12] - (0x01: Battery is nearly empty), (0x02: An Extension Controller is connected), (0x04: Speaker enabled), (0x08: IR enabled), (0x10: LED1, 0x20: LED2, 0x40: LED3, 0x80: LED4)
|
||||
uint8_t batteryLevel;
|
||||
|
|
|
@ -167,13 +167,13 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
|||
|
||||
/* Initialize data structures for endpoints of device */
|
||||
epInfo[ XBOX_INPUT_PIPE ].epAddr = 0x01; // XBOX report endpoint
|
||||
epInfo[ XBOX_INPUT_PIPE ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_INPUT_PIPE ].bmSndToggle = 0;
|
||||
epInfo[ XBOX_INPUT_PIPE ].bmRcvToggle = 0;
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].epAddr = 0x02; // XBOX output endpoint
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].bmSndToggle = 0;
|
||||
|
|
|
@ -19,14 +19,12 @@
|
|||
#define _xboxold_h_
|
||||
|
||||
#include "Usb.h"
|
||||
#include "Hid.h"
|
||||
#include "controllerEnums.h"
|
||||
|
||||
/* Data Xbox taken from descriptors */
|
||||
#define EP_MAXPKTSIZE 32 // Max size for data via USB
|
||||
|
||||
/* Endpoint types */
|
||||
#define EP_INTERRUPT 0x03
|
||||
|
||||
/* Names we give to the 3 Xbox pipes */
|
||||
#define XBOX_CONTROL_PIPE 0
|
||||
#define XBOX_INPUT_PIPE 1
|
||||
|
@ -42,10 +40,6 @@
|
|||
#define XBOX_OLD_PID3 0x0287 // Microsoft Microsoft Xbox Controller S
|
||||
#define XBOX_OLD_PID4 0x0289 // Smaller Microsoft Xbox controller (US)
|
||||
|
||||
// Used in control endpoint header for HID Commands
|
||||
#define bmREQ_HID_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||
#define HID_REQUEST_SET_REPORT 0x09
|
||||
|
||||
#define XBOX_MAX_ENDPOINTS 3
|
||||
|
||||
/** This class implements support for a the original Xbox controller via USB. */
|
||||
|
|
16
XBOXRECV.cpp
16
XBOXRECV.cpp
|
@ -188,52 +188,52 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
|||
|
||||
/* Initialize data structures for endpoints of device */
|
||||
epInfo[ XBOX_INPUT_PIPE_1 ].epAddr = 0x01; // XBOX 360 report endpoint - poll interval 1ms
|
||||
epInfo[ XBOX_INPUT_PIPE_1 ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE_1 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE_1 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_INPUT_PIPE_1 ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_INPUT_PIPE_1 ].bmSndToggle = 0;
|
||||
epInfo[ XBOX_INPUT_PIPE_1 ].bmRcvToggle = 0;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_1 ].epAddr = 0x01; // XBOX 360 output endpoint - poll interval 8ms
|
||||
epInfo[ XBOX_OUTPUT_PIPE_1 ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_1 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_1 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_OUTPUT_PIPE_1 ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_1 ].bmSndToggle = 0;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_1 ].bmRcvToggle = 0;
|
||||
|
||||
epInfo[ XBOX_INPUT_PIPE_2 ].epAddr = 0x03; // XBOX 360 report endpoint - poll interval 1ms
|
||||
epInfo[ XBOX_INPUT_PIPE_2 ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE_2 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE_2 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_INPUT_PIPE_2 ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_INPUT_PIPE_2 ].bmSndToggle = 0;
|
||||
epInfo[ XBOX_INPUT_PIPE_2 ].bmRcvToggle = 0;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_2 ].epAddr = 0x03; // XBOX 360 output endpoint - poll interval 8ms
|
||||
epInfo[ XBOX_OUTPUT_PIPE_2 ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_2 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_2 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_OUTPUT_PIPE_2 ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_2 ].bmSndToggle = 0;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_2 ].bmRcvToggle = 0;
|
||||
|
||||
epInfo[ XBOX_INPUT_PIPE_3 ].epAddr = 0x05; // XBOX 360 report endpoint - poll interval 1ms
|
||||
epInfo[ XBOX_INPUT_PIPE_3 ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE_3 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE_3 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_INPUT_PIPE_3 ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_INPUT_PIPE_3 ].bmSndToggle = 0;
|
||||
epInfo[ XBOX_INPUT_PIPE_3 ].bmRcvToggle = 0;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_3 ].epAddr = 0x05; // XBOX 360 output endpoint - poll interval 8ms
|
||||
epInfo[ XBOX_OUTPUT_PIPE_3 ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_3 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_3 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_OUTPUT_PIPE_3 ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_3 ].bmSndToggle = 0;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_3 ].bmRcvToggle = 0;
|
||||
|
||||
epInfo[ XBOX_INPUT_PIPE_4 ].epAddr = 0x07; // XBOX 360 report endpoint - poll interval 1ms
|
||||
epInfo[ XBOX_INPUT_PIPE_4 ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE_4 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE_4 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_INPUT_PIPE_4 ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_INPUT_PIPE_4 ].bmSndToggle = 0;
|
||||
epInfo[ XBOX_INPUT_PIPE_4 ].bmRcvToggle = 0;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_4 ].epAddr = 0x07; // XBOX 360 output endpoint - poll interval 8ms
|
||||
epInfo[ XBOX_OUTPUT_PIPE_4 ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_4 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_4 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_OUTPUT_PIPE_4 ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_OUTPUT_PIPE_4 ].bmSndToggle = 0;
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
/* Data Xbox 360 taken from descriptors */
|
||||
#define EP_MAXPKTSIZE 32 // max size for data via USB
|
||||
|
||||
/* Endpoint types */
|
||||
#define EP_INTERRUPT 0x03
|
||||
|
||||
/* Names we give to the 9 Xbox360 pipes */
|
||||
#define XBOX_CONTROL_PIPE 0
|
||||
#define XBOX_INPUT_PIPE_1 1
|
||||
|
|
|
@ -105,7 +105,7 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
|||
Notify(PSTR("\r\nThis library only supports Xbox 360 controllers via USB"), 0x80);
|
||||
#endif
|
||||
goto FailUnknownDevice;
|
||||
} else if(PID != XBOX_WIRED_PID && PID != MADCATZ_WIRED_PID && PID != GAMESTOP_WIRED_PID && PID != AFTERGLOW_WIRED_PID) // Check PID
|
||||
} else if(PID != XBOX_WIRED_PID && PID != MADCATZ_WIRED_PID && PID != GAMESTOP_WIRED_PID && PID != AFTERGLOW_WIRED_PID && PID != JOYTECH_WIRED_PID) // Check PID
|
||||
goto FailUnknownDevice;
|
||||
|
||||
// Allocate new address according to device class
|
||||
|
@ -155,13 +155,13 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
|||
|
||||
/* Initialize data structures for endpoints of device */
|
||||
epInfo[ XBOX_INPUT_PIPE ].epAddr = 0x01; // XBOX 360 report endpoint
|
||||
epInfo[ XBOX_INPUT_PIPE ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_INPUT_PIPE ].bmSndToggle = 0;
|
||||
epInfo[ XBOX_INPUT_PIPE ].bmRcvToggle = 0;
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].epAddr = 0x02; // XBOX 360 output endpoint
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].bmSndToggle = 0;
|
||||
|
|
11
XBOXUSB.h
11
XBOXUSB.h
|
@ -19,14 +19,12 @@
|
|||
#define _xboxusb_h_
|
||||
|
||||
#include "Usb.h"
|
||||
#include "Hid.h"
|
||||
#include "xboxEnums.h"
|
||||
|
||||
/* Data Xbox 360 taken from descriptors */
|
||||
#define EP_MAXPKTSIZE 32 // max size for data via USB
|
||||
|
||||
/* Endpoint types */
|
||||
#define EP_INTERRUPT 0x03
|
||||
|
||||
/* Names we give to the 3 Xbox360 pipes */
|
||||
#define XBOX_CONTROL_PIPE 0
|
||||
#define XBOX_INPUT_PIPE 1
|
||||
|
@ -43,15 +41,12 @@
|
|||
#define XBOX_WIRELESS_RECEIVER_PID 0x0719 // Microsoft Wireless Gaming Receiver
|
||||
#define XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID 0x0291 // Third party Wireless Gaming Receiver
|
||||
#define MADCATZ_WIRED_PID 0xF016 // Mad Catz wired controller
|
||||
#define JOYTECH_WIRED_PID 0xBEEF // For Joytech wired controller
|
||||
#define GAMESTOP_WIRED_PID 0x0401 // Gamestop wired controller
|
||||
#define AFTERGLOW_WIRED_PID 0x0213 // Afterglow wired controller - it uses the same VID as a Gamestop controller
|
||||
|
||||
#define XBOX_REPORT_BUFFER_SIZE 14 // Size of the input report buffer
|
||||
|
||||
// Used in control endpoint header for HID Commands
|
||||
#define bmREQ_HID_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||
#define HID_REQUEST_SET_REPORT 0x09
|
||||
|
||||
#define XBOX_MAX_ENDPOINTS 3
|
||||
|
||||
/** This class implements support for a Xbox wired controller via USB. */
|
||||
|
@ -106,7 +101,7 @@ public:
|
|||
* @return Returns true if the device's VID and PID matches this driver.
|
||||
*/
|
||||
virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
|
||||
return ((vid == XBOX_VID || vid == MADCATZ_VID || vid == JOYTECH_VID || vid == GAMESTOP_VID) && (pid == XBOX_WIRED_PID || pid == MADCATZ_WIRED_PID || pid == GAMESTOP_WIRED_PID || pid == AFTERGLOW_WIRED_PID));
|
||||
return ((vid == XBOX_VID || vid == MADCATZ_VID || vid == JOYTECH_VID || vid == GAMESTOP_VID) && (pid == XBOX_WIRED_PID || pid == MADCATZ_WIRED_PID || pid == GAMESTOP_WIRED_PID || pid == AFTERGLOW_WIRED_PID || pid == JOYTECH_WIRED_PID));
|
||||
};
|
||||
/**@}*/
|
||||
|
||||
|
|
|
@ -121,13 +121,16 @@ void loop() {
|
|||
printAngle = !printAngle;
|
||||
}
|
||||
}
|
||||
#if 0 // Set this to 1 in order to see the angle of the controller
|
||||
if (printAngle) {
|
||||
Serial.print(F("\r\nPitch: "));
|
||||
Serial.print(PS3.getAngle(Pitch));
|
||||
Serial.print(F("\tRoll: "));
|
||||
Serial.print(PS3.getAngle(Roll));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if 0 // Set this to 1 in order to enable support for the Playstation Move controller
|
||||
else if (PS3.PS3MoveConnected) {
|
||||
if (PS3.getAnalogButton(T)) {
|
||||
Serial.print(F("\r\nT: "));
|
||||
|
@ -180,4 +183,5 @@ void loop() {
|
|||
Serial.print(PS3.getTemperature());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ void loop() {
|
|||
Serial.print(F("\r\nB"));
|
||||
}
|
||||
}
|
||||
#if 0 // Set this to 1 in order to see the angle of the controllers
|
||||
if (printAngle) {
|
||||
Serial.print(F("\r\nPitch: "));
|
||||
Serial.print(Wii.getPitch());
|
||||
|
@ -97,7 +98,9 @@ void loop() {
|
|||
Serial.print(Wii.getNunchuckRoll());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if 0 // Set this to 1 if you are using a Nunchuck controller
|
||||
if (Wii.nunchuckConnected) {
|
||||
if (Wii.getButtonClick(Z))
|
||||
Serial.print(F("\r\nZ"));
|
||||
|
@ -110,4 +113,5 @@ void loop() {
|
|||
Serial.print(Wii.getAnalogHat(HatY));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -8,91 +8,91 @@
|
|||
|
||||
class KbdRptParser : public KeyboardReportParser
|
||||
{
|
||||
void PrintKey(uint8_t mod, uint8_t key);
|
||||
void PrintKey(uint8_t mod, uint8_t key);
|
||||
|
||||
protected:
|
||||
void OnControlKeysChanged(uint8_t before, uint8_t after);
|
||||
protected:
|
||||
void OnControlKeysChanged(uint8_t before, uint8_t after);
|
||||
|
||||
void OnKeyDown (uint8_t mod, uint8_t key);
|
||||
void OnKeyUp (uint8_t mod, uint8_t key);
|
||||
void OnKeyPressed(uint8_t key);
|
||||
void OnKeyDown (uint8_t mod, uint8_t key);
|
||||
void OnKeyUp (uint8_t mod, uint8_t key);
|
||||
void OnKeyPressed(uint8_t key);
|
||||
};
|
||||
|
||||
void KbdRptParser::PrintKey(uint8_t m, uint8_t key)
|
||||
{
|
||||
MODIFIERKEYS mod;
|
||||
*((uint8_t*)&mod) = m;
|
||||
Serial.print((mod.bmLeftCtrl == 1) ? "C" : " ");
|
||||
Serial.print((mod.bmLeftShift == 1) ? "S" : " ");
|
||||
Serial.print((mod.bmLeftAlt == 1) ? "A" : " ");
|
||||
Serial.print((mod.bmLeftGUI == 1) ? "G" : " ");
|
||||
MODIFIERKEYS mod;
|
||||
*((uint8_t*)&mod) = m;
|
||||
Serial.print((mod.bmLeftCtrl == 1) ? "C" : " ");
|
||||
Serial.print((mod.bmLeftShift == 1) ? "S" : " ");
|
||||
Serial.print((mod.bmLeftAlt == 1) ? "A" : " ");
|
||||
Serial.print((mod.bmLeftGUI == 1) ? "G" : " ");
|
||||
|
||||
Serial.print(" >");
|
||||
PrintHex<uint8_t>(key, 0x80);
|
||||
Serial.print("< ");
|
||||
Serial.print(" >");
|
||||
PrintHex<uint8_t>(key, 0x80);
|
||||
Serial.print("< ");
|
||||
|
||||
Serial.print((mod.bmRightCtrl == 1) ? "C" : " ");
|
||||
Serial.print((mod.bmRightShift == 1) ? "S" : " ");
|
||||
Serial.print((mod.bmRightAlt == 1) ? "A" : " ");
|
||||
Serial.println((mod.bmRightGUI == 1) ? "G" : " ");
|
||||
Serial.print((mod.bmRightCtrl == 1) ? "C" : " ");
|
||||
Serial.print((mod.bmRightShift == 1) ? "S" : " ");
|
||||
Serial.print((mod.bmRightAlt == 1) ? "A" : " ");
|
||||
Serial.println((mod.bmRightGUI == 1) ? "G" : " ");
|
||||
};
|
||||
|
||||
void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)
|
||||
{
|
||||
Serial.print("DN ");
|
||||
PrintKey(mod, key);
|
||||
uint8_t c = OemToAscii(mod, key);
|
||||
Serial.print("DN ");
|
||||
PrintKey(mod, key);
|
||||
uint8_t c = OemToAscii(mod, key);
|
||||
|
||||
if (c)
|
||||
OnKeyPressed(c);
|
||||
if (c)
|
||||
OnKeyPressed(c);
|
||||
}
|
||||
|
||||
void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) {
|
||||
|
||||
MODIFIERKEYS beforeMod;
|
||||
*((uint8_t*)&beforeMod) = before;
|
||||
MODIFIERKEYS beforeMod;
|
||||
*((uint8_t*)&beforeMod) = before;
|
||||
|
||||
MODIFIERKEYS afterMod;
|
||||
*((uint8_t*)&afterMod) = after;
|
||||
MODIFIERKEYS afterMod;
|
||||
*((uint8_t*)&afterMod) = after;
|
||||
|
||||
if (beforeMod.bmLeftCtrl != afterMod.bmLeftCtrl) {
|
||||
Serial.println("LeftCtrl changed");
|
||||
}
|
||||
if (beforeMod.bmLeftShift != afterMod.bmLeftShift) {
|
||||
Serial.println("LeftShift changed");
|
||||
}
|
||||
if (beforeMod.bmLeftAlt != afterMod.bmLeftAlt) {
|
||||
Serial.println("LeftAlt changed");
|
||||
}
|
||||
if (beforeMod.bmLeftGUI != afterMod.bmLeftGUI) {
|
||||
Serial.println("LeftGUI changed");
|
||||
}
|
||||
if (beforeMod.bmLeftCtrl != afterMod.bmLeftCtrl) {
|
||||
Serial.println("LeftCtrl changed");
|
||||
}
|
||||
if (beforeMod.bmLeftShift != afterMod.bmLeftShift) {
|
||||
Serial.println("LeftShift changed");
|
||||
}
|
||||
if (beforeMod.bmLeftAlt != afterMod.bmLeftAlt) {
|
||||
Serial.println("LeftAlt changed");
|
||||
}
|
||||
if (beforeMod.bmLeftGUI != afterMod.bmLeftGUI) {
|
||||
Serial.println("LeftGUI changed");
|
||||
}
|
||||
|
||||
if (beforeMod.bmRightCtrl != afterMod.bmRightCtrl) {
|
||||
Serial.println("RightCtrl changed");
|
||||
}
|
||||
if (beforeMod.bmRightShift != afterMod.bmRightShift) {
|
||||
Serial.println("RightShift changed");
|
||||
}
|
||||
if (beforeMod.bmRightAlt != afterMod.bmRightAlt) {
|
||||
Serial.println("RightAlt changed");
|
||||
}
|
||||
if (beforeMod.bmRightGUI != afterMod.bmRightGUI) {
|
||||
Serial.println("RightGUI changed");
|
||||
}
|
||||
if (beforeMod.bmRightCtrl != afterMod.bmRightCtrl) {
|
||||
Serial.println("RightCtrl changed");
|
||||
}
|
||||
if (beforeMod.bmRightShift != afterMod.bmRightShift) {
|
||||
Serial.println("RightShift changed");
|
||||
}
|
||||
if (beforeMod.bmRightAlt != afterMod.bmRightAlt) {
|
||||
Serial.println("RightAlt changed");
|
||||
}
|
||||
if (beforeMod.bmRightGUI != afterMod.bmRightGUI) {
|
||||
Serial.println("RightGUI changed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)
|
||||
{
|
||||
Serial.print("UP ");
|
||||
PrintKey(mod, key);
|
||||
Serial.print("UP ");
|
||||
PrintKey(mod, key);
|
||||
}
|
||||
|
||||
void KbdRptParser::OnKeyPressed(uint8_t key)
|
||||
{
|
||||
Serial.print("ASCII: ");
|
||||
Serial.println((char)key);
|
||||
Serial.print("ASCII: ");
|
||||
Serial.println((char)key);
|
||||
};
|
||||
|
||||
USB Usb;
|
||||
|
@ -105,24 +105,24 @@ KbdRptParser Prs;
|
|||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin( 115200 );
|
||||
Serial.begin( 115200 );
|
||||
#if !defined(__MIPSEL__)
|
||||
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
|
||||
#endif
|
||||
Serial.println("Start");
|
||||
Serial.println("Start");
|
||||
|
||||
if (Usb.Init() == -1)
|
||||
Serial.println("OSC did not start.");
|
||||
if (Usb.Init() == -1)
|
||||
Serial.println("OSC did not start.");
|
||||
|
||||
delay( 200 );
|
||||
delay( 200 );
|
||||
|
||||
next_time = millis() + 5000;
|
||||
next_time = millis() + 5000;
|
||||
|
||||
HidKeyboard.SetReportParser(0, (HIDReportParser*)&Prs);
|
||||
HidKeyboard.SetReportParser(0, (HIDReportParser*)&Prs);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Usb.Task();
|
||||
Usb.Task();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,139 +8,139 @@
|
|||
|
||||
class MouseRptParser : public MouseReportParser
|
||||
{
|
||||
protected:
|
||||
void OnMouseMove(MOUSEINFO *mi);
|
||||
void OnLeftButtonUp(MOUSEINFO *mi);
|
||||
void OnLeftButtonDown(MOUSEINFO *mi);
|
||||
void OnRightButtonUp(MOUSEINFO *mi);
|
||||
void OnRightButtonDown(MOUSEINFO *mi);
|
||||
void OnMiddleButtonUp(MOUSEINFO *mi);
|
||||
void OnMiddleButtonDown(MOUSEINFO *mi);
|
||||
protected:
|
||||
void OnMouseMove(MOUSEINFO *mi);
|
||||
void OnLeftButtonUp(MOUSEINFO *mi);
|
||||
void OnLeftButtonDown(MOUSEINFO *mi);
|
||||
void OnRightButtonUp(MOUSEINFO *mi);
|
||||
void OnRightButtonDown(MOUSEINFO *mi);
|
||||
void OnMiddleButtonUp(MOUSEINFO *mi);
|
||||
void OnMiddleButtonDown(MOUSEINFO *mi);
|
||||
};
|
||||
void MouseRptParser::OnMouseMove(MOUSEINFO *mi)
|
||||
{
|
||||
Serial.print("dx=");
|
||||
Serial.print(mi->dX, DEC);
|
||||
Serial.print(" dy=");
|
||||
Serial.println(mi->dY, DEC);
|
||||
Serial.print("dx=");
|
||||
Serial.print(mi->dX, DEC);
|
||||
Serial.print(" dy=");
|
||||
Serial.println(mi->dY, DEC);
|
||||
};
|
||||
void MouseRptParser::OnLeftButtonUp (MOUSEINFO *mi)
|
||||
{
|
||||
Serial.println("L Butt Up");
|
||||
Serial.println("L Butt Up");
|
||||
};
|
||||
void MouseRptParser::OnLeftButtonDown (MOUSEINFO *mi)
|
||||
{
|
||||
Serial.println("L Butt Dn");
|
||||
Serial.println("L Butt Dn");
|
||||
};
|
||||
void MouseRptParser::OnRightButtonUp (MOUSEINFO *mi)
|
||||
{
|
||||
Serial.println("R Butt Up");
|
||||
Serial.println("R Butt Up");
|
||||
};
|
||||
void MouseRptParser::OnRightButtonDown (MOUSEINFO *mi)
|
||||
{
|
||||
Serial.println("R Butt Dn");
|
||||
Serial.println("R Butt Dn");
|
||||
};
|
||||
void MouseRptParser::OnMiddleButtonUp (MOUSEINFO *mi)
|
||||
{
|
||||
Serial.println("M Butt Up");
|
||||
Serial.println("M Butt Up");
|
||||
};
|
||||
void MouseRptParser::OnMiddleButtonDown (MOUSEINFO *mi)
|
||||
{
|
||||
Serial.println("M Butt Dn");
|
||||
Serial.println("M Butt Dn");
|
||||
};
|
||||
|
||||
class KbdRptParser : public KeyboardReportParser
|
||||
{
|
||||
void PrintKey(uint8_t mod, uint8_t key);
|
||||
void PrintKey(uint8_t mod, uint8_t key);
|
||||
|
||||
protected:
|
||||
void OnControlKeysChanged(uint8_t before, uint8_t after);
|
||||
void OnKeyDown (uint8_t mod, uint8_t key);
|
||||
void OnKeyUp (uint8_t mod, uint8_t key);
|
||||
void OnKeyPressed(uint8_t key);
|
||||
protected:
|
||||
void OnControlKeysChanged(uint8_t before, uint8_t after);
|
||||
void OnKeyDown (uint8_t mod, uint8_t key);
|
||||
void OnKeyUp (uint8_t mod, uint8_t key);
|
||||
void OnKeyPressed(uint8_t key);
|
||||
};
|
||||
|
||||
void KbdRptParser::PrintKey(uint8_t m, uint8_t key)
|
||||
{
|
||||
MODIFIERKEYS mod;
|
||||
*((uint8_t*)&mod) = m;
|
||||
Serial.print((mod.bmLeftCtrl == 1) ? "C" : " ");
|
||||
Serial.print((mod.bmLeftShift == 1) ? "S" : " ");
|
||||
Serial.print((mod.bmLeftAlt == 1) ? "A" : " ");
|
||||
Serial.print((mod.bmLeftGUI == 1) ? "G" : " ");
|
||||
MODIFIERKEYS mod;
|
||||
*((uint8_t*)&mod) = m;
|
||||
Serial.print((mod.bmLeftCtrl == 1) ? "C" : " ");
|
||||
Serial.print((mod.bmLeftShift == 1) ? "S" : " ");
|
||||
Serial.print((mod.bmLeftAlt == 1) ? "A" : " ");
|
||||
Serial.print((mod.bmLeftGUI == 1) ? "G" : " ");
|
||||
|
||||
Serial.print(" >");
|
||||
PrintHex<uint8_t>(key, 0x80);
|
||||
Serial.print("< ");
|
||||
Serial.print(" >");
|
||||
PrintHex<uint8_t>(key, 0x80);
|
||||
Serial.print("< ");
|
||||
|
||||
Serial.print((mod.bmRightCtrl == 1) ? "C" : " ");
|
||||
Serial.print((mod.bmRightShift == 1) ? "S" : " ");
|
||||
Serial.print((mod.bmRightAlt == 1) ? "A" : " ");
|
||||
Serial.println((mod.bmRightGUI == 1) ? "G" : " ");
|
||||
Serial.print((mod.bmRightCtrl == 1) ? "C" : " ");
|
||||
Serial.print((mod.bmRightShift == 1) ? "S" : " ");
|
||||
Serial.print((mod.bmRightAlt == 1) ? "A" : " ");
|
||||
Serial.println((mod.bmRightGUI == 1) ? "G" : " ");
|
||||
};
|
||||
|
||||
void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)
|
||||
{
|
||||
Serial.print("DN ");
|
||||
PrintKey(mod, key);
|
||||
uint8_t c = OemToAscii(mod, key);
|
||||
Serial.print("DN ");
|
||||
PrintKey(mod, key);
|
||||
uint8_t c = OemToAscii(mod, key);
|
||||
|
||||
if (c)
|
||||
OnKeyPressed(c);
|
||||
if (c)
|
||||
OnKeyPressed(c);
|
||||
}
|
||||
|
||||
void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) {
|
||||
|
||||
MODIFIERKEYS beforeMod;
|
||||
*((uint8_t*)&beforeMod) = before;
|
||||
MODIFIERKEYS beforeMod;
|
||||
*((uint8_t*)&beforeMod) = before;
|
||||
|
||||
MODIFIERKEYS afterMod;
|
||||
*((uint8_t*)&afterMod) = after;
|
||||
MODIFIERKEYS afterMod;
|
||||
*((uint8_t*)&afterMod) = after;
|
||||
|
||||
if (beforeMod.bmLeftCtrl != afterMod.bmLeftCtrl) {
|
||||
Serial.println("LeftCtrl changed");
|
||||
}
|
||||
if (beforeMod.bmLeftShift != afterMod.bmLeftShift) {
|
||||
Serial.println("LeftShift changed");
|
||||
}
|
||||
if (beforeMod.bmLeftAlt != afterMod.bmLeftAlt) {
|
||||
Serial.println("LeftAlt changed");
|
||||
}
|
||||
if (beforeMod.bmLeftGUI != afterMod.bmLeftGUI) {
|
||||
Serial.println("LeftGUI changed");
|
||||
}
|
||||
if (beforeMod.bmLeftCtrl != afterMod.bmLeftCtrl) {
|
||||
Serial.println("LeftCtrl changed");
|
||||
}
|
||||
if (beforeMod.bmLeftShift != afterMod.bmLeftShift) {
|
||||
Serial.println("LeftShift changed");
|
||||
}
|
||||
if (beforeMod.bmLeftAlt != afterMod.bmLeftAlt) {
|
||||
Serial.println("LeftAlt changed");
|
||||
}
|
||||
if (beforeMod.bmLeftGUI != afterMod.bmLeftGUI) {
|
||||
Serial.println("LeftGUI changed");
|
||||
}
|
||||
|
||||
if (beforeMod.bmRightCtrl != afterMod.bmRightCtrl) {
|
||||
Serial.println("RightCtrl changed");
|
||||
}
|
||||
if (beforeMod.bmRightShift != afterMod.bmRightShift) {
|
||||
Serial.println("RightShift changed");
|
||||
}
|
||||
if (beforeMod.bmRightAlt != afterMod.bmRightAlt) {
|
||||
Serial.println("RightAlt changed");
|
||||
}
|
||||
if (beforeMod.bmRightGUI != afterMod.bmRightGUI) {
|
||||
Serial.println("RightGUI changed");
|
||||
}
|
||||
if (beforeMod.bmRightCtrl != afterMod.bmRightCtrl) {
|
||||
Serial.println("RightCtrl changed");
|
||||
}
|
||||
if (beforeMod.bmRightShift != afterMod.bmRightShift) {
|
||||
Serial.println("RightShift changed");
|
||||
}
|
||||
if (beforeMod.bmRightAlt != afterMod.bmRightAlt) {
|
||||
Serial.println("RightAlt changed");
|
||||
}
|
||||
if (beforeMod.bmRightGUI != afterMod.bmRightGUI) {
|
||||
Serial.println("RightGUI changed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)
|
||||
{
|
||||
Serial.print("UP ");
|
||||
PrintKey(mod, key);
|
||||
Serial.print("UP ");
|
||||
PrintKey(mod, key);
|
||||
}
|
||||
|
||||
void KbdRptParser::OnKeyPressed(uint8_t key)
|
||||
{
|
||||
Serial.print("ASCII: ");
|
||||
Serial.println((char)key);
|
||||
Serial.print("ASCII: ");
|
||||
Serial.println((char)key);
|
||||
};
|
||||
|
||||
USB Usb;
|
||||
USBHub Hub(&Usb);
|
||||
|
||||
HIDBoot<HID_PROTOCOL_KEYBOARD | HID_PROTOCOL_MOUSE> HidComposite(&Usb);
|
||||
HIDBoot < HID_PROTOCOL_KEYBOARD | HID_PROTOCOL_MOUSE > HidComposite(&Usb);
|
||||
HIDBoot<HID_PROTOCOL_KEYBOARD> HidKeyboard(&Usb);
|
||||
HIDBoot<HID_PROTOCOL_MOUSE> HidMouse(&Usb);
|
||||
|
||||
|
@ -151,27 +151,27 @@ MouseRptParser MousePrs;
|
|||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin( 115200 );
|
||||
Serial.begin( 115200 );
|
||||
#if !defined(__MIPSEL__)
|
||||
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
|
||||
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
|
||||
#endif
|
||||
Serial.println("Start");
|
||||
Serial.println("Start");
|
||||
|
||||
if (Usb.Init() == -1)
|
||||
Serial.println("OSC did not start.");
|
||||
if (Usb.Init() == -1)
|
||||
Serial.println("OSC did not start.");
|
||||
|
||||
delay( 200 );
|
||||
delay( 200 );
|
||||
|
||||
//next_time = millis() + 5000;
|
||||
//next_time = millis() + 5000;
|
||||
|
||||
HidComposite.SetReportParser(0, (HIDReportParser*)&KbdPrs);
|
||||
HidComposite.SetReportParser(1,(HIDReportParser*)&MousePrs);
|
||||
HidKeyboard.SetReportParser(0, (HIDReportParser*)&KbdPrs);
|
||||
HidMouse.SetReportParser(0,(HIDReportParser*)&MousePrs);
|
||||
HidComposite.SetReportParser(0, (HIDReportParser*)&KbdPrs);
|
||||
HidComposite.SetReportParser(1, (HIDReportParser*)&MousePrs);
|
||||
HidKeyboard.SetReportParser(0, (HIDReportParser*)&KbdPrs);
|
||||
HidMouse.SetReportParser(0, (HIDReportParser*)&MousePrs);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Usb.Task();
|
||||
Usb.Task();
|
||||
}
|
||||
|
||||
|
|
46
library.json
Normal file
46
library.json
Normal file
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"name": "USB-Host-Shield-20",
|
||||
"keywords": "usb, host, ftdi, adk, acm, pl2303, hid, bluetooth, spp, ps3, ps4, buzz, xbox, wii, mass storage",
|
||||
"description": "Revision 2.0 of MAX3421E-based USB Host Shield Library",
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
"name": "Oleg Mazurov",
|
||||
"email": "mazurov@circuitsathome.com",
|
||||
"url": "http://www.circuitsathome.com",
|
||||
"maintainer": true
|
||||
},
|
||||
{
|
||||
"name": "Alexei Glushchenko",
|
||||
"email": "alex-gl@mail.ru"
|
||||
},
|
||||
{
|
||||
"name": "Kristian Lauszus",
|
||||
"email": "kristianl@tkjelectronics.com",
|
||||
"url": "http://tkjelectronics.com",
|
||||
"maintainer": true
|
||||
},
|
||||
{
|
||||
"name": "Andrew Kroll",
|
||||
"email": "xxxajk@gmail.com",
|
||||
"maintainer": true
|
||||
}
|
||||
],
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/felis/USB_Host_Shield_2.0.git"
|
||||
},
|
||||
"examples":
|
||||
[
|
||||
"examples/*/*.ino",
|
||||
"examples/*/*/*.ino"
|
||||
],
|
||||
"frameworks": "arduino",
|
||||
"platforms":
|
||||
[
|
||||
"atmelavr",
|
||||
"teensy",
|
||||
"atmelsam"
|
||||
]
|
||||
}
|
|
@ -129,10 +129,10 @@ e-mail : support@circuitsathome.com
|
|||
#define USING_SPI4TEENSY3 0
|
||||
#endif
|
||||
|
||||
#if (defined(ARDUINO_SAM_DUE) && defined(__SAM3X8E__))
|
||||
#include <SPI.h> // Use the Arduino SPI library
|
||||
#if (defined(ARDUINO_SAM_DUE) && defined(__SAM3X8E__)) || defined(RBL_NRF51822)
|
||||
#include <SPI.h> // Use the Arduino SPI library for the Arduino Due and RedBearLab nRF51822
|
||||
#endif
|
||||
#if defined(__PIC32MX__) || defined(__PIC32MZ__)
|
||||
#if defined(__PIC32MX__) || defined(__PIC32MZ__)
|
||||
#include <../../../../hardware/pic32/libraries/SPI/SPI.h> // Hack to use the SPI library
|
||||
#endif
|
||||
#endif /* SETTINGS_H */
|
||||
|
|
Loading…
Reference in a new issue