mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
dec18-1
This commit is contained in:
commit
94ac0b986a
45 changed files with 2191 additions and 1005 deletions
181
BTD.cpp
181
BTD.cpp
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "BTD.h"
|
#include "BTD.h"
|
||||||
// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h
|
// To enable serial debugging see "settings.h"
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
|
|
||||||
const uint8_t BTD::BTD_CONTROL_PIPE = 0;
|
const uint8_t BTD::BTD_CONTROL_PIPE = 0;
|
||||||
|
@ -27,6 +27,8 @@ const uint8_t BTD::BTD_DATAOUT_PIPE = 3;
|
||||||
BTD::BTD(USB *p) :
|
BTD::BTD(USB *p) :
|
||||||
connectToWii(false),
|
connectToWii(false),
|
||||||
pairWithWii(false),
|
pairWithWii(false),
|
||||||
|
connectToHIDDevice(false),
|
||||||
|
pairWithHIDDevice(false),
|
||||||
pUsb(p), // Pointer to USB class instance - mandatory
|
pUsb(p), // Pointer to USB class instance - mandatory
|
||||||
bAddress(0), // Device address - mandatory
|
bAddress(0), // Device address - mandatory
|
||||||
bNumEP(1), // If config descriptor needs to be parsed
|
bNumEP(1), // If config descriptor needs to be parsed
|
||||||
|
@ -37,7 +39,7 @@ bPollEnable(false) // Don't start polling before dongle is connected
|
||||||
for (uint8_t i = 0; i < BTD_NUMSERVICES; i++)
|
for (uint8_t i = 0; i < BTD_NUMSERVICES; i++)
|
||||||
btService[i] = NULL;
|
btService[i] = NULL;
|
||||||
|
|
||||||
clearAllVariables(); // Set all variables, endpoint structs etc. to default values
|
Initialize(); // Set all variables, endpoint structs etc. to default values
|
||||||
|
|
||||||
if (pUsb) // Register in USB subsystem
|
if (pUsb) // Register in USB subsystem
|
||||||
pUsb->RegisterDeviceClass(this); // Set devConfig[] entry
|
pUsb->RegisterDeviceClass(this); // Set devConfig[] entry
|
||||||
|
@ -50,7 +52,7 @@ uint8_t BTD::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
UsbDevice *p = NULL;
|
UsbDevice *p = NULL;
|
||||||
EpInfo *oldep_ptr = NULL;
|
EpInfo *oldep_ptr = NULL;
|
||||||
|
|
||||||
clearAllVariables(); // Set all variables, endpoint structs etc. to default values
|
Initialize(); // Set all variables, endpoint structs etc. to default values
|
||||||
|
|
||||||
AddressPool &addrPool = pUsb->GetAddressPool(); // Get memory address of USB device address pool
|
AddressPool &addrPool = pUsb->GetAddressPool(); // Get memory address of USB device address pool
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
|
@ -288,7 +290,7 @@ Fail:
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTD::clearAllVariables() {
|
void BTD::Initialize() {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for (i = 0; i < BTD_MAX_ENDPOINTS; i++) {
|
for (i = 0; i < BTD_MAX_ENDPOINTS; i++) {
|
||||||
epInfo[i].epAddr = 0;
|
epInfo[i].epAddr = 0;
|
||||||
|
@ -303,6 +305,8 @@ void BTD::clearAllVariables() {
|
||||||
|
|
||||||
connectToWii = false;
|
connectToWii = false;
|
||||||
incomingWii = false;
|
incomingWii = false;
|
||||||
|
connectToHIDDevice = false;
|
||||||
|
incomingHIDDevice = false;
|
||||||
bAddress = 0; // Clear device address
|
bAddress = 0; // Clear device address
|
||||||
bNumEP = 1; // Must have to be reset to 1
|
bNumEP = 1; // Must have to be reset to 1
|
||||||
qNextPollTime = 0; // Reset next poll time
|
qNextPollTime = 0; // Reset next poll time
|
||||||
|
@ -363,7 +367,7 @@ void BTD::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) {
|
||||||
|
|
||||||
/* Performs a cleanup after failed Init() attempt */
|
/* Performs a cleanup after failed Init() attempt */
|
||||||
uint8_t BTD::Release() {
|
uint8_t BTD::Release() {
|
||||||
clearAllVariables(); // Set all variables, endpoint structs etc. to default values
|
Initialize(); // Set all variables, endpoint structs etc. to default values
|
||||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -402,26 +406,27 @@ void BTD::HCI_event_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_COMMAND_STATUS:
|
case EV_COMMAND_STATUS:
|
||||||
if (hcibuf[2]) { // show status on serial if not OK
|
if (hcibuf[2]) { // Show status on serial if not OK
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHCI Command Failed: "), 0x80);
|
Notify(PSTR("\r\nHCI Command Failed: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (hcibuf[2], 0x80);
|
D_PrintHex<uint8_t > (hcibuf[2], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
|
||||||
D_PrintHex<uint8_t > (hcibuf[4], 0x80);
|
|
||||||
Notify(PSTR(" "), 0x80);
|
|
||||||
D_PrintHex<uint8_t > (hcibuf[5], 0x80);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_INQUIRY_COMPLETE:
|
case EV_INQUIRY_COMPLETE:
|
||||||
if (inquiry_counter >= 5 && pairWithWii) {
|
if (inquiry_counter >= 5 && (pairWithWii || pairWithHIDDevice)) {
|
||||||
inquiry_counter = 0;
|
inquiry_counter = 0;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
if (pairWithWii)
|
||||||
Notify(PSTR("\r\nCouldn't find Wiimote"), 0x80);
|
Notify(PSTR("\r\nCouldn't find Wiimote"), 0x80);
|
||||||
|
else
|
||||||
|
Notify(PSTR("\r\nCouldn't find HID device"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
connectToWii = false;
|
connectToWii = false;
|
||||||
pairWithWii = false;
|
pairWithWii = false;
|
||||||
|
connectToHIDDevice = false;
|
||||||
|
pairWithHIDDevice = false;
|
||||||
hci_state = HCI_SCANNING_STATE;
|
hci_state = HCI_SCANNING_STATE;
|
||||||
}
|
}
|
||||||
inquiry_counter++;
|
inquiry_counter++;
|
||||||
|
@ -434,28 +439,44 @@ void BTD::HCI_event_task() {
|
||||||
Notify(hcibuf[2], 0x80);
|
Notify(hcibuf[2], 0x80);
|
||||||
#endif
|
#endif
|
||||||
for (uint8_t i = 0; i < hcibuf[2]; i++) {
|
for (uint8_t i = 0; i < hcibuf[2]; i++) {
|
||||||
if ((hcibuf[4 + 8 * hcibuf[2] + 3 * i] == 0x04 && hcibuf[5 + 8 * hcibuf[2] + 3 * i] == 0x25 && hcibuf[6 + 8 * hcibuf[2] + 3 * i] == 0x00) || (hcibuf[4 + 8 * hcibuf[2] + 3 * i] == 0x08 && hcibuf[5 + 8 * hcibuf[2] + 3 * i] == 0x05 && hcibuf[6 + 8 * hcibuf[2] + 3 * i] == 0x00)) { // See http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html and http://wiibrew.org/wiki/Wiimote#SDP_information
|
uint8_t offset = 8 * hcibuf[2] + 3 * i;
|
||||||
if (hcibuf[4 + 8 * hcibuf[2] + 3 * i] == 0x08) // Check if it's the new Wiimote with motion plus inside that was detected
|
uint8_t classOfDevice[3];
|
||||||
|
|
||||||
|
for (uint8_t j = 0; j < 3; j++)
|
||||||
|
classOfDevice[j] = hcibuf[j + 4 + offset];
|
||||||
|
|
||||||
|
if (pairWithWii && classOfDevice[2] == 0x00 && (classOfDevice[1] & 0x05) && (classOfDevice[0] & 0x0C)) { // See http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html and http://wiibrew.org/wiki/Wiimote#SDP_information
|
||||||
|
if (classOfDevice[0] & 0x08) // Check if it's the new Wiimote with motion plus inside that was detected
|
||||||
motionPlusInside = true;
|
motionPlusInside = true;
|
||||||
else
|
else
|
||||||
motionPlusInside = false;
|
motionPlusInside = false;
|
||||||
disc_bdaddr[0] = hcibuf[3 + 6 * i];
|
|
||||||
disc_bdaddr[1] = hcibuf[4 + 6 * i];
|
for (uint8_t j = 0; j < 6; j++)
|
||||||
disc_bdaddr[2] = hcibuf[5 + 6 * i];
|
disc_bdaddr[j] = hcibuf[j + 3 + 6 * i];
|
||||||
disc_bdaddr[3] = hcibuf[6 + 6 * i];
|
|
||||||
disc_bdaddr[4] = hcibuf[7 + 6 * i];
|
hci_event_flag |= HCI_FLAG_DEVICE_FOUND;
|
||||||
disc_bdaddr[5] = hcibuf[8 + 6 * i];
|
|
||||||
hci_event_flag |= HCI_FLAG_WII_FOUND;
|
|
||||||
break;
|
break;
|
||||||
|
} else if (pairWithHIDDevice && (classOfDevice[1] & 0x05) && (classOfDevice[0] & 0xC0)) { // Check if it is a mouse or keyboard
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
if (classOfDevice[0] & 0x80)
|
||||||
|
Notify(PSTR("\r\nMouse found"), 0x80);
|
||||||
|
if (classOfDevice[0] & 0x40)
|
||||||
|
Notify(PSTR("\r\nKeyboard found"), 0x80);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (uint8_t j = 0; j < 6; j++)
|
||||||
|
disc_bdaddr[j] = hcibuf[j + 3 + 6 * i];
|
||||||
|
|
||||||
|
hci_event_flag |= HCI_FLAG_DEVICE_FOUND;
|
||||||
}
|
}
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
else {
|
else {
|
||||||
Notify(PSTR("\r\nClass of device: "), 0x80);
|
Notify(PSTR("\r\nClass of device: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (hcibuf[6 + 8 * hcibuf[2] + 3 * i], 0x80);
|
D_PrintHex<uint8_t > (classOfDevice[2], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
D_PrintHex<uint8_t > (hcibuf[5 + 8 * hcibuf[2] + 3 * i], 0x80);
|
D_PrintHex<uint8_t > (classOfDevice[1], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
D_PrintHex<uint8_t > (hcibuf[4 + 8 * hcibuf[2] + 3 * i], 0x80);
|
D_PrintHex<uint8_t > (classOfDevice[0], 0x80);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -465,15 +486,18 @@ void BTD::HCI_event_task() {
|
||||||
case EV_CONNECT_COMPLETE:
|
case EV_CONNECT_COMPLETE:
|
||||||
hci_event_flag |= HCI_FLAG_CONNECT_EVENT;
|
hci_event_flag |= HCI_FLAG_CONNECT_EVENT;
|
||||||
if (!hcibuf[2]) { // check if connected OK
|
if (!hcibuf[2]) { // check if connected OK
|
||||||
|
#ifdef EXTRADEBUG
|
||||||
|
Notify(PSTR("\r\nConnection established"), 0x80);
|
||||||
|
#endif
|
||||||
hci_handle = hcibuf[3] | ((hcibuf[4] & 0x0F) << 8); // store the handle for the ACL connection
|
hci_handle = hcibuf[3] | ((hcibuf[4] & 0x0F) << 8); // store the handle for the ACL connection
|
||||||
hci_event_flag |= HCI_FLAG_CONN_COMPLETE; // set connection complete flag
|
hci_event_flag |= HCI_FLAG_CONN_COMPLETE; // set connection complete flag
|
||||||
}
|
} else {
|
||||||
|
hci_state = HCI_CHECK_DEVICE_SERVICE;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
else {
|
Notify(PSTR("\r\nConnection Failed: "), 0x80);
|
||||||
Notify(PSTR("\r\nConnection Failed"), 0x80);
|
D_PrintHex<uint8_t > (hcibuf[2], 0x80);
|
||||||
hci_state = HCI_CHECK_WII_SERVICE;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_DISCONNECT_COMPLETE:
|
case EV_DISCONNECT_COMPLETE:
|
||||||
|
@ -492,12 +516,19 @@ void BTD::HCI_event_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_INCOMING_CONNECT:
|
case EV_INCOMING_CONNECT:
|
||||||
disc_bdaddr[0] = hcibuf[2];
|
for (uint8_t i = 0; i < 6; i++)
|
||||||
disc_bdaddr[1] = hcibuf[3];
|
disc_bdaddr[i] = hcibuf[i + 2];
|
||||||
disc_bdaddr[2] = hcibuf[4];
|
|
||||||
disc_bdaddr[3] = hcibuf[5];
|
if ((hcibuf[9] & 0x05) && (hcibuf[8] & 0xC0)) { // Check if it is a mouse or keyboard
|
||||||
disc_bdaddr[4] = hcibuf[6];
|
#ifdef DEBUG_USB_HOST
|
||||||
disc_bdaddr[5] = hcibuf[7];
|
if (hcibuf[8] & 0x80)
|
||||||
|
Notify(PSTR("\r\nMouse is connecting"), 0x80);
|
||||||
|
if (hcibuf[8] & 0x40)
|
||||||
|
Notify(PSTR("\r\nKeyboard is connecting"), 0x80);
|
||||||
|
#endif
|
||||||
|
incomingHIDDevice = true;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("\r\nClass of device: "), 0x80);
|
Notify(PSTR("\r\nClass of device: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (hcibuf[10], 0x80);
|
D_PrintHex<uint8_t > (hcibuf[10], 0x80);
|
||||||
|
@ -539,9 +570,14 @@ void BTD::HCI_event_task() {
|
||||||
case EV_AUTHENTICATION_COMPLETE:
|
case EV_AUTHENTICATION_COMPLETE:
|
||||||
if (pairWithWii && !connectToWii) {
|
if (pairWithWii && !connectToWii) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nPairing successful"), 0x80);
|
Notify(PSTR("\r\nPairing successful with Wiimote"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
connectToWii = true; // Only send the ACL data to the Wii service
|
connectToWii = true; // Only send the ACL data to the Wii service
|
||||||
|
} else if (pairWithHIDDevice && !connectToHIDDevice) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nPairing successful with HID device"), 0x80);
|
||||||
|
#endif
|
||||||
|
connectToHIDDevice = true; // Only send the ACL data to the Wii service
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/* We will just ignore the following events */
|
/* We will just ignore the following events */
|
||||||
|
@ -640,7 +676,7 @@ void BTD::HCI_task() {
|
||||||
hci_set_local_name(btdName);
|
hci_set_local_name(btdName);
|
||||||
hci_state = HCI_SET_NAME_STATE;
|
hci_state = HCI_SET_NAME_STATE;
|
||||||
} else
|
} else
|
||||||
hci_state = HCI_CHECK_WII_SERVICE;
|
hci_state = HCI_CHECK_DEVICE_SERVICE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -650,14 +686,17 @@ void BTD::HCI_task() {
|
||||||
Notify(PSTR("\r\nThe name is set to: "), 0x80);
|
Notify(PSTR("\r\nThe name is set to: "), 0x80);
|
||||||
NotifyStr(btdName, 0x80);
|
NotifyStr(btdName, 0x80);
|
||||||
#endif
|
#endif
|
||||||
hci_state = HCI_CHECK_WII_SERVICE;
|
hci_state = HCI_CHECK_DEVICE_SERVICE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_CHECK_WII_SERVICE:
|
case HCI_CHECK_DEVICE_SERVICE:
|
||||||
if (pairWithWii) { // Check if it should try to connect to a wiimote
|
if (pairWithHIDDevice || pairWithWii) { // Check if it should try to connect to a wiimote
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
if (pairWithWii)
|
||||||
Notify(PSTR("\r\nStarting inquiry\r\nPress 1 & 2 on the Wiimote\r\nOr press sync if you are using a Wii U Pro Controller"), 0x80);
|
Notify(PSTR("\r\nStarting inquiry\r\nPress 1 & 2 on the Wiimote\r\nOr press sync if you are using a Wii U Pro Controller"), 0x80);
|
||||||
|
else
|
||||||
|
Notify(PSTR("\r\nPlease enable discovery of your device"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
hci_inquiry();
|
hci_inquiry();
|
||||||
hci_state = HCI_INQUIRY_STATE;
|
hci_state = HCI_INQUIRY_STATE;
|
||||||
|
@ -666,37 +705,55 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_INQUIRY_STATE:
|
case HCI_INQUIRY_STATE:
|
||||||
if (hci_wii_found) {
|
if (hci_device_found) {
|
||||||
hci_inquiry_cancel(); // Stop inquiry
|
hci_inquiry_cancel(); // Stop inquiry
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
if (pairWithWii)
|
||||||
Notify(PSTR("\r\nWiimote found"), 0x80);
|
Notify(PSTR("\r\nWiimote found"), 0x80);
|
||||||
|
else
|
||||||
|
Notify(PSTR("\r\nHID device found"), 0x80);
|
||||||
|
|
||||||
Notify(PSTR("\r\nNow just create the instance like so:"), 0x80);
|
Notify(PSTR("\r\nNow just create the instance like so:"), 0x80);
|
||||||
|
if (pairWithWii)
|
||||||
Notify(PSTR("\r\nWII Wii(&Btd);"), 0x80);
|
Notify(PSTR("\r\nWII Wii(&Btd);"), 0x80);
|
||||||
Notify(PSTR("\r\nAnd then press any button on the Wiimote"), 0x80);
|
else
|
||||||
|
Notify(PSTR("\r\nBTHID hid(&Btd);"), 0x80);
|
||||||
|
|
||||||
|
Notify(PSTR("\r\nAnd then press any button on the "), 0x80);
|
||||||
|
if (pairWithWii)
|
||||||
|
Notify(PSTR("Wiimote"), 0x80);
|
||||||
|
else
|
||||||
|
Notify(PSTR("device"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
if (motionPlusInside) {
|
if (motionPlusInside) {
|
||||||
hci_remote_name(); // We need to know the name to distinguish between a Wiimote and a Wii U Pro Controller
|
hci_remote_name(); // We need to know the name to distinguish between a Wiimote and a Wii U Pro Controller
|
||||||
hci_state = HCI_REMOTE_NAME_STATE;
|
hci_state = HCI_REMOTE_NAME_STATE;
|
||||||
} else
|
} else
|
||||||
hci_state = HCI_CONNECT_WII_STATE;
|
hci_state = HCI_CONNECT_DEVICE_STATE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_CONNECT_WII_STATE:
|
case HCI_CONNECT_DEVICE_STATE:
|
||||||
if (hci_cmd_complete) {
|
if (hci_cmd_complete) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
if (pairWithWii)
|
||||||
Notify(PSTR("\r\nConnecting to Wiimote"), 0x80);
|
Notify(PSTR("\r\nConnecting to Wiimote"), 0x80);
|
||||||
|
else
|
||||||
|
Notify(PSTR("\r\nConnecting to HID device"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
hci_connect();
|
hci_connect();
|
||||||
hci_state = HCI_CONNECTED_WII_STATE;
|
hci_state = HCI_CONNECTED_DEVICE_STATE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_CONNECTED_WII_STATE:
|
case HCI_CONNECTED_DEVICE_STATE:
|
||||||
if (hci_connect_event) {
|
if (hci_connect_event) {
|
||||||
if (hci_connect_complete) {
|
if (hci_connect_complete) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
if (pairWithWii)
|
||||||
Notify(PSTR("\r\nConnected to Wiimote"), 0x80);
|
Notify(PSTR("\r\nConnected to Wiimote"), 0x80);
|
||||||
|
else
|
||||||
|
Notify(PSTR("\r\nConnected to HID device"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
hci_authentication_request(); // This will start the pairing with the wiimote
|
hci_authentication_request(); // This will start the pairing with the wiimote
|
||||||
hci_state = HCI_SCANNING_STATE;
|
hci_state = HCI_SCANNING_STATE;
|
||||||
|
@ -710,7 +767,7 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_SCANNING_STATE:
|
case HCI_SCANNING_STATE:
|
||||||
if (!connectToWii && !pairWithWii) {
|
if (!connectToWii && !pairWithWii && !connectToHIDDevice && !pairWithHIDDevice) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nWait For Incoming Connection Request"), 0x80);
|
Notify(PSTR("\r\nWait For Incoming Connection Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -764,7 +821,7 @@ void BTD::HCI_task() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pairWithWii && motionPlusInside)
|
if (pairWithWii && motionPlusInside)
|
||||||
hci_state = HCI_CONNECT_WII_STATE;
|
hci_state = HCI_CONNECT_DEVICE_STATE;
|
||||||
else {
|
else {
|
||||||
hci_accept_connection();
|
hci_accept_connection();
|
||||||
hci_state = HCI_CONNECTED_STATE;
|
hci_state = HCI_CONNECTED_STATE;
|
||||||
|
@ -817,6 +874,10 @@ void BTD::HCI_task() {
|
||||||
incomingWii = false;
|
incomingWii = false;
|
||||||
pairWithWii = false;
|
pairWithWii = false;
|
||||||
|
|
||||||
|
connectToHIDDevice = false;
|
||||||
|
incomingHIDDevice = false;
|
||||||
|
pairWithHIDDevice = false;
|
||||||
|
|
||||||
hci_state = HCI_SCANNING_STATE;
|
hci_state = HCI_SCANNING_STATE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -948,7 +1009,7 @@ void BTD::hci_set_local_name(const char* name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTD::hci_inquiry() {
|
void BTD::hci_inquiry() {
|
||||||
hci_event_flag &= ~HCI_FLAG_WII_FOUND;
|
hci_event_flag &= ~HCI_FLAG_DEVICE_FOUND;
|
||||||
hcibuf[0] = 0x01;
|
hcibuf[0] = 0x01;
|
||||||
hcibuf[1] = 0x01 << 2; // HCI OGF = 1
|
hcibuf[1] = 0x01 << 2; // HCI OGF = 1
|
||||||
hcibuf[2] = 0x05; // Parameter Total Length = 5
|
hcibuf[2] = 0x05; // Parameter Total Length = 5
|
||||||
|
@ -970,16 +1031,20 @@ void BTD::hci_inquiry_cancel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTD::hci_connect() {
|
void BTD::hci_connect() {
|
||||||
|
hci_connect(disc_bdaddr); // Use last discovered device
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTD::hci_connect(uint8_t *bdaddr) {
|
||||||
hci_event_flag &= ~(HCI_FLAG_CONN_COMPLETE | HCI_FLAG_CONNECT_EVENT);
|
hci_event_flag &= ~(HCI_FLAG_CONN_COMPLETE | HCI_FLAG_CONNECT_EVENT);
|
||||||
hcibuf[0] = 0x05;
|
hcibuf[0] = 0x05;
|
||||||
hcibuf[1] = 0x01 << 2; // HCI OGF = 1
|
hcibuf[1] = 0x01 << 2; // HCI OGF = 1
|
||||||
hcibuf[2] = 0x0D; // parameter Total Length = 13
|
hcibuf[2] = 0x0D; // parameter Total Length = 13
|
||||||
hcibuf[3] = disc_bdaddr[0]; // 6 octet bdaddr
|
hcibuf[3] = bdaddr[0]; // 6 octet bdaddr (LSB)
|
||||||
hcibuf[4] = disc_bdaddr[1];
|
hcibuf[4] = bdaddr[1];
|
||||||
hcibuf[5] = disc_bdaddr[2];
|
hcibuf[5] = bdaddr[2];
|
||||||
hcibuf[6] = disc_bdaddr[3];
|
hcibuf[6] = bdaddr[3];
|
||||||
hcibuf[7] = disc_bdaddr[4];
|
hcibuf[7] = bdaddr[4];
|
||||||
hcibuf[8] = disc_bdaddr[5];
|
hcibuf[8] = bdaddr[5];
|
||||||
hcibuf[9] = 0x18; // DM1 or DH1 may be used
|
hcibuf[9] = 0x18; // DM1 or DH1 may be used
|
||||||
hcibuf[10] = 0xCC; // DM3, DH3, DM5, DH5 may be used
|
hcibuf[10] = 0xCC; // DM3, DH3, DM5, DH5 may be used
|
||||||
hcibuf[11] = 0x01; // Page repetition mode R1
|
hcibuf[11] = 0x01; // Page repetition mode R1
|
||||||
|
@ -1078,7 +1143,7 @@ void BTD::hci_disconnect(uint16_t handle) { // This is called by the different s
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTD::hci_write_class_of_device() { // See http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html
|
void BTD::hci_write_class_of_device() { // See http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html
|
||||||
hcibuf[0] = 0x24; // HCI OCF = 3
|
hcibuf[0] = 0x24; // HCI OCF = 24
|
||||||
hcibuf[1] = 0x03 << 2; // HCI OGF = 3
|
hcibuf[1] = 0x03 << 2; // HCI OGF = 3
|
||||||
hcibuf[2] = 0x03; // parameter length = 3
|
hcibuf[2] = 0x03; // parameter length = 3
|
||||||
hcibuf[3] = 0x04; // Robot
|
hcibuf[3] = 0x04; // Robot
|
||||||
|
@ -1258,9 +1323,9 @@ void BTD::setBdaddr(uint8_t* bdaddr) {
|
||||||
buf[1] = 0x00;
|
buf[1] = 0x00;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
for (uint8_t i = 0; i < 6; i++)
|
||||||
buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed
|
buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first
|
||||||
|
|
||||||
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
|
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
||||||
pUsb->ctrlReq(bAddress, epInfo[BTD_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
|
pUsb->ctrlReq(bAddress, epInfo[BTD_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1276,6 +1341,6 @@ void BTD::setMoveBdaddr(uint8_t* bdaddr) {
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
for (uint8_t i = 0; i < 6; i++)
|
||||||
buf[i + 1] = bdaddr[i];
|
buf[i + 1] = bdaddr[i];
|
||||||
|
|
||||||
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
|
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
||||||
pUsb->ctrlReq(bAddress, epInfo[BTD_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL);
|
pUsb->ctrlReq(bAddress, epInfo[BTD_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL);
|
||||||
}
|
}
|
||||||
|
|
45
BTD.h
45
BTD.h
|
@ -45,11 +45,11 @@
|
||||||
#define HCI_BDADDR_STATE 3
|
#define HCI_BDADDR_STATE 3
|
||||||
#define HCI_LOCAL_VERSION_STATE 4
|
#define HCI_LOCAL_VERSION_STATE 4
|
||||||
#define HCI_SET_NAME_STATE 5
|
#define HCI_SET_NAME_STATE 5
|
||||||
#define HCI_CHECK_WII_SERVICE 6
|
#define HCI_CHECK_DEVICE_SERVICE 6
|
||||||
|
|
||||||
#define HCI_INQUIRY_STATE 7 // These three states are only used if it should pair and connect to a Wii controller
|
#define HCI_INQUIRY_STATE 7 // These three states are only used if it should pair and connect to a Wii controller
|
||||||
#define HCI_CONNECT_WII_STATE 8
|
#define HCI_CONNECT_DEVICE_STATE 8
|
||||||
#define HCI_CONNECTED_WII_STATE 9
|
#define HCI_CONNECTED_DEVICE_STATE 9
|
||||||
|
|
||||||
#define HCI_SCANNING_STATE 10
|
#define HCI_SCANNING_STATE 10
|
||||||
#define HCI_CONNECT_IN_STATE 11
|
#define HCI_CONNECT_IN_STATE 11
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
#define HCI_FLAG_INCOMING_REQUEST 0x10
|
#define HCI_FLAG_INCOMING_REQUEST 0x10
|
||||||
#define HCI_FLAG_READ_BDADDR 0x20
|
#define HCI_FLAG_READ_BDADDR 0x20
|
||||||
#define HCI_FLAG_READ_VERSION 0x40
|
#define HCI_FLAG_READ_VERSION 0x40
|
||||||
#define HCI_FLAG_WII_FOUND 0x80
|
#define HCI_FLAG_DEVICE_FOUND 0x80
|
||||||
#define HCI_FLAG_CONNECT_EVENT 0x100
|
#define HCI_FLAG_CONNECT_EVENT 0x100
|
||||||
|
|
||||||
/*Macros for HCI event flag tests */
|
/*Macros for HCI event flag tests */
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
#define hci_incoming_connect_request (hci_event_flag & HCI_FLAG_INCOMING_REQUEST)
|
#define hci_incoming_connect_request (hci_event_flag & HCI_FLAG_INCOMING_REQUEST)
|
||||||
#define hci_read_bdaddr_complete (hci_event_flag & HCI_FLAG_READ_BDADDR)
|
#define hci_read_bdaddr_complete (hci_event_flag & HCI_FLAG_READ_BDADDR)
|
||||||
#define hci_read_version_complete (hci_event_flag & HCI_FLAG_READ_VERSION)
|
#define hci_read_version_complete (hci_event_flag & HCI_FLAG_READ_VERSION)
|
||||||
#define hci_wii_found (hci_event_flag & HCI_FLAG_WII_FOUND)
|
#define hci_device_found (hci_event_flag & HCI_FLAG_DEVICE_FOUND)
|
||||||
#define hci_connect_event (hci_event_flag & HCI_FLAG_CONNECT_EVENT)
|
#define hci_connect_event (hci_event_flag & HCI_FLAG_CONNECT_EVENT)
|
||||||
|
|
||||||
/* HCI Events managed */
|
/* HCI Events managed */
|
||||||
|
@ -133,6 +133,8 @@
|
||||||
#define BTD_MAX_ENDPOINTS 4
|
#define BTD_MAX_ENDPOINTS 4
|
||||||
#define BTD_NUMSERVICES 4 // Max number of Bluetooth services - if you need more than four simply increase this number
|
#define BTD_NUMSERVICES 4 // Max number of Bluetooth services - if you need more than four simply increase this number
|
||||||
|
|
||||||
|
#define PAIR 1
|
||||||
|
|
||||||
/** All Bluetooth services should include this class. */
|
/** All Bluetooth services should include this class. */
|
||||||
class BluetoothService {
|
class BluetoothService {
|
||||||
public:
|
public:
|
||||||
|
@ -219,7 +221,13 @@ public:
|
||||||
* @return Returns true if the device's VID and PID matches this driver.
|
* @return Returns true if the device's VID and PID matches this driver.
|
||||||
*/
|
*/
|
||||||
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) {
|
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) {
|
||||||
return ((vid == PS3_VID || vid == IOGEAR_GBU521_VID) && (pid == PS3_PID || pid == PS3NAVIGATION_PID || pid == PS3MOVE_PID || pid == IOGEAR_GBU521_PID));
|
if (vid == IOGEAR_GBU521_VID && pid == IOGEAR_GBU521_PID)
|
||||||
|
return true;
|
||||||
|
if (my_bdaddr[0] != 0x00 || my_bdaddr[1] != 0x00 || my_bdaddr[2] != 0x00 || my_bdaddr[3] != 0x00 || my_bdaddr[4] != 0x00 || my_bdaddr[5] != 0x00) { // Check if Bluetooth address is set
|
||||||
|
if (vid == PS3_VID && (pid == PS3_PID || pid == PS3NAVIGATION_PID || pid == PS3MOVE_PID))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
|
@ -307,8 +315,13 @@ public:
|
||||||
void hci_inquiry();
|
void hci_inquiry();
|
||||||
/** Cancel a HCI inquiry. */
|
/** Cancel a HCI inquiry. */
|
||||||
void hci_inquiry_cancel();
|
void hci_inquiry_cancel();
|
||||||
/** Connect to a device. */
|
/** Connect to last device communicated with. */
|
||||||
void hci_connect();
|
void hci_connect();
|
||||||
|
/**
|
||||||
|
* Connect to device.
|
||||||
|
* @param bdaddr Bluetooth address of the device.
|
||||||
|
*/
|
||||||
|
void hci_connect(uint8_t *bdaddr);
|
||||||
/** Used to a set the class of the device. */
|
/** Used to a set the class of the device. */
|
||||||
void hci_write_class_of_device();
|
void hci_write_class_of_device();
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
@ -411,19 +424,31 @@ public:
|
||||||
/** Call this function to pair with a Wiimote */
|
/** Call this function to pair with a Wiimote */
|
||||||
void pairWithWiimote() {
|
void pairWithWiimote() {
|
||||||
pairWithWii = true;
|
pairWithWii = true;
|
||||||
hci_state = HCI_CHECK_WII_SERVICE;
|
hci_state = HCI_CHECK_DEVICE_SERVICE;
|
||||||
};
|
};
|
||||||
/** Used to only send the ACL data to the wiimote. */
|
/** Used to only send the ACL data to the wiimote. */
|
||||||
bool connectToWii;
|
bool connectToWii;
|
||||||
/** True if a Wiimote is connecting. */
|
/** True if a Wiimote is connecting. */
|
||||||
bool incomingWii;
|
bool incomingWii;
|
||||||
/** True when it should pair with the incoming Wiimote. */
|
/** True when it should pair with a Wiimote. */
|
||||||
bool pairWithWii;
|
bool pairWithWii;
|
||||||
/** True if it's the new Wiimote with the Motion Plus Inside or a Wii U Pro Controller. */
|
/** True if it's the new Wiimote with the Motion Plus Inside or a Wii U Pro Controller. */
|
||||||
bool motionPlusInside;
|
bool motionPlusInside;
|
||||||
/** True if it's a Wii U Pro Controller. */
|
/** True if it's a Wii U Pro Controller. */
|
||||||
bool wiiUProController;
|
bool wiiUProController;
|
||||||
|
|
||||||
|
/** Call this function to pair with a Wiimote */
|
||||||
|
void pairWithHID() {
|
||||||
|
pairWithHIDDevice = true;
|
||||||
|
hci_state = HCI_CHECK_DEVICE_SERVICE;
|
||||||
|
};
|
||||||
|
/** Used to only send the ACL data to the wiimote. */
|
||||||
|
bool connectToHIDDevice;
|
||||||
|
/** True if a Wiimote is connecting. */
|
||||||
|
bool incomingHIDDevice;
|
||||||
|
/** True when it should pair with a device like a mouse or keyboard. */
|
||||||
|
bool pairWithHIDDevice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the poll interval taken from the endpoint descriptors.
|
* Read the poll interval taken from the endpoint descriptors.
|
||||||
* @return The poll interval in ms.
|
* @return The poll interval in ms.
|
||||||
|
@ -463,7 +488,7 @@ protected:
|
||||||
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
|
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void clearAllVariables(); // Set all variables, endpoint structs etc. to default values
|
void Initialize(); // Set all variables, endpoint structs etc. to default values
|
||||||
BluetoothService* btService[BTD_NUMSERVICES];
|
BluetoothService* btService[BTD_NUMSERVICES];
|
||||||
|
|
||||||
uint16_t PID, VID; // PID and VID of device connected
|
uint16_t PID, VID; // PID and VID of device connected
|
||||||
|
|
404
BTHID.cpp
Normal file
404
BTHID.cpp
Normal file
|
@ -0,0 +1,404 @@
|
||||||
|
/* Copyright (C) 2013 Kristian Lauszus, TKJ Electronics. All rights reserved.
|
||||||
|
|
||||||
|
This software may be distributed and modified under the terms of the GNU
|
||||||
|
General Public License version 2 (GPL2) as published by the Free Software
|
||||||
|
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||||
|
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||||
|
on this software must also be made publicly available under the terms of
|
||||||
|
the GPL2 ("Copyleft").
|
||||||
|
|
||||||
|
Contact information
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Kristian Lauszus, TKJ Electronics
|
||||||
|
Web : http://www.tkjelectronics.com
|
||||||
|
e-mail : kristianl@tkjelectronics.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "BTHID.h"
|
||||||
|
// To enable serial debugging see "settings.h"
|
||||||
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
|
//#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
|
||||||
|
protocolMode(HID_BOOT_PROTOCOL)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < epMUL; i++)
|
||||||
|
pRptParser[i] = NULL;
|
||||||
|
|
||||||
|
if (pBtd)
|
||||||
|
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
||||||
|
|
||||||
|
pBtd->pairWithHIDDevice = pair;
|
||||||
|
|
||||||
|
if (pair)
|
||||||
|
pBtd->btdPin= pin;
|
||||||
|
|
||||||
|
/* Set device cid for the control and intterrupt channelse - LSB */
|
||||||
|
control_dcid[0] = 0x70; // 0x0070
|
||||||
|
control_dcid[1] = 0x00;
|
||||||
|
interrupt_dcid[0] = 0x71; // 0x0071
|
||||||
|
interrupt_dcid[1] = 0x00;
|
||||||
|
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTHID::Reset() {
|
||||||
|
connected = false;
|
||||||
|
activeConnection = false;
|
||||||
|
l2cap_event_flag = 0; // Reset flags
|
||||||
|
l2cap_state = L2CAP_WAIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTHID::disconnect() { // Use this void to disconnect any of the controllers
|
||||||
|
// First the HID interrupt channel has to be disconnected, then the HID control channel and finally the HCI connection
|
||||||
|
pBtd->l2cap_disconnection_request(hci_handle, 0x0A, interrupt_scid, interrupt_dcid);
|
||||||
|
Reset();
|
||||||
|
l2cap_state = L2CAP_INTERRUPT_DISCONNECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTHID::ACLData(uint8_t* l2capinbuf) {
|
||||||
|
if (!pBtd->l2capConnectionClaimed && pBtd->incomingHIDDevice && !connected && !activeConnection) {
|
||||||
|
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||||
|
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
|
||||||
|
pBtd->incomingHIDDevice = false;
|
||||||
|
pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service
|
||||||
|
activeConnection = true;
|
||||||
|
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
||||||
|
l2cap_state = L2CAP_WAIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000)) { // acl_handle_ok or it's a new connection
|
||||||
|
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { // 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);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
||||||
|
#endif
|
||||||
|
} else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) {
|
||||||
|
if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success
|
||||||
|
if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) {
|
||||||
|
//Notify(PSTR("\r\nHID Control Connection Complete"), 0x80);
|
||||||
|
identifier = l2capinbuf[9];
|
||||||
|
control_scid[0] = l2capinbuf[12];
|
||||||
|
control_scid[1] = l2capinbuf[13];
|
||||||
|
l2cap_event_flag |= L2CAP_FLAG_CONTROL_CONNECTED;
|
||||||
|
} else if (l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) {
|
||||||
|
//Notify(PSTR("\r\nHID Interrupt Connection Complete"), 0x80);
|
||||||
|
identifier = l2capinbuf[9];
|
||||||
|
interrupt_scid[0] = l2capinbuf[12];
|
||||||
|
interrupt_scid[1] = l2capinbuf[13];
|
||||||
|
l2cap_event_flag |= L2CAP_FLAG_INTERRUPT_CONNECTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||||
|
#ifdef EXTRADEBUG
|
||||||
|
Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
|
||||||
|
Notify(PSTR(" SCID: "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
||||||
|
Notify(PSTR(" Identifier: "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
|
||||||
|
#endif
|
||||||
|
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
|
||||||
|
identifier = l2capinbuf[9];
|
||||||
|
control_scid[0] = l2capinbuf[14];
|
||||||
|
control_scid[1] = l2capinbuf[15];
|
||||||
|
l2cap_event_flag |= L2CAP_FLAG_CONNECTION_CONTROL_REQUEST;
|
||||||
|
} else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) {
|
||||||
|
identifier = l2capinbuf[9];
|
||||||
|
interrupt_scid[0] = l2capinbuf[14];
|
||||||
|
interrupt_scid[1] = l2capinbuf[15];
|
||||||
|
l2cap_event_flag |= L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST;
|
||||||
|
}
|
||||||
|
} else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
|
||||||
|
if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
|
||||||
|
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
||||||
|
//Notify(PSTR("\r\nHID Control Configuration Complete"), 0x80);
|
||||||
|
identifier = l2capinbuf[9];
|
||||||
|
l2cap_event_flag |= L2CAP_FLAG_CONFIG_CONTROL_SUCCESS;
|
||||||
|
} else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
|
||||||
|
//Notify(PSTR("\r\nHID Interrupt Configuration Complete"), 0x80);
|
||||||
|
identifier = l2capinbuf[9];
|
||||||
|
l2cap_event_flag |= L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
|
||||||
|
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
||||||
|
//Notify(PSTR("\r\nHID Control Configuration Request"), 0x80);
|
||||||
|
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], control_scid);
|
||||||
|
} else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
|
||||||
|
//Notify(PSTR("\r\nHID Interrupt Configuration Request"), 0x80);
|
||||||
|
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], interrupt_scid);
|
||||||
|
}
|
||||||
|
} else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
|
||||||
|
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nDisconnect Request: Control Channel"), 0x80);
|
||||||
|
#endif
|
||||||
|
identifier = l2capinbuf[9];
|
||||||
|
pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid);
|
||||||
|
Reset();
|
||||||
|
} else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"), 0x80);
|
||||||
|
#endif
|
||||||
|
identifier = l2capinbuf[9];
|
||||||
|
pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid);
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
} else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
|
||||||
|
if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
|
||||||
|
//Notify(PSTR("\r\nDisconnect Response: Control Channel"), 0x80);
|
||||||
|
identifier = l2capinbuf[9];
|
||||||
|
l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE;
|
||||||
|
} else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
|
||||||
|
//Notify(PSTR("\r\nDisconnect Response: Interrupt Channel"), 0x80);
|
||||||
|
identifier = l2capinbuf[9];
|
||||||
|
l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef EXTRADEBUG
|
||||||
|
else {
|
||||||
|
identifier = l2capinbuf[9];
|
||||||
|
Notify(PSTR("\r\nL2CAP Unknown Signaling Command: "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt
|
||||||
|
#ifdef PRINTREPORT
|
||||||
|
Notify(PSTR("\r\nL2CAP Interrupt: "), 0x80);
|
||||||
|
for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) {
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
|
||||||
|
switch (l2capinbuf[9]) {
|
||||||
|
case 0x01: // Keyboard events
|
||||||
|
if (pRptParser[KEYBOARD_PARSER_ID]) {
|
||||||
|
uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
|
||||||
|
pRptParser[KEYBOARD_PARSER_ID]->Parse(reinterpret_cast<HID *> (this), 0, (uint8_t) length, &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x02: // Mouse events
|
||||||
|
if (pRptParser[MOUSE_PARSER_ID]) {
|
||||||
|
uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
|
||||||
|
pRptParser[MOUSE_PARSER_ID]->Parse(reinterpret_cast<HID *> (this), 0, (uint8_t) length, &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x03:
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nChange mode event: "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[11], 0x80);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
default:
|
||||||
|
Notify(PSTR("\r\nUnknown Report type: "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (l2capinbuf[6] == control_dcid[0] && l2capinbuf[7] == control_dcid[1]) { // l2cap_control
|
||||||
|
#ifdef PRINTREPORT
|
||||||
|
Notify(PSTR("\r\nL2CAP Control: "), 0x80);
|
||||||
|
for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) {
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef EXTRADEBUG
|
||||||
|
else {
|
||||||
|
Notify(PSTR("\r\nUnsupported L2CAP Data - Channel ID: "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[7], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[6], 0x80);
|
||||||
|
|
||||||
|
Notify(PSTR("\r\nData: "), 0x80);
|
||||||
|
Notify(PSTR("\r\n"), 0x80);
|
||||||
|
for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) {
|
||||||
|
D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
L2CAP_task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTHID::L2CAP_task() {
|
||||||
|
switch (l2cap_state) {
|
||||||
|
/* These states are used if the HID device is the host */
|
||||||
|
case L2CAP_CONTROL_SUCCESS:
|
||||||
|
if (l2cap_config_success_control_flag) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
|
||||||
|
#endif
|
||||||
|
setProtocol(); // Set protocol before establishing HID interrupt channel
|
||||||
|
l2cap_state = L2CAP_INTERRUPT_SETUP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L2CAP_INTERRUPT_SETUP:
|
||||||
|
if (l2cap_connection_request_interrupt_flag) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
|
||||||
|
#endif
|
||||||
|
pBtd->l2cap_connection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid, PENDING);
|
||||||
|
delay(1);
|
||||||
|
pBtd->l2cap_connection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid, SUCCESSFUL);
|
||||||
|
identifier++;
|
||||||
|
delay(1);
|
||||||
|
pBtd->l2cap_config_request(hci_handle, identifier, interrupt_scid);
|
||||||
|
|
||||||
|
l2cap_state = L2CAP_INTERRUPT_CONFIG_REQUEST;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* These states are used if the Arduino is the host */
|
||||||
|
case L2CAP_CONTROL_CONNECT_REQUEST:
|
||||||
|
if (l2cap_connected_control_flag) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nSend HID Control Config Request"), 0x80);
|
||||||
|
#endif
|
||||||
|
identifier++;
|
||||||
|
pBtd->l2cap_config_request(hci_handle, identifier, control_scid);
|
||||||
|
l2cap_state = L2CAP_CONTROL_CONFIG_REQUEST;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L2CAP_CONTROL_CONFIG_REQUEST:
|
||||||
|
if (l2cap_config_success_control_flag) {
|
||||||
|
setProtocol(); // Set protocol before establishing HID interrupt channel
|
||||||
|
delay(1); // Short delay between commands - just to be sure
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nSend HID Interrupt Connection Request"), 0x80);
|
||||||
|
#endif
|
||||||
|
identifier++;
|
||||||
|
pBtd->l2cap_connection_request(hci_handle, identifier, interrupt_dcid, HID_INTR_PSM);
|
||||||
|
l2cap_state = L2CAP_INTERRUPT_CONNECT_REQUEST;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L2CAP_INTERRUPT_CONNECT_REQUEST:
|
||||||
|
if (l2cap_connected_interrupt_flag) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nSend HID Interrupt Config Request"), 0x80);
|
||||||
|
#endif
|
||||||
|
identifier++;
|
||||||
|
pBtd->l2cap_config_request(hci_handle, identifier, interrupt_scid);
|
||||||
|
l2cap_state = L2CAP_INTERRUPT_CONFIG_REQUEST;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L2CAP_INTERRUPT_CONFIG_REQUEST:
|
||||||
|
if (l2cap_config_success_interrupt_flag) { // Now the HID channels is established
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nHID Channels Established"), 0x80);
|
||||||
|
#endif
|
||||||
|
pBtd->connectToHIDDevice = false;
|
||||||
|
pBtd->pairWithHIDDevice = false;
|
||||||
|
connected = true;
|
||||||
|
onInit();
|
||||||
|
l2cap_state = L2CAP_DONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L2CAP_DONE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L2CAP_INTERRUPT_DISCONNECT:
|
||||||
|
if (l2cap_disconnect_response_interrupt_flag) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80);
|
||||||
|
#endif
|
||||||
|
identifier++;
|
||||||
|
pBtd->l2cap_disconnection_request(hci_handle, identifier, control_scid, control_dcid);
|
||||||
|
l2cap_state = L2CAP_CONTROL_DISCONNECT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L2CAP_CONTROL_DISCONNECT:
|
||||||
|
if (l2cap_disconnect_response_control_flag) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nDisconnected Control Channel"), 0x80);
|
||||||
|
#endif
|
||||||
|
pBtd->hci_disconnect(hci_handle);
|
||||||
|
hci_handle = -1; // Reset handle
|
||||||
|
l2cap_event_flag = 0; // Reset flags
|
||||||
|
l2cap_state = L2CAP_WAIT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTHID::Run() {
|
||||||
|
switch (l2cap_state) {
|
||||||
|
case L2CAP_WAIT:
|
||||||
|
if (pBtd->connectToHIDDevice && !pBtd->l2capConnectionClaimed && !connected && !activeConnection) {
|
||||||
|
pBtd->l2capConnectionClaimed = true;
|
||||||
|
activeConnection = true;
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nSend HID Control Connection Request"), 0x80);
|
||||||
|
#endif
|
||||||
|
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
||||||
|
l2cap_event_flag = 0; // Reset flags
|
||||||
|
identifier = 0;
|
||||||
|
pBtd->l2cap_connection_request(hci_handle, identifier, control_dcid, HID_CTRL_PSM);
|
||||||
|
l2cap_state = L2CAP_CONTROL_CONNECT_REQUEST;
|
||||||
|
} else if (l2cap_connection_request_control_flag) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80);
|
||||||
|
#endif
|
||||||
|
pBtd->l2cap_connection_response(hci_handle, identifier, control_dcid, control_scid, PENDING);
|
||||||
|
delay(1);
|
||||||
|
pBtd->l2cap_connection_response(hci_handle, identifier, control_dcid, control_scid, SUCCESSFUL);
|
||||||
|
identifier++;
|
||||||
|
delay(1);
|
||||||
|
pBtd->l2cap_config_request(hci_handle, identifier, control_scid);
|
||||||
|
l2cap_state = L2CAP_CONTROL_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* HID Commands */
|
||||||
|
/************************************************************/
|
||||||
|
void BTHID::setProtocol() {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nSet protocol mode: "), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (protocolMode, 0x80);
|
||||||
|
#endif
|
||||||
|
uint8_t command = 0x70 | protocolMode; // Set Protocol, see HID specs page 33
|
||||||
|
pBtd->L2CAP_Command(hci_handle, &command, 1, control_scid[0], control_scid[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTHID::setLeds(uint8_t data) {
|
||||||
|
uint8_t buf[3];
|
||||||
|
buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
||||||
|
buf[1] = 0x01; // Report ID
|
||||||
|
buf[2] = data;
|
||||||
|
pBtd->L2CAP_Command(hci_handle, buf, 3, interrupt_scid[0], interrupt_scid[1]);
|
||||||
|
}
|
161
BTHID.h
Normal file
161
BTHID.h
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/* Copyright (C) 2013 Kristian Lauszus, TKJ Electronics. All rights reserved.
|
||||||
|
|
||||||
|
This software may be distributed and modified under the terms of the GNU
|
||||||
|
General Public License version 2 (GPL2) as published by the Free Software
|
||||||
|
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
||||||
|
this file. Please note that GPL2 Section 2[b] requires that all works based
|
||||||
|
on this software must also be made publicly available under the terms of
|
||||||
|
the GPL2 ("Copyleft").
|
||||||
|
|
||||||
|
Contact information
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Kristian Lauszus, TKJ Electronics
|
||||||
|
Web : http://www.tkjelectronics.com
|
||||||
|
e-mail : kristianl@tkjelectronics.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _bthid_h_
|
||||||
|
#define _bthid_h_
|
||||||
|
|
||||||
|
#include "BTD.h"
|
||||||
|
#include "hidboot.h"
|
||||||
|
|
||||||
|
/* Bluetooth L2CAP states for L2CAP_task() */
|
||||||
|
#define L2CAP_WAIT 0
|
||||||
|
|
||||||
|
// These states are used if the device is the host
|
||||||
|
#define L2CAP_CONTROL_SUCCESS 1
|
||||||
|
#define L2CAP_INTERRUPT_SETUP 2
|
||||||
|
|
||||||
|
// These states are used if the Arduino is the host
|
||||||
|
#define L2CAP_CONTROL_CONNECT_REQUEST 3
|
||||||
|
#define L2CAP_CONTROL_CONFIG_REQUEST 4
|
||||||
|
#define L2CAP_INTERRUPT_CONNECT_REQUEST 5
|
||||||
|
|
||||||
|
#define L2CAP_INTERRUPT_CONFIG_REQUEST 6
|
||||||
|
#define L2CAP_DONE 7
|
||||||
|
|
||||||
|
#define L2CAP_INTERRUPT_DISCONNECT 8
|
||||||
|
#define L2CAP_CONTROL_DISCONNECT 9
|
||||||
|
|
||||||
|
/* L2CAP event flags */
|
||||||
|
#define L2CAP_FLAG_CONTROL_CONNECTED 0x01
|
||||||
|
#define L2CAP_FLAG_INTERRUPT_CONNECTED 0x02
|
||||||
|
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS 0x04
|
||||||
|
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS 0x08
|
||||||
|
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE 0x10
|
||||||
|
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE 0x20
|
||||||
|
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST 0x40
|
||||||
|
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST 0x80
|
||||||
|
|
||||||
|
/* Macros for L2CAP event flag tests */
|
||||||
|
#define l2cap_connected_control_flag (l2cap_event_flag & L2CAP_FLAG_CONTROL_CONNECTED)
|
||||||
|
#define l2cap_connected_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_INTERRUPT_CONNECTED)
|
||||||
|
#define l2cap_config_success_control_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)
|
||||||
|
#define l2cap_config_success_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)
|
||||||
|
#define l2cap_disconnect_response_control_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)
|
||||||
|
#define l2cap_disconnect_response_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE)
|
||||||
|
#define l2cap_connection_request_control_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_CONTROL_REQUEST)
|
||||||
|
#define l2cap_connection_request_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST)
|
||||||
|
|
||||||
|
#define KEYBOARD_PARSER_ID 0
|
||||||
|
#define MOUSE_PARSER_ID 1
|
||||||
|
#define epMUL 2
|
||||||
|
|
||||||
|
/** This BluetoothService class implements support for the HID keyboard and mice. */
|
||||||
|
class BTHID : public BluetoothService {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor for the BTHID class.
|
||||||
|
* @param p Pointer to the BTD class instance.
|
||||||
|
* @param pair Set this to true in order to pair with the device. If the argument is omitted then it will not pair with it. One can use ::PAIR to set it to true.
|
||||||
|
* @param pin Write the pin to BTD#btdPin. If argument is omitted, then "0000" will be used.
|
||||||
|
*/
|
||||||
|
BTHID(BTD *p, bool pair = false, const char *pin = "0000");
|
||||||
|
|
||||||
|
/** @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 maschine. */
|
||||||
|
virtual void Run();
|
||||||
|
/** Use this to reset the service. */
|
||||||
|
virtual void Reset();
|
||||||
|
/** Used this to disconnect any of the controllers. */
|
||||||
|
virtual void disconnect();
|
||||||
|
/**@}*/
|
||||||
|
|
||||||
|
HIDReportParser *GetReportParser(uint8_t id) {
|
||||||
|
return pRptParser[id];
|
||||||
|
};
|
||||||
|
|
||||||
|
bool SetReportParser(uint8_t id, HIDReportParser *prs) {
|
||||||
|
pRptParser[id] = prs;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
void setProtocolMode(uint8_t mode) {
|
||||||
|
protocolMode = mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Used to set the leds on a keyboard */
|
||||||
|
void setLeds(uint8_t data);
|
||||||
|
|
||||||
|
/** True if a device is connected */
|
||||||
|
bool connected;
|
||||||
|
|
||||||
|
/** Call this to start the paring sequence with a controller */
|
||||||
|
void pair(void) {
|
||||||
|
if (pBtd)
|
||||||
|
pBtd->pairWithHID();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to call your own function when the controller is successfully initialized.
|
||||||
|
* @param funcOnInit Function to call.
|
||||||
|
*/
|
||||||
|
void attachOnInit(void (*funcOnInit)(void)) {
|
||||||
|
pFuncOnInit = funcOnInit;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
BTD *pBtd; // Pointer to BTD instance
|
||||||
|
|
||||||
|
HIDReportParser *pRptParser[epMUL];
|
||||||
|
|
||||||
|
/** Set report protocol. */
|
||||||
|
void setProtocol();
|
||||||
|
uint8_t protocolMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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() {
|
||||||
|
if (pFuncOnInit)
|
||||||
|
pFuncOnInit(); // Call the user function
|
||||||
|
}
|
||||||
|
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
||||||
|
|
||||||
|
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;
|
||||||
|
uint8_t l2cap_event_flag; // l2cap flags of received Bluetooth events
|
||||||
|
|
||||||
|
/* L2CAP Channels */
|
||||||
|
uint8_t control_scid[2]; // L2CAP source CID for HID_Control
|
||||||
|
uint8_t control_dcid[2]; // 0x0070
|
||||||
|
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
|
||||||
|
uint8_t interrupt_dcid[2]; // 0x0071
|
||||||
|
uint8_t identifier; // Identifier for connection
|
||||||
|
};
|
||||||
|
#endif
|
81
PS3BT.cpp
81
PS3BT.cpp
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PS3BT.h"
|
#include "PS3BT.h"
|
||||||
// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h
|
// To enable serial debugging see "settings.h"
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
|
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
|
||||||
|
|
||||||
|
@ -36,14 +36,14 @@ pBtd(p) // pointer to USB class instance - mandatory
|
||||||
HIDBuffer[0] = 0x52; // HID BT Set_report (0x50) | Report Type (Output 0x02)
|
HIDBuffer[0] = 0x52; // HID BT Set_report (0x50) | Report Type (Output 0x02)
|
||||||
HIDBuffer[1] = 0x01; // Report ID
|
HIDBuffer[1] = 0x01; // Report ID
|
||||||
|
|
||||||
//Needed for PS3 Move Controller commands to work via bluetooth
|
// Needed for PS3 Move Controller commands to work via bluetooth
|
||||||
HIDMoveBuffer[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
HIDMoveBuffer[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
||||||
HIDMoveBuffer[1] = 0x02; // Report ID
|
HIDMoveBuffer[1] = 0x02; // Report ID
|
||||||
|
|
||||||
/* Set device cid for the control and intterrupt channelse - LSB */
|
/* Set device cid for the control and intterrupt channelse - LSB */
|
||||||
control_dcid[0] = 0x40; //0x0040
|
control_dcid[0] = 0x40; // 0x0040
|
||||||
control_dcid[1] = 0x00;
|
control_dcid[1] = 0x00;
|
||||||
interrupt_dcid[0] = 0x41; //0x0041
|
interrupt_dcid[0] = 0x41; // 0x0041
|
||||||
interrupt_dcid[1] = 0x00;
|
interrupt_dcid[1] = 0x00;
|
||||||
|
|
||||||
Reset();
|
Reset();
|
||||||
|
@ -56,25 +56,19 @@ bool PS3BT::getButtonPress(Button b) {
|
||||||
bool PS3BT::getButtonClick(Button b) {
|
bool PS3BT::getButtonClick(Button b) {
|
||||||
uint32_t button = pgm_read_dword(&BUTTONS[(uint8_t)b]);
|
uint32_t button = pgm_read_dword(&BUTTONS[(uint8_t)b]);
|
||||||
bool click = (ButtonClickState & button);
|
bool click = (ButtonClickState & button);
|
||||||
ButtonClickState &= ~button; // clear "click" event
|
ButtonClickState &= ~button; // Clear "click" event
|
||||||
return click;
|
return click;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t PS3BT::getAnalogButton(Button a) {
|
uint8_t PS3BT::getAnalogButton(Button a) {
|
||||||
if (l2capinbuf == NULL)
|
|
||||||
return 0;
|
|
||||||
return (uint8_t)(l2capinbuf[pgm_read_byte(&ANALOGBUTTONS[(uint8_t)a])]);
|
return (uint8_t)(l2capinbuf[pgm_read_byte(&ANALOGBUTTONS[(uint8_t)a])]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t PS3BT::getAnalogHat(AnalogHat a) {
|
uint8_t PS3BT::getAnalogHat(AnalogHat a) {
|
||||||
if (l2capinbuf == NULL)
|
|
||||||
return 0;
|
|
||||||
return (uint8_t)(l2capinbuf[(uint8_t)a + 15]);
|
return (uint8_t)(l2capinbuf[(uint8_t)a + 15]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t PS3BT::getSensor(Sensor a) {
|
int16_t PS3BT::getSensor(Sensor a) {
|
||||||
if (l2capinbuf == NULL)
|
|
||||||
return 0;
|
|
||||||
if (PS3Connected) {
|
if (PS3Connected) {
|
||||||
if (a == aX || a == aY || a == aZ || a == gZ)
|
if (a == aX || a == aY || a == aZ || a == gZ)
|
||||||
return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]);
|
return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]);
|
||||||
|
@ -92,13 +86,11 @@ int16_t PS3BT::getSensor(Sensor a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
double PS3BT::getAngle(Angle a) {
|
double PS3BT::getAngle(Angle a) {
|
||||||
double accXval;
|
double accXval, accYval, accZval;
|
||||||
double accYval;
|
|
||||||
double accZval;
|
|
||||||
|
|
||||||
if (PS3Connected) {
|
if (PS3Connected) {
|
||||||
// Data for the Kionix KXPC4 used in the DualShock 3
|
// Data for the Kionix KXPC4 used in the DualShock 3
|
||||||
const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
|
const double zeroG = 511.5; // 1.65/3.3*1023 (1.65V)
|
||||||
accXval = -((double)getSensor(aX) - zeroG);
|
accXval = -((double)getSensor(aX) - zeroG);
|
||||||
accYval = -((double)getSensor(aY) - zeroG);
|
accYval = -((double)getSensor(aY) - zeroG);
|
||||||
accZval = -((double)getSensor(aZ) - zeroG);
|
accZval = -((double)getSensor(aZ) - zeroG);
|
||||||
|
@ -114,13 +106,10 @@ double PS3BT::getAngle(Angle a) {
|
||||||
// Convert to 360 degrees resolution
|
// Convert to 360 degrees resolution
|
||||||
// atan2 outputs the value of -π to π (radians)
|
// atan2 outputs the value of -π to π (radians)
|
||||||
// We are then converting it to 0 to 2π and then to degrees
|
// We are then converting it to 0 to 2π and then to degrees
|
||||||
if (a == Pitch) {
|
if (a == Pitch)
|
||||||
double angle = (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
|
return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
|
||||||
return angle;
|
else
|
||||||
} else {
|
return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
|
||||||
double angle = (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
|
|
||||||
return angle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double PS3BT::get9DOFValues(Sensor a) { // Thanks to Manfred Piendl
|
double PS3BT::get9DOFValues(Sensor a) { // Thanks to Manfred Piendl
|
||||||
|
@ -168,11 +157,7 @@ String PS3BT::getTemperature() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PS3BT::getStatus(Status c) {
|
bool PS3BT::getStatus(Status c) {
|
||||||
if (l2capinbuf == NULL)
|
return (l2capinbuf[(uint16_t)c >> 8] == ((uint8_t)c & 0xff));
|
||||||
return false;
|
|
||||||
if (l2capinbuf[(uint16_t)c >> 8] == ((uint8_t)c & 0xff))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String PS3BT::getStatusString() {
|
String PS3BT::getStatusString() {
|
||||||
|
@ -266,8 +251,7 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (((ACLData[0] | (ACLData[1] << 8)) == (hci_handle | 0x2000))) { //acl_handle_ok
|
if (((ACLData[0] | (ACLData[1] << 8)) == (hci_handle | 0x2000))) { //acl_handle_ok
|
||||||
for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
|
memcpy(l2capinbuf, ACLData, BULK_MAXPKTSIZE);
|
||||||
l2capinbuf[i] = ACLData[i];
|
|
||||||
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U
|
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //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
|
||||||
|
@ -457,8 +441,7 @@ void PS3BT::L2CAP_task() {
|
||||||
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[0] == 'M') { // First letter in Motion Controller ('M')
|
||||||
for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // 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
|
||||||
l2capinbuf[i] = 0;
|
|
||||||
l2cap_state = L2CAP_HID_PS3_LED;
|
l2cap_state = L2CAP_HID_PS3_LED;
|
||||||
} else
|
} else
|
||||||
l2cap_state = L2CAP_HID_ENABLE_SIXAXIS;
|
l2cap_state = L2CAP_HID_ENABLE_SIXAXIS;
|
||||||
|
@ -497,8 +480,7 @@ void PS3BT::Run() {
|
||||||
switch (l2cap_state) {
|
switch (l2cap_state) {
|
||||||
case L2CAP_HID_ENABLE_SIXAXIS:
|
case L2CAP_HID_ENABLE_SIXAXIS:
|
||||||
if (millis() - timer > 1000) { // loop 1 second before sending the command
|
if (millis() - timer > 1000) { // loop 1 second before sending the command
|
||||||
for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // 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
|
||||||
l2capinbuf[i] = 0;
|
|
||||||
for (uint8_t i = 15; i < 19; i++)
|
for (uint8_t i = 15; i < 19; i++)
|
||||||
l2capinbuf[i] = 0x7F; // Set the analog joystick values to center position
|
l2capinbuf[i] = 0x7F; // Set the analog joystick values to center position
|
||||||
enable_sixaxis();
|
enable_sixaxis();
|
||||||
|
@ -536,9 +518,9 @@ 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 aproximatly every 5th second for it to stay on
|
||||||
if (millis() - timerBulbRumble > 4000) { //Send at least every 4th second
|
if (millis() - timerBulbRumble > 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();
|
timerBulbRumble = millis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -550,18 +532,22 @@ void PS3BT::Run() {
|
||||||
/* HID Commands */
|
/* HID Commands */
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
|
|
||||||
//Playstation Sixaxis Dualshock and Navigation Controller commands
|
// Playstation Sixaxis Dualshock and Navigation Controller commands
|
||||||
|
|
||||||
void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) {
|
void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) {
|
||||||
if (millis() - timerHID <= 250)// Check if is has been more than 250ms since last command
|
if (millis() - timerHID <= 150) // Check if is has been more than 150ms since last command
|
||||||
delay((uint32_t)(250 - (millis() - timerHID))); //There have to be a delay between commands
|
delay((uint32_t)(150 - (millis() - timerHID))); // There have to be a delay between commands
|
||||||
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]); // Both the Navigation and Dualshock controller sends data via the control channel
|
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]); // Both the Navigation and Dualshock controller sends data via the control channel
|
||||||
timerHID = millis();
|
timerHID = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3BT::setAllOff() {
|
void PS3BT::setAllOff() {
|
||||||
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
|
HIDBuffer[3] = 0x00; // Rumble bytes
|
||||||
HIDBuffer[i + 2] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // First two bytes reserved for report type and ID
|
HIDBuffer[4] = 0x00;
|
||||||
|
HIDBuffer[5] = 0x00;
|
||||||
|
HIDBuffer[6] = 0x00;
|
||||||
|
|
||||||
|
HIDBuffer[11] = 0x00; // LED byte
|
||||||
|
|
||||||
HID_Command(HIDBuffer, HID_BUFFERSIZE);
|
HID_Command(HIDBuffer, HID_BUFFERSIZE);
|
||||||
}
|
}
|
||||||
|
@ -596,6 +582,7 @@ void PS3BT::setLedRaw(uint8_t value) {
|
||||||
HIDBuffer[11] = value << 1;
|
HIDBuffer[11] = value << 1;
|
||||||
HID_Command(HIDBuffer, HID_BUFFERSIZE);
|
HID_Command(HIDBuffer, HID_BUFFERSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3BT::setLedOff(LED a) {
|
void PS3BT::setLedOff(LED a) {
|
||||||
HIDBuffer[11] &= ~((uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1));
|
HIDBuffer[11] &= ~((uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1));
|
||||||
HID_Command(HIDBuffer, HID_BUFFERSIZE);
|
HID_Command(HIDBuffer, HID_BUFFERSIZE);
|
||||||
|
@ -611,7 +598,7 @@ void PS3BT::setLedToggle(LED a) {
|
||||||
HID_Command(HIDBuffer, HID_BUFFERSIZE);
|
HID_Command(HIDBuffer, HID_BUFFERSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3BT::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navigation controller to send data via USB
|
void PS3BT::enable_sixaxis() { // Command used to enable the Dualshock 3 and Navigation controller to send data via Bluetooth
|
||||||
uint8_t cmd_buf[6];
|
uint8_t cmd_buf[6];
|
||||||
cmd_buf[0] = 0x53; // HID BT Set_report (0x50) | Report Type (Feature 0x03)
|
cmd_buf[0] = 0x53; // HID BT Set_report (0x50) | Report Type (Feature 0x03)
|
||||||
cmd_buf[1] = 0xF4; // Report ID
|
cmd_buf[1] = 0xF4; // Report ID
|
||||||
|
@ -623,17 +610,17 @@ void PS3BT::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navi
|
||||||
HID_Command(cmd_buf, 6);
|
HID_Command(cmd_buf, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Playstation Move Controller commands
|
// Playstation Move Controller commands
|
||||||
|
|
||||||
void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) {
|
void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) {
|
||||||
if (millis() - timerHID <= 250)// Check if is has been less than 200ms since last command
|
if (millis() - timerHID <= 150)// Check if is has been less than 150ms since last command
|
||||||
delay((uint32_t)(250 - (millis() - timerHID))); //There have to be a delay between commands
|
delay((uint32_t)(150 - (millis() - timerHID))); // There have to be a delay between commands
|
||||||
pBtd->L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]); // The Move controller sends it's data via the intterrupt channel
|
pBtd->L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]); // The Move controller sends it's data via the intterrupt channel
|
||||||
timerHID = millis();
|
timerHID = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3BT::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { //Use this to set the Color using RGB values
|
void PS3BT::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { //Use this to set the Color using RGB values
|
||||||
//set the Bulb's values into the write buffer
|
// Set the Bulb's values into the write buffer
|
||||||
HIDMoveBuffer[3] = r;
|
HIDMoveBuffer[3] = r;
|
||||||
HIDMoveBuffer[4] = g;
|
HIDMoveBuffer[4] = g;
|
||||||
HIDMoveBuffer[5] = b;
|
HIDMoveBuffer[5] = b;
|
||||||
|
@ -650,7 +637,7 @@ void PS3BT::moveSetRumble(uint8_t rumble) {
|
||||||
if (rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)
|
if (rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)
|
||||||
Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
|
Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
//set the rumble value into the write buffer
|
// Set the rumble value into the write buffer
|
||||||
HIDMoveBuffer[7] = rumble;
|
HIDMoveBuffer[7] = rumble;
|
||||||
|
|
||||||
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);
|
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);
|
||||||
|
|
4
PS3BT.h
4
PS3BT.h
|
@ -176,6 +176,10 @@ public:
|
||||||
* @param value See: ::LED enum.
|
* @param value See: ::LED enum.
|
||||||
*/
|
*/
|
||||||
void setLedRaw(uint8_t value);
|
void setLedRaw(uint8_t value);
|
||||||
|
/** Turn all LEDs off. */
|
||||||
|
void setLedOff() {
|
||||||
|
setLedRaw(0);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Turn the specific ::LED off.
|
* Turn the specific ::LED off.
|
||||||
* @param a The ::LED to turn off.
|
* @param a The ::LED to turn off.
|
||||||
|
|
111
PS3USB.cpp
111
PS3USB.cpp
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PS3USB.h"
|
#include "PS3USB.h"
|
||||||
// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h
|
// To enable serial debugging see "settings.h"
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
|
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
|
||||||
|
|
||||||
|
@ -279,8 +279,7 @@ uint8_t PS3USB::Poll() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else if (PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
|
} else if (PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
|
||||||
if (millis() - timer > 4000) // Send at least every 4th second
|
if (millis() - timer > 4000) { // Send at least every 4th second
|
||||||
{
|
|
||||||
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on
|
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on
|
||||||
timer = millis();
|
timer = millis();
|
||||||
}
|
}
|
||||||
|
@ -289,9 +288,6 @@ uint8_t PS3USB::Poll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::readReport() {
|
void PS3USB::readReport() {
|
||||||
if (readBuf == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ButtonState = (uint32_t)(readBuf[2] | ((uint16_t)readBuf[3] << 8) | ((uint32_t)readBuf[4] << 16));
|
ButtonState = (uint32_t)(readBuf[2] | ((uint16_t)readBuf[3] << 8) | ((uint32_t)readBuf[4] << 16));
|
||||||
|
|
||||||
//Notify(PSTR("\r\nButtonState", 0x80);
|
//Notify(PSTR("\r\nButtonState", 0x80);
|
||||||
|
@ -303,10 +299,8 @@ void PS3USB::readReport() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::printReport() { //Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
|
void PS3USB::printReport() { // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
|
||||||
#ifdef PRINTREPORT
|
#ifdef PRINTREPORT
|
||||||
if (readBuf == NULL)
|
|
||||||
return;
|
|
||||||
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) {
|
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) {
|
||||||
D_PrintHex<uint8_t > (readBuf[i], 0x80);
|
D_PrintHex<uint8_t > (readBuf[i], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
|
@ -322,25 +316,19 @@ bool PS3USB::getButtonPress(Button b) {
|
||||||
bool PS3USB::getButtonClick(Button b) {
|
bool PS3USB::getButtonClick(Button b) {
|
||||||
uint32_t button = pgm_read_dword(&BUTTONS[(uint8_t)b]);
|
uint32_t button = pgm_read_dword(&BUTTONS[(uint8_t)b]);
|
||||||
bool click = (ButtonClickState & button);
|
bool click = (ButtonClickState & button);
|
||||||
ButtonClickState &= ~button; // clear "click" event
|
ButtonClickState &= ~button; // Clear "click" event
|
||||||
return click;
|
return click;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t PS3USB::getAnalogButton(Button a) {
|
uint8_t PS3USB::getAnalogButton(Button a) {
|
||||||
if (readBuf == NULL)
|
|
||||||
return 0;
|
|
||||||
return (uint8_t)(readBuf[(pgm_read_byte(&ANALOGBUTTONS[(uint8_t)a])) - 9]);
|
return (uint8_t)(readBuf[(pgm_read_byte(&ANALOGBUTTONS[(uint8_t)a])) - 9]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t PS3USB::getAnalogHat(AnalogHat a) {
|
uint8_t PS3USB::getAnalogHat(AnalogHat a) {
|
||||||
if (readBuf == NULL)
|
|
||||||
return 0;
|
|
||||||
return (uint8_t)(readBuf[((uint8_t)a + 6)]);
|
return (uint8_t)(readBuf[((uint8_t)a + 6)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t PS3USB::getSensor(Sensor a) {
|
uint16_t PS3USB::getSensor(Sensor a) {
|
||||||
if (readBuf == NULL)
|
|
||||||
return 0;
|
|
||||||
return ((readBuf[((uint16_t)a) - 9] << 8) | readBuf[((uint16_t)a + 1) - 9]);
|
return ((readBuf[((uint16_t)a) - 9] << 8) | readBuf[((uint16_t)a + 1) - 9]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,23 +347,16 @@ double PS3USB::getAngle(Angle a) {
|
||||||
// Convert to 360 degrees resolution
|
// Convert to 360 degrees resolution
|
||||||
// atan2 outputs the value of -π to π (radians)
|
// atan2 outputs the value of -π to π (radians)
|
||||||
// We are then converting it to 0 to 2π and then to degrees
|
// We are then converting it to 0 to 2π and then to degrees
|
||||||
if (a == Pitch) {
|
if (a == Pitch)
|
||||||
double angle = (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
|
return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
|
||||||
return angle;
|
else
|
||||||
} else {
|
return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
|
||||||
double angle = (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
|
|
||||||
return angle;
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PS3USB::getStatus(Status c) {
|
bool PS3USB::getStatus(Status c) {
|
||||||
if (readBuf == NULL)
|
return (readBuf[((uint16_t)c >> 8) - 9] == ((uint8_t)c & 0xff));
|
||||||
return false;
|
|
||||||
if (readBuf[((uint16_t)c >> 8) - 9] == ((uint8_t)c & 0xff))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String PS3USB::getStatusString() {
|
String PS3USB::getStatusString() {
|
||||||
|
@ -414,8 +395,8 @@ String PS3USB::getStatusString() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Playstation Sixaxis Dualshock and Navigation Controller commands */
|
/* Playstation Sixaxis Dualshock and Navigation Controller commands */
|
||||||
void PS3USB::PS3_Command(uint8_t* data, uint16_t nbytes) {
|
void PS3USB::PS3_Command(uint8_t *data, uint16_t nbytes) {
|
||||||
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x01), 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 (0x01), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
|
||||||
pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x01, 0x02, 0x00, nbytes, nbytes, data, NULL);
|
pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x01, 0x02, 0x00, nbytes, nbytes, data, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,9 +409,9 @@ void PS3USB::setAllOff() {
|
||||||
|
|
||||||
void PS3USB::setRumbleOff() {
|
void PS3USB::setRumbleOff() {
|
||||||
writeBuf[1] = 0x00;
|
writeBuf[1] = 0x00;
|
||||||
writeBuf[2] = 0x00; //low mode off
|
writeBuf[2] = 0x00; // Low mode off
|
||||||
writeBuf[3] = 0x00;
|
writeBuf[3] = 0x00;
|
||||||
writeBuf[4] = 0x00; //high mode off
|
writeBuf[4] = 0x00; // High mode off
|
||||||
|
|
||||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
@ -474,36 +455,47 @@ void PS3USB::setLedToggle(LED a) {
|
||||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::setBdaddr(uint8_t* BDADDR) {
|
void PS3USB::setBdaddr(uint8_t *bdaddr) {
|
||||||
/* Set the internal bluetooth address */
|
/* Set the internal Bluetooth address */
|
||||||
uint8_t buf[8];
|
uint8_t buf[8];
|
||||||
buf[0] = 0x01;
|
buf[0] = 0x01;
|
||||||
buf[1] = 0x00;
|
buf[1] = 0x00;
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
buf[i + 2] = BDADDR[5 - i]; //Copy into buffer, has to be written reversed
|
|
||||||
|
|
||||||
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
|
for (uint8_t i = 0; i < 6; i++)
|
||||||
|
buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first
|
||||||
|
|
||||||
|
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
||||||
pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
|
pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navigation controller to send data via USB
|
void PS3USB::getBdaddr(uint8_t *bdaddr) {
|
||||||
|
uint8_t buf[8];
|
||||||
|
|
||||||
|
// bmRequest = Device to host (0x80) | Class (0x20) | Interface (0x01) = 0xA1, bRequest = Get Report (0x01), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
||||||
|
pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 6; i++)
|
||||||
|
bdaddr[5 - i] = buf[i + 2]; // Copy into buffer reversed, so it is LSB first
|
||||||
|
}
|
||||||
|
|
||||||
|
void PS3USB::enable_sixaxis() { // Command used to enable the Dualshock 3 and Navigation controller to send data via USB
|
||||||
uint8_t cmd_buf[4];
|
uint8_t cmd_buf[4];
|
||||||
cmd_buf[0] = 0x42; // Special PS3 Controller enable commands
|
cmd_buf[0] = 0x42; // Special PS3 Controller enable commands
|
||||||
cmd_buf[1] = 0x0c;
|
cmd_buf[1] = 0x0c;
|
||||||
cmd_buf[2] = 0x00;
|
cmd_buf[2] = 0x00;
|
||||||
cmd_buf[3] = 0x00;
|
cmd_buf[3] = 0x00;
|
||||||
|
|
||||||
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF4), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
|
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF4), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
|
||||||
pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF4, 0x03, 0x00, 4, 4, cmd_buf, NULL);
|
pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF4, 0x03, 0x00, 4, 4, cmd_buf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Playstation Move Controller commands */
|
/* Playstation Move Controller commands */
|
||||||
void PS3USB::Move_Command(uint8_t* data, uint16_t nbytes) {
|
void PS3USB::Move_Command(uint8_t *data, uint16_t nbytes) {
|
||||||
pUsb->outTransfer(bAddress, epInfo[ PS3_OUTPUT_PIPE ].epAddr, nbytes, data);
|
pUsb->outTransfer(bAddress, epInfo[ PS3_OUTPUT_PIPE ].epAddr, nbytes, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { //Use this to set the Color using RGB values
|
void PS3USB::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { // Use this to set the Color using RGB values
|
||||||
// set the Bulb's values into the write buffer
|
// Set the Bulb's values into the write buffer
|
||||||
writeBuf[2] = r;
|
writeBuf[2] = r;
|
||||||
writeBuf[3] = g;
|
writeBuf[3] = g;
|
||||||
writeBuf[4] = b;
|
writeBuf[4] = b;
|
||||||
|
@ -511,7 +503,7 @@ void PS3USB::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { //Use this to set th
|
||||||
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
|
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::moveSetBulb(Colors color) { //Use this to set the Color using the predefined colors in "enums.h"
|
void PS3USB::moveSetBulb(Colors color) { // Use this to set the Color using the predefined colors in "enums.h"
|
||||||
moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
|
moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,14 +512,13 @@ void PS3USB::moveSetRumble(uint8_t rumble) {
|
||||||
if (rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)
|
if (rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)
|
||||||
Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
|
Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
//set the rumble value into the write buffer
|
writeBuf[6] = rumble; // Set the rumble value into the write buffer
|
||||||
writeBuf[6] = rumble;
|
|
||||||
|
|
||||||
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
|
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::setMoveBdaddr(uint8_t* BDADDR) {
|
void PS3USB::setMoveBdaddr(uint8_t *bdaddr) {
|
||||||
/* Set the internal bluetooth address */
|
/* Set the internal Bluetooth address */
|
||||||
uint8_t buf[11];
|
uint8_t buf[11];
|
||||||
buf[0] = 0x05;
|
buf[0] = 0x05;
|
||||||
buf[7] = 0x10;
|
buf[7] = 0x10;
|
||||||
|
@ -536,12 +527,34 @@ void PS3USB::setMoveBdaddr(uint8_t* BDADDR) {
|
||||||
buf[10] = 0x12;
|
buf[10] = 0x12;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
for (uint8_t i = 0; i < 6; i++)
|
||||||
buf[i + 1] = BDADDR[i];
|
buf[i + 1] = bdaddr[i];
|
||||||
|
|
||||||
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
|
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
||||||
pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL);
|
pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PS3USB::getMoveBdaddr(uint8_t *bdaddr) {
|
||||||
|
uint8_t buf[16];
|
||||||
|
|
||||||
|
// bmRequest = Device to host (0x80) | Class (0x20) | Interface (0x01) = 0xA1, bRequest = Get Report (0x01), Report ID (0x04), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
||||||
|
pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0x04, 0x03, 0x00, 16, 16, buf, NULL);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 6; i++)
|
||||||
|
bdaddr[i] = buf[10 + i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void PS3USB::getMoveCalibration(uint8_t *data) {
|
||||||
|
uint8_t buf[49];
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 3; i++) {
|
||||||
|
// bmRequest = Device to host (0x80) | Class (0x20) | Interface (0x01) = 0xA1, bRequest = Get Report (0x01), Report ID (0x10), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
||||||
|
pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0x10, 0x03, 0x00, 49, 49, buf, NULL);
|
||||||
|
|
||||||
|
for (byte j = 0; j < 49; j++)
|
||||||
|
data[49 * i + j] = buf[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PS3USB::onInit() {
|
void PS3USB::onInit() {
|
||||||
if (pFuncOnInit)
|
if (pFuncOnInit)
|
||||||
pFuncOnInit(); // Call the user function
|
pFuncOnInit(); // Call the user function
|
||||||
|
|
41
PS3USB.h
41
PS3USB.h
|
@ -38,8 +38,11 @@
|
||||||
#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
|
// 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_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 HID_REQUEST_SET_REPORT 0x09
|
||||||
|
|
||||||
#define PS3_MAX_ENDPOINTS 3
|
#define PS3_MAX_ENDPOINTS 3
|
||||||
|
@ -112,14 +115,34 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to set the Bluetooth address inside the Dualshock 3 and Navigation controller.
|
* Used to set the Bluetooth address inside the Dualshock 3 and Navigation controller.
|
||||||
* @param BDADDR Your dongles Bluetooth address.
|
* Set using LSB first.
|
||||||
|
* @param bdaddr Your dongles Bluetooth address.
|
||||||
*/
|
*/
|
||||||
void setBdaddr(uint8_t* BDADDR);
|
void setBdaddr(uint8_t *bdaddr);
|
||||||
|
/**
|
||||||
|
* Used to get the Bluetooth address inside the Dualshock 3 and Navigation controller.
|
||||||
|
* Will return LSB first.
|
||||||
|
* @param bdaddr Your dongles Bluetooth address.
|
||||||
|
*/
|
||||||
|
void getBdaddr(uint8_t *bdaddr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to set the Bluetooth address inside the Move controller.
|
* Used to set the Bluetooth address inside the Move controller.
|
||||||
* @param BDADDR Your dongles Bluetooth address.
|
* Set using LSB first.
|
||||||
|
* @param bdaddr Your dongles Bluetooth address.
|
||||||
*/
|
*/
|
||||||
void setMoveBdaddr(uint8_t* BDADDR);
|
void setMoveBdaddr(uint8_t *bdaddr);
|
||||||
|
/**
|
||||||
|
* Used to get the Bluetooth address inside the Move controller.
|
||||||
|
* Will return LSB first.
|
||||||
|
* @param bdaddr Your dongles Bluetooth address.
|
||||||
|
*/
|
||||||
|
void getMoveBdaddr(uint8_t *bdaddr);
|
||||||
|
/**
|
||||||
|
* Used to get the calibration data inside the Move controller.
|
||||||
|
* @param data Buffer to store data in. Must be at least 147 bytes
|
||||||
|
*/
|
||||||
|
void getMoveCalibration(uint8_t *data);
|
||||||
|
|
||||||
/** @name PS3 Controller functions */
|
/** @name PS3 Controller functions */
|
||||||
/**
|
/**
|
||||||
|
@ -197,6 +220,10 @@ public:
|
||||||
* @param value See: ::LED enum.
|
* @param value See: ::LED enum.
|
||||||
*/
|
*/
|
||||||
void setLedRaw(uint8_t value);
|
void setLedRaw(uint8_t value);
|
||||||
|
/** Turn all LEDs off. */
|
||||||
|
void setLedOff() {
|
||||||
|
setLedRaw(0);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Turn the specific ::LED off.
|
* Turn the specific ::LED off.
|
||||||
* @param a The ::LED to turn off.
|
* @param a The ::LED to turn off.
|
||||||
|
@ -278,8 +305,8 @@ private:
|
||||||
void printReport(); // print incoming date - Uncomment for debugging
|
void printReport(); // print incoming date - Uncomment for debugging
|
||||||
|
|
||||||
/* Private commands */
|
/* Private commands */
|
||||||
void PS3_Command(uint8_t* data, uint16_t nbytes);
|
void PS3_Command(uint8_t *data, uint16_t nbytes);
|
||||||
void enable_sixaxis(); // Command used to enable the Dualshock 3 and Navigation controller to send data via USB
|
void enable_sixaxis(); // Command used to enable the Dualshock 3 and Navigation controller to send data via USB
|
||||||
void Move_Command(uint8_t* data, uint16_t nbytes);
|
void Move_Command(uint8_t *data, uint16_t nbytes);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
15
README.md
15
README.md
|
@ -22,7 +22,7 @@ For more information about the hardware see the [Hardware Manual](http://www.cir
|
||||||
* __Alexei Glushchenko, Circuits@Home__ - <alex-gl@mail.ru>
|
* __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>
|
* __Kristian Lauszus, TKJ Electronics__ - <kristianl@tkjelectronics.com>
|
||||||
* Developer of the [BTD](#bluetooth-libraries), [SPP](#spp-library), [PS3](#ps3-library), [Wii](#wii-library), and [Xbox](#xbox-library) libraries
|
* Developer of the [BTD](#bluetooth-libraries), [BTHID](#bthid-library), [SPP](#spp-library), [PS3](#ps3-library), [Wii](#wii-library), and [Xbox](#xbox-library) libraries
|
||||||
* __Andrew Kroll__ - <xxxajk@gmail.com>
|
* __Andrew Kroll__ - <xxxajk@gmail.com>
|
||||||
* Major contributor to mass storage code
|
* Major contributor to mass storage code
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ Currently the following boards are supported by the library:
|
||||||
|
|
||||||
* All official Arduino AVR boards (Uno, Duemilanove, Mega, Mega 2560, Mega ADK, Leonardo etc.)
|
* All official Arduino AVR boards (Uno, Duemilanove, Mega, Mega 2560, Mega ADK, Leonardo etc.)
|
||||||
* Teensy (Teensy++ 1.0, Teensy 2.0, Teensy++ 2.0, and Teensy 3.0)
|
* Teensy (Teensy++ 1.0, Teensy 2.0, Teensy++ 2.0, and Teensy 3.0)
|
||||||
|
* Note if you are using the Teensy 3.0 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
|
* Balanduino
|
||||||
* Sanguino
|
* Sanguino
|
||||||
* Black Widdow
|
* Black Widdow
|
||||||
|
@ -86,7 +87,15 @@ This library make it easy to add support for different Bluetooth services like a
|
||||||
Some different examples can be found in the [example directory](examples/Bluetooth).
|
Some different examples can be found in the [example directory](examples/Bluetooth).
|
||||||
|
|
||||||
The BTD library will also make it possible to use multiple services at once, the following example sketch is an example of this:
|
The BTD library will also make it possible to use multiple services at once, the following example sketch is an example of this:
|
||||||
<https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/Bluetooth/PS3SPP/PS3SPP.ino>
|
<https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/Bluetooth/PS3SPP/PS3SPP.ino>.
|
||||||
|
|
||||||
|
### [BTHID library](BTHID.cpp)
|
||||||
|
|
||||||
|
The [Bluetooth HID library](BTHID.cpp) allows you to connect HID devices via Bluetooth to the USB Host Shield.
|
||||||
|
|
||||||
|
Currently HID mice and keyboards are supported.
|
||||||
|
|
||||||
|
It uses the standard Boot protocol by default, but it is also able to use the Report protocol as well. You would simply have to call ```setProtocolMode()``` and then parse ```HID_RPT_PROTOCOL``` as an argument. You will then have to modify the parser for your device. See the example: <https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/Bluetooth/BTHID/BTHID.ino> for more information.
|
||||||
|
|
||||||
### [SPP library](SPP.cpp)
|
### [SPP library](SPP.cpp)
|
||||||
|
|
||||||
|
@ -107,7 +116,7 @@ These libraries consist of the [PS3BT](PS3BT.cpp) and [PS3USB](PS3USB.cpp). Thes
|
||||||
|
|
||||||
In order to use your Playstation controller via Bluetooth you have to set the Bluetooth address of the dongle internally to your PS3 Controller. This can be achieved by plugging the controller in via USB and letting the library set it automatically.
|
In order to use your Playstation controller via Bluetooth you have to set the Bluetooth address of the dongle internally to your PS3 Controller. This can be achieved by plugging the controller in via USB and letting the library set it automatically.
|
||||||
|
|
||||||
__Note:__ To obtain the address you have to plug in the Bluetooth dongle before connecting the controller, or alternatively you could set it in code like so: <https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/Bluetooth/PS3BT/PS3BT.ino#L12>.
|
__Note:__ To obtain the address you have to plug in the Bluetooth dongle before connecting the controller, or alternatively you could set it in code like so: <https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/Bluetooth/PS3BT/PS3BT.ino#L15>.
|
||||||
|
|
||||||
For more information about the PS3 protocol see the official wiki: <https://github.com/felis/USB_Host_Shield_2.0/wiki/PS3-Information>.
|
For more information about the PS3 protocol see the official wiki: <https://github.com/felis/USB_Host_Shield_2.0/wiki/PS3-Information>.
|
||||||
|
|
||||||
|
|
46
SPP.cpp
46
SPP.cpp
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SPP.h"
|
#include "SPP.h"
|
||||||
// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h
|
// To enable serial debugging see "settings.h"
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
//#define PRINTREPORT // Uncomment to print the report sent to the Arduino
|
//#define PRINTREPORT // Uncomment to print the report sent to the Arduino
|
||||||
|
|
||||||
|
@ -270,12 +270,19 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
/* Read the incoming message */
|
/* Read the incoming message */
|
||||||
if (rfcommChannelType == RFCOMM_UIH && rfcommChannel == rfcommChannelConnection) {
|
if (rfcommChannelType == RFCOMM_UIH && rfcommChannel == rfcommChannelConnection) {
|
||||||
uint8_t length = l2capinbuf[10] >> 1; // Get length
|
uint8_t length = l2capinbuf[10] >> 1; // Get length
|
||||||
uint8_t offset = l2capinbuf[4] - length - 4; // See if there is credit
|
uint8_t offset = l2capinbuf[4] - length - 4; // Check if there is credit
|
||||||
if (rfcommAvailable + length <= sizeof (rfcommDataBuffer)) { // Don't add data to buffer if it would be full
|
if (checkFcs(&l2capinbuf[8], l2capinbuf[11 + length + offset])) {
|
||||||
for (uint8_t i = 0; i < length; i++)
|
uint8_t i = 0;
|
||||||
rfcommDataBuffer[rfcommAvailable + i] = l2capinbuf[11 + i + offset];
|
for (; i < length; i++) {
|
||||||
rfcommAvailable += length;
|
if (rfcommAvailable + i >= sizeof (rfcommDataBuffer)) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nWarning: Buffer is full!"), 0x80);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
rfcommDataBuffer[rfcommAvailable + i] = l2capinbuf[11 + i + offset];
|
||||||
|
}
|
||||||
|
rfcommAvailable += i;
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("\r\nRFCOMM Data Available: "), 0x80);
|
Notify(PSTR("\r\nRFCOMM Data Available: "), 0x80);
|
||||||
Notify(rfcommAvailable, 0x80);
|
Notify(rfcommAvailable, 0x80);
|
||||||
|
@ -283,6 +290,11 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
Notify(PSTR(" - Credit: 0x"), 0x80);
|
Notify(PSTR(" - Credit: 0x"), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[11], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[11], 0x80);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
else
|
||||||
|
Notify(PSTR("\r\nError in FCS checksum!"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send to the Arduino via Bluetooth
|
#ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send to the Arduino via Bluetooth
|
||||||
for (uint8_t i = 0; i < length; i++)
|
for (uint8_t i = 0; i < length; i++)
|
||||||
|
@ -723,16 +735,24 @@ void SPP::sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CRC on 2 bytes */
|
/* CRC on 2 bytes */
|
||||||
uint8_t SPP::__crc(uint8_t* data) {
|
uint8_t SPP::crc(uint8_t *data) {
|
||||||
return (pgm_read_byte(&rfcomm_crc_table[pgm_read_byte(&rfcomm_crc_table[0xff ^ data[0]]) ^ data[1]]));
|
return (pgm_read_byte(&rfcomm_crc_table[pgm_read_byte(&rfcomm_crc_table[0xFF ^ data[0]]) ^ data[1]]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate FCS - we never actually check if the host sends correct FCS to the Arduino */
|
/* Calculate FCS */
|
||||||
uint8_t SPP::calcFcs(uint8_t *data) {
|
uint8_t SPP::calcFcs(uint8_t *data) {
|
||||||
if ((data[1] & 0xEF) == RFCOMM_UIH)
|
if ((data[1] & 0xEF) == RFCOMM_UIH)
|
||||||
return (0xff - __crc(data)); // FCS on 2 bytes
|
return (0xFF - crc(data)); // FCS on 2 bytes
|
||||||
else
|
else
|
||||||
return (0xff - pgm_read_byte(&rfcomm_crc_table[__crc(data) ^ data[2]])); // FCS on 3 bytes
|
return (0xFF - pgm_read_byte(&rfcomm_crc_table[crc(data) ^ data[2]])); // FCS on 3 bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check FCS */
|
||||||
|
bool SPP::checkFcs(uint8_t *data, uint8_t fcs) {
|
||||||
|
uint8_t temp = crc(data);
|
||||||
|
if ((data[1] & 0xEF) != RFCOMM_UIH)
|
||||||
|
temp = pgm_read_byte(&rfcomm_crc_table[temp ^ data[2]]); // FCS on 3 bytes
|
||||||
|
return (pgm_read_byte(&rfcomm_crc_table[temp ^ fcs]) == 0xCF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Serial commands */
|
/* Serial commands */
|
||||||
|
@ -740,7 +760,7 @@ size_t SPP::write(uint8_t data) {
|
||||||
return write(&data,1);
|
return write(&data,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SPP::write(const uint8_t* data, size_t size) {
|
size_t SPP::write(const uint8_t *data, size_t size) {
|
||||||
for(uint8_t i = 0; i < size; i++) {
|
for(uint8_t i = 0; i < size; i++) {
|
||||||
if(sppIndex >= sizeof(sppOutputBuffer)/sizeof(sppOutputBuffer[0]))
|
if(sppIndex >= sizeof(sppOutputBuffer)/sizeof(sppOutputBuffer[0]))
|
||||||
send(); // Send the current data in the buffer
|
send(); // Send the current data in the buffer
|
||||||
|
@ -781,7 +801,7 @@ int SPP::available(void) {
|
||||||
return rfcommAvailable;
|
return rfcommAvailable;
|
||||||
};
|
};
|
||||||
|
|
||||||
void SPP::flush(void) {
|
void SPP::discard(void) {
|
||||||
rfcommAvailable = 0;
|
rfcommAvailable = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
26
SPP.h
26
SPP.h
|
@ -89,16 +89,19 @@
|
||||||
#define BT_RFCOMM_NSC_RSP 0x11
|
#define BT_RFCOMM_NSC_RSP 0x11
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** This BluetoothService class implements the Serial Port Protocol (SPP). */
|
/**
|
||||||
|
* This BluetoothService class implements the Serial Port Protocol (SPP).
|
||||||
|
* It inherits the Arduino Stream class. This allows it to use all the standard Arduino print functions.
|
||||||
|
*/
|
||||||
class SPP : public BluetoothService, public Stream {
|
class SPP : public BluetoothService, public Stream {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor for the SPP class.
|
* Constructor for the SPP class.
|
||||||
* @param p Pointer to BTD class instance.
|
* @param p Pointer to BTD class instance.
|
||||||
* @param name Set the name to BTD#btdName. If argument is omitted, then "Arduino" will be used.
|
* @param name Set the name to BTD#btdName. If argument is omitted, then "Arduino" will be used.
|
||||||
* @param pin Write the pin to BTD#btdPin. If argument is omitted, then "1234" will be used.
|
* @param pin Write the pin to BTD#btdPin. If argument is omitted, then "0000" will be used.
|
||||||
*/
|
*/
|
||||||
SPP(BTD *p, const char* name = "Arduino", const char* pin = "1234");
|
SPP(BTD *p, const char *name = "Arduino", const char *pin = "0000");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to provide Boolean tests for the class.
|
* Used to provide Boolean tests for the class.
|
||||||
|
@ -130,8 +133,10 @@ public:
|
||||||
* @return Return the number of bytes ready to be read.
|
* @return Return the number of bytes ready to be read.
|
||||||
*/
|
*/
|
||||||
virtual int available(void);
|
virtual int available(void);
|
||||||
/** Discard all the bytes in the buffer. */
|
/** Send out all bytes in the buffer. */
|
||||||
virtual void flush(void);
|
virtual void flush(void) {
|
||||||
|
send();
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Used to read the next value in the buffer without advancing to the next one.
|
* Used to read the next value in the buffer without advancing to the next one.
|
||||||
* @return Return the byte. Will return -1 if no bytes are available.
|
* @return Return the byte. Will return -1 if no bytes are available.
|
||||||
|
@ -157,6 +162,8 @@ public:
|
||||||
virtual size_t write(const uint8_t* data, size_t size);
|
virtual size_t write(const uint8_t* data, size_t size);
|
||||||
/** Pull in write(const char *str) from Print */
|
/** Pull in write(const char *str) from Print */
|
||||||
using Print::write;
|
using Print::write;
|
||||||
|
/** Discard all the bytes in the buffer. */
|
||||||
|
void discard(void);
|
||||||
/**
|
/**
|
||||||
* This will send all the bytes in the buffer.
|
* This will send all the bytes in the buffer.
|
||||||
* This is called whenever Usb.Task() is called,
|
* This is called whenever Usb.Task() is called,
|
||||||
|
@ -215,7 +222,7 @@ private:
|
||||||
void RFCOMM_task(); // RFCOMM state machine
|
void RFCOMM_task(); // RFCOMM state machine
|
||||||
|
|
||||||
/* SDP Commands */
|
/* SDP Commands */
|
||||||
void SDP_Command(uint8_t* data, uint8_t nbytes);
|
void SDP_Command(uint8_t *data, uint8_t nbytes);
|
||||||
void serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow);
|
void serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow);
|
||||||
void serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
|
void serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
|
||||||
void serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
|
void serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
|
||||||
|
@ -223,10 +230,11 @@ private:
|
||||||
void l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
|
void l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
|
||||||
|
|
||||||
/* RFCOMM Commands */
|
/* RFCOMM Commands */
|
||||||
void RFCOMM_Command(uint8_t* data, uint8_t nbytes);
|
void RFCOMM_Command(uint8_t *data, uint8_t nbytes);
|
||||||
void sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t* data, uint8_t length);
|
void sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t *data, uint8_t length);
|
||||||
void sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit);
|
void sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit);
|
||||||
uint8_t calcFcs(uint8_t *data);
|
uint8_t calcFcs(uint8_t *data);
|
||||||
uint8_t __crc(uint8_t* data);
|
bool checkFcs(uint8_t *data, uint8_t fcs);
|
||||||
|
uint8_t crc(uint8_t *data);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
7
Usb.cpp
7
Usb.cpp
|
@ -567,6 +567,7 @@ uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed) {
|
uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
//printf("AttemptConfig: parent = %i, port = %i\r\n", parent, port);
|
//printf("AttemptConfig: parent = %i, port = %i\r\n", parent, port);
|
||||||
|
uint8_t retries = 0;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed);
|
uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed);
|
||||||
|
@ -579,15 +580,17 @@ again:
|
||||||
// reset parent port
|
// reset parent port
|
||||||
devConfig[parent]->ResetHubPort(port);
|
devConfig[parent]->ResetHubPort(port);
|
||||||
}
|
}
|
||||||
} else if (rcode == hrJERR) { // Some devices returns this when plugged in - trying to initialize the device again usually works
|
} else if (rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
|
||||||
delay(100);
|
delay(100);
|
||||||
|
retries++;
|
||||||
goto again;
|
goto again;
|
||||||
} else if (rcode)
|
} else if (rcode)
|
||||||
return rcode;
|
return rcode;
|
||||||
|
|
||||||
rcode = devConfig[driver]->Init(parent, port, lowspeed);
|
rcode = devConfig[driver]->Init(parent, port, lowspeed);
|
||||||
if (rcode == hrJERR) { // Some devices returns this when plugged in - trying to initialize the device again usually works
|
if (rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
|
||||||
delay(100);
|
delay(100);
|
||||||
|
retries++;
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
if (rcode) {
|
if (rcode) {
|
||||||
|
|
|
@ -138,7 +138,7 @@ typedef struct {
|
||||||
} wVal_u;
|
} wVal_u;
|
||||||
uint16_t wIndex; // 4 Depends on bRequest
|
uint16_t wIndex; // 4 Depends on bRequest
|
||||||
uint16_t wLength; // 6 Depends on bRequest
|
uint16_t wLength; // 6 Depends on bRequest
|
||||||
} SETUP_PKT, *PSETUP_PKT __attribute__((packed));
|
}__attribute__((packed)) SETUP_PKT, *PSETUP_PKT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
10
Wii.cpp
10
Wii.cpp
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Wii.h"
|
#include "Wii.h"
|
||||||
// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h
|
// To enable serial debugging see "settings.h"
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
//#define PRINTREPORT // Uncomment to print the report send by the Wii controllers
|
//#define PRINTREPORT // Uncomment to print the report send by the Wii controllers
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
#endif
|
#endif
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) {
|
} else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) {
|
||||||
if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success
|
if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success
|
||||||
if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) { // Success
|
if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) {
|
||||||
//Notify(PSTR("\r\nHID Control Connection Complete"), 0x80);
|
//Notify(PSTR("\r\nHID Control Connection Complete"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
control_scid[0] = l2capinbuf[12];
|
control_scid[0] = l2capinbuf[12];
|
||||||
|
@ -473,11 +473,11 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
pitchGyroSpeed = (double)gyroPitchRaw / ((double)gyroPitchZero / pitchGyroScale);
|
pitchGyroSpeed = (double)gyroPitchRaw / ((double)gyroPitchZero / pitchGyroScale);
|
||||||
|
|
||||||
/* The onboard gyro has two ranges for slow and fast mode */
|
/* The onboard gyro has two ranges for slow and fast mode */
|
||||||
if (!(l2capinbuf[18] & 0x02)) // Check if fast more is used
|
if (!(l2capinbuf[18] & 0x02)) // Check if fast mode is used
|
||||||
yawGyroSpeed *= 4.545;
|
yawGyroSpeed *= 4.545;
|
||||||
if (!(l2capinbuf[18] & 0x01)) // Check if fast more is used
|
if (!(l2capinbuf[18] & 0x01)) // Check if fast mode is used
|
||||||
pitchGyroSpeed *= 4.545;
|
pitchGyroSpeed *= 4.545;
|
||||||
if (!(l2capinbuf[19] & 0x02)) // Check if fast more is used
|
if (!(l2capinbuf[19] & 0x02)) // Check if fast mode is used
|
||||||
rollGyroSpeed *= 4.545;
|
rollGyroSpeed *= 4.545;
|
||||||
|
|
||||||
compPitch = (0.93 * (compPitch + (pitchGyroSpeed * (double)(micros() - timer) / 1000000)))+(0.07 * getWiimotePitch()); // Use a complimentary filter to calculate the angle
|
compPitch = (0.93 * (compPitch + (pitchGyroSpeed * (double)(micros() - timer) / 1000000)))+(0.07 * getWiimotePitch()); // Use a complimentary filter to calculate the angle
|
||||||
|
|
8
Wii.h
8
Wii.h
|
@ -76,8 +76,6 @@
|
||||||
#define motion_plus_connected_flag (l2cap_event_flag & WII_FLAG_MOTION_PLUS_CONNECTED)
|
#define motion_plus_connected_flag (l2cap_event_flag & WII_FLAG_MOTION_PLUS_CONNECTED)
|
||||||
#define nunchuck_connected_flag (l2cap_event_flag & WII_FLAG_NUNCHUCK_CONNECTED)
|
#define nunchuck_connected_flag (l2cap_event_flag & WII_FLAG_NUNCHUCK_CONNECTED)
|
||||||
|
|
||||||
#define PAIR 1
|
|
||||||
|
|
||||||
/** Enum used to read the joystick on the Nunchuck. */
|
/** Enum used to read the joystick on the Nunchuck. */
|
||||||
enum Hat {
|
enum Hat {
|
||||||
/** Read the x-axis on the Nunchuck joystick. */
|
/** Read the x-axis on the Nunchuck joystick. */
|
||||||
|
@ -191,6 +189,10 @@ public:
|
||||||
* @param value See: ::LED enum.
|
* @param value See: ::LED enum.
|
||||||
*/
|
*/
|
||||||
void setLedRaw(uint8_t value);
|
void setLedRaw(uint8_t value);
|
||||||
|
/** Turn all LEDs off. */
|
||||||
|
void setLedOff() {
|
||||||
|
setLedRaw(0);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Turn the specific ::LED off.
|
* Turn the specific ::LED off.
|
||||||
* @param a The ::LED to turn off.
|
* @param a The ::LED to turn off.
|
||||||
|
@ -210,9 +212,7 @@ public:
|
||||||
* This will set the LEDs, so the user can see which connections are active.
|
* This will set the LEDs, so the user can see which connections are active.
|
||||||
*
|
*
|
||||||
* The first ::LED indicate that the Wiimote is connected,
|
* The first ::LED indicate that the Wiimote is connected,
|
||||||
*
|
|
||||||
* the second ::LED indicate indicate that a Motion Plus is also connected
|
* the second ::LED indicate indicate that a Motion Plus is also connected
|
||||||
*
|
|
||||||
* the third ::LED will indicate that a Nunchuck controller is also connected.
|
* the third ::LED will indicate that a Nunchuck controller is also connected.
|
||||||
*/
|
*/
|
||||||
void setLedStatus();
|
void setLedStatus();
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
Please see <http://wiibrew.org/wiki/Wiimote#IR_Camera> for the complete capabilities of the Wii camera. The IR camera code was written based on the above website and with support from Kristian Lauszus.
|
Please see <http://wiibrew.org/wiki/Wiimote#IR_Camera> for the complete capabilities of the Wii camera. The IR camera code was written based on the above website and with support from Kristian Lauszus.
|
||||||
|
|
||||||
Must omit the "." in the name of the USB\_Host\_Shiled\_2.0 library folder when inserting into the Arudino library folder.
|
This library is large, if you run into memory problems when uploading to the Arduino, disable serial debugging.
|
||||||
|
|
||||||
This library is large, if you run into memory problems when uploading to the Arduino, comment out the \#define DEBUG in the BTD.cpp and Wii.cpp files.
|
|
||||||
|
|
||||||
To enable the IR camera code, uncomment \#define WIICAMERA in Wii.h.
|
To enable the IR camera code, uncomment \#define WIICAMERA in Wii.h.
|
||||||
|
|
||||||
|
|
11
XBOXOLD.cpp
11
XBOXOLD.cpp
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "XBOXOLD.h"
|
#include "XBOXOLD.h"
|
||||||
// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h
|
// To enable serial debugging see "settings.h"
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
//#define PRINTREPORT // Uncomment to print the report send by the Xbox controller
|
//#define PRINTREPORT // Uncomment to print the report send by the Xbox controller
|
||||||
|
|
||||||
|
@ -290,15 +290,15 @@ void XBOXOLD::printReport(uint16_t length) { //Uncomment "#define PRINTREPORT" t
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t XBOXOLD::getButtonPress(Button b) {
|
uint8_t XBOXOLD::getButtonPress(Button b) {
|
||||||
|
uint8_t button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]);
|
||||||
if (b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons
|
if (b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons
|
||||||
return buttonValues[pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b])]; // Analog buttons
|
return buttonValues[button]; // Analog buttons
|
||||||
return (ButtonState & pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b])); // Digital buttons
|
return (ButtonState & button); // Digital buttons
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XBOXOLD::getButtonClick(Button b) {
|
bool XBOXOLD::getButtonClick(Button b) {
|
||||||
uint8_t button;
|
uint8_t button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]);
|
||||||
if (b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) { // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons
|
if (b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) { // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons
|
||||||
button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]);
|
|
||||||
if (buttonClicked[button]) {
|
if (buttonClicked[button]) {
|
||||||
buttonClicked[button] = false;
|
buttonClicked[button] = false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -306,7 +306,6 @@ bool XBOXOLD::getButtonClick(Button b) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]); // Digital buttons
|
|
||||||
bool click = (ButtonClickState & button);
|
bool click = (ButtonClickState & button);
|
||||||
ButtonClickState &= ~button; // clear "click" event
|
ButtonClickState &= ~button; // clear "click" event
|
||||||
return click;
|
return click;
|
||||||
|
|
220
XBOXRECV.cpp
220
XBOXRECV.cpp
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "XBOXRECV.h"
|
#include "XBOXRECV.h"
|
||||||
// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h
|
// To enable serial debugging see "settings.h"
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
|
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
|
||||||
|
|
||||||
|
@ -37,29 +37,27 @@ bPollEnable(false) { // don't start polling before dongle is connected
|
||||||
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
|
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
uint8_t XBOXRECV::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
|
const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
|
||||||
|
uint8_t buf[constBufSize];
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
UsbDevice *p = NULL;
|
UsbDevice *p = NULL;
|
||||||
EpInfo *oldep_ptr = NULL;
|
EpInfo *oldep_ptr = NULL;
|
||||||
uint16_t PID;
|
uint16_t PID, VID;
|
||||||
uint16_t VID;
|
|
||||||
|
|
||||||
// get memory address of USB device address pool
|
AddressPool &addrPool = pUsb->GetAddressPool(); // Get memory address of USB device address pool
|
||||||
AddressPool &addrPool = pUsb->GetAddressPool();
|
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("\r\nXBOXRECV Init"), 0x80);
|
Notify(PSTR("\r\nXBOXRECV Init"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
// check if address has already been assigned to an instance
|
|
||||||
if (bAddress) {
|
if (bAddress) { // Check if address has already been assigned to an instance
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress in use"), 0x80);
|
Notify(PSTR("\r\nAddress in use"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get pointer to pseudo device with address 0 assigned
|
p = addrPool.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned
|
||||||
p = addrPool.GetUsbDevicePtr(0);
|
|
||||||
|
|
||||||
if (!p) {
|
if (!p) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
@ -75,18 +73,13 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
return USB_ERROR_EPINFO_IS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save old pointer to EP_RECORD of address 0
|
oldep_ptr = p->epinfo; // Save old pointer to EP_RECORD of address 0
|
||||||
oldep_ptr = p->epinfo;
|
p->epinfo = epInfo; // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
|
||||||
|
|
||||||
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
|
|
||||||
p->epinfo = epInfo;
|
|
||||||
|
|
||||||
p->lowspeed = lowspeed;
|
p->lowspeed = lowspeed;
|
||||||
|
|
||||||
// Get device descriptor
|
rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
|
||||||
rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
|
|
||||||
// Restore p->epinfo
|
p->epinfo = oldep_ptr; // Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
|
@ -94,53 +87,100 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
|
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
|
||||||
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
|
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
|
||||||
|
|
||||||
if (VID != XBOX_VID && VID != MADCATZ_VID) // We just check if it's a Xbox receiver using the Vendor ID
|
if ((VID != XBOX_VID && VID != MADCATZ_VID) || (PID != XBOX_WIRELESS_RECEIVER_PID && PID != XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID)) { // Check if it's a Xbox receiver using the Vendor ID and Product ID
|
||||||
goto FailUnknownDevice;
|
|
||||||
else if (PID != XBOX_WIRELESS_RECEIVER_PID && PID != XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID) { // Check the PID as well
|
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nYou'll need a wireless receiver for this libary to work"), 0x80);
|
Notify(PSTR("\r\nYou'll need a wireless receiver for this libary to work"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
goto FailUnknownDevice;
|
goto FailUnknownDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate new address according to device class
|
bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class
|
||||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
|
||||||
|
|
||||||
if (!bAddress)
|
if (!bAddress) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nOut of address space"), 0x80);
|
||||||
|
#endif
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
}
|
||||||
|
|
||||||
// Extract Max Packet Size from device descriptor
|
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; // Extract Max Packet Size from device descriptor
|
||||||
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
epInfo[1].epAddr = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; // Steal and abuse from epInfo structure to save memory
|
||||||
|
|
||||||
// Assign new address to the device
|
delay(20); // Wait a little before resetting device
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
|
||||||
|
return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET;
|
||||||
|
|
||||||
|
/* Diagnostic messages */
|
||||||
|
FailGetDevDescr:
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
NotifyFailGetDevDescr(rcode);
|
||||||
|
#endif
|
||||||
|
if (rcode != hrJERR)
|
||||||
|
rcode = USB_ERROR_FailGetDevDescr;
|
||||||
|
goto Fail;
|
||||||
|
|
||||||
|
FailUnknownDevice:
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
NotifyFailUnknownDevice(VID,PID);
|
||||||
|
#endif
|
||||||
|
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
Fail:
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
|
||||||
|
NotifyFail(rcode);
|
||||||
|
#endif
|
||||||
|
Release();
|
||||||
|
return rcode;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
uint8_t rcode;
|
||||||
|
uint8_t num_of_conf = epInfo[1].epAddr; // Number of configurations
|
||||||
|
epInfo[1].epAddr = 0;
|
||||||
|
|
||||||
|
AddressPool &addrPool = pUsb->GetAddressPool();
|
||||||
|
#ifdef EXTRADEBUG
|
||||||
|
Notify(PSTR("\r\nBTD Init"), 0x80);
|
||||||
|
#endif
|
||||||
|
UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
|
||||||
|
|
||||||
|
if (!p) {
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nAddress not found"), 0x80);
|
||||||
|
#endif
|
||||||
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(300); // Assign new address to the device
|
||||||
|
|
||||||
|
rcode = pUsb->setAddr(0, 0, bAddress); // Assign new address to the device
|
||||||
if (rcode) {
|
if (rcode) {
|
||||||
p->lowspeed = false;
|
|
||||||
addrPool.FreeAddress(bAddress);
|
|
||||||
bAddress = 0;
|
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nsetAddr: "), 0x80);
|
Notify(PSTR("\r\nsetAddr: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (rcode, 0x80);
|
D_PrintHex<uint8_t > (rcode, 0x80);
|
||||||
#endif
|
#endif
|
||||||
return rcode;
|
p->lowspeed = false;
|
||||||
|
goto Fail;
|
||||||
}
|
}
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("\r\nAddr: "), 0x80);
|
Notify(PSTR("\r\nAddr: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (bAddress, 0x80);
|
D_PrintHex<uint8_t > (bAddress, 0x80);
|
||||||
#endif
|
#endif
|
||||||
delay(300); // Spec says you should wait at least 200ms
|
|
||||||
|
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
|
|
||||||
//get pointer to assigned address record
|
p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
if (!p) {
|
||||||
if (!p)
|
#ifdef DEBUG_USB_HOST
|
||||||
|
Notify(PSTR("\r\nAddress not found"), 0x80);
|
||||||
|
#endif
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
}
|
||||||
|
|
||||||
p->lowspeed = lowspeed;
|
p->lowspeed = lowspeed;
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer - only EP0 is known
|
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
|
@ -216,9 +256,10 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
#endif
|
#endif
|
||||||
XboxReceiverConnected = true;
|
XboxReceiverConnected = true;
|
||||||
bPollEnable = true;
|
bPollEnable = true;
|
||||||
return 0; // successful configuration
|
checkStatusTimer = 0; // Reset timer
|
||||||
|
return 0; // Successful configuration
|
||||||
|
|
||||||
/* diagnostic messages */
|
/* Diagnostic messages */
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
NotifyFailGetDevDescr();
|
NotifyFailGetDevDescr();
|
||||||
|
@ -237,12 +278,6 @@ FailSetConfDescr:
|
||||||
#endif
|
#endif
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailUnknownDevice:
|
|
||||||
#ifdef DEBUG_USB_HOST
|
|
||||||
NotifyFailUnknownDevice(VID,PID);
|
|
||||||
#endif
|
|
||||||
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
|
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
|
||||||
|
@ -266,23 +301,23 @@ uint8_t XBOXRECV::Release() {
|
||||||
uint8_t XBOXRECV::Poll() {
|
uint8_t XBOXRECV::Poll() {
|
||||||
if (!bPollEnable)
|
if (!bPollEnable)
|
||||||
return 0;
|
return 0;
|
||||||
if (!timer || ((millis() - timer) > 3000)) { // Run checkStatus every 3 seconds
|
if (!checkStatusTimer || ((millis() - checkStatusTimer) > 3000)) { // Run checkStatus every 3 seconds
|
||||||
timer = millis();
|
checkStatusTimer = millis();
|
||||||
checkStatus();
|
checkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t inputPipe;
|
uint8_t inputPipe;
|
||||||
uint16_t bufferSize;
|
uint16_t bufferSize;
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
switch (i) {
|
if (i == 0)
|
||||||
case 0: inputPipe = XBOX_INPUT_PIPE_1;
|
inputPipe = XBOX_INPUT_PIPE_1;
|
||||||
break;
|
else if (i == 1)
|
||||||
case 1: inputPipe = XBOX_INPUT_PIPE_2;
|
inputPipe = XBOX_INPUT_PIPE_2;
|
||||||
break;
|
else if (i == 2)
|
||||||
case 2: inputPipe = XBOX_INPUT_PIPE_3;
|
inputPipe = XBOX_INPUT_PIPE_3;
|
||||||
break;
|
else
|
||||||
case 3: inputPipe = XBOX_INPUT_PIPE_4;
|
inputPipe = XBOX_INPUT_PIPE_4;
|
||||||
break;
|
|
||||||
}
|
|
||||||
bufferSize = EP_MAXPKTSIZE; // This is the maximum number of bytes we want to receive
|
bufferSize = EP_MAXPKTSIZE; // This is the maximum number of bytes we want to receive
|
||||||
pUsb->inTransfer(bAddress, epInfo[ inputPipe ].epAddr, &bufferSize, readBuf);
|
pUsb->inTransfer(bAddress, epInfo[ inputPipe ].epAddr, &bufferSize, readBuf);
|
||||||
if (bufferSize > 0) { // The number of received bytes
|
if (bufferSize > 0) { // The number of received bytes
|
||||||
|
@ -420,47 +455,54 @@ bool XBOXRECV::buttonChanged(uint8_t controller) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ControllerStatus Breakdown
|
ControllerStatus Breakdown
|
||||||
ControllerStatus[controller] & 0x0001 // 0
|
ControllerStatus[controller] & 0x0001 // 0
|
||||||
ControllerStatus[controller] & 0x0002 // normal batteries, no rechargeable battery pack
|
ControllerStatus[controller] & 0x0002 // normal batteries, no rechargeable battery pack
|
||||||
ControllerStatus[controller] & 0x0004 // controller starting up / settling
|
ControllerStatus[controller] & 0x0004 // controller starting up / settling
|
||||||
ControllerStatus[controller] & 0x0008 // headset adapter plugged in, but no headphones connected (mute?)
|
ControllerStatus[controller] & 0x0008 // headset adapter plugged in, but no headphones connected (mute?)
|
||||||
ControllerStatus[controller] & 0x0010 // 0
|
ControllerStatus[controller] & 0x0010 // 0
|
||||||
ControllerStatus[controller] & 0x0020 // 1
|
ControllerStatus[controller] & 0x0020 // 1
|
||||||
ControllerStatus[controller] & 0x0040 // battery level (high bit)
|
ControllerStatus[controller] & 0x0040 // battery level (high bit)
|
||||||
ControllerStatus[controller] & 0x0080 // battery level (low bit)
|
ControllerStatus[controller] & 0x0080 // battery level (low bit)
|
||||||
ControllerStatus[controller] & 0x0100 // 1
|
ControllerStatus[controller] & 0x0100 // 1
|
||||||
ControllerStatus[controller] & 0x0200 // 1
|
ControllerStatus[controller] & 0x0200 // 1
|
||||||
ControllerStatus[controller] & 0x0400 // headset adapter plugged in
|
ControllerStatus[controller] & 0x0400 // headset adapter plugged in
|
||||||
ControllerStatus[controller] & 0x0800 // 0
|
ControllerStatus[controller] & 0x0800 // 0
|
||||||
ControllerStatus[controller] & 0x1000 // 1
|
ControllerStatus[controller] & 0x1000 // 1
|
||||||
ControllerStatus[controller] & 0x2000 // 0
|
ControllerStatus[controller] & 0x2000 // 0
|
||||||
ControllerStatus[controller] & 0x4000 // 0
|
ControllerStatus[controller] & 0x4000 // 0
|
||||||
ControllerStatus[controller] & 0x8000 // 0
|
ControllerStatus[controller] & 0x8000 // 0
|
||||||
*/
|
*/
|
||||||
uint8_t XBOXRECV::getBatteryLevel(uint8_t controller) {
|
uint8_t XBOXRECV::getBatteryLevel(uint8_t controller) {
|
||||||
return ((controllerStatus[controller] & 0x00C0) >> 6);
|
return ((controllerStatus[controller] & 0x00C0) >> 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) {
|
void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) {
|
||||||
uint8_t rcode;
|
|
||||||
uint8_t outputPipe;
|
uint8_t outputPipe;
|
||||||
switch (controller) {
|
if (controller == 0)
|
||||||
case 0: outputPipe = XBOX_OUTPUT_PIPE_1;
|
outputPipe = XBOX_OUTPUT_PIPE_1;
|
||||||
break;
|
else if (controller == 1)
|
||||||
case 1: outputPipe = XBOX_OUTPUT_PIPE_2;
|
outputPipe = XBOX_OUTPUT_PIPE_2;
|
||||||
break;
|
else if (controller == 2)
|
||||||
case 2: outputPipe = XBOX_OUTPUT_PIPE_3;
|
outputPipe = XBOX_OUTPUT_PIPE_3;
|
||||||
break;
|
else
|
||||||
case 3: outputPipe = XBOX_OUTPUT_PIPE_4;
|
outputPipe = XBOX_OUTPUT_PIPE_4;
|
||||||
break;
|
|
||||||
}
|
uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ outputPipe ].epAddr, nbytes, data);
|
||||||
rcode = pUsb->outTransfer(bAddress, epInfo[ outputPipe ].epAddr, nbytes, data);
|
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
if (rcode)
|
if (rcode)
|
||||||
Notify(PSTR("Error sending Xbox message\r\n"), 0x80);
|
Notify(PSTR("Error sending Xbox message\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XBOXRECV::disconnect(uint8_t controller) {
|
||||||
|
writeBuf[0] = 0x00;
|
||||||
|
writeBuf[1] = 0x00;
|
||||||
|
writeBuf[2] = 0x08;
|
||||||
|
writeBuf[3] = 0xC0;
|
||||||
|
|
||||||
|
XboxCommand(controller, writeBuf, 4);
|
||||||
|
}
|
||||||
|
|
||||||
void XBOXRECV::setLedRaw(uint8_t value, uint8_t controller) {
|
void XBOXRECV::setLedRaw(uint8_t value, uint8_t controller) {
|
||||||
writeBuf[0] = 0x00;
|
writeBuf[0] = 0x00;
|
||||||
writeBuf[1] = 0x00;
|
writeBuf[1] = 0x00;
|
||||||
|
|
16
XBOXRECV.h
16
XBOXRECV.h
|
@ -64,6 +64,14 @@ public:
|
||||||
XBOXRECV(USB *pUsb);
|
XBOXRECV(USB *pUsb);
|
||||||
|
|
||||||
/** @name USBDeviceConfig implementation */
|
/** @name USBDeviceConfig implementation */
|
||||||
|
/**
|
||||||
|
* Address assignment and basic initilization is done here.
|
||||||
|
* @param parent Hub number.
|
||||||
|
* @param port Port number on the hub.
|
||||||
|
* @param lowspeed Speed of the device.
|
||||||
|
* @return 0 on success.
|
||||||
|
*/
|
||||||
|
virtual uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed);
|
||||||
/**
|
/**
|
||||||
* Initialize the Xbox wireless receiver.
|
* Initialize the Xbox wireless receiver.
|
||||||
* @param parent Hub number.
|
* @param parent Hub number.
|
||||||
|
@ -136,6 +144,12 @@ public:
|
||||||
*/
|
*/
|
||||||
int16_t getAnalogHat(AnalogHat a, uint8_t controller = 0);
|
int16_t getAnalogHat(AnalogHat a, uint8_t controller = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to disconnect any of the controllers.
|
||||||
|
* @param controller The controller to disconnect. Default to 0.
|
||||||
|
*/
|
||||||
|
void disconnect(uint8_t controller = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turn rumble off and all the LEDs on the specific controller.
|
* Turn rumble off and all the LEDs on the specific controller.
|
||||||
* @param controller The controller to write to. Default to 0.
|
* @param controller The controller to write to. Default to 0.
|
||||||
|
@ -251,7 +265,7 @@ private:
|
||||||
bool L2Clicked[4]; // These buttons are analog, so we use we use these bools to check if they where clicked or not
|
bool L2Clicked[4]; // These buttons are analog, so we use we use these bools to check if they where clicked or not
|
||||||
bool R2Clicked[4];
|
bool R2Clicked[4];
|
||||||
|
|
||||||
unsigned long timer; // Timing for checkStatus() signals
|
uint32_t checkStatusTimer; // Timing for checkStatus() signals
|
||||||
|
|
||||||
uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
|
uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
|
||||||
uint8_t writeBuf[7]; // General purpose buffer for output data
|
uint8_t writeBuf[7]; // General purpose buffer for output data
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "XBOXUSB.h"
|
#include "XBOXUSB.h"
|
||||||
// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h
|
// To enable serial debugging see "settings.h"
|
||||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||||
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
|
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
|
||||||
|
|
||||||
|
|
47
examples/Bluetooth/BTHID/BTHID.ino
Normal file
47
examples/Bluetooth/BTHID/BTHID.ino
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
Example sketch for the HID Bluetooth library - developed by Kristian Lauszus
|
||||||
|
For more information visit my blog: http://blog.tkjelectronics.dk/ or
|
||||||
|
send me an e-mail: kristianl@tkjelectronics.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <BTHID.h>
|
||||||
|
#include <usbhub.h>
|
||||||
|
#include "KeyboardParser.h"
|
||||||
|
#include "MouseParser.h"
|
||||||
|
|
||||||
|
USB Usb;
|
||||||
|
//USBHub Hub1(&Usb); // Some dongles have a hub inside
|
||||||
|
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
||||||
|
|
||||||
|
/* You can create the instance of the class in two ways */
|
||||||
|
// This will start an inquiry and then pair with your device - you only have to do this once
|
||||||
|
// If you are using a Bluetooth keyboard, then you should type in the password on the keypad and then press enter
|
||||||
|
BTHID hid(&Btd, PAIR, "0000");
|
||||||
|
|
||||||
|
// After that you can simply create the instance like so and then press any button on the device
|
||||||
|
//BTHID hid(&Btd);
|
||||||
|
|
||||||
|
KbdRptParser keyboardPrs;
|
||||||
|
MouseRptParser mousePrs;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
|
||||||
|
if (Usb.Init() == -1) {
|
||||||
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
|
while (1); // Halt
|
||||||
|
}
|
||||||
|
|
||||||
|
hid.SetReportParser(KEYBOARD_PARSER_ID, (HIDReportParser*)&keyboardPrs);
|
||||||
|
hid.SetReportParser(MOUSE_PARSER_ID, (HIDReportParser*)&mousePrs);
|
||||||
|
|
||||||
|
// If "Boot Protocol Mode" does not work, then try "Report Protocol Mode"
|
||||||
|
// If that does not work either, then uncomment PRINTREPORT in BTHID.cpp to see the raw report
|
||||||
|
hid.setProtocolMode(HID_BOOT_PROTOCOL); // Boot Protocol Mode
|
||||||
|
//hid.setProtocolMode(HID_RPT_PROTOCOL); // Report Protocol Mode
|
||||||
|
|
||||||
|
Serial.print(F("\r\nHID Bluetooth Library Started"));
|
||||||
|
}
|
||||||
|
void loop() {
|
||||||
|
Usb.Task();
|
||||||
|
}
|
105
examples/Bluetooth/BTHID/KeyboardParser.h
Normal file
105
examples/Bluetooth/BTHID/KeyboardParser.h
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
#ifndef __kbdrptparser_h_
|
||||||
|
#define __kbdrptparser_h_
|
||||||
|
|
||||||
|
class KbdRptParser : public KeyboardReportParser {
|
||||||
|
protected:
|
||||||
|
virtual uint8_t HandleLockingKeys(HID *hid, uint8_t key);
|
||||||
|
virtual void OnControlKeysChanged(uint8_t before, uint8_t after);
|
||||||
|
virtual void OnKeyDown(uint8_t mod, uint8_t key);
|
||||||
|
virtual void OnKeyUp(uint8_t mod, uint8_t key);
|
||||||
|
virtual void OnKeyPressed(uint8_t key);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void PrintKey(uint8_t mod, uint8_t key);
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t KbdRptParser::HandleLockingKeys(HID *hid, uint8_t key) {
|
||||||
|
uint8_t old_keys = kbdLockingKeys.bLeds;
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case KEY_NUM_LOCK:
|
||||||
|
Serial.println(F("Num lock"));
|
||||||
|
kbdLockingKeys.kbdLeds.bmNumLock = ~kbdLockingKeys.kbdLeds.bmNumLock;
|
||||||
|
break;
|
||||||
|
case KEY_CAPS_LOCK:
|
||||||
|
Serial.println(F("Caps lock"));
|
||||||
|
kbdLockingKeys.kbdLeds.bmCapsLock = ~kbdLockingKeys.kbdLeds.bmCapsLock;
|
||||||
|
break;
|
||||||
|
case KEY_SCROLL_LOCK:
|
||||||
|
Serial.println(F("Scroll lock"));
|
||||||
|
kbdLockingKeys.kbdLeds.bmScrollLock = ~kbdLockingKeys.kbdLeds.bmScrollLock;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_keys != kbdLockingKeys.bLeds && hid) {
|
||||||
|
BTHID *pBTHID = reinterpret_cast<BTHID *> (hid); // A cast the other way around is done in BTHID.cpp
|
||||||
|
pBTHID->setLeds(kbdLockingKeys.bLeds); // Update the LEDs on the keyboard
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
void KbdRptParser::PrintKey(uint8_t m, uint8_t key) {
|
||||||
|
MODIFIERKEYS mod;
|
||||||
|
*((uint8_t*)&mod) = m;
|
||||||
|
Serial.print((mod.bmLeftCtrl == 1) ? F("C") : F(" "));
|
||||||
|
Serial.print((mod.bmLeftShift == 1) ? F("S") : F(" "));
|
||||||
|
Serial.print((mod.bmLeftAlt == 1) ? F("A") : F(" "));
|
||||||
|
Serial.print((mod.bmLeftGUI == 1) ? F("G") : F(" "));
|
||||||
|
|
||||||
|
Serial.print(F(" >"));
|
||||||
|
PrintHex<uint8_t>(key, 0x80);
|
||||||
|
Serial.print(F("< "));
|
||||||
|
|
||||||
|
Serial.print((mod.bmRightCtrl == 1) ? F("C") : F(" "));
|
||||||
|
Serial.print((mod.bmRightShift == 1) ? F("S") : F(" "));
|
||||||
|
Serial.print((mod.bmRightAlt == 1) ? F("A") : F(" "));
|
||||||
|
Serial.println((mod.bmRightGUI == 1) ? F("G") : F(" "));
|
||||||
|
};
|
||||||
|
|
||||||
|
void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key) {
|
||||||
|
Serial.print(F("DN "));
|
||||||
|
PrintKey(mod, key);
|
||||||
|
uint8_t c = OemToAscii(mod, key);
|
||||||
|
|
||||||
|
if (c)
|
||||||
|
OnKeyPressed(c);
|
||||||
|
};
|
||||||
|
|
||||||
|
void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) {
|
||||||
|
MODIFIERKEYS beforeMod;
|
||||||
|
*((uint8_t*)&beforeMod) = before;
|
||||||
|
|
||||||
|
MODIFIERKEYS afterMod;
|
||||||
|
*((uint8_t*)&afterMod) = after;
|
||||||
|
|
||||||
|
if (beforeMod.bmLeftCtrl != afterMod.bmLeftCtrl)
|
||||||
|
Serial.println(F("LeftCtrl changed"));
|
||||||
|
if (beforeMod.bmLeftShift != afterMod.bmLeftShift)
|
||||||
|
Serial.println(F("LeftShift changed"));
|
||||||
|
if (beforeMod.bmLeftAlt != afterMod.bmLeftAlt)
|
||||||
|
Serial.println(F("LeftAlt changed"));
|
||||||
|
if (beforeMod.bmLeftGUI != afterMod.bmLeftGUI)
|
||||||
|
Serial.println(F("LeftGUI changed"));
|
||||||
|
|
||||||
|
if (beforeMod.bmRightCtrl != afterMod.bmRightCtrl)
|
||||||
|
Serial.println(F("RightCtrl changed"));
|
||||||
|
if (beforeMod.bmRightShift != afterMod.bmRightShift)
|
||||||
|
Serial.println(F("RightShift changed"));
|
||||||
|
if (beforeMod.bmRightAlt != afterMod.bmRightAlt)
|
||||||
|
Serial.println(F("RightAlt changed"));
|
||||||
|
if (beforeMod.bmRightGUI != afterMod.bmRightGUI)
|
||||||
|
Serial.println(F("RightGUI changed"));
|
||||||
|
};
|
||||||
|
|
||||||
|
void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key) {
|
||||||
|
Serial.print(F("UP "));
|
||||||
|
PrintKey(mod, key);
|
||||||
|
};
|
||||||
|
|
||||||
|
void KbdRptParser::OnKeyPressed(uint8_t key) {
|
||||||
|
Serial.print(F("ASCII: "));
|
||||||
|
Serial.println((char)key);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
46
examples/Bluetooth/BTHID/MouseParser.h
Normal file
46
examples/Bluetooth/BTHID/MouseParser.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef __mouserptparser_h__
|
||||||
|
#define __mouserptparser_h__
|
||||||
|
|
||||||
|
class MouseRptParser : public MouseReportParser {
|
||||||
|
protected:
|
||||||
|
virtual void OnMouseMove(MOUSEINFO *mi);
|
||||||
|
virtual void OnLeftButtonUp(MOUSEINFO *mi);
|
||||||
|
virtual void OnLeftButtonDown(MOUSEINFO *mi);
|
||||||
|
virtual void OnRightButtonUp(MOUSEINFO *mi);
|
||||||
|
virtual void OnRightButtonDown(MOUSEINFO *mi);
|
||||||
|
virtual void OnMiddleButtonUp(MOUSEINFO *mi);
|
||||||
|
virtual void OnMiddleButtonDown(MOUSEINFO *mi);
|
||||||
|
};
|
||||||
|
|
||||||
|
void MouseRptParser::OnMouseMove(MOUSEINFO *mi) {
|
||||||
|
Serial.print(F("dx="));
|
||||||
|
Serial.print(mi->dX, DEC);
|
||||||
|
Serial.print(F(" dy="));
|
||||||
|
Serial.println(mi->dY, DEC);
|
||||||
|
};
|
||||||
|
|
||||||
|
void MouseRptParser::OnLeftButtonUp(MOUSEINFO *mi) {
|
||||||
|
Serial.println(F("L Butt Up"));
|
||||||
|
};
|
||||||
|
|
||||||
|
void MouseRptParser::OnLeftButtonDown(MOUSEINFO *mi) {
|
||||||
|
Serial.println(F("L Butt Dn"));
|
||||||
|
};
|
||||||
|
|
||||||
|
void MouseRptParser::OnRightButtonUp(MOUSEINFO *mi) {
|
||||||
|
Serial.println(F("R Butt Up"));
|
||||||
|
};
|
||||||
|
|
||||||
|
void MouseRptParser::OnRightButtonDown(MOUSEINFO *mi) {
|
||||||
|
Serial.println(F("R Butt Dn"));
|
||||||
|
};
|
||||||
|
|
||||||
|
void MouseRptParser::OnMiddleButtonUp(MOUSEINFO *mi) {
|
||||||
|
Serial.println(F("M Butt Up"));
|
||||||
|
};
|
||||||
|
|
||||||
|
void MouseRptParser::OnMiddleButtonDown(MOUSEINFO *mi) {
|
||||||
|
Serial.println(F("M Butt Dn"));
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -8,7 +8,8 @@
|
||||||
#include <usbhub.h>
|
#include <usbhub.h>
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
USBHub Hub1(&Usb); // Some dongles have a hub inside
|
//USBHub Hub1(&Usb); // Some dongles have a hub inside
|
||||||
|
|
||||||
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
||||||
/* You can create the instance of the class in two ways */
|
/* You can create the instance of the class in two ways */
|
||||||
PS3BT PS3(&Btd); // This will just create the instance
|
PS3BT PS3(&Btd); // This will just create the instance
|
||||||
|
@ -22,20 +23,20 @@ void setup() {
|
||||||
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
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); //halt
|
while (1); //halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nPS3 Bluetooth Library Started"));
|
Serial.print(F("\r\nPS3 Bluetooth Library Started"));
|
||||||
}
|
}
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task();
|
Usb.Task();
|
||||||
|
|
||||||
if(PS3.PS3Connected || PS3.PS3NavigationConnected) {
|
if (PS3.PS3Connected || PS3.PS3NavigationConnected) {
|
||||||
if(PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
|
if (PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
|
||||||
Serial.print(F("\r\nLeftHatX: "));
|
Serial.print(F("\r\nLeftHatX: "));
|
||||||
Serial.print(PS3.getAnalogHat(LeftHatX));
|
Serial.print(PS3.getAnalogHat(LeftHatX));
|
||||||
Serial.print(F("\tLeftHatY: "));
|
Serial.print(F("\tLeftHatY: "));
|
||||||
Serial.print(PS3.getAnalogHat(LeftHatY));
|
Serial.print(PS3.getAnalogHat(LeftHatY));
|
||||||
if(!PS3.PS3NavigationConnected) {
|
if (PS3.PS3Connected) { // The Navigation controller only have one joystick
|
||||||
Serial.print(F("\tRightHatX: "));
|
Serial.print(F("\tRightHatX: "));
|
||||||
Serial.print(PS3.getAnalogHat(RightHatX));
|
Serial.print(PS3.getAnalogHat(RightHatX));
|
||||||
Serial.print(F("\tRightHatY: "));
|
Serial.print(F("\tRightHatY: "));
|
||||||
|
@ -43,131 +44,131 @@ void loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Analog button values can be read from almost all buttons
|
// Analog button values can be read from almost all buttons
|
||||||
if(PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) {
|
if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) {
|
||||||
Serial.print(F("\r\nL2: "));
|
Serial.print(F("\r\nL2: "));
|
||||||
Serial.print(PS3.getAnalogButton(L2));
|
Serial.print(PS3.getAnalogButton(L2));
|
||||||
if(!PS3.PS3NavigationConnected) {
|
if (!PS3.PS3NavigationConnected) {
|
||||||
Serial.print(F("\tR2: "));
|
Serial.print(F("\tR2: "));
|
||||||
Serial.print(PS3.getAnalogButton(R2));
|
Serial.print(PS3.getAnalogButton(R2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(PS)) {
|
if (PS3.getButtonClick(PS)) {
|
||||||
Serial.print(F("\r\nPS"));
|
Serial.print(F("\r\nPS"));
|
||||||
PS3.disconnect();
|
PS3.disconnect();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(PS3.getButtonClick(TRIANGLE))
|
if (PS3.getButtonClick(TRIANGLE))
|
||||||
Serial.print(F("\r\nTraingle"));
|
Serial.print(F("\r\nTraingle"));
|
||||||
if(PS3.getButtonClick(CIRCLE))
|
if (PS3.getButtonClick(CIRCLE))
|
||||||
Serial.print(F("\r\nCircle"));
|
Serial.print(F("\r\nCircle"));
|
||||||
if(PS3.getButtonClick(CROSS))
|
if (PS3.getButtonClick(CROSS))
|
||||||
Serial.print(F("\r\nCross"));
|
Serial.print(F("\r\nCross"));
|
||||||
if(PS3.getButtonClick(SQUARE))
|
if (PS3.getButtonClick(SQUARE))
|
||||||
Serial.print(F("\r\nSquare"));
|
Serial.print(F("\r\nSquare"));
|
||||||
|
|
||||||
if(PS3.getButtonClick(UP)) {
|
if (PS3.getButtonClick(UP)) {
|
||||||
Serial.print(F("\r\nUp"));
|
Serial.print(F("\r\nUp"));
|
||||||
if(PS3.PS3Connected) {
|
if (PS3.PS3Connected) {
|
||||||
PS3.setAllOff();
|
PS3.setLedOff();
|
||||||
PS3.setLedOn(LED4);
|
PS3.setLedOn(LED4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(RIGHT)) {
|
if (PS3.getButtonClick(RIGHT)) {
|
||||||
Serial.print(F("\r\nRight"));
|
Serial.print(F("\r\nRight"));
|
||||||
if(PS3.PS3Connected) {
|
if (PS3.PS3Connected) {
|
||||||
PS3.setAllOff();
|
PS3.setLedOff();
|
||||||
PS3.setLedOn(LED1);
|
PS3.setLedOn(LED1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(DOWN)) {
|
if (PS3.getButtonClick(DOWN)) {
|
||||||
Serial.print(F("\r\nDown"));
|
Serial.print(F("\r\nDown"));
|
||||||
if(PS3.PS3Connected) {
|
if (PS3.PS3Connected) {
|
||||||
PS3.setAllOff();
|
PS3.setLedOff();
|
||||||
PS3.setLedOn(LED2);
|
PS3.setLedOn(LED2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(LEFT)) {
|
if (PS3.getButtonClick(LEFT)) {
|
||||||
Serial.print(F("\r\nLeft"));
|
Serial.print(F("\r\nLeft"));
|
||||||
if(PS3.PS3Connected) {
|
if (PS3.PS3Connected) {
|
||||||
PS3.setAllOff();
|
PS3.setLedOff();
|
||||||
PS3.setLedOn(LED3);
|
PS3.setLedOn(LED3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(PS3.getButtonClick(L1))
|
if (PS3.getButtonClick(L1))
|
||||||
Serial.print(F("\r\nL1"));
|
Serial.print(F("\r\nL1"));
|
||||||
if(PS3.getButtonClick(L3))
|
if (PS3.getButtonClick(L3))
|
||||||
Serial.print(F("\r\nL3"));
|
Serial.print(F("\r\nL3"));
|
||||||
if(PS3.getButtonClick(R1))
|
if (PS3.getButtonClick(R1))
|
||||||
Serial.print(F("\r\nR1"));
|
Serial.print(F("\r\nR1"));
|
||||||
if(PS3.getButtonClick(R3))
|
if (PS3.getButtonClick(R3))
|
||||||
Serial.print(F("\r\nR3"));
|
Serial.print(F("\r\nR3"));
|
||||||
|
|
||||||
if(PS3.getButtonClick(SELECT)) {
|
if (PS3.getButtonClick(SELECT)) {
|
||||||
Serial.print(F("\r\nSelect - "));
|
Serial.print(F("\r\nSelect - "));
|
||||||
Serial.print(PS3.getStatusString());
|
Serial.print(PS3.getStatusString());
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(START)) {
|
if (PS3.getButtonClick(START)) {
|
||||||
Serial.print(F("\r\nStart"));
|
Serial.print(F("\r\nStart"));
|
||||||
printAngle = !printAngle;
|
printAngle = !printAngle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(printAngle) {
|
if (printAngle) {
|
||||||
Serial.print(F("\r\nPitch: "));
|
Serial.print(F("\r\nPitch: "));
|
||||||
Serial.print(PS3.getAngle(Pitch));
|
Serial.print(PS3.getAngle(Pitch));
|
||||||
Serial.print(F("\tRoll: "));
|
Serial.print(F("\tRoll: "));
|
||||||
Serial.print(PS3.getAngle(Roll));
|
Serial.print(PS3.getAngle(Roll));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(PS3.PS3MoveConnected) {
|
else if (PS3.PS3MoveConnected) {
|
||||||
if(PS3.getAnalogButton(T)) {
|
if (PS3.getAnalogButton(T)) {
|
||||||
Serial.print(F("\r\nT: "));
|
Serial.print(F("\r\nT: "));
|
||||||
Serial.print(PS3.getAnalogButton(T));
|
Serial.print(PS3.getAnalogButton(T));
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(PS)) {
|
if (PS3.getButtonClick(PS)) {
|
||||||
Serial.print(F("\r\nPS"));
|
Serial.print(F("\r\nPS"));
|
||||||
PS3.disconnect();
|
PS3.disconnect();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(PS3.getButtonClick(SELECT)) {
|
if (PS3.getButtonClick(SELECT)) {
|
||||||
Serial.print(F("\r\nSelect"));
|
Serial.print(F("\r\nSelect"));
|
||||||
printTemperature = !printTemperature;
|
printTemperature = !printTemperature;
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(START)) {
|
if (PS3.getButtonClick(START)) {
|
||||||
Serial.print(F("\r\nStart"));
|
Serial.print(F("\r\nStart"));
|
||||||
printAngle = !printAngle;
|
printAngle = !printAngle;
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(TRIANGLE)) {
|
if (PS3.getButtonClick(TRIANGLE)) {
|
||||||
Serial.print(F("\r\nTriangle"));
|
Serial.print(F("\r\nTriangle"));
|
||||||
PS3.moveSetBulb(Red);
|
PS3.moveSetBulb(Red);
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(CIRCLE)) {
|
if (PS3.getButtonClick(CIRCLE)) {
|
||||||
Serial.print(F("\r\nCircle"));
|
Serial.print(F("\r\nCircle"));
|
||||||
PS3.moveSetBulb(Green);
|
PS3.moveSetBulb(Green);
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(SQUARE)) {
|
if (PS3.getButtonClick(SQUARE)) {
|
||||||
Serial.print(F("\r\nSquare"));
|
Serial.print(F("\r\nSquare"));
|
||||||
PS3.moveSetBulb(Blue);
|
PS3.moveSetBulb(Blue);
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(CROSS)) {
|
if (PS3.getButtonClick(CROSS)) {
|
||||||
Serial.print(F("\r\nCross"));
|
Serial.print(F("\r\nCross"));
|
||||||
PS3.moveSetBulb(Yellow);
|
PS3.moveSetBulb(Yellow);
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(MOVE)) {
|
if (PS3.getButtonClick(MOVE)) {
|
||||||
PS3.moveSetBulb(Off);
|
PS3.moveSetBulb(Off);
|
||||||
Serial.print(F("\r\nMove"));
|
Serial.print(F("\r\nMove"));
|
||||||
Serial.print(F(" - "));
|
Serial.print(F(" - "));
|
||||||
Serial.print(PS3.getStatusString());
|
Serial.print(PS3.getStatusString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(printAngle) {
|
if (printAngle) {
|
||||||
Serial.print(F("\r\nPitch: "));
|
Serial.print(F("\r\nPitch: "));
|
||||||
Serial.print(PS3.getAngle(Pitch));
|
Serial.print(PS3.getAngle(Pitch));
|
||||||
Serial.print(F("\tRoll: "));
|
Serial.print(F("\tRoll: "));
|
||||||
Serial.print(PS3.getAngle(Roll));
|
Serial.print(PS3.getAngle(Roll));
|
||||||
}
|
}
|
||||||
else if(printTemperature) {
|
else if (printTemperature) {
|
||||||
Serial.print(F("\r\nTemperature: "));
|
Serial.print(F("\r\nTemperature: "));
|
||||||
Serial.print(PS3.getTemperature());
|
Serial.print(PS3.getTemperature());
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,16 @@
|
||||||
#include <usbhub.h>
|
#include <usbhub.h>
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
USBHub Hub1(&Usb); // Some dongles have a hub inside
|
//USBHub Hub1(&Usb); // Some dongles have a hub inside
|
||||||
|
|
||||||
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
||||||
PS3BT *PS3[2]; // We will use this pointer to store the two instance, you can easily make it larger if you like, but it will use a lot of RAM!
|
PS3BT *PS3[2]; // We will use this pointer to store the two instance, you can easily make it larger if you like, but it will use a lot of RAM!
|
||||||
const uint8_t length = sizeof(PS3)/sizeof(PS3[0]); // Get the lenght of the array
|
const uint8_t length = sizeof(PS3) / sizeof(PS3[0]); // Get the lenght of the array
|
||||||
boolean printAngle[length];
|
boolean printAngle[length];
|
||||||
boolean oldControllerState[length];
|
boolean oldControllerState[length];
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
for (uint8_t i=0;i<length;i++) {
|
for (uint8_t i = 0; i < length; i++) {
|
||||||
PS3[i] = new PS3BT(&Btd); // Create the instances
|
PS3[i] = new PS3BT(&Btd); // Create the instances
|
||||||
PS3[i]->attachOnInit(onInit); // onInit() is called upon a new connection - you can call the function whatever you like
|
PS3[i]->attachOnInit(onInit); // onInit() is called upon a new connection - you can call the function whatever you like
|
||||||
}
|
}
|
||||||
|
@ -26,21 +27,21 @@ void setup() {
|
||||||
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
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); //halt
|
while (1); //halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nPS3 Bluetooth Library Started"));
|
Serial.print(F("\r\nPS3 Bluetooth Library Started"));
|
||||||
}
|
}
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task();
|
Usb.Task();
|
||||||
|
|
||||||
for(uint8_t i=0;i<length;i++) {
|
for (uint8_t i = 0; i < length; i++) {
|
||||||
if(PS3[i]->PS3Connected || PS3[i]->PS3NavigationConnected) {
|
if (PS3[i]->PS3Connected || PS3[i]->PS3NavigationConnected) {
|
||||||
if(PS3[i]->getAnalogHat(LeftHatX) > 137 || PS3[i]->getAnalogHat(LeftHatX) < 117 || PS3[i]->getAnalogHat(LeftHatY) > 137 || PS3[i]->getAnalogHat(LeftHatY) < 117 || PS3[i]->getAnalogHat(RightHatX) > 137 || PS3[i]->getAnalogHat(RightHatX) < 117 || PS3[i]->getAnalogHat(RightHatY) > 137 || PS3[i]->getAnalogHat(RightHatY) < 117) {
|
if (PS3[i]->getAnalogHat(LeftHatX) > 137 || PS3[i]->getAnalogHat(LeftHatX) < 117 || PS3[i]->getAnalogHat(LeftHatY) > 137 || PS3[i]->getAnalogHat(LeftHatY) < 117 || PS3[i]->getAnalogHat(RightHatX) > 137 || PS3[i]->getAnalogHat(RightHatX) < 117 || PS3[i]->getAnalogHat(RightHatY) > 137 || PS3[i]->getAnalogHat(RightHatY) < 117) {
|
||||||
Serial.print(F("\r\nLeftHatX: "));
|
Serial.print(F("\r\nLeftHatX: "));
|
||||||
Serial.print(PS3[i]->getAnalogHat(LeftHatX));
|
Serial.print(PS3[i]->getAnalogHat(LeftHatX));
|
||||||
Serial.print(F("\tLeftHatY: "));
|
Serial.print(F("\tLeftHatY: "));
|
||||||
Serial.print(PS3[i]->getAnalogHat(LeftHatY));
|
Serial.print(PS3[i]->getAnalogHat(LeftHatY));
|
||||||
if(!PS3[i]->PS3NavigationConnected) { // The Navigation controller only have one joystick
|
if (PS3[i]->PS3Connected) { // The Navigation controller only have one joystick
|
||||||
Serial.print(F("\tRightHatX: "));
|
Serial.print(F("\tRightHatX: "));
|
||||||
Serial.print(PS3[i]->getAnalogHat(RightHatX));
|
Serial.print(PS3[i]->getAnalogHat(RightHatX));
|
||||||
Serial.print(F("\tRightHatY: "));
|
Serial.print(F("\tRightHatY: "));
|
||||||
|
@ -48,77 +49,77 @@ void loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Analog button values can be read from almost all buttons
|
//Analog button values can be read from almost all buttons
|
||||||
if(PS3[i]->getAnalogButton(L2) || PS3[i]->getAnalogButton(R2)) {
|
if (PS3[i]->getAnalogButton(L2) || PS3[i]->getAnalogButton(R2)) {
|
||||||
Serial.print(F("\r\nL2: "));
|
Serial.print(F("\r\nL2: "));
|
||||||
Serial.print(PS3[i]->getAnalogButton(L2));
|
Serial.print(PS3[i]->getAnalogButton(L2));
|
||||||
if(!PS3[i]->PS3NavigationConnected) {
|
if (!PS3[i]->PS3NavigationConnected) {
|
||||||
Serial.print(F("\tR2: "));
|
Serial.print(F("\tR2: "));
|
||||||
Serial.print(PS3[i]->getAnalogButton(R2));
|
Serial.print(PS3[i]->getAnalogButton(R2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PS3[i]->getButtonClick(PS)) {
|
if (PS3[i]->getButtonClick(PS)) {
|
||||||
Serial.print(F("\r\nPS"));
|
Serial.print(F("\r\nPS"));
|
||||||
PS3[i]->disconnect();
|
PS3[i]->disconnect();
|
||||||
oldControllerState[i] = false; // Reset value
|
oldControllerState[i] = false; // Reset value
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(PS3[i]->getButtonClick(TRIANGLE))
|
if (PS3[i]->getButtonClick(TRIANGLE))
|
||||||
Serial.print(F("\r\nTraingle"));
|
Serial.print(F("\r\nTraingle"));
|
||||||
if(PS3[i]->getButtonClick(CIRCLE))
|
if (PS3[i]->getButtonClick(CIRCLE))
|
||||||
Serial.print(F("\r\nCircle"));
|
Serial.print(F("\r\nCircle"));
|
||||||
if(PS3[i]->getButtonClick(CROSS))
|
if (PS3[i]->getButtonClick(CROSS))
|
||||||
Serial.print(F("\r\nCross"));
|
Serial.print(F("\r\nCross"));
|
||||||
if(PS3[i]->getButtonClick(SQUARE))
|
if (PS3[i]->getButtonClick(SQUARE))
|
||||||
Serial.print(F("\r\nSquare"));
|
Serial.print(F("\r\nSquare"));
|
||||||
|
|
||||||
if(PS3[i]->getButtonClick(UP)) {
|
if (PS3[i]->getButtonClick(UP)) {
|
||||||
Serial.print(F("\r\nUp"));
|
Serial.print(F("\r\nUp"));
|
||||||
if(PS3[i]->PS3Connected) {
|
if (PS3[i]->PS3Connected) {
|
||||||
PS3[i]->setAllOff();
|
PS3[i]->setLedOff();
|
||||||
PS3[i]->setLedOn(LED4);
|
PS3[i]->setLedOn(LED4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PS3[i]->getButtonClick(RIGHT)) {
|
if (PS3[i]->getButtonClick(RIGHT)) {
|
||||||
Serial.print(F("\r\nRight"));
|
Serial.print(F("\r\nRight"));
|
||||||
if(PS3[i]->PS3Connected) {
|
if (PS3[i]->PS3Connected) {
|
||||||
PS3[i]->setAllOff();
|
PS3[i]->setLedOff();
|
||||||
PS3[i]->setLedOn(LED1);
|
PS3[i]->setLedOn(LED1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PS3[i]->getButtonClick(DOWN)) {
|
if (PS3[i]->getButtonClick(DOWN)) {
|
||||||
Serial.print(F("\r\nDown"));
|
Serial.print(F("\r\nDown"));
|
||||||
if(PS3[i]->PS3Connected) {
|
if (PS3[i]->PS3Connected) {
|
||||||
PS3[i]->setAllOff();
|
PS3[i]->setLedOff();
|
||||||
PS3[i]->setLedOn(LED2);
|
PS3[i]->setLedOn(LED2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PS3[i]->getButtonClick(LEFT)) {
|
if (PS3[i]->getButtonClick(LEFT)) {
|
||||||
Serial.print(F("\r\nLeft"));
|
Serial.print(F("\r\nLeft"));
|
||||||
if(PS3[i]->PS3Connected) {
|
if (PS3[i]->PS3Connected) {
|
||||||
PS3[i]->setAllOff();
|
PS3[i]->setLedOff();
|
||||||
PS3[i]->setLedOn(LED3);
|
PS3[i]->setLedOn(LED3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(PS3[i]->getButtonClick(L1))
|
if (PS3[i]->getButtonClick(L1))
|
||||||
Serial.print(F("\r\nL1"));
|
Serial.print(F("\r\nL1"));
|
||||||
if(PS3[i]->getButtonClick(L3))
|
if (PS3[i]->getButtonClick(L3))
|
||||||
Serial.print(F("\r\nL3"));
|
Serial.print(F("\r\nL3"));
|
||||||
if(PS3[i]->getButtonClick(R1))
|
if (PS3[i]->getButtonClick(R1))
|
||||||
Serial.print(F("\r\nR1"));
|
Serial.print(F("\r\nR1"));
|
||||||
if(PS3[i]->getButtonClick(R3))
|
if (PS3[i]->getButtonClick(R3))
|
||||||
Serial.print(F("\r\nR3"));
|
Serial.print(F("\r\nR3"));
|
||||||
|
|
||||||
if(PS3[i]->getButtonClick(SELECT)) {
|
if (PS3[i]->getButtonClick(SELECT)) {
|
||||||
Serial.print(F("\r\nSelect - "));
|
Serial.print(F("\r\nSelect - "));
|
||||||
Serial.print(PS3[i]->getStatusString());
|
Serial.print(PS3[i]->getStatusString());
|
||||||
}
|
}
|
||||||
if(PS3[i]->getButtonClick(START)) {
|
if (PS3[i]->getButtonClick(START)) {
|
||||||
Serial.print(F("\r\nStart"));
|
Serial.print(F("\r\nStart"));
|
||||||
printAngle[i] = !printAngle[i];
|
printAngle[i] = !printAngle[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(printAngle[i]) {
|
if (printAngle[i]) {
|
||||||
Serial.print(F("\r\nPitch: "));
|
Serial.print(F("\r\nPitch: "));
|
||||||
Serial.print(PS3[i]->getAngle(Pitch));
|
Serial.print(PS3[i]->getAngle(Pitch));
|
||||||
Serial.print(F("\tRoll: "));
|
Serial.print(F("\tRoll: "));
|
||||||
|
@ -131,7 +132,7 @@ void loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void onInit() {
|
void onInit() {
|
||||||
for (uint8_t i=0;i<length;i++) {
|
for (uint8_t i = 0; i < length; i++) {
|
||||||
if ((PS3[i]->PS3Connected || PS3[i]->PS3NavigationConnected) && !oldControllerState[i]) {
|
if ((PS3[i]->PS3Connected || PS3[i]->PS3NavigationConnected) && !oldControllerState[i]) {
|
||||||
oldControllerState[i] = true; // Used to check which is the new controller
|
oldControllerState[i] = true; // Used to check which is the new controller
|
||||||
PS3[i]->setLedOn((LED)i); // Cast directly to LED enum - see: "controllerEnums.h"
|
PS3[i]->setLedOn((LED)i); // Cast directly to LED enum - see: "controllerEnums.h"
|
||||||
|
|
|
@ -14,11 +14,12 @@
|
||||||
#include <usbhub.h>
|
#include <usbhub.h>
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
USBHub Hub1(&Usb); // Some dongles have a hub inside
|
//USBHub Hub1(&Usb); // Some dongles have a hub inside
|
||||||
|
|
||||||
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
||||||
|
|
||||||
/* You can create the instances of the bluetooth services in two ways */
|
/* You can create the instances of the bluetooth services in two ways */
|
||||||
SPP SerialBT(&Btd); // This will set the name to the defaults: "Arduino" and the pin to "1234"
|
SPP SerialBT(&Btd); // This will set the name to the defaults: "Arduino" and the pin to "0000"
|
||||||
//SPP SerialBTBT(&Btd,"Lauszus's Arduino","0000"); // You can also set the name and pin like so
|
//SPP SerialBTBT(&Btd,"Lauszus's Arduino","0000"); // You can also set the name and pin like so
|
||||||
PS3BT PS3(&Btd); // This will just create the instance
|
PS3BT PS3(&Btd); // This will just create the instance
|
||||||
//PS3BT PS3(&Btd,0x00,0x15,0x83,0x3D,0x0A,0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch
|
//PS3BT PS3(&Btd,0x00,0x15,0x83,0x3D,0x0A,0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch
|
||||||
|
@ -31,7 +32,7 @@ void setup() {
|
||||||
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
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); //halt
|
while (1); //halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nBluetooth Library Started"));
|
Serial.print(F("\r\nBluetooth Library Started"));
|
||||||
output.reserve(200); // Reserve 200 bytes for the output string
|
output.reserve(200); // Reserve 200 bytes for the output string
|
||||||
|
@ -39,27 +40,27 @@ void setup() {
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task(); // The SPP data is actually not send until this is called, one could call SerialBT.send() directly as well
|
Usb.Task(); // The SPP data is actually not send until this is called, one could call SerialBT.send() directly as well
|
||||||
|
|
||||||
if(SerialBT.connected) {
|
if (SerialBT.connected) {
|
||||||
if(firstMessage) {
|
if (firstMessage) {
|
||||||
firstMessage = false;
|
firstMessage = false;
|
||||||
SerialBT.println(F("Hello from Arduino")); // Send welcome message
|
SerialBT.println(F("Hello from Arduino")); // Send welcome message
|
||||||
}
|
}
|
||||||
if(Serial.available())
|
if (Serial.available())
|
||||||
SerialBT.write(Serial.read());
|
SerialBT.write(Serial.read());
|
||||||
if(SerialBT.available())
|
if (SerialBT.available())
|
||||||
Serial.write(SerialBT.read());
|
Serial.write(SerialBT.read());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
firstMessage = true;
|
firstMessage = true;
|
||||||
|
|
||||||
if(PS3.PS3Connected || PS3.PS3NavigationConnected) {
|
if (PS3.PS3Connected || PS3.PS3NavigationConnected) {
|
||||||
output = ""; // Reset output string
|
output = ""; // Reset output string
|
||||||
if(PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
|
if (PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
|
||||||
output += "LeftHatX: ";
|
output += "LeftHatX: ";
|
||||||
output += PS3.getAnalogHat(LeftHatX);
|
output += PS3.getAnalogHat(LeftHatX);
|
||||||
output += "\tLeftHatY: ";
|
output += "\tLeftHatY: ";
|
||||||
output += PS3.getAnalogHat(LeftHatY);
|
output += PS3.getAnalogHat(LeftHatY);
|
||||||
if(!PS3.PS3NavigationConnected) {
|
if (PS3.PS3Connected) { // The Navigation controller only have one joystick
|
||||||
output += "\tRightHatX: ";
|
output += "\tRightHatX: ";
|
||||||
output += PS3.getAnalogHat(RightHatX);
|
output += PS3.getAnalogHat(RightHatX);
|
||||||
output += "\tRightHatY: ";
|
output += "\tRightHatY: ";
|
||||||
|
@ -67,85 +68,85 @@ void loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Analog button values can be read from almost all buttons
|
//Analog button values can be read from almost all buttons
|
||||||
if(PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) {
|
if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) {
|
||||||
if(output != "")
|
if (output != "")
|
||||||
output += "\r\n";
|
output += "\r\n";
|
||||||
output += "L2: ";
|
output += "L2: ";
|
||||||
output += PS3.getAnalogButton(L2);
|
output += PS3.getAnalogButton(L2);
|
||||||
if(!PS3.PS3NavigationConnected) {
|
if (!PS3.PS3NavigationConnected) {
|
||||||
output += "\tR2: ";
|
output += "\tR2: ";
|
||||||
output += PS3.getAnalogButton(R2);
|
output += PS3.getAnalogButton(R2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(output != "") {
|
if (output != "") {
|
||||||
Serial.println(output);
|
Serial.println(output);
|
||||||
if(SerialBT.connected)
|
if (SerialBT.connected)
|
||||||
SerialBT.println(output);
|
SerialBT.println(output);
|
||||||
output = ""; // Reset output string
|
output = ""; // Reset output string
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(PS)) {
|
if (PS3.getButtonClick(PS)) {
|
||||||
output += " - PS";
|
output += " - PS";
|
||||||
PS3.disconnect();
|
PS3.disconnect();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(PS3.getButtonClick(TRIANGLE))
|
if (PS3.getButtonClick(TRIANGLE))
|
||||||
output += " - Traingle";
|
output += " - Traingle";
|
||||||
if(PS3.getButtonClick(CIRCLE))
|
if (PS3.getButtonClick(CIRCLE))
|
||||||
output += " - Circle";
|
output += " - Circle";
|
||||||
if(PS3.getButtonClick(CROSS))
|
if (PS3.getButtonClick(CROSS))
|
||||||
output += " - Cross";
|
output += " - Cross";
|
||||||
if(PS3.getButtonClick(SQUARE))
|
if (PS3.getButtonClick(SQUARE))
|
||||||
output += " - Square";
|
output += " - Square";
|
||||||
|
|
||||||
if(PS3.getButtonClick(UP)) {
|
if (PS3.getButtonClick(UP)) {
|
||||||
output += " - Up";
|
output += " - Up";
|
||||||
if(PS3.PS3Connected) {
|
if (PS3.PS3Connected) {
|
||||||
PS3.setAllOff();
|
PS3.setLedOff();
|
||||||
PS3.setLedOn(LED4);
|
PS3.setLedOn(LED4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(RIGHT)) {
|
if (PS3.getButtonClick(RIGHT)) {
|
||||||
output += " - Right";
|
output += " - Right";
|
||||||
if(PS3.PS3Connected) {
|
if (PS3.PS3Connected) {
|
||||||
PS3.setAllOff();
|
PS3.setLedOff();
|
||||||
PS3.setLedOn(LED1);
|
PS3.setLedOn(LED1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(DOWN)) {
|
if (PS3.getButtonClick(DOWN)) {
|
||||||
output += " - Down";
|
output += " - Down";
|
||||||
if(PS3.PS3Connected) {
|
if (PS3.PS3Connected) {
|
||||||
PS3.setAllOff();
|
PS3.setLedOff();
|
||||||
PS3.setLedOn(LED2);
|
PS3.setLedOn(LED2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(LEFT)) {
|
if (PS3.getButtonClick(LEFT)) {
|
||||||
output += " - Left";
|
output += " - Left";
|
||||||
if(PS3.PS3Connected) {
|
if (PS3.PS3Connected) {
|
||||||
PS3.setAllOff();
|
PS3.setLedOff();
|
||||||
PS3.setLedOn(LED3);
|
PS3.setLedOn(LED3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(PS3.getButtonClick(L1))
|
if (PS3.getButtonClick(L1))
|
||||||
output += " - L1";
|
output += " - L1";
|
||||||
if(PS3.getButtonClick(L3))
|
if (PS3.getButtonClick(L3))
|
||||||
output += " - L3";
|
output += " - L3";
|
||||||
if(PS3.getButtonClick(R1))
|
if (PS3.getButtonClick(R1))
|
||||||
output += " - R1";
|
output += " - R1";
|
||||||
if(PS3.getButtonClick(R3))
|
if (PS3.getButtonClick(R3))
|
||||||
output += " - R3";
|
output += " - R3";
|
||||||
|
|
||||||
if(PS3.getButtonClick(SELECT)) {
|
if (PS3.getButtonClick(SELECT)) {
|
||||||
output += " - Select - ";
|
output += " - Select - ";
|
||||||
output += PS3.getStatusString();
|
output += PS3.getStatusString();
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(START))
|
if (PS3.getButtonClick(START))
|
||||||
output += " - Start";
|
output += " - Start";
|
||||||
|
|
||||||
if(output != "") {
|
if (output != "") {
|
||||||
String string = "PS3 Controller" + output;
|
String string = "PS3 Controller" + output;
|
||||||
Serial.println(string);
|
Serial.println(string);
|
||||||
if(SerialBT.connected)
|
if (SerialBT.connected)
|
||||||
SerialBT.println(string);
|
SerialBT.println(string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
#include <usbhub.h>
|
#include <usbhub.h>
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
USBHub Hub1(&Usb); // Some dongles have a hub inside
|
//USBHub Hub1(&Usb); // Some dongles have a hub inside
|
||||||
|
|
||||||
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
||||||
/* You can create the instance of the class in two ways */
|
/* You can create the instance of the class in two ways */
|
||||||
SPP SerialBT(&Btd); // This will set the name to the defaults: "Arduino" and the pin to "1234"
|
SPP SerialBT(&Btd); // This will set the name to the defaults: "Arduino" and the pin to "1234"
|
||||||
|
@ -21,21 +22,21 @@ void setup() {
|
||||||
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
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); //halt
|
while (1); //halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nSPP Bluetooth Library Started"));
|
Serial.print(F("\r\nSPP Bluetooth Library Started"));
|
||||||
}
|
}
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task(); // The SPP data is actually not send until this is called, one could call SerialBT.send() directly as well
|
Usb.Task(); // The SPP data is actually not send until this is called, one could call SerialBT.send() directly as well
|
||||||
|
|
||||||
if(SerialBT.connected) {
|
if (SerialBT.connected) {
|
||||||
if(firstMessage) {
|
if (firstMessage) {
|
||||||
firstMessage = false;
|
firstMessage = false;
|
||||||
SerialBT.println(F("Hello from Arduino")); // Send welcome message
|
SerialBT.println(F("Hello from Arduino")); // Send welcome message
|
||||||
}
|
}
|
||||||
if(Serial.available())
|
if (Serial.available())
|
||||||
SerialBT.write(Serial.read());
|
SerialBT.write(Serial.read());
|
||||||
if(SerialBT.available())
|
if (SerialBT.available())
|
||||||
Serial.write(SerialBT.read());
|
Serial.write(SerialBT.read());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -8,55 +8,56 @@
|
||||||
#include <usbhub.h>
|
#include <usbhub.h>
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
USBHub Hub1(&Usb); // Some dongles have a hub inside
|
//USBHub Hub1(&Usb); // Some dongles have a hub inside
|
||||||
|
|
||||||
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
||||||
SPP* SerialBT[2]; // We will use this pointer to store the two instance, you can easily make it larger if you like, but it will use a lot of RAM!
|
SPP *SerialBT[2]; // We will use this pointer to store the two instance, you can easily make it larger if you like, but it will use a lot of RAM!
|
||||||
const uint8_t length = sizeof(SerialBT)/sizeof(SerialBT[0]); // Get the lenght of the array
|
const uint8_t length = sizeof(SerialBT) / sizeof(SerialBT[0]); // Get the lenght of the array
|
||||||
boolean firstMessage[length] = { true }; // Set all to true
|
boolean firstMessage[length] = { true }; // Set all to true
|
||||||
uint8_t buffer[50];
|
uint8_t buffer[50];
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
for(uint8_t i=0;i<length;i++)
|
for (uint8_t i = 0; i < length; i++)
|
||||||
SerialBT[i] = new SPP(&Btd); // This will set the name to the default: "Arduino" and the pin to "1234" for all connections
|
SerialBT[i] = new SPP(&Btd); // This will set the name to the default: "Arduino" and the pin to "0000" for all connections
|
||||||
|
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
|
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); //halt
|
while (1); //halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nSPP Bluetooth Library Started"));
|
Serial.print(F("\r\nSPP Bluetooth Library Started"));
|
||||||
}
|
}
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task(); // The SPP data is actually not send until this is called, one could call SerialBT.send() directly as well
|
Usb.Task(); // The SPP data is actually not send until this is called, one could call SerialBT.send() directly as well
|
||||||
|
|
||||||
for(uint8_t i=0;i<length;i++) {
|
for (uint8_t i = 0; i < length; i++) {
|
||||||
if(SerialBT[i]->connected) {
|
if (SerialBT[i]->connected) {
|
||||||
if(firstMessage[i]) {
|
if (firstMessage[i]) {
|
||||||
firstMessage[i] = false;
|
firstMessage[i] = false;
|
||||||
SerialBT[i]->println(F("Hello from Arduino")); // Send welcome message
|
SerialBT[i]->println(F("Hello from Arduino")); // Send welcome message
|
||||||
}
|
}
|
||||||
if(SerialBT[i]->available())
|
if (SerialBT[i]->available())
|
||||||
Serial.write(SerialBT[i]->read());
|
Serial.write(SerialBT[i]->read());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
firstMessage[i] = true;
|
firstMessage[i] = true;
|
||||||
}
|
}
|
||||||
if(Serial.available()) {
|
if (Serial.available()) {
|
||||||
delay(10); // Wait for the rest of the data to arrive
|
delay(10); // Wait for the rest of the data to arrive
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
while(Serial.available() && i < sizeof(buffer)) // Read the data
|
while (Serial.available() && i < sizeof(buffer)) // Read the data
|
||||||
buffer[i++] = Serial.read();
|
buffer[i++] = Serial.read();
|
||||||
/*
|
/*
|
||||||
Set the connection you want to send to using the first character
|
Set the connection you want to send to using the first character
|
||||||
For instace "0Hello World" would send "Hello World" to connection 0
|
For instace "0Hello World" would send "Hello World" to connection 0
|
||||||
*/
|
*/
|
||||||
uint8_t id = buffer[0]-'0'; // Convert from ASCII
|
uint8_t id = buffer[0] - '0'; // Convert from ASCII
|
||||||
if(id < length && i > 1) { // And then compare to length and make sure there is any text
|
if (id < length && i > 1) { // And then compare to length and make sure there is any text
|
||||||
if(SerialBT[id]->connected) { // Check if a device is actually connected
|
if (SerialBT[id]->connected) { // Check if a device is actually connected
|
||||||
for(uint8_t i2 = 0; i2 < i-1; i2++) // Don't include the first character
|
for (uint8_t i2 = 0; i2 < i - 1; i2++) // Don't include the first character
|
||||||
buffer[i2] = buffer[i2+1];
|
buffer[i2] = buffer[i2 + 1];
|
||||||
SerialBT[id]->write(buffer,i-1); // Send the data
|
SerialBT[id]->write(buffer, i - 1); // Send the data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,11 @@
|
||||||
#include <usbhub.h>
|
#include <usbhub.h>
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
USBHub Hub1(&Usb); // Some dongles have a hub inside
|
//USBHub Hub1(&Usb); // Some dongles have a hub inside
|
||||||
|
|
||||||
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
||||||
/* You can create the instance of the class in two ways */
|
/* You can create the instance of the class in two ways */
|
||||||
WII Wii(&Btd,PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once
|
WII Wii(&Btd, PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once
|
||||||
//WII Wii(&Btd); // After that you can simply create the instance like so and then press any button on the Wiimote
|
//WII Wii(&Btd); // After that you can simply create the instance like so and then press any button on the Wiimote
|
||||||
|
|
||||||
bool printAngle;
|
bool printAngle;
|
||||||
|
@ -21,68 +22,68 @@ void setup() {
|
||||||
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
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); //halt
|
while (1); //halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nWiimote Bluetooth Library Started"));
|
Serial.print(F("\r\nWiimote Bluetooth Library Started"));
|
||||||
}
|
}
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task();
|
Usb.Task();
|
||||||
if(Wii.wiimoteConnected) {
|
if (Wii.wiimoteConnected) {
|
||||||
if(Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down
|
if (Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down
|
||||||
Serial.print(F("\r\nHOME"));
|
Serial.print(F("\r\nHOME"));
|
||||||
Wii.disconnect();
|
Wii.disconnect();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(Wii.getButtonClick(LEFT)) {
|
if (Wii.getButtonClick(LEFT)) {
|
||||||
Wii.setAllOff();
|
Wii.setLedOff();
|
||||||
Wii.setLedOn(LED1);
|
Wii.setLedOn(LED1);
|
||||||
Serial.print(F("\r\nLeft"));
|
Serial.print(F("\r\nLeft"));
|
||||||
}
|
}
|
||||||
if(Wii.getButtonClick(RIGHT)) {
|
if (Wii.getButtonClick(RIGHT)) {
|
||||||
Wii.setAllOff();
|
Wii.setLedOff();
|
||||||
Wii.setLedOn(LED3);
|
Wii.setLedOn(LED3);
|
||||||
Serial.print(F("\r\nRight"));
|
Serial.print(F("\r\nRight"));
|
||||||
}
|
}
|
||||||
if(Wii.getButtonClick(DOWN)) {
|
if (Wii.getButtonClick(DOWN)) {
|
||||||
Wii.setAllOff();
|
Wii.setLedOff();
|
||||||
Wii.setLedOn(LED4);
|
Wii.setLedOn(LED4);
|
||||||
Serial.print(F("\r\nDown"));
|
Serial.print(F("\r\nDown"));
|
||||||
}
|
}
|
||||||
if(Wii.getButtonClick(UP)) {
|
if (Wii.getButtonClick(UP)) {
|
||||||
Wii.setAllOff();
|
Wii.setLedOff();
|
||||||
Wii.setLedOn(LED2);
|
Wii.setLedOn(LED2);
|
||||||
Serial.print(F("\r\nUp"));
|
Serial.print(F("\r\nUp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Wii.getButtonClick(PLUS))
|
if (Wii.getButtonClick(PLUS))
|
||||||
Serial.print(F("\r\nPlus"));
|
Serial.print(F("\r\nPlus"));
|
||||||
if(Wii.getButtonClick(MINUS))
|
if (Wii.getButtonClick(MINUS))
|
||||||
Serial.print(F("\r\nMinus"));
|
Serial.print(F("\r\nMinus"));
|
||||||
|
|
||||||
if(Wii.getButtonClick(ONE))
|
if (Wii.getButtonClick(ONE))
|
||||||
Serial.print(F("\r\nOne"));
|
Serial.print(F("\r\nOne"));
|
||||||
if(Wii.getButtonClick(TWO))
|
if (Wii.getButtonClick(TWO))
|
||||||
Serial.print(F("\r\nTwo"));
|
Serial.print(F("\r\nTwo"));
|
||||||
|
|
||||||
if(Wii.getButtonClick(A)) {
|
if (Wii.getButtonClick(A)) {
|
||||||
printAngle = !printAngle;
|
printAngle = !printAngle;
|
||||||
Serial.print(F("\r\nA"));
|
Serial.print(F("\r\nA"));
|
||||||
}
|
}
|
||||||
if(Wii.getButtonClick(B)) {
|
if (Wii.getButtonClick(B)) {
|
||||||
Wii.setRumbleToggle();
|
Wii.setRumbleToggle();
|
||||||
Serial.print(F("\r\nB"));
|
Serial.print(F("\r\nB"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(printAngle) {
|
if (printAngle) {
|
||||||
Serial.print(F("\r\nPitch: "));
|
Serial.print(F("\r\nPitch: "));
|
||||||
Serial.print(Wii.getPitch());
|
Serial.print(Wii.getPitch());
|
||||||
Serial.print(F("\tRoll: "));
|
Serial.print(F("\tRoll: "));
|
||||||
Serial.print(Wii.getRoll());
|
Serial.print(Wii.getRoll());
|
||||||
if(Wii.motionPlusConnected) {
|
if (Wii.motionPlusConnected) {
|
||||||
Serial.print(F("\tYaw: "));
|
Serial.print(F("\tYaw: "));
|
||||||
Serial.print(Wii.getYaw());
|
Serial.print(Wii.getYaw());
|
||||||
}
|
}
|
||||||
if(Wii.nunchuckConnected) {
|
if (Wii.nunchuckConnected) {
|
||||||
Serial.print(F("\tNunchuck Pitch: "));
|
Serial.print(F("\tNunchuck Pitch: "));
|
||||||
Serial.print(Wii.getNunchuckPitch());
|
Serial.print(Wii.getNunchuckPitch());
|
||||||
Serial.print(F("\tNunchuck Roll: "));
|
Serial.print(F("\tNunchuck Roll: "));
|
||||||
|
@ -90,12 +91,12 @@ void loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(Wii.nunchuckConnected) {
|
if (Wii.nunchuckConnected) {
|
||||||
if(Wii.getButtonClick(Z))
|
if (Wii.getButtonClick(Z))
|
||||||
Serial.print(F("\r\nZ"));
|
Serial.print(F("\r\nZ"));
|
||||||
if(Wii.getButtonClick(C))
|
if (Wii.getButtonClick(C))
|
||||||
Serial.print(F("\r\nC"));
|
Serial.print(F("\r\nC"));
|
||||||
if(Wii.getAnalogHat(HatX) > 137 || Wii.getAnalogHat(HatX) < 117 || Wii.getAnalogHat(HatY) > 137 || Wii.getAnalogHat(HatY) < 117) {
|
if (Wii.getAnalogHat(HatX) > 137 || Wii.getAnalogHat(HatX) < 117 || Wii.getAnalogHat(HatY) > 137 || Wii.getAnalogHat(HatY) < 117) {
|
||||||
Serial.print(F("\r\nHatX: "));
|
Serial.print(F("\r\nHatX: "));
|
||||||
Serial.print(Wii.getAnalogHat(HatX));
|
Serial.print(Wii.getAnalogHat(HatX));
|
||||||
Serial.print(F("\tHatY: "));
|
Serial.print(F("\tHatY: "));
|
||||||
|
|
|
@ -19,10 +19,11 @@ Otherwise, wire up a IR LED yourself.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
USBHub Hub1(&Usb); // Some dongles have a hub inside
|
//USBHub Hub1(&Usb); // Some dongles have a hub inside
|
||||||
|
|
||||||
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
||||||
/* You can create the instance of the class in two ways */
|
/* You can create the instance of the class in two ways */
|
||||||
WII Wii(&Btd,PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once
|
WII Wii(&Btd, PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once
|
||||||
//WII Wii(&Btd); // After the Wiimote pairs once with the line of code above, you can simply create the instance like so and re upload and then press any button on the Wiimote
|
//WII Wii(&Btd); // After the Wiimote pairs once with the line of code above, you can simply create the instance like so and re upload and then press any button on the Wiimote
|
||||||
|
|
||||||
bool printAngle;
|
bool printAngle;
|
||||||
|
@ -33,31 +34,31 @@ void setup() {
|
||||||
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
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); //halt
|
while (1); //halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nWiimote Bluetooth Library Started"));
|
Serial.print(F("\r\nWiimote Bluetooth Library Started"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task();
|
Usb.Task();
|
||||||
if(Wii.wiimoteConnected) {
|
if (Wii.wiimoteConnected) {
|
||||||
if(Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down
|
if (Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down
|
||||||
Serial.print(F("\r\nHOME"));
|
Serial.print(F("\r\nHOME"));
|
||||||
Wii.disconnect();
|
Wii.disconnect();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(Wii.getButtonClick(ONE))
|
if (Wii.getButtonClick(ONE))
|
||||||
Wii.IRinitialize(); // Run the initialisation sequence
|
Wii.IRinitialize(); // Run the initialisation sequence
|
||||||
if(Wii.getButtonClick(MINUS) || Wii.getButtonClick(PLUS)) {
|
if (Wii.getButtonClick(MINUS) || Wii.getButtonClick(PLUS)) {
|
||||||
if(!Wii.isIRCameraEnabled())
|
if (!Wii.isIRCameraEnabled())
|
||||||
Serial.print(F("\r\nEnable IR camera first"));
|
Serial.print(F("\r\nEnable IR camera first"));
|
||||||
else {
|
else {
|
||||||
if(Wii.getButtonPress(MINUS)) { // getButtonClick will only return true once
|
if (Wii.getButtonPress(MINUS)) { // getButtonClick will only return true once
|
||||||
if(printObjects > 0)
|
if (printObjects > 0)
|
||||||
printObjects--;
|
printObjects--;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(printObjects < 4)
|
if (printObjects < 4)
|
||||||
printObjects++;
|
printObjects++;
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nTracking "));
|
Serial.print(F("\r\nTracking "));
|
||||||
|
@ -65,17 +66,17 @@ void loop() {
|
||||||
Serial.print(F(" objects"));
|
Serial.print(F(" objects"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(Wii.getButtonClick(A)) {
|
if (Wii.getButtonClick(A)) {
|
||||||
printAngle = !printAngle;
|
printAngle = !printAngle;
|
||||||
Serial.print(F("\r\nA"));
|
Serial.print(F("\r\nA"));
|
||||||
}
|
}
|
||||||
if(Wii.getButtonClick(B)) {
|
if (Wii.getButtonClick(B)) {
|
||||||
Serial.print(F("\r\nBattery level: "));
|
Serial.print(F("\r\nBattery level: "));
|
||||||
Serial.print(Wii.getBatteryLevel()); // You can get the battery level as well
|
Serial.print(Wii.getBatteryLevel()); // You can get the battery level as well
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(printObjects > 0) {
|
if (printObjects > 0) {
|
||||||
if(Wii.getIRx1() != 0x3FF || Wii.getIRy1() != 0x3FF || Wii.getIRs1() != 0) { // Only print if the IR camera is actually seeing something
|
if (Wii.getIRx1() != 0x3FF || Wii.getIRy1() != 0x3FF || Wii.getIRs1() != 0) { // Only print if the IR camera is actually seeing something
|
||||||
Serial.print(F("\r\nx1: "));
|
Serial.print(F("\r\nx1: "));
|
||||||
Serial.print(Wii.getIRx1());
|
Serial.print(Wii.getIRx1());
|
||||||
Serial.print(F("\ty1: "));
|
Serial.print(F("\ty1: "));
|
||||||
|
@ -83,8 +84,8 @@ void loop() {
|
||||||
Serial.print(F("\ts1:"));
|
Serial.print(F("\ts1:"));
|
||||||
Serial.print(Wii.getIRs1());
|
Serial.print(Wii.getIRs1());
|
||||||
}
|
}
|
||||||
if(printObjects > 1) {
|
if (printObjects > 1) {
|
||||||
if(Wii.getIRx2() != 0x3FF || Wii.getIRy2() != 0x3FF || Wii.getIRs2() != 0) {
|
if (Wii.getIRx2() != 0x3FF || Wii.getIRy2() != 0x3FF || Wii.getIRs2() != 0) {
|
||||||
Serial.print(F("\r\nx2: "));
|
Serial.print(F("\r\nx2: "));
|
||||||
Serial.print(Wii.getIRx2());
|
Serial.print(Wii.getIRx2());
|
||||||
Serial.print(F("\ty2: "));
|
Serial.print(F("\ty2: "));
|
||||||
|
@ -92,8 +93,8 @@ void loop() {
|
||||||
Serial.print(F("\ts2:"));
|
Serial.print(F("\ts2:"));
|
||||||
Serial.print(Wii.getIRs2());
|
Serial.print(Wii.getIRs2());
|
||||||
}
|
}
|
||||||
if(printObjects > 2) {
|
if (printObjects > 2) {
|
||||||
if(Wii.getIRx3() != 0x3FF || Wii.getIRy3() != 0x3FF || Wii.getIRs3() != 0) {
|
if (Wii.getIRx3() != 0x3FF || Wii.getIRy3() != 0x3FF || Wii.getIRs3() != 0) {
|
||||||
Serial.print(F("\r\nx3: "));
|
Serial.print(F("\r\nx3: "));
|
||||||
Serial.print(Wii.getIRx3());
|
Serial.print(Wii.getIRx3());
|
||||||
Serial.print(F("\ty3: "));
|
Serial.print(F("\ty3: "));
|
||||||
|
@ -101,8 +102,8 @@ void loop() {
|
||||||
Serial.print(F("\ts3:"));
|
Serial.print(F("\ts3:"));
|
||||||
Serial.print(Wii.getIRs3());
|
Serial.print(Wii.getIRs3());
|
||||||
}
|
}
|
||||||
if(printObjects > 3) {
|
if (printObjects > 3) {
|
||||||
if(Wii.getIRx4() != 0x3FF || Wii.getIRy4() != 0x3FF || Wii.getIRs4() != 0) {
|
if (Wii.getIRx4() != 0x3FF || Wii.getIRy4() != 0x3FF || Wii.getIRs4() != 0) {
|
||||||
Serial.print(F("\r\nx4: "));
|
Serial.print(F("\r\nx4: "));
|
||||||
Serial.print(Wii.getIRx4());
|
Serial.print(Wii.getIRx4());
|
||||||
Serial.print(F("\ty4: "));
|
Serial.print(F("\ty4: "));
|
||||||
|
@ -114,7 +115,7 @@ void loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(printAngle) { // There is no extension bytes available, so the MotionPlus or Nunchuck can't be read
|
if (printAngle) { // There is no extension bytes available, so the MotionPlus or Nunchuck can't be read
|
||||||
Serial.print(F("\r\nPitch: "));
|
Serial.print(F("\r\nPitch: "));
|
||||||
Serial.print(Wii.getPitch());
|
Serial.print(Wii.getPitch());
|
||||||
Serial.print(F("\tRoll: "));
|
Serial.print(F("\tRoll: "));
|
||||||
|
|
|
@ -9,15 +9,16 @@
|
||||||
#include <usbhub.h>
|
#include <usbhub.h>
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
USBHub Hub1(&Usb); // Some dongles have a hub inside
|
//USBHub Hub1(&Usb); // Some dongles have a hub inside
|
||||||
|
|
||||||
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
||||||
WII *Wii[2]; // We will use this pointer to store the two instance, you can easily make it larger if you like, but it will use a lot of RAM!
|
WII *Wii[2]; // We will use this pointer to store the two instance, you can easily make it larger if you like, but it will use a lot of RAM!
|
||||||
const uint8_t length = sizeof(Wii)/sizeof(Wii[0]); // Get the lenght of the array
|
const uint8_t length = sizeof(Wii) / sizeof(Wii[0]); // Get the lenght of the array
|
||||||
boolean printAngle[length];
|
boolean printAngle[length];
|
||||||
boolean oldControllerState[length];
|
boolean oldControllerState[length];
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
for (uint8_t i=0;i<length;i++) {
|
for (uint8_t i = 0; i < length; i++) {
|
||||||
Wii[i] = new WII(&Btd); // You will have to pair each controller with the dongle before you can define the instances like so, just add PAIR as the second argument
|
Wii[i] = new WII(&Btd); // You will have to pair each controller with the dongle before you can define the instances like so, just add PAIR as the second argument
|
||||||
Wii[i]->attachOnInit(onInit); // onInit() is called upon a new connection - you can call the function whatever you like
|
Wii[i]->attachOnInit(onInit); // onInit() is called upon a new connection - you can call the function whatever you like
|
||||||
}
|
}
|
||||||
|
@ -26,71 +27,71 @@ void setup() {
|
||||||
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
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); //halt
|
while (1); //halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nWiimote Bluetooth Library Started"));
|
Serial.print(F("\r\nWiimote Bluetooth Library Started"));
|
||||||
}
|
}
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task();
|
Usb.Task();
|
||||||
|
|
||||||
for(uint8_t i=0;i<length;i++) {
|
for (uint8_t i = 0; i < length; i++) {
|
||||||
if(Wii[i]->wiimoteConnected) {
|
if (Wii[i]->wiimoteConnected) {
|
||||||
if(Wii[i]->getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down
|
if (Wii[i]->getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down
|
||||||
Serial.print(F("\r\nHOME"));
|
Serial.print(F("\r\nHOME"));
|
||||||
Wii[i]->disconnect();
|
Wii[i]->disconnect();
|
||||||
oldControllerState[i] = false; // Reset value
|
oldControllerState[i] = false; // Reset value
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(Wii[i]->getButtonClick(LEFT)) {
|
if (Wii[i]->getButtonClick(LEFT)) {
|
||||||
Wii[i]->setAllOff();
|
Wii[i]->setLedOff();
|
||||||
Wii[i]->setLedOn(LED1);
|
Wii[i]->setLedOn(LED1);
|
||||||
Serial.print(F("\r\nLeft"));
|
Serial.print(F("\r\nLeft"));
|
||||||
}
|
}
|
||||||
if(Wii[i]->getButtonClick(RIGHT)) {
|
if (Wii[i]->getButtonClick(RIGHT)) {
|
||||||
Wii[i]->setAllOff();
|
Wii[i]->setLedOff();
|
||||||
Wii[i]->setLedOn(LED3);
|
Wii[i]->setLedOn(LED3);
|
||||||
Serial.print(F("\r\nRight"));
|
Serial.print(F("\r\nRight"));
|
||||||
}
|
}
|
||||||
if(Wii[i]->getButtonClick(DOWN)) {
|
if (Wii[i]->getButtonClick(DOWN)) {
|
||||||
Wii[i]->setAllOff();
|
Wii[i]->setLedOff();
|
||||||
Wii[i]->setLedOn(LED4);
|
Wii[i]->setLedOn(LED4);
|
||||||
Serial.print(F("\r\nDown"));
|
Serial.print(F("\r\nDown"));
|
||||||
}
|
}
|
||||||
if(Wii[i]->getButtonClick(UP)) {
|
if (Wii[i]->getButtonClick(UP)) {
|
||||||
Wii[i]->setAllOff();
|
Wii[i]->setLedOff();
|
||||||
Wii[i]->setLedOn(LED2);
|
Wii[i]->setLedOn(LED2);
|
||||||
Serial.print(F("\r\nUp"));
|
Serial.print(F("\r\nUp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Wii[i]->getButtonClick(PLUS))
|
if (Wii[i]->getButtonClick(PLUS))
|
||||||
Serial.print(F("\r\nPlus"));
|
Serial.print(F("\r\nPlus"));
|
||||||
if(Wii[i]->getButtonClick(MINUS))
|
if (Wii[i]->getButtonClick(MINUS))
|
||||||
Serial.print(F("\r\nMinus"));
|
Serial.print(F("\r\nMinus"));
|
||||||
|
|
||||||
if(Wii[i]->getButtonClick(ONE))
|
if (Wii[i]->getButtonClick(ONE))
|
||||||
Serial.print(F("\r\nOne"));
|
Serial.print(F("\r\nOne"));
|
||||||
if(Wii[i]->getButtonClick(TWO))
|
if (Wii[i]->getButtonClick(TWO))
|
||||||
Serial.print(F("\r\nTwo"));
|
Serial.print(F("\r\nTwo"));
|
||||||
|
|
||||||
if(Wii[i]->getButtonClick(A)) {
|
if (Wii[i]->getButtonClick(A)) {
|
||||||
printAngle[i] = !printAngle[i];
|
printAngle[i] = !printAngle[i];
|
||||||
Serial.print(F("\r\nA"));
|
Serial.print(F("\r\nA"));
|
||||||
}
|
}
|
||||||
if(Wii[i]->getButtonClick(B)) {
|
if (Wii[i]->getButtonClick(B)) {
|
||||||
Wii[i]->setRumbleToggle();
|
Wii[i]->setRumbleToggle();
|
||||||
Serial.print(F("\r\nB"));
|
Serial.print(F("\r\nB"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(printAngle[i]) {
|
if (printAngle[i]) {
|
||||||
Serial.print(F("\r\nPitch: "));
|
Serial.print(F("\r\nPitch: "));
|
||||||
Serial.print(Wii[i]->getPitch());
|
Serial.print(Wii[i]->getPitch());
|
||||||
Serial.print(F("\tRoll: "));
|
Serial.print(F("\tRoll: "));
|
||||||
Serial.print(Wii[i]->getRoll());
|
Serial.print(Wii[i]->getRoll());
|
||||||
if(Wii[i]->motionPlusConnected) {
|
if (Wii[i]->motionPlusConnected) {
|
||||||
Serial.print(F("\tYaw: "));
|
Serial.print(F("\tYaw: "));
|
||||||
Serial.print(Wii[i]->getYaw());
|
Serial.print(Wii[i]->getYaw());
|
||||||
}
|
}
|
||||||
if(Wii[i]->nunchuckConnected) {
|
if (Wii[i]->nunchuckConnected) {
|
||||||
Serial.print(F("\tNunchuck Pitch: "));
|
Serial.print(F("\tNunchuck Pitch: "));
|
||||||
Serial.print(Wii[i]->getNunchuckPitch());
|
Serial.print(Wii[i]->getNunchuckPitch());
|
||||||
Serial.print(F("\tNunchuck Roll: "));
|
Serial.print(F("\tNunchuck Roll: "));
|
||||||
|
@ -98,12 +99,12 @@ void loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(Wii[i]->nunchuckConnected) {
|
if (Wii[i]->nunchuckConnected) {
|
||||||
if(Wii[i]->getButtonClick(Z))
|
if (Wii[i]->getButtonClick(Z))
|
||||||
Serial.print(F("\r\nZ"));
|
Serial.print(F("\r\nZ"));
|
||||||
if(Wii[i]->getButtonClick(C))
|
if (Wii[i]->getButtonClick(C))
|
||||||
Serial.print(F("\r\nC"));
|
Serial.print(F("\r\nC"));
|
||||||
if(Wii[i]->getAnalogHat(HatX) > 137 || Wii[i]->getAnalogHat(HatX) < 117 || Wii[i]->getAnalogHat(HatY) > 137 || Wii[i]->getAnalogHat(HatY) < 117) {
|
if (Wii[i]->getAnalogHat(HatX) > 137 || Wii[i]->getAnalogHat(HatX) < 117 || Wii[i]->getAnalogHat(HatY) > 137 || Wii[i]->getAnalogHat(HatY) < 117) {
|
||||||
Serial.print(F("\r\nHatX: "));
|
Serial.print(F("\r\nHatX: "));
|
||||||
Serial.print(Wii[i]->getAnalogHat(HatX));
|
Serial.print(Wii[i]->getAnalogHat(HatX));
|
||||||
Serial.print(F("\tHatY: "));
|
Serial.print(F("\tHatY: "));
|
||||||
|
@ -114,7 +115,7 @@ void loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void onInit() {
|
void onInit() {
|
||||||
for (uint8_t i=0;i<length;i++) {
|
for (uint8_t i = 0; i < length; i++) {
|
||||||
if (Wii[i]->wiimoteConnected && !oldControllerState[i]) {
|
if (Wii[i]->wiimoteConnected && !oldControllerState[i]) {
|
||||||
oldControllerState[i] = true; // Used to check which is the new controller
|
oldControllerState[i] = true; // Used to check which is the new controller
|
||||||
Wii[i]->setLedOn((LED)i); // Cast directly to LED enum - see: "controllerEnums.h"
|
Wii[i]->setLedOn((LED)i); // Cast directly to LED enum - see: "controllerEnums.h"
|
||||||
|
|
|
@ -8,10 +8,11 @@
|
||||||
#include <usbhub.h>
|
#include <usbhub.h>
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
USBHub Hub1(&Usb); // Some dongles have a hub inside
|
//USBHub Hub1(&Usb); // Some dongles have a hub inside
|
||||||
|
|
||||||
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
||||||
/* You can create the instance of the class in two ways */
|
/* You can create the instance of the class in two ways */
|
||||||
WII Wii(&Btd,PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once
|
WII Wii(&Btd, PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once
|
||||||
//WII Wii(&Btd); // After that you can simply create the instance like so and then press any button on the Wiimote
|
//WII Wii(&Btd); // After that you can simply create the instance like so and then press any button on the Wiimote
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
@ -19,69 +20,69 @@ void setup() {
|
||||||
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
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); //halt
|
while (1); //halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nWiimote Bluetooth Library Started"));
|
Serial.print(F("\r\nWiimote Bluetooth Library Started"));
|
||||||
}
|
}
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task();
|
Usb.Task();
|
||||||
if(Wii.wiiUProControllerConnected) {
|
if (Wii.wiiUProControllerConnected) {
|
||||||
if(Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down
|
if (Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down
|
||||||
Serial.print(F("\r\nHome"));
|
Serial.print(F("\r\nHome"));
|
||||||
Wii.disconnect();
|
Wii.disconnect();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(Wii.getButtonClick(LEFT)) {
|
if (Wii.getButtonClick(LEFT)) {
|
||||||
Wii.setAllOff();
|
Wii.setLedOff();
|
||||||
Wii.setLedOn(LED1);
|
Wii.setLedOn(LED1);
|
||||||
Serial.print(F("\r\nLeft"));
|
Serial.print(F("\r\nLeft"));
|
||||||
}
|
}
|
||||||
if(Wii.getButtonClick(RIGHT)) {
|
if (Wii.getButtonClick(RIGHT)) {
|
||||||
Wii.setAllOff();
|
Wii.setLedOff();
|
||||||
Wii.setLedOn(LED3);
|
Wii.setLedOn(LED3);
|
||||||
Serial.print(F("\r\nRight"));
|
Serial.print(F("\r\nRight"));
|
||||||
}
|
}
|
||||||
if(Wii.getButtonClick(DOWN)) {
|
if (Wii.getButtonClick(DOWN)) {
|
||||||
Wii.setAllOff();
|
Wii.setLedOff();
|
||||||
Wii.setLedOn(LED4);
|
Wii.setLedOn(LED4);
|
||||||
Serial.print(F("\r\nDown"));
|
Serial.print(F("\r\nDown"));
|
||||||
}
|
}
|
||||||
if(Wii.getButtonClick(UP)) {
|
if (Wii.getButtonClick(UP)) {
|
||||||
Wii.setAllOff();
|
Wii.setLedOff();
|
||||||
Wii.setLedOn(LED2);
|
Wii.setLedOn(LED2);
|
||||||
Serial.print(F("\r\nUp"));
|
Serial.print(F("\r\nUp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Wii.getButtonClick(PLUS))
|
if (Wii.getButtonClick(PLUS))
|
||||||
Serial.print(F("\r\nPlus"));
|
Serial.print(F("\r\nPlus"));
|
||||||
if(Wii.getButtonClick(MINUS))
|
if (Wii.getButtonClick(MINUS))
|
||||||
Serial.print(F("\r\nMinus"));
|
Serial.print(F("\r\nMinus"));
|
||||||
|
|
||||||
if(Wii.getButtonClick(A))
|
if (Wii.getButtonClick(A))
|
||||||
Serial.print(F("\r\nA"));
|
Serial.print(F("\r\nA"));
|
||||||
if(Wii.getButtonClick(B)) {
|
if (Wii.getButtonClick(B)) {
|
||||||
Wii.setRumbleToggle();
|
Wii.setRumbleToggle();
|
||||||
Serial.print(F("\r\nB"));
|
Serial.print(F("\r\nB"));
|
||||||
}
|
}
|
||||||
if(Wii.getButtonClick(X))
|
if (Wii.getButtonClick(X))
|
||||||
Serial.print(F("\r\nX"));
|
Serial.print(F("\r\nX"));
|
||||||
if(Wii.getButtonClick(Y))
|
if (Wii.getButtonClick(Y))
|
||||||
Serial.print(F("\r\nY"));
|
Serial.print(F("\r\nY"));
|
||||||
|
|
||||||
if(Wii.getButtonClick(L))
|
if (Wii.getButtonClick(L))
|
||||||
Serial.print(F("\r\nL"));
|
Serial.print(F("\r\nL"));
|
||||||
if(Wii.getButtonClick(R))
|
if (Wii.getButtonClick(R))
|
||||||
Serial.print(F("\r\nR"));
|
Serial.print(F("\r\nR"));
|
||||||
if(Wii.getButtonClick(ZL))
|
if (Wii.getButtonClick(ZL))
|
||||||
Serial.print(F("\r\nZL"));
|
Serial.print(F("\r\nZL"));
|
||||||
if(Wii.getButtonClick(ZR))
|
if (Wii.getButtonClick(ZR))
|
||||||
Serial.print(F("\r\nZR"));
|
Serial.print(F("\r\nZR"));
|
||||||
if(Wii.getButtonClick(L3))
|
if (Wii.getButtonClick(L3))
|
||||||
Serial.print(F("\r\nL3"));
|
Serial.print(F("\r\nL3"));
|
||||||
if(Wii.getButtonClick(R3))
|
if (Wii.getButtonClick(R3))
|
||||||
Serial.print(F("\r\nR3"));
|
Serial.print(F("\r\nR3"));
|
||||||
}
|
}
|
||||||
if(Wii.getAnalogHat(LeftHatX) > 2200 || Wii.getAnalogHat(LeftHatX) < 1800 || Wii.getAnalogHat(LeftHatY) > 2200 || Wii.getAnalogHat(LeftHatY) < 1800 || Wii.getAnalogHat(RightHatX) > 2200 || Wii.getAnalogHat(RightHatX) < 1800 || Wii.getAnalogHat(RightHatY) > 2200 || Wii.getAnalogHat(RightHatY) < 1800) {
|
if (Wii.getAnalogHat(LeftHatX) > 2200 || Wii.getAnalogHat(LeftHatX) < 1800 || Wii.getAnalogHat(LeftHatY) > 2200 || Wii.getAnalogHat(LeftHatY) < 1800 || Wii.getAnalogHat(RightHatX) > 2200 || Wii.getAnalogHat(RightHatX) < 1800 || Wii.getAnalogHat(RightHatY) > 2200 || Wii.getAnalogHat(RightHatY) < 1800) {
|
||||||
Serial.print(F("\r\nLeftHatX: "));
|
Serial.print(F("\r\nLeftHatX: "));
|
||||||
Serial.print(Wii.getAnalogHat(LeftHatX));
|
Serial.print(Wii.getAnalogHat(LeftHatX));
|
||||||
Serial.print(F("\tLeftHatY: "));
|
Serial.print(F("\tLeftHatY: "));
|
||||||
|
|
|
@ -19,20 +19,20 @@ void setup() {
|
||||||
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
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); //halt
|
while (1); //halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nPS3 USB Library Started"));
|
Serial.print(F("\r\nPS3 USB Library Started"));
|
||||||
}
|
}
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task();
|
Usb.Task();
|
||||||
|
|
||||||
if(PS3.PS3Connected || PS3.PS3NavigationConnected) {
|
if (PS3.PS3Connected || PS3.PS3NavigationConnected) {
|
||||||
if(PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
|
if (PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
|
||||||
Serial.print(F("\r\nLeftHatX: "));
|
Serial.print(F("\r\nLeftHatX: "));
|
||||||
Serial.print(PS3.getAnalogHat(LeftHatX));
|
Serial.print(PS3.getAnalogHat(LeftHatX));
|
||||||
Serial.print(F("\tLeftHatY: "));
|
Serial.print(F("\tLeftHatY: "));
|
||||||
Serial.print(PS3.getAnalogHat(LeftHatY));
|
Serial.print(PS3.getAnalogHat(LeftHatY));
|
||||||
if(!PS3.PS3NavigationConnected) {
|
if (PS3.PS3Connected) { // The Navigation controller only have one joystick
|
||||||
Serial.print(F("\tRightHatX: "));
|
Serial.print(F("\tRightHatX: "));
|
||||||
Serial.print(PS3.getAnalogHat(RightHatX));
|
Serial.print(PS3.getAnalogHat(RightHatX));
|
||||||
Serial.print(F("\tRightHatY: "));
|
Serial.print(F("\tRightHatY: "));
|
||||||
|
@ -40,121 +40,101 @@ void loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Analog button values can be read from almost all buttons
|
// Analog button values can be read from almost all buttons
|
||||||
if(PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) {
|
if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) {
|
||||||
Serial.print(F("\r\nL2: "));
|
Serial.print(F("\r\nL2: "));
|
||||||
Serial.print(PS3.getAnalogButton(L2));
|
Serial.print(PS3.getAnalogButton(L2));
|
||||||
if(!PS3.PS3NavigationConnected) {
|
if (!PS3.PS3NavigationConnected) {
|
||||||
Serial.print(F("\tR2: "));
|
Serial.print(F("\tR2: "));
|
||||||
Serial.print(PS3.getAnalogButton(R2));
|
Serial.print(PS3.getAnalogButton(R2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(PS))
|
if (PS3.getButtonClick(PS))
|
||||||
Serial.print(F("\r\nPS"));
|
Serial.print(F("\r\nPS"));
|
||||||
|
|
||||||
if(PS3.getButtonClick(TRIANGLE))
|
if (PS3.getButtonClick(TRIANGLE))
|
||||||
Serial.print(F("\r\nTraingle"));
|
Serial.print(F("\r\nTraingle"));
|
||||||
if(PS3.getButtonClick(CIRCLE))
|
if (PS3.getButtonClick(CIRCLE))
|
||||||
Serial.print(F("\r\nCircle"));
|
Serial.print(F("\r\nCircle"));
|
||||||
if(PS3.getButtonClick(CROSS))
|
if (PS3.getButtonClick(CROSS))
|
||||||
Serial.print(F("\r\nCross"));
|
Serial.print(F("\r\nCross"));
|
||||||
if(PS3.getButtonClick(SQUARE))
|
if (PS3.getButtonClick(SQUARE))
|
||||||
Serial.print(F("\r\nSquare"));
|
Serial.print(F("\r\nSquare"));
|
||||||
|
|
||||||
if(PS3.getButtonClick(UP)) {
|
if (PS3.getButtonClick(UP)) {
|
||||||
Serial.print(F("\r\nUp"));
|
Serial.print(F("\r\nUp"));
|
||||||
PS3.setAllOff();
|
PS3.setLedOff();
|
||||||
PS3.setLedOn(LED4);
|
PS3.setLedOn(LED4);
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(RIGHT)) {
|
if (PS3.getButtonClick(RIGHT)) {
|
||||||
Serial.print(F("\r\nRight"));
|
Serial.print(F("\r\nRight"));
|
||||||
PS3.setAllOff();
|
PS3.setLedOff();
|
||||||
PS3.setLedOn(LED1);
|
PS3.setLedOn(LED1);
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(DOWN)) {
|
if (PS3.getButtonClick(DOWN)) {
|
||||||
Serial.print(F("\r\nDown"));
|
Serial.print(F("\r\nDown"));
|
||||||
PS3.setAllOff();
|
PS3.setLedOff();
|
||||||
PS3.setLedOn(LED2);
|
PS3.setLedOn(LED2);
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(LEFT)) {
|
if (PS3.getButtonClick(LEFT)) {
|
||||||
Serial.print(F("\r\nLeft"));
|
Serial.print(F("\r\nLeft"));
|
||||||
PS3.setAllOff();
|
PS3.setLedOff();
|
||||||
PS3.setLedOn(LED3);
|
PS3.setLedOn(LED3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(PS3.getButtonClick(L1))
|
if (PS3.getButtonClick(L1))
|
||||||
Serial.print(F("\r\nL1"));
|
Serial.print(F("\r\nL1"));
|
||||||
if(PS3.getButtonClick(L3))
|
if (PS3.getButtonClick(L3))
|
||||||
Serial.print(F("\r\nL3"));
|
Serial.print(F("\r\nL3"));
|
||||||
if(PS3.getButtonClick(R1))
|
if (PS3.getButtonClick(R1))
|
||||||
Serial.print(F("\r\nR1"));
|
Serial.print(F("\r\nR1"));
|
||||||
if(PS3.getButtonClick(R3))
|
if (PS3.getButtonClick(R3))
|
||||||
Serial.print(F("\r\nR3"));
|
Serial.print(F("\r\nR3"));
|
||||||
|
|
||||||
if(PS3.getButtonClick(SELECT)) {
|
if (PS3.getButtonClick(SELECT)) {
|
||||||
Serial.print(F("\r\nSelect - "));
|
Serial.print(F("\r\nSelect - "));
|
||||||
Serial.print(PS3.getStatusString());
|
Serial.print(PS3.getStatusString());
|
||||||
}
|
}
|
||||||
if(PS3.getButtonClick(START)) {
|
if (PS3.getButtonClick(START)) {
|
||||||
Serial.print(F("\r\nStart"));
|
Serial.print(F("\r\nStart"));
|
||||||
printAngle = !printAngle;
|
printAngle = !printAngle;
|
||||||
}
|
}
|
||||||
}
|
if (printAngle) {
|
||||||
if(printAngle) {
|
|
||||||
Serial.print(F("\r\nPitch: "));
|
Serial.print(F("\r\nPitch: "));
|
||||||
Serial.print(PS3.getAngle(Pitch));
|
Serial.print(PS3.getAngle(Pitch));
|
||||||
Serial.print(F("\tRoll: "));
|
Serial.print(F("\tRoll: "));
|
||||||
Serial.print(PS3.getAngle(Roll));
|
Serial.print(PS3.getAngle(Roll));
|
||||||
}
|
}
|
||||||
else if(PS3.PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
|
}
|
||||||
switch(state) {
|
else if (PS3.PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
|
||||||
case 0:
|
if (state == 0) {
|
||||||
PS3.moveSetRumble(0);
|
PS3.moveSetRumble(0);
|
||||||
PS3.moveSetBulb(Off);
|
PS3.moveSetBulb(Off);
|
||||||
state = 1;
|
} else if (state == 1) {
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
PS3.moveSetRumble(75);
|
PS3.moveSetRumble(75);
|
||||||
PS3.moveSetBulb(Red);
|
PS3.moveSetBulb(Red);
|
||||||
state = 2;
|
} else if (state == 2) {
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
PS3.moveSetRumble(125);
|
PS3.moveSetRumble(125);
|
||||||
PS3.moveSetBulb(Green);
|
PS3.moveSetBulb(Green);
|
||||||
state = 3;
|
} else if (state == 3) {
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
PS3.moveSetRumble(150);
|
PS3.moveSetRumble(150);
|
||||||
PS3.moveSetBulb(Blue);
|
PS3.moveSetBulb(Blue);
|
||||||
state = 4;
|
} else if (state == 4) {
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
PS3.moveSetRumble(175);
|
PS3.moveSetRumble(175);
|
||||||
PS3.moveSetBulb(Yellow);
|
PS3.moveSetBulb(Yellow);
|
||||||
state = 5;
|
} else if (state == 5) {
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
PS3.moveSetRumble(200);
|
PS3.moveSetRumble(200);
|
||||||
PS3.moveSetBulb(Lightblue);
|
PS3.moveSetBulb(Lightblue);
|
||||||
state = 6;
|
} else if (state == 6) {
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
PS3.moveSetRumble(225);
|
PS3.moveSetRumble(225);
|
||||||
PS3.moveSetBulb(Purble);
|
PS3.moveSetBulb(Purble);
|
||||||
state = 7;
|
} else if (state == 7) {
|
||||||
break;
|
|
||||||
|
|
||||||
case 7:
|
|
||||||
PS3.moveSetRumble(250);
|
PS3.moveSetRumble(250);
|
||||||
PS3.moveSetBulb(White);
|
PS3.moveSetBulb(White);
|
||||||
state = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state++;
|
||||||
|
if (state > 7)
|
||||||
|
state = 0;
|
||||||
delay(1000);
|
delay(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,83 +16,84 @@ void setup() {
|
||||||
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
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); // halt
|
while (1); // halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nXBOX Library Started"));
|
Serial.print(F("\r\nXBOX Library Started"));
|
||||||
}
|
}
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task();
|
Usb.Task();
|
||||||
if(Xbox.XboxConnected) {
|
if (Xbox.XboxConnected) {
|
||||||
if(Xbox.getButtonPress(BLACK) || Xbox.getButtonPress(WHITE)) {
|
if (Xbox.getButtonPress(BLACK) || Xbox.getButtonPress(WHITE)) {
|
||||||
Serial.print("BLACK: ");
|
Serial.print("BLACK: ");
|
||||||
Serial.print(Xbox.getButtonPress(BLACK));
|
Serial.print(Xbox.getButtonPress(BLACK));
|
||||||
Serial.print("\tWHITE: ");
|
Serial.print("\tWHITE: ");
|
||||||
Serial.println(Xbox.getButtonPress(WHITE));
|
Serial.println(Xbox.getButtonPress(WHITE));
|
||||||
Xbox.setRumbleOn(Xbox.getButtonPress(BLACK),Xbox.getButtonPress(WHITE));
|
Xbox.setRumbleOn(Xbox.getButtonPress(BLACK), Xbox.getButtonPress(WHITE));
|
||||||
} else
|
} else
|
||||||
Xbox.setRumbleOn(0,0);
|
Xbox.setRumbleOn(0, 0);
|
||||||
if(Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500 || Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500 || Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500 || Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) {
|
|
||||||
if(Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500) {
|
if (Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500 || Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500 || Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500 || Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) {
|
||||||
|
if (Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500) {
|
||||||
Serial.print(F("LeftHatX: "));
|
Serial.print(F("LeftHatX: "));
|
||||||
Serial.print(Xbox.getAnalogHat(LeftHatX));
|
Serial.print(Xbox.getAnalogHat(LeftHatX));
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
}
|
}
|
||||||
if(Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500) {
|
if (Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500) {
|
||||||
Serial.print(F("LeftHatY: "));
|
Serial.print(F("LeftHatY: "));
|
||||||
Serial.print(Xbox.getAnalogHat(LeftHatY));
|
Serial.print(Xbox.getAnalogHat(LeftHatY));
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
}
|
}
|
||||||
if(Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500) {
|
if (Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500) {
|
||||||
Serial.print(F("RightHatX: "));
|
Serial.print(F("RightHatX: "));
|
||||||
Serial.print(Xbox.getAnalogHat(RightHatX));
|
Serial.print(Xbox.getAnalogHat(RightHatX));
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
}
|
}
|
||||||
if(Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) {
|
if (Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) {
|
||||||
Serial.print(F("RightHatY: "));
|
Serial.print(F("RightHatY: "));
|
||||||
Serial.print(Xbox.getAnalogHat(RightHatY));
|
Serial.print(Xbox.getAnalogHat(RightHatY));
|
||||||
}
|
}
|
||||||
Serial.println();
|
Serial.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Xbox.getButtonClick(UP))
|
if (Xbox.getButtonClick(UP))
|
||||||
Serial.println(F("Up"));
|
Serial.println(F("Up"));
|
||||||
if(Xbox.getButtonClick(DOWN))
|
if (Xbox.getButtonClick(DOWN))
|
||||||
Serial.println(F("Down"));
|
Serial.println(F("Down"));
|
||||||
if(Xbox.getButtonClick(LEFT))
|
if (Xbox.getButtonClick(LEFT))
|
||||||
Serial.println(F("Left"));
|
Serial.println(F("Left"));
|
||||||
if(Xbox.getButtonClick(RIGHT))
|
if (Xbox.getButtonClick(RIGHT))
|
||||||
Serial.println(F("Right"));
|
Serial.println(F("Right"));
|
||||||
|
|
||||||
if(Xbox.getButtonClick(START))
|
if (Xbox.getButtonClick(START))
|
||||||
Serial.println(F("Start"));
|
Serial.println(F("Start"));
|
||||||
if(Xbox.getButtonClick(BACK))
|
if (Xbox.getButtonClick(BACK))
|
||||||
Serial.println(F("Back"));
|
Serial.println(F("Back"));
|
||||||
if(Xbox.getButtonClick(L3))
|
if (Xbox.getButtonClick(L3))
|
||||||
Serial.println(F("L3"));
|
Serial.println(F("L3"));
|
||||||
if(Xbox.getButtonClick(R3))
|
if (Xbox.getButtonClick(R3))
|
||||||
Serial.println(F("R3"));
|
Serial.println(F("R3"));
|
||||||
|
|
||||||
if(Xbox.getButtonPress(A)) {
|
if (Xbox.getButtonPress(A)) {
|
||||||
Serial.print(F("A: "));
|
Serial.print(F("A: "));
|
||||||
Serial.println(Xbox.getButtonPress(A));
|
Serial.println(Xbox.getButtonPress(A));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonPress(B)) {
|
if (Xbox.getButtonPress(B)) {
|
||||||
Serial.print(F("B: "));
|
Serial.print(F("B: "));
|
||||||
Serial.println(Xbox.getButtonPress(B));
|
Serial.println(Xbox.getButtonPress(B));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonPress(X)) {
|
if (Xbox.getButtonPress(X)) {
|
||||||
Serial.print(F("X: "));
|
Serial.print(F("X: "));
|
||||||
Serial.println(Xbox.getButtonPress(X));
|
Serial.println(Xbox.getButtonPress(X));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonPress(Y)) {
|
if (Xbox.getButtonPress(Y)) {
|
||||||
Serial.print(F("Y: "));
|
Serial.print(F("Y: "));
|
||||||
Serial.println(Xbox.getButtonPress(Y));
|
Serial.println(Xbox.getButtonPress(Y));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonPress(L1)) {
|
if (Xbox.getButtonPress(L1)) {
|
||||||
Serial.print(F("L1: "));
|
Serial.print(F("L1: "));
|
||||||
Serial.println(Xbox.getButtonPress(L1));
|
Serial.println(Xbox.getButtonPress(L1));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonPress(R1)) {
|
if (Xbox.getButtonPress(R1)) {
|
||||||
Serial.print(F("R1: "));
|
Serial.print(F("R1: "));
|
||||||
Serial.println(Xbox.getButtonPress(R1));
|
Serial.println(Xbox.getButtonPress(R1));
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,98 +15,100 @@ void setup() {
|
||||||
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
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); //halt
|
while (1); //halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nXbox Wireless Receiver Library Started"));
|
Serial.print(F("\r\nXbox Wireless Receiver Library Started"));
|
||||||
}
|
}
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task();
|
Usb.Task();
|
||||||
if(Xbox.XboxReceiverConnected) {
|
if (Xbox.XboxReceiverConnected) {
|
||||||
for(uint8_t i=0;i<4;i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
if(Xbox.Xbox360Connected[i]) {
|
if (Xbox.Xbox360Connected[i]) {
|
||||||
if(Xbox.getButtonPress(L2,i) || Xbox.getButtonPress(R2,i)) {
|
if (Xbox.getButtonPress(L2, i) || Xbox.getButtonPress(R2, i)) {
|
||||||
Serial.print("L2: ");
|
Serial.print("L2: ");
|
||||||
Serial.print(Xbox.getButtonPress(L2,i));
|
Serial.print(Xbox.getButtonPress(L2, i));
|
||||||
Serial.print("\tR2: ");
|
Serial.print("\tR2: ");
|
||||||
Serial.println(Xbox.getButtonPress(R2,i));
|
Serial.println(Xbox.getButtonPress(R2, i));
|
||||||
Xbox.setRumbleOn(Xbox.getButtonPress(L2,i),Xbox.getButtonPress(R2,i),i);
|
Xbox.setRumbleOn(Xbox.getButtonPress(L2, i), Xbox.getButtonPress(R2, i), i);
|
||||||
}
|
}
|
||||||
if(Xbox.getAnalogHat(LeftHatX,i) > 7500 || Xbox.getAnalogHat(LeftHatX,i) < -7500 || Xbox.getAnalogHat(LeftHatY,i) > 7500 || Xbox.getAnalogHat(LeftHatY,i) < -7500 || Xbox.getAnalogHat(RightHatX,i) > 7500 || Xbox.getAnalogHat(RightHatX,i) < -7500 || Xbox.getAnalogHat(RightHatY,i) > 7500 || Xbox.getAnalogHat(RightHatY,i) < -7500) {
|
|
||||||
if(Xbox.getAnalogHat(LeftHatX,i) > 7500 || Xbox.getAnalogHat(LeftHatX,i) < -7500) {
|
if (Xbox.getAnalogHat(LeftHatX, i) > 7500 || Xbox.getAnalogHat(LeftHatX, i) < -7500 || Xbox.getAnalogHat(LeftHatY, i) > 7500 || Xbox.getAnalogHat(LeftHatY, i) < -7500 || Xbox.getAnalogHat(RightHatX, i) > 7500 || Xbox.getAnalogHat(RightHatX, i) < -7500 || Xbox.getAnalogHat(RightHatY, i) > 7500 || Xbox.getAnalogHat(RightHatY, i) < -7500) {
|
||||||
|
if (Xbox.getAnalogHat(LeftHatX, i) > 7500 || Xbox.getAnalogHat(LeftHatX, i) < -7500) {
|
||||||
Serial.print(F("LeftHatX: "));
|
Serial.print(F("LeftHatX: "));
|
||||||
Serial.print(Xbox.getAnalogHat(LeftHatX,i));
|
Serial.print(Xbox.getAnalogHat(LeftHatX, i));
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
}
|
}
|
||||||
if(Xbox.getAnalogHat(LeftHatY,i) > 7500 || Xbox.getAnalogHat(LeftHatY,i) < -7500) {
|
if (Xbox.getAnalogHat(LeftHatY, i) > 7500 || Xbox.getAnalogHat(LeftHatY, i) < -7500) {
|
||||||
Serial.print(F("LeftHatY: "));
|
Serial.print(F("LeftHatY: "));
|
||||||
Serial.print(Xbox.getAnalogHat(LeftHatY,i));
|
Serial.print(Xbox.getAnalogHat(LeftHatY, i));
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
}
|
}
|
||||||
if(Xbox.getAnalogHat(RightHatX,i) > 7500 || Xbox.getAnalogHat(RightHatX,i) < -7500) {
|
if (Xbox.getAnalogHat(RightHatX, i) > 7500 || Xbox.getAnalogHat(RightHatX, i) < -7500) {
|
||||||
Serial.print(F("RightHatX: "));
|
Serial.print(F("RightHatX: "));
|
||||||
Serial.print(Xbox.getAnalogHat(RightHatX,i));
|
Serial.print(Xbox.getAnalogHat(RightHatX, i));
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
}
|
}
|
||||||
if(Xbox.getAnalogHat(RightHatY,i) > 7500 || Xbox.getAnalogHat(RightHatY,i) < -7500) {
|
if (Xbox.getAnalogHat(RightHatY, i) > 7500 || Xbox.getAnalogHat(RightHatY, i) < -7500) {
|
||||||
Serial.print(F("RightHatY: "));
|
Serial.print(F("RightHatY: "));
|
||||||
Serial.print(Xbox.getAnalogHat(RightHatY,i));
|
Serial.print(Xbox.getAnalogHat(RightHatY, i));
|
||||||
}
|
}
|
||||||
Serial.println();
|
Serial.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Xbox.getButtonClick(UP,i)) {
|
if (Xbox.getButtonClick(UP, i)) {
|
||||||
Xbox.setLedOn(LED1,i);
|
Xbox.setLedOn(LED1, i);
|
||||||
Serial.println(F("Up"));
|
Serial.println(F("Up"));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonClick(DOWN,i)) {
|
if (Xbox.getButtonClick(DOWN, i)) {
|
||||||
Xbox.setLedOn(LED4,i);
|
Xbox.setLedOn(LED4, i);
|
||||||
Serial.println(F("Down"));
|
Serial.println(F("Down"));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonClick(LEFT,i)) {
|
if (Xbox.getButtonClick(LEFT, i)) {
|
||||||
Xbox.setLedOn(LED3,i);
|
Xbox.setLedOn(LED3, i);
|
||||||
Serial.println(F("Left"));
|
Serial.println(F("Left"));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonClick(RIGHT,i)) {
|
if (Xbox.getButtonClick(RIGHT, i)) {
|
||||||
Xbox.setLedOn(LED2,i);
|
Xbox.setLedOn(LED2, i);
|
||||||
Serial.println(F("Right"));
|
Serial.println(F("Right"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Xbox.getButtonClick(START,i)) {
|
if (Xbox.getButtonClick(START, i)) {
|
||||||
Xbox.setLedMode(ALTERNATING,i);
|
Xbox.setLedMode(ALTERNATING, i);
|
||||||
Serial.println(F("Start"));
|
Serial.println(F("Start"));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonClick(BACK,i)) {
|
if (Xbox.getButtonClick(BACK, i)) {
|
||||||
Xbox.setLedBlink(ALL,i);
|
Xbox.setLedBlink(ALL, i);
|
||||||
Serial.println(F("Back"));
|
Serial.println(F("Back"));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonClick(L3,i))
|
if (Xbox.getButtonClick(L3, i))
|
||||||
Serial.println(F("L3"));
|
Serial.println(F("L3"));
|
||||||
if(Xbox.getButtonClick(R3,i))
|
if (Xbox.getButtonClick(R3, i))
|
||||||
Serial.println(F("R3"));
|
Serial.println(F("R3"));
|
||||||
|
|
||||||
if(Xbox.getButtonClick(L1,i))
|
if (Xbox.getButtonClick(L1, i))
|
||||||
Serial.println(F("L1"));
|
Serial.println(F("L1"));
|
||||||
if(Xbox.getButtonClick(R1,i))
|
if (Xbox.getButtonClick(R1, i))
|
||||||
Serial.println(F("R1"));
|
Serial.println(F("R1"));
|
||||||
if(Xbox.getButtonClick(XBOX,i)) {
|
if (Xbox.getButtonClick(XBOX, i)) {
|
||||||
Xbox.setLedMode(ROTATING,i);
|
Xbox.setLedMode(ROTATING, i);
|
||||||
Serial.print(F("Xbox (Battery: "));
|
Serial.print(F("Xbox (Battery: "));
|
||||||
Serial.print(Xbox.getBatteryLevel(i)); // The battery level in the range 0-3
|
Serial.print(Xbox.getBatteryLevel(i)); // The battery level in the range 0-3
|
||||||
Serial.println(F(")"));
|
Serial.println(F(")"));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonClick(SYNC,i))
|
if (Xbox.getButtonClick(SYNC, i)) {
|
||||||
Serial.println(F("Sync"));
|
Serial.println(F("Sync"));
|
||||||
|
Xbox.disconnect(i);
|
||||||
|
}
|
||||||
|
|
||||||
if(Xbox.getButtonClick(A,i))
|
if (Xbox.getButtonClick(A, i))
|
||||||
Serial.println(F("A"));
|
Serial.println(F("A"));
|
||||||
if(Xbox.getButtonClick(B,i))
|
if (Xbox.getButtonClick(B, i))
|
||||||
Serial.println(F("B"));
|
Serial.println(F("B"));
|
||||||
if(Xbox.getButtonClick(X,i))
|
if (Xbox.getButtonClick(X, i))
|
||||||
Serial.println(F("X"));
|
Serial.println(F("X"));
|
||||||
if(Xbox.getButtonClick(Y,i))
|
if (Xbox.getButtonClick(Y, i))
|
||||||
Serial.println(F("Y"));
|
Serial.println(F("Y"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delay(1);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,90 +14,91 @@ void setup() {
|
||||||
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
|
||||||
if (Usb.Init() == -1) {
|
if (Usb.Init() == -1) {
|
||||||
Serial.print(F("\r\nOSC did not start"));
|
Serial.print(F("\r\nOSC did not start"));
|
||||||
while(1); //halt
|
while (1); //halt
|
||||||
}
|
}
|
||||||
Serial.print(F("\r\nXBOX USB Library Started"));
|
Serial.print(F("\r\nXBOX USB Library Started"));
|
||||||
}
|
}
|
||||||
void loop() {
|
void loop() {
|
||||||
Usb.Task();
|
Usb.Task();
|
||||||
if(Xbox.Xbox360Connected) {
|
if (Xbox.Xbox360Connected) {
|
||||||
if(Xbox.getButtonPress(L2) || Xbox.getButtonPress(R2)) {
|
if (Xbox.getButtonPress(L2) || Xbox.getButtonPress(R2)) {
|
||||||
Serial.print("L2: ");
|
Serial.print("L2: ");
|
||||||
Serial.print(Xbox.getButtonPress(L2));
|
Serial.print(Xbox.getButtonPress(L2));
|
||||||
Serial.print("\tR2: ");
|
Serial.print("\tR2: ");
|
||||||
Serial.println(Xbox.getButtonPress(R2));
|
Serial.println(Xbox.getButtonPress(R2));
|
||||||
Xbox.setRumbleOn(Xbox.getButtonPress(L2),Xbox.getButtonPress(R2));
|
Xbox.setRumbleOn(Xbox.getButtonPress(L2), Xbox.getButtonPress(R2));
|
||||||
} else
|
} else
|
||||||
Xbox.setRumbleOn(0,0);
|
Xbox.setRumbleOn(0, 0);
|
||||||
if(Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500 || Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500 || Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500 || Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) {
|
|
||||||
if(Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500) {
|
if (Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500 || Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500 || Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500 || Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) {
|
||||||
|
if (Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500) {
|
||||||
Serial.print(F("LeftHatX: "));
|
Serial.print(F("LeftHatX: "));
|
||||||
Serial.print(Xbox.getAnalogHat(LeftHatX));
|
Serial.print(Xbox.getAnalogHat(LeftHatX));
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
}
|
}
|
||||||
if(Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500) {
|
if (Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500) {
|
||||||
Serial.print(F("LeftHatY: "));
|
Serial.print(F("LeftHatY: "));
|
||||||
Serial.print(Xbox.getAnalogHat(LeftHatY));
|
Serial.print(Xbox.getAnalogHat(LeftHatY));
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
}
|
}
|
||||||
if(Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500) {
|
if (Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500) {
|
||||||
Serial.print(F("RightHatX: "));
|
Serial.print(F("RightHatX: "));
|
||||||
Serial.print(Xbox.getAnalogHat(RightHatX));
|
Serial.print(Xbox.getAnalogHat(RightHatX));
|
||||||
Serial.print("\t");
|
Serial.print("\t");
|
||||||
}
|
}
|
||||||
if(Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) {
|
if (Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) {
|
||||||
Serial.print(F("RightHatY: "));
|
Serial.print(F("RightHatY: "));
|
||||||
Serial.print(Xbox.getAnalogHat(RightHatY));
|
Serial.print(Xbox.getAnalogHat(RightHatY));
|
||||||
}
|
}
|
||||||
Serial.println();
|
Serial.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Xbox.getButtonClick(UP)) {
|
if (Xbox.getButtonClick(UP)) {
|
||||||
Xbox.setLedOn(LED1);
|
Xbox.setLedOn(LED1);
|
||||||
Serial.println(F("Up"));
|
Serial.println(F("Up"));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonClick(DOWN)) {
|
if (Xbox.getButtonClick(DOWN)) {
|
||||||
Xbox.setLedOn(LED4);
|
Xbox.setLedOn(LED4);
|
||||||
Serial.println(F("Down"));
|
Serial.println(F("Down"));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonClick(LEFT)) {
|
if (Xbox.getButtonClick(LEFT)) {
|
||||||
Xbox.setLedOn(LED3);
|
Xbox.setLedOn(LED3);
|
||||||
Serial.println(F("Left"));
|
Serial.println(F("Left"));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonClick(RIGHT)) {
|
if (Xbox.getButtonClick(RIGHT)) {
|
||||||
Xbox.setLedOn(LED2);
|
Xbox.setLedOn(LED2);
|
||||||
Serial.println(F("Right"));
|
Serial.println(F("Right"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Xbox.getButtonClick(START)) {
|
if (Xbox.getButtonClick(START)) {
|
||||||
Xbox.setLedMode(ALTERNATING);
|
Xbox.setLedMode(ALTERNATING);
|
||||||
Serial.println(F("Start"));
|
Serial.println(F("Start"));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonClick(BACK)) {
|
if (Xbox.getButtonClick(BACK)) {
|
||||||
Xbox.setLedBlink(ALL);
|
Xbox.setLedBlink(ALL);
|
||||||
Serial.println(F("Back"));
|
Serial.println(F("Back"));
|
||||||
}
|
}
|
||||||
if(Xbox.getButtonClick(L3))
|
if (Xbox.getButtonClick(L3))
|
||||||
Serial.println(F("L3"));
|
Serial.println(F("L3"));
|
||||||
if(Xbox.getButtonClick(R3))
|
if (Xbox.getButtonClick(R3))
|
||||||
Serial.println(F("R3"));
|
Serial.println(F("R3"));
|
||||||
|
|
||||||
if(Xbox.getButtonClick(L1))
|
if (Xbox.getButtonClick(L1))
|
||||||
Serial.println(F("L1"));
|
Serial.println(F("L1"));
|
||||||
if(Xbox.getButtonClick(R1))
|
if (Xbox.getButtonClick(R1))
|
||||||
Serial.println(F("R1"));
|
Serial.println(F("R1"));
|
||||||
if(Xbox.getButtonClick(XBOX)) {
|
if (Xbox.getButtonClick(XBOX)) {
|
||||||
Xbox.setLedMode(ROTATING);
|
Xbox.setLedMode(ROTATING);
|
||||||
Serial.println(F("Xbox"));
|
Serial.println(F("Xbox"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Xbox.getButtonClick(A))
|
if (Xbox.getButtonClick(A))
|
||||||
Serial.println(F("A"));
|
Serial.println(F("A"));
|
||||||
if(Xbox.getButtonClick(B))
|
if (Xbox.getButtonClick(B))
|
||||||
Serial.println(F("B"));
|
Serial.println(F("B"));
|
||||||
if(Xbox.getButtonClick(X))
|
if (Xbox.getButtonClick(X))
|
||||||
Serial.println(F("X"));
|
Serial.println(F("X"));
|
||||||
if(Xbox.getButtonClick(Y))
|
if (Xbox.getButtonClick(Y))
|
||||||
Serial.println(F("Y"));
|
Serial.println(F("Y"));
|
||||||
}
|
}
|
||||||
delay(1);
|
delay(1);
|
||||||
|
|
|
@ -10,7 +10,9 @@ ADK adk(&Usb, "TKJElectronics", // Manufacturer Name
|
||||||
"http://www.tkjelectronics.dk/uploads/ArduinoBlinkLED.apk", // URL (web page to visit if no installed apps support the accessory)
|
"http://www.tkjelectronics.dk/uploads/ArduinoBlinkLED.apk", // URL (web page to visit if no installed apps support the accessory)
|
||||||
"123456789"); // Serial Number (optional)
|
"123456789"); // Serial Number (optional)
|
||||||
|
|
||||||
#define LED LED_BUILTIN // Pin 13 is occupied by the SCK pin on a normal Arduino (Uno, Duemilanove etc.), so use a different pin
|
#define LED LED_BUILTIN // Use built in LED - note that pin 13 is occupied by the SCK pin on a normal Arduino (Uno, Duemilanove etc.), so use a different pin
|
||||||
|
|
||||||
|
uint32_t timer;
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
@ -29,13 +31,26 @@ void loop() {
|
||||||
uint8_t msg[1];
|
uint8_t msg[1];
|
||||||
uint16_t len = sizeof(msg);
|
uint16_t len = sizeof(msg);
|
||||||
uint8_t rcode = adk.RcvData(&len, msg);
|
uint8_t rcode = adk.RcvData(&len, msg);
|
||||||
if (rcode && rcode != hrNAK)
|
if (rcode && rcode != hrNAK) {
|
||||||
USBTRACE2("Data rcv. :", rcode);
|
Serial.print(F("\r\nData rcv: "));
|
||||||
else if (len > 0) {
|
Serial.print(rcode, HEX);
|
||||||
|
} else if (len > 0) {
|
||||||
Serial.print(F("\r\nData Packet: "));
|
Serial.print(F("\r\nData Packet: "));
|
||||||
Serial.print(msg[0]);
|
Serial.print(msg[0]);
|
||||||
digitalWrite(LED, msg[0] ? HIGH : LOW);
|
digitalWrite(LED, msg[0] ? HIGH : LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (millis() - timer >= 1000) { // Send data every 1s
|
||||||
|
timer = millis();
|
||||||
|
rcode = adk.SndData(sizeof(timer), (uint8_t*)&timer);
|
||||||
|
if (rcode && rcode != hrNAK) {
|
||||||
|
Serial.print(F("\r\nData send: "));
|
||||||
|
Serial.print(rcode, HEX);
|
||||||
|
} else if (rcode != hrNAK) {
|
||||||
|
Serial.print(F("\r\nTimer: "));
|
||||||
|
Serial.print(timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
digitalWrite(LED, LOW);
|
digitalWrite(LED, LOW);
|
||||||
|
|
|
@ -43,12 +43,12 @@ EXTRA_FLAGS += -D USB_HOST_SERIAL=Serial3
|
||||||
#EXTRA_FLAGS += -D DEBUG_USB_HOST
|
#EXTRA_FLAGS += -D DEBUG_USB_HOST
|
||||||
|
|
||||||
# The following are the libraries used.
|
# The following are the libraries used.
|
||||||
LIB_DIRS =
|
LIB_DIRS += ../../
|
||||||
LIB_DIRS += ../libraries/xmem
|
LIB_DIRS += ../testusbhostFAT/xmem2
|
||||||
LIB_DIRS += ../libraries/USB_Host_Shield_2_0
|
LIB_DIRS += ../testusbhostFAT/generic_storage
|
||||||
LIB_DIRS += ../libraries/generic_storage
|
LIB_DIRS += ../testusbhostFAT/RTClib
|
||||||
LIB_DIRS += ../libraries/RTClib
|
|
||||||
LIB_DIRS += $(ARD_HOME)/libraries/Wire
|
LIB_DIRS += $(ARD_HOME)/libraries/Wire
|
||||||
LIB_DIRS += $(ARD_HOME)/libraries/Wire/utility
|
LIB_DIRS += $(ARD_HOME)/libraries/Wire/utility
|
||||||
|
|
||||||
# And finally, the part that brings everything together for you.
|
# And finally, the part that brings everything together for you.
|
||||||
include ../Arduino_Makefile_master/_Makefile.master
|
include Arduino_Makefile_master/_Makefile.master
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit cb8b5690c7d683e0c24e6894ff05552f83240714
|
Subproject commit a4bd6f500f70599847de60973371ee973d094a34
|
|
@ -47,8 +47,11 @@
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
// End of Arduino IDE specific hacks //
|
// End of Arduino IDE specific hacks //
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
|
#if defined(AVR)
|
||||||
#include <xmem.h>
|
#include <xmem.h>
|
||||||
|
#else
|
||||||
|
#include <spi4teensy3.h>
|
||||||
|
#endif
|
||||||
#if WANT_HUB_TEST
|
#if WANT_HUB_TEST
|
||||||
#include <usbhub.h>
|
#include <usbhub.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -59,22 +62,23 @@
|
||||||
#include <FAT/FAT.h>
|
#include <FAT/FAT.h>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include <RTClib.h>
|
#include <RTClib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#if defined(AVR)
|
||||||
static FILE tty_stdio;
|
static FILE tty_stdio;
|
||||||
static FILE tty_stderr;
|
static FILE tty_stderr;
|
||||||
USB Usb;
|
volatile uint32_t LEDnext_time; // fade timeout
|
||||||
|
volatile uint32_t HEAPnext_time; // when to print out next heap report
|
||||||
#define LED 13 // the pin that the LED is attached to
|
|
||||||
|
|
||||||
volatile int brightness = 0; // how bright the LED is
|
volatile int brightness = 0; // how bright the LED is
|
||||||
volatile int fadeAmount = 80; // how many points to fade the LED by
|
volatile int fadeAmount = 80; // how many points to fade the LED by
|
||||||
|
#endif
|
||||||
|
|
||||||
|
USB Usb;
|
||||||
|
|
||||||
volatile uint8_t current_state = 1;
|
volatile uint8_t current_state = 1;
|
||||||
volatile uint32_t LEDnext_time; // fade timeout
|
|
||||||
volatile uint8_t last_state = 0;
|
volatile uint8_t last_state = 0;
|
||||||
volatile boolean fatready = false;
|
volatile boolean fatready = false;
|
||||||
volatile boolean partsready = false;
|
volatile boolean partsready = false;
|
||||||
volatile boolean notified = false;
|
volatile boolean notified = false;
|
||||||
volatile uint32_t HEAPnext_time; // when to print out next heap report
|
|
||||||
volatile boolean runtest = false;
|
volatile boolean runtest = false;
|
||||||
volatile boolean usbon = false;
|
volatile boolean usbon = false;
|
||||||
volatile uint32_t usbon_time;
|
volatile uint32_t usbon_time;
|
||||||
|
@ -96,6 +100,7 @@ static storage_t sto[_VOLUMES];
|
||||||
#define mbxs 128
|
#define mbxs 128
|
||||||
static uint8_t My_Buff_x[mbxs]; /* File read buffer */
|
static uint8_t My_Buff_x[mbxs]; /* File read buffer */
|
||||||
|
|
||||||
|
#if defined(AVR)
|
||||||
|
|
||||||
#define prescale1 ((1 << WGM12) | (1 << CS10))
|
#define prescale1 ((1 << WGM12) | (1 << CS10))
|
||||||
#define prescale8 ((1 << WGM12) | (1 << CS11))
|
#define prescale8 ((1 << WGM12) | (1 << CS11))
|
||||||
|
@ -110,6 +115,11 @@ static int tty_stderr_putc(char c, FILE *t) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tty_stderr_flush(FILE *t) {
|
||||||
|
USB_HOST_SERIAL.flush();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int tty_std_putc(char c, FILE *t) {
|
static int tty_std_putc(char c, FILE *t) {
|
||||||
Serial.write(c);
|
Serial.write(c);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -120,6 +130,49 @@ static int tty_std_getc(FILE *t) {
|
||||||
return Serial.read();
|
return Serial.read();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tty_std_flush(FILE *t) {
|
||||||
|
Serial.flush();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
int _write(int fd, const char *ptr, int len) {
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < len; j++) {
|
||||||
|
if (fd == 1)
|
||||||
|
Serial.write(*ptr++);
|
||||||
|
else if (fd == 2)
|
||||||
|
USB_HOST_SERIAL.write(*ptr++);
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _read(int fd, char *ptr, int len) {
|
||||||
|
if (len > 0 && fd == 0) {
|
||||||
|
while (!Serial.available());
|
||||||
|
*ptr = Serial.read();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
int _fstat(int fd, struct stat *st) {
|
||||||
|
memset(st, 0, sizeof (*st));
|
||||||
|
st->st_mode = S_IFCHR;
|
||||||
|
st->st_blksize = 1024;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _isatty(int fd) {
|
||||||
|
return (fd < 3) ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
boolean serr = false;
|
boolean serr = false;
|
||||||
for (int i = 0; i < _VOLUMES; i++) {
|
for (int i = 0; i < _VOLUMES; i++) {
|
||||||
|
@ -130,8 +183,10 @@ void setup() {
|
||||||
// Set this to higher values to enable more debug information
|
// Set this to higher values to enable more debug information
|
||||||
// minimum 0x00, maximum 0xff
|
// minimum 0x00, maximum 0xff
|
||||||
UsbDEBUGlvl = 0x51;
|
UsbDEBUGlvl = 0x51;
|
||||||
|
|
||||||
|
#if defined(AVR)
|
||||||
// make LED pin as an output:
|
// make LED pin as an output:
|
||||||
pinMode(LED, OUTPUT);
|
pinMode(LED_BUILTIN, OUTPUT);
|
||||||
pinMode(2, OUTPUT);
|
pinMode(2, OUTPUT);
|
||||||
// Ensure TX is off
|
// Ensure TX is off
|
||||||
_SFR_BYTE(UCSR0B) &= ~_BV(TXEN0);
|
_SFR_BYTE(UCSR0B) &= ~_BV(TXEN0);
|
||||||
|
@ -148,21 +203,26 @@ void setup() {
|
||||||
tty_stdio.get = tty_std_getc;
|
tty_stdio.get = tty_std_getc;
|
||||||
tty_stdio.flags = _FDEV_SETUP_RW;
|
tty_stdio.flags = _FDEV_SETUP_RW;
|
||||||
tty_stdio.udata = 0;
|
tty_stdio.udata = 0;
|
||||||
stdout = &tty_stdio;
|
|
||||||
stdin = &tty_stdio;
|
|
||||||
|
|
||||||
tty_stderr.put = tty_stderr_putc;
|
tty_stderr.put = tty_stderr_putc;
|
||||||
tty_stderr.get = NULL;
|
tty_stderr.get = NULL;
|
||||||
tty_stderr.flags = _FDEV_SETUP_WRITE;
|
tty_stderr.flags = _FDEV_SETUP_WRITE;
|
||||||
tty_stderr.udata = 0;
|
tty_stderr.udata = 0;
|
||||||
|
|
||||||
|
stdout = &tty_stdio;
|
||||||
|
stdin = &tty_stdio;
|
||||||
stderr = &tty_stderr;
|
stderr = &tty_stderr;
|
||||||
|
|
||||||
// Blink LED
|
// Blink LED
|
||||||
delay(500);
|
delay(500);
|
||||||
analogWrite(LED, 255);
|
analogWrite(LED_BUILTIN, 255);
|
||||||
delay(500);
|
delay(500);
|
||||||
analogWrite(LED, 0);
|
analogWrite(LED_BUILTIN, 0);
|
||||||
delay(500);
|
delay(500);
|
||||||
|
#else
|
||||||
|
while (!Serial);
|
||||||
|
#endif
|
||||||
|
|
||||||
printf_P(PSTR("\r\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nStart\r\n"));
|
printf_P(PSTR("\r\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nStart\r\n"));
|
||||||
printf_P(PSTR("Current UsbDEBUGlvl %02x\r\n"), UsbDEBUGlvl);
|
printf_P(PSTR("Current UsbDEBUGlvl %02x\r\n"), UsbDEBUGlvl);
|
||||||
printf_P(PSTR("'+' and '-' increase/decrease by 0x01\r\n"));
|
printf_P(PSTR("'+' and '-' increase/decrease by 0x01\r\n"));
|
||||||
|
@ -187,17 +247,19 @@ void setup() {
|
||||||
#endif
|
#endif
|
||||||
"\r\n"));
|
"\r\n"));
|
||||||
}
|
}
|
||||||
analogWrite(LED, 255);
|
#if defined(AVR)
|
||||||
|
|
||||||
|
analogWrite(LED_BUILTIN, 255);
|
||||||
delay(500);
|
delay(500);
|
||||||
analogWrite(LED, 0);
|
analogWrite(LED_BUILTIN, 0);
|
||||||
delay(500);
|
delay(500);
|
||||||
analogWrite(LED, 255);
|
analogWrite(LED_BUILTIN, 255);
|
||||||
delay(500);
|
delay(500);
|
||||||
analogWrite(LED, 0);
|
analogWrite(LED_BUILTIN, 0);
|
||||||
delay(500);
|
delay(500);
|
||||||
analogWrite(LED, 255);
|
analogWrite(LED_BUILTIN, 255);
|
||||||
delay(500);
|
delay(500);
|
||||||
analogWrite(LED, 0);
|
analogWrite(LED_BUILTIN, 0);
|
||||||
delay(500);
|
delay(500);
|
||||||
|
|
||||||
LEDnext_time = millis() + 1;
|
LEDnext_time = millis() + 1;
|
||||||
|
@ -206,6 +268,7 @@ void setup() {
|
||||||
#endif
|
#endif
|
||||||
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
|
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
|
||||||
printf_P(PSTR("SP %x\r\n"), (uint8_t *)(SP));
|
printf_P(PSTR("SP %x\r\n"), (uint8_t *)(SP));
|
||||||
|
#endif
|
||||||
|
|
||||||
// Even though I'm not going to actually be deleting,
|
// Even though I'm not going to actually be deleting,
|
||||||
// I want to be able to have slightly more control.
|
// I want to be able to have slightly more control.
|
||||||
|
@ -213,7 +276,9 @@ void setup() {
|
||||||
#if WANT_HUB_TEST
|
#if WANT_HUB_TEST
|
||||||
for (int i = 0; i < MAX_HUBS; i++) {
|
for (int i = 0; i < MAX_HUBS; i++) {
|
||||||
Hubs[i] = new USBHub(&Usb);
|
Hubs[i] = new USBHub(&Usb);
|
||||||
|
#if defined(AVR)
|
||||||
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
|
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Initialize generic storage. This must be done before USB starts.
|
// Initialize generic storage. This must be done before USB starts.
|
||||||
|
@ -223,10 +288,8 @@ void setup() {
|
||||||
printf_P(PSTR("No USB HOST Shield?\r\n"));
|
printf_P(PSTR("No USB HOST Shield?\r\n"));
|
||||||
Notify(PSTR("OSC did not start."), 0x40);
|
Notify(PSTR("OSC did not start."), 0x40);
|
||||||
}
|
}
|
||||||
// usb VBUS _OFF_
|
|
||||||
//Usb.gpioWr(0x00);
|
#if defined(AVR)
|
||||||
//digitalWrite(2, 0);
|
|
||||||
//usbon_time = millis() + 2000;
|
|
||||||
cli();
|
cli();
|
||||||
TCCR3A = 0;
|
TCCR3A = 0;
|
||||||
TCCR3B = 0;
|
TCCR3B = 0;
|
||||||
|
@ -237,6 +300,32 @@ void setup() {
|
||||||
sei();
|
sei();
|
||||||
|
|
||||||
HEAPnext_time = millis() + 10000;
|
HEAPnext_time = millis() + 10000;
|
||||||
|
#else
|
||||||
|
#if 0
|
||||||
|
//
|
||||||
|
// On the teensy 3 we can raise the speed of SPI here.
|
||||||
|
//
|
||||||
|
// Default seen is 0xB8011001.
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t ctar = SPI0_CTAR0;
|
||||||
|
//printf("SPI_CTAR0 = %8.8X\r\n", ctar);
|
||||||
|
ctar &= 0x7FFCFFF0; // 1/4 fSYS, 12.5Mhz
|
||||||
|
//printf("SPI_CTAR0 = %8.8X\r\n", ctar);
|
||||||
|
ctar |= 0x80000000; // 1/2 fSYS 25Mhz
|
||||||
|
//printf("SPI_CTAR0 = %8.8X\r\n", ctar);
|
||||||
|
|
||||||
|
uint32_t mcr = SPI0_MCR;
|
||||||
|
if (mcr & SPI_MCR_MDIS) {
|
||||||
|
SPI0_CTAR0 = ctar;
|
||||||
|
} else {
|
||||||
|
SPI0_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT;
|
||||||
|
SPI0_CTAR0 = ctar;
|
||||||
|
SPI0_MCR = mcr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialEvent() {
|
void serialEvent() {
|
||||||
|
@ -278,12 +367,14 @@ void serialEvent() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(AVR)
|
||||||
|
|
||||||
ISR(TIMER3_COMPA_vect) {
|
ISR(TIMER3_COMPA_vect) {
|
||||||
if (millis() >= LEDnext_time) {
|
if (millis() >= LEDnext_time) {
|
||||||
LEDnext_time = millis() + 30;
|
LEDnext_time = millis() + 30;
|
||||||
|
|
||||||
// set the brightness of LED
|
// set the brightness of LED
|
||||||
analogWrite(LED, brightness);
|
analogWrite(LED_BUILTIN, brightness);
|
||||||
|
|
||||||
// change the brightness for next time through the loop:
|
// change the brightness for next time through the loop:
|
||||||
brightness = brightness + fadeAmount;
|
brightness = brightness + fadeAmount;
|
||||||
|
@ -299,6 +390,7 @@ ISR(TIMER3_COMPA_vect) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool isfat(uint8_t t) {
|
bool isfat(uint8_t t) {
|
||||||
return (t == 0x01 || t == 0x04 || t == 0x06 || t == 0x0b || t == 0x0c || t == 0x0e || t == 0x1);
|
return (t == 0x01 || t == 0x04 || t == 0x06 || t == 0x0b || t == 0x0c || t == 0x0e || t == 0x1);
|
||||||
|
@ -312,6 +404,7 @@ void die(FRESULT rc) {
|
||||||
void loop() {
|
void loop() {
|
||||||
FIL My_File_Object_x; /* File object */
|
FIL My_File_Object_x; /* File object */
|
||||||
|
|
||||||
|
#if defined(AVR)
|
||||||
// Print a heap status report about every 10 seconds.
|
// Print a heap status report about every 10 seconds.
|
||||||
if (millis() >= HEAPnext_time) {
|
if (millis() >= HEAPnext_time) {
|
||||||
if (UsbDEBUGlvl > 0x50) {
|
if (UsbDEBUGlvl > 0x50) {
|
||||||
|
@ -319,7 +412,11 @@ void loop() {
|
||||||
}
|
}
|
||||||
HEAPnext_time = millis() + 10000;
|
HEAPnext_time = millis() + 10000;
|
||||||
}
|
}
|
||||||
|
TCCR3B = 0;
|
||||||
|
#else
|
||||||
|
// Arm suffers here, oh well...
|
||||||
|
serialEvent();
|
||||||
|
#endif
|
||||||
// Horrid! This sort of thing really belongs in an ISR, not here!
|
// Horrid! This sort of thing really belongs in an ISR, not here!
|
||||||
// We also will be needing to test each hub port, we don't do this yet!
|
// We also will be needing to test each hub port, we don't do this yet!
|
||||||
if (!change && !usbon && millis() >= usbon_time) {
|
if (!change && !usbon && millis() >= usbon_time) {
|
||||||
|
@ -342,11 +439,15 @@ void loop() {
|
||||||
if (current_state != last_state) {
|
if (current_state != last_state) {
|
||||||
if (UsbDEBUGlvl > 0x50)
|
if (UsbDEBUGlvl > 0x50)
|
||||||
printf_P(PSTR("USB state = %x\r\n"), current_state);
|
printf_P(PSTR("USB state = %x\r\n"), current_state);
|
||||||
|
#if defined(AVR)
|
||||||
if (current_state == USB_STATE_RUNNING) {
|
if (current_state == USB_STATE_RUNNING) {
|
||||||
fadeAmount = 30;
|
fadeAmount = 30;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (current_state == USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) {
|
if (current_state == USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) {
|
||||||
|
#if defined(AVR)
|
||||||
fadeAmount = 80;
|
fadeAmount = 80;
|
||||||
|
#endif
|
||||||
partsready = false;
|
partsready = false;
|
||||||
for (int i = 0; i < cpart; i++) {
|
for (int i = 0; i < cpart; i++) {
|
||||||
if (Fats[i] != NULL)
|
if (Fats[i] != NULL)
|
||||||
|
@ -365,10 +466,10 @@ void loop() {
|
||||||
if (partsready && !fatready) {
|
if (partsready && !fatready) {
|
||||||
if (cpart > 0) fatready = true;
|
if (cpart > 0) fatready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is horrible, and needs to be moved elsewhere!
|
// This is horrible, and needs to be moved elsewhere!
|
||||||
for (int B = 0; B < MAX_USB_MS_DRIVERS; B++) {
|
for (int B = 0; B < MAX_USB_MS_DRIVERS; B++) {
|
||||||
if (!partsready && Bulk[B]->GetAddress() != NULL) {
|
if (!partsready && (Bulk[B]->GetAddress() != NULL)) {
|
||||||
|
|
||||||
// Build a list.
|
// Build a list.
|
||||||
int ML = Bulk[B]->GetbMaxLUN();
|
int ML = Bulk[B]->GetbMaxLUN();
|
||||||
//printf("MAXLUN = %i\r\n", ML);
|
//printf("MAXLUN = %i\r\n", ML);
|
||||||
|
@ -376,8 +477,8 @@ void loop() {
|
||||||
for (int i = 0; i < ML; i++) {
|
for (int i = 0; i < ML; i++) {
|
||||||
if (Bulk[B]->LUNIsGood(i)) {
|
if (Bulk[B]->LUNIsGood(i)) {
|
||||||
partsready = true;
|
partsready = true;
|
||||||
((pvt_t *)sto[i].private_data)->lun = i;
|
((pvt_t *)(sto[i].private_data))->lun = i;
|
||||||
((pvt_t *)sto[i].private_data)->B = B;
|
((pvt_t *)(sto[i].private_data))->B = B;
|
||||||
sto[i].Read = *PRead;
|
sto[i].Read = *PRead;
|
||||||
sto[i].Write = *PWrite;
|
sto[i].Write = *PWrite;
|
||||||
sto[i].Reads = *PReads;
|
sto[i].Reads = *PReads;
|
||||||
|
@ -440,7 +541,9 @@ void loop() {
|
||||||
p = ((struct Pvt *)(Fats[0]->storage->private_data));
|
p = ((struct Pvt *)(Fats[0]->storage->private_data));
|
||||||
if (!Bulk[p->B]->LUNIsGood(p->lun)) {
|
if (!Bulk[p->B]->LUNIsGood(p->lun)) {
|
||||||
// media change
|
// media change
|
||||||
|
#if defined(AVR)
|
||||||
fadeAmount = 80;
|
fadeAmount = 80;
|
||||||
|
#endif
|
||||||
partsready = false;
|
partsready = false;
|
||||||
for (int i = 0; i < cpart; i++) {
|
for (int i = 0; i < cpart; i++) {
|
||||||
if (Fats[i] != NULL)
|
if (Fats[i] != NULL)
|
||||||
|
@ -459,11 +562,13 @@ void loop() {
|
||||||
UINT bw, br, i;
|
UINT bw, br, i;
|
||||||
|
|
||||||
if (!notified) {
|
if (!notified) {
|
||||||
|
#if defined(AVR)
|
||||||
fadeAmount = 5;
|
fadeAmount = 5;
|
||||||
|
#endif
|
||||||
notified = true;
|
notified = true;
|
||||||
printf_P(PSTR("\r\nOpen an existing file (message.txt).\r\n"));
|
printf_P(PSTR("\r\nOpen an existing file (message.txt).\r\n"));
|
||||||
rc = f_open(&My_File_Object_x, "0:/MESSAGE.TXT", FA_READ);
|
rc = f_open(&My_File_Object_x, "0:/MESSAGE.TXT", FA_READ);
|
||||||
if (rc) printf_P(PSTR("Error %i, message.txt not found.\r\n"));
|
if (rc) printf_P(PSTR("Error %i, message.txt not found.\r\n"), rc);
|
||||||
else {
|
else {
|
||||||
printf_P(PSTR("\r\nType the file content.\r\n"));
|
printf_P(PSTR("\r\nType the file content.\r\n"));
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -522,7 +627,9 @@ outdir:
|
||||||
}
|
}
|
||||||
|
|
||||||
printf_P(PSTR("\r\nDirectory listing...\r\n"));
|
printf_P(PSTR("\r\nDirectory listing...\r\n"));
|
||||||
|
#if defined(AVR)
|
||||||
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
|
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
|
||||||
|
#endif
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if _USE_LFN
|
#if _USE_LFN
|
||||||
My_File_Info_Object_x.lfsize = _MAX_LFN;
|
My_File_Info_Object_x.lfsize = _MAX_LFN;
|
||||||
|
@ -583,7 +690,9 @@ out:
|
||||||
rc = f_open(&My_File_Object_x, "0:/10MB.bin", FA_WRITE | FA_CREATE_ALWAYS);
|
rc = f_open(&My_File_Object_x, "0:/10MB.bin", FA_WRITE | FA_CREATE_ALWAYS);
|
||||||
if (rc) goto failed;
|
if (rc) goto failed;
|
||||||
for (bw = 0; bw < mbxs; bw++) My_Buff_x[bw] = bw & 0xff;
|
for (bw = 0; bw < mbxs; bw++) My_Buff_x[bw] = bw & 0xff;
|
||||||
|
fflush(stdout);
|
||||||
start = millis();
|
start = millis();
|
||||||
|
while (start == millis());
|
||||||
for (ii = 10485760LU / mbxs; ii > 0LU; ii--) {
|
for (ii = 10485760LU / mbxs; ii > 0LU; ii--) {
|
||||||
rc = f_write(&My_File_Object_x, My_Buff_x, mbxs, &bw);
|
rc = f_write(&My_File_Object_x, My_Buff_x, mbxs, &bw);
|
||||||
if (rc || !bw) goto failed;
|
if (rc || !bw) goto failed;
|
||||||
|
@ -591,10 +700,12 @@ out:
|
||||||
rc = f_close(&My_File_Object_x);
|
rc = f_close(&My_File_Object_x);
|
||||||
if (rc) goto failed;
|
if (rc) goto failed;
|
||||||
end = millis();
|
end = millis();
|
||||||
wt = end - start;
|
wt = (end - start) - 1;
|
||||||
printf_P(PSTR("Time to write 10485760 bytes: %lu ms (%lu sec) \r\n"), wt, (500 + wt) / 1000UL);
|
printf_P(PSTR("Time to write 10485760 bytes: %lu ms (%lu sec) \r\n"), wt, (500 + wt) / 1000UL);
|
||||||
rc = f_open(&My_File_Object_x, "0:/10MB.bin", FA_READ);
|
rc = f_open(&My_File_Object_x, "0:/10MB.bin", FA_READ);
|
||||||
|
fflush(stdout);
|
||||||
start = millis();
|
start = millis();
|
||||||
|
while (start == millis());
|
||||||
if (rc) goto failed;
|
if (rc) goto failed;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
rc = f_read(&My_File_Object_x, My_Buff_x, mbxs, &bw); /* Read a chunk of file */
|
rc = f_read(&My_File_Object_x, My_Buff_x, mbxs, &bw); /* Read a chunk of file */
|
||||||
|
@ -604,7 +715,7 @@ out:
|
||||||
if (rc) goto failed;
|
if (rc) goto failed;
|
||||||
rc = f_close(&My_File_Object_x);
|
rc = f_close(&My_File_Object_x);
|
||||||
if (rc) goto failed;
|
if (rc) goto failed;
|
||||||
rt = end - start;
|
rt = (end - start) - 1;
|
||||||
printf_P(PSTR("Time to read 10485760 bytes: %lu ms (%lu sec)\r\nDelete test file\r\n"), rt, (500 + rt) / 1000UL);
|
printf_P(PSTR("Time to read 10485760 bytes: %lu ms (%lu sec)\r\nDelete test file\r\n"), rt, (500 + rt) / 1000UL);
|
||||||
failed:
|
failed:
|
||||||
if (rc) die(rc);
|
if (rc) die(rc);
|
||||||
|
@ -613,3 +724,4 @@ failed:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
hidboot.h
12
hidboot.h
|
@ -495,10 +495,14 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() {
|
||||||
if(pRptParser[i])
|
if(pRptParser[i])
|
||||||
pRptParser[i]->Parse((HID*)this, 0, (uint8_t) read, buf);
|
pRptParser[i]->Parse((HID*)this, 0, (uint8_t) read, buf);
|
||||||
|
|
||||||
//for (uint8_t i=0; i<read; i++)
|
#if 0 // Set this to 1 to print the incoming data
|
||||||
// PrintHex<uint8_t>(buf[i]);
|
for (uint8_t i=0; i < read; i++) {
|
||||||
//if (read)
|
PrintHex<uint8_t > (buf[i], 0x80);
|
||||||
// USB_HOST_SERIAL.println("");
|
USB_HOST_SERIAL.write(' ');
|
||||||
|
}
|
||||||
|
if (read)
|
||||||
|
USB_HOST_SERIAL.println();
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if(rcode != hrNAK) {
|
if(rcode != hrNAK) {
|
||||||
USBTRACE2("Poll:", rcode);
|
USBTRACE2("Poll:", rcode);
|
||||||
|
|
27
keywords.txt
27
keywords.txt
|
@ -19,6 +19,11 @@ USBHub KEYWORD1
|
||||||
|
|
||||||
BTD KEYWORD1
|
BTD KEYWORD1
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
####################################################
|
||||||
|
Task KEYWORD2
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
# Syntax Coloring Map For PS3 Bluetooth/USB Library
|
# Syntax Coloring Map For PS3 Bluetooth/USB Library
|
||||||
####################################################
|
####################################################
|
||||||
|
@ -34,7 +39,10 @@ PS3USB KEYWORD1
|
||||||
# Methods and Functions (KEYWORD2)
|
# Methods and Functions (KEYWORD2)
|
||||||
####################################################
|
####################################################
|
||||||
setBdaddr KEYWORD2
|
setBdaddr KEYWORD2
|
||||||
|
getBdaddr KEYWORD2
|
||||||
setMoveBdaddr KEYWORD2
|
setMoveBdaddr KEYWORD2
|
||||||
|
getMoveBdaddr KEYWORD2
|
||||||
|
getMoveCalibration KEYWORD2
|
||||||
|
|
||||||
getButtonPress KEYWORD2
|
getButtonPress KEYWORD2
|
||||||
getButtonClick KEYWORD2
|
getButtonClick KEYWORD2
|
||||||
|
@ -220,8 +228,7 @@ SPP KEYWORD1
|
||||||
####################################################
|
####################################################
|
||||||
|
|
||||||
connected KEYWORD2
|
connected KEYWORD2
|
||||||
printNumber KEYWORD2
|
discard KEYWORD2
|
||||||
printNumberln KEYWORD2
|
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
# Syntax Coloring Map For Wiimote Library
|
# Syntax Coloring Map For Wiimote Library
|
||||||
|
@ -290,3 +297,19 @@ getIRs3 KEYWORD2
|
||||||
getIRx4 KEYWORD2
|
getIRx4 KEYWORD2
|
||||||
getIRy4 KEYWORD2
|
getIRy4 KEYWORD2
|
||||||
getIRs4 KEYWORD2
|
getIRs4 KEYWORD2
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
# Syntax Coloring Map For RFCOMM/SPP Library
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
# Datatypes (KEYWORD1)
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
BTHID KEYWORD1
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
####################################################
|
||||||
|
SetReportParser KEYWORD2
|
||||||
|
setProtocolMode KEYWORD2
|
16
masstorage.h
16
masstorage.h
|
@ -190,12 +190,12 @@ struct CDB6 {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) :
|
CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) :
|
||||||
Opcode(_Opcode), LUN(_LUN), LBAMSB(BGRAB2(LBA) & 0x1f), LBAHB(BGRAB1(LBA)), LBALB(BGRAB0(LBA)),
|
Opcode(_Opcode), LBAMSB(BGRAB2(LBA) & 0x1f), LUN(_LUN), LBAHB(BGRAB1(LBA)), LBALB(BGRAB0(LBA)),
|
||||||
AllocationLength(_AllocationLength), Control(_Control) {
|
AllocationLength(_AllocationLength), Control(_Control) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control) :
|
CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control) :
|
||||||
Opcode(_Opcode), LUN(_LUN), LBAMSB(0), LBAHB(0), LBALB(0),
|
Opcode(_Opcode), LBAMSB(0), LUN(_LUN), LBAHB(0), LBALB(0),
|
||||||
AllocationLength(_AllocationLength), Control(_Control) {
|
AllocationLength(_AllocationLength), Control(_Control) {
|
||||||
}
|
}
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
@ -391,23 +391,27 @@ public:
|
||||||
|
|
||||||
CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) :
|
CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) :
|
||||||
CommandBlockWrapperBase(tag, xflen, flgs),
|
CommandBlockWrapperBase(tag, xflen, flgs),
|
||||||
bmReserved1(0), bmReserved2(0), bmCBWLUN(lu), bmCBWCBLength(cmdlen) {
|
bmCBWLUN(lu), bmReserved1(0), bmCBWCBLength(cmdlen), bmReserved2(0) {
|
||||||
for(int i = 0; i < 16; i++) CBWCB[i] = 0;
|
for(int i = 0; i < 16; i++) CBWCB[i] = 0;
|
||||||
((BASICCDB_t *) CBWCB)->LUN = cmd;
|
// Type punning can cause optimization problems and bugs.
|
||||||
|
// Using reinterpret_cast to a different object is the proper way to do this.
|
||||||
|
//(((BASICCDB_t *) CBWCB)->LUN) = cmd;
|
||||||
|
BASICCDB_t *x = reinterpret_cast<BASICCDB_t *> (CBWCB);
|
||||||
|
x->LUN = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap for CDB of 6
|
// Wrap for CDB of 6
|
||||||
|
|
||||||
CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB6_t *cdb, uint8_t dir) :
|
CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB6_t *cdb, uint8_t dir) :
|
||||||
CommandBlockWrapperBase(tag, xflen, dir),
|
CommandBlockWrapperBase(tag, xflen, dir),
|
||||||
bmReserved1(0), bmReserved2(0), bmCBWLUN(cdb->LUN), bmCBWCBLength(6) {
|
bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(6), bmReserved2(0) {
|
||||||
memcpy(&CBWCB, cdb, 6);
|
memcpy(&CBWCB, cdb, 6);
|
||||||
}
|
}
|
||||||
// Wrap for CDB of 10
|
// Wrap for CDB of 10
|
||||||
|
|
||||||
CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB10_t *cdb, uint8_t dir) :
|
CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB10_t *cdb, uint8_t dir) :
|
||||||
CommandBlockWrapperBase(tag, xflen, dir),
|
CommandBlockWrapperBase(tag, xflen, dir),
|
||||||
bmReserved1(0), bmReserved2(0), bmCBWLUN(cdb->LUN), bmCBWCBLength(10) {
|
bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(10), bmReserved2(0) {
|
||||||
memcpy(&CBWCB, cdb, 10);
|
memcpy(&CBWCB, cdb, 10);
|
||||||
}
|
}
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
14
settings.h
14
settings.h
|
@ -47,6 +47,14 @@
|
||||||
#define MASS_MAX_SUPPORTED_LUN 8
|
#define MASS_MAX_SUPPORTED_LUN 8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Set to 1 to use the faster spi4teensy3 driver.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifndef USE_SPI4TEENSY3
|
||||||
|
#define USE_SPI4TEENSY3 1
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// AUTOMATIC Settings
|
// AUTOMATIC Settings
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -76,4 +84,10 @@
|
||||||
#define XMEM_RELEASE_SPI() (void(0))
|
#define XMEM_RELEASE_SPI() (void(0))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __MK20DX128__
|
||||||
|
#define USING_SPI4TEENSY3 USE_SPI4TEENSY3
|
||||||
|
#else
|
||||||
|
#define USING_SPI4TEENSY3 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* SETTINGS_H */
|
#endif /* SETTINGS_H */
|
||||||
|
|
46
usbhost.h
46
usbhost.h
|
@ -22,8 +22,26 @@ e-mail : support@circuitsathome.com
|
||||||
#else
|
#else
|
||||||
#define _USBHOST_H_
|
#define _USBHOST_H_
|
||||||
|
|
||||||
|
#if USING_SPI4TEENSY3
|
||||||
|
#include <spi4teensy3.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* SPI initialization */
|
/* SPI initialization */
|
||||||
template< typename CLK, typename MOSI, typename MISO, typename SPI_SS > class SPi {
|
template< typename CLK, typename MOSI, typename MISO, typename SPI_SS > class SPi {
|
||||||
|
#if USING_SPI4TEENSY3
|
||||||
|
public:
|
||||||
|
|
||||||
|
static void init() {
|
||||||
|
// spi4teensy3 inits everything for us, except /SS
|
||||||
|
// CLK, MOSI and MISO are hard coded for now.
|
||||||
|
// spi4teensy3::init(0,0,0); // full speed, cpol 0, cpha 0
|
||||||
|
spi4teensy3::init(); // full speed, cpol 0, cpha 0
|
||||||
|
SPI_SS::SetDirWrite();
|
||||||
|
SPI_SS::Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static void init() {
|
static void init() {
|
||||||
|
@ -39,6 +57,7 @@ public:
|
||||||
//tmp = SPSR;
|
//tmp = SPSR;
|
||||||
//tmp = SPDR;
|
//tmp = SPDR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SPI pin definitions. see avrpins.h */
|
/* SPI pin definitions. see avrpins.h */
|
||||||
|
@ -93,7 +112,7 @@ template< typename SS, typename INTR >
|
||||||
/* constructor */
|
/* constructor */
|
||||||
template< typename SS, typename INTR >
|
template< typename SS, typename INTR >
|
||||||
MAX3421e< SS, INTR >::MAX3421e() {
|
MAX3421e< SS, INTR >::MAX3421e() {
|
||||||
// Leaving ADK hardware setup in here, for now. This really belongs with the other parts.
|
// Leaving ADK hardware setup in here, for now. This really belongs with the other parts.
|
||||||
#ifdef BOARD_MEGA_ADK
|
#ifdef BOARD_MEGA_ADK
|
||||||
// For Mega ADK, which has a Max3421e on-board, set MAX_RESET to output mode, and then set it to HIGH
|
// For Mega ADK, which has a Max3421e on-board, set MAX_RESET to output mode, and then set it to HIGH
|
||||||
P55::SetDirWrite();
|
P55::SetDirWrite();
|
||||||
|
@ -106,10 +125,17 @@ template< typename SS, typename INTR >
|
||||||
void MAX3421e< SS, INTR >::regWr(uint8_t reg, uint8_t data) {
|
void MAX3421e< SS, INTR >::regWr(uint8_t reg, uint8_t data) {
|
||||||
XMEM_ACQUIRE_SPI();
|
XMEM_ACQUIRE_SPI();
|
||||||
SS::Clear();
|
SS::Clear();
|
||||||
|
#if USING_SPI4TEENSY3
|
||||||
|
uint8_t c[2];
|
||||||
|
c[0] = reg | 0x02;
|
||||||
|
c[1] = data;
|
||||||
|
spi4teensy3::send(c, 2);
|
||||||
|
#else
|
||||||
SPDR = (reg | 0x02);
|
SPDR = (reg | 0x02);
|
||||||
while(!(SPSR & (1 << SPIF)));
|
while(!(SPSR & (1 << SPIF)));
|
||||||
SPDR = data;
|
SPDR = data;
|
||||||
while(!(SPSR & (1 << SPIF)));
|
while(!(SPSR & (1 << SPIF)));
|
||||||
|
#endif
|
||||||
SS::Set();
|
SS::Set();
|
||||||
XMEM_RELEASE_SPI();
|
XMEM_RELEASE_SPI();
|
||||||
return;
|
return;
|
||||||
|
@ -121,6 +147,11 @@ template< typename SS, typename INTR >
|
||||||
uint8_t* MAX3421e< SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
uint8_t* MAX3421e< SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
||||||
XMEM_ACQUIRE_SPI();
|
XMEM_ACQUIRE_SPI();
|
||||||
SS::Clear();
|
SS::Clear();
|
||||||
|
#if USING_SPI4TEENSY3
|
||||||
|
spi4teensy3::send(reg | 0x02);
|
||||||
|
spi4teensy3::send(data_p, nbytes);
|
||||||
|
data_p += nbytes;
|
||||||
|
#else
|
||||||
SPDR = (reg | 0x02); //set WR bit and send register number
|
SPDR = (reg | 0x02); //set WR bit and send register number
|
||||||
while(nbytes--) {
|
while(nbytes--) {
|
||||||
while(!(SPSR & (1 << SPIF))); //check if previous byte was sent
|
while(!(SPSR & (1 << SPIF))); //check if previous byte was sent
|
||||||
|
@ -128,6 +159,7 @@ uint8_t* MAX3421e< SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* dat
|
||||||
data_p++; // advance data pointer
|
data_p++; // advance data pointer
|
||||||
}
|
}
|
||||||
while(!(SPSR & (1 << SPIF)));
|
while(!(SPSR & (1 << SPIF)));
|
||||||
|
#endif
|
||||||
SS::Set();
|
SS::Set();
|
||||||
XMEM_RELEASE_SPI();
|
XMEM_RELEASE_SPI();
|
||||||
return( data_p);
|
return( data_p);
|
||||||
|
@ -149,12 +181,18 @@ template< typename SS, typename INTR >
|
||||||
uint8_t MAX3421e< SS, INTR >::regRd(uint8_t reg) {
|
uint8_t MAX3421e< SS, INTR >::regRd(uint8_t reg) {
|
||||||
XMEM_ACQUIRE_SPI();
|
XMEM_ACQUIRE_SPI();
|
||||||
SS::Clear();
|
SS::Clear();
|
||||||
|
#if USING_SPI4TEENSY3
|
||||||
|
spi4teensy3::send(reg);
|
||||||
|
uint8_t rv = spi4teensy3::receive();
|
||||||
|
SS::Set();
|
||||||
|
#else
|
||||||
SPDR = reg;
|
SPDR = reg;
|
||||||
while(!(SPSR & (1 << SPIF)));
|
while(!(SPSR & (1 << SPIF)));
|
||||||
SPDR = 0; //send empty byte
|
SPDR = 0; //send empty byte
|
||||||
while(!(SPSR & (1 << SPIF)));
|
while(!(SPSR & (1 << SPIF)));
|
||||||
SS::Set();
|
SS::Set();
|
||||||
uint8_t rv = SPDR;
|
uint8_t rv = SPDR;
|
||||||
|
#endif
|
||||||
XMEM_RELEASE_SPI();
|
XMEM_RELEASE_SPI();
|
||||||
return(rv);
|
return(rv);
|
||||||
}
|
}
|
||||||
|
@ -165,6 +203,11 @@ template< typename SS, typename INTR >
|
||||||
uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
||||||
XMEM_ACQUIRE_SPI();
|
XMEM_ACQUIRE_SPI();
|
||||||
SS::Clear();
|
SS::Clear();
|
||||||
|
#if USING_SPI4TEENSY3
|
||||||
|
spi4teensy3::send(reg);
|
||||||
|
spi4teensy3::receive(data_p, nbytes);
|
||||||
|
data_p += nbytes;
|
||||||
|
#else
|
||||||
SPDR = reg;
|
SPDR = reg;
|
||||||
while(!(SPSR & (1 << SPIF))); //wait
|
while(!(SPSR & (1 << SPIF))); //wait
|
||||||
while(nbytes) {
|
while(nbytes) {
|
||||||
|
@ -182,6 +225,7 @@ uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* dat
|
||||||
#else
|
#else
|
||||||
*data_p++ = SPDR;
|
*data_p++ = SPDR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
SS::Set();
|
SS::Set();
|
||||||
XMEM_RELEASE_SPI();
|
XMEM_RELEASE_SPI();
|
||||||
|
|
Loading…
Reference in a new issue