Janitorial, whitespace fixes. No new code.

This commit is contained in:
Andrew J. Kroll 2013-12-25 05:09:57 -05:00
parent b8fb19fb90
commit f1af9b08ec
54 changed files with 1370 additions and 1310 deletions

250
BTD.cpp
View file

@ -36,12 +36,12 @@ qNextPollTime(0), // Reset NextPollTime
pollInterval(0),
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;
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
}
@ -60,7 +60,7 @@ uint8_t BTD::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
Notify(PSTR("\r\nBTD ConfigureDevice"), 0x80);
#endif
if (bAddress) { // Check if address has already been assigned to an instance
if(bAddress) { // Check if address has already been assigned to an instance
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress in use"), 0x80);
#endif
@ -68,14 +68,14 @@ uint8_t BTD::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
}
p = addrPool.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned
if (!p) {
if(!p) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
if (!p->epinfo) {
if(!p->epinfo) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nepinfo is null"), 0x80);
#endif
@ -89,12 +89,12 @@ uint8_t BTD::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
p->epinfo = oldep_ptr; // Restore p->epinfo
if (rcode)
if(rcode)
goto FailGetDevDescr;
bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class
if (!bAddress) {
if(!bAddress) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nOut of address space"), 0x80);
#endif
@ -113,7 +113,7 @@ FailGetDevDescr:
#ifdef DEBUG_USB_HOST
NotifyFailGetDevDescr(rcode);
#endif
if (rcode != hrJERR)
if(rcode != hrJERR)
rcode = USB_ERROR_FailGetDevDescr;
Release();
return rcode;
@ -130,7 +130,7 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
#endif
UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
if (!p) {
if(!p) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
@ -140,7 +140,7 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
delay(300); // Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress); // Assign new address to the device
if (rcode) {
if(rcode) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nsetAddr: "), 0x80);
D_PrintHex<uint8_t > (rcode, 0x80);
@ -156,7 +156,7 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = false;
p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
if (!p) {
if(!p) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
@ -166,18 +166,18 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed;
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
if (VID == PS3_VID && (PID == PS3_PID || PID == PS3NAVIGATION_PID || PID == PS3MOVE_PID)) {
if(VID == PS3_VID && (PID == PS3_PID || PID == PS3NAVIGATION_PID || PID == PS3MOVE_PID)) {
delay(100);
rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, 1); // We only need the Control endpoint, so we don't have to initialize the other endpoints of device
if (rcode)
if(rcode)
goto FailSetConfDescr;
#ifdef DEBUG_USB_HOST
if (PID == PS3_PID || PID == PS3NAVIGATION_PID) {
if (PID == PS3_PID)
if(PID == PS3_PID || PID == PS3NAVIGATION_PID) {
if(PID == PS3_PID)
Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
else // It must be a navigation controller
Notify(PSTR("\r\nNavigation Controller Connected"), 0x80);
@ -185,18 +185,18 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
Notify(PSTR("\r\nMotion Controller Connected"), 0x80);
#endif
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) {
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) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nPlease plug in the dongle before trying to pair with the PS3 Controller\r\nor set the Bluetooth address in the constructor of the PS3BT class"), 0x80);
#endif
} else {
if (PID == PS3_PID || PID == PS3NAVIGATION_PID)
if(PID == PS3_PID || PID == PS3NAVIGATION_PID)
setBdaddr(my_bdaddr); // Set internal Bluetooth address
else
setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
for (int8_t i = 5; i > 0; i--) {
for(int8_t i = 5; i > 0; i--) {
D_PrintHex<uint8_t > (my_bdaddr[i], 0x80);
Notify(PSTR(":"), 0x80);
}
@ -212,31 +212,31 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Check if attached device is a Bluetooth dongle and fill endpoint data structure
// First interface in the configuration must have Bluetooth assigned Class/Subclass/Protocol
// And 3 endpoints - interrupt-IN, bulk-IN, bulk-OUT, not necessarily in this order
for (uint8_t i = 0; i < num_of_conf; i++) {
if (VID == IOGEAR_GBU521_VID && PID == IOGEAR_GBU521_PID) {
for(uint8_t i = 0; i < num_of_conf; i++) {
if(VID == IOGEAR_GBU521_VID && PID == IOGEAR_GBU521_PID) {
ConfigDescParser<USB_CLASS_VENDOR_SPECIFIC, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this); // Needed for the IOGEAR GBU521
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
} else {
ConfigDescParser<USB_CLASS_WIRELESS_CTRL, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this);
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
}
if (rcode) // Check error code
if(rcode) // Check error code
goto FailGetConfDescr;
if (bNumEP >= BTD_MAX_ENDPOINTS) // All endpoints extracted
if(bNumEP >= BTD_MAX_ENDPOINTS) // All endpoints extracted
break;
}
if (bNumEP < BTD_MAX_ENDPOINTS)
if(bNumEP < BTD_MAX_ENDPOINTS)
goto FailUnknownDevice;
// Assign epInfo to epinfo pointer - this time all 3 endpoins
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
// Set Configuration Value
rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, bConfNum);
if (rcode)
if(rcode)
goto FailSetConfDescr;
hci_num_reset_loops = 100; // only loop 100 times before trying to send the hci reset command
@ -287,14 +287,14 @@ Fail:
void BTD::Initialize() {
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].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
}
for (i = 0; i < BTD_NUMSERVICES; i++) {
if (btService[i])
for(i = 0; i < BTD_NUMSERVICES; i++) {
if(btService[i])
btService[i]->Reset(); // Reset all Bluetooth services
}
@ -315,17 +315,17 @@ void BTD::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto
//ErrorMessage<uint8_t>(PSTR("Iface Num"),iface);
//ErrorMessage<uint8_t>(PSTR("Alt.Set"),alt);
if (alt) // Wrong interface - by BT spec, no alt setting
if(alt) // Wrong interface - by BT spec, no alt setting
return;
bConfNum = conf;
uint8_t index;
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80) { // Interrupt In endpoint found
if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80) { // Interrupt In endpoint found
index = BTD_EVENT_PIPE;
epInfo[index].bmNakPower = USB_NAK_NOWAIT;
} else {
if ((pep->bmAttributes & 0x02) == 2) // Bulk endpoint found
if((pep->bmAttributes & 0x02) == 2) // Bulk endpoint found
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? BTD_DATAIN_PIPE : BTD_DATAOUT_PIPE;
else
return;
@ -337,7 +337,7 @@ void BTD::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto
#ifdef EXTRADEBUG
PrintEndpointDescriptor(pep);
#endif
if (pollInterval < pep->bInterval) // Set the polling interval as the largest polling interval obtained from endpoints
if(pollInterval < pep->bInterval) // Set the polling interval as the largest polling interval obtained from endpoints
pollInterval = pep->bInterval;
bNumEP++;
}
@ -368,9 +368,9 @@ uint8_t BTD::Release() {
}
uint8_t BTD::Poll() {
if (!bPollEnable)
if(!bPollEnable)
return 0;
if (qNextPollTime <= millis()) { // Don't poll if shorter than polling interval
if(qNextPollTime <= millis()) { // Don't poll if shorter than polling interval
qNextPollTime = millis() + pollInterval; // Set new poll time
HCI_event_task(); // Poll the HCI event pipe
HCI_task(); // HCI state machine
@ -383,16 +383,16 @@ void BTD::HCI_event_task() {
uint16_t length = BULK_MAXPKTSIZE; // Request more than 16 bytes anyway, the inTransfer routine will take care of this
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_EVENT_PIPE ].epAddr, &length, hcibuf); // Input on endpoint 1
if (!rcode || rcode == hrNAK) { // Check for errors
switch (hcibuf[0]) { // Switch on event type
if(!rcode || rcode == hrNAK) { // Check for errors
switch(hcibuf[0]) { // Switch on event type
case EV_COMMAND_COMPLETE:
if (!hcibuf[5]) { // Check if command succeeded
if(!hcibuf[5]) { // Check if command succeeded
hci_set_flag(HCI_FLAG_CMD_COMPLETE); // Set command complete flag
if ((hcibuf[3] == 0x01) && (hcibuf[4] == 0x10)) { // Parameters from read local version information
if((hcibuf[3] == 0x01) && (hcibuf[4] == 0x10)) { // Parameters from read local version information
hci_version = hcibuf[6]; // Used to check if it supports 2.0+EDR - see http://www.bluetooth.org/Technical/AssignedNumbers/hci.htm
hci_set_flag(HCI_FLAG_READ_VERSION);
} else if ((hcibuf[3] == 0x09) && (hcibuf[4] == 0x10)) { // Parameters from read local bluetooth address
for (uint8_t i = 0; i < 6; i++)
} else if((hcibuf[3] == 0x09) && (hcibuf[4] == 0x10)) { // Parameters from read local bluetooth address
for(uint8_t i = 0; i < 6; i++)
my_bdaddr[i] = hcibuf[6 + i];
hci_set_flag(HCI_FLAG_READ_BDADDR);
}
@ -400,7 +400,7 @@ void BTD::HCI_event_task() {
break;
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
Notify(PSTR("\r\nHCI Command Failed: "), 0x80);
D_PrintHex<uint8_t > (hcibuf[2], 0x80);
@ -409,10 +409,10 @@ void BTD::HCI_event_task() {
break;
case EV_INQUIRY_COMPLETE:
if (inquiry_counter >= 5 && (pairWithWii || pairWithHIDDevice)) {
if(inquiry_counter >= 5 && (pairWithWii || pairWithHIDDevice)) {
inquiry_counter = 0;
#ifdef DEBUG_USB_HOST
if (pairWithWii)
if(pairWithWii)
Notify(PSTR("\r\nCouldn't find Wiimote"), 0x80);
else
Notify(PSTR("\r\nCouldn't find HID device"), 0x80);
@ -427,38 +427,38 @@ void BTD::HCI_event_task() {
break;
case EV_INQUIRY_RESULT:
if (hcibuf[2]) { // Check that there is more than zero responses
if(hcibuf[2]) { // Check that there is more than zero responses
#ifdef EXTRADEBUG
Notify(PSTR("\r\nNumber of responses: "), 0x80);
Notify(hcibuf[2], 0x80);
#endif
for (uint8_t i = 0; i < hcibuf[2]; i++) {
for(uint8_t i = 0; i < hcibuf[2]; i++) {
uint8_t offset = 8 * hcibuf[2] + 3 * i;
uint8_t classOfDevice[3];
for (uint8_t j = 0; j < 3; j++)
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://wiibrew.org/wiki/Wiimote#SDP_information
if (classOfDevice[0] & 0x08) // Check if it's the new Wiimote with motion plus inside that was detected
if(pairWithWii && classOfDevice[2] == 0x00 && (classOfDevice[1] & 0x05) && (classOfDevice[0] & 0x0C)) { // See 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;
else
motionPlusInside = false;
for (uint8_t j = 0; j < 6; j++)
for(uint8_t j = 0; j < 6; j++)
disc_bdaddr[j] = hcibuf[j + 3 + 6 * i];
hci_set_flag(HCI_FLAG_DEVICE_FOUND);
break;
} else if (pairWithHIDDevice && (classOfDevice[1] & 0x05) && (classOfDevice[0] & 0xC0)) { // Check if it is a mouse or keyboard - see: http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html
} else if(pairWithHIDDevice && (classOfDevice[1] & 0x05) && (classOfDevice[0] & 0xC0)) { // Check if it is a mouse or keyboard - see: http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html
#ifdef DEBUG_USB_HOST
if (classOfDevice[0] & 0x80)
if(classOfDevice[0] & 0x80)
Notify(PSTR("\r\nMouse found"), 0x80);
if (classOfDevice[0] & 0x40)
if(classOfDevice[0] & 0x40)
Notify(PSTR("\r\nKeyboard found"), 0x80);
#endif
for (uint8_t j = 0; j < 6; j++)
for(uint8_t j = 0; j < 6; j++)
disc_bdaddr[j] = hcibuf[j + 3 + 6 * i];
hci_set_flag(HCI_FLAG_DEVICE_FOUND);
@ -479,7 +479,7 @@ void BTD::HCI_event_task() {
case EV_CONNECT_COMPLETE:
hci_set_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
@ -495,17 +495,17 @@ void BTD::HCI_event_task() {
break;
case EV_DISCONNECT_COMPLETE:
if (!hcibuf[2]) { // Check if disconnected OK
if(!hcibuf[2]) { // Check if disconnected OK
hci_set_flag(HCI_FLAG_DISCONNECT_COMPLETE); // Set disconnect command complete flag
hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE); // Clear connection complete flag
}
break;
case EV_REMOTE_NAME_COMPLETE:
if (!hcibuf[2]) { // Check if reading is OK
for (uint8_t i = 0; i < min(sizeof (remote_name), sizeof (hcibuf) - 9); i++) {
if(!hcibuf[2]) { // Check if reading is OK
for(uint8_t i = 0; i < min(sizeof (remote_name), sizeof (hcibuf) - 9); i++) {
remote_name[i] = hcibuf[9 + i];
if (remote_name[i] == '\0') // End of string
if(remote_name[i] == '\0') // End of string
break;
}
hci_set_flag(HCI_FLAG_REMOTE_NAME_COMPLETE);
@ -513,14 +513,14 @@ void BTD::HCI_event_task() {
break;
case EV_INCOMING_CONNECT:
for (uint8_t i = 0; i < 6; i++)
for(uint8_t i = 0; i < 6; i++)
disc_bdaddr[i] = hcibuf[i + 2];
if ((hcibuf[9] & 0x05) && (hcibuf[8] & 0xC0)) { // Check if it is a mouse or keyboard
if((hcibuf[9] & 0x05) && (hcibuf[8] & 0xC0)) { // Check if it is a mouse or keyboard
#ifdef DEBUG_USB_HOST
if (hcibuf[8] & 0x80)
if(hcibuf[8] & 0x80)
Notify(PSTR("\r\nMouse is connecting"), 0x80);
if (hcibuf[8] & 0x40)
if(hcibuf[8] & 0x40)
Notify(PSTR("\r\nKeyboard is connecting"), 0x80);
#endif
incomingHIDDevice = true;
@ -538,12 +538,12 @@ void BTD::HCI_event_task() {
break;
case EV_PIN_CODE_REQUEST:
if (pairWithWii) {
if(pairWithWii) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nPairing with wiimote"), 0x80);
#endif
hci_pin_code_request_reply();
} else if (btdPin != NULL) {
} else if(btdPin != NULL) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nBluetooth pin is set too: "), 0x80);
NotifyStr(btdPin, 0x80);
@ -565,12 +565,12 @@ void BTD::HCI_event_task() {
break;
case EV_AUTHENTICATION_COMPLETE:
if (pairWithWii && !connectToWii) {
if(pairWithWii && !connectToWii) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nPairing successful with Wiimote"), 0x80);
#endif
connectToWii = true; // Used to indicate to the Wii service, that it should connect to this device
} else if (pairWithHIDDevice && !connectToHIDDevice) {
} else if(pairWithHIDDevice && !connectToHIDDevice) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nPairing successful with HID device"), 0x80);
#endif
@ -592,7 +592,7 @@ void BTD::HCI_event_task() {
break;
#ifdef EXTRADEBUG
default:
if (hcibuf[0] != 0x00) {
if(hcibuf[0] != 0x00) {
Notify(PSTR("\r\nUnmanaged HCI Event: "), 0x80);
D_PrintHex<uint8_t > (hcibuf[0], 0x80);
}
@ -610,10 +610,10 @@ void BTD::HCI_event_task() {
/* Poll Bluetooth and print result */
void BTD::HCI_task() {
switch (hci_state) {
switch(hci_state) {
case HCI_INIT_STATE:
hci_counter++;
if (hci_counter > hci_num_reset_loops) { // wait until we have looped x times to clear any old events
if(hci_counter > hci_num_reset_loops) { // wait until we have looped x times to clear any old events
hci_reset();
hci_state = HCI_RESET_STATE;
hci_counter = 0;
@ -622,16 +622,16 @@ void BTD::HCI_task() {
case HCI_RESET_STATE:
hci_counter++;
if (hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
hci_counter = 0;
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHCI Reset complete"), 0x80);
#endif
hci_state = HCI_CLASS_STATE;
hci_write_class_of_device();
} else if (hci_counter > hci_num_reset_loops) {
} else if(hci_counter > hci_num_reset_loops) {
hci_num_reset_loops *= 10;
if (hci_num_reset_loops > 2000)
if(hci_num_reset_loops > 2000)
hci_num_reset_loops = 2000;
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nNo response to HCI Reset"), 0x80);
@ -642,7 +642,7 @@ void BTD::HCI_task() {
break;
case HCI_CLASS_STATE:
if (hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nWrite class of device"), 0x80);
#endif
@ -652,10 +652,10 @@ void BTD::HCI_task() {
break;
case HCI_BDADDR_STATE:
if (hci_check_flag(HCI_FLAG_READ_BDADDR)) {
if(hci_check_flag(HCI_FLAG_READ_BDADDR)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nLocal Bluetooth Address: "), 0x80);
for (int8_t i = 5; i > 0; i--) {
for(int8_t i = 5; i > 0; i--) {
D_PrintHex<uint8_t > (my_bdaddr[i], 0x80);
Notify(PSTR(":"), 0x80);
}
@ -667,8 +667,8 @@ void BTD::HCI_task() {
break;
case HCI_LOCAL_VERSION_STATE: // The local version is used by the PS3BT class
if (hci_check_flag(HCI_FLAG_READ_VERSION)) {
if (btdName != NULL) {
if(hci_check_flag(HCI_FLAG_READ_VERSION)) {
if(btdName != NULL) {
hci_set_local_name(btdName);
hci_state = HCI_SET_NAME_STATE;
} else
@ -677,7 +677,7 @@ void BTD::HCI_task() {
break;
case HCI_SET_NAME_STATE:
if (hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nThe name is set to: "), 0x80);
NotifyStr(btdName, 0x80);
@ -687,9 +687,9 @@ void BTD::HCI_task() {
break;
case HCI_CHECK_DEVICE_SERVICE:
if (pairWithHIDDevice || 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
if (pairWithWii)
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);
else
Notify(PSTR("\r\nPlease enable discovery of your device"), 0x80);
@ -701,27 +701,27 @@ void BTD::HCI_task() {
break;
case HCI_INQUIRY_STATE:
if (hci_check_flag(HCI_FLAG_DEVICE_FOUND)) {
if(hci_check_flag(HCI_FLAG_DEVICE_FOUND)) {
hci_inquiry_cancel(); // Stop inquiry
#ifdef DEBUG_USB_HOST
if (pairWithWii)
if(pairWithWii)
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);
if (pairWithWii)
if(pairWithWii)
Notify(PSTR("\r\nWII Wii(&Btd);"), 0x80);
else
Notify(PSTR("\r\nBTHID hid(&Btd);"), 0x80);
Notify(PSTR("\r\nAnd then press any button on the "), 0x80);
if (pairWithWii)
if(pairWithWii)
Notify(PSTR("Wiimote"), 0x80);
else
Notify(PSTR("device"), 0x80);
#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_state = HCI_REMOTE_NAME_STATE;
} else
@ -730,9 +730,9 @@ void BTD::HCI_task() {
break;
case HCI_CONNECT_DEVICE_STATE:
if (hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
#ifdef DEBUG_USB_HOST
if (pairWithWii)
if(pairWithWii)
Notify(PSTR("\r\nConnecting to Wiimote"), 0x80);
else
Notify(PSTR("\r\nConnecting to HID device"), 0x80);
@ -743,10 +743,10 @@ void BTD::HCI_task() {
break;
case HCI_CONNECTED_DEVICE_STATE:
if (hci_check_flag(HCI_FLAG_CONNECT_EVENT)) {
if (hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) {
if(hci_check_flag(HCI_FLAG_CONNECT_EVENT)) {
if(hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) {
#ifdef DEBUG_USB_HOST
if (pairWithWii)
if(pairWithWii)
Notify(PSTR("\r\nConnected to Wiimote"), 0x80);
else
Notify(PSTR("\r\nConnected to HID device"), 0x80);
@ -763,7 +763,7 @@ void BTD::HCI_task() {
break;
case HCI_SCANNING_STATE:
if (!connectToWii && !pairWithWii && !connectToHIDDevice && !pairWithHIDDevice) {
if(!connectToWii && !pairWithWii && !connectToHIDDevice && !pairWithHIDDevice) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nWait For Incoming Connection Request"), 0x80);
#endif
@ -774,38 +774,38 @@ void BTD::HCI_task() {
break;
case HCI_CONNECT_IN_STATE:
if (hci_check_flag(HCI_FLAG_INCOMING_REQUEST)) {
if(hci_check_flag(HCI_FLAG_INCOMING_REQUEST)) {
watingForConnection = false;
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nIncoming Connection Request"), 0x80);
#endif
hci_remote_name();
hci_state = HCI_REMOTE_NAME_STATE;
} else if (hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE))
} else if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE))
hci_state = HCI_DISCONNECT_STATE;
break;
case HCI_REMOTE_NAME_STATE:
if (hci_check_flag(HCI_FLAG_REMOTE_NAME_COMPLETE)) {
if(hci_check_flag(HCI_FLAG_REMOTE_NAME_COMPLETE)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nRemote Name: "), 0x80);
for (uint8_t i = 0; i < 30; i++) {
if (remote_name[i] == '\0') // End of string
for(uint8_t i = 0; i < 30; i++) {
if(remote_name[i] == '\0') // End of string
break;
Notifyc(remote_name[i], 0x80);
}
#endif
if (strncmp((const char*)remote_name, "Nintendo", 8) == 0) {
if(strncmp((const char*)remote_name, "Nintendo", 8) == 0) {
incomingWii = true;
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nWiimote is connecting"), 0x80);
#endif
if (strncmp((const char*)remote_name, "Nintendo RVL-CNT-01-TR", 22) == 0) {
if(strncmp((const char*)remote_name, "Nintendo RVL-CNT-01-TR", 22) == 0) {
#ifdef DEBUG_USB_HOST
Notify(PSTR(" with Motion Plus Inside"), 0x80);
#endif
motionPlusInside = true;
} else if (strncmp((const char*)remote_name, "Nintendo RVL-CNT-01-UC", 22) == 0) {
} else if(strncmp((const char*)remote_name, "Nintendo RVL-CNT-01-UC", 22) == 0) {
#ifdef DEBUG_USB_HOST
Notify(PSTR(" - Wii U Pro Controller"), 0x80);
#endif
@ -816,7 +816,7 @@ void BTD::HCI_task() {
wiiUProController = false;
}
}
if (pairWithWii && motionPlusInside)
if(pairWithWii && motionPlusInside)
hci_state = HCI_CONNECT_DEVICE_STATE;
else {
hci_accept_connection();
@ -826,10 +826,10 @@ void BTD::HCI_task() {
break;
case HCI_CONNECTED_STATE:
if (hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) {
if(hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nConnected to Device: "), 0x80);
for (int8_t i = 5; i > 0; i--) {
for(int8_t i = 5; i > 0; i--) {
D_PrintHex<uint8_t > (disc_bdaddr[i], 0x80);
Notify(PSTR(":"), 0x80);
}
@ -847,14 +847,14 @@ void BTD::HCI_task() {
case HCI_DONE_STATE:
hci_counter++;
if (hci_counter > 1000) { // Wait until we have looped 1000 times to make sure that the L2CAP connection has been started
if(hci_counter > 1000) { // Wait until we have looped 1000 times to make sure that the L2CAP connection has been started
hci_counter = 0;
hci_state = HCI_SCANNING_STATE;
}
break;
case HCI_DISCONNECT_STATE:
if (hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE)) {
if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHCI Disconnected from Device"), 0x80);
#endif
@ -879,22 +879,22 @@ void BTD::ACL_event_task() {
uint16_t length = BULK_MAXPKTSIZE;
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_DATAIN_PIPE ].epAddr, &length, l2capinbuf); // Input on endpoint 2
if (!rcode) { // Check for errors
if (length > 0) { // Check if any data was read
for (uint8_t i = 0; i < BTD_NUMSERVICES; i++) {
if (btService[i])
if(!rcode) { // Check for errors
if(length > 0) { // Check if any data was read
for(uint8_t i = 0; i < BTD_NUMSERVICES; i++) {
if(btService[i])
btService[i]->ACLData(l2capinbuf);
}
}
}
#ifdef EXTRADEBUG
else if (rcode != hrNAK) {
else if(rcode != hrNAK) {
Notify(PSTR("\r\nACL data in error: "), 0x80);
D_PrintHex<uint8_t > (rcode, 0x80);
}
#endif
for (uint8_t i = 0; i < BTD_NUMSERVICES; i++)
if (btService[i])
for(uint8_t i = 0; i < BTD_NUMSERVICES; i++)
if(btService[i])
btService[i]->Run();
}
@ -921,7 +921,7 @@ void BTD::hci_write_scan_enable() {
hcibuf[0] = 0x1A; // HCI OCF = 1A
hcibuf[1] = 0x03 << 2; // HCI OGF = 3
hcibuf[2] = 0x01; // parameter length = 1
if (btdName != NULL)
if(btdName != NULL)
hcibuf[3] = 0x03; // Inquiry Scan enabled. Page Scan enabled.
else
hcibuf[3] = 0x02; // Inquiry Scan disabled. Page Scan enabled.
@ -996,7 +996,7 @@ void BTD::hci_set_local_name(const char* name) {
hcibuf[1] = 0x03 << 2; // HCI OGF = 3
hcibuf[2] = strlen(name) + 1; // parameter length = the length of the string + end byte
uint8_t i;
for (i = 0; i < strlen(name); i++)
for(i = 0; i < strlen(name); i++)
hcibuf[i + 3] = name[i];
hcibuf[i + 3] = 0x00; // End of string
@ -1061,26 +1061,26 @@ void BTD::hci_pin_code_request_reply() {
hcibuf[6] = disc_bdaddr[3];
hcibuf[7] = disc_bdaddr[4];
hcibuf[8] = disc_bdaddr[5];
if (pairWithWii) {
if(pairWithWii) {
hcibuf[9] = 6; // Pin length is the length of the Bluetooth address
if (wiiUProController) {
if(wiiUProController) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nParing with Wii U Pro Controller"), 0x80);
#endif
for (uint8_t i = 0; i < 6; i++)
for(uint8_t i = 0; i < 6; i++)
hcibuf[10 + i] = my_bdaddr[i]; // The pin is the Bluetooth dongles Bluetooth address backwards
} else {
for (uint8_t i = 0; i < 6; i++)
for(uint8_t i = 0; i < 6; i++)
hcibuf[10 + i] = disc_bdaddr[i]; // The pin is the Wiimote's Bluetooth address backwards
}
for (uint8_t i = 16; i < 26; i++)
for(uint8_t i = 16; i < 26; i++)
hcibuf[i] = 0x00; // The rest should be 0
} else {
hcibuf[9] = strlen(btdPin); // Length of pin
uint8_t i;
for (i = 0; i < strlen(btdPin); i++) // The maximum size of the pin is 16
for(i = 0; i < strlen(btdPin); i++) // The maximum size of the pin is 16
hcibuf[i + 10] = btdPin[i];
for (; i < 16; i++)
for(; i < 16; i++)
hcibuf[i + 10] = 0x00; // The rest should be 0
}
@ -1184,11 +1184,11 @@ void BTD::L2CAP_Command(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t
buf[6] = channelLow;
buf[7] = channelHigh;
for (uint16_t i = 0; i < nbytes; i++) // L2CAP C-frame
for(uint16_t i = 0; i < nbytes; i++) // L2CAP C-frame
buf[8 + i] = data[i];
uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf);
if (rcode) {
if(rcode) {
delay(100); // This small delay prevents it from overflowing if it fails
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nError sending L2CAP message: 0x"), 0x80);
@ -1317,7 +1317,7 @@ void BTD::setBdaddr(uint8_t* bdaddr) {
buf[0] = 0x01;
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, 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
@ -1333,7 +1333,7 @@ void BTD::setMoveBdaddr(uint8_t* bdaddr) {
buf[9] = 0x02;
buf[10] = 0x12;
for (uint8_t i = 0; i < 6; i++)
for(uint8_t i = 0; i < 6; 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

11
BTD.h
View file

@ -262,12 +262,15 @@ public:
virtual bool isReady() {
return bPollEnable;
};
/**
* Used by the USB core to check what this driver support.
* @param klass The device's USB class.
* @return Returns true if the device's USB class matches this driver.
*/
virtual boolean DEVCLASSOK(uint8_t klass) { return (klass == USB_CLASS_WIRELESS_CTRL); }
virtual boolean DEVCLASSOK(uint8_t klass) {
return (klass == USB_CLASS_WIRELESS_CTRL);
}
/**
* Used by the USB core to check what this driver support.
@ -277,10 +280,10 @@ public:
* @return Returns true if the device's VID and PID matches this driver.
*/
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) {
if (vid == IOGEAR_GBU521_VID && 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))
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;

114
BTHID.cpp
View file

@ -22,16 +22,15 @@
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 < NUM_PARSERS; i++)
protocolMode(HID_BOOT_PROTOCOL) {
for(uint8_t i = 0; i < NUM_PARSERS; i++)
pRptParser[i] = NULL;
if (pBtd)
if(pBtd)
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
pBtd->pairWithHIDDevice = pair;
pBtd->btdPin= pin;
pBtd->btdPin = pin;
/* Set device cid for the control and intterrupt channelse - LSB */
control_dcid[0] = 0x70; // 0x0070
@ -57,9 +56,9 @@ void BTHID::disconnect() { // Use this void to disconnect any of the controllers
}
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) {
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;
@ -68,9 +67,9 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
}
}
}
if ((l2capinbuf[0] | (uint16_t)l2capinbuf[1] << 8) == (hci_handle | 0x2000U)) { // acl_handle_ok or it's a new connection
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // l2cap_control - Channel ID for ACL-U
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
if((l2capinbuf[0] | (uint16_t)l2capinbuf[1] << 8) == (hci_handle | 0x2000U)) { // acl_handle_ok or it's a new connection
if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // l2cap_control - Channel ID for ACL-U
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
@ -85,15 +84,15 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
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]) {
} 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_set_flag(L2CAP_FLAG_CONTROL_CONNECTED);
} else if (l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) {
} 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];
@ -101,7 +100,7 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
l2cap_set_flag(L2CAP_FLAG_INTERRUPT_CONNECTED);
}
}
} else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
} 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);
@ -114,46 +113,46 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
Notify(PSTR(" Identifier: "), 0x80);
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
#endif
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
identifier = l2capinbuf[9];
control_scid[0] = l2capinbuf[14];
control_scid[1] = l2capinbuf[15];
l2cap_set_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST);
} else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) {
} else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) {
identifier = l2capinbuf[9];
interrupt_scid[0] = l2capinbuf[14];
interrupt_scid[1] = l2capinbuf[15];
l2cap_set_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]) {
} 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_set_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS);
} else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
} else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
//Notify(PSTR("\r\nHID Interrupt Configuration Complete"), 0x80);
identifier = l2capinbuf[9];
l2cap_set_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]) {
} 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]) {
} 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]) {
} 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]) {
} 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
@ -161,12 +160,12 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
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]) {
} 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_set_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE);
} else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
} else if(l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
//Notify(PSTR("\r\nDisconnect Response: Interrupt Channel"), 0x80);
identifier = l2capinbuf[9];
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE);
@ -179,27 +178,27 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
}
#endif
} else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt
} 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++) {
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]) {
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
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
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;
#ifdef DEBUG_USB_HOST
@ -210,10 +209,10 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
#endif
}
}
} else if (l2capinbuf[6] == control_dcid[0] && l2capinbuf[7] == control_dcid[1]) { // l2cap_control
} 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++) {
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);
}
@ -228,7 +227,7 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
Notify(PSTR("\r\nData: "), 0x80);
Notify(PSTR("\r\n"), 0x80);
for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) {
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);
}
@ -239,10 +238,10 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
}
void BTHID::L2CAP_task() {
switch (l2cap_state) {
switch(l2cap_state) {
/* These states are used if the HID device is the host */
case L2CAP_CONTROL_SUCCESS:
if (l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
if(l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
#endif
@ -252,7 +251,7 @@ void BTHID::L2CAP_task() {
break;
case L2CAP_INTERRUPT_SETUP:
if (l2cap_check_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST)) {
if(l2cap_check_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
#endif
@ -269,7 +268,7 @@ void BTHID::L2CAP_task() {
/* These states are used if the Arduino is the host */
case L2CAP_CONTROL_CONNECT_REQUEST:
if (l2cap_check_flag(L2CAP_FLAG_CONTROL_CONNECTED)) {
if(l2cap_check_flag(L2CAP_FLAG_CONTROL_CONNECTED)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nSend HID Control Config Request"), 0x80);
#endif
@ -280,7 +279,7 @@ void BTHID::L2CAP_task() {
break;
case L2CAP_CONTROL_CONFIG_REQUEST:
if (l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
if(l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
setProtocol(); // Set protocol before establishing HID interrupt channel
delay(1); // Short delay between commands - just to be sure
#ifdef DEBUG_USB_HOST
@ -293,7 +292,7 @@ void BTHID::L2CAP_task() {
break;
case L2CAP_INTERRUPT_CONNECT_REQUEST:
if (l2cap_check_flag(L2CAP_FLAG_INTERRUPT_CONNECTED)) {
if(l2cap_check_flag(L2CAP_FLAG_INTERRUPT_CONNECTED)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nSend HID Interrupt Config Request"), 0x80);
#endif
@ -304,7 +303,7 @@ void BTHID::L2CAP_task() {
break;
case L2CAP_INTERRUPT_CONFIG_REQUEST:
if (l2cap_check_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)) { // Now the HID channels is established
if(l2cap_check_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)) { // Now the HID channels is established
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHID Channels Established"), 0x80);
#endif
@ -320,7 +319,7 @@ void BTHID::L2CAP_task() {
break;
case L2CAP_INTERRUPT_DISCONNECT:
if (l2cap_check_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE)) {
if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80);
#endif
@ -331,7 +330,7 @@ void BTHID::L2CAP_task() {
break;
case L2CAP_CONTROL_DISCONNECT:
if (l2cap_check_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)) {
if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nDisconnected Control Channel"), 0x80);
#endif
@ -345,9 +344,9 @@ void BTHID::L2CAP_task() {
}
void BTHID::Run() {
switch (l2cap_state) {
switch(l2cap_state) {
case L2CAP_WAIT:
if (pBtd->connectToHIDDevice && !pBtd->l2capConnectionClaimed && !connected && !activeConnection) {
if(pBtd->connectToHIDDevice && !pBtd->l2capConnectionClaimed && !connected && !activeConnection) {
pBtd->l2capConnectionClaimed = true;
activeConnection = true;
#ifdef DEBUG_USB_HOST
@ -358,7 +357,7 @@ void BTHID::Run() {
identifier = 0;
pBtd->l2cap_connection_request(hci_handle, identifier, control_dcid, HID_CTRL_PSM);
l2cap_state = L2CAP_CONTROL_CONNECT_REQUEST;
} else if (l2cap_check_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST)) {
} else if(l2cap_check_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80);
#endif
@ -376,6 +375,7 @@ void BTHID::Run() {
/************************************************************/
/* HID Commands */
/************************************************************/
void BTHID::setProtocol() {
#ifdef DEBUG_USB_HOST
@ -392,4 +392,4 @@ void BTHID::setLeds(uint8_t data) {
buf[1] = 0x01; // Report ID
buf[2] = data;
pBtd->L2CAP_Command(hci_handle, buf, 3, interrupt_scid[0], interrupt_scid[1]);
}
}

View file

@ -48,6 +48,7 @@ public:
virtual void Reset();
/** Used this to disconnect any of the controllers. */
virtual void disconnect();
/**@}*/
HIDReportParser *GetReportParser(uint8_t id) {
@ -71,7 +72,7 @@ public:
/** Call this to start the paring sequence with a controller */
void pair(void) {
if (pBtd)
if(pBtd)
pBtd->pairWithHID();
};
@ -98,7 +99,7 @@ private:
* This is useful for instance if you want to set the LEDs in a specific way.
*/
void onInit() {
if (pFuncOnInit)
if(pFuncOnInit)
pFuncOnInit(); // Call the user function
}
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
@ -120,4 +121,4 @@ private:
uint8_t interrupt_dcid[2]; // 0x0071
uint8_t identifier; // Identifier for connection
};
#endif
#endif

198
PS3BT.cpp
View file

@ -23,7 +23,7 @@
PS3BT::PS3BT(BTD *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0) :
pBtd(p) // pointer to USB class instance - mandatory
{
if (pBtd)
if(pBtd)
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
pBtd->my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
@ -69,15 +69,15 @@ uint8_t PS3BT::getAnalogHat(AnalogHat a) {
}
int16_t PS3BT::getSensor(Sensor a) {
if (PS3Connected) {
if (a == aX || a == aY || a == aZ || a == gZ)
if(PS3Connected) {
if(a == aX || a == aY || a == aZ || a == gZ)
return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]);
else
return 0;
} else if (PS3MoveConnected) {
if (a == mXmove || a == mYmove) // These are all 12-bits long
} else if(PS3MoveConnected) {
if(a == mXmove || a == mYmove) // These are all 12-bits long
return (((l2capinbuf[(uint16_t)a] & 0x0F) << 8) | (l2capinbuf[(uint16_t)a + 1]));
else if (a == mZmove || a == tempMove) // The tempearature is also 12 bits long
else if(a == mZmove || a == tempMove) // The tempearature is also 12 bits long
return ((l2capinbuf[(uint16_t)a] << 4) | ((l2capinbuf[(uint16_t)a + 1] & 0xF0) >> 4));
else // aXmove, aYmove, aZmove, gXmove, gYmove and gZmove
return (l2capinbuf[(uint16_t)a] | (l2capinbuf[(uint16_t)a + 1] << 8));
@ -88,13 +88,13 @@ int16_t PS3BT::getSensor(Sensor a) {
double PS3BT::getAngle(Angle a) {
double accXval, accYval, accZval;
if (PS3Connected) {
if(PS3Connected) {
// Data for the Kionix KXPC4 used in the DualShock 3
const double zeroG = 511.5; // 1.65/3.3*1023 (1.65V)
accXval = -((double)getSensor(aX) - zeroG);
accYval = -((double)getSensor(aY) - zeroG);
accZval = -((double)getSensor(aZ) - zeroG);
} else if (PS3MoveConnected) {
} else if(PS3MoveConnected) {
// It's a Kionix KXSC4 inside the Motion controller
const uint16_t zeroG = 0x8000;
accXval = -(int16_t)(getSensor(aXmove) - zeroG);
@ -106,34 +106,34 @@ double PS3BT::getAngle(Angle a) {
// Convert to 360 degrees resolution
// atan2 outputs the value of -π to π (radians)
// We are then converting it to 0 to 2π and then to degrees
if (a == Pitch)
if(a == Pitch)
return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
else
return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
}
double PS3BT::get9DOFValues(Sensor a) { // Thanks to Manfred Piendl
if (!PS3MoveConnected)
if(!PS3MoveConnected)
return 0;
int16_t value = getSensor(a);
if (a == mXmove || a == mYmove || a == mZmove) {
if (value > 2047)
if(a == mXmove || a == mYmove || a == mZmove) {
if(value > 2047)
value -= 0x1000;
return (double)value / 3.2; // unit: muT = 10^(-6) Tesla
} else if (a == aXmove || a == aYmove || a == aZmove) {
if (value < 0)
} else if(a == aXmove || a == aYmove || a == aZmove) {
if(value < 0)
value += 0x8000;
else
value -= 0x8000;
return (double)value / 442.0; // unit: m/(s^2)
} else if (a == gXmove || a == gYmove || a == gZmove) {
if (value < 0)
} else if(a == gXmove || a == gYmove || a == gZmove) {
if(value < 0)
value += 0x8000;
else
value -= 0x8000;
if (a == gXmove)
if(a == gXmove)
return (double)value / 11.6; // unit: deg/s
else if (a == gYmove)
else if(a == gYmove)
return (double)value / 11.2; // unit: deg/s
else // gZmove
return (double)value / 9.6; // unit: deg/s
@ -142,12 +142,12 @@ double PS3BT::get9DOFValues(Sensor a) { // Thanks to Manfred Piendl
}
String PS3BT::getTemperature() {
if (PS3MoveConnected) {
if(PS3MoveConnected) {
int16_t input = getSensor(tempMove);
String output = String(input / 100);
output += ".";
if (input % 100 < 10)
if(input % 100 < 10)
output += "0";
output += String(input % 100);
@ -161,48 +161,48 @@ bool PS3BT::getStatus(Status c) {
}
String PS3BT::getStatusString() {
if (PS3Connected || PS3NavigationConnected) {
if(PS3Connected || PS3NavigationConnected) {
char statusOutput[100]; // Max string length plus null character
strcpy_P(statusOutput, PSTR("ConnectionStatus: "));
if (getStatus(Plugged)) strcat_P(statusOutput, PSTR("Plugged"));
else if (getStatus(Unplugged)) strcat_P(statusOutput, PSTR("Unplugged"));
if(getStatus(Plugged)) strcat_P(statusOutput, PSTR("Plugged"));
else if(getStatus(Unplugged)) strcat_P(statusOutput, PSTR("Unplugged"));
else strcat_P(statusOutput, PSTR("Error"));
strcat_P(statusOutput, PSTR(" - PowerRating: "));
if (getStatus(Charging)) strcat_P(statusOutput, PSTR("Charging"));
else if (getStatus(NotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
else if (getStatus(Shutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
else if (getStatus(Dying)) strcat_P(statusOutput, PSTR("Dying"));
else if (getStatus(Low)) strcat_P(statusOutput, PSTR("Low"));
else if (getStatus(High)) strcat_P(statusOutput, PSTR("High"));
else if (getStatus(Full)) strcat_P(statusOutput, PSTR("Full"));
if(getStatus(Charging)) strcat_P(statusOutput, PSTR("Charging"));
else if(getStatus(NotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
else if(getStatus(Shutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
else if(getStatus(Dying)) strcat_P(statusOutput, PSTR("Dying"));
else if(getStatus(Low)) strcat_P(statusOutput, PSTR("Low"));
else if(getStatus(High)) strcat_P(statusOutput, PSTR("High"));
else if(getStatus(Full)) strcat_P(statusOutput, PSTR("Full"));
else strcat_P(statusOutput, PSTR("Error"));
strcat_P(statusOutput, PSTR(" - WirelessStatus: "));
if (getStatus(CableRumble)) strcat_P(statusOutput, PSTR("Cable - Rumble is on"));
else if (getStatus(Cable)) strcat_P(statusOutput, PSTR("Cable - Rumble is off"));
else if (getStatus(BluetoothRumble)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is on"));
else if (getStatus(Bluetooth)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is off"));
if(getStatus(CableRumble)) strcat_P(statusOutput, PSTR("Cable - Rumble is on"));
else if(getStatus(Cable)) strcat_P(statusOutput, PSTR("Cable - Rumble is off"));
else if(getStatus(BluetoothRumble)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is on"));
else if(getStatus(Bluetooth)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is off"));
else strcat_P(statusOutput, PSTR("Error"));
return statusOutput;
} else if (PS3MoveConnected) {
} else if(PS3MoveConnected) {
char statusOutput[26]; // Max string length plus null character
strcpy_P(statusOutput, PSTR("PowerRating: "));
if (getStatus(MoveCharging)) strcat_P(statusOutput, PSTR("Charging"));
else if (getStatus(MoveNotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
else if (getStatus(MoveShutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
else if (getStatus(MoveDying)) strcat_P(statusOutput, PSTR("Dying"));
else if (getStatus(MoveLow)) strcat_P(statusOutput, PSTR("Low"));
else if (getStatus(MoveHigh)) strcat_P(statusOutput, PSTR("High"));
else if (getStatus(MoveFull)) strcat_P(statusOutput, PSTR("Full"));
if(getStatus(MoveCharging)) strcat_P(statusOutput, PSTR("Charging"));
else if(getStatus(MoveNotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
else if(getStatus(MoveShutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
else if(getStatus(MoveDying)) strcat_P(statusOutput, PSTR("Dying"));
else if(getStatus(MoveLow)) strcat_P(statusOutput, PSTR("Low"));
else if(getStatus(MoveHigh)) strcat_P(statusOutput, PSTR("High"));
else if(getStatus(MoveFull)) strcat_P(statusOutput, PSTR("Full"));
else strcat_P(statusOutput, PSTR("Error"));
return statusOutput;
@ -219,7 +219,7 @@ void PS3BT::Reset() {
l2cap_state = L2CAP_WAIT;
// Needed for PS3 Dualshock Controller commands to work via Bluetooth
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
HIDBuffer[i + 2] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // First two bytes reserved for report type and ID
}
@ -231,17 +231,17 @@ void PS3BT::disconnect() { // Use this void to disconnect any of the controllers
}
void PS3BT::ACLData(uint8_t* ACLData) {
if (!pBtd->l2capConnectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected && !activeConnection && !pBtd->connectToWii && !pBtd->incomingWii && !pBtd->pairWithWii) {
if (ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) {
if ((ACLData[12] | (ACLData[13] << 8)) == HID_CTRL_PSM) {
if(!pBtd->l2capConnectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected && !activeConnection && !pBtd->connectToWii && !pBtd->incomingWii && !pBtd->pairWithWii) {
if(ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) {
if((ACLData[12] | (ACLData[13] << 8)) == HID_CTRL_PSM) {
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;
for (uint8_t i = 0; i < 30; i++)
for(uint8_t i = 0; i < 30; i++)
remote_name[i] = pBtd->remote_name[i]; // Store the remote name for the connection
#ifdef DEBUG_USB_HOST
if (pBtd->hci_version < 3) { // Check the HCI Version of the Bluetooth dongle
if(pBtd->hci_version < 3) { // Check the HCI Version of the Bluetooth dongle
Notify(PSTR("\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour HCI Version is: "), 0x80);
Notify(pBtd->hci_version, 0x80);
Notify(PSTR("\r\nBut should be at least 3\r\nThis means that it doesn't support Bluetooth Version 2.0+EDR"), 0x80);
@ -250,10 +250,10 @@ void PS3BT::ACLData(uint8_t* ACLData) {
}
}
}
if ((ACLData[0] | (uint16_t)ACLData[1] << 8) == (hci_handle | 0x2000U)) { //acl_handle_ok
if((ACLData[0] | (uint16_t)ACLData[1] << 8) == (hci_handle | 0x2000U)) { //acl_handle_ok
memcpy(l2capinbuf, ACLData, BULK_MAXPKTSIZE);
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
@ -268,7 +268,7 @@ void PS3BT::ACLData(uint8_t* ACLData) {
Notify(PSTR(" "), 0x80);
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
#endif
} else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
} 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);
@ -281,44 +281,44 @@ void PS3BT::ACLData(uint8_t* ACLData) {
Notify(PSTR(" Identifier: "), 0x80);
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
#endif
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
identifier = l2capinbuf[9];
control_scid[0] = l2capinbuf[14];
control_scid[1] = l2capinbuf[15];
l2cap_set_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST);
} else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) {
} else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) {
identifier = l2capinbuf[9];
interrupt_scid[0] = l2capinbuf[14];
interrupt_scid[1] = l2capinbuf[15];
l2cap_set_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]) {
} 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);
l2cap_set_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS);
} else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
} else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
//Notify(PSTR("\r\nHID Interrupt Configuration Complete"), 0x80);
l2cap_set_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]) {
} 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]) {
} 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]) {
} 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]) {
} 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
@ -326,12 +326,12 @@ void PS3BT::ACLData(uint8_t* ACLData) {
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]) {
} 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_set_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE);
} else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
} else if(l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
//Notify(PSTR("\r\nDisconnect Response: Interrupt Channel"), 0x80);
identifier = l2capinbuf[9];
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE);
@ -343,26 +343,26 @@ void PS3BT::ACLData(uint8_t* ACLData) {
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
}
#endif
} else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt
} else if(l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt
//Notify(PSTR("\r\nL2CAP Interrupt"), 0x80);
if (PS3Connected || PS3MoveConnected || PS3NavigationConnected) {
if(PS3Connected || PS3MoveConnected || PS3NavigationConnected) {
/* Read Report */
if (l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
if (PS3Connected || PS3NavigationConnected)
if(l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
if(PS3Connected || PS3NavigationConnected)
ButtonState = (uint32_t)(l2capinbuf[11] | ((uint16_t)l2capinbuf[12] << 8) | ((uint32_t)l2capinbuf[13] << 16));
else if (PS3MoveConnected)
else if(PS3MoveConnected)
ButtonState = (uint32_t)(l2capinbuf[10] | ((uint16_t)l2capinbuf[11] << 8) | ((uint32_t)l2capinbuf[12] << 16));
//Notify(PSTR("\r\nButtonState", 0x80);
//PrintHex<uint32_t>(ButtonState, 0x80);
if (ButtonState != OldButtonState) {
if(ButtonState != OldButtonState) {
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
OldButtonState = ButtonState;
}
#ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
for (uint8_t i = 10; i < 58; i++) {
for(uint8_t i = 10; i < 58; i++) {
D_PrintHex<uint8_t > (l2capinbuf[i], 0x80);
Notify(PSTR(" "), 0x80);
}
@ -376,9 +376,9 @@ void PS3BT::ACLData(uint8_t* ACLData) {
}
void PS3BT::L2CAP_task() {
switch (l2cap_state) {
switch(l2cap_state) {
case L2CAP_WAIT:
if (l2cap_check_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST)) {
if(l2cap_check_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80);
#endif
@ -393,7 +393,7 @@ void PS3BT::L2CAP_task() {
break;
case L2CAP_CONTROL_SUCCESS:
if (l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
if(l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
#endif
@ -402,7 +402,7 @@ void PS3BT::L2CAP_task() {
break;
case L2CAP_INTERRUPT_SETUP:
if (l2cap_check_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST)) {
if(l2cap_check_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
#endif
@ -418,11 +418,11 @@ void PS3BT::L2CAP_task() {
break;
case L2CAP_INTERRUPT_CONFIG_REQUEST:
if (l2cap_check_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)) { // Now the HID channels is established
if(l2cap_check_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)) { // Now the HID channels is established
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHID Interrupt Successfully Configured"), 0x80);
#endif
if (remote_name[0] == 'M') { // First letter in Motion Controller ('M')
if(remote_name[0] == 'M') { // First letter in Motion Controller ('M')
memset(l2capinbuf, 0, BULK_MAXPKTSIZE); // Reset l2cap in buffer as it sometimes read it as a button has been pressed
l2cap_state = TURN_ON_LED;
} else
@ -434,7 +434,7 @@ void PS3BT::L2CAP_task() {
/* These states are handled in Run() */
case L2CAP_INTERRUPT_DISCONNECT:
if (l2cap_check_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE)) {
if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80);
#endif
@ -445,7 +445,7 @@ void PS3BT::L2CAP_task() {
break;
case L2CAP_CONTROL_DISCONNECT:
if (l2cap_check_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)) {
if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nDisconnected Control Channel"), 0x80);
#endif
@ -459,11 +459,11 @@ void PS3BT::L2CAP_task() {
}
void PS3BT::Run() {
switch (l2cap_state) {
switch(l2cap_state) {
case PS3_ENABLE_SIXAXIS:
if (millis() - timer > 1000) { // loop 1 second before sending the command
if(millis() - timer > 1000) { // loop 1 second before sending the command
memset(l2capinbuf, 0, BULK_MAXPKTSIZE); // Reset l2cap in buffer as it sometimes read it as a button has been pressed
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
enable_sixaxis();
l2cap_state = TURN_ON_LED;
@ -472,18 +472,18 @@ void PS3BT::Run() {
break;
case TURN_ON_LED:
if (millis() - timer > 1000) { // loop 1 second before sending the command
if (remote_name[0] == 'P') { // First letter in PLAYSTATION(R)3 Controller ('P')
if(millis() - timer > 1000) { // loop 1 second before sending the command
if(remote_name[0] == 'P') { // First letter in PLAYSTATION(R)3 Controller ('P')
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n"), 0x80);
#endif
PS3Connected = true;
} else if (remote_name[0] == 'N') { // First letter in Navigation Controller ('N')
} else if(remote_name[0] == 'N') { // First letter in Navigation Controller ('N')
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nNavigation Controller Enabled\r\n"), 0x80);
#endif
PS3NavigationConnected = true;
} else if (remote_name[0] == 'M') { // First letter in Motion Controller ('M')
} else if(remote_name[0] == 'M') { // First letter in Motion Controller ('M')
timerBulbRumble = millis();
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nMotion Controller Enabled\r\n"), 0x80);
@ -500,8 +500,8 @@ void PS3BT::Run() {
break;
case L2CAP_DONE:
if (PS3MoveConnected) { // The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on
if (millis() - timerBulbRumble > 4000) { // Send at least every 4th second
if(PS3MoveConnected) { // The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on
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
timerBulbRumble = millis();
}
@ -517,7 +517,7 @@ void PS3BT::Run() {
// Playstation Sixaxis Dualshock and Navigation Controller commands
void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) {
if (millis() - timerHID <= 150) // Check if is has been more than 150ms since last command
if(millis() - timerHID <= 150) // Check if is has been more than 150ms since last command
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
timerHID = millis();
@ -544,8 +544,8 @@ void PS3BT::setRumbleOff() {
}
void PS3BT::setRumbleOn(Rumble mode) {
uint8_t power[2] = { 0xff, 0x00 }; // Defaults to RumbleLow
if (mode == RumbleHigh) {
uint8_t power[2] = {0xff, 0x00}; // Defaults to RumbleLow
if(mode == RumbleHigh) {
power[0] = 0x00;
power[1] = 0xff;
}
@ -595,7 +595,7 @@ void PS3BT::enable_sixaxis() { // Command used to enable the Dualshock 3 and Nav
// Playstation Move Controller commands
void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) {
if (millis() - timerHID <= 150)// Check if is has been less than 150ms since last command
if(millis() - timerHID <= 150)// Check if is has been less than 150ms since last command
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
timerHID = millis();
@ -616,7 +616,7 @@ void PS3BT::moveSetBulb(Colors color) { //Use this to set the Color using the pr
void PS3BT::moveSetRumble(uint8_t rumble) {
#ifdef DEBUG_USB_HOST
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);
#endif
// Set the rumble value into the write buffer
@ -626,12 +626,12 @@ void PS3BT::moveSetRumble(uint8_t rumble) {
}
void PS3BT::onInit() {
if (pFuncOnInit)
if(pFuncOnInit)
pFuncOnInit(); // Call the user function
else {
if (PS3MoveConnected)
if(PS3MoveConnected)
moveSetBulb(Red);
else // Dualshock 3 or Navigation controller
setLedOn(LED1);
}
}
}

View file

@ -143,6 +143,7 @@ public:
* @param value See: ::LED enum.
*/
void setLedRaw(uint8_t value);
/** Turn all LEDs off. */
void setLedOff() {
setLedRaw(0);

View file

@ -212,4 +212,4 @@ enum Rumble {
RumbleLow = 0x20,
};
#endif
#endif

View file

@ -25,14 +25,14 @@ pUsb(p), // pointer to USB class instance - mandatory
bAddress(0), // device address - mandatory
bPollEnable(false) // don't start polling before dongle is connected
{
for (uint8_t i = 0; i < PS3_MAX_ENDPOINTS; i++) {
for(uint8_t i = 0; i < PS3_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
}
if (pUsb) // register in USB subsystem
if(pUsb) // register in USB subsystem
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
@ -58,7 +58,7 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
Notify(PSTR("\r\nPS3USB Init"), 0x80);
#endif
// check if address has already been assigned to an instance
if (bAddress) {
if(bAddress) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress in use"), 0x80);
#endif
@ -68,14 +68,14 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p) {
if(!p) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
if (!p->epinfo) {
if(!p->epinfo) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nepinfo is null"), 0x80);
#endif
@ -95,19 +95,19 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
if (rcode)
if(rcode)
goto FailGetDevDescr;
VID = udd->idVendor;
PID = udd->idProduct;
if (VID != PS3_VID || (PID != PS3_PID && PID != PS3NAVIGATION_PID && PID != PS3MOVE_PID))
if(VID != PS3_VID || (PID != PS3_PID && PID != PS3NAVIGATION_PID && PID != PS3MOVE_PID))
goto FailUnknownDevice;
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from device descriptor
@ -115,7 +115,7 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
if(rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
@ -135,14 +135,14 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
//get pointer to assigned address record
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
// Assign epInfo to epinfo pointer - only EP0 is known
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
@ -165,17 +165,17 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = 0;
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
delay(200); //Give time for address change
rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1);
if (rcode)
if(rcode)
goto FailSetConfDescr;
if (PID == PS3_PID || PID == PS3NAVIGATION_PID) {
if (PID == PS3_PID) {
if(PID == PS3_PID || PID == PS3NAVIGATION_PID) {
if(PID == PS3_PID) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
#endif
@ -189,10 +189,10 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
enable_sixaxis(); // The PS3 controller needs a special command before it starts sending data
// Needed for PS3 Dualshock and Navigation commands to work
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]);
for (uint8_t i = 6; i < 10; i++)
for(uint8_t i = 6; i < 10; i++)
readBuf[i] = 0x7F; // Set the analog joystick values to center position
} else { // must be a Motion controller
#ifdef DEBUG_USB_HOST
@ -201,15 +201,15 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
PS3MoveConnected = true;
writeBuf[0] = 0x02; // Set report ID, this is needed for Move commands to work
}
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) {
if (PS3MoveConnected)
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) {
if(PS3MoveConnected)
setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address
else
setBdaddr(my_bdaddr); // Set internal Bluetooth address
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
for (int8_t i = 5; i > 0; i--) {
for(int8_t i = 5; i > 0; i--) {
D_PrintHex<uint8_t > (my_bdaddr[i], 0x80);
Notify(PSTR(":"), 0x80);
}
@ -269,20 +269,20 @@ uint8_t PS3USB::Release() {
}
uint8_t PS3USB::Poll() {
if (!bPollEnable)
if(!bPollEnable)
return 0;
if (PS3Connected || PS3NavigationConnected) {
if(PS3Connected || PS3NavigationConnected) {
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
if (millis() - timer > 100) { // Loop 100ms before processing data
if(millis() - timer > 100) { // Loop 100ms before processing data
readReport();
#ifdef PRINTREPORT
printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
#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
if (millis() - timer > 4000) { // Send at least every 4th second
} 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
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();
}
@ -296,7 +296,7 @@ void PS3USB::readReport() {
//Notify(PSTR("\r\nButtonState", 0x80);
//PrintHex<uint32_t>(ButtonState, 0x80);
if (ButtonState != OldButtonState) {
if(ButtonState != OldButtonState) {
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
OldButtonState = ButtonState;
}
@ -304,7 +304,7 @@ void PS3USB::readReport() {
void PS3USB::printReport() { // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
#ifdef PRINTREPORT
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);
Notify(PSTR(" "), 0x80);
}
@ -336,7 +336,7 @@ uint16_t PS3USB::getSensor(Sensor a) {
}
double PS3USB::getAngle(Angle a) {
if (PS3Connected) {
if(PS3Connected) {
double accXval;
double accYval;
double accZval;
@ -350,7 +350,7 @@ double PS3USB::getAngle(Angle a) {
// Convert to 360 degrees resolution
// atan2 outputs the value of -π to π (radians)
// We are then converting it to 0 to 2π and then to degrees
if (a == Pitch)
if(a == Pitch)
return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
else
return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
@ -363,33 +363,33 @@ bool PS3USB::getStatus(Status c) {
}
String PS3USB::getStatusString() {
if (PS3Connected || PS3NavigationConnected) {
if(PS3Connected || PS3NavigationConnected) {
char statusOutput[100];
strcpy(statusOutput, "ConnectionStatus: ");
if (getStatus(Plugged)) strcat(statusOutput, "Plugged");
else if (getStatus(Unplugged)) strcat(statusOutput, "Unplugged");
if(getStatus(Plugged)) strcat(statusOutput, "Plugged");
else if(getStatus(Unplugged)) strcat(statusOutput, "Unplugged");
else strcat(statusOutput, "Error");
strcat(statusOutput, " - PowerRating: ");
if (getStatus(Charging)) strcat(statusOutput, "Charging");
else if (getStatus(NotCharging)) strcat(statusOutput, "Not Charging");
else if (getStatus(Shutdown)) strcat(statusOutput, "Shutdown");
else if (getStatus(Dying)) strcat(statusOutput, "Dying");
else if (getStatus(Low)) strcat(statusOutput, "Low");
else if (getStatus(High)) strcat(statusOutput, "High");
else if (getStatus(Full)) strcat(statusOutput, "Full");
if(getStatus(Charging)) strcat(statusOutput, "Charging");
else if(getStatus(NotCharging)) strcat(statusOutput, "Not Charging");
else if(getStatus(Shutdown)) strcat(statusOutput, "Shutdown");
else if(getStatus(Dying)) strcat(statusOutput, "Dying");
else if(getStatus(Low)) strcat(statusOutput, "Low");
else if(getStatus(High)) strcat(statusOutput, "High");
else if(getStatus(Full)) strcat(statusOutput, "Full");
else strcat(statusOutput, "Error");
strcat(statusOutput, " - WirelessStatus: ");
if (getStatus(CableRumble)) strcat(statusOutput, "Cable - Rumble is on");
else if (getStatus(Cable)) strcat(statusOutput, "Cable - Rumble is off");
else if (getStatus(BluetoothRumble)) strcat(statusOutput, "Bluetooth - Rumble is on");
else if (getStatus(Bluetooth)) strcat(statusOutput, "Bluetooth - Rumble is off");
if(getStatus(CableRumble)) strcat(statusOutput, "Cable - Rumble is on");
else if(getStatus(Cable)) strcat(statusOutput, "Cable - Rumble is off");
else if(getStatus(BluetoothRumble)) strcat(statusOutput, "Bluetooth - Rumble is on");
else if(getStatus(Bluetooth)) strcat(statusOutput, "Bluetooth - Rumble is off");
else strcat(statusOutput, "Error");
return statusOutput;
@ -404,7 +404,7 @@ void PS3USB::PS3_Command(uint8_t *data, uint16_t nbytes) {
}
void PS3USB::setAllOff() {
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
@ -420,9 +420,9 @@ void PS3USB::setRumbleOff() {
}
void PS3USB::setRumbleOn(Rumble mode) {
if ((mode & 0x30) > 0x00) {
if((mode & 0x30) > 0x00) {
uint8_t power[2] = {0xff, 0x00}; // Defaults to RumbleLow
if (mode == RumbleHigh) {
if(mode == RumbleHigh) {
power[0] = 0x00;
power[1] = 0xff;
}
@ -464,7 +464,7 @@ void PS3USB::setBdaddr(uint8_t *bdaddr) {
buf[0] = 0x01;
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, 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
@ -477,7 +477,7 @@ void PS3USB::getBdaddr(uint8_t *bdaddr) {
// 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++)
for(uint8_t i = 0; i < 6; i++)
bdaddr[5 - i] = buf[i + 2]; // Copy into buffer reversed, so it is LSB first
}
@ -512,7 +512,7 @@ void PS3USB::moveSetBulb(Colors color) { // Use this to set the Color using the
void PS3USB::moveSetRumble(uint8_t rumble) {
#ifdef DEBUG_USB_HOST
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);
#endif
writeBuf[6] = rumble; // Set the rumble value into the write buffer
@ -529,7 +529,7 @@ void PS3USB::setMoveBdaddr(uint8_t *bdaddr) {
buf[9] = 0x02;
buf[10] = 0x12;
for (uint8_t i = 0; i < 6; i++)
for(uint8_t i = 0; i < 6; 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
@ -542,27 +542,27 @@ void PS3USB::getMoveBdaddr(uint8_t *bdaddr) {
// 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++)
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++) {
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++)
for(byte j = 0; j < 49; j++)
data[49 * i + j] = buf[j];
}
}
void PS3USB::onInit() {
if (pFuncOnInit)
if(pFuncOnInit)
pFuncOnInit(); // Call the user function
else {
if (PS3MoveConnected)
if(PS3MoveConnected)
moveSetBulb(Red);
else // Dualshock 3 or Navigation controller
setLedOn(LED1);

View file

@ -220,6 +220,7 @@ public:
* @param value See: ::LED enum.
*/
void setLedRaw(uint8_t value);
/** Turn all LEDs off. */
void setLedOff() {
setLedRaw(0);

168
SPP.cpp
View file

@ -45,7 +45,7 @@ const uint8_t rfcomm_crc_table[256] PROGMEM = {/* reversed, 8-bit, poly=0x07 */
SPP::SPP(BTD *p, const char* name, const char* pin) :
pBtd(p) // Pointer to BTD class instance - mandatory
{
if (pBtd)
if(pBtd)
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
pBtd->btdName = name;
@ -74,32 +74,32 @@ void SPP::Reset() {
void SPP::disconnect() {
connected = false;
// First the two L2CAP channels has to be disconnected and then the HCI connection
if (RFCOMMConnected)
if(RFCOMMConnected)
pBtd->l2cap_disconnection_request(hci_handle, ++identifier, rfcomm_scid, rfcomm_dcid);
if (RFCOMMConnected && SDPConnected)
if(RFCOMMConnected && SDPConnected)
delay(1); // Add delay between commands
if (SDPConnected)
if(SDPConnected)
pBtd->l2cap_disconnection_request(hci_handle, ++identifier, sdp_scid, sdp_dcid);
l2cap_sdp_state = L2CAP_DISCONNECT_RESPONSE;
}
void SPP::ACLData(uint8_t* l2capinbuf) {
if (!connected) {
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM && !pBtd->sdpConnectionClaimed) {
if(!connected) {
if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM && !pBtd->sdpConnectionClaimed) {
pBtd->sdpConnectionClaimed = true;
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
l2cap_sdp_state = L2CAP_SDP_WAIT; // Reset state
} else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == RFCOMM_PSM && !pBtd->rfcommConnectionClaimed) {
} else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == RFCOMM_PSM && !pBtd->rfcommConnectionClaimed) {
pBtd->rfcommConnectionClaimed = true;
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT; // Reset state
}
}
}
if ((l2capinbuf[0] | (uint16_t)l2capinbuf[1] << 8) == (hci_handle | 0x2000U)) { // acl_handle_ok
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
if((l2capinbuf[0] | (uint16_t)l2capinbuf[1] << 8) == (hci_handle | 0x2000U)) { // acl_handle_ok
if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
@ -114,7 +114,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
Notify(PSTR(" "), 0x80);
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
#endif
} else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
} 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);
@ -127,56 +127,56 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
Notify(PSTR(" Identifier: "), 0x80);
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
#endif
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM) { // It doesn't matter if it receives another reqeust, since it waits for the channel to disconnect in the L2CAP_SDP_DONE state, and the l2cap_event_flag will be cleared if so
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM) { // It doesn't matter if it receives another reqeust, since it waits for the channel to disconnect in the L2CAP_SDP_DONE state, and the l2cap_event_flag will be cleared if so
identifier = l2capinbuf[9];
sdp_scid[0] = l2capinbuf[14];
sdp_scid[1] = l2capinbuf[15];
l2cap_set_flag(L2CAP_FLAG_CONNECTION_SDP_REQUEST);
} else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == RFCOMM_PSM) { // ----- || -----
} else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == RFCOMM_PSM) { // ----- || -----
identifier = l2capinbuf[9];
rfcomm_scid[0] = l2capinbuf[14];
rfcomm_scid[1] = l2capinbuf[15];
l2cap_set_flag(L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST);
}
} else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
if (l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
} else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
if(l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
//Notify(PSTR("\r\nSDP Configuration Complete"), 0x80);
l2cap_set_flag(L2CAP_FLAG_CONFIG_SDP_SUCCESS);
} else if (l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
} else if(l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
//Notify(PSTR("\r\nRFCOMM Configuration Complete"), 0x80);
l2cap_set_flag(L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS);
}
}
} else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
if (l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
} else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
if(l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
//Notify(PSTR("\r\nSDP Configuration Request"), 0x80);
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], sdp_scid);
} else if (l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
} else if(l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
//Notify(PSTR("\r\nRFCOMM Configuration Request"), 0x80);
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], rfcomm_scid);
}
} else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
if (l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
} else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
if(l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
//Notify(PSTR("\r\nDisconnect Request: SDP Channel"), 0x80);
identifier = l2capinbuf[9];
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_SDP_REQUEST);
} else if (l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
} else if(l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
//Notify(PSTR("\r\nDisconnect Request: RFCOMM Channel"), 0x80);
identifier = l2capinbuf[9];
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST);
}
} else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
if (l2capinbuf[12] == sdp_scid[0] && l2capinbuf[13] == sdp_scid[1]) {
} else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
if(l2capinbuf[12] == sdp_scid[0] && l2capinbuf[13] == sdp_scid[1]) {
//Notify(PSTR("\r\nDisconnect Response: SDP Channel"), 0x80);
identifier = l2capinbuf[9];
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_RESPONSE);
} else if (l2capinbuf[12] == rfcomm_scid[0] && l2capinbuf[13] == rfcomm_scid[1]) {
} else if(l2capinbuf[12] == rfcomm_scid[0] && l2capinbuf[13] == rfcomm_scid[1]) {
//Notify(PSTR("\r\nDisconnect Response: RFCOMM Channel"), 0x80);
identifier = l2capinbuf[9];
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_RESPONSE);
}
} else if (l2capinbuf[8] == L2CAP_CMD_INFORMATION_REQUEST) {
} else if(l2capinbuf[8] == L2CAP_CMD_INFORMATION_REQUEST) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nInformation request"), 0x80);
#endif
@ -189,18 +189,18 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
}
#endif
} else if (l2capinbuf[6] == sdp_dcid[0] && l2capinbuf[7] == sdp_dcid[1]) { // SDP
if (l2capinbuf[8] == SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST_PDU) {
if (((l2capinbuf[16] << 8 | l2capinbuf[17]) == SERIALPORT_UUID) || ((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000 && (l2capinbuf[18] << 8 | l2capinbuf[19]) == SERIALPORT_UUID)) { // Check if it's sending the full UUID, see: https://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm, we will just check the first four bytes
if (firstMessage) {
} else if(l2capinbuf[6] == sdp_dcid[0] && l2capinbuf[7] == sdp_dcid[1]) { // SDP
if(l2capinbuf[8] == SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST_PDU) {
if(((l2capinbuf[16] << 8 | l2capinbuf[17]) == SERIALPORT_UUID) || ((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000 && (l2capinbuf[18] << 8 | l2capinbuf[19]) == SERIALPORT_UUID)) { // Check if it's sending the full UUID, see: https://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm, we will just check the first four bytes
if(firstMessage) {
serialPortResponse1(l2capinbuf[9], l2capinbuf[10]);
firstMessage = false;
} else {
serialPortResponse2(l2capinbuf[9], l2capinbuf[10]); // Serialport continuation state
firstMessage = true;
}
} else if (((l2capinbuf[16] << 8 | l2capinbuf[17]) == L2CAP_UUID) || ((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000 && (l2capinbuf[18] << 8 | l2capinbuf[19]) == L2CAP_UUID)) {
if (firstMessage) {
} else if(((l2capinbuf[16] << 8 | l2capinbuf[17]) == L2CAP_UUID) || ((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000 && (l2capinbuf[18] << 8 | l2capinbuf[19]) == L2CAP_UUID)) {
if(firstMessage) {
l2capResponse1(l2capinbuf[9], l2capinbuf[10]);
firstMessage = false;
} else {
@ -216,14 +216,14 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
uuid = (l2capinbuf[18] << 8 | l2capinbuf[19]);
else // Short UUID
uuid = (l2capinbuf[16] << 8 | l2capinbuf[17]);
D_PrintHex<uint16_t> (uuid, 0x80);
D_PrintHex<uint16_t > (uuid, 0x80);
Notify(PSTR("\r\nLength: "), 0x80);
uint16_t length = l2capinbuf[11] << 8 | l2capinbuf[12];
D_PrintHex<uint16_t> (length, 0x80);
D_PrintHex<uint16_t > (length, 0x80);
Notify(PSTR("\r\nData: "), 0x80);
for (uint8_t i = 0; i < length; i++) {
D_PrintHex<uint8_t> (l2capinbuf[13+i], 0x80);
for(uint8_t i = 0; i < length; i++) {
D_PrintHex<uint8_t > (l2capinbuf[13 + i], 0x80);
Notify(PSTR(" "), 0x80);
}
#endif
@ -234,14 +234,14 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
}
#endif
} else if (l2capinbuf[6] == rfcomm_dcid[0] && l2capinbuf[7] == rfcomm_dcid[1]) { // RFCOMM
} else if(l2capinbuf[6] == rfcomm_dcid[0] && l2capinbuf[7] == rfcomm_dcid[1]) { // RFCOMM
rfcommChannel = l2capinbuf[8] & 0xF8;
rfcommDirection = l2capinbuf[8] & 0x04;
rfcommCommandResponse = l2capinbuf[8] & 0x02;
rfcommChannelType = l2capinbuf[9] & 0xEF;
rfcommPfBit = l2capinbuf[9] & 0x10;
if (rfcommChannel >> 3 != 0x00)
if(rfcommChannel >> 3 != 0x00)
rfcommChannelConnection = rfcommChannel;
#ifdef EXTRADEBUG
@ -256,7 +256,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
Notify(PSTR(" PF_BIT: "), 0x80);
D_PrintHex<uint8_t > (rfcommPfBit, 0x80);
#endif
if (rfcommChannelType == RFCOMM_DISC) {
if(rfcommChannelType == RFCOMM_DISC) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nReceived Disconnect RFCOMM Command on channel: "), 0x80);
D_PrintHex<uint8_t > (rfcommChannel >> 3, 0x80);
@ -264,15 +264,15 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
connected = false;
sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse, RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00); // UA Command
}
if (connected) {
if(connected) {
/* 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 offset = l2capinbuf[4] - length - 4; // Check if there is credit
if (checkFcs(&l2capinbuf[8], l2capinbuf[11 + length + offset])) {
if(checkFcs(&l2capinbuf[8], l2capinbuf[11 + length + offset])) {
uint8_t i = 0;
for (; i < length; i++) {
if (rfcommAvailable + i >= sizeof (rfcommDataBuffer)) {
for(; i < length; i++) {
if(rfcommAvailable + i >= sizeof (rfcommDataBuffer)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nWarning: Buffer is full!"), 0x80);
#endif
@ -284,7 +284,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
#ifdef EXTRADEBUG
Notify(PSTR("\r\nRFCOMM Data Available: "), 0x80);
Notify(rfcommAvailable, 0x80);
if (offset) {
if(offset) {
Notify(PSTR(" - Credit: 0x"), 0x80);
D_PrintHex<uint8_t > (l2capinbuf[11], 0x80);
}
@ -295,10 +295,10 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
Notify(PSTR("\r\nError in FCS checksum!"), 0x80);
#endif
#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++)
Notifyc(l2capinbuf[i + 11 + offset], 0x80);
#endif
} else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_RPN_CMD) { // UIH Remote Port Negotiation Command
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_RPN_CMD) { // UIH Remote Port Negotiation Command
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
#endif
@ -313,7 +313,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
rfcommbuf[8] = l2capinbuf[19]; // MaxRatransm.
rfcommbuf[9] = l2capinbuf[20]; // Number of Frames
sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A); // UIH Remote Port Negotiation Response
} else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_CMD) { // UIH Modem Status Command
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_CMD) { // UIH Modem Status Command
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nSend UIH Modem Status Response"), 0x80);
#endif
@ -324,12 +324,12 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
}
} else {
if (rfcommChannelType == RFCOMM_SABM) { // SABM Command - this is sent twice: once for channel 0 and then for the channel to establish
if(rfcommChannelType == RFCOMM_SABM) { // SABM Command - this is sent twice: once for channel 0 and then for the channel to establish
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nReceived SABM Command"), 0x80);
#endif
sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse, RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00); // UA Command
} else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_PN_CMD) { // UIH Parameter Negotiation Command
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_PN_CMD) { // UIH Parameter Negotiation Command
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nReceived UIH Parameter Negotiation Command"), 0x80);
#endif
@ -344,7 +344,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
rfcommbuf[8] = 0x00; // MaxRatransm.
rfcommbuf[9] = 0x00; // Number of Frames
sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A);
} else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_CMD) { // UIH Modem Status Command
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_CMD) { // UIH Modem Status Command
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nSend UIH Modem Status Response"), 0x80);
#endif
@ -364,8 +364,8 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
rfcommbuf[3] = 0x8D; // Can receive frames (YES), Ready to Communicate (YES), Ready to Receive (YES), Incomig Call (NO), Data is Value (YES)
sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
} else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_RSP) { // UIH Modem Status Response
if (!creditSent) {
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_RSP) { // UIH Modem Status Response
if(!creditSent) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nSend UIH Command with credit"), 0x80);
#endif
@ -374,11 +374,11 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
timer = millis();
waitForLastCommand = true;
}
} else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[10] == 0x01) { // UIH Command with credit
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[10] == 0x01) { // UIH Command with credit
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nReceived UIH Command with credit"), 0x80);
#endif
} else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_RPN_CMD) { // UIH Remote Port Negotiation Command
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_RPN_CMD) { // UIH Remote Port Negotiation Command
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
#endif
@ -402,7 +402,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
sppIndex = 0;
}
#ifdef EXTRADEBUG
else if (rfcommChannelType != RFCOMM_DISC) {
else if(rfcommChannelType != RFCOMM_DISC) {
Notify(PSTR("\r\nUnsupported RFCOMM Data - ChannelType: "), 0x80);
D_PrintHex<uint8_t > (rfcommChannelType, 0x80);
Notify(PSTR(" Command: "), 0x80);
@ -425,7 +425,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
}
void SPP::Run() {
if (waitForLastCommand && (millis() - timer) > 100) { // We will only wait 100ms and see if the UIH Remote Port Negotiation Command is send, as some deviced don't send it
if(waitForLastCommand && (millis() - timer) > 100) { // We will only wait 100ms and see if the UIH Remote Port Negotiation Command is send, as some deviced don't send it
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"), 0x80);
#endif
@ -438,9 +438,9 @@ void SPP::Run() {
}
void SPP::SDP_task() {
switch (l2cap_sdp_state) {
switch(l2cap_sdp_state) {
case L2CAP_SDP_WAIT:
if (l2cap_check_flag(L2CAP_FLAG_CONNECTION_SDP_REQUEST)) {
if(l2cap_check_flag(L2CAP_FLAG_CONNECTION_SDP_REQUEST)) {
l2cap_clear_flag(L2CAP_FLAG_CONNECTION_SDP_REQUEST); // Clear flag
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nSDP Incoming Connection Request"), 0x80);
@ -452,7 +452,7 @@ void SPP::SDP_task() {
delay(1);
pBtd->l2cap_config_request(hci_handle, identifier, sdp_scid);
l2cap_sdp_state = L2CAP_SDP_SUCCESS;
} else if (l2cap_check_flag(L2CAP_FLAG_DISCONNECT_SDP_REQUEST)) {
} else if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_SDP_REQUEST)) {
l2cap_clear_flag(L2CAP_FLAG_DISCONNECT_SDP_REQUEST); // Clear flag
SDPConnected = false;
#ifdef DEBUG_USB_HOST
@ -462,7 +462,7 @@ void SPP::SDP_task() {
}
break;
case L2CAP_SDP_SUCCESS:
if (l2cap_check_flag(L2CAP_FLAG_CONFIG_SDP_SUCCESS)) {
if(l2cap_check_flag(L2CAP_FLAG_CONFIG_SDP_SUCCESS)) {
l2cap_clear_flag(L2CAP_FLAG_CONFIG_SDP_SUCCESS); // Clear flag
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nSDP Successfully Configured"), 0x80);
@ -474,7 +474,7 @@ void SPP::SDP_task() {
break;
case L2CAP_DISCONNECT_RESPONSE: // This is for both disconnection response from the RFCOMM and SDP channel if they were connected
if (l2cap_check_flag(L2CAP_FLAG_DISCONNECT_RESPONSE)) {
if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_RESPONSE)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nDisconnected L2CAP Connection"), 0x80);
#endif
@ -487,9 +487,9 @@ void SPP::SDP_task() {
}
void SPP::RFCOMM_task() {
switch (l2cap_rfcomm_state) {
switch(l2cap_rfcomm_state) {
case L2CAP_RFCOMM_WAIT:
if (l2cap_check_flag(L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST)) {
if(l2cap_check_flag(L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST)) {
l2cap_clear_flag(L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST); // Clear flag
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nRFCOMM Incoming Connection Request"), 0x80);
@ -501,7 +501,7 @@ void SPP::RFCOMM_task() {
delay(1);
pBtd->l2cap_config_request(hci_handle, identifier, rfcomm_scid);
l2cap_rfcomm_state = L2CAP_RFCOMM_SUCCESS;
} else if (l2cap_check_flag(L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST)) {
} else if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST)) {
l2cap_clear_flag(L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST); // Clear flag
RFCOMMConnected = false;
connected = false;
@ -512,7 +512,7 @@ void SPP::RFCOMM_task() {
}
break;
case L2CAP_RFCOMM_SUCCESS:
if (l2cap_check_flag(L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS)) {
if(l2cap_check_flag(L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS)) {
l2cap_clear_flag(L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS); // Clear flag
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nRFCOMM Successfully Configured"), 0x80);
@ -670,12 +670,12 @@ void SPP::sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t cha
l2capoutbuf[1] = channelType | pfBit; // RFCOMM Control
l2capoutbuf[2] = length << 1 | 0x01; // Length and format (always 0x01 bytes format)
uint8_t i = 0;
for (; i < length; i++)
for(; i < length; i++)
l2capoutbuf[i + 3] = data[i];
l2capoutbuf[i + 3] = calcFcs(l2capoutbuf);
#ifdef EXTRADEBUG
Notify(PSTR(" - RFCOMM Data: "), 0x80);
for (i = 0; i < length + 4; i++) {
for(i = 0; i < length + 4; i++) {
D_PrintHex<uint8_t > (l2capoutbuf[i], 0x80);
Notify(PSTR(" "), 0x80);
}
@ -691,7 +691,7 @@ void SPP::sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8
l2capoutbuf[4] = calcFcs(l2capoutbuf);
#ifdef EXTRADEBUG
Notify(PSTR(" - RFCOMM Credit Data: "), 0x80);
for (uint8_t i = 0; i < 5; i++) {
for(uint8_t i = 0; i < 5; i++) {
D_PrintHex<uint8_t > (l2capoutbuf[i], 0x80);
Notify(PSTR(" "), 0x80);
}
@ -707,7 +707,7 @@ uint8_t SPP::crc(uint8_t *data) {
/* Calculate FCS */
uint8_t SPP::calcFcs(uint8_t *data) {
uint8_t temp = crc(data);
if ((data[1] & 0xEF) == RFCOMM_UIH)
if((data[1] & 0xEF) == RFCOMM_UIH)
return (0xFF - temp); // FCS on 2 bytes
else
return (0xFF - pgm_read_byte(&rfcomm_crc_table[temp ^ data[2]])); // FCS on 3 bytes
@ -716,29 +716,33 @@ uint8_t SPP::calcFcs(uint8_t *data) {
/* Check FCS */
bool SPP::checkFcs(uint8_t *data, uint8_t fcs) {
uint8_t temp = crc(data);
if ((data[1] & 0xEF) != RFCOMM_UIH)
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 */
#if defined(ARDUINO) && ARDUINO >=100
size_t SPP::write(uint8_t data) {
return write(&data, 1);
}
#else
void SPP::write(uint8_t data) {
write(&data, 1);
}
#endif
#if defined(ARDUINO) && ARDUINO >=100
size_t SPP::write(const uint8_t *data, size_t size) {
#else
void SPP::write(const uint8_t *data, size_t size) {
#endif
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
sppOutputBuffer[sppIndex++] = data[i]; // All the bytes are put into a buffer and then send using the send() function
}
@ -748,7 +752,7 @@ void SPP::write(const uint8_t *data, size_t size) {
}
void SPP::send() {
if (!connected || !sppIndex)
if(!connected || !sppIndex)
return;
uint8_t length; // This is the length of the string we are sending
uint8_t offset = 0; // This is used to keep track of where we are in the string
@ -756,15 +760,15 @@ void SPP::send() {
l2capoutbuf[0] = rfcommChannelConnection | 0 | 0 | extendAddress; // RFCOMM Address
l2capoutbuf[1] = RFCOMM_UIH; // RFCOMM Control
while (sppIndex) { // We will run this while loop until this variable is 0
if (sppIndex > (sizeof (l2capoutbuf) - 4)) // Check if the string is larger than the outgoing buffer
while(sppIndex) { // We will run this while loop until this variable is 0
if(sppIndex > (sizeof (l2capoutbuf) - 4)) // Check if the string is larger than the outgoing buffer
length = sizeof (l2capoutbuf) - 4;
else
length = sppIndex;
l2capoutbuf[2] = length << 1 | 1; // Length
uint8_t i = 0;
for (; i < length; i++)
for(; i < length; i++)
l2capoutbuf[i + 3] = sppOutputBuffer[i + offset];
l2capoutbuf[i + 3] = calcFcs(l2capoutbuf); // Calculate checksum
@ -784,20 +788,20 @@ void SPP::discard(void) {
}
int SPP::peek(void) {
if (rfcommAvailable == 0) // Don't read if there is nothing in the buffer
if(rfcommAvailable == 0) // Don't read if there is nothing in the buffer
return -1;
return rfcommDataBuffer[0];
}
int SPP::read(void) {
if (rfcommAvailable == 0) // Don't read if there is nothing in the buffer
if(rfcommAvailable == 0) // Don't read if there is nothing in the buffer
return -1;
uint8_t output = rfcommDataBuffer[0];
for (uint8_t i = 1; i < rfcommAvailable; i++)
for(uint8_t i = 1; i < rfcommAvailable; i++)
rfcommDataBuffer[i - 1] = rfcommDataBuffer[i]; // Shift the buffer one left
rfcommAvailable--;
bytesRead++;
if (bytesRead > (sizeof (rfcommDataBuffer) - 5)) { // We will send the command just before it runs out of credit
if(bytesRead > (sizeof (rfcommDataBuffer) - 5)) { // We will send the command just before it runs out of credit
bytesRead = 0;
sendRfcommCredit(rfcommChannelConnection, rfcommDirection, 0, RFCOMM_UIH, 0x10, sizeof (rfcommDataBuffer)); // Send more credit
#ifdef EXTRADEBUG

3
SPP.h
View file

@ -98,6 +98,7 @@ public:
* @return Return the number of bytes ready to be read.
*/
virtual int available(void);
/** Send out all bytes in the buffer. */
virtual void flush(void) {
send();
@ -218,4 +219,4 @@ private:
bool checkFcs(uint8_t *data, uint8_t fcs);
uint8_t crc(uint8_t *data);
};
#endif
#endif

173
Usb.cpp
View file

@ -44,13 +44,13 @@ void USB::setUsbTaskState(uint8_t state) {
EpInfo* USB::getEpInfoEntry(uint8_t addr, uint8_t ep) {
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
if (!p || !p->epinfo)
if(!p || !p->epinfo)
return NULL;
EpInfo *pep = p->epinfo;
for (uint8_t i = 0; i < p->epcount; i++) {
if ((pep)->epAddr == ep)
for(uint8_t i = 0; i < p->epcount; i++) {
if((pep)->epAddr == ep)
return pep;
pep++;
@ -62,12 +62,12 @@ EpInfo* USB::getEpInfoEntry(uint8_t addr, uint8_t ep) {
/* each device is different and has different number of endpoints. This function plugs endpoint record structure, defined in application, to devtable */
uint8_t USB::setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr) {
if (!eprecord_ptr)
if(!eprecord_ptr)
return USB_ERROR_INVALID_ARGUMENT;
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->address.devAddress = addr;
@ -80,15 +80,15 @@ uint8_t USB::setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr)
uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t &nak_limit) {
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p->epinfo)
if(!p->epinfo)
return USB_ERROR_EPINFO_IS_NULL;
*ppep = getEpInfoEntry(addr, ep);
if (!*ppep)
if(!*ppep)
return USB_ERROR_EP_NOT_FOUND_IN_TBL;
nak_limit = (0x0001UL << (((*ppep)->bmNakPower > USB_NAK_MAX_POWER) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower));
@ -134,7 +134,7 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
rcode = SetAddress(addr, ep, &pep, nak_limit);
if (rcode)
if(rcode)
return rcode;
direction = ((bmReqType & 0x80) > 0);
@ -151,39 +151,39 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
rcode = dispatchPkt(tokSETUP, ep, nak_limit); //dispatch packet
if (rcode) //return HRSLT if not zero
if(rcode) //return HRSLT if not zero
return ( rcode);
if (dataptr != NULL) //data stage, if present
if(dataptr != NULL) //data stage, if present
{
if (direction) //IN transfer
if(direction) //IN transfer
{
uint16_t left = total;
pep->bmRcvToggle = 1; //bmRCVTOG1;
while (left) {
while(left) {
// Bytes read into buffer
uint16_t read = nbytes;
//uint16_t read = (left<nbytes) ? left : nbytes;
rcode = InTransfer(pep, nak_limit, &read, dataptr);
if (rcode == hrTOGERR) {
if(rcode == hrTOGERR) {
// yes, we flip it wrong here so that next time it is actually correct!
pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
continue;
}
if (rcode)
if(rcode)
return rcode;
// Invoke callback function if inTransfer completed successfully and callback function pointer is specified
if (!rcode && p)
if(!rcode && p)
((USBReadParser*)p)->Parse(read, dataptr, total - left);
left -= read;
if (read < nbytes)
if(read < nbytes)
break;
}
} else //OUT transfer
@ -191,7 +191,7 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
pep->bmSndToggle = 1; //bmSNDTOG1;
rcode = OutTransfer(pep, nak_limit, nbytes, dataptr);
}
if (rcode) //return error
if(rcode) //return error
return ( rcode);
}
// Status stage
@ -209,7 +209,7 @@ uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t*
uint8_t rcode = SetAddress(addr, ep, &pep, nak_limit);
if (rcode) {
if(rcode) {
USBTRACE3("(USB::InTransfer) SetAddress Failed ", rcode, 0x81);
USBTRACE3("(USB::InTransfer) addr requested ", addr, 0x81);
USBTRACE3("(USB::InTransfer) ep requested ", ep, 0x81);
@ -229,22 +229,22 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
*nbytesptr = 0;
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
while (1) // use a 'return' to exit this loop
{
// use a 'break' to exit this loop
while(1) {
rcode = dispatchPkt(tokIN, pep->epAddr, nak_limit); //IN packet to EP-'endpoint'. Function takes care of NAKS.
if (rcode == hrTOGERR) {
if(rcode == hrTOGERR) {
// yes, we flip it wrong here so that next time it is actually correct!
pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
continue;
}
if (rcode) {
if(rcode) {
//printf(">>>>>>>> Problem! dispatchPkt %2.2x\r\n", rcode);
break; //should be 0, indicating ACK. Else return error code.
}
/* check for RCVDAVIRQ and generate error if not present */
/* the only case when absence of RCVDAVIRQ makes sense is when toggle error occurred. Need to add handling for that */
if ((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) {
if((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) {
//printf(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n");
rcode = 0xf0; //receive error
break;
@ -253,7 +253,7 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
//printf("Got %i bytes \r\n", pktsize);
// This would be OK, but...
//assert(pktsize <= nbytes);
if (pktsize > nbytes) {
if(pktsize > nbytes) {
// This can happen. Use of assert on Arduino locks up the Arduino.
// So I will trim the value, and hope for the best.
//printf(">>>>>>>> Problem! Wanted %i bytes but got %i.\r\n", nbytes, pktsize);
@ -262,7 +262,7 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr);
if (mem_left < 0)
if(mem_left < 0)
mem_left = 0;
data = bytesRd(rRCVFIFO, ((pktsize > mem_left) ? mem_left : pktsize), data);
@ -273,7 +273,7 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
/* The transfer is complete under two conditions: */
/* 1. The device sent a short packet (L.T. maxPacketSize) */
/* 2. 'nbytes' have been transferred. */
if ((pktsize < maxpktsize) || (*nbytesptr >= nbytes)) // have we transferred 'nbytes' bytes?
if((pktsize < maxpktsize) || (*nbytesptr >= nbytes)) // have we transferred 'nbytes' bytes?
{
// Save toggle value
pep->bmRcvToggle = ((regRd(rHRSL) & bmRCVTOGRD)) ? 1 : 0;
@ -295,7 +295,7 @@ uint8_t USB::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dat
uint8_t rcode = SetAddress(addr, ep, &pep, nak_limit);
if (rcode)
if(rcode)
return rcode;
return OutTransfer(pep, nak_limit, nbytes, data);
@ -309,35 +309,35 @@ uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8
uint8_t maxpktsize = pep->maxPktSize;
if (maxpktsize < 1 || maxpktsize > 64)
if(maxpktsize < 1 || maxpktsize > 64)
return USB_ERROR_INVALID_MAX_PKT_SIZE;
unsigned long timeout = millis() + USB_XFER_TIMEOUT;
regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
while (bytes_left) {
while(bytes_left) {
retry_count = 0;
nak_count = 0;
bytes_tosend = (bytes_left >= maxpktsize) ? maxpktsize : bytes_left;
bytesWr(rSNDFIFO, bytes_tosend, data_p); //filling output FIFO
regWr(rSNDBC, bytes_tosend); //set number of bytes
regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
while (!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
rcode = (regRd(rHRSL) & 0x0f);
while (rcode && (timeout > millis())) {
switch (rcode) {
while(rcode && (timeout > millis())) {
switch(rcode) {
case hrNAK:
nak_count++;
if (nak_limit && (nak_count == nak_limit))
if(nak_limit && (nak_count == nak_limit))
goto breakout;
//return ( rcode);
break;
case hrTIMEOUT:
retry_count++;
if (retry_count == USB_RETRY_LIMIT)
if(retry_count == USB_RETRY_LIMIT)
goto breakout;
//return ( rcode);
break;
@ -355,7 +355,7 @@ uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8
regWr(rSNDFIFO, *data_p);
regWr(rSNDBC, bytes_tosend);
regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
while (!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
rcode = (regRd(rHRSL) & 0x0f);
}//while( rcode && ....
@ -380,15 +380,15 @@ uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
uint8_t retry_count = 0;
uint16_t nak_count = 0;
while (timeout > millis()) {
while(timeout > millis()) {
regWr(rHXFR, (token | ep)); //launch the transfer
rcode = USB_ERROR_TRANSFER_TIMEOUT;
while (timeout > millis()) //wait for transfer completion
while(timeout > millis()) //wait for transfer completion
{
tmpdata = regRd(rHIRQ);
if (tmpdata & bmHXFRDNIRQ) {
if(tmpdata & bmHXFRDNIRQ) {
regWr(rHIRQ, bmHXFRDNIRQ); //clear the interrupt
rcode = 0x00;
break;
@ -401,15 +401,15 @@ uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
rcode = (regRd(rHRSL) & 0x0f); //analyze transfer result
switch (rcode) {
switch(rcode) {
case hrNAK:
nak_count++;
if (nak_limit && (nak_count == nak_limit))
if(nak_limit && (nak_count == nak_limit))
return (rcode);
break;
case hrTIMEOUT:
retry_count++;
if (retry_count == USB_RETRY_LIMIT)
if(retry_count == USB_RETRY_LIMIT)
return (rcode);
break;
default:
@ -434,13 +434,13 @@ void USB::Task(void) //USB state machine
tmpdata = getVbusState();
/* modify USB task state if Vbus changed */
switch (tmpdata) {
switch(tmpdata) {
case SE1: //illegal state
usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
lowspeed = false;
break;
case SE0: //disconnected
if ((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED)
if((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED)
usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
lowspeed = false;
break;
@ -449,23 +449,23 @@ void USB::Task(void) //USB state machine
lowspeed = true;
//intentional fallthrough
case FSHOST: //attached
if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
if((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
delay = millis() + USB_SETTLE_DELAY;
usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
}
break;
}// switch( tmpdata
for (uint8_t i = 0; i < USB_NUMDEVICES; i++)
if (devConfig[i])
for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
if(devConfig[i])
rcode = devConfig[i]->Poll();
switch (usb_task_state) {
switch(usb_task_state) {
case USB_DETACHED_SUBSTATE_INITIALIZE:
init();
for (uint8_t i = 0; i < USB_NUMDEVICES; i++)
if (devConfig[i])
for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
if(devConfig[i])
rcode = devConfig[i]->Release();
usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
@ -475,7 +475,7 @@ void USB::Task(void) //USB state machine
case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
break;
case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device
if (delay < millis())
if(delay < millis())
usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
else break; // don't fall through
case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
@ -483,7 +483,7 @@ void USB::Task(void) //USB state machine
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
break;
case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
if ((regRd(rHCTL) & bmBUSRST) == 0) {
if((regRd(rHCTL) & bmBUSRST) == 0) {
tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation
regWr(rMODE, tmpdata);
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
@ -491,7 +491,7 @@ void USB::Task(void) //USB state machine
}
break;
case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
if (regRd(rHIRQ) & bmFRAMEIRQ) {
if(regRd(rHIRQ) & bmFRAMEIRQ) {
//when first SOF received _and_ 20ms has passed we can continue
/*
if (delay < millis()) //20ms passed
@ -502,7 +502,7 @@ void USB::Task(void) //USB state machine
}
break;
case USB_ATTACHED_SUBSTATE_WAIT_RESET:
if (delay < millis()) usb_task_state = USB_STATE_CONFIGURING;
if(delay < millis()) usb_task_state = USB_STATE_CONFIGURING;
else break; // don't fall through
case USB_STATE_CONFIGURING:
@ -511,8 +511,8 @@ void USB::Task(void) //USB state machine
rcode = Configuring(0, 0, lowspeed);
if (rcode) {
if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) {
if(rcode) {
if(rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) {
usb_error = rcode;
usb_task_state = USB_STATE_ERROR;
}
@ -535,10 +535,10 @@ uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
// Get pointer to pseudo device with address 0 assigned
p0 = addrPool.GetUsbDevicePtr(0);
if (!p0)
if(!p0)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p0->epinfo)
if(!p0->epinfo)
return USB_ERROR_EPINFO_IS_NULL;
p0->lowspeed = (lowspeed) ? true : false;
@ -546,12 +546,12 @@ uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
// Allocate new address according to device class
uint8_t bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
@ -559,7 +559,7 @@ uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign new address to the device
rcode = setAddr(0, 0, bAddress);
if (rcode) {
if(rcode) {
addrPool.FreeAddress(bAddress);
bAddress = 0;
return rcode;
@ -573,8 +573,8 @@ uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lo
again:
uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed);
if (rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) {
if (parent == 0) {
if(rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) {
if(parent == 0) {
// Send a bus reset on the root interface.
regWr(rHCTL, bmBUSRST); //issue bus reset
delay(102); // delay 102ms, compensate for clock inaccuracy.
@ -582,22 +582,22 @@ again:
// reset parent port
devConfig[parent]->ResetHubPort(port);
}
} else if (rcode == hrJERR && retries < 3) { // 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);
retries++;
goto again;
} else if (rcode)
} else if(rcode)
return rcode;
rcode = devConfig[driver]->Init(parent, port, lowspeed);
if (rcode == hrJERR && retries < 3) { // 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);
retries++;
goto again;
}
if (rcode) {
if(rcode) {
// Issue a bus reset, because the device may be in a limbo state
if (parent == 0) {
if(parent == 0) {
// Send a bus reset on the root interface.
regWr(rHCTL, bmBUSRST); //issue bus reset
delay(102); // delay 102ms, compensate for clock inaccuracy.
@ -669,7 +669,7 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
AddressPool &addrPool = GetAddressPool();
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p) {
if(!p) {
//printf("Configuring error: USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL\r\n");
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
@ -689,7 +689,7 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
if (rcode) {
if(rcode) {
//printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n");
return rcode;
}
@ -705,30 +705,30 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
uint8_t klass = udd->bDeviceClass;
// Attempt to configure if VID/PID or device class matches with a driver
for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
if (!devConfig[devConfigIndex]) continue; // no driver
if (devConfig[devConfigIndex]->GetAddress()) continue; // consumed
if (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass)) {
for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
if(!devConfig[devConfigIndex]) continue; // no driver
if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed
if(devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass)) {
rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED)
if(rcode != USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED)
break;
}
}
if (devConfigIndex < USB_NUMDEVICES) {
if(devConfigIndex < USB_NUMDEVICES) {
return rcode;
}
// blindly attempt to configure
for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
if (!devConfig[devConfigIndex]) continue;
if (devConfig[devConfigIndex]->GetAddress()) continue; // consumed
if (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass)) continue; // If this is true it means it must have returned USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED above
for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
if(!devConfig[devConfigIndex]) continue;
if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed
if(devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass)) continue; // If this is true it means it must have returned USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED above
rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
//printf("ERROR ENUMERATING %2.2x\r\n", rcode);
if (!(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED || rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE)) {
if(!(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED || rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE)) {
// in case of an error dev_index should be reset to 0
// in order to start from the very beginning the
// next time the program gets here
@ -744,12 +744,12 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
}
uint8_t USB::ReleaseDevice(uint8_t addr) {
if (!addr)
if(!addr)
return 0;
for (uint8_t i = 0; i < USB_NUMDEVICES; i++) {
if (!devConfig[i]) continue;
if (devConfig[i]->GetAddress() == addr)
for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
if(!devConfig[i]) continue;
if(devConfig[i]->GetAddress() == addr)
return devConfig[i]->Release();
}
return 0;
@ -776,7 +776,7 @@ uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser
uint8_t ret = getConfDescr(addr, ep, 9, conf, buf);
if (ret)
if(ret)
return ret;
uint16_t total = ucd->wTotalLength;
@ -807,4 +807,3 @@ uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) {
}
#endif // defined(USB_METHODS_INLINE)

View file

@ -104,14 +104,38 @@ typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega
class USBDeviceConfig {
public:
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed) { return 0; }
virtual uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {return 0; }
virtual uint8_t Release() { return 0; }
virtual uint8_t Poll() { return 0; }
virtual uint8_t GetAddress() { return 0; }
virtual void ResetHubPort(uint8_t port) { return; } // Note used for hubs only!
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) { return false; }
virtual boolean DEVCLASSOK(uint8_t klass) { return false; }
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed) {
return 0;
}
virtual uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
return 0;
}
virtual uint8_t Release() {
return 0;
}
virtual uint8_t Poll() {
return 0;
}
virtual uint8_t GetAddress() {
return 0;
}
virtual void ResetHubPort(uint8_t port) {
return;
} // Note used for hubs only!
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) {
return false;
}
virtual boolean DEVCLASSOK(uint8_t klass) {
return false;
}
};
/* USB Setup Packet Structure */
@ -138,7 +162,7 @@ typedef struct {
} wVal_u;
uint16_t wIndex; // 4 Depends on bRequest
uint16_t wLength; // 6 Depends on bRequest
}__attribute__((packed)) SETUP_PKT, *PSETUP_PKT;
} __attribute__((packed)) SETUP_PKT, *PSETUP_PKT;
@ -166,7 +190,7 @@ public:
};
AddressPool& GetAddressPool() {
return(AddressPool&) addrPool;
return (AddressPool&)addrPool;
};
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev) {
@ -225,30 +249,29 @@ private:
//get device descriptor
inline uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) {
return( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr));
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr));
}
//get configuration descriptor
inline uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
return( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr));
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr));
}
//get string descriptor
inline uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t nuint8_ts, uint8_t index, uint16_t langid, uint8_t* dataptr) {
return( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr));
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr));
}
//set address
inline uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) {
return( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL));
return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL));
}
//set configuration
inline uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) {
return( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL));
return ( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL));
}
#endif // defined(USB_METHODS_INLINE)
#endif /* USBCORE_H */

281
Wii.cpp
View file

@ -84,7 +84,7 @@ const uint32_t PROCONTROLLERBUTTONS[] PROGMEM = {
WII::WII(BTD *p, bool pair) :
pBtd(p) // pointer to USB class instance - mandatory
{
if (pBtd)
if(pBtd)
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
pBtd->pairWithWii = pair;
@ -115,8 +115,8 @@ void WII::Reset() {
}
void WII::disconnect() { // Use this void to disconnect any of the controllers
if (!motionPlusInside) { // The old Wiimote needs a delay after the first command or it will automatically reconnect
if (motionPlusConnected) {
if(!motionPlusInside) { // The old Wiimote needs a delay after the first command or it will automatically reconnect
if(motionPlusConnected) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nDeactivating Motion Plus"), 0x80);
#endif
@ -132,9 +132,9 @@ void WII::disconnect() { // Use this void to disconnect any of the controllers
}
void WII::ACLData(uint8_t* l2capinbuf) {
if (!pBtd->l2capConnectionClaimed && pBtd->incomingWii && !wiimoteConnected && !activeConnection) {
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
if(!pBtd->l2capConnectionClaimed && pBtd->incomingWii && !wiimoteConnected && !activeConnection) {
if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
motionPlusInside = pBtd->motionPlusInside;
pBtd->incomingWii = false;
pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service
@ -144,9 +144,9 @@ void WII::ACLData(uint8_t* l2capinbuf) {
}
}
}
if ((l2capinbuf[0] | (uint16_t)l2capinbuf[1] << 8) == (hci_handle | 0x2000U)) { // acl_handle_ok or it's a new connection
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
if((l2capinbuf[0] | (uint16_t)l2capinbuf[1] << 8) == (hci_handle | 0x2000U)) { // acl_handle_ok or it's a new connection
if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
@ -161,15 +161,15 @@ void WII::ACLData(uint8_t* l2capinbuf) {
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]) {
} 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_set_flag(L2CAP_FLAG_CONTROL_CONNECTED);
} else if (l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) {
} 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];
@ -177,7 +177,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
l2cap_set_flag(L2CAP_FLAG_INTERRUPT_CONNECTED);
}
}
} else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
} 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);
@ -190,46 +190,46 @@ void WII::ACLData(uint8_t* l2capinbuf) {
Notify(PSTR(" Identifier: "), 0x80);
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
#endif
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
identifier = l2capinbuf[9];
control_scid[0] = l2capinbuf[14];
control_scid[1] = l2capinbuf[15];
l2cap_set_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST);
} else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) {
} else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) {
identifier = l2capinbuf[9];
interrupt_scid[0] = l2capinbuf[14];
interrupt_scid[1] = l2capinbuf[15];
l2cap_set_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]) {
} 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_set_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS);
} else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
} else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
//Notify(PSTR("\r\nHID Interrupt Configuration Complete"), 0x80);
identifier = l2capinbuf[9];
l2cap_set_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]) {
} 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]) {
} 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]) {
} 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]) {
} 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
@ -237,12 +237,12 @@ void WII::ACLData(uint8_t* l2capinbuf) {
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]) {
} 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_set_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE);
} else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
} else if(l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
//Notify(PSTR("\r\nDisconnect Response: Interrupt Channel"), 0x80);
identifier = l2capinbuf[9];
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE);
@ -255,41 +255,41 @@ void WII::ACLData(uint8_t* l2capinbuf) {
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
}
#endif
} else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt
} else if(l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt
//Notify(PSTR("\r\nL2CAP Interrupt"), 0x80);
if (l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
if ((l2capinbuf[9] >= 0x20 && l2capinbuf[9] <= 0x22) || (l2capinbuf[9] >= 0x30 && l2capinbuf[9] <= 0x37) || l2capinbuf[9] == 0x3e || l2capinbuf[9] == 0x3f) { // These reports include the buttons
if ((l2capinbuf[9] >= 0x20 && l2capinbuf[9] <= 0x22) || l2capinbuf[9] == 0x31 || l2capinbuf[9] == 0x33) // These reports have no extensions bytes
if(l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
if((l2capinbuf[9] >= 0x20 && l2capinbuf[9] <= 0x22) || (l2capinbuf[9] >= 0x30 && l2capinbuf[9] <= 0x37) || l2capinbuf[9] == 0x3e || l2capinbuf[9] == 0x3f) { // These reports include the buttons
if((l2capinbuf[9] >= 0x20 && l2capinbuf[9] <= 0x22) || l2capinbuf[9] == 0x31 || l2capinbuf[9] == 0x33) // These reports have no extensions bytes
ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8));
else if (wiiUProControllerConnected)
else if(wiiUProControllerConnected)
ButtonState = (uint32_t)(((~l2capinbuf[23]) & 0xFE) | ((uint16_t)(~l2capinbuf[24]) << 8) | ((uint32_t)((~l2capinbuf[25]) & 0x03) << 16));
else if (motionPlusConnected) {
if (l2capinbuf[20] & 0x02) // Only update the wiimote buttons, since the extension bytes are from the Motion Plus
else if(motionPlusConnected) {
if(l2capinbuf[20] & 0x02) // Only update the wiimote buttons, since the extension bytes are from the Motion Plus
ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)(ButtonState & 0xFFFF0000)));
else if (nunchuckConnected) // Update if it's a report from the Nunchuck
else if(nunchuckConnected) // Update if it's a report from the Nunchuck
ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)((~l2capinbuf[20]) & 0x0C) << 14));
//else if(classicControllerConnected) // Update if it's a report from the Classic Controller
} else if (nunchuckConnected) // The Nunchuck is directly connected
} else if(nunchuckConnected) // The Nunchuck is directly connected
ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)((~l2capinbuf[20]) & 0x03) << 16));
//else if(classicControllerConnected) // The Classic Controller is directly connected
else if (!unknownExtensionConnected)
else if(!unknownExtensionConnected)
ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8));
#ifdef PRINTREPORT
Notify(PSTR("ButtonState: "), 0x80);
D_PrintHex<uint32_t > (ButtonState, 0x80);
Notify(PSTR("\r\n"), 0x80);
#endif
if (ButtonState != OldButtonState) {
if(ButtonState != OldButtonState) {
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
OldButtonState = ButtonState;
}
}
if (l2capinbuf[9] == 0x31 || l2capinbuf[9] == 0x33 || l2capinbuf[9] == 0x35 || l2capinbuf[9] == 0x37) { // Read the accelerometer
if(l2capinbuf[9] == 0x31 || l2capinbuf[9] == 0x33 || l2capinbuf[9] == 0x35 || l2capinbuf[9] == 0x37) { // Read the accelerometer
accXwiimote = ((l2capinbuf[12] << 2) | (l2capinbuf[10] & 0x60 >> 5)) - 500;
accYwiimote = ((l2capinbuf[13] << 2) | (l2capinbuf[11] & 0x20 >> 4)) - 500;
accZwiimote = ((l2capinbuf[14] << 2) | (l2capinbuf[11] & 0x40 >> 5)) - 500;
}
switch (l2capinbuf[9]) {
switch(l2capinbuf[9]) {
case 0x20: // Status Information - (a1) 20 BB BB LF 00 00 VV
#ifdef EXTRADEBUG
Notify(PSTR("\r\nStatus report was received"), 0x80);
@ -297,33 +297,33 @@ void WII::ACLData(uint8_t* l2capinbuf) {
wiiState = l2capinbuf[12]; // (0x01: Battery is nearly empty), (0x02: An Extension Controller is connected), (0x04: Speaker enabled), (0x08: IR enabled), (0x10: LED1, 0x20: LED2, 0x40: LED3, 0x80: LED4)
batteryLevel = l2capinbuf[15]; // Update battery level
#ifdef DEBUG_USB_HOST
if (l2capinbuf[12] & 0x01)
if(l2capinbuf[12] & 0x01)
Notify(PSTR("\r\nWARNING: Battery is nearly empty"), 0x80);
#endif
if (checkExtension) { // If this is false it means that the user must have called getBatteryLevel()
if (l2capinbuf[12] & 0x02) { // Check if a extension is connected
if(checkExtension) { // If this is false it means that the user must have called getBatteryLevel()
if(l2capinbuf[12] & 0x02) { // Check if a extension is connected
#ifdef DEBUG_USB_HOST
if (!unknownExtensionConnected)
if(!unknownExtensionConnected)
Notify(PSTR("\r\nExtension connected"), 0x80);
#endif
unknownExtensionConnected = true;
#ifdef WIICAMERA
if (!isIRCameraEnabled()) // Don't activate the Motion Plus if we are trying to initialize the IR camera
if(!isIRCameraEnabled()) // Don't activate the Motion Plus if we are trying to initialize the IR camera
#endif
setReportMode(false, 0x35); // Also read the extension
setReportMode(false, 0x35); // Also read the extension
} else {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nExtension disconnected"), 0x80);
#endif
if (motionPlusConnected) {
if(motionPlusConnected) {
#ifdef DEBUG_USB_HOST
Notify(PSTR(" - from Motion Plus"), 0x80);
#endif
wii_clear_flag(WII_FLAG_NUNCHUCK_CONNECTED);
if (!activateNunchuck) // If it's already trying to initialize the Nunchuck don't set it to false
if(!activateNunchuck) // If it's already trying to initialize the Nunchuck don't set it to false
nunchuckConnected = false;
//else if(classicControllerConnected)
} else if (nunchuckConnected) {
} else if(nunchuckConnected) {
#ifdef DEBUG_USB_HOST
Notify(PSTR(" - Nunchuck"), 0x80);
#endif
@ -338,28 +338,28 @@ void WII::ACLData(uint8_t* l2capinbuf) {
checkExtension = true; // Check for extensions by default
break;
case 0x21: // Read Memory Data
if ((l2capinbuf[12] & 0x0F) == 0) { // No error
if((l2capinbuf[12] & 0x0F) == 0) { // No error
// See: http://wiibrew.org/wiki/Wiimote/Extension_Controllers
if (l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x00) {
if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x00) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nNunchuck connected"), 0x80);
#endif
wii_set_flag(WII_FLAG_NUNCHUCK_CONNECTED);
} else if (l2capinbuf[16] == 0x00 && (l2capinbuf[17] == 0xA6 || l2capinbuf[17] == 0xA4) && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x05) {
} else if(l2capinbuf[16] == 0x00 && (l2capinbuf[17] == 0xA6 || l2capinbuf[17] == 0xA4) && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x05) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nMotion Plus connected"), 0x80);
#endif
wii_set_flag(WII_FLAG_MOTION_PLUS_CONNECTED);
} else if (l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x04 && l2capinbuf[20] == 0x05) {
} else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x04 && l2capinbuf[20] == 0x05) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nMotion Plus activated in normal mode"), 0x80);
#endif
motionPlusConnected = true;
#ifdef WIICAMERA
if (!isIRCameraEnabled()) // Don't activate the Motion Plus if we are trying to initialize the IR camera
if(!isIRCameraEnabled()) // Don't activate the Motion Plus if we are trying to initialize the IR camera
#endif
setReportMode(false, 0x35); // Also read the extension
} else if (l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x05 && l2capinbuf[20] == 0x05) {
} else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x05 && l2capinbuf[20] == 0x05) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nMotion Plus activated in Nunchuck pass-through mode"), 0x80);
#endif
@ -367,16 +367,16 @@ void WII::ACLData(uint8_t* l2capinbuf) {
motionPlusConnected = true;
nunchuckConnected = true;
#ifdef WIICAMERA
if (!isIRCameraEnabled()) // Don't activate the Motion Plus if we are trying to initialize the IR camera
if(!isIRCameraEnabled()) // Don't activate the Motion Plus if we are trying to initialize the IR camera
#endif
setReportMode(false, 0x35); // Also read the extension
} else if (l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA6 && l2capinbuf[18] == 0x20 && (l2capinbuf[19] == 0x00 || l2capinbuf[19] == 0x04 || l2capinbuf[19] == 0x05 || l2capinbuf[19] == 0x07) && l2capinbuf[20] == 0x05) {
} else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA6 && l2capinbuf[18] == 0x20 && (l2capinbuf[19] == 0x00 || l2capinbuf[19] == 0x04 || l2capinbuf[19] == 0x05 || l2capinbuf[19] == 0x07) && l2capinbuf[20] == 0x05) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nInactive Wii Motion Plus"), 0x80);
Notify(PSTR("\r\nPlease unplug the Motion Plus, disconnect the Wiimote and then replug the Motion Plus Extension"), 0x80);
#endif
stateCounter = 300; // Skip the rest in "WII_CHECK_MOTION_PLUS_STATE"
} else if (l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x01 && l2capinbuf[20] == 0x20) {
} else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x01 && l2capinbuf[20] == 0x20) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nWii U Pro Controller connected"), 0x80);
#endif
@ -388,7 +388,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
Notify(PSTR("\r\nData: "), 0x80);
for (uint8_t i = 0; i < ((l2capinbuf[12] >> 4) + 1); i++) { // bit 4-7 is the length-1
for(uint8_t i = 0; i < ((l2capinbuf[12] >> 4) + 1); i++) { // bit 4-7 is the length-1
D_PrintHex<uint8_t > (l2capinbuf[15 + i], 0x80);
Notify(PSTR(" "), 0x80);
}
@ -405,7 +405,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
break;
case 0x22: // Acknowledge output report, return function result
#ifdef DEBUG_USB_HOST
if (l2capinbuf[13] != 0x00) { // Check if there is an error
if(l2capinbuf[13] != 0x00) { // Check if there is an error
Notify(PSTR("\r\nCommand failed: "), 0x80);
D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
}
@ -461,9 +461,9 @@ void WII::ACLData(uint8_t* l2capinbuf) {
break;
case 0x35: // Core Buttons and Accelerometer with 16 Extension Bytes
// (a1) 35 BB BB AA AA AA EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
if (motionPlusConnected) {
if (l2capinbuf[20] & 0x02) { // Check if it's a report from the Motion controller or the extension
if (motionValuesReset) { // We will only use the values when the gyro value has been set
if(motionPlusConnected) {
if(l2capinbuf[20] & 0x02) { // Check if it's a report from the Motion controller or the extension
if(motionValuesReset) { // We will only use the values when the gyro value has been set
gyroYawRaw = ((l2capinbuf[15] | ((l2capinbuf[18] & 0xFC) << 6)) - gyroYawZero);
gyroRollRaw = ((l2capinbuf[16] | ((l2capinbuf[19] & 0xFC) << 6)) - gyroRollZero);
gyroPitchRaw = ((l2capinbuf[17] | ((l2capinbuf[20] & 0xFC) << 6)) - gyroPitchZero);
@ -473,11 +473,11 @@ void WII::ACLData(uint8_t* l2capinbuf) {
pitchGyroSpeed = (double)gyroPitchRaw / ((double)gyroPitchZero / pitchGyroScale);
/* The onboard gyro has two ranges for slow and fast mode */
if (!(l2capinbuf[18] & 0x02)) // Check if fast mode is used
if(!(l2capinbuf[18] & 0x02)) // Check if fast mode is used
yawGyroSpeed *= 4.545;
if (!(l2capinbuf[18] & 0x01)) // Check if fast mode is used
if(!(l2capinbuf[18] & 0x01)) // Check if fast mode is used
pitchGyroSpeed *= 4.545;
if (!(l2capinbuf[19] & 0x02)) // Check if fast mode is used
if(!(l2capinbuf[19] & 0x02)) // Check if fast mode is used
rollGyroSpeed *= 4.545;
compPitch = (0.93 * (compPitch + (pitchGyroSpeed * (double)(micros() - timer) / 1000000)))+(0.07 * getWiimotePitch()); // Use a complimentary filter to calculate the angle
@ -495,15 +495,15 @@ void WII::ACLData(uint8_t* l2capinbuf) {
Notify(gyroRoll, 0x80);
Notify(PSTR("\tgyroPitch: "), 0x80);
Notify(gyroPitch, 0x80);
*/
*/
/*
Notify(PSTR("\twiimoteRoll: "), 0x80);
Notify(wiimoteRoll, 0x80);
Notify(PSTR("\twiimotePitch: "), 0x80);
Notify(wiimotePitch, 0x80);
*/
*/
} else {
if ((micros() - timer) > 1000000) { // Loop for 1 sec before resetting the values
if((micros() - timer) > 1000000) { // Loop for 1 sec before resetting the values
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nThe gyro values has been reset"), 0x80);
#endif
@ -524,7 +524,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
}
}
} else {
if (nunchuckConnected) {
if(nunchuckConnected) {
hatValues[HatX] = l2capinbuf[15];
hatValues[HatY] = l2capinbuf[16];
accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x10 >> 3)) - 416;
@ -533,8 +533,8 @@ void WII::ACLData(uint8_t* l2capinbuf) {
}
//else if(classicControllerConnected) { }
}
if (l2capinbuf[19] & 0x01) {
if (!extensionConnected) {
if(l2capinbuf[19] & 0x01) {
if(!extensionConnected) {
extensionConnected = true;
unknownExtensionConnected = true;
#ifdef DEBUG_USB_HOST
@ -542,7 +542,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
#endif
}
} else {
if (extensionConnected && !unknownExtensionConnected) {
if(extensionConnected && !unknownExtensionConnected) {
extensionConnected = false;
unknownExtensionConnected = true;
#ifdef DEBUG_USB_HOST
@ -552,13 +552,13 @@ void WII::ACLData(uint8_t* l2capinbuf) {
}
}
} else if (nunchuckConnected) {
} else if(nunchuckConnected) {
hatValues[HatX] = l2capinbuf[15];
hatValues[HatY] = l2capinbuf[16];
accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x0C >> 2)) - 416;
accYnunchuck = ((l2capinbuf[18] << 2) | (l2capinbuf[20] & 0x30 >> 4)) - 416;
accZnunchuck = ((l2capinbuf[19] << 2) | (l2capinbuf[20] & 0xC0 >> 6)) - 416;
} else if (wiiUProControllerConnected) {
} else if(wiiUProControllerConnected) {
hatValues[LeftHatX] = (l2capinbuf[15] | l2capinbuf[16] << 8);
hatValues[RightHatX] = (l2capinbuf[17] | l2capinbuf[18] << 8);
hatValues[LeftHatY] = (l2capinbuf[19] | l2capinbuf[20] << 8);
@ -579,10 +579,10 @@ void WII::ACLData(uint8_t* l2capinbuf) {
}
void WII::L2CAP_task() {
switch (l2cap_state) {
switch(l2cap_state) {
/* These states are used if the Wiimote is the host */
case L2CAP_CONTROL_SUCCESS:
if (l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
if(l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
#endif
@ -591,7 +591,7 @@ void WII::L2CAP_task() {
break;
case L2CAP_INTERRUPT_SETUP:
if (l2cap_check_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST)) {
if(l2cap_check_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
#endif
@ -608,7 +608,7 @@ void WII::L2CAP_task() {
/* These states are used if the Arduino is the host */
case L2CAP_CONTROL_CONNECT_REQUEST:
if (l2cap_check_flag(L2CAP_FLAG_CONTROL_CONNECTED)) {
if(l2cap_check_flag(L2CAP_FLAG_CONTROL_CONNECTED)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nSend HID Control Config Request"), 0x80);
#endif
@ -619,7 +619,7 @@ void WII::L2CAP_task() {
break;
case L2CAP_CONTROL_CONFIG_REQUEST:
if (l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
if(l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nSend HID Interrupt Connection Request"), 0x80);
#endif
@ -630,7 +630,7 @@ void WII::L2CAP_task() {
break;
case L2CAP_INTERRUPT_CONNECT_REQUEST:
if (l2cap_check_flag(L2CAP_FLAG_INTERRUPT_CONNECTED)) {
if(l2cap_check_flag(L2CAP_FLAG_INTERRUPT_CONNECTED)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nSend HID Interrupt Config Request"), 0x80);
#endif
@ -641,7 +641,7 @@ void WII::L2CAP_task() {
break;
case L2CAP_INTERRUPT_CONFIG_REQUEST:
if (l2cap_check_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)) { // Now the HID channels is established
if(l2cap_check_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)) { // Now the HID channels is established
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHID Channels Established"), 0x80);
#endif
@ -655,7 +655,7 @@ void WII::L2CAP_task() {
/* The next states are in run() */
case L2CAP_INTERRUPT_DISCONNECT:
if (l2cap_check_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE) && millis() > timer) {
if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE) && millis() > timer) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80);
#endif
@ -666,7 +666,7 @@ void WII::L2CAP_task() {
break;
case L2CAP_CONTROL_DISCONNECT:
if (l2cap_check_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)) {
if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nDisconnected Control Channel"), 0x80);
#endif
@ -680,12 +680,12 @@ void WII::L2CAP_task() {
}
void WII::Run() {
if (l2cap_state == L2CAP_INTERRUPT_DISCONNECT && millis() > timer)
if(l2cap_state == L2CAP_INTERRUPT_DISCONNECT && millis() > timer)
L2CAP_task(); // Call the rest of the disconnection routine after we have waited long enough
switch (l2cap_state) {
switch(l2cap_state) {
case L2CAP_WAIT:
if (pBtd->connectToWii && !pBtd->l2capConnectionClaimed && !wiimoteConnected && !activeConnection) {
if(pBtd->connectToWii && !pBtd->l2capConnectionClaimed && !wiimoteConnected && !activeConnection) {
pBtd->l2capConnectionClaimed = true;
activeConnection = true;
motionPlusInside = pBtd->motionPlusInside;
@ -697,7 +697,7 @@ void WII::Run() {
identifier = 0;
pBtd->l2cap_connection_request(hci_handle, identifier, control_dcid, HID_CTRL_PSM);
l2cap_state = L2CAP_CONTROL_CONNECT_REQUEST;
} else if (l2cap_check_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST)) {
} else if(l2cap_check_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80);
#endif
@ -713,25 +713,25 @@ void WII::Run() {
case WII_CHECK_MOTION_PLUS_STATE:
#ifdef DEBUG_USB_HOST
if (stateCounter == 0) // Only print onnce
if(stateCounter == 0) // Only print onnce
Notify(PSTR("\r\nChecking if a Motion Plus is connected"), 0x80);
#endif
stateCounter++;
if (stateCounter % 200 == 0)
if(stateCounter % 200 == 0)
checkMotionPresent(); // Check if there is a motion plus connected
if (wii_check_flag(WII_FLAG_MOTION_PLUS_CONNECTED)) {
if(wii_check_flag(WII_FLAG_MOTION_PLUS_CONNECTED)) {
stateCounter = 0;
l2cap_state = WII_INIT_MOTION_PLUS_STATE;
timer = micros();
if (unknownExtensionConnected) {
if(unknownExtensionConnected) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nA extension is also connected"), 0x80);
#endif
activateNunchuck = true; // For we will just set this to true as this the only extension supported so far
}
} else if (stateCounter == 601) { // We will try three times to check for the motion plus
} else if(stateCounter == 601) { // We will try three times to check for the motion plus
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nNo Motion Plus was detected"), 0x80);
#endif
@ -742,23 +742,23 @@ void WII::Run() {
case WII_CHECK_EXTENSION_STATE: // This is used to check if there is anything plugged in to the extension port
#ifdef DEBUG_USB_HOST
if (stateCounter == 0) // Only print onnce
if(stateCounter == 0) // Only print onnce
Notify(PSTR("\r\nChecking if there is any extension connected"), 0x80);
#endif
stateCounter++; // We use this counter as there has to be a short delay between the commands
if (stateCounter == 1)
if(stateCounter == 1)
statusRequest(); // See if a new device has connected
if (stateCounter == 100) {
if (unknownExtensionConnected) // Check if there is a extension is connected to the port
if(stateCounter == 100) {
if(unknownExtensionConnected) // Check if there is a extension is connected to the port
initExtension1();
else
stateCounter = 399;
} else if (stateCounter == 200)
} else if(stateCounter == 200)
initExtension2();
else if (stateCounter == 300) {
else if(stateCounter == 300) {
readExtensionType();
unknownExtensionConnected = false;
} else if (stateCounter == 400) {
} else if(stateCounter == 400) {
stateCounter = 0;
l2cap_state = TURN_ON_LED;
}
@ -766,13 +766,13 @@ void WII::Run() {
case WII_INIT_MOTION_PLUS_STATE:
stateCounter++;
if (stateCounter == 1)
if(stateCounter == 1)
initMotionPlus();
else if (stateCounter == 100)
else if(stateCounter == 100)
activateMotionPlus();
else if (stateCounter == 200)
else if(stateCounter == 200)
readExtensionType(); // Check if it has been activated
else if (stateCounter == 300) {
else if(stateCounter == 300) {
stateCounter = 0;
unknownExtensionConnected = false; // The motion plus will send a status report when it's activated, we will set this to false so it doesn't reinitialize the Motion Plus
l2cap_state = TURN_ON_LED;
@ -780,7 +780,7 @@ void WII::Run() {
break;
case TURN_ON_LED:
if (wii_check_flag(WII_FLAG_NUNCHUCK_CONNECTED))
if(wii_check_flag(WII_FLAG_NUNCHUCK_CONNECTED))
nunchuckConnected = true;
wiimoteConnected = true;
onInit();
@ -788,46 +788,46 @@ void WII::Run() {
break;
case L2CAP_DONE:
if (unknownExtensionConnected) {
if(unknownExtensionConnected) {
#ifdef DEBUG_USB_HOST
if (stateCounter == 0) // Only print once
if(stateCounter == 0) // Only print once
Notify(PSTR("\r\nChecking extension port"), 0x80);
#endif
stateCounter++; // We will use this counter as there has to be a short delay between the commands
if (stateCounter == 50)
if(stateCounter == 50)
statusRequest();
else if (stateCounter == 100)
else if(stateCounter == 100)
initExtension1();
else if (stateCounter == 150)
if ((extensionConnected && motionPlusConnected) || (unknownExtensionConnected && !motionPlusConnected))
else if(stateCounter == 150)
if((extensionConnected && motionPlusConnected) || (unknownExtensionConnected && !motionPlusConnected))
initExtension2();
else
stateCounter = 299; // There is no extension connected
else if (stateCounter == 200)
else if(stateCounter == 200)
readExtensionType();
else if (stateCounter == 250) {
if (wii_check_flag(WII_FLAG_NUNCHUCK_CONNECTED)) {
else if(stateCounter == 250) {
if(wii_check_flag(WII_FLAG_NUNCHUCK_CONNECTED)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nNunchuck was reconnected"), 0x80);
#endif
activateNunchuck = true;
nunchuckConnected = true;
}
if (!motionPlusConnected)
if(!motionPlusConnected)
stateCounter = 449;
} else if (stateCounter == 300) {
if (motionPlusConnected) {
} else if(stateCounter == 300) {
if(motionPlusConnected) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nReactivating the Motion Plus"), 0x80);
#endif
initMotionPlus();
} else
stateCounter = 449;
} else if (stateCounter == 350)
} else if(stateCounter == 350)
activateMotionPlus();
else if (stateCounter == 400)
else if(stateCounter == 400)
readExtensionType(); // Check if it has been activated
else if (stateCounter == 450) {
else if(stateCounter == 450) {
onInit();
stateCounter = 0;
unknownExtensionConnected = false;
@ -843,7 +843,7 @@ void WII::Run() {
/************************************************************/
void WII::HID_Command(uint8_t* data, uint8_t nbytes) {
if (motionPlusInside)
if(motionPlusInside)
pBtd->L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]); // It's the new wiimote with the Motion Plus Inside
else
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
@ -878,6 +878,7 @@ void WII::setLedRaw(uint8_t value) {
HIDBuffer[2] = value | (HIDBuffer[2] & 0x01); // Keep the rumble bit
HID_Command(HIDBuffer, 3);
}
void WII::setLedOff(LED a) {
HIDBuffer[1] = 0x11;
HIDBuffer[2] &= ~(pgm_read_byte(&LEDS[(uint8_t)a]));
@ -899,11 +900,11 @@ void WII::setLedToggle(LED a) {
void WII::setLedStatus() {
HIDBuffer[1] = 0x11;
HIDBuffer[2] = (HIDBuffer[2] & 0x01); // Keep the rumble bit
if (wiimoteConnected)
if(wiimoteConnected)
HIDBuffer[2] |= 0x10; // If it's connected LED1 will light up
if (motionPlusConnected)
if(motionPlusConnected)
HIDBuffer[2] |= 0x20; // If it's connected LED2 will light up
if (nunchuckConnected)
if(nunchuckConnected)
HIDBuffer[2] |= 0x40; // If it's connected LED3 will light up
HID_Command(HIDBuffer, 3);
@ -919,7 +920,7 @@ void WII::setReportMode(bool continuous, uint8_t mode) {
uint8_t cmd_buf[4];
cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
cmd_buf[1] = 0x12;
if (continuous)
if(continuous)
cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01); // Keep the rumble bit
else
cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01); // Keep the rumble bit
@ -949,9 +950,9 @@ void WII::writeData(uint32_t offset, uint8_t size, uint8_t* data) {
cmd_buf[5] = (uint8_t)(offset & 0xFF);
cmd_buf[6] = size;
uint8_t i = 0;
for (; i < size; i++)
for(; i < size; i++)
cmd_buf[7 + i] = data[i];
for (; i < 16; i++) // Set the rest to zero
for(; i < 16; i++) // Set the rest to zero
cmd_buf[7 + i] = 0x00;
HID_Command(cmd_buf, 23);
}
@ -976,17 +977,17 @@ void WII::initMotionPlus() {
void WII::activateMotionPlus() {
uint8_t buf[1];
if (pBtd->wiiUProController) {
if(pBtd->wiiUProController) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nActivating Wii U Pro Controller"), 0x80);
#endif
buf[0] = 0x00; // It seems like you can send anything but 0x04, 0x05, and 0x07
} else if (activateNunchuck) {
} else if(activateNunchuck) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nActivating Motion Plus in pass-through mode"), 0x80);
#endif
buf[0] = 0x05; // Activate nunchuck pass-through mode
} //else if(classicControllerConnected && extensionConnected)
}//else if(classicControllerConnected && extensionConnected)
//buf[0] = 0x07;
else {
#ifdef DEBUG_USB_HOST
@ -1001,7 +1002,7 @@ void WII::readData(uint32_t offset, uint16_t size, bool EEPROM) {
uint8_t cmd_buf[8];
cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
cmd_buf[1] = 0x17; // Read data
if (EEPROM)
if(EEPROM)
cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01); // Read from EEPROM
else
cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01); // Read from memory
@ -1032,7 +1033,7 @@ void WII::checkMotionPresent() {
/************************************************************/
bool WII::getButtonPress(Button b) { // Return true when a button is pressed
if (wiiUProControllerConnected)
if(wiiUProControllerConnected)
return (ButtonState & pgm_read_dword(&PROCONTROLLERBUTTONS[(uint8_t)b]));
else
return (ButtonState & pgm_read_dword(&BUTTONS[(uint8_t)b]));
@ -1040,7 +1041,7 @@ bool WII::getButtonPress(Button b) { // Return true when a button is pressed
bool WII::getButtonClick(Button b) { // Only return true when a button is clicked
uint32_t button;
if (wiiUProControllerConnected)
if(wiiUProControllerConnected)
button = pgm_read_dword(&PROCONTROLLERBUTTONS[(uint8_t)b]);
else
button = pgm_read_dword(&BUTTONS[(uint8_t)b]);
@ -1050,11 +1051,11 @@ bool WII::getButtonClick(Button b) { // Only return true when a button is clicke
}
uint8_t WII::getAnalogHat(Hat a) {
if (!nunchuckConnected)
if(!nunchuckConnected)
return 127; // Return center position
else {
uint8_t output = hatValues[(uint8_t)a];
if (output == 0xFF || output == 0x00) // The joystick will only read 255 or 0 when the cable is unplugged or initializing, so we will just return the center position
if(output == 0xFF || output == 0x00) // The joystick will only read 255 or 0 when the cable is unplugged or initializing, so we will just return the center position
return 127;
else
return output;
@ -1062,11 +1063,11 @@ uint8_t WII::getAnalogHat(Hat a) {
}
uint16_t WII::getAnalogHat(AnalogHat a) {
if (!wiiUProControllerConnected)
if(!wiiUProControllerConnected)
return 2000;
else {
uint16_t output = hatValues[(uint8_t)a];
if (output == 0x00) // The joystick will only read 0 when it is first initializing, so we will just return the center position
if(output == 0x00) // The joystick will only read 0 when it is first initializing, so we will just return the center position
return 2000;
else
return output;
@ -1074,7 +1075,7 @@ uint16_t WII::getAnalogHat(AnalogHat a) {
}
void WII::onInit() {
if (pFuncOnInit)
if(pFuncOnInit)
pFuncOnInit(); // Call the user function
else
setLedStatus();

15
Wii.h
View file

@ -85,6 +85,7 @@ public:
/**@}*/
/** @name Wii Controller functions */
/** Call this to start the paring sequence with a controller */
void pair(void) {
if(pBtd)
@ -108,7 +109,7 @@ public:
* @return Pitch in the range from 0-360.
*/
double getPitch() {
if (motionPlusConnected)
if(motionPlusConnected)
return compPitch;
return getWiimotePitch();
};
@ -118,7 +119,7 @@ public:
* @return Roll in the range from 0-360.
*/
double getRoll() {
if (motionPlusConnected)
if(motionPlusConnected)
return compRoll;
return getWiimoteRoll();
};
@ -147,6 +148,7 @@ public:
* @param value See: ::LED enum.
*/
void setLedRaw(uint8_t value);
/** Turn all LEDs off. */
void setLedOff() {
setLedRaw(0);
@ -180,6 +182,7 @@ public:
* @return The battery level in the range 0-255.
*/
uint8_t getBatteryLevel();
/**
* Return the Wiimote state.
* @return See: http://wiibrew.org/wiki/Wiimote#0x20:_Status.
@ -211,20 +214,24 @@ public:
/* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */
/**@{*/
/** Pitch and roll calculated from the accelerometer inside the Wiimote. */
double getWiimotePitch() {
return (atan2(accYwiimote, accZwiimote) + PI) * RAD_TO_DEG;
};
double getWiimoteRoll() {
return (atan2(accXwiimote, accZwiimote) + PI) * RAD_TO_DEG;
};
/**@}*/
/**@{*/
/** Pitch and roll calculated from the accelerometer inside the Nunchuck. */
double getNunchuckPitch() {
return (atan2(accYnunchuck, accZnunchuck) + PI) * RAD_TO_DEG;
};
double getNunchuckRoll() {
return (atan2(accXnunchuck, accZnunchuck) + PI) * RAD_TO_DEG;
};
@ -381,7 +388,7 @@ public:
* @return True if it's enabled, false if not.
*/
bool isIRCameraEnabled() {
return(wiiState & 0x08);
return (wiiState & 0x08);
};
/**@}*/
#endif
@ -479,4 +486,4 @@ private:
uint8_t IR_object_s4;
#endif
};
#endif
#endif

View file

@ -48,14 +48,14 @@ XBOXOLD::XBOXOLD(USB *p) :
pUsb(p), // pointer to USB class instance - mandatory
bAddress(0), // device address - mandatory
bPollEnable(false) { // don't start polling before dongle is connected
for (uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
for(uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
}
if (pUsb) // register in USB subsystem
if(pUsb) // register in USB subsystem
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
}
@ -74,7 +74,7 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
Notify(PSTR("\r\nXBOXUSB Init"), 0x80);
#endif
// check if address has already been assigned to an instance
if (bAddress) {
if(bAddress) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress in use"), 0x80);
#endif
@ -84,14 +84,14 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p) {
if(!p) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
if (!p->epinfo) {
if(!p->epinfo) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nepinfo is null"), 0x80);
#endif
@ -111,19 +111,19 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
if (rcode)
if(rcode)
goto FailGetDevDescr;
VID = udd->idVendor;
PID = udd->idProduct;
if ((VID != XBOX_VID && VID != MADCATZ_VID && VID != JOYTECH_VID) || (PID != XBOX_OLD_PID1 && PID != XBOX_OLD_PID2 && PID != XBOX_OLD_PID3 && PID != XBOX_OLD_PID4)) // Check if VID and PID match
if((VID != XBOX_VID && VID != MADCATZ_VID && VID != JOYTECH_VID) || (PID != XBOX_OLD_PID1 && PID != XBOX_OLD_PID2 && PID != XBOX_OLD_PID3 && PID != XBOX_OLD_PID4)) // Check if VID and PID match
goto FailUnknownDevice;
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from device descriptor
@ -131,7 +131,7 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
if(rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
@ -151,14 +151,14 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
//get pointer to assigned address record
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
// Assign epInfo to epinfo pointer - only EP0 is known
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
/* The application will work in reduced host mode, so we can save program and data
@ -180,19 +180,19 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = 0;
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
delay(200); // Give time for address change
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
if (rcode)
if(rcode)
goto FailSetConfDescr;
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nXbox Controller Connected\r\n"), 0x80);
#endif
if (pFuncOnInit)
if(pFuncOnInit)
pFuncOnInit(); // Call the user function
XboxConnected = true;
bPollEnable = true;
@ -242,7 +242,7 @@ uint8_t XBOXOLD::Release() {
}
uint8_t XBOXOLD::Poll() {
if (!bPollEnable)
if(!bPollEnable)
return 0;
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
@ -256,8 +256,8 @@ uint8_t XBOXOLD::Poll() {
void XBOXOLD::readReport() {
ButtonState = readBuf[2];
for (uint8_t i = 0; i < sizeof(buttonValues); i++)
buttonValues[i] = readBuf[i + 4]; // A, B, X, Y, BLACK, WHITE, L1, and R1
for(uint8_t i = 0; i < sizeof (buttonValues); i++)
buttonValues[i] = readBuf[i + 4]; // A, B, X, Y, BLACK, WHITE, L1, and R1
hatValue[LeftHatX] = (int16_t)(((uint16_t)readBuf[12] << 8) | readBuf[13]);
hatValue[LeftHatY] = (int16_t)(((uint16_t)readBuf[14] << 8) | readBuf[15]);
@ -267,23 +267,23 @@ void XBOXOLD::readReport() {
//Notify(PSTR("\r\nButtonState"), 0x80);
//PrintHex<uint8_t>(ButtonState, 0x80);
if (ButtonState != OldButtonState || memcmp(buttonValues, oldButtonValues, sizeof(buttonValues)) != 0) {
if(ButtonState != OldButtonState || memcmp(buttonValues, oldButtonValues, sizeof (buttonValues)) != 0) {
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
OldButtonState = ButtonState;
for (uint8_t i = 0; i < sizeof(buttonValues); i++) {
if (oldButtonValues[i] == 0 && buttonValues[i] != 0)
buttonClicked[i] = true; // Update A, B, X, Y, BLACK, WHITE, L1, and R1 click state
oldButtonValues[i] = buttonValues[i];
for(uint8_t i = 0; i < sizeof (buttonValues); i++) {
if(oldButtonValues[i] == 0 && buttonValues[i] != 0)
buttonClicked[i] = true; // Update A, B, X, Y, BLACK, WHITE, L1, and R1 click state
oldButtonValues[i] = buttonValues[i];
}
}
}
void XBOXOLD::printReport(uint16_t length) { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox controller
#ifdef PRINTREPORT
if (readBuf == NULL)
if(readBuf == NULL)
return;
for (uint8_t i = 0; i < length; i++) {
for(uint8_t i = 0; i < length; i++) {
D_PrintHex<uint8_t > (readBuf[i], 0x80);
Notify(PSTR(" "), 0x80);
}
@ -293,19 +293,19 @@ void XBOXOLD::printReport(uint16_t length) { //Uncomment "#define PRINTREPORT" t
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
return buttonValues[button]; // 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[button]; // Analog buttons
return (ButtonState & button); // Digital buttons
}
bool XBOXOLD::getButtonClick(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 (buttonClicked[button]) {
buttonClicked[button] = false;
return true;
}
return false;
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(buttonClicked[button]) {
buttonClicked[button] = false;
return true;
}
return false;
}
bool click = (ButtonClickState & button);
@ -334,4 +334,4 @@ void XBOXOLD::setRumbleOn(uint8_t lValue, uint8_t rValue) {
writeBuf[5] = lValue; // big weight
XboxCommand(writeBuf, 6);
}
}

View file

@ -189,4 +189,4 @@ private:
/* Private commands */
void XboxCommand(uint8_t* data, uint16_t nbytes);
};
#endif
#endif

View file

@ -26,14 +26,14 @@ XBOXRECV::XBOXRECV(USB *p) :
pUsb(p), // pointer to USB class instance - mandatory
bAddress(0), // device address - mandatory
bPollEnable(false) { // don't start polling before dongle is connected
for (uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
for(uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
}
if (pUsb) // register in USB subsystem
if(pUsb) // register in USB subsystem
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
}
@ -51,7 +51,7 @@ uint8_t XBOXRECV::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
Notify(PSTR("\r\nXBOXRECV Init"), 0x80);
#endif
if (bAddress) { // Check if address has already been assigned to an instance
if(bAddress) { // Check if address has already been assigned to an instance
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress in use"), 0x80);
#endif
@ -60,14 +60,14 @@ uint8_t XBOXRECV::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
p = addrPool.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned
if (!p) {
if(!p) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
if (!p->epinfo) {
if(!p->epinfo) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nepinfo is null"), 0x80);
#endif
@ -82,13 +82,13 @@ uint8_t XBOXRECV::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
p->epinfo = oldep_ptr; // Restore p->epinfo
if (rcode)
if(rcode)
goto FailGetDevDescr;
VID = udd->idVendor;
PID = udd->idProduct;
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
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
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nYou'll need a wireless receiver for this libary to work"), 0x80);
#endif
@ -97,7 +97,7 @@ uint8_t XBOXRECV::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class
if (!bAddress) {
if(!bAddress) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nOut of address space"), 0x80);
#endif
@ -115,13 +115,13 @@ FailGetDevDescr:
#ifdef DEBUG_USB_HOST
NotifyFailGetDevDescr(rcode);
#endif
if (rcode != hrJERR)
if(rcode != hrJERR)
rcode = USB_ERROR_FailGetDevDescr;
goto Fail;
FailUnknownDevice:
#ifdef DEBUG_USB_HOST
NotifyFailUnknownDevice(VID,PID);
NotifyFailUnknownDevice(VID, PID);
#endif
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
@ -143,7 +143,7 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
#endif
UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
if (!p) {
if(!p) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
@ -153,7 +153,7 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
delay(300); // Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress); // Assign new address to the device
if (rcode) {
if(rcode) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nsetAddr: "), 0x80);
D_PrintHex<uint8_t > (rcode, 0x80);
@ -169,7 +169,7 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = false;
p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
if (!p) {
if(!p) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
@ -179,7 +179,7 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed;
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
/* The application will work in reduced host mode, so we can save program and data
@ -240,13 +240,13 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
epInfo[ XBOX_OUTPUT_PIPE_4 ].bmRcvToggle = 0;
rcode = pUsb->setEpInfoEntry(bAddress, 9, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
delay(200); //Give time for address change
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
if (rcode)
if(rcode)
goto FailSetConfDescr;
#ifdef DEBUG_USB_HOST
@ -281,7 +281,7 @@ Fail:
/* Performs a cleanup after failed Init() attempt */
uint8_t XBOXRECV::Release() {
XboxReceiverConnected = false;
for (uint8_t i = 0; i < 4; i++)
for(uint8_t i = 0; i < 4; i++)
Xbox360Connected[i] = 0x00;
pUsb->GetAddressPool().FreeAddress(bAddress);
bAddress = 0;
@ -290,28 +290,28 @@ uint8_t XBOXRECV::Release() {
}
uint8_t XBOXRECV::Poll() {
if (!bPollEnable)
if(!bPollEnable)
return 0;
if (!checkStatusTimer || ((millis() - checkStatusTimer) > 3000)) { // Run checkStatus every 3 seconds
if(!checkStatusTimer || ((millis() - checkStatusTimer) > 3000)) { // Run checkStatus every 3 seconds
checkStatusTimer = millis();
checkStatus();
}
uint8_t inputPipe;
uint16_t bufferSize;
for (uint8_t i = 0; i < 4; i++) {
if (i == 0)
for(uint8_t i = 0; i < 4; i++) {
if(i == 0)
inputPipe = XBOX_INPUT_PIPE_1;
else if (i == 1)
else if(i == 1)
inputPipe = XBOX_INPUT_PIPE_2;
else if (i == 2)
else if(i == 2)
inputPipe = XBOX_INPUT_PIPE_3;
else
inputPipe = XBOX_INPUT_PIPE_4;
bufferSize = EP_MAXPKTSIZE; // This is the maximum number of bytes we want to receive
pUsb->inTransfer(bAddress, epInfo[ inputPipe ].epAddr, &bufferSize, readBuf);
if (bufferSize > 0) { // The number of received bytes
if(bufferSize > 0) { // The number of received bytes
#ifdef EXTRADEBUG
Notify(PSTR("Bytes Received: "), 0x80);
D_PrintHex<uint16_t > (bufferSize, 0x80);
@ -327,19 +327,19 @@ uint8_t XBOXRECV::Poll() {
}
void XBOXRECV::readReport(uint8_t controller) {
if (readBuf == NULL)
if(readBuf == NULL)
return;
// This report is send when a controller is connected and disconnected
if (readBuf[0] == 0x08 && readBuf[1] != Xbox360Connected[controller]) {
if(readBuf[0] == 0x08 && readBuf[1] != Xbox360Connected[controller]) {
Xbox360Connected[controller] = readBuf[1];
#ifdef DEBUG_USB_HOST
Notify(PSTR("Controller "), 0x80);
Notify(controller, 0x80);
#endif
if (Xbox360Connected[controller]) {
if(Xbox360Connected[controller]) {
#ifdef DEBUG_USB_HOST
const char* str = 0;
switch (readBuf[1]) {
switch(readBuf[1]) {
case 0x80: str = PSTR(" as controller\r\n");
break;
case 0x40: str = PSTR(" as headset\r\n");
@ -359,15 +359,15 @@ void XBOXRECV::readReport(uint8_t controller) {
return;
}
// Controller status report
if (readBuf[1] == 0x00 && readBuf[3] & 0x13 && readBuf[4] >= 0x22) {
if(readBuf[1] == 0x00 && readBuf[3] & 0x13 && readBuf[4] >= 0x22) {
controllerStatus[controller] = ((uint16_t)readBuf[3] << 8) | readBuf[4];
return;
}
if (readBuf[1] != 0x01) // Check if it's the correct report - the receiver also sends different status reports
if(readBuf[1] != 0x01) // Check if it's the correct report - the receiver also sends different status reports
return;
// A controller must be connected if it's sending data
if (!Xbox360Connected[controller])
if(!Xbox360Connected[controller])
Xbox360Connected[controller] |= 0x80;
ButtonState[controller] = (uint32_t)(readBuf[9] | ((uint16_t)readBuf[8] << 8) | ((uint32_t)readBuf[7] << 16) | ((uint32_t)readBuf[6] << 24));
@ -380,12 +380,12 @@ void XBOXRECV::readReport(uint8_t controller) {
//Notify(PSTR("\r\nButtonState: "), 0x80);
//PrintHex<uint32_t>(ButtonState[controller], 0x80);
if (ButtonState[controller] != OldButtonState[controller]) {
if(ButtonState[controller] != OldButtonState[controller]) {
buttonStateChanged[controller] = true;
ButtonClickState[controller] = (ButtonState[controller] >> 16) & ((~OldButtonState[controller]) >> 16); // Update click state variable, but don't include the two trigger buttons L2 and R2
if (((uint8_t)OldButtonState[controller]) == 0 && ((uint8_t)ButtonState[controller]) != 0) // The L2 and R2 buttons are special as they are analog buttons
if(((uint8_t)OldButtonState[controller]) == 0 && ((uint8_t)ButtonState[controller]) != 0) // The L2 and R2 buttons are special as they are analog buttons
R2Clicked[controller] = true;
if ((uint8_t)(OldButtonState[controller] >> 8) == 0 && (uint8_t)(ButtonState[controller] >> 8) != 0)
if((uint8_t)(OldButtonState[controller] >> 8) == 0 && (uint8_t)(ButtonState[controller] >> 8) != 0)
L2Clicked[controller] = true;
OldButtonState[controller] = ButtonState[controller];
}
@ -393,12 +393,12 @@ void XBOXRECV::readReport(uint8_t controller) {
void XBOXRECV::printReport(uint8_t controller, uint8_t nBytes) { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
#ifdef PRINTREPORT
if (readBuf == NULL)
if(readBuf == NULL)
return;
Notify(PSTR("Controller "), 0x80);
Notify(controller, 0x80);
Notify(PSTR(": "), 0x80);
for (uint8_t i = 0; i < nBytes; i++) {
for(uint8_t i = 0; i < nBytes; i++) {
D_PrintHex<uint8_t > (readBuf[i], 0x80);
Notify(PSTR(" "), 0x80);
}
@ -407,22 +407,22 @@ void XBOXRECV::printReport(uint8_t controller, uint8_t nBytes) { //Uncomment "#d
}
uint8_t XBOXRECV::getButtonPress(Button b, uint8_t controller) {
if (b == L2) // These are analog buttons
if(b == L2) // These are analog buttons
return (uint8_t)(ButtonState[controller] >> 8);
else if (b == R2)
else if(b == R2)
return (uint8_t)ButtonState[controller];
return (bool)(ButtonState[controller] & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16));
}
bool XBOXRECV::getButtonClick(Button b, uint8_t controller) {
if (b == L2) {
if (L2Clicked[controller]) {
if(b == L2) {
if(L2Clicked[controller]) {
L2Clicked[controller] = false;
return true;
}
return false;
} else if (b == R2) {
if (R2Clicked[controller]) {
} else if(b == R2) {
if(R2Clicked[controller]) {
R2Clicked[controller] = false;
return true;
}
@ -472,7 +472,7 @@ void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) {
uint8_t rcode;
#endif
uint8_t outputPipe;
switch (controller) {
switch(controller) {
case 0: outputPipe = XBOX_OUTPUT_PIPE_1;
break;
case 1: outputPipe = XBOX_OUTPUT_PIPE_2;
@ -489,7 +489,7 @@ void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) {
#endif
pUsb->outTransfer(bAddress, epInfo[ outputPipe ].epAddr, nbytes, data);
#ifdef EXTRADEBUG
if (rcode)
if(rcode)
Notify(PSTR("Error sending Xbox message\r\n"), 0x80);
#endif
}
@ -513,7 +513,7 @@ void XBOXRECV::setLedRaw(uint8_t value, uint8_t controller) {
}
void XBOXRECV::setLedOn(LED led, uint8_t controller) {
if (led != ALL) // All LEDs can't be on a the same time
if(led != ALL) // All LEDs can't be on a the same time
setLedRaw(pgm_read_byte(&XBOXLEDS[(uint8_t)led]) + 4, controller);
}
@ -530,14 +530,14 @@ Thanks to BusHound from Perisoft.net for the Windows USB Analysis output
Found by timstamp.co.uk
*/
void XBOXRECV::checkStatus() {
if (!bPollEnable)
if(!bPollEnable)
return;
// Get controller info
writeBuf[0] = 0x08;
writeBuf[1] = 0x00;
writeBuf[2] = 0x0f;
writeBuf[3] = 0xc0;
for (uint8_t i = 0; i < 4; i++) {
for(uint8_t i = 0; i < 4; i++) {
XboxCommand(i, writeBuf, 4);
}
// Get battery status
@ -545,8 +545,8 @@ void XBOXRECV::checkStatus() {
writeBuf[1] = 0x00;
writeBuf[2] = 0x00;
writeBuf[3] = 0x40;
for (uint8_t i = 0; i < 4; i++) {
if (Xbox360Connected[i])
for(uint8_t i = 0; i < 4; i++) {
if(Xbox360Connected[i])
XboxCommand(i, writeBuf, 4);
}
}
@ -564,18 +564,18 @@ void XBOXRECV::setRumbleOn(uint8_t lValue, uint8_t rValue, uint8_t controller) {
}
void XBOXRECV::onInit(uint8_t controller) {
if (pFuncOnInit)
if(pFuncOnInit)
pFuncOnInit(); // Call the user function
else {
LED led;
if (controller == 0)
led = LED1;
else if (controller == 1)
led = LED2;
else if (controller == 2)
led = LED3;
if(controller == 0)
led = LED1;
else if(controller == 1)
led = LED2;
else if(controller == 2)
led = LED3;
else
led = LED4;
led = LED4;
setLedOn(led, controller);
}
}

View file

@ -277,4 +277,4 @@ private:
void XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes);
void checkStatus();
};
#endif
#endif

View file

@ -24,14 +24,14 @@ XBOXUSB::XBOXUSB(USB *p) :
pUsb(p), // pointer to USB class instance - mandatory
bAddress(0), // device address - mandatory
bPollEnable(false) { // don't start polling before dongle is connected
for (uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
for(uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
}
if (pUsb) // register in USB subsystem
if(pUsb) // register in USB subsystem
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
}
@ -50,7 +50,7 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
Notify(PSTR("\r\nXBOXUSB Init"), 0x80);
#endif
// check if address has already been assigned to an instance
if (bAddress) {
if(bAddress) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress in use"), 0x80);
#endif
@ -60,14 +60,14 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p) {
if(!p) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
if (!p->epinfo) {
if(!p->epinfo) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nepinfo is null"), 0x80);
#endif
@ -87,31 +87,31 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
if (rcode)
if(rcode)
goto FailGetDevDescr;
VID = udd->idVendor;
PID = udd->idProduct;
if (VID != XBOX_VID && VID != MADCATZ_VID && VID != JOYTECH_VID && VID != GAMESTOP_VID) // Check VID
if(VID != XBOX_VID && VID != MADCATZ_VID && VID != JOYTECH_VID && VID != GAMESTOP_VID) // Check VID
goto FailUnknownDevice;
if (PID == XBOX_WIRELESS_PID) {
if(PID == XBOX_WIRELESS_PID) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nYou have plugged in a wireless Xbox 360 controller - it doesn't support USB communication"), 0x80);
#endif
goto FailUnknownDevice;
} else if (PID == XBOX_WIRELESS_RECEIVER_PID || PID == XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID) {
} else if(PID == XBOX_WIRELESS_RECEIVER_PID || PID == XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nThis library only supports Xbox 360 controllers via USB"), 0x80);
#endif
goto FailUnknownDevice;
} else if (PID != XBOX_WIRED_PID && PID != GAMESTOP_WIRED_PID) // Check PID
} else if(PID != XBOX_WIRED_PID && PID != GAMESTOP_WIRED_PID) // Check PID
goto FailUnknownDevice;
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from device descriptor
@ -119,7 +119,7 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
if(rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
@ -139,14 +139,14 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
//get pointer to assigned address record
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
// Assign epInfo to epinfo pointer - only EP0 is known
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
/* The application will work in reduced host mode, so we can save program and data
@ -168,13 +168,13 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = 0;
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
delay(200); // Give time for address change
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
if (rcode)
if(rcode)
goto FailSetConfDescr;
#ifdef DEBUG_USB_HOST
@ -229,7 +229,7 @@ uint8_t XBOXUSB::Release() {
}
uint8_t XBOXUSB::Poll() {
if (!bPollEnable)
if(!bPollEnable)
return 0;
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
@ -241,9 +241,9 @@ uint8_t XBOXUSB::Poll() {
}
void XBOXUSB::readReport() {
if (readBuf == NULL)
if(readBuf == NULL)
return;
if (readBuf[0] != 0x00 || readBuf[1] != 0x14) { // Check if it's the correct report - the controller also sends different status reports
if(readBuf[0] != 0x00 || readBuf[1] != 0x14) { // Check if it's the correct report - the controller also sends different status reports
return;
}
@ -257,11 +257,11 @@ void XBOXUSB::readReport() {
//Notify(PSTR("\r\nButtonState"), 0x80);
//PrintHex<uint32_t>(ButtonState, 0x80);
if (ButtonState != OldButtonState) {
if(ButtonState != OldButtonState) {
ButtonClickState = (ButtonState >> 16) & ((~OldButtonState) >> 16); // Update click state variable, but don't include the two trigger buttons L2 and R2
if (((uint8_t)OldButtonState) == 0 && ((uint8_t)ButtonState) != 0) // The L2 and R2 buttons are special as they are analog buttons
if(((uint8_t)OldButtonState) == 0 && ((uint8_t)ButtonState) != 0) // The L2 and R2 buttons are special as they are analog buttons
R2Clicked = true;
if ((uint8_t)(OldButtonState >> 8) == 0 && (uint8_t)(ButtonState >> 8) != 0)
if((uint8_t)(OldButtonState >> 8) == 0 && (uint8_t)(ButtonState >> 8) != 0)
L2Clicked = true;
OldButtonState = ButtonState;
}
@ -269,9 +269,9 @@ void XBOXUSB::readReport() {
void XBOXUSB::printReport() { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
#ifdef PRINTREPORT
if (readBuf == NULL)
if(readBuf == NULL)
return;
for (uint8_t i = 0; i < XBOX_REPORT_BUFFER_SIZE; i++) {
for(uint8_t i = 0; i < XBOX_REPORT_BUFFER_SIZE; i++) {
D_PrintHex<uint8_t > (readBuf[i], 0x80);
Notify(PSTR(" "), 0x80);
}
@ -280,22 +280,22 @@ void XBOXUSB::printReport() { //Uncomment "#define PRINTREPORT" to print the rep
}
uint8_t XBOXUSB::getButtonPress(Button b) {
if (b == L2) // These are analog buttons
if(b == L2) // These are analog buttons
return (uint8_t)(ButtonState >> 8);
else if (b == R2)
else if(b == R2)
return (uint8_t)ButtonState;
return (bool)(ButtonState & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16));
}
bool XBOXUSB::getButtonClick(Button b) {
if (b == L2) {
if (L2Clicked) {
if(b == L2) {
if(L2Clicked) {
L2Clicked = false;
return true;
}
return false;
} else if (b == R2) {
if (R2Clicked) {
} else if(b == R2) {
if(R2Clicked) {
R2Clicked = false;
return true;
}
@ -326,7 +326,7 @@ void XBOXUSB::setLedRaw(uint8_t value) {
}
void XBOXUSB::setLedOn(LED led) {
if (led != ALL) // All LEDs can't be on a the same time
if(led != ALL) // All LEDs can't be on a the same time
setLedRaw((pgm_read_byte(&XBOXLEDS[(uint8_t)led])) + 4);
}
@ -352,7 +352,7 @@ void XBOXUSB::setRumbleOn(uint8_t lValue, uint8_t rValue) {
}
void XBOXUSB::onInit() {
if (pFuncOnInit)
if(pFuncOnInit)
pFuncOnInit(); // Call the user function
else
setLedOn(LED1);

View file

@ -111,6 +111,7 @@ class AddressPoolImpl : public AddressPool {
};
// Returns thePool index for a given address
uint8_t FindAddressIndex(uint8_t address = 0) {
for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) {
if(thePool[i].address.devAddress == address)
@ -120,6 +121,7 @@ class AddressPoolImpl : public AddressPool {
};
// Returns thePool child index for a given parent
uint8_t FindChildIndex(UsbDeviceAddress addr, uint8_t start = 1) {
for(uint8_t i = (start < 1 || start >= MAX_DEVICES_ALLOWED) ? 1 : start; i < MAX_DEVICES_ALLOWED; i++) {
if(thePool[i].address.bmParent == addr.bmAddress)
@ -129,6 +131,7 @@ class AddressPoolImpl : public AddressPool {
};
// Frees address entry specified by index parameter
void FreeAddressByIndex(uint8_t index) {
// Zero field is reserved and should not be affected
if(index == 0)
@ -148,6 +151,7 @@ class AddressPoolImpl : public AddressPool {
}
// Initializes the whole address pool at once
void InitAllAddresses() {
for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
InitEntry(i);
@ -172,16 +176,18 @@ public:
};
// Returns a pointer to a specified address entry
virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) {
if(!addr)
return thePool;
uint8_t index = FindAddressIndex(addr);
return(!index) ? NULL : thePool + index;
return (!index) ? NULL : thePool + index;
};
// Performs an operation specified by pfunc for each addressed device
void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) {
if(!pfunc)
return;
@ -192,13 +198,14 @@ public:
};
// Allocates new address
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0) {
/* if (parent != 0 && port == 0)
USB_HOST_SERIAL.println("PRT:0"); */
UsbDeviceAddress _parent;
_parent.devAddress = parent;
if(_parent.bmReserved || port > 7)
//if(parent > 127 || port > 7)
//if(parent > 127 || port > 7)
return 0;
if(is_hub && hubCounter == 7)
@ -243,6 +250,7 @@ public:
};
// Empties pool entry
virtual void FreeAddress(uint8_t addr) {
// if the root hub is disconnected all the addresses should be initialized
if(addr == 0x41) {

50
adk.cpp
View file

@ -13,7 +13,7 @@ Contact information
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
*/
/* Google ADK interface */
@ -42,7 +42,7 @@ bConfNum(0), //configuration number
bNumEP(1), //if config descriptor needs to be parsed
ready(false) {
// initialize endpoint data structures
for (uint8_t i = 0; i < ADK_MAX_ENDPOINTS; i++) {
for(uint8_t i = 0; i < ADK_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
@ -50,7 +50,7 @@ ready(false) {
}//for(uint8_t i=0; i<ADK_MAX_ENDPOINTS; i++...
// register in USB subsystem
if (pUsb) {
if(pUsb) {
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
}
}
@ -74,7 +74,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
USBTRACE("\r\nADK Init");
// check if address has already been assigned to an instance
if (bAddress) {
if(bAddress) {
USBTRACE("\r\nAddress in use");
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
}
@ -82,12 +82,12 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p) {
if(!p) {
USBTRACE("\r\nAddress not found");
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
if (!p->epinfo) {
if(!p->epinfo) {
USBTRACE("epinfo is null\r\n");
return USB_ERROR_EPINFO_IS_NULL;
}
@ -106,7 +106,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
if (rcode) {
if(rcode) {
goto FailGetDevDescr;
}
@ -118,7 +118,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
if(rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
@ -134,7 +134,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
//get pointer to assigned address record
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p) {
if(!p) {
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
@ -142,49 +142,49 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign epInfo to epinfo pointer - only EP0 is known
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode) {
if(rcode) {
goto FailSetDevTblEntry;
}
//check if ADK device is already in accessory mode; if yes, configure and exit
if (udd->idVendor == ADK_VID &&
if(udd->idVendor == ADK_VID &&
(udd->idProduct == ADK_PID || udd->idProduct == ADB_PID)) {
USBTRACE("\r\nAcc.mode device detected");
/* go through configurations, find first bulk-IN, bulk-OUT EP, fill epInfo and quit */
num_of_conf = udd->bNumConfigurations;
//USBTRACE2("\r\nNC:",num_of_conf);
for (uint8_t i = 0; i < num_of_conf; i++) {
for(uint8_t i = 0; i < num_of_conf; i++) {
ConfigDescParser < 0, 0, 0, 0 > confDescrParser(this);
delay(1);
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
#if defined(XOOM)
//added by Jaylen Scott Vanorden
if (rcode) {
if(rcode) {
USBTRACE2("\r\nGot 1st bad code for config: ", rcode);
// Try once more
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
}
#endif
if (rcode) {
if(rcode) {
goto FailGetConfDescr;
}
if (bNumEP > 2) {
if(bNumEP > 2) {
break;
}
} // for (uint8_t i=0; i<num_of_conf; i++...
if (bNumEP == 3) {
if(bNumEP == 3) {
// Assign epInfo to epinfo pointer - this time all 3 endpoins
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
if (rcode) {
if(rcode) {
goto FailSetDevTblEntry;
}
}
// Set Configuration Value
rcode = pUsb->setConf(bAddress, 0, bConfNum);
if (rcode) {
if(rcode) {
goto FailSetConfDescr;
}
/* print endpoint structure */
@ -202,7 +202,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
USBTRACE2("\r\nAddr: ", epInfo[epDataInIndex].epAddr);
USBTRACE2("\r\nMax.pkt.size: ", epInfo[epDataInIndex].maxPktSize);
USBTRACE2("\r\nAttr: ", epInfo[epDataInIndex].epAttribs);
*/
*/
USBTRACE("\r\nConfiguration successful");
ready = true;
@ -216,13 +216,13 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
rcode = getProto((uint8_t*) & adkproto);
#if defined(XOOM)
//added by Jaylen Scott Vanorden
if (rcode) {
if(rcode) {
USBTRACE2("\r\nGot 1st bad code for proto: ", rcode);
// Try once more
rcode = getProto((uint8_t*) & adkproto);
}
#endif
if (rcode) {
if(rcode) {
goto FailGetProto; //init fails
}
USBTRACE2("\r\nADK protocol rev. ", adkproto);
@ -248,7 +248,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
//switch to accessory mode
//the Android phone will reset
rcode = switchAcc();
if (rcode) {
if(rcode) {
goto FailSwAcc; //init fails
}
rcode = USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET;
@ -292,7 +292,7 @@ FailSwAcc:
goto Fail;
#endif
//FailOnInit:
//FailOnInit:
// USBTRACE("OnInit:");
// goto Fail;
//
@ -314,13 +314,13 @@ void ADK::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto
//ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
//added by Yuuichi Akagawa
if (bNumEP == 3) {
if(bNumEP == 3) {
return;
}
bConfNum = conf;
if ((pep->bmAttributes & 0x02) == 2) {
if((pep->bmAttributes & 0x02) == 2) {
uint8_t index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
// Fill in the endpoint info structure
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);

12
adk.h
View file

@ -13,7 +13,7 @@ Contact information
Circuits At Home, LTD
Web : http://www.circuitsathome.com
e-mail : support@circuitsathome.com
*/
*/
/* Google ADK interface support header */
@ -27,8 +27,8 @@ e-mail : support@circuitsathome.com
#define ADB_PID 0x2D01
#define XOOM //enables repeating getProto() and getConf() attempts
//necessary for slow devices such as Motorola XOOM
//defined by default, can be commented out to save memory
//necessary for slow devices such as Motorola XOOM
//defined by default, can be commented out to save memory
/* requests */
@ -124,17 +124,17 @@ public:
/* returns 2 bytes in *adkproto */
inline uint8_t ADK::getProto(uint8_t* adkproto) {
return( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_GET, ADK_GETPROTO, 0, 0, 0, 2, 2, adkproto, NULL));
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_GET, ADK_GETPROTO, 0, 0, 0, 2, 2, adkproto, NULL));
}
/* send ADK string */
inline uint8_t ADK::sendStr(uint8_t index, const char* str) {
return( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_SENDSTR, 0, 0, index, strlen(str) + 1, strlen(str) + 1, (uint8_t*) str, NULL));
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_SENDSTR, 0, 0, index, strlen(str) + 1, strlen(str) + 1, (uint8_t*)str, NULL));
}
/* switch to accessory mode */
inline uint8_t ADK::switchAcc(void) {
return( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_ACCSTART, 0, 0, 0, 0, 0, NULL, NULL));
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_ACCSTART, 0, 0, 0, 0, 0, NULL, NULL));
}
#endif // _ADK_H_

View file

@ -218,7 +218,7 @@ public:
}
static uint8_t IsSet() {
return PORT::PinRead() & (uint8_t) (1 << PIN);
return PORT::PinRead() & (uint8_t)(1 << PIN);
}
static void WaiteForSet() {

View file

@ -30,7 +30,7 @@ bNumEP(1),
qNextPollTime(0),
bPollEnable(false),
ready(false) {
for (uint8_t i = 0; i < ACM_MAX_ENDPOINTS; i++) {
for(uint8_t i = 0; i < ACM_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
@ -40,7 +40,7 @@ ready(false) {
//if (!i)
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
}
if (pUsb)
if(pUsb)
pUsb->RegisterDeviceClass(this);
}
@ -59,16 +59,16 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
USBTRACE("ACM Init\r\n");
if (bAddress)
if(bAddress)
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p->epinfo) {
if(!p->epinfo) {
USBTRACE("epinfo\r\n");
return USB_ERROR_EPINFO_IS_NULL;
}
@ -87,13 +87,13 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
if (rcode)
if(rcode)
goto FailGetDevDescr;
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor
@ -102,7 +102,7 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
if(rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
@ -116,7 +116,7 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
@ -126,12 +126,12 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
USBTRACE2("NC:", num_of_conf);
for (uint8_t i = 0; i < num_of_conf; i++) {
for(uint8_t i = 0; i < num_of_conf; i++) {
ConfigDescParser< USB_CLASS_COM_AND_CDC_CTRL,
CDC_SUBCLASS_ACM,
CDC_PROTOCOL_ITU_T_V_250,
@ -144,19 +144,19 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
rcode = pUsb->getConfDescr(bAddress, 0, i, &CdcControlParser);
if (rcode)
if(rcode)
goto FailGetConfDescr;
rcode = pUsb->getConfDescr(bAddress, 0, i, &CdcDataParser);
if (rcode)
if(rcode)
goto FailGetConfDescr;
if (bNumEP > 1)
if(bNumEP > 1)
break;
} // for
if (bNumEP < 4)
if(bNumEP < 4)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
// Assign epInfo to epinfo pointer
@ -167,12 +167,12 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Set Configuration Value
rcode = pUsb->setConf(bAddress, 0, bConfNum);
if (rcode)
if(rcode)
goto FailSetConfDescr;
rcode = pAsync->OnInit(this);
if (rcode)
if(rcode)
goto FailOnInit;
USBTRACE("ACM configured\r\n");
@ -230,10 +230,10 @@ void ACM::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto
uint8_t index;
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
index = epInterruptInIndex;
else
if ((pep->bmAttributes & 0x02) == 2)
if((pep->bmAttributes & 0x02) == 2)
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
else
return;
@ -264,7 +264,7 @@ uint8_t ACM::Release() {
uint8_t ACM::Poll() {
uint8_t rcode = 0;
if (!bPollEnable)
if(!bPollEnable)
return 0;
//uint32_t time_now = millis();

View file

@ -114,14 +114,13 @@ typedef struct {
uint8_t bDataBits; // Data bits (5, 6, 7, 8 or 16)
} LINE_CODING;
typedef struct
{
uint8_t bmRequestType; // 0xa1 for class-specific notifications
uint8_t bNotification;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
uint16_t bmState; //UART state bitmap for SERIAL_STATE, other notifications variable length
typedef struct {
uint8_t bmRequestType; // 0xa1 for class-specific notifications
uint8_t bNotification;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
uint16_t bmState; //UART state bitmap for SERIAL_STATE, other notifications variable length
} CLASS_NOTIFICATION;
class ACM;
@ -151,7 +150,7 @@ protected:
uint8_t bNumEP; // total number of EP in the configuration
uint32_t qNextPollTime; // next poll time
bool bPollEnable; // poll enable flag
bool ready; //device ready indicator
bool ready; //device ready indicator
EpInfo epInfo[ACM_MAX_ENDPOINTS];
@ -167,7 +166,7 @@ public:
uint8_t GetLineCoding(LINE_CODING *dataptr);
uint8_t SetControlLineState(uint8_t state);
uint8_t SendBreak(uint16_t duration);
uint8_t GetNotif( uint16_t *bytes_rcvd, uint8_t *dataptr );
uint8_t GetNotif(uint16_t *bytes_rcvd, uint8_t *dataptr);
// Methods for recieving and sending data
uint8_t RcvData(uint16_t *nbytesptr, uint8_t *dataptr);
@ -182,9 +181,9 @@ public:
return bAddress;
};
virtual bool isReady() {
return ready;
};
virtual bool isReady() {
return ready;
};
// UsbConfigXtracter implementation
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);

View file

@ -26,7 +26,7 @@ pUsb(p),
bAddress(0),
bNumEP(1),
wFTDIType(0) {
for (uint8_t i = 0; i < FTDI_MAX_ENDPOINTS; i++) {
for(uint8_t i = 0; i < FTDI_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
@ -34,7 +34,7 @@ wFTDIType(0) {
//if (!i)
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
}
if (pUsb)
if(pUsb)
pUsb->RegisterDeviceClass(this);
}
@ -56,16 +56,16 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
USBTRACE("FTDI Init\r\n");
if (bAddress)
if(bAddress)
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p->epinfo) {
if(!p->epinfo) {
USBTRACE("epinfo\r\n");
return USB_ERROR_EPINFO_IS_NULL;
}
@ -84,9 +84,9 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
if (rcode)
if(rcode)
goto FailGetDevDescr;
if (udd->idVendor != FTDI_VID || udd->idProduct != FTDI_PID)
if(udd->idVendor != FTDI_VID || udd->idProduct != FTDI_PID)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
// Save type of FTDI chip
@ -95,7 +95,7 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor
@ -104,7 +104,7 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
if(rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
@ -118,7 +118,7 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
@ -128,30 +128,30 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
USBTRACE2("NC:", num_of_conf);
for (uint8_t i = 0; i < num_of_conf; i++) {
for(uint8_t i = 0; i < num_of_conf; i++) {
HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
ConfigDescParser < 0xFF, 0xFF, 0xFF, CP_MASK_COMPARE_ALL> confDescrParser(this);
rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
if (rcode)
if(rcode)
goto FailGetConfDescr;
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
if (rcode)
if(rcode)
goto FailGetConfDescr;
if (bNumEP > 1)
if(bNumEP > 1)
break;
} // for
if (bNumEP < 2)
if(bNumEP < 2)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
USBTRACE2("NumEP:", bNumEP);
@ -164,12 +164,12 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Set Configuration Value
rcode = pUsb->setConf(bAddress, 0, bConfNum);
if (rcode)
if(rcode)
goto FailSetConfDescr;
rcode = pAsync->OnInit(this);
if (rcode)
if(rcode)
goto FailOnInit;
USBTRACE("FTDI configured\r\n");
@ -221,10 +221,10 @@ void FTDI::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t prot
uint8_t index;
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
index = epInterruptInIndex;
else
if ((pep->bmAttributes & 0x02) == 2)
if((pep->bmAttributes & 0x02) == 2)
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
else
return;
@ -270,19 +270,19 @@ uint8_t FTDI::SetBaudRate(uint32_t baud) {
divisor3 = 48000000 / 2 / baud; // divisor shifted 3 bits to the left
if (wFTDIType == FT232AM) {
if ((divisor3 & 0x7) == 7)
if(wFTDIType == FT232AM) {
if((divisor3 & 0x7) == 7)
divisor3++; // round x.7/8 up to x+1
baud_value = divisor3 >> 3;
divisor3 &= 0x7;
if (divisor3 == 1) baud_value |= 0xc000;
if(divisor3 == 1) baud_value |= 0xc000;
else // 0.125
if (divisor3 >= 4) baud_value |= 0x4000;
if(divisor3 >= 4) baud_value |= 0x4000;
else // 0.5
if (divisor3 != 0) baud_value |= 0x8000; // 0.25
if (baud_value == 1) baud_value = 0; /* special case for maximum baud rate */
if(divisor3 != 0) baud_value |= 0x8000; // 0.25
if(baud_value == 1) baud_value = 0; /* special case for maximum baud rate */
} else {
static const unsigned char divfrac [8] = {0, 3, 2, 0, 1, 1, 2, 3};
static const unsigned char divindex[8] = {0, 0, 0, 1, 0, 1, 1, 1};
@ -292,9 +292,9 @@ uint8_t FTDI::SetBaudRate(uint32_t baud) {
baud_index = divindex[divisor3 & 0x7];
/* Deal with special cases for highest baud rates. */
if (baud_value == 1) baud_value = 0;
if(baud_value == 1) baud_value = 0;
else // 1.0
if (baud_value == 0x4001) baud_value = 1; // 1.5
if(baud_value == 0x4001) baud_value = 1; // 1.5
}
USBTRACE2("baud_value:", baud_value);
USBTRACE2("baud_index:", baud_index);

View file

@ -130,4 +130,4 @@ public:
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
};
#endif // __CDCFTDI_H__
#endif // __CDCFTDI_H__

View file

@ -35,16 +35,16 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
USBTRACE("PL Init\r\n");
if (bAddress)
if(bAddress)
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p->epinfo) {
if(!p->epinfo) {
USBTRACE("epinfo\r\n");
return USB_ERROR_EPINFO_IS_NULL;
}
@ -63,10 +63,10 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
if (rcode)
if(rcode)
goto FailGetDevDescr;
if (udd->idVendor != PL_VID && udd->idProduct != PL_PID)
if(udd->idVendor != PL_VID && udd->idProduct != PL_PID)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
// Save type of PL chip
@ -75,7 +75,7 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor
@ -84,7 +84,7 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
if(rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
@ -98,7 +98,7 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
@ -108,30 +108,30 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
USBTRACE2("NC:", num_of_conf);
for (uint8_t i = 0; i < num_of_conf; i++) {
for(uint8_t i = 0; i < num_of_conf; i++) {
HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
ConfigDescParser < 0xFF, 0, 0, CP_MASK_COMPARE_CLASS> confDescrParser(this);
rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
if (rcode)
if(rcode)
goto FailGetConfDescr;
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
if (rcode)
if(rcode)
goto FailGetConfDescr;
if (bNumEP > 1)
if(bNumEP > 1)
break;
} // for
if (bNumEP < 2)
if(bNumEP < 2)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
// Assign epInfo to epinfo pointer
@ -142,12 +142,12 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Set Configuration Value
rcode = pUsb->setConf(bAddress, 0, bConfNum);
if (rcode)
if(rcode)
goto FailSetConfDescr;
rcode = pAsync->OnInit(this);
if (rcode)
if(rcode)
goto FailOnInit;
USBTRACE("PL configured\r\n");
@ -208,5 +208,3 @@ Fail:
// //}
// return rcode;
//}

View file

@ -58,7 +58,10 @@ class ConfigDescParser : public USBReadParser {
void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
public:
void SetOR(void) { UseOr = true; }
void SetOR(void) {
UseOr = true;
}
ConfigDescParser(UsbConfigXtracter *xtractor);
virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset);
};
@ -75,11 +78,10 @@ UseOr(false) {
theSkipper.Initialize(&theBuffer);
};
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset) {
uint16_t cntdn = (uint16_t) len;
uint8_t *p = (uint8_t*) pbuf;
uint16_t cntdn = (uint16_t)len;
uint8_t *p = (uint8_t*)pbuf;
while(cntdn)
if(!ParseDescriptor(&p, &cntdn))
@ -90,8 +92,8 @@ void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uin
compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor(uint8_t **pp, uint16_t *pcntdn) {
USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR*> (varBuffer);
USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*> (varBuffer);
USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR*>(varBuffer);
USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*>(varBuffer);
switch(stateParseDescr) {
case 0:
theBuffer.valueSize = 2;
@ -100,8 +102,8 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
case 1:
if(!valParser.Parse(pp, pcntdn))
return false;
dscrLen = *((uint8_t*) theBuffer.pValue);
dscrType = *((uint8_t*) theBuffer.pValue + 1);
dscrLen = *((uint8_t*)theBuffer.pValue);
dscrType = *((uint8_t*)theBuffer.pValue + 1);
stateParseDescr = 2;
case 2:
// This is a sort of hack. Assuming that two bytes are all ready in the buffer
@ -116,10 +118,10 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
case USB_DESCRIPTOR_INTERFACE:
isGoodInterface = false;
case USB_DESCRIPTOR_CONFIGURATION:
theBuffer.valueSize = sizeof(USB_CONFIGURATION_DESCRIPTOR) - 2;
theBuffer.valueSize = sizeof (USB_CONFIGURATION_DESCRIPTOR) - 2;
break;
case USB_DESCRIPTOR_ENDPOINT:
theBuffer.valueSize = sizeof(USB_ENDPOINT_DESCRIPTOR) - 2;
theBuffer.valueSize = sizeof (USB_ENDPOINT_DESCRIPTOR) - 2;
break;
case HID_DESCRIPTOR_HID:
theBuffer.valueSize = dscrLen - 2;
@ -158,7 +160,7 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
return false;
if(isGoodInterface)
if(theXtractor)
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*) varBuffer);
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer);
break;
//case HID_DESCRIPTOR_HID:
// if (!valParser.Parse(pp, pcntdn))

View file

@ -117,4 +117,4 @@ enum AnalogHat {
RightHatY = 3,
};
#endif
#endif

View file

@ -41,7 +41,7 @@ public:
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
void HexDumper<BASE_CLASS, LEN_TYPE, OFFSET_TYPE>::Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset) {
if(UsbDEBUGlvl >= 0x80) { // Fully bypass this block of code if we do not debug.
if(UsbDEBUGlvl >= 0x80) { // Fully bypass this block of code if we do not debug.
for(LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) {
if(!byteCount) {
PrintHex<OFFSET_TYPE > (byteTotal, 0x80);

View file

@ -1,6 +1,7 @@
#include "hid.h"
//get HID report descriptor
/* WRONG! Endpoint is _ALWAYS_ ZERO for HID! We want the _INTERFACE_ value here!
uint8_t HID::GetReportDescr(uint8_t ep, USBReadParser *parser) {
const uint8_t constBufLen = 64;
@ -12,7 +13,7 @@ uint8_t HID::GetReportDescr(uint8_t ep, USBReadParser *parser) {
//return ((rcode != hrSTALL) ? rcode : 0);
return rcode;
}
*/
*/
uint8_t HID::GetReportDescr(uint16_t wIndex, USBReadParser *parser) {
const uint8_t constBufLen = 64;
uint8_t buf[constBufLen];

1
hid.h
View file

@ -140,7 +140,6 @@ public:
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) = 0;
};
class HID : public USBDeviceConfig, public UsbConfigXtracter {
protected:
USB *pUsb; // USB class instance pointer

View file

@ -980,7 +980,7 @@ void ReportDescParserBase::Parse(const uint16_t len, const uint8_t *pbuf, const
totalSize = 0;
while (cntdn) {
while(cntdn) {
//USB_HOST_SERIAL.println("");
//PrintHex<uint16_t>(offset + len - cntdn);
//USB_HOST_SERIAL.print(":");
@ -995,7 +995,7 @@ void ReportDescParserBase::Parse(const uint16_t len, const uint8_t *pbuf, const
void ReportDescParserBase::PrintValue(uint8_t *p, uint8_t len) {
E_Notify(PSTR("("), 0x80);
for (; len; p++, len--)
for(; len; p++, len--)
PrintHex<uint8_t > (*p, 0x80);
E_Notify(PSTR(")"), 0x80);
}
@ -1007,7 +1007,7 @@ void ReportDescParserBase::PrintByteValue(uint8_t data) {
}
void ReportDescParserBase::PrintItemTitle(uint8_t prefix) {
switch (prefix & (TYPE_MASK | TAG_MASK)) {
switch(prefix & (TYPE_MASK | TAG_MASK)) {
case (TYPE_GLOBAL | TAG_GLOBAL_PUSH):
E_Notify(PSTR("\r\nPush"), 0x80);
break;
@ -1074,9 +1074,9 @@ void ReportDescParserBase::PrintItemTitle(uint8_t prefix) {
uint8_t ReportDescParserBase::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
//uint8_t ret = enErrorSuccess;
//reinterpret_cast<>(varBuffer);
switch (itemParseState) {
switch(itemParseState) {
case 0:
if (**pp == HID_LONG_ITEM_PREFIX)
if(**pp == HID_LONG_ITEM_PREFIX)
USBTRACE("\r\nLONG\r\n");
else {
uint8_t size = ((**pp) & DATA_SIZE_MASK);
@ -1091,10 +1091,10 @@ switch (itemParseState) {
itemSize--;
itemParseState = 1;
if (!itemSize)
if(!itemSize)
break;
if (!pcntdn)
if(!pcntdn)
return enErrorIncomplete;
case 1:
//USBTRACE2("\r\niSz:",itemSize);
@ -1103,18 +1103,18 @@ switch (itemParseState) {
valParser.Initialize(&theBuffer);
itemParseState = 2;
case 2:
if (!valParser.Parse(pp, pcntdn))
if(!valParser.Parse(pp, pcntdn))
return enErrorIncomplete;
itemParseState = 3;
case 3:
{
uint8_t data = *((uint8_t*)varBuffer);
switch (itemPrefix & (TYPE_MASK | TAG_MASK)) {
switch(itemPrefix & (TYPE_MASK | TAG_MASK)) {
case (TYPE_LOCAL | TAG_LOCAL_USAGE):
if (pfUsage) {
if (theBuffer.valueSize > 1) {
uint16_t* ui16 = reinterpret_cast<uint16_t *>(varBuffer);
if(pfUsage) {
if(theBuffer.valueSize > 1) {
uint16_t* ui16 = reinterpret_cast<uint16_t *>(varBuffer);
pfUsage(*ui16);
} else
pfUsage(data);
@ -1149,7 +1149,7 @@ switch (itemParseState) {
break;
case (TYPE_MAIN | TAG_MAIN_COLLECTION):
case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION):
switch (data) {
switch(data) {
case 0x00:
E_Notify(PSTR(" Physical"), 0x80);
break;
@ -1216,23 +1216,23 @@ ReportDescParserBase::UsagePageFunc ReportDescParserBase::usagePageFunctions[] /
void ReportDescParserBase::SetUsagePage(uint16_t page) {
pfUsage = NULL;
if (VALUE_BETWEEN(page, 0x00, 0x11))
if(VALUE_BETWEEN(page, 0x00, 0x11))
pfUsage = (usagePageFunctions[page - 1]);
// Dead code...
//
// pfUsage = (UsagePageFunc)pgm_read_pointer(usagePageFunctions[page - 1]);
//else if (page > 0x7f && page < 0x84)
// E_Notify(pstrUsagePageMonitor);
//else if (page > 0x83 && page < 0x8c)
// E_Notify(pstrUsagePagePower);
//else if (page > 0x8b && page < 0x92)
// E_Notify((char*)pgm_read_pointer(&usagePageTitles1[page - 0x8c]));
//else if (page > 0xfeff && page <= 0xffff)
// E_Notify(pstrUsagePageVendorDefined);
//
// Dead code...
//
// pfUsage = (UsagePageFunc)pgm_read_pointer(usagePageFunctions[page - 1]);
//else if (page > 0x7f && page < 0x84)
// E_Notify(pstrUsagePageMonitor);
//else if (page > 0x83 && page < 0x8c)
// E_Notify(pstrUsagePagePower);
//else if (page > 0x8b && page < 0x92)
// E_Notify((char*)pgm_read_pointer(&usagePageTitles1[page - 0x8c]));
//else if (page > 0xfeff && page <= 0xffff)
// E_Notify(pstrUsagePageVendorDefined);
//
else
switch (page) {
switch(page) {
case 0x14:
pfUsage = &ReportDescParserBase::PrintAlphanumDisplayPageUsage;
break;
@ -1248,14 +1248,14 @@ void ReportDescParserBase::PrintUsagePage(uint16_t page) {
output_if_between(page, 0x00, 0x11, w, E_Notify, usagePageTitles0, 0x80)
else output_if_between(page, 0x8b, 0x92, w, E_Notify, usagePageTitles1, 0x80)
else if (VALUE_BETWEEN(page, 0x7f, 0x84))
else if(VALUE_BETWEEN(page, 0x7f, 0x84))
E_Notify(pstrUsagePageMonitor, 0x80);
else if (VALUE_BETWEEN(page, 0x83, 0x8c))
else if(VALUE_BETWEEN(page, 0x83, 0x8c))
E_Notify(pstrUsagePagePower, 0x80);
else if (page > 0xfeff /* && page <= 0xffff */)
else if(page > 0xfeff /* && page <= 0xffff */)
E_Notify(pstrUsagePageVendorDefined, 0x80);
else
switch (page) {
switch(page) {
case 0x14:
E_Notify(pstrUsagePageAlphaNumericDisplay, 0x80);
break;
@ -1409,8 +1409,8 @@ void ReportDescParserBase::PrintMedicalInstrumentPageUsage(uint16_t usage) {
const char * const * w;
E_Notify(pstrSpace, 0x80);
if (usage == 1) E_Notify(pstrUsageMedicalUltrasound, 0x80);
else if (usage == 0x70)
if(usage == 1) E_Notify(pstrUsageMedicalUltrasound, 0x80);
else if(usage == 0x70)
E_Notify(pstrUsageDepthGainCompensation, 0x80);
else output_if_between(usage, 0x1f, 0x28, w, E_Notify, medInstrTitles0, 0x80)
else output_if_between(usage, 0x3f, 0x45, w, E_Notify, medInstrTitles1, 0x80)
@ -1423,9 +1423,9 @@ void ReportDescParserBase::PrintMedicalInstrumentPageUsage(uint16_t usage) {
uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
//uint8_t ret = enErrorSuccess;
switch (itemParseState) {
switch(itemParseState) {
case 0:
if (**pp == HID_LONG_ITEM_PREFIX)
if(**pp == HID_LONG_ITEM_PREFIX)
USBTRACE("\r\nLONG\r\n");
else {
uint8_t size = ((**pp) & DATA_SIZE_MASK);
@ -1437,28 +1437,28 @@ uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
itemSize--;
itemParseState = 1;
if (!itemSize)
if(!itemSize)
break;
if (!pcntdn)
if(!pcntdn)
return enErrorIncomplete;
case 1:
theBuffer.valueSize = itemSize;
valParser.Initialize(&theBuffer);
itemParseState = 2;
case 2:
if (!valParser.Parse(pp, pcntdn))
if(!valParser.Parse(pp, pcntdn))
return enErrorIncomplete;
itemParseState = 3;
case 3:
{
uint8_t data = *((uint8_t*)varBuffer);
switch (itemPrefix & (TYPE_MASK | TAG_MASK)) {
switch(itemPrefix & (TYPE_MASK | TAG_MASK)) {
case (TYPE_LOCAL | TAG_LOCAL_USAGE):
if (pfUsage) {
if (theBuffer.valueSize > 1) {
uint16_t* ui16 = reinterpret_cast<uint16_t *>(varBuffer);
if(pfUsage) {
if(theBuffer.valueSize > 1) {
uint16_t* ui16 = reinterpret_cast<uint16_t *>(varBuffer);
pfUsage(*ui16);
} else
pfUsage(data);
@ -1512,7 +1512,7 @@ void ReportDescParser2::OnInputItem(uint8_t itm) {
uint8_t bit_offset = totalSize - tmp; // number of bits in the current byte already handled
uint8_t *p = pBuf + byte_offset; // current byte pointer
if (bit_offset)
if(bit_offset)
*p >>= bit_offset;
uint8_t usage = useMin;
@ -1522,7 +1522,7 @@ void ReportDescParser2::OnInputItem(uint8_t itm) {
uint8_t bits_of_byte = 8;
// for each field in field array defined by rptCount
for (uint8_t field = 0; field < rptCount; field++, usage++) {
for(uint8_t field = 0; field < rptCount; field++, usage++) {
union {
uint8_t bResult[4];
@ -1533,7 +1533,7 @@ void ReportDescParser2::OnInputItem(uint8_t itm) {
result.dwResult = 0;
uint8_t mask = 0;
if (print_usemin_usemax)
if(print_usemin_usemax)
pfUsage(usage);
// bits_left - number of bits in the field(array of fields, depending on Report Count) left to process
@ -1541,7 +1541,7 @@ void ReportDescParser2::OnInputItem(uint8_t itm) {
// bits_to_copy - number of bits to copy to result buffer
// for each bit in a field
for (uint8_t bits_left = rptSize, bits_to_copy = 0; bits_left;
for(uint8_t bits_left = rptSize, bits_to_copy = 0; bits_left;
bits_left -= bits_to_copy) {
bits_to_copy = (bits_left > bits_of_byte) ? bits_of_byte : bits_left;
@ -1553,7 +1553,7 @@ void ReportDescParser2::OnInputItem(uint8_t itm) {
mask = 0;
for (uint8_t j = bits_to_copy; j; j--) {
for(uint8_t j = bits_to_copy; j; j--) {
mask <<= 1;
mask |= 1;
}
@ -1562,7 +1562,7 @@ void ReportDescParser2::OnInputItem(uint8_t itm) {
bits_of_byte -= bits_to_copy;
if (bits_of_byte < 1) {
if(bits_of_byte < 1) {
bits_of_byte = 8;
p++;
}
@ -1577,6 +1577,6 @@ void UniversalReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t
uint8_t ret = hid->GetReportDescr(0, &prs);
if (ret)
if(ret)
ErrorMessage<uint8_t > (PSTR("GetReportDescr-2"), ret);
}

View file

@ -101,7 +101,7 @@ protected:
MultiValueBuffer theBuffer;
MultiByteValueParser valParser;
ByteSkipper theSkipper;
uint8_t varBuffer[sizeof(USB_CONFIGURATION_DESCRIPTOR)];
uint8_t varBuffer[sizeof (USB_CONFIGURATION_DESCRIPTOR)];
uint8_t itemParseState; // Item parser state variable
uint8_t itemSize; // Item size
@ -126,8 +126,7 @@ public:
itemPrefix(0),
rptSize(0),
rptCount(0),
pfUsage(NULL)
{
pfUsage(NULL) {
theBuffer.pValue = varBuffer;
valParser.Initialize(&theBuffer);
theSkipper.Initialize(&theBuffer);

View file

@ -7,14 +7,14 @@ bPollEnable(false),
bHasReportId(false) {
Initialize();
if (pUsb)
if(pUsb)
pUsb->RegisterDeviceClass(this);
}
uint16_t HIDUniversal::GetHidClassDescrLen(uint8_t type, uint8_t num) {
for (uint8_t i = 0, n = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
if (descrInfo[i].bDescrType == type) {
if (n == num)
for(uint8_t i = 0, n = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
if(descrInfo[i].bDescrType == type) {
if(n == num)
return descrInfo[i].wDescriptorLength;
n++;
}
@ -23,22 +23,22 @@ uint16_t HIDUniversal::GetHidClassDescrLen(uint8_t type, uint8_t num) {
}
void HIDUniversal::Initialize() {
for (uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
rptParsers[i].rptId = 0;
rptParsers[i].rptParser = NULL;
}
for (uint8_t i = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
for(uint8_t i = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
descrInfo[i].bDescrType = 0;
descrInfo[i].wDescriptorLength = 0;
}
for (uint8_t i = 0; i < maxHidInterfaces; i++) {
for(uint8_t i = 0; i < maxHidInterfaces; i++) {
hidInterfaces[i].bmInterface = 0;
hidInterfaces[i].bmProtocol = 0;
for (uint8_t j = 0; j < maxEpPerInterface; j++)
for(uint8_t j = 0; j < maxEpPerInterface; j++)
hidInterfaces[i].epIndex[j] = 0;
}
for (uint8_t i = 0; i < totalEndpoints; i++) {
for(uint8_t i = 0; i < totalEndpoints; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
@ -52,8 +52,8 @@ void HIDUniversal::Initialize() {
}
bool HIDUniversal::SetReportParser(uint8_t id, HIDReportParser *prs) {
for (uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
if (rptParsers[i].rptId == 0 && rptParsers[i].rptParser == NULL) {
for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
if(rptParsers[i].rptId == 0 && rptParsers[i].rptParser == NULL) {
rptParsers[i].rptId = id;
rptParsers[i].rptParser = prs;
return true;
@ -63,11 +63,11 @@ bool HIDUniversal::SetReportParser(uint8_t id, HIDReportParser *prs) {
}
HIDReportParser* HIDUniversal::GetReportParser(uint8_t id) {
if (!bHasReportId)
if(!bHasReportId)
return ((rptParsers[0].rptParser) ? rptParsers[0].rptParser : NULL);
for (uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
if (rptParsers[i].rptId == id)
for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
if(rptParsers[i].rptId == id)
return rptParsers[i].rptParser;
}
return NULL;
@ -90,16 +90,16 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
USBTRACE("HU Init\r\n");
if (bAddress)
if(bAddress)
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p->epinfo) {
if(!p->epinfo) {
USBTRACE("epinfo\r\n");
return USB_ERROR_EPINFO_IS_NULL;
}
@ -115,10 +115,10 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
if (!rcode)
if(!rcode)
len = (buf[0] > constBufSize) ? constBufSize : buf[0];
if (rcode) {
if(rcode) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
@ -131,7 +131,7 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor
@ -140,7 +140,7 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
if(rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
@ -156,15 +156,15 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
if (len)
if(len)
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
if (rcode)
if(rcode)
goto FailGetDevDescr;
num_of_conf = udd->bNumConfigurations;
@ -172,12 +172,12 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
USBTRACE2("NC:", num_of_conf);
for (uint8_t i = 0; i < num_of_conf; i++) {
for(uint8_t i = 0; i < num_of_conf; i++) {
//HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
ConfigDescParser<USB_CLASS_HID, 0, 0,
CP_MASK_COMPARE_CLASS> confDescrParser(this);
@ -185,14 +185,14 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
//rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
if (rcode)
if(rcode)
goto FailGetConfDescr;
if (bNumEP > 1)
if(bNumEP > 1)
break;
} // for
if (bNumEP < 2)
if(bNumEP < 2)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
// Assign epInfo to epinfo pointer
@ -203,16 +203,16 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Set Configuration Value
rcode = pUsb->setConf(bAddress, 0, bConfNum);
if (rcode)
if(rcode)
goto FailSetConfDescr;
for (uint8_t i = 0; i < bNumIface; i++) {
if (hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
for(uint8_t i = 0; i < bNumIface; i++) {
if(hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
continue;
rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
if (rcode && rcode != hrSTALL)
if(rcode && rcode != hrSTALL)
goto FailSetIdle;
}
@ -262,8 +262,8 @@ Fail:
}
HIDUniversal::HIDInterface* HIDUniversal::FindInterface(uint8_t iface, uint8_t alt, uint8_t proto) {
for (uint8_t i = 0; i < bNumIface && i < maxHidInterfaces; i++)
if (hidInterfaces[i].bmInterface == iface && hidInterfaces[i].bmAltSet == alt
for(uint8_t i = 0; i < bNumIface && i < maxHidInterfaces; i++)
if(hidInterfaces[i].bmInterface == iface && hidInterfaces[i].bmAltSet == alt
&& hidInterfaces[i].bmProtocol == proto)
return hidInterfaces + i;
return NULL;
@ -271,7 +271,7 @@ HIDUniversal::HIDInterface* HIDUniversal::FindInterface(uint8_t iface, uint8_t a
void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
// If the first configuration satisfies, the others are not concidered.
if (bNumEP > 1 && conf != bConfNum)
if(bNumEP > 1 && conf != bConfNum)
return;
//ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
@ -284,7 +284,7 @@ void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint
HIDInterface *piface = FindInterface(iface, alt, proto);
// Fill in interface structure in case of new interface
if (!piface) {
if(!piface) {
piface = hidInterfaces + bNumIface;
piface->bmInterface = iface;
piface->bmAltSet = alt;
@ -292,12 +292,12 @@ void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint
bNumIface++;
}
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
index = epInterruptInIndex;
else
index = epInterruptOutIndex;
if (index) {
if(index) {
// Fill in the endpoint info structure
epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
@ -323,34 +323,34 @@ uint8_t HIDUniversal::Release() {
}
bool HIDUniversal::BuffersIdentical(uint8_t len, uint8_t *buf1, uint8_t *buf2) {
for (uint8_t i = 0; i < len; i++)
if (buf1[i] != buf2[i])
for(uint8_t i = 0; i < len; i++)
if(buf1[i] != buf2[i])
return false;
return true;
}
void HIDUniversal::ZeroMemory(uint8_t len, uint8_t *buf) {
for (uint8_t i = 0; i < len; i++)
for(uint8_t i = 0; i < len; i++)
buf[i] = 0;
}
void HIDUniversal::SaveBuffer(uint8_t len, uint8_t *src, uint8_t *dest) {
for (uint8_t i = 0; i < len; i++)
for(uint8_t i = 0; i < len; i++)
dest[i] = src[i];
}
uint8_t HIDUniversal::Poll() {
uint8_t rcode = 0;
if (!bPollEnable)
if(!bPollEnable)
return 0;
if (qNextPollTime <= millis()) {
if(qNextPollTime <= millis()) {
qNextPollTime = millis() + 50;
uint8_t buf[constBuffLen];
for (uint8_t i = 0; i < bNumIface; i++) {
for(uint8_t i = 0; i < bNumIface; i++) {
uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
uint16_t read = (uint16_t)epInfo[index].maxPktSize;
@ -358,32 +358,32 @@ uint8_t HIDUniversal::Poll() {
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf);
if (rcode) {
if (rcode != hrNAK)
if(rcode) {
if(rcode != hrNAK)
USBTRACE3("(hiduniversal.h) Poll:", rcode, 0x81);
return rcode;
}
if (read > constBuffLen)
if(read > constBuffLen)
read = constBuffLen;
bool identical = BuffersIdentical(read, buf, prevBuf);
SaveBuffer(read, buf, prevBuf);
if (identical)
if(identical)
return 0;
Notify(PSTR("\r\nBuf: "), 0x80);
for (uint8_t i = 0; i < read; i++)
for(uint8_t i = 0; i < read; i++)
D_PrintHex<uint8_t > (buf[i], 0x80);
Notify(PSTR("\r\n"), 0x80);
HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0));
if (prs)
if(prs)
prs->Parse(this, bHasReportId, (uint8_t)read, buf);
}
}

View file

@ -76,4 +76,4 @@ public:
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
};
#endif // __HIDUNIVERSAL_H__
#endif // __HIDUNIVERSAL_H__

View file

@ -974,4 +974,4 @@ const char pstrUsageSoftControlAdjust [] PROGMEM = "Soft Ctrl Adj";
//const char *medInstrTitles3[];
//const char *medInstrTitles4[];
#endif //__HIDUSAGESTR_H__
#endif //__HIDUSAGESTR_H__

View file

@ -1043,4 +1043,4 @@ e-mail : support@circuitsathome.com
// pstrUsageSoftControlAdjust
//};
#endif // __HIDUSAGETITLEARRAYS_H__
#endif // __HIDUSAGETITLEARRAYS_H__

View file

@ -63,6 +63,7 @@
* Debug macros: Strings are stored in progmem (flash) instead of RAM.
*/
#define USBTRACE(s) (Notify(PSTR(s), 0x80))
#define USBTRACE1(s,l) (Notify(PSTR(s), l))
#define USBTRACE2(s,r) (Notify(PSTR(s), 0x80), D_PrintHex((r), 0x80), Notify(PSTR("\r\n"), 0x80))
#define USBTRACE3(s,r,l) (Notify(PSTR(s), l), D_PrintHex((r), l), Notify(PSTR("\r\n"), l))

View file

@ -17,7 +17,7 @@ const uint8_t BulkOnly::epInterruptInIndex = 3;
* @return media capacity
*/
uint32_t BulkOnly::GetCapacity(uint8_t lun) {
if (LUNOk[lun])
if(LUNOk[lun])
return CurrentCapacity[lun];
return 0LU;
}
@ -29,7 +29,7 @@ uint32_t BulkOnly::GetCapacity(uint8_t lun) {
* @return media sector size
*/
uint16_t BulkOnly::GetSectorSize(uint8_t lun) {
if (LUNOk[lun])
if(LUNOk[lun])
return CurrentSectorSize[lun];
return 0U;
}
@ -115,7 +115,7 @@ uint8_t BulkOnly::MediaCTL(uint8_t lun, uint8_t ctl) {
Notify(PSTR("-----------------\r\n"), 0x80);
uint8_t rcode = MASS_ERR_UNIT_NOT_READY;
if (bAddress) {
if(bAddress) {
CDB6_t cdb = CDB6_t(SCSI_CMD_START_STOP_UNIT, lun, ctl & 0x03, 0);
rcode = SCSITransaction6(&cdb, (uint16_t)0, NULL, (uint8_t)MASS_CMD_DIR_OUT);
} else {
@ -135,7 +135,7 @@ uint8_t BulkOnly::MediaCTL(uint8_t lun, uint8_t ctl) {
* @return 0 on success
*/
uint8_t BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf) {
if (!LUNOk[lun]) return MASS_ERR_NO_MEDIA;
if(!LUNOk[lun]) return MASS_ERR_NO_MEDIA;
Notify(PSTR("\r\nRead LUN:\t"), 0x80);
D_PrintHex<uint8_t > (lun, 0x90);
Notify(PSTR("\r\nLBA:\t\t"), 0x90);
@ -150,10 +150,10 @@ uint8_t BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t block
again:
uint8_t er = SCSITransaction10(&cdb, ((uint16_t)bsize * blocks), buf, (uint8_t)MASS_CMD_DIR_IN);
if (er == MASS_ERR_STALL) {
if(er == MASS_ERR_STALL) {
MediaCTL(lun, 1);
delay(150);
if (!TestUnitReady(lun)) goto again;
if(!TestUnitReady(lun)) goto again;
}
return er;
}
@ -169,8 +169,8 @@ again:
* @return 0 on success
*/
uint8_t BulkOnly::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t * buf) {
if (!LUNOk[lun]) return MASS_ERR_NO_MEDIA;
if (!WriteOk[lun]) return MASS_ERR_WRITE_PROTECTED;
if(!LUNOk[lun]) return MASS_ERR_NO_MEDIA;
if(!WriteOk[lun]) return MASS_ERR_WRITE_PROTECTED;
Notify(PSTR("\r\nWrite LUN:\t"), 0x80);
D_PrintHex<uint8_t > (lun, 0x90);
Notify(PSTR("\r\nLBA:\t\t"), 0x90);
@ -185,10 +185,10 @@ uint8_t BulkOnly::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t bloc
again:
uint8_t er = SCSITransaction10(&cdb, ((uint16_t)bsize * blocks), (void*)buf, (uint8_t)MASS_CMD_DIR_OUT);
if (er == MASS_ERR_WRITE_STALL) {
if(er == MASS_ERR_WRITE_STALL) {
MediaCTL(lun, 1);
delay(150);
if (!TestUnitReady(lun)) goto again;
if(!TestUnitReady(lun)) goto again;
}
return er;
}
@ -213,7 +213,7 @@ bPollEnable(false),
bLastUsbError(0) {
ClearAllEP();
dCBWTag = 0;
if (pUsb)
if(pUsb)
pUsb->RegisterDeviceClass(this);
}
@ -245,17 +245,17 @@ uint8_t BulkOnly::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
AddressPool &addrPool = pUsb->GetAddressPool();
if (bAddress)
if(bAddress)
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
// <TECHNICAL>
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p) {
if(!p) {
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
if (!p->epinfo) {
if(!p->epinfo) {
USBTRACE("epinfo\r\n");
return USB_ERROR_EPINFO_IS_NULL;
}
@ -273,13 +273,13 @@ uint8_t BulkOnly::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
if (rcode) {
if(rcode) {
goto FailGetDevDescr;
}
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor
@ -315,14 +315,14 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
AddressPool &addrPool = pUsb->GetAddressPool();
UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
// Assign new address to the device
delay(2000);
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
if(rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
@ -336,7 +336,7 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
@ -344,12 +344,12 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
USBTRACE2("NC:", num_of_conf);
for (uint8_t i = 0; i < num_of_conf; i++) {
for(uint8_t i = 0; i < num_of_conf; i++) {
ConfigDescParser< USB_CLASS_MASS_STORAGE,
MASS_SUBCLASS_SCSI,
MASS_PROTO_BBB,
@ -359,14 +359,14 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
rcode = pUsb->getConfDescr(bAddress, 0, i, &BulkOnlyParser);
if (rcode)
if(rcode)
goto FailGetConfDescr;
if (bNumEP > 1)
if(bNumEP > 1)
break;
}
if (bNumEP < 3)
if(bNumEP < 3)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
// Assign epInfo to epinfo pointer
@ -377,38 +377,38 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Set Configuration Value
rcode = pUsb->setConf(bAddress, 0, bConfNum);
if (rcode)
if(rcode)
goto FailSetConfDescr;
//Linux does a 1sec delay after this.
delay(1000);
rcode = GetMaxLUN(&bMaxLUN);
if (rcode)
if(rcode)
goto FailGetMaxLUN;
if (bMaxLUN >= MASS_MAX_SUPPORTED_LUN) bMaxLUN = MASS_MAX_SUPPORTED_LUN - 1;
if(bMaxLUN >= MASS_MAX_SUPPORTED_LUN) bMaxLUN = MASS_MAX_SUPPORTED_LUN - 1;
ErrorMessage<uint8_t > (PSTR("MaxLUN"), bMaxLUN);
delay(1000); // Delay a bit for slow firmware.
for (uint8_t lun = 0; lun <= bMaxLUN; lun++) {
for(uint8_t lun = 0; lun <= bMaxLUN; lun++) {
InquiryResponse response;
rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response);
if (rcode) {
if(rcode) {
ErrorMessage<uint8_t > (PSTR("Inquiry"), rcode);
} else {
#if 0
printf("LUN %i `", lun);
uint8_t *buf = response.VendorID;
for (int i = 0; i < 28; i++) printf("%c", buf[i]);
for(int i = 0; i < 28; i++) printf("%c", buf[i]);
printf("'\r\nQualifier %1.1X ", response.PeripheralQualifier);
printf("Device type %2.2X ", response.DeviceType);
printf("RMB %1.1X ", response.Removable);
printf("SSCS %1.1X ", response.SCCS);
uint8_t sv = response.Version;
printf("SCSI version %2.2X\r\nDevice conforms to ", sv);
switch (sv) {
switch(sv) {
case 0:
printf("No specific");
break;
@ -436,20 +436,20 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
printf(" standards.\r\n");
#endif
uint8_t tries = 0xf0;
while ((rcode = TestUnitReady(lun))) {
if (rcode == 0x08) break; // break on no media, this is OK to do.
while((rcode = TestUnitReady(lun))) {
if(rcode == 0x08) break; // break on no media, this is OK to do.
// try to lock media and spin up
if (tries < 14) {
if(tries < 14) {
LockMedia(lun, 1);
MediaCTL(lun, 1); // I actually have a USB stick that needs this!
} else delay(2 * (tries + 1));
tries++;
if (!tries) break;
if(!tries) break;
}
if (!rcode) {
if(!rcode) {
delay(1000);
LUNOk[lun] = CheckLUN(lun);
if (!LUNOk[lun]) LUNOk[lun] = CheckLUN(lun);
if(!LUNOk[lun]) LUNOk[lun] = CheckLUN(lun);
}
}
}
@ -459,7 +459,7 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
rcode = OnInit();
if (rcode)
if(rcode)
goto FailOnInit;
#ifdef DEBUG_USB_HOST
@ -489,11 +489,11 @@ FailGetMaxLUN:
goto Fail;
#endif
//#ifdef DEBUG_USB_HOST
//FailInvalidSectorSize:
// USBTRACE("Sector Size is NOT VALID: ");
// goto Fail;
//#endif
//#ifdef DEBUG_USB_HOST
//FailInvalidSectorSize:
// USBTRACE("Sector Size is NOT VALID: ");
// goto Fail;
//#endif
FailSetDevTblEntry:
#ifdef DEBUG_USB_HOST
@ -532,10 +532,10 @@ void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t
uint8_t index;
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
index = epInterruptInIndex;
else
if ((pep->bmAttributes & 0x02) == 2)
if((pep->bmAttributes & 0x02) == 2)
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
else
return;
@ -570,35 +570,35 @@ uint8_t BulkOnly::Release() {
boolean BulkOnly::CheckLUN(uint8_t lun) {
uint8_t rcode;
Capacity capacity;
for (uint8_t i = 0; i < 8; i++) capacity.data[i] = 0;
for(uint8_t i = 0; i < 8; i++) capacity.data[i] = 0;
rcode = ReadCapacity10(lun, (uint8_t*)capacity.data);
if (rcode) {
if(rcode) {
//printf(">>>>>>>>>>>>>>>>ReadCapacity returned %i\r\n", rcode);
return false;
}
ErrorMessage<uint8_t > (PSTR(">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun);
for (uint8_t i = 0; i < 8 /*sizeof (Capacity)*/; i++)
for(uint8_t i = 0; i < 8 /*sizeof (Capacity)*/; i++)
D_PrintHex<uint8_t > (capacity.data[i], 0x80);
Notify(PSTR("\r\n\r\n"), 0x80);
// Only 512/1024/2048/4096 are valid values!
uint32_t c = BMAKE32(capacity.data[4], capacity.data[5], capacity.data[6], capacity.data[7]);
if (c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) {
if(c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) {
return false;
}
// Store capacity information.
CurrentSectorSize[lun] = (uint16_t)(c); // & 0xFFFF);
CurrentCapacity[lun] = BMAKE32(capacity.data[0], capacity.data[1], capacity.data[2], capacity.data[3]) + 1;
if (CurrentCapacity[lun] == /*0xffffffffLU */ 0x01LU || CurrentCapacity[lun] == 0x00LU) {
if(CurrentCapacity[lun] == /*0xffffffffLU */ 0x01LU || CurrentCapacity[lun] == 0x00LU) {
// Buggy firmware will report 0xffffffff or 0 for no media
if (CurrentCapacity[lun])
if(CurrentCapacity[lun])
ErrorMessage<uint8_t > (PSTR(">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun);
return false;
}
delay(20);
Page3F(lun);
if (!TestUnitReady(lun)) return true;
if(!TestUnitReady(lun)) return true;
return false;
}
@ -608,18 +608,18 @@ boolean BulkOnly::CheckLUN(uint8_t lun) {
* Scan for media change on all LUNs
*/
void BulkOnly::CheckMedia() {
for (uint8_t lun = 0; lun <= bMaxLUN; lun++) {
if (TestUnitReady(lun)) {
for(uint8_t lun = 0; lun <= bMaxLUN; lun++) {
if(TestUnitReady(lun)) {
LUNOk[lun] = false;
continue;
}
if (!LUNOk[lun])
if(!LUNOk[lun])
LUNOk[lun] = CheckLUN(lun);
}
#if 0
printf("}}}}}}}}}}}}}}}}STATUS ");
for (uint8_t lun = 0; lun <= bMaxLUN; lun++) {
if (LUNOk[lun])
for(uint8_t lun = 0; lun <= bMaxLUN; lun++) {
if(LUNOk[lun])
printf("#");
else printf(".");
}
@ -636,10 +636,10 @@ void BulkOnly::CheckMedia() {
uint8_t BulkOnly::Poll() {
//uint8_t rcode = 0;
if (!bPollEnable)
if(!bPollEnable)
return 0;
if (qNextPollTime <= millis()) {
if(qNextPollTime <= millis()) {
CheckMedia();
}
//rcode = 0;
@ -664,7 +664,7 @@ uint8_t BulkOnly::Poll() {
uint8_t BulkOnly::GetMaxLUN(uint8_t *plun) {
uint8_t ret = pUsb->ctrlReq(bAddress, 0, bmREQ_MASSIN, MASS_REQ_GET_MAX_LUN, 0, 0, bIface, 1, 1, plun, NULL);
if (ret == hrSTALL)
if(ret == hrSTALL)
*plun = 0;
return 0;
@ -696,7 +696,7 @@ uint8_t BulkOnly::Inquiry(uint8_t lun, uint16_t bsize, uint8_t *buf) {
*/
uint8_t BulkOnly::TestUnitReady(uint8_t lun) {
//SetCurLUN(lun);
if (!bAddress)
if(!bAddress)
return MASS_ERR_UNIT_NOT_READY;
Notify(PSTR("\r\nTestUnitReady\r\n"), 0x80);
@ -752,15 +752,15 @@ uint8_t BulkOnly::ReadCapacity10(uint8_t lun, uint8_t *buf) {
*/
uint8_t BulkOnly::Page3F(uint8_t lun) {
uint8_t buf[192];
for (int i = 0; i < 192; i++) {
for(int i = 0; i < 192; i++) {
buf[i] = 0x00;
}
WriteOk[lun] = true;
uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
if (!rc) {
if(!rc) {
WriteOk[lun] = ((buf[2] & 0x80) == 0);
Notify(PSTR("Mode Sense: "), 0x80);
for (int i = 0; i < 4; i++) {
for(int i = 0; i < 4; i++) {
D_PrintHex<uint8_t > (buf[i], 0x80);
Notify(PSTR(" "), 0x80);
}
@ -803,15 +803,15 @@ uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) {
* @return
*/
uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
if (index == 0)
if(index == 0)
return 0;
uint8_t ret = 0;
while ((ret = (pUsb->ctrlReq(bAddress, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT, USB_REQUEST_CLEAR_FEATURE, USB_FEATURE_ENDPOINT_HALT, 0, ((index == epDataInIndex) ? (0x80 | epInfo[index].epAddr) : epInfo[index].epAddr), 0, 0, NULL, NULL)) == 0x01))
while((ret = (pUsb->ctrlReq(bAddress, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT, USB_REQUEST_CLEAR_FEATURE, USB_FEATURE_ENDPOINT_HALT, 0, ((index == epDataInIndex) ? (0x80 | epInfo[index].epAddr) : epInfo[index].epAddr), 0, 0, NULL, NULL)) == 0x01))
delay(6);
if (ret) {
if(ret) {
ErrorMessage<uint8_t > (PSTR("ClearEpHalt"), ret);
ErrorMessage<uint8_t > (PSTR("EP"), ((index == epDataInIndex) ? (0x80 | epInfo[index].epAddr) : epInfo[index].epAddr));
return ret;
@ -827,7 +827,7 @@ uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
*
*/
void BulkOnly::Reset() {
while (pUsb->ctrlReq(bAddress, 0, bmREQ_MASSOUT, MASS_REQ_BOMSR, 0, 0, bIface, 0, 0, NULL, NULL) == 0x01) delay(6);
while(pUsb->ctrlReq(bAddress, 0, bmREQ_MASSOUT, MASS_REQ_BOMSR, 0, 0, bIface, 0, 0, NULL, NULL) == 0x01) delay(6);
}
/**
@ -855,7 +855,7 @@ uint8_t BulkOnly::ResetRecovery() {
* Clear all EP data and clear all LUN status
*/
void BulkOnly::ClearAllEP() {
for (uint8_t i = 0; i < MASS_MAX_ENDPOINTS; i++) {
for(uint8_t i = 0; i < MASS_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
@ -863,7 +863,7 @@ void BulkOnly::ClearAllEP() {
epInfo[i].bmNakPower = USB_NAK_DEFAULT;
}
for (uint8_t i = 0; i < MASS_MAX_SUPPORTED_LUN; i++) {
for(uint8_t i = 0; i < MASS_MAX_SUPPORTED_LUN; i++) {
LUNOk[i] = false;
WriteOk[i] = false;
CurrentCapacity[i] = 0lu;
@ -888,11 +888,11 @@ void BulkOnly::ClearAllEP() {
* @return
*/
bool BulkOnly::IsValidCSW(CommandStatusWrapper *pcsw, CommandBlockWrapperBase *pcbw) {
if (pcsw->dCSWSignature != MASS_CSW_SIGNATURE) {
if(pcsw->dCSWSignature != MASS_CSW_SIGNATURE) {
Notify(PSTR("CSW:Sig error\r\n"), 0x80);
return false;
}
if (pcsw->dCSWTag != pcbw->dCBWTag) {
if(pcsw->dCSWTag != pcbw->dCBWTag) {
Notify(PSTR("CSW:Wrong tag\r\n"), 0x80);
return false;
}
@ -912,12 +912,12 @@ uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
bLastUsbError = error;
//if (error)
//ClearEpHalt(index);
while (error && count) {
if (error != hrSUCCESS) {
while(error && count) {
if(error != hrSUCCESS) {
ErrorMessage<uint8_t > (PSTR("USB Error"), error);
ErrorMessage<uint8_t > (PSTR("Index"), index);
}
switch (error) {
switch(error) {
// case hrWRONGPID:
case hrSUCCESS:
return MASS_ERR_SUCCESS;
@ -927,15 +927,15 @@ uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
case hrTIMEOUT:
case hrJERR: return MASS_ERR_DEVICE_DISCONNECTED;
case hrSTALL:
if (index == 0)
if(index == 0)
return MASS_ERR_STALL;
ClearEpHalt(index);
if (index != epDataInIndex)
if(index != epDataInIndex)
return MASS_ERR_WRITE_STALL;
return MASS_ERR_STALL;
case hrNAK:
if (index == 0)
if(index == 0)
return MASS_ERR_UNIT_BUSY;
return MASS_ERR_UNIT_BUSY;
@ -944,10 +944,10 @@ uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
// I have only ran into one device that has this firmware bug, and this is
// the only clean way to get back into sync with the buggy device firmware.
// --AJK
if (bAddress && bConfNum) {
if(bAddress && bConfNum) {
error = pUsb->setConf(bAddress, 0, bConfNum);
if (error)
if(error)
break;
}
return MASS_ERR_SUCCESS;
@ -999,33 +999,33 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
SetCurLUN(pcbw->bmCBWLUN);
ErrorMessage<uint32_t > (PSTR("CBW.dCBWTag"), pcbw->dCBWTag);
while ((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw)) == hrBUSY) delay(1);
while((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw)) == hrBUSY) delay(1);
ret = HandleUsbError(usberr, epDataOutIndex);
//ret = HandleUsbError(pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw), epDataOutIndex);
if (ret) {
if(ret) {
ErrorMessage<uint8_t > (PSTR("============================ CBW"), ret);
} else {
if (bytes) {
if (!write) {
if(bytes) {
if(!write) {
#if MS_WANT_PARSER
if (callback) {
if(callback) {
uint8_t rbuf[bytes];
while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, rbuf)) == hrBUSY) delay(1);
if (usberr == hrSUCCESS) ((USBReadParser*)buf)->Parse(bytes, rbuf, 0);
while((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, rbuf)) == hrBUSY) delay(1);
if(usberr == hrSUCCESS) ((USBReadParser*)buf)->Parse(bytes, rbuf, 0);
} else {
#endif
while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*)buf)) == hrBUSY) delay(1);
while((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*)buf)) == hrBUSY) delay(1);
#if MS_WANT_PARSER
}
#endif
ret = HandleUsbError(usberr, epDataInIndex);
} else {
while ((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, bytes, (uint8_t*)buf)) == hrBUSY) delay(1);
while((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, bytes, (uint8_t*)buf)) == hrBUSY) delay(1);
ret = HandleUsbError(usberr, epDataOutIndex);
}
if (ret) {
if(ret) {
ErrorMessage<uint8_t > (PSTR("============================ DAT"), ret);
}
}
@ -1034,13 +1034,13 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
{
bytes = sizeof (CommandStatusWrapper);
int tries = 2;
while (tries--) {
while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*) & csw)) == hrBUSY) delay(1);
if (!usberr) break;
while(tries--) {
while((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*) & csw)) == hrBUSY) delay(1);
if(!usberr) break;
ClearEpHalt(epDataInIndex);
if (tries) ResetRecovery();
if(tries) ResetRecovery();
}
if (!ret) {
if(!ret) {
Notify(PSTR("CBW:\t\tOK\r\n"), 0x80);
Notify(PSTR("Data Stage:\tOK\r\n"), 0x80);
} else {
@ -1049,11 +1049,11 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
return ret;
}
ret = HandleUsbError(usberr, epDataInIndex);
if (ret) {
if(ret) {
ErrorMessage<uint8_t > (PSTR("============================ CSW"), ret);
}
if (usberr == hrSUCCESS) {
if (IsValidCSW(&csw, pcbw)) {
if(usberr == hrSUCCESS) {
if(IsValidCSW(&csw, pcbw)) {
//ErrorMessage<uint32_t > (PSTR("CSW.dCBWTag"), csw.dCSWTag);
//ErrorMessage<uint8_t > (PSTR("bCSWStatus"), csw.bCSWStatus);
//ErrorMessage<uint32_t > (PSTR("dCSWDataResidue"), csw.dCSWDataResidue);
@ -1082,7 +1082,7 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
* @return
*/
uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
if (lun > bMaxLUN)
if(lun > bMaxLUN)
return MASS_ERR_INVALID_LUN;
bTheLUN = lun;
return MASS_ERR_SUCCESS;
@ -1097,7 +1097,7 @@ uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
uint8_t ret = 0;
switch (status) {
switch(status) {
case 0: return MASS_ERR_SUCCESS;
case 2:
@ -1113,13 +1113,13 @@ uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
ret = RequestSense(bTheLUN, sizeof (RequestSenseResponce), (uint8_t*) & rsp);
if (ret) {
if(ret) {
return MASS_ERR_GENERAL_SCSI_ERROR;
}
ErrorMessage<uint8_t > (PSTR("Response Code"), rsp.bResponseCode);
if (rsp.bResponseCode & 0x80) {
if(rsp.bResponseCode & 0x80) {
Notify(PSTR("Information field: "), 0x80);
for (int i = 0; i < 4; i++) {
for(int i = 0; i < 4; i++) {
D_PrintHex<uint8_t > (rsp.CmdSpecificInformation[i], 0x80);
Notify(PSTR(" "), 0x80);
}
@ -1129,23 +1129,23 @@ uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
ErrorMessage<uint8_t > (PSTR("Add Sense Code"), rsp.bAdditionalSenseCode);
ErrorMessage<uint8_t > (PSTR("Add Sense Qual"), rsp.bAdditionalSenseQualifier);
// warning, this is not testing ASQ, only SK and ASC.
switch (rsp.bmSenseKey) {
switch(rsp.bmSenseKey) {
case SCSI_S_UNIT_ATTENTION:
switch (rsp.bAdditionalSenseCode) {
switch(rsp.bAdditionalSenseCode) {
case SCSI_ASC_MEDIA_CHANGED:
return MASS_ERR_MEDIA_CHANGED;
default:
return MASS_ERR_UNIT_NOT_READY;
}
case SCSI_S_NOT_READY:
switch (rsp.bAdditionalSenseCode) {
switch(rsp.bAdditionalSenseCode) {
case SCSI_ASC_MEDIUM_NOT_PRESENT:
return MASS_ERR_NO_MEDIA;
default:
return MASS_ERR_UNIT_NOT_READY;
}
case SCSI_S_ILLEGAL_REQUEST:
switch (rsp.bAdditionalSenseCode) {
switch(rsp.bAdditionalSenseCode) {
case SCSI_ASC_LBA_OUT_OF_RANGE:
return MASS_ERR_BAD_LBA;
default:
@ -1207,7 +1207,7 @@ void BulkOnly::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR * ep_ptr) {
/* We won't be needing this... */
uint8_t BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, USBReadParser * prs) {
#if MS_WANT_PARSER
if (!LUNOk[lun]) return MASS_ERR_NO_MEDIA;
if(!LUNOk[lun]) return MASS_ERR_NO_MEDIA;
Notify(PSTR("\r\nRead (With parser)\r\n"), 0x80);
Notify(PSTR("---------\r\n"), 0x80);

View file

@ -396,7 +396,7 @@ public:
// Type punning can cause optimization problems and bugs.
// Using reinterpret_cast to a dreinterpretifferent object is the proper way to do this.
//(((BASICCDB_t *) CBWCB)->LUN) = cmd;
BASICCDB_t *x = reinterpret_cast<BASICCDB_t *> (CBWCB);
BASICCDB_t *x = reinterpret_cast<BASICCDB_t *>(CBWCB);
x->LUN = cmd;
}
@ -516,7 +516,7 @@ public:
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
virtual boolean DEVCLASSOK(uint8_t klass) {
return(klass == USB_CLASS_MASS_STORAGE);
return (klass == USB_CLASS_MASS_STORAGE);
}
uint8_t SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);

View file

@ -52,14 +52,14 @@ void Max_LCD::init() {
}
void Max_LCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
if (lines > 1) {
if(lines > 1) {
_displayfunction |= LCD_2LINE;
}
_numlines = lines;
_currline = 0;
// for some 1 line displays you can select a 10 pixel high font
if ((dotsize != 0) && (lines == 1)) {
if((dotsize != 0) && (lines == 1)) {
_displayfunction |= LCD_5x10DOTS;
}
@ -123,7 +123,7 @@ void Max_LCD::home() {
void Max_LCD::setCursor(uint8_t col, uint8_t row) {
int row_offsets[] = {0x00, 0x40, 0x14, 0x54};
if (row > _numlines) {
if(row > _numlines) {
row = _numlines - 1; // we count rows starting w/0
}
@ -211,7 +211,7 @@ void Max_LCD::noAutoscroll(void) {
void Max_LCD::createChar(uint8_t location, uint8_t charmap[]) {
location &= 0x7; // we only have 8 locations 0-7
command(LCD_SETCGRAMADDR | (location << 3));
for (int i = 0; i < 8; i++) {
for(int i = 0; i < 8; i++) {
write(charmap[i]);
}
}
@ -224,11 +224,13 @@ inline void Max_LCD::command(uint8_t value) {
}
#if defined(ARDUINO) && ARDUINO >=100
inline size_t Max_LCD::write(uint8_t value) {
LCD_sendchar(value);
return 1; // Assume success
}
#else
inline void Max_LCD::write(uint8_t value) {
LCD_sendchar(value);
}

View file

@ -62,8 +62,7 @@ e-mail : support@circuitsathome.com
#define LCD_5x10DOTS 0x04
#define LCD_5x8DOTS 0x00
class Max_LCD : public Print
{
class Max_LCD : public Print {
USB *pUsb;
public:
@ -104,4 +103,4 @@ private:
uint8_t _numlines, _currline;
};
#endif
#endif

View file

@ -22,7 +22,7 @@ e-mail : support@circuitsathome.com
int UsbDEBUGlvl = 0x80;
void E_Notifyc(char c, int lvl) {
if (UsbDEBUGlvl < lvl) return;
if(UsbDEBUGlvl < lvl) return;
#if defined(ARDUINO) && ARDUINO >=100
USB_HOST_SERIAL.print(c);
#else
@ -32,23 +32,23 @@ void E_Notifyc(char c, int lvl) {
}
void E_Notify(char const * msg, int lvl) {
if (UsbDEBUGlvl < lvl) return;
if (!msg) return;
if(UsbDEBUGlvl < lvl) return;
if(!msg) return;
char c;
while ((c = pgm_read_byte(msg++))) E_Notifyc(c, lvl);
while((c = pgm_read_byte(msg++))) E_Notifyc(c, lvl);
}
void E_NotifyStr(char const * msg, int lvl) {
if (UsbDEBUGlvl < lvl) return;
if (!msg) return;
if(UsbDEBUGlvl < lvl) return;
if(!msg) return;
char c;
while ((c = *msg++)) E_Notifyc(c, lvl);
while((c = *msg++)) E_Notifyc(c, lvl);
}
void E_Notify(uint8_t b, int lvl) {
if (UsbDEBUGlvl < lvl) return;
if(UsbDEBUGlvl < lvl) return;
#if defined(ARDUINO) && ARDUINO >=100
USB_HOST_SERIAL.print(b);
#else
@ -58,12 +58,13 @@ void E_Notify(uint8_t b, int lvl) {
}
void E_Notify(double d, int lvl) {
if (UsbDEBUGlvl < lvl) return;
if(UsbDEBUGlvl < lvl) return;
USB_HOST_SERIAL.print(d);
//USB_HOST_SERIAL.flush();
}
#ifdef DEBUG_USB_HOST
void NotifyFailGetDevDescr(void) {
Notify(PSTR("\r\ngetDevDescr "), 0x80);
}
@ -71,6 +72,7 @@ void NotifyFailGetDevDescr(void) {
void NotifyFailSetDevTblEntry(void) {
Notify(PSTR("\r\nsetDevTblEn "), 0x80);
}
void NotifyFailGetConfDescr(void) {
Notify(PSTR("\r\ngetConf "), 0x80);
}

View file

@ -17,14 +17,14 @@ e-mail : support@circuitsathome.com
#include "Usb.h"
bool MultiByteValueParser::Parse(uint8_t **pp, uint16_t *pcntdn) {
if (!pBuf) {
if(!pBuf) {
Notify(PSTR("Buffer pointer is NULL!\r\n"), 0x80);
return false;
}
for (; countDown && (*pcntdn); countDown--, (*pcntdn)--, (*pp)++)
for(; countDown && (*pcntdn); countDown--, (*pcntdn)--, (*pp)++)
pBuf[valueSize - countDown] = (**pp);
if (countDown)
if(countDown)
return false;
countDown = valueSize;
@ -32,14 +32,14 @@ bool MultiByteValueParser::Parse(uint8_t **pp, uint16_t *pcntdn) {
}
bool PTPListParser::Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me) {
switch (nStage) {
switch(nStage) {
case 0:
pBuf->valueSize = lenSize;
theParser.Initialize(pBuf);
nStage = 1;
case 1:
if (!theParser.Parse(pp, pcntdn))
if(!theParser.Parse(pp, pcntdn))
return false;
arLen = 0;
@ -53,11 +53,11 @@ bool PTPListParser::Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf,
nStage = 3;
case 3:
for (; arLenCntdn; arLenCntdn--) {
if (!theParser.Parse(pp, pcntdn))
for(; arLenCntdn; arLenCntdn--) {
if(!theParser.Parse(pp, pcntdn))
return false;
if (pf)
if(pf)
pf(pBuf, (arLen - arLenCntdn), me);
}

View file

@ -40,7 +40,7 @@ public:
};
void Initialize(MultiValueBuffer * const pbuf) {
pBuf = (uint8_t*) pbuf->pValue;
pBuf = (uint8_t*)pbuf->pValue;
countDown = valueSize = pbuf->valueSize;
};
@ -58,7 +58,7 @@ public:
};
void Initialize(MultiValueBuffer *pbuf) {
pBuf = (uint8_t*) pbuf->pValue;
pBuf = (uint8_t*)pbuf->pValue;
countDown = 0;
};
@ -73,7 +73,7 @@ public:
if(!countDown)
nStage = 0;
};
return(!countDown);
return (!countDown);
};
};

View file

@ -24,7 +24,7 @@ void E_Notifyc(char c, int lvl);
template <class T>
void PrintHex(T val, int lvl) {
int num_nibbles = sizeof(T) * 2;
int num_nibbles = sizeof (T) * 2;
do {
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
@ -35,7 +35,7 @@ void PrintHex(T val, int lvl) {
template <class T>
void PrintBin(T val, int lvl) {
for(T mask = (((T) 1) << ((sizeof(T) << 3) - 1)); mask; mask >>= 1)
for(T mask = (((T)1) << ((sizeof (T) << 3) - 1)); mask; mask >>= 1)
if(val & mask)
E_Notifyc('1', lvl);
else
@ -44,7 +44,7 @@ void PrintBin(T val, int lvl) {
template <class T>
void SerialPrintHex(T val) {
int num_nibbles = sizeof(T) * 2;
int num_nibbles = sizeof (T) * 2;
do {
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
@ -55,7 +55,7 @@ void SerialPrintHex(T val) {
template <class T>
void PrintHex2(Print *prn, T val) {
T mask = (((T) 1) << (((sizeof(T) << 1) - 1) << 2));
T mask = (((T)1) << (((sizeof (T) << 1) - 1) << 2));
while(mask > 1) {
if(val < mask)
@ -63,19 +63,19 @@ void PrintHex2(Print *prn, T val) {
mask >>= 4;
}
prn->print((T) val, HEX);
prn->print((T)val, HEX);
}
template <class T> void D_PrintHex(T val, int lvl) {
#ifdef DEBUG_USB_HOST
PrintHex<T>(val, lvl);
PrintHex<T > (val, lvl);
#endif
}
template <class T>
void D_PrintBin(T val, int lvl) {
#ifdef DEBUG_USB_HOST
PrintBin<T>(val, lvl);
PrintBin<T > (val, lvl);
#endif
}

View file

@ -22,14 +22,19 @@ e-mail : support@circuitsathome.com
extern int UsbDEBUGlvl;
// This parser does absolutely nothing with the data, just swallows it.
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
class SinkParser : public BASE_CLASS {
public:
SinkParser() {};
void Initialize() {};
void Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset) {};
SinkParser() {
};
void Initialize() {
};
void Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset) {
};
};

View file

@ -162,7 +162,7 @@ uint8_t* MAX3421e< SPI_SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t*
#endif
SPI_SS::Set();
XMEM_RELEASE_SPI();
return( data_p);
return ( data_p);
}
/* GPIO write */
/*GPIO byte is split between 2 registers, so two writes are needed to write one byte */
@ -194,7 +194,7 @@ uint8_t MAX3421e< SPI_SS, INTR >::regRd(uint8_t reg) {
uint8_t rv = SPDR;
#endif
XMEM_RELEASE_SPI();
return(rv);
return (rv);
}
/* multiple-byte register read */
@ -229,7 +229,7 @@ uint8_t* MAX3421e< SPI_SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t*
#endif
SPI_SS::Set();
XMEM_RELEASE_SPI();
return( data_p);
return ( data_p);
}
/* GPIO read. See gpioWr for explanation */
@ -240,7 +240,7 @@ uint8_t MAX3421e< SPI_SS, INTR >::gpioRd() {
gpin = regRd(rIOPINS2); //pins 4-7
gpin &= 0xf0; //clean lower nibble
gpin |= (regRd(rIOPINS1) >> 4); //shift low bits and OR with upper from previous operation.
return( gpin);
return ( gpin);
}
/* reset MAX3421E. Returns number of cycles it took for PLL to stabilize after reset
@ -255,7 +255,7 @@ uint16_t MAX3421e< SPI_SS, INTR >::reset() {
break;
}
}
return( i);
return ( i);
}
/* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
@ -276,7 +276,7 @@ int8_t MAX3421e< SPI_SS, INTR >::Init() {
regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL));
if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
return( -1);
return ( -1);
}
regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST); // set pull-downs, Host
@ -292,7 +292,7 @@ int8_t MAX3421e< SPI_SS, INTR >::Init() {
regWr(rHIRQ, bmCONDETIRQ); //clear connection detect interrupt
regWr(rCPUCTL, 0x01); //enable interrupt pin
return( 0);
return ( 0);
}
/* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
@ -312,7 +312,7 @@ int8_t MAX3421e< SPI_SS, INTR >::Init(int mseconds) {
regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL | GPX_VBDET));
if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
return( -1);
return ( -1);
}
// Delay a minimum of 1 second to ensure any capacitors are drained.
@ -336,7 +336,7 @@ int8_t MAX3421e< SPI_SS, INTR >::Init(int mseconds) {
// GPX pin on. This is done here so that busprobe will fail if we have a switch connected.
regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL));
return( 0);
return ( 0);
}
/* probe bus to determine device presence and speed and switch host to this speed */
@ -391,7 +391,7 @@ uint8_t MAX3421e< SPI_SS, INTR >::Task(void) {
// GpxHandler();
// }
// usbSM(); //USB state machine
return( rcode);
return ( rcode);
}
template< typename SPI_SS, typename INTR >
@ -408,7 +408,7 @@ uint8_t MAX3421e< SPI_SS, INTR >::IntHandler() {
}
/* End HIRQ interrupts handling, clear serviced IRQs */
regWr(rHIRQ, HIRQ_sendback);
return( HIRQ_sendback);
return ( HIRQ_sendback);
}
//template< typename SPI_SS, typename INTR >
//uint8_t MAX3421e< SPI_SS, INTR >::GpxHandler()

View file

@ -35,7 +35,7 @@ bPollEnable(false) {
epInfo[1].epAttribs = 0;
epInfo[1].bmNakPower = USB_NAK_NOWAIT;
if (pUsb)
if(pUsb)
pUsb->RegisterDeviceClass(this);
}
@ -57,133 +57,133 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
//switch (bInitState) {
// case 0:
if (bAddress)
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
if(bAddress)
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)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p->epinfo)
return USB_ERROR_EPINFO_IS_NULL;
if(!p->epinfo)
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;
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
p->epinfo = epInfo;
// 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, 8, (uint8_t*)buf);
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
p->lowspeed = false;
p->lowspeed = false;
if (!rcode)
len = (buf[0] > 32) ? 32 : buf[0];
if(!rcode)
len = (buf[0] > 32) ? 32 : buf[0];
if (rcode) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
return rcode;
}
if(rcode) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
return rcode;
}
// Extract device class from device descriptor
// If device class is not a hub return
if (udd->bDeviceClass != 0x09)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
// Extract device class from device descriptor
// If device class is not a hub return
if(udd->bDeviceClass != 0x09)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, (udd->bDeviceClass == 0x09) ? true : false, port);
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, (udd->bDeviceClass == 0x09) ? true : false, port);
if (!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor
epInfo[0].maxPktSize = udd->bMaxPacketSize0;
// Extract Max Packet Size from the device descriptor
epInfo[0].maxPktSize = udd->bMaxPacketSize0;
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
addrPool.FreeAddress(bAddress);
bAddress = 0;
return rcode;
}
if(rcode) {
// Restore p->epinfo
p->epinfo = oldep_ptr;
addrPool.FreeAddress(bAddress);
bAddress = 0;
return rcode;
}
//USBTRACE2("\r\nHub address: ", bAddress );
//USBTRACE2("\r\nHub address: ", bAddress );
// Restore p->epinfo
p->epinfo = oldep_ptr;
// Restore p->epinfo
p->epinfo = oldep_ptr;
if (len)
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
if(len)
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
if (rcode)
goto FailGetDevDescr;
if(rcode)
goto FailGetDevDescr;
// Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 2, epInfo);
// Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 2, epInfo);
if (rcode)
goto FailSetDevTblEntry;
if(rcode)
goto FailSetDevTblEntry;
// bInitState = 1;
// case 1:
// Get hub descriptor
rcode = GetHubDescriptor(0, 8, buf);
// Get hub descriptor
rcode = GetHubDescriptor(0, 8, buf);
if (rcode)
goto FailGetHubDescr;
if(rcode)
goto FailGetHubDescr;
// Save number of ports for future use
bNbrPorts = hd->bNbrPorts;
// Save number of ports for future use
bNbrPorts = hd->bNbrPorts;
// bInitState = 2;
// case 2:
// Read configuration Descriptor in Order To Obtain Proper Configuration Value
rcode = pUsb->getConfDescr(bAddress, 0, 8, 0, buf);
// Read configuration Descriptor in Order To Obtain Proper Configuration Value
rcode = pUsb->getConfDescr(bAddress, 0, 8, 0, buf);
if (!rcode) {
cd_len = ucd->wTotalLength;
rcode = pUsb->getConfDescr(bAddress, 0, cd_len, 0, buf);
}
if (rcode)
goto FailGetConfDescr;
if(!rcode) {
cd_len = ucd->wTotalLength;
rcode = pUsb->getConfDescr(bAddress, 0, cd_len, 0, buf);
}
if(rcode)
goto FailGetConfDescr;
// The following code is of no practical use in real life applications.
// It only intended for the usb protocol sniffer to properly parse hub-class requests.
{
uint8_t buf2[24];
// The following code is of no practical use in real life applications.
// It only intended for the usb protocol sniffer to properly parse hub-class requests.
{
uint8_t buf2[24];
rcode = pUsb->getConfDescr(bAddress, 0, buf[0], 0, buf2);
rcode = pUsb->getConfDescr(bAddress, 0, buf[0], 0, buf2);
if (rcode)
goto FailGetConfDescr;
}
if(rcode)
goto FailGetConfDescr;
}
// Set Configuration Value
rcode = pUsb->setConf(bAddress, 0, buf[5]);
// Set Configuration Value
rcode = pUsb->setConf(bAddress, 0, buf[5]);
if (rcode)
goto FailSetConfDescr;
if(rcode)
goto FailSetConfDescr;
// bInitState = 3;
// case 3:
// Power on all ports
for (uint8_t j = 1; j <= bNbrPorts; j++)
SetPortFeature(HUB_FEATURE_PORT_POWER, j, 0); //HubPortPowerOn(j);
// Power on all ports
for(uint8_t j = 1; j <= bNbrPorts; j++)
SetPortFeature(HUB_FEATURE_PORT_POWER, j, 0); //HubPortPowerOn(j);
pUsb->SetHubPreMask();
bPollEnable = true;
pUsb->SetHubPreMask();
bPollEnable = true;
// bInitState = 0;
//}
//bInitState = 0;
@ -214,7 +214,7 @@ Fail:
uint8_t USBHub::Release() {
pUsb->GetAddressPool().FreeAddress(bAddress);
if (bAddress == 0x41)
if(bAddress == 0x41)
pUsb->SetHubPreMask();
bAddress = 0;
@ -227,10 +227,10 @@ uint8_t USBHub::Release() {
uint8_t USBHub::Poll() {
uint8_t rcode = 0;
if (!bPollEnable)
if(!bPollEnable)
return 0;
if (qNextPollTime <= millis()) {
if(qNextPollTime <= millis()) {
rcode = CheckHubStatus();
qNextPollTime = millis() + 100;
}
@ -244,7 +244,7 @@ uint8_t USBHub::CheckHubStatus() {
rcode = pUsb->inTransfer(bAddress, 1, &read, buf);
if (rcode)
if(rcode)
return rcode;
//if (buf[0] & 0x01) // Hub Status Change
@ -258,36 +258,36 @@ uint8_t USBHub::CheckHubStatus() {
// return rcode;
// }
//}
for (uint8_t port = 1, mask = 0x02; port < 8; mask <<= 1, port++) {
if (buf[0] & mask) {
for(uint8_t port = 1, mask = 0x02; port < 8; mask <<= 1, port++) {
if(buf[0] & mask) {
HubEvent evt;
evt.bmEvent = 0;
rcode = GetPortStatus(port, 4, evt.evtBuff);
if (rcode)
if(rcode)
continue;
rcode = PortStatusChange(port, evt);
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
if(rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
return 0;
if (rcode)
if(rcode)
return rcode;
}
} // for
for (uint8_t port = 1; port <= bNbrPorts; port++) {
for(uint8_t port = 1; port <= bNbrPorts; port++) {
HubEvent evt;
evt.bmEvent = 0;
rcode = GetPortStatus(port, 4, evt.evtBuff);
if (rcode)
if(rcode)
continue;
if ((evt.bmStatus & bmHUB_PORT_STATE_CHECK_DISABLED) != bmHUB_PORT_STATE_DISABLED)
if((evt.bmStatus & bmHUB_PORT_STATE_CHECK_DISABLED) != bmHUB_PORT_STATE_DISABLED)
continue;
// Emulate connection event for the port
@ -295,10 +295,10 @@ uint8_t USBHub::CheckHubStatus() {
rcode = PortStatusChange(port, evt);
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
if(rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
return 0;
if (rcode)
if(rcode)
return rcode;
} // for
return 0;
@ -314,10 +314,10 @@ void USBHub::ResetHubPort(uint8_t port) {
SetPortFeature(HUB_FEATURE_PORT_RESET, port, 0);
for (int i = 0; i < 3; i++) {
for(int i = 0; i < 3; i++) {
rcode = GetPortStatus(port, 4, evt.evtBuff);
if (rcode) break; // Some kind of error, bail.
if (evt.bmEvent == bmHUB_PORT_EVENT_RESET_COMPLETE || evt.bmEvent == bmHUB_PORT_EVENT_LS_RESET_COMPLETE) {
if(rcode) break; // Some kind of error, bail.
if(evt.bmEvent == bmHUB_PORT_EVENT_RESET_COMPLETE || evt.bmEvent == bmHUB_PORT_EVENT_LS_RESET_COMPLETE) {
break;
}
delay(100); // simulate polling.
@ -328,11 +328,11 @@ void USBHub::ResetHubPort(uint8_t port) {
}
uint8_t USBHub::PortStatusChange(uint8_t port, HubEvent &evt) {
switch (evt.bmEvent) {
switch(evt.bmEvent) {
// Device connected event
case bmHUB_PORT_EVENT_CONNECT:
case bmHUB_PORT_EVENT_LS_CONNECT:
if (bResetInitiated)
if(bResetInitiated)
return 0;
ClearPortFeature(HUB_FEATURE_C_PORT_ENABLE, port, 0);
@ -379,7 +379,7 @@ void PrintHubPortStatus(USBHub *hubptr, uint8_t addr, uint8_t port, bool print_c
rcode = hubptr->GetPortStatus(port, 4, evt.evtBuff);
if (rcode) {
if(rcode) {
USB_HOST_SERIAL.println("ERROR!");
return;
}
@ -408,7 +408,7 @@ void PrintHubPortStatus(USBHub *hubptr, uint8_t addr, uint8_t port, bool print_c
USB_HOST_SERIAL.print("INDICATOR:\t");
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_INDICATOR) > 0, DEC);
if (!print_changes)
if(!print_changes)
return;
USB_HOST_SERIAL.println("\r\nChange");

View file

@ -170,7 +170,7 @@ class USBHub : USBDeviceConfig {
uint8_t bAddress; // address
uint8_t bNbrPorts; // number of ports
// uint8_t bInitState; // initialization state variable
// uint8_t bInitState; // initialization state variable
uint32_t qNextPollTime; // next poll time
bool bPollEnable; // poll enable flag
@ -195,52 +195,56 @@ public:
virtual uint8_t Release();
virtual uint8_t Poll();
virtual void ResetHubPort(uint8_t port);
virtual uint8_t GetAddress() {
return bAddress;
};
virtual boolean DEVCLASSOK(uint8_t klass) { return (klass == 0x09); }
virtual boolean DEVCLASSOK(uint8_t klass) {
return (klass == 0x09);
}
};
// Clear Hub Feature
inline uint8_t USBHub::ClearHubFeature(uint8_t fid) {
return( pUsb->ctrlReq(bAddress, 0, bmREQ_CLEAR_HUB_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, 0, NULL, NULL));
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CLEAR_HUB_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, 0, NULL, NULL));
}
// Clear Port Feature
inline uint8_t USBHub::ClearPortFeature(uint8_t fid, uint8_t port, uint8_t sel) {
return( pUsb->ctrlReq(bAddress, 0, bmREQ_CLEAR_PORT_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000 | port) | (sel << 8)), 0, 0, NULL, NULL));
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CLEAR_PORT_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000 | port) | (sel << 8)), 0, 0, NULL, NULL));
}
// Get Hub Descriptor
inline uint8_t USBHub::GetHubDescriptor(uint8_t index, uint16_t nbytes, uint8_t *dataptr) {
return( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_HUB_DESCRIPTOR, USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, nbytes, dataptr, NULL));
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_HUB_DESCRIPTOR, USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, nbytes, dataptr, NULL));
}
// Get Hub Status
inline uint8_t USBHub::GetHubStatus(uint16_t nbytes, uint8_t* dataptr) {
return( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_HUB_STATUS, USB_REQUEST_GET_STATUS, 0, 0, 0x0000, nbytes, nbytes, dataptr, NULL));
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_HUB_STATUS, USB_REQUEST_GET_STATUS, 0, 0, 0x0000, nbytes, nbytes, dataptr, NULL));
}
// Get Port Status
inline uint8_t USBHub::GetPortStatus(uint8_t port, uint16_t nbytes, uint8_t* dataptr) {
return( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, nbytes, dataptr, NULL));
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, nbytes, dataptr, NULL));
}
// Set Hub Descriptor
inline uint8_t USBHub::SetHubDescriptor(uint8_t port, uint16_t nbytes, uint8_t* dataptr) {
return( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_HUB_DESCRIPTOR, USB_REQUEST_SET_DESCRIPTOR, 0, 0, port, nbytes, nbytes, dataptr, NULL));
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_HUB_DESCRIPTOR, USB_REQUEST_SET_DESCRIPTOR, 0, 0, port, nbytes, nbytes, dataptr, NULL));
}
// Set Hub Feature
inline uint8_t USBHub::SetHubFeature(uint8_t fid) {
return( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_HUB_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, 0, 0, 0, NULL, NULL));
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_HUB_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, 0, 0, 0, NULL, NULL));
}
// Set Port Feature
inline uint8_t USBHub::SetPortFeature(uint8_t fid, uint8_t port, uint8_t sel) {
return( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_PORT_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000 | sel) << 8) | port), 0, 0, NULL, NULL));
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_PORT_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000 | sel) << 8) | port), 0, 0, NULL, NULL));
}
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes = false);

View file

@ -61,4 +61,4 @@ const uint16_t XBOXBUTTONS[] PROGMEM = {
0x0008 // SYNC
};
#endif
#endif