mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Merge branch 'dev' into SPI
This commit is contained in:
commit
8aafdccc80
18 changed files with 227 additions and 266 deletions
7
BTD.cpp
7
BTD.cpp
|
@ -380,6 +380,12 @@ uint8_t BTD::Poll() {
|
||||||
return 0;
|
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() {
|
void BTD::HCI_event_task() {
|
||||||
uint16_t length = BULK_MAXPKTSIZE; // Request more than 16 bytes anyway, the inTransfer routine will take care of this
|
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
|
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
|
if(remote_name[i] == '\0') // End of string
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// TODO: Altid sæt '\0' i remote name!
|
||||||
hci_set_flag(HCI_FLAG_REMOTE_NAME_COMPLETE);
|
hci_set_flag(HCI_FLAG_REMOTE_NAME_COMPLETE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
151
BTD.h
151
BTD.h
|
@ -19,6 +19,7 @@
|
||||||
#define _btd_h_
|
#define _btd_h_
|
||||||
|
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
#include "Hid.h"
|
||||||
|
|
||||||
//PID and VID of the Sony PS3 devices
|
//PID and VID of the Sony PS3 devices
|
||||||
#define PS3_VID 0x054C // Sony Corporation
|
#define PS3_VID 0x054C // Sony Corporation
|
||||||
|
@ -34,9 +35,6 @@
|
||||||
|
|
||||||
// Used in control endpoint header for HCI Commands
|
// 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
|
#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() */
|
/* Bluetooth HCI states for hci_task() */
|
||||||
#define HCI_INIT_STATE 0
|
#define HCI_INIT_STATE 0
|
||||||
|
@ -60,15 +58,15 @@
|
||||||
#define HCI_DISCONNECT_STATE 16
|
#define HCI_DISCONNECT_STATE 16
|
||||||
|
|
||||||
/* HCI event flags*/
|
/* HCI event flags*/
|
||||||
#define HCI_FLAG_CMD_COMPLETE 0x01
|
#define HCI_FLAG_CMD_COMPLETE (1UL << 0)
|
||||||
#define HCI_FLAG_CONNECT_COMPLETE 0x02
|
#define HCI_FLAG_CONNECT_COMPLETE (1UL << 1)
|
||||||
#define HCI_FLAG_DISCONNECT_COMPLETE 0x04
|
#define HCI_FLAG_DISCONNECT_COMPLETE (1UL << 2)
|
||||||
#define HCI_FLAG_REMOTE_NAME_COMPLETE 0x08
|
#define HCI_FLAG_REMOTE_NAME_COMPLETE (1UL << 3)
|
||||||
#define HCI_FLAG_INCOMING_REQUEST 0x10
|
#define HCI_FLAG_INCOMING_REQUEST (1UL << 4)
|
||||||
#define HCI_FLAG_READ_BDADDR 0x20
|
#define HCI_FLAG_READ_BDADDR (1UL << 5)
|
||||||
#define HCI_FLAG_READ_VERSION 0x40
|
#define HCI_FLAG_READ_VERSION (1UL << 6)
|
||||||
#define HCI_FLAG_DEVICE_FOUND 0x80
|
#define HCI_FLAG_DEVICE_FOUND (1UL << 7)
|
||||||
#define HCI_FLAG_CONNECT_EVENT 0x100
|
#define HCI_FLAG_CONNECT_EVENT (1UL << 8)
|
||||||
|
|
||||||
/* Macros for HCI event flag tests */
|
/* Macros for HCI event flag tests */
|
||||||
#define hci_check_flag(flag) (hci_event_flag & (flag))
|
#define hci_check_flag(flag) (hci_event_flag & (flag))
|
||||||
|
@ -133,28 +131,28 @@
|
||||||
#define WII_INIT_MOTION_PLUS_STATE 21
|
#define WII_INIT_MOTION_PLUS_STATE 21
|
||||||
|
|
||||||
/* L2CAP event flags for HID Control channel */
|
/* L2CAP event flags for HID Control channel */
|
||||||
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST 0x00000001
|
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST (1UL << 0)
|
||||||
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS 0x00000002
|
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS (1UL << 1)
|
||||||
#define L2CAP_FLAG_CONTROL_CONNECTED 0x00000004
|
#define L2CAP_FLAG_CONTROL_CONNECTED (1UL << 2)
|
||||||
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE 0x00000008
|
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE (1UL << 3)
|
||||||
|
|
||||||
/* L2CAP event flags for HID Interrupt channel */
|
/* L2CAP event flags for HID Interrupt channel */
|
||||||
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST 0x00000010
|
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST (1UL << 4)
|
||||||
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS 0x00000020
|
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS (1UL << 5)
|
||||||
#define L2CAP_FLAG_INTERRUPT_CONNECTED 0x00000040
|
#define L2CAP_FLAG_INTERRUPT_CONNECTED (1UL << 6)
|
||||||
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE 0x00000080
|
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE (1UL << 7)
|
||||||
|
|
||||||
/* L2CAP event flags for SDP channel */
|
/* L2CAP event flags for SDP channel */
|
||||||
#define L2CAP_FLAG_CONNECTION_SDP_REQUEST 0x00000100
|
#define L2CAP_FLAG_CONNECTION_SDP_REQUEST (1UL << 8)
|
||||||
#define L2CAP_FLAG_CONFIG_SDP_SUCCESS 0x00000200
|
#define L2CAP_FLAG_CONFIG_SDP_SUCCESS (1UL << 9)
|
||||||
#define L2CAP_FLAG_DISCONNECT_SDP_REQUEST 0x00000400
|
#define L2CAP_FLAG_DISCONNECT_SDP_REQUEST (1UL << 10)
|
||||||
|
|
||||||
/* L2CAP event flags for RFCOMM channel */
|
/* L2CAP event flags for RFCOMM channel */
|
||||||
#define L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST 0x00000800
|
#define L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST (1UL << 11)
|
||||||
#define L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS 0x00001000
|
#define L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS (1UL << 12)
|
||||||
#define L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST 0x00002000
|
#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 */
|
/* Macros for L2CAP event flag tests */
|
||||||
#define l2cap_check_flag(flag) (l2cap_event_flag & (flag))
|
#define l2cap_check_flag(flag) (l2cap_event_flag & (flag))
|
||||||
|
@ -191,37 +189,7 @@
|
||||||
|
|
||||||
#define PAIR 1
|
#define PAIR 1
|
||||||
|
|
||||||
/* acl_handle_ok or it's a new connection */
|
class BluetoothService;
|
||||||
#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();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Bluetooth Dongle class will take care of all the USB communication
|
* 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. */
|
/** Disconnects both the L2CAP Channel and the HCI Connection for all Bluetooth services. */
|
||||||
void disconnect() {
|
void disconnect();
|
||||||
for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++)
|
|
||||||
if(btService[i])
|
|
||||||
btService[i]->disconnect();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register Bluetooth dongle members/services.
|
* Register Bluetooth dongle members/services.
|
||||||
* @param pService Pointer to BluetoothService class instance.
|
* @param pService Pointer to BluetoothService class instance.
|
||||||
* @return The service ID on success or -1 on fail.
|
* @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++) {
|
for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++) {
|
||||||
if(!btService[i]) {
|
if(!btService[i]) {
|
||||||
btService[i] = pService;
|
btService[i] = pService;
|
||||||
return i; // Return ID
|
return i; // Return ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1; // ErrorregisterServiceClass
|
return -1; // Error registering BluetoothService
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @name HCI Commands */
|
/** @name HCI Commands */
|
||||||
|
@ -594,4 +558,61 @@ private:
|
||||||
void setBdaddr(uint8_t* BDADDR);
|
void setBdaddr(uint8_t* BDADDR);
|
||||||
void setMoveBdaddr(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
|
#endif
|
||||||
|
|
|
@ -21,14 +21,11 @@
|
||||||
//#define PRINTREPORT // Uncomment to print the report send by the HID device
|
//#define PRINTREPORT // Uncomment to print the report send by the HID device
|
||||||
|
|
||||||
BTHID::BTHID(BTD *p, bool pair, const char *pin) :
|
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) {
|
protocolMode(HID_BOOT_PROTOCOL) {
|
||||||
for(uint8_t i = 0; i < NUM_PARSERS; i++)
|
for(uint8_t i = 0; i < NUM_PARSERS; i++)
|
||||||
pRptParser[i] = NULL;
|
pRptParser[i] = NULL;
|
||||||
|
|
||||||
if(pBtd)
|
|
||||||
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
|
||||||
|
|
||||||
pBtd->pairWithHIDDevice = pair;
|
pBtd->pairWithHIDDevice = pair;
|
||||||
pBtd->btdPin = pin;
|
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[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // l2cap_control - Channel ID for ACL-U
|
||||||
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#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");
|
BTHID(BTD *p, bool pair = false, const char *pin = "0000");
|
||||||
|
|
||||||
/** @name BluetoothService implementation */
|
/** @name BluetoothService implementation */
|
||||||
/**
|
|
||||||
* Used to pass acldata to the services.
|
|
||||||
* @param ACLData Incoming acldata.
|
|
||||||
*/
|
|
||||||
virtual void ACLData(uint8_t* ACLData);
|
|
||||||
/** Used to run part of the state machine. */
|
|
||||||
virtual void Run();
|
|
||||||
/** Use this to reset the service. */
|
|
||||||
virtual void Reset();
|
|
||||||
/** Used this to disconnect the devices. */
|
/** Used this to disconnect the devices. */
|
||||||
virtual void disconnect();
|
virtual void disconnect();
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
@ -97,15 +88,29 @@ public:
|
||||||
pBtd->pairWithHID();
|
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:
|
protected:
|
||||||
|
/** @name BluetoothService implementation */
|
||||||
|
/**
|
||||||
|
* Used to pass acldata to the services.
|
||||||
|
* @param ACLData Incoming acldata.
|
||||||
|
*/
|
||||||
|
virtual void ACLData(uint8_t* ACLData);
|
||||||
|
/** Used to run part of the state machine. */
|
||||||
|
virtual void Run();
|
||||||
|
/** Use this to reset the service. */
|
||||||
|
virtual 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.
|
||||||
|
*/
|
||||||
|
virtual void onInit() {
|
||||||
|
if(pFuncOnInit)
|
||||||
|
pFuncOnInit(); // Call the user function
|
||||||
|
OnInitBTHID();
|
||||||
|
};
|
||||||
|
/**@}*/
|
||||||
|
|
||||||
/** @name Overridable functions */
|
/** @name Overridable functions */
|
||||||
/**
|
/**
|
||||||
* Used to parse Bluetooth HID data to any class that inherits this class.
|
* 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 */
|
/** L2CAP source CID for HID_Control */
|
||||||
|
|
||||||
uint8_t control_scid[2];
|
uint8_t control_scid[2];
|
||||||
|
|
||||||
/** L2CAP source CID for HID_Interrupt */
|
/** L2CAP source CID for HID_Interrupt */
|
||||||
|
@ -145,18 +143,6 @@ private:
|
||||||
void setProtocol();
|
void setProtocol();
|
||||||
uint8_t protocolMode;
|
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
|
void L2CAP_task(); // L2CAP state machine
|
||||||
|
|
||||||
bool activeConnection; // Used to indicate if it already has established a connection
|
bool activeConnection; // Used to indicate if it already has established a connection
|
||||||
|
@ -164,8 +150,6 @@ private:
|
||||||
/* Variables used for L2CAP communication */
|
/* Variables used for L2CAP communication */
|
||||||
uint8_t control_dcid[2]; // L2CAP device CID for HID_Control - Always 0x0070
|
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 interrupt_dcid[2]; // L2CAP device CID for HID_Interrupt - Always 0x0071
|
||||||
uint8_t identifier; // Identifier for connection
|
|
||||||
uint8_t l2cap_state;
|
uint8_t l2cap_state;
|
||||||
uint32_t l2cap_event_flag; // l2cap flags of received Bluetooth events
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
30
PS3BT.cpp
30
PS3BT.cpp
|
@ -21,11 +21,8 @@
|
||||||
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
|
//#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) :
|
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[5] = btadr5; // Change to your dongle's Bluetooth address instead
|
||||||
pBtd->my_bdaddr[4] = btadr4;
|
pBtd->my_bdaddr[4] = btadr4;
|
||||||
pBtd->my_bdaddr[3] = btadr3;
|
pBtd->my_bdaddr[3] = btadr3;
|
||||||
|
@ -232,8 +229,7 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
||||||
activeConnection = true;
|
activeConnection = true;
|
||||||
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
||||||
l2cap_state = L2CAP_WAIT;
|
l2cap_state = L2CAP_WAIT;
|
||||||
for(uint8_t i = 0; i < 30; i++)
|
remote_name_first = pBtd->remote_name[0]; // Store the first letter in remote name for the connection
|
||||||
remote_name[i] = pBtd->remote_name[i]; // Store the remote name for the connection
|
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
if(pBtd->hci_version < 3) { // Check the HCI Version of the Bluetooth dongle
|
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);
|
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);
|
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) {
|
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
||||||
|
@ -419,7 +415,7 @@ void PS3BT::L2CAP_task() {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Interrupt Successfully Configured"), 0x80);
|
Notify(PSTR("\r\nHID Interrupt Successfully Configured"), 0x80);
|
||||||
#endif
|
#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
|
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;
|
l2cap_state = TURN_ON_LED;
|
||||||
} else
|
} else
|
||||||
|
@ -470,18 +466,18 @@ void PS3BT::Run() {
|
||||||
|
|
||||||
case TURN_ON_LED:
|
case TURN_ON_LED:
|
||||||
if(millis() - timer > 1000) { // loop 1 second before sending the command
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n"), 0x80);
|
Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
PS3Connected = true;
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nNavigation Controller Enabled\r\n"), 0x80);
|
Notify(PSTR("\r\nNavigation Controller Enabled\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
PS3NavigationConnected = true;
|
PS3NavigationConnected = true;
|
||||||
} else if(remote_name[0] == 'M') { // First letter in Motion Controller ('M')
|
} else if(remote_name_first == 'M') { // First letter in Motion Controller ('M')
|
||||||
timerBulbRumble = millis();
|
timer = millis();
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nMotion Controller Enabled\r\n"), 0x80);
|
Notify(PSTR("\r\nMotion Controller Enabled\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -497,10 +493,10 @@ void PS3BT::Run() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_DONE:
|
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(PS3MoveConnected) { // The Bulb and rumble values, has to be send at approximately every 5th second for it to stay on
|
||||||
if(millis() - timerBulbRumble > 4000) { // Send at least every 4th second
|
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
|
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;
|
break;
|
||||||
|
|
47
PS3BT.h
47
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);
|
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 */
|
/** @name BluetoothService implementation */
|
||||||
/**
|
|
||||||
* Used to pass acldata to the services.
|
|
||||||
* @param ACLData Incoming acldata.
|
|
||||||
*/
|
|
||||||
virtual void ACLData(uint8_t* ACLData);
|
|
||||||
/** Used to run part of the state machine. */
|
|
||||||
virtual void Run();
|
|
||||||
/** Use this to reset the service. */
|
|
||||||
virtual void Reset();
|
|
||||||
/** Used this to disconnect any of the controllers. */
|
/** Used this to disconnect any of the controllers. */
|
||||||
virtual void disconnect();
|
virtual void disconnect();
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
@ -183,14 +174,6 @@ public:
|
||||||
uint32_t getLastMessageTime() {
|
uint32_t getLastMessageTime() {
|
||||||
return lastMessageTime;
|
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. */
|
/** 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. */
|
/** Variable used to indicate if the Navigation controller is successfully connected. */
|
||||||
bool PS3NavigationConnected;
|
bool PS3NavigationConnected;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
/* Mandatory members */
|
/** @name BluetoothService implementation */
|
||||||
BTD *pBtd;
|
/**
|
||||||
|
* Used to pass acldata to the services.
|
||||||
|
* @param ACLData Incoming acldata.
|
||||||
|
*/
|
||||||
|
virtual void ACLData(uint8_t* ACLData);
|
||||||
|
/** Used to run part of the state machine. */
|
||||||
|
virtual void Run();
|
||||||
|
/** Use this to reset the service. */
|
||||||
|
virtual void Reset();
|
||||||
/**
|
/**
|
||||||
* Called when the controller is successfully initialized.
|
* Called when the controller is successfully initialized.
|
||||||
* Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
|
* 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.
|
* This is useful for instance if you want to set the LEDs in a specific way.
|
||||||
*/
|
*/
|
||||||
void onInit();
|
virtual void onInit();
|
||||||
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
/**@}*/
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
void L2CAP_task(); // L2CAP state machine
|
void L2CAP_task(); // L2CAP state machine
|
||||||
|
|
||||||
/* Variables filled from HCI event management */
|
/* Variables filled from HCI event management */
|
||||||
int16_t hci_handle;
|
char remote_name_first; // First letter in remote name
|
||||||
uint8_t remote_name[30]; // First 30 chars of remote name
|
|
||||||
bool activeConnection; // Used to indicate if it's already has established a connection
|
bool activeConnection; // Used to indicate if it's already has established a connection
|
||||||
|
|
||||||
/* Variables used by high level L2CAP task */
|
/* Variables used by high level L2CAP task */
|
||||||
uint8_t l2cap_state;
|
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.
|
uint32_t lastMessageTime; // Variable used to store the millis value of the last message.
|
||||||
|
|
||||||
unsigned long timer;
|
|
||||||
|
|
||||||
uint32_t ButtonState;
|
uint32_t ButtonState;
|
||||||
uint32_t OldButtonState;
|
uint32_t OldButtonState;
|
||||||
uint32_t ButtonClickState;
|
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 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 l2capinbuf[BULK_MAXPKTSIZE]; // General purpose buffer for L2CAP in data
|
||||||
uint8_t HIDBuffer[HID_BUFFERSIZE]; // Used to store HID commands
|
uint8_t HIDBuffer[HID_BUFFERSIZE]; // Used to store HID commands
|
||||||
|
@ -243,7 +231,6 @@ private:
|
||||||
uint8_t control_dcid[2]; // 0x0040
|
uint8_t control_dcid[2]; // 0x0040
|
||||||
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
|
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
|
||||||
uint8_t interrupt_dcid[2]; // 0x0041
|
uint8_t interrupt_dcid[2]; // 0x0041
|
||||||
uint8_t identifier; // Identifier for connection
|
|
||||||
|
|
||||||
/* HID Commands */
|
/* HID Commands */
|
||||||
void HID_Command(uint8_t* data, uint8_t nbytes);
|
void HID_Command(uint8_t* data, uint8_t nbytes);
|
||||||
|
|
8
PS3USB.h
8
PS3USB.h
|
@ -19,6 +19,7 @@
|
||||||
#define _ps3usb_h_
|
#define _ps3usb_h_
|
||||||
|
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
#include "Hid.h"
|
||||||
#include "PS3Enums.h"
|
#include "PS3Enums.h"
|
||||||
|
|
||||||
/* PS3 data taken from descriptors */
|
/* PS3 data taken from descriptors */
|
||||||
|
@ -35,13 +36,6 @@
|
||||||
#define PS3NAVIGATION_PID 0x042F // Navigation controller
|
#define PS3NAVIGATION_PID 0x042F // Navigation controller
|
||||||
#define PS3MOVE_PID 0x03D5 // Motion 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
|
#define PS3_MAX_ENDPOINTS 3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
10
PS4BT.h
10
PS4BT.h
|
@ -46,14 +46,6 @@ public:
|
||||||
return BTHID::connected;
|
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:
|
protected:
|
||||||
/** @name BTHID implementation */
|
/** @name BTHID implementation */
|
||||||
/**
|
/**
|
||||||
|
@ -125,7 +117,5 @@ private:
|
||||||
void HID_Command(uint8_t *data, uint8_t nbytes) {
|
void HID_Command(uint8_t *data, uint8_t nbytes) {
|
||||||
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
|
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
|
||||||
};
|
};
|
||||||
|
|
||||||
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
|
@ -78,5 +78,5 @@ void PSBuzz::setLedRaw(bool value, uint8_t controller) {
|
||||||
|
|
||||||
void PSBuzz::PSBuzz_Command(uint8_t *data, uint16_t nbytes) {
|
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)
|
// 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);
|
pUsb->ctrlReq(bAddress, epInfo[0].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
|
||||||
};
|
};
|
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) :
|
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->btdName = name;
|
||||||
pBtd->btdPin = pin;
|
pBtd->btdPin = pin;
|
||||||
|
|
||||||
|
@ -69,6 +66,7 @@ void SPP::Reset() {
|
||||||
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT;
|
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT;
|
||||||
l2cap_event_flag = 0;
|
l2cap_event_flag = 0;
|
||||||
sppIndex = 0;
|
sppIndex = 0;
|
||||||
|
creditSent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPP::disconnect() {
|
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(checkHciHandle(l2capinbuf, hci_handle)) { // acl_handle_ok
|
||||||
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) {
|
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
||||||
|
@ -397,10 +395,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nRFCOMM Connection is now established\r\n"), 0x80);
|
Notify(PSTR("\r\nRFCOMM Connection is now established\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
waitForLastCommand = false;
|
onInit();
|
||||||
creditSent = false;
|
|
||||||
connected = true; // The RFCOMM channel is now established
|
|
||||||
sppIndex = 0;
|
|
||||||
}
|
}
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
else if(rfcommChannelType != RFCOMM_DISC) {
|
else if(rfcommChannelType != RFCOMM_DISC) {
|
||||||
|
@ -430,14 +425,20 @@ void SPP::Run() {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"), 0x80);
|
Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
creditSent = false;
|
onInit();
|
||||||
waitForLastCommand = false;
|
|
||||||
connected = true; // The RFCOMM channel is now established
|
|
||||||
sppIndex = 0;
|
|
||||||
}
|
}
|
||||||
send(); // Send all bytes currently in the buffer
|
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() {
|
void SPP::SDP_task() {
|
||||||
switch(l2cap_sdp_state) {
|
switch(l2cap_sdp_state) {
|
||||||
case L2CAP_SDP_WAIT:
|
case L2CAP_SDP_WAIT:
|
||||||
|
|
47
SPP.h
47
SPP.h
|
@ -68,6 +68,11 @@ public:
|
||||||
*/
|
*/
|
||||||
SPP(BTD *p, const char *name = "Arduino", const char *pin = "0000");
|
SPP(BTD *p, const char *name = "Arduino", const char *pin = "0000");
|
||||||
|
|
||||||
|
/** @name BluetoothService implementation */
|
||||||
|
/** Used this to disconnect the virtual serial port. */
|
||||||
|
virtual void disconnect();
|
||||||
|
/**@}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to provide Boolean tests for the class.
|
* Used to provide Boolean tests for the class.
|
||||||
* @return Return true if SPP communication is connected.
|
* @return Return true if SPP communication is connected.
|
||||||
|
@ -78,20 +83,6 @@ public:
|
||||||
/** Variable used to indicate if the connection is established. */
|
/** Variable used to indicate if the connection is established. */
|
||||||
bool connected;
|
bool connected;
|
||||||
|
|
||||||
/** @name BluetoothService implementation */
|
|
||||||
/**
|
|
||||||
* Used to pass acldata to the services.
|
|
||||||
* @param ACLData Incoming acldata.
|
|
||||||
*/
|
|
||||||
virtual void ACLData(uint8_t* ACLData);
|
|
||||||
/** Used to establish the connection automatically. */
|
|
||||||
virtual void Run();
|
|
||||||
/** Use this to reset the service. */
|
|
||||||
virtual void Reset();
|
|
||||||
/** Used this to disconnect the virtual serial port. */
|
|
||||||
virtual void disconnect();
|
|
||||||
/**@}*/
|
|
||||||
|
|
||||||
/** @name Serial port profile (SPP) Print functions */
|
/** @name Serial port profile (SPP) Print functions */
|
||||||
/**
|
/**
|
||||||
* Get number of bytes waiting to be read.
|
* Get number of bytes waiting to be read.
|
||||||
|
@ -154,20 +145,33 @@ public:
|
||||||
void send(void);
|
void send(void);
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
/* Bluetooth dongle library pointer */
|
/** @name BluetoothService implementation */
|
||||||
BTD *pBtd;
|
/**
|
||||||
|
* Used to pass acldata to the services.
|
||||||
|
* @param ACLData Incoming acldata.
|
||||||
|
*/
|
||||||
|
virtual void ACLData(uint8_t* ACLData);
|
||||||
|
/** Used to establish the connection automatically. */
|
||||||
|
virtual void Run();
|
||||||
|
/** Use this to reset the service. */
|
||||||
|
virtual 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.
|
||||||
|
*/
|
||||||
|
virtual void onInit();
|
||||||
|
/**@}*/
|
||||||
|
|
||||||
|
private:
|
||||||
/* Set true when a channel is created */
|
/* Set true when a channel is created */
|
||||||
bool SDPConnected;
|
bool SDPConnected;
|
||||||
bool RFCOMMConnected;
|
bool RFCOMMConnected;
|
||||||
|
|
||||||
uint16_t hci_handle; // The HCI Handle for the connection
|
|
||||||
|
|
||||||
/* Variables used by L2CAP state machines */
|
/* Variables used by L2CAP state machines */
|
||||||
uint8_t l2cap_sdp_state;
|
uint8_t l2cap_sdp_state;
|
||||||
uint8_t l2cap_rfcomm_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 l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
|
||||||
uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
|
uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
|
||||||
|
@ -177,7 +181,6 @@ private:
|
||||||
uint8_t sdp_dcid[2]; // 0x0050
|
uint8_t sdp_dcid[2]; // 0x0050
|
||||||
uint8_t rfcomm_scid[2]; // L2CAP source CID for RFCOMM
|
uint8_t rfcomm_scid[2]; // L2CAP source CID for RFCOMM
|
||||||
uint8_t rfcomm_dcid[2]; // 0x0051
|
uint8_t rfcomm_dcid[2]; // 0x0051
|
||||||
uint8_t identifier; // Identifier for command
|
|
||||||
|
|
||||||
/* RFCOMM Variables */
|
/* RFCOMM Variables */
|
||||||
uint8_t rfcommChannel;
|
uint8_t rfcommChannel;
|
||||||
|
@ -187,7 +190,7 @@ private:
|
||||||
uint8_t rfcommChannelType;
|
uint8_t rfcommChannelType;
|
||||||
uint8_t rfcommPfBit;
|
uint8_t rfcommPfBit;
|
||||||
|
|
||||||
unsigned long timer;
|
uint32_t timer;
|
||||||
bool waitForLastCommand;
|
bool waitForLastCommand;
|
||||||
bool creditSent;
|
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) :
|
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;
|
pBtd->pairWithWii = pair;
|
||||||
|
|
||||||
HIDBuffer[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
HIDBuffer[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
||||||
|
|
||||||
/* Set device cid for the control and intterrupt channelse - LSB */
|
/* Set device cid for the control and intterrupt channelse - LSB */
|
||||||
control_dcid[0] = 0x60; //0x0060
|
control_dcid[0] = 0x60; // 0x0060
|
||||||
control_dcid[1] = 0x00;
|
control_dcid[1] = 0x00;
|
||||||
interrupt_dcid[0] = 0x61; //0x0061
|
interrupt_dcid[0] = 0x61; // 0x0061
|
||||||
interrupt_dcid[1] = 0x00;
|
interrupt_dcid[1] = 0x00;
|
||||||
|
|
||||||
Reset();
|
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(checkHciHandle(l2capinbuf, hci_handle)) { // acl_handle_ok
|
||||||
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) {
|
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
||||||
|
|
42
Wii.h
42
Wii.h
|
@ -55,15 +55,6 @@ public:
|
||||||
WII(BTD *p, bool pair = false);
|
WII(BTD *p, bool pair = false);
|
||||||
|
|
||||||
/** @name BluetoothService implementation */
|
/** @name BluetoothService implementation */
|
||||||
/**
|
|
||||||
* Used to pass acldata to the services.
|
|
||||||
* @param ACLData Incoming acldata.
|
|
||||||
*/
|
|
||||||
virtual void ACLData(uint8_t* ACLData);
|
|
||||||
/** Used to run part of the state machine. */
|
|
||||||
virtual void Run();
|
|
||||||
/** Use this to reset the service. */
|
|
||||||
virtual void Reset();
|
|
||||||
/** Used this to disconnect any of the controllers. */
|
/** Used this to disconnect any of the controllers. */
|
||||||
virtual void disconnect();
|
virtual void disconnect();
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
@ -189,14 +180,6 @@ public:
|
||||||
uint8_t getWiiState() {
|
uint8_t getWiiState() {
|
||||||
return wiiState;
|
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
|
#endif
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
BTD *pBtd; // Pointer to BTD instance
|
/** @name BluetoothService implementation */
|
||||||
|
/**
|
||||||
|
* Used to pass acldata to the services.
|
||||||
|
* @param ACLData Incoming acldata.
|
||||||
|
*/
|
||||||
|
virtual void ACLData(uint8_t* ACLData);
|
||||||
|
/** Used to run part of the state machine. */
|
||||||
|
virtual void Run();
|
||||||
|
/** Use this to reset the service. */
|
||||||
|
virtual void Reset();
|
||||||
/**
|
/**
|
||||||
* Called when the controller is successfully initialized.
|
* Called when the controller is successfully initialized.
|
||||||
* Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
|
* 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.
|
* This is useful for instance if you want to set the LEDs in a specific way.
|
||||||
*/
|
*/
|
||||||
void onInit();
|
virtual void onInit();
|
||||||
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
/**@}*/
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
void L2CAP_task(); // L2CAP state machine
|
void L2CAP_task(); // L2CAP state machine
|
||||||
|
|
||||||
/* Variables filled from HCI event management */
|
/* Variables filled from HCI event management */
|
||||||
uint16_t hci_handle;
|
|
||||||
bool activeConnection; // Used to indicate if it's already has established a connection
|
bool activeConnection; // Used to indicate if it's already has established a connection
|
||||||
|
|
||||||
/* Variables used by high level L2CAP task */
|
/* Variables used by high level L2CAP task */
|
||||||
uint8_t l2cap_state;
|
uint8_t l2cap_state;
|
||||||
uint32_t l2cap_event_flag; // L2CAP flags of received Bluetooth events
|
|
||||||
uint8_t wii_event_flag; // Used for Wii flags
|
uint8_t wii_event_flag; // Used for Wii flags
|
||||||
|
|
||||||
uint32_t ButtonState;
|
uint32_t ButtonState;
|
||||||
|
@ -432,7 +423,6 @@ private:
|
||||||
uint8_t control_dcid[2]; // 0x0060
|
uint8_t control_dcid[2]; // 0x0060
|
||||||
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
|
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
|
||||||
uint8_t interrupt_dcid[2]; // 0x0061
|
uint8_t interrupt_dcid[2]; // 0x0061
|
||||||
uint8_t identifier; // Identifier for connection
|
|
||||||
|
|
||||||
/* HID Commands */
|
/* HID Commands */
|
||||||
void HID_Command(uint8_t* data, uint8_t nbytes);
|
void HID_Command(uint8_t* data, uint8_t nbytes);
|
||||||
|
@ -457,7 +447,7 @@ private:
|
||||||
|
|
||||||
bool activateNunchuck;
|
bool activateNunchuck;
|
||||||
bool motionValuesReset; // This bool is true when the gyro values has been reset
|
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 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;
|
uint8_t batteryLevel;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define _xboxold_h_
|
#define _xboxold_h_
|
||||||
|
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
#include "Hid.h"
|
||||||
#include "controllerEnums.h"
|
#include "controllerEnums.h"
|
||||||
|
|
||||||
/* Data Xbox taken from descriptors */
|
/* Data Xbox taken from descriptors */
|
||||||
|
@ -39,10 +40,6 @@
|
||||||
#define XBOX_OLD_PID3 0x0287 // Microsoft Microsoft Xbox Controller S
|
#define XBOX_OLD_PID3 0x0287 // Microsoft Microsoft Xbox Controller S
|
||||||
#define XBOX_OLD_PID4 0x0289 // Smaller Microsoft Xbox controller (US)
|
#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
|
#define XBOX_MAX_ENDPOINTS 3
|
||||||
|
|
||||||
/** This class implements support for a the original Xbox controller via USB. */
|
/** This class implements support for a the original Xbox controller via USB. */
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define _xboxusb_h_
|
#define _xboxusb_h_
|
||||||
|
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
#include "Hid.h"
|
||||||
#include "xboxEnums.h"
|
#include "xboxEnums.h"
|
||||||
|
|
||||||
/* Data Xbox 360 taken from descriptors */
|
/* Data Xbox 360 taken from descriptors */
|
||||||
|
@ -45,10 +46,6 @@
|
||||||
|
|
||||||
#define XBOX_REPORT_BUFFER_SIZE 14 // Size of the input report buffer
|
#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
|
#define XBOX_MAX_ENDPOINTS 3
|
||||||
|
|
||||||
/** This class implements support for a Xbox wired controller via USB. */
|
/** This class implements support for a Xbox wired controller via USB. */
|
||||||
|
|
16
hid.cpp
16
hid.cpp
|
@ -24,7 +24,7 @@ uint8_t HID::GetReportDescr(uint8_t ep, USBReadParser *parser) {
|
||||||
const uint8_t constBufLen = 64;
|
const uint8_t constBufLen = 64;
|
||||||
uint8_t buf[constBufLen];
|
uint8_t buf[constBufLen];
|
||||||
|
|
||||||
uint8_t rcode = pUsb->ctrlReq(bAddress, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00,
|
uint8_t rcode = pUsb->ctrlReq(bAddress, ep, bmREQ_HID_REPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00,
|
||||||
HID_DESCRIPTOR_REPORT, 0x0000, 128, constBufLen, buf, (USBReadParser*)parser);
|
HID_DESCRIPTOR_REPORT, 0x0000, 128, constBufLen, buf, (USBReadParser*)parser);
|
||||||
|
|
||||||
//return ((rcode != hrSTALL) ? rcode : 0);
|
//return ((rcode != hrSTALL) ? rcode : 0);
|
||||||
|
@ -35,7 +35,7 @@ uint8_t HID::GetReportDescr(uint16_t wIndex, USBReadParser *parser) {
|
||||||
const uint8_t constBufLen = 64;
|
const uint8_t constBufLen = 64;
|
||||||
uint8_t buf[constBufLen];
|
uint8_t buf[constBufLen];
|
||||||
|
|
||||||
uint8_t rcode = pUsb->ctrlReq(bAddress, 0x00, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00,
|
uint8_t rcode = pUsb->ctrlReq(bAddress, 0x00, bmREQ_HID_REPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00,
|
||||||
HID_DESCRIPTOR_REPORT, wIndex, 128, constBufLen, buf, (USBReadParser*)parser);
|
HID_DESCRIPTOR_REPORT, wIndex, 128, constBufLen, buf, (USBReadParser*)parser);
|
||||||
|
|
||||||
//return ((rcode != hrSTALL) ? rcode : 0);
|
//return ((rcode != hrSTALL) ? rcode : 0);
|
||||||
|
@ -48,27 +48,27 @@ uint8_t HID::GetReportDescr(uint16_t wIndex, USBReadParser *parser) {
|
||||||
//}
|
//}
|
||||||
|
|
||||||
uint8_t HID::SetReport(uint8_t ep, uint8_t iface, uint8_t report_type, uint8_t report_id, uint16_t nbytes, uint8_t* dataptr) {
|
uint8_t HID::SetReport(uint8_t ep, uint8_t iface, uint8_t report_type, uint8_t report_id, uint16_t nbytes, uint8_t* dataptr) {
|
||||||
return ( pUsb->ctrlReq(bAddress, ep, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, report_id, report_type, iface, nbytes, nbytes, dataptr, NULL));
|
return ( pUsb->ctrlReq(bAddress, ep, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, report_id, report_type, iface, nbytes, nbytes, dataptr, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HID::GetReport(uint8_t ep, uint8_t iface, uint8_t report_type, uint8_t report_id, uint16_t nbytes, uint8_t* dataptr) {
|
uint8_t HID::GetReport(uint8_t ep, uint8_t iface, uint8_t report_type, uint8_t report_id, uint16_t nbytes, uint8_t* dataptr) {
|
||||||
return ( pUsb->ctrlReq(bAddress, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, iface, nbytes, nbytes, dataptr, NULL));
|
return ( pUsb->ctrlReq(bAddress, ep, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, report_id, report_type, iface, nbytes, nbytes, dataptr, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HID::GetIdle(uint8_t iface, uint8_t reportID, uint8_t* dataptr) {
|
uint8_t HID::GetIdle(uint8_t iface, uint8_t reportID, uint8_t* dataptr) {
|
||||||
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_HIDIN, HID_REQUEST_GET_IDLE, reportID, 0, iface, 0x0001, 0x0001, dataptr, NULL));
|
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_HID_IN, HID_REQUEST_GET_IDLE, reportID, 0, iface, 0x0001, 0x0001, dataptr, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HID::SetIdle(uint8_t iface, uint8_t reportID, uint8_t duration) {
|
uint8_t HID::SetIdle(uint8_t iface, uint8_t reportID, uint8_t duration) {
|
||||||
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_HIDOUT, HID_REQUEST_SET_IDLE, reportID, duration, iface, 0x0000, 0x0000, NULL, NULL));
|
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_HID_OUT, HID_REQUEST_SET_IDLE, reportID, duration, iface, 0x0000, 0x0000, NULL, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HID::SetProtocol(uint8_t iface, uint8_t protocol) {
|
uint8_t HID::SetProtocol(uint8_t iface, uint8_t protocol) {
|
||||||
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_HIDOUT, HID_REQUEST_SET_PROTOCOL, protocol, 0x00, iface, 0x0000, 0x0000, NULL, NULL));
|
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_HID_OUT, HID_REQUEST_SET_PROTOCOL, protocol, 0x00, iface, 0x0000, 0x0000, NULL, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HID::GetProtocol(uint8_t iface, uint8_t* dataptr) {
|
uint8_t HID::GetProtocol(uint8_t iface, uint8_t* dataptr) {
|
||||||
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_HIDIN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, iface, 0x0001, 0x0001, dataptr, NULL));
|
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_HID_IN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, iface, 0x0001, 0x0001, dataptr, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HID::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) {
|
void HID::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) {
|
||||||
|
|
6
hid.h
6
hid.h
|
@ -60,9 +60,9 @@ e-mail : support@circuitsathome.com
|
||||||
#define TAG_LOCAL_USAGEMAX 0x20
|
#define TAG_LOCAL_USAGEMAX 0x20
|
||||||
|
|
||||||
/* HID requests */
|
/* HID requests */
|
||||||
#define bmREQ_HIDOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
#define bmREQ_HID_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||||
#define bmREQ_HIDIN USB_SETUP_DEVICE_TO_HOST|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 bmREQ_HIDREPORT USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_INTERFACE
|
#define bmREQ_HID_REPORT USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_INTERFACE
|
||||||
|
|
||||||
/* HID constants. Not part of chapter 9 */
|
/* HID constants. Not part of chapter 9 */
|
||||||
/* Class-Specific Requests */
|
/* Class-Specific Requests */
|
||||||
|
|
|
@ -22,7 +22,7 @@ e-mail : support@circuitsathome.com
|
||||||
#define _Max_LCD_h_
|
#define _Max_LCD_h_
|
||||||
|
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
#include "Print.h"
|
#include <Print.h>
|
||||||
|
|
||||||
// commands
|
// commands
|
||||||
#define LCD_CLEARDISPLAY 0x01
|
#define LCD_CLEARDISPLAY 0x01
|
||||||
|
|
Loading…
Reference in a new issue