mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Janitorial, whitespace fixes. No new code.
This commit is contained in:
parent
b8fb19fb90
commit
f1af9b08ec
54 changed files with 1370 additions and 1310 deletions
250
BTD.cpp
250
BTD.cpp
|
@ -36,12 +36,12 @@ qNextPollTime(0), // Reset NextPollTime
|
||||||
pollInterval(0),
|
pollInterval(0),
|
||||||
bPollEnable(false) // Don't start polling before dongle is connected
|
bPollEnable(false) // Don't start polling before dongle is connected
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < BTD_NUMSERVICES; i++)
|
for(uint8_t i = 0; i < BTD_NUMSERVICES; i++)
|
||||||
btService[i] = NULL;
|
btService[i] = NULL;
|
||||||
|
|
||||||
Initialize(); // Set all variables, endpoint structs etc. to default values
|
Initialize(); // Set all variables, endpoint structs etc. to default values
|
||||||
|
|
||||||
if (pUsb) // Register in USB subsystem
|
if(pUsb) // Register in USB subsystem
|
||||||
pUsb->RegisterDeviceClass(this); // Set devConfig[] entry
|
pUsb->RegisterDeviceClass(this); // Set devConfig[] entry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ uint8_t BTD::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
Notify(PSTR("\r\nBTD ConfigureDevice"), 0x80);
|
Notify(PSTR("\r\nBTD ConfigureDevice"), 0x80);
|
||||||
#endif
|
#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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress in use"), 0x80);
|
Notify(PSTR("\r\nAddress in use"), 0x80);
|
||||||
#endif
|
#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
|
p = addrPool.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned
|
||||||
if (!p) {
|
if(!p) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress not found"), 0x80);
|
Notify(PSTR("\r\nAddress not found"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p->epinfo) {
|
if(!p->epinfo) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nepinfo is null"), 0x80);
|
Notify(PSTR("\r\nepinfo is null"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -89,12 +89,12 @@ uint8_t BTD::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
p->epinfo = oldep_ptr; // Restore p->epinfo
|
p->epinfo = oldep_ptr; // Restore p->epinfo
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
|
|
||||||
bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class
|
bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class
|
||||||
|
|
||||||
if (!bAddress) {
|
if(!bAddress) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nOut of address space"), 0x80);
|
Notify(PSTR("\r\nOut of address space"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -113,7 +113,7 @@ FailGetDevDescr:
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
NotifyFailGetDevDescr(rcode);
|
NotifyFailGetDevDescr(rcode);
|
||||||
#endif
|
#endif
|
||||||
if (rcode != hrJERR)
|
if(rcode != hrJERR)
|
||||||
rcode = USB_ERROR_FailGetDevDescr;
|
rcode = USB_ERROR_FailGetDevDescr;
|
||||||
Release();
|
Release();
|
||||||
return rcode;
|
return rcode;
|
||||||
|
@ -130,7 +130,7 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
#endif
|
#endif
|
||||||
UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
|
UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
|
||||||
|
|
||||||
if (!p) {
|
if(!p) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress not found"), 0x80);
|
Notify(PSTR("\r\nAddress not found"), 0x80);
|
||||||
#endif
|
#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
|
delay(300); // Assign new address to the device
|
||||||
|
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress); // 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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nsetAddr: "), 0x80);
|
Notify(PSTR("\r\nsetAddr: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (rcode, 0x80);
|
D_PrintHex<uint8_t > (rcode, 0x80);
|
||||||
|
@ -156,7 +156,7 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
|
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
|
p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
|
||||||
if (!p) {
|
if(!p) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress not found"), 0x80);
|
Notify(PSTR("\r\nAddress not found"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -166,18 +166,18 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
p->lowspeed = lowspeed;
|
p->lowspeed = lowspeed;
|
||||||
|
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known
|
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
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);
|
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
|
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;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
if (PID == PS3_PID || PID == PS3NAVIGATION_PID) {
|
if(PID == PS3_PID || PID == PS3NAVIGATION_PID) {
|
||||||
if (PID == PS3_PID)
|
if(PID == PS3_PID)
|
||||||
Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
|
Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
|
||||||
else // It must be a navigation controller
|
else // It must be a navigation controller
|
||||||
Notify(PSTR("\r\nNavigation Controller Connected"), 0x80);
|
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);
|
Notify(PSTR("\r\nMotion Controller Connected"), 0x80);
|
||||||
#endif
|
#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
|
#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);
|
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
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (PID == PS3_PID || PID == PS3NAVIGATION_PID)
|
if(PID == PS3_PID || PID == PS3NAVIGATION_PID)
|
||||||
setBdaddr(my_bdaddr); // Set internal Bluetooth address
|
setBdaddr(my_bdaddr); // Set internal Bluetooth address
|
||||||
else
|
else
|
||||||
setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address
|
setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
|
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);
|
D_PrintHex<uint8_t > (my_bdaddr[i], 0x80);
|
||||||
Notify(PSTR(":"), 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
|
// 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
|
// 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
|
// And 3 endpoints - interrupt-IN, bulk-IN, bulk-OUT, not necessarily in this order
|
||||||
for (uint8_t i = 0; i < num_of_conf; i++) {
|
for(uint8_t i = 0; i < num_of_conf; i++) {
|
||||||
if (VID == IOGEAR_GBU521_VID && PID == IOGEAR_GBU521_PID) {
|
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
|
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);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||||
} else {
|
} else {
|
||||||
ConfigDescParser<USB_CLASS_WIRELESS_CTRL, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this);
|
ConfigDescParser<USB_CLASS_WIRELESS_CTRL, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this);
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||||
}
|
}
|
||||||
if (rcode) // Check error code
|
if(rcode) // Check error code
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
if (bNumEP >= BTD_MAX_ENDPOINTS) // All endpoints extracted
|
if(bNumEP >= BTD_MAX_ENDPOINTS) // All endpoints extracted
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bNumEP < BTD_MAX_ENDPOINTS)
|
if(bNumEP < BTD_MAX_ENDPOINTS)
|
||||||
goto FailUnknownDevice;
|
goto FailUnknownDevice;
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer - this time all 3 endpoins
|
// Assign epInfo to epinfo pointer - this time all 3 endpoins
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, bConfNum);
|
rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, bConfNum);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
hci_num_reset_loops = 100; // only loop 100 times before trying to send the hci reset command
|
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() {
|
void BTD::Initialize() {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for (i = 0; i < BTD_MAX_ENDPOINTS; i++) {
|
for(i = 0; i < BTD_MAX_ENDPOINTS; i++) {
|
||||||
epInfo[i].epAddr = 0;
|
epInfo[i].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
||||||
}
|
}
|
||||||
for (i = 0; i < BTD_NUMSERVICES; i++) {
|
for(i = 0; i < BTD_NUMSERVICES; i++) {
|
||||||
if (btService[i])
|
if(btService[i])
|
||||||
btService[i]->Reset(); // Reset all Bluetooth services
|
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("Iface Num"),iface);
|
||||||
//ErrorMessage<uint8_t>(PSTR("Alt.Set"),alt);
|
//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;
|
return;
|
||||||
|
|
||||||
bConfNum = conf;
|
bConfNum = conf;
|
||||||
uint8_t index;
|
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;
|
index = BTD_EVENT_PIPE;
|
||||||
epInfo[index].bmNakPower = USB_NAK_NOWAIT;
|
epInfo[index].bmNakPower = USB_NAK_NOWAIT;
|
||||||
} else {
|
} 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;
|
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? BTD_DATAIN_PIPE : BTD_DATAOUT_PIPE;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
@ -337,7 +337,7 @@ void BTD::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
PrintEndpointDescriptor(pep);
|
PrintEndpointDescriptor(pep);
|
||||||
#endif
|
#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;
|
pollInterval = pep->bInterval;
|
||||||
bNumEP++;
|
bNumEP++;
|
||||||
}
|
}
|
||||||
|
@ -368,9 +368,9 @@ uint8_t BTD::Release() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t BTD::Poll() {
|
uint8_t BTD::Poll() {
|
||||||
if (!bPollEnable)
|
if(!bPollEnable)
|
||||||
return 0;
|
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
|
qNextPollTime = millis() + pollInterval; // Set new poll time
|
||||||
HCI_event_task(); // Poll the HCI event pipe
|
HCI_event_task(); // Poll the HCI event pipe
|
||||||
HCI_task(); // HCI state machine
|
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
|
uint16_t length = BULK_MAXPKTSIZE; // Request more than 16 bytes anyway, the inTransfer routine will take care of this
|
||||||
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_EVENT_PIPE ].epAddr, &length, hcibuf); // Input on endpoint 1
|
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_EVENT_PIPE ].epAddr, &length, hcibuf); // Input on endpoint 1
|
||||||
|
|
||||||
if (!rcode || rcode == hrNAK) { // Check for errors
|
if(!rcode || rcode == hrNAK) { // Check for errors
|
||||||
switch (hcibuf[0]) { // Switch on event type
|
switch(hcibuf[0]) { // Switch on event type
|
||||||
case EV_COMMAND_COMPLETE:
|
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
|
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_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);
|
hci_set_flag(HCI_FLAG_READ_VERSION);
|
||||||
} else if ((hcibuf[3] == 0x09) && (hcibuf[4] == 0x10)) { // Parameters from read local bluetooth address
|
} else if((hcibuf[3] == 0x09) && (hcibuf[4] == 0x10)) { // Parameters from read local bluetooth address
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
for(uint8_t i = 0; i < 6; i++)
|
||||||
my_bdaddr[i] = hcibuf[6 + i];
|
my_bdaddr[i] = hcibuf[6 + i];
|
||||||
hci_set_flag(HCI_FLAG_READ_BDADDR);
|
hci_set_flag(HCI_FLAG_READ_BDADDR);
|
||||||
}
|
}
|
||||||
|
@ -400,7 +400,7 @@ void BTD::HCI_event_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_COMMAND_STATUS:
|
case EV_COMMAND_STATUS:
|
||||||
if (hcibuf[2]) { // Show status on serial if not OK
|
if(hcibuf[2]) { // Show status on serial if not OK
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHCI Command Failed: "), 0x80);
|
Notify(PSTR("\r\nHCI Command Failed: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (hcibuf[2], 0x80);
|
D_PrintHex<uint8_t > (hcibuf[2], 0x80);
|
||||||
|
@ -409,10 +409,10 @@ void BTD::HCI_event_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_INQUIRY_COMPLETE:
|
case EV_INQUIRY_COMPLETE:
|
||||||
if (inquiry_counter >= 5 && (pairWithWii || pairWithHIDDevice)) {
|
if(inquiry_counter >= 5 && (pairWithWii || pairWithHIDDevice)) {
|
||||||
inquiry_counter = 0;
|
inquiry_counter = 0;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
if (pairWithWii)
|
if(pairWithWii)
|
||||||
Notify(PSTR("\r\nCouldn't find Wiimote"), 0x80);
|
Notify(PSTR("\r\nCouldn't find Wiimote"), 0x80);
|
||||||
else
|
else
|
||||||
Notify(PSTR("\r\nCouldn't find HID device"), 0x80);
|
Notify(PSTR("\r\nCouldn't find HID device"), 0x80);
|
||||||
|
@ -427,38 +427,38 @@ void BTD::HCI_event_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_INQUIRY_RESULT:
|
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
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("\r\nNumber of responses: "), 0x80);
|
Notify(PSTR("\r\nNumber of responses: "), 0x80);
|
||||||
Notify(hcibuf[2], 0x80);
|
Notify(hcibuf[2], 0x80);
|
||||||
#endif
|
#endif
|
||||||
for (uint8_t i = 0; i < hcibuf[2]; i++) {
|
for(uint8_t i = 0; i < hcibuf[2]; i++) {
|
||||||
uint8_t offset = 8 * hcibuf[2] + 3 * i;
|
uint8_t offset = 8 * hcibuf[2] + 3 * i;
|
||||||
uint8_t classOfDevice[3];
|
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];
|
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(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(classOfDevice[0] & 0x08) // Check if it's the new Wiimote with motion plus inside that was detected
|
||||||
motionPlusInside = true;
|
motionPlusInside = true;
|
||||||
else
|
else
|
||||||
motionPlusInside = false;
|
motionPlusInside = false;
|
||||||
|
|
||||||
for (uint8_t j = 0; j < 6; j++)
|
for(uint8_t j = 0; j < 6; j++)
|
||||||
disc_bdaddr[j] = hcibuf[j + 3 + 6 * i];
|
disc_bdaddr[j] = hcibuf[j + 3 + 6 * i];
|
||||||
|
|
||||||
hci_set_flag(HCI_FLAG_DEVICE_FOUND);
|
hci_set_flag(HCI_FLAG_DEVICE_FOUND);
|
||||||
break;
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
if (classOfDevice[0] & 0x80)
|
if(classOfDevice[0] & 0x80)
|
||||||
Notify(PSTR("\r\nMouse found"), 0x80);
|
Notify(PSTR("\r\nMouse found"), 0x80);
|
||||||
if (classOfDevice[0] & 0x40)
|
if(classOfDevice[0] & 0x40)
|
||||||
Notify(PSTR("\r\nKeyboard found"), 0x80);
|
Notify(PSTR("\r\nKeyboard found"), 0x80);
|
||||||
#endif
|
#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];
|
disc_bdaddr[j] = hcibuf[j + 3 + 6 * i];
|
||||||
|
|
||||||
hci_set_flag(HCI_FLAG_DEVICE_FOUND);
|
hci_set_flag(HCI_FLAG_DEVICE_FOUND);
|
||||||
|
@ -479,7 +479,7 @@ void BTD::HCI_event_task() {
|
||||||
|
|
||||||
case EV_CONNECT_COMPLETE:
|
case EV_CONNECT_COMPLETE:
|
||||||
hci_set_flag(HCI_FLAG_CONNECT_EVENT);
|
hci_set_flag(HCI_FLAG_CONNECT_EVENT);
|
||||||
if (!hcibuf[2]) { // Check if connected OK
|
if(!hcibuf[2]) { // Check if connected OK
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("\r\nConnection established"), 0x80);
|
Notify(PSTR("\r\nConnection established"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -495,17 +495,17 @@ void BTD::HCI_event_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_DISCONNECT_COMPLETE:
|
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_set_flag(HCI_FLAG_DISCONNECT_COMPLETE); // Set disconnect command complete flag
|
||||||
hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE); // Clear connection complete flag
|
hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE); // Clear connection complete flag
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_REMOTE_NAME_COMPLETE:
|
case EV_REMOTE_NAME_COMPLETE:
|
||||||
if (!hcibuf[2]) { // Check if reading is OK
|
if(!hcibuf[2]) { // Check if reading is OK
|
||||||
for (uint8_t i = 0; i < min(sizeof (remote_name), sizeof (hcibuf) - 9); i++) {
|
for(uint8_t i = 0; i < min(sizeof (remote_name), sizeof (hcibuf) - 9); i++) {
|
||||||
remote_name[i] = 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;
|
break;
|
||||||
}
|
}
|
||||||
hci_set_flag(HCI_FLAG_REMOTE_NAME_COMPLETE);
|
hci_set_flag(HCI_FLAG_REMOTE_NAME_COMPLETE);
|
||||||
|
@ -513,14 +513,14 @@ void BTD::HCI_event_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_INCOMING_CONNECT:
|
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];
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
if (hcibuf[8] & 0x80)
|
if(hcibuf[8] & 0x80)
|
||||||
Notify(PSTR("\r\nMouse is connecting"), 0x80);
|
Notify(PSTR("\r\nMouse is connecting"), 0x80);
|
||||||
if (hcibuf[8] & 0x40)
|
if(hcibuf[8] & 0x40)
|
||||||
Notify(PSTR("\r\nKeyboard is connecting"), 0x80);
|
Notify(PSTR("\r\nKeyboard is connecting"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
incomingHIDDevice = true;
|
incomingHIDDevice = true;
|
||||||
|
@ -538,12 +538,12 @@ void BTD::HCI_event_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_PIN_CODE_REQUEST:
|
case EV_PIN_CODE_REQUEST:
|
||||||
if (pairWithWii) {
|
if(pairWithWii) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nPairing with wiimote"), 0x80);
|
Notify(PSTR("\r\nPairing with wiimote"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
hci_pin_code_request_reply();
|
hci_pin_code_request_reply();
|
||||||
} else if (btdPin != NULL) {
|
} else if(btdPin != NULL) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nBluetooth pin is set too: "), 0x80);
|
Notify(PSTR("\r\nBluetooth pin is set too: "), 0x80);
|
||||||
NotifyStr(btdPin, 0x80);
|
NotifyStr(btdPin, 0x80);
|
||||||
|
@ -565,12 +565,12 @@ void BTD::HCI_event_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_AUTHENTICATION_COMPLETE:
|
case EV_AUTHENTICATION_COMPLETE:
|
||||||
if (pairWithWii && !connectToWii) {
|
if(pairWithWii && !connectToWii) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nPairing successful with Wiimote"), 0x80);
|
Notify(PSTR("\r\nPairing successful with Wiimote"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
connectToWii = true; // Used to indicate to the Wii service, that it should connect to this device
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nPairing successful with HID device"), 0x80);
|
Notify(PSTR("\r\nPairing successful with HID device"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -592,7 +592,7 @@ void BTD::HCI_event_task() {
|
||||||
break;
|
break;
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
default:
|
default:
|
||||||
if (hcibuf[0] != 0x00) {
|
if(hcibuf[0] != 0x00) {
|
||||||
Notify(PSTR("\r\nUnmanaged HCI Event: "), 0x80);
|
Notify(PSTR("\r\nUnmanaged HCI Event: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (hcibuf[0], 0x80);
|
D_PrintHex<uint8_t > (hcibuf[0], 0x80);
|
||||||
}
|
}
|
||||||
|
@ -610,10 +610,10 @@ void BTD::HCI_event_task() {
|
||||||
|
|
||||||
/* Poll Bluetooth and print result */
|
/* Poll Bluetooth and print result */
|
||||||
void BTD::HCI_task() {
|
void BTD::HCI_task() {
|
||||||
switch (hci_state) {
|
switch(hci_state) {
|
||||||
case HCI_INIT_STATE:
|
case HCI_INIT_STATE:
|
||||||
hci_counter++;
|
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_reset();
|
||||||
hci_state = HCI_RESET_STATE;
|
hci_state = HCI_RESET_STATE;
|
||||||
hci_counter = 0;
|
hci_counter = 0;
|
||||||
|
@ -622,16 +622,16 @@ void BTD::HCI_task() {
|
||||||
|
|
||||||
case HCI_RESET_STATE:
|
case HCI_RESET_STATE:
|
||||||
hci_counter++;
|
hci_counter++;
|
||||||
if (hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
|
if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
|
||||||
hci_counter = 0;
|
hci_counter = 0;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHCI Reset complete"), 0x80);
|
Notify(PSTR("\r\nHCI Reset complete"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
hci_state = HCI_CLASS_STATE;
|
hci_state = HCI_CLASS_STATE;
|
||||||
hci_write_class_of_device();
|
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;
|
hci_num_reset_loops *= 10;
|
||||||
if (hci_num_reset_loops > 2000)
|
if(hci_num_reset_loops > 2000)
|
||||||
hci_num_reset_loops = 2000;
|
hci_num_reset_loops = 2000;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nNo response to HCI Reset"), 0x80);
|
Notify(PSTR("\r\nNo response to HCI Reset"), 0x80);
|
||||||
|
@ -642,7 +642,7 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_CLASS_STATE:
|
case HCI_CLASS_STATE:
|
||||||
if (hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
|
if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nWrite class of device"), 0x80);
|
Notify(PSTR("\r\nWrite class of device"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -652,10 +652,10 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_BDADDR_STATE:
|
case HCI_BDADDR_STATE:
|
||||||
if (hci_check_flag(HCI_FLAG_READ_BDADDR)) {
|
if(hci_check_flag(HCI_FLAG_READ_BDADDR)) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nLocal Bluetooth Address: "), 0x80);
|
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);
|
D_PrintHex<uint8_t > (my_bdaddr[i], 0x80);
|
||||||
Notify(PSTR(":"), 0x80);
|
Notify(PSTR(":"), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -667,8 +667,8 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_LOCAL_VERSION_STATE: // The local version is used by the PS3BT class
|
case HCI_LOCAL_VERSION_STATE: // The local version is used by the PS3BT class
|
||||||
if (hci_check_flag(HCI_FLAG_READ_VERSION)) {
|
if(hci_check_flag(HCI_FLAG_READ_VERSION)) {
|
||||||
if (btdName != NULL) {
|
if(btdName != NULL) {
|
||||||
hci_set_local_name(btdName);
|
hci_set_local_name(btdName);
|
||||||
hci_state = HCI_SET_NAME_STATE;
|
hci_state = HCI_SET_NAME_STATE;
|
||||||
} else
|
} else
|
||||||
|
@ -677,7 +677,7 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_SET_NAME_STATE:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nThe name is set to: "), 0x80);
|
Notify(PSTR("\r\nThe name is set to: "), 0x80);
|
||||||
NotifyStr(btdName, 0x80);
|
NotifyStr(btdName, 0x80);
|
||||||
|
@ -687,9 +687,9 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_CHECK_DEVICE_SERVICE:
|
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
|
#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);
|
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
|
else
|
||||||
Notify(PSTR("\r\nPlease enable discovery of your device"), 0x80);
|
Notify(PSTR("\r\nPlease enable discovery of your device"), 0x80);
|
||||||
|
@ -701,27 +701,27 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_INQUIRY_STATE:
|
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
|
hci_inquiry_cancel(); // Stop inquiry
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
if (pairWithWii)
|
if(pairWithWii)
|
||||||
Notify(PSTR("\r\nWiimote found"), 0x80);
|
Notify(PSTR("\r\nWiimote found"), 0x80);
|
||||||
else
|
else
|
||||||
Notify(PSTR("\r\nHID device found"), 0x80);
|
Notify(PSTR("\r\nHID device found"), 0x80);
|
||||||
|
|
||||||
Notify(PSTR("\r\nNow just create the instance like so:"), 0x80);
|
Notify(PSTR("\r\nNow just create the instance like so:"), 0x80);
|
||||||
if (pairWithWii)
|
if(pairWithWii)
|
||||||
Notify(PSTR("\r\nWII Wii(&Btd);"), 0x80);
|
Notify(PSTR("\r\nWII Wii(&Btd);"), 0x80);
|
||||||
else
|
else
|
||||||
Notify(PSTR("\r\nBTHID hid(&Btd);"), 0x80);
|
Notify(PSTR("\r\nBTHID hid(&Btd);"), 0x80);
|
||||||
|
|
||||||
Notify(PSTR("\r\nAnd then press any button on the "), 0x80);
|
Notify(PSTR("\r\nAnd then press any button on the "), 0x80);
|
||||||
if (pairWithWii)
|
if(pairWithWii)
|
||||||
Notify(PSTR("Wiimote"), 0x80);
|
Notify(PSTR("Wiimote"), 0x80);
|
||||||
else
|
else
|
||||||
Notify(PSTR("device"), 0x80);
|
Notify(PSTR("device"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
if (motionPlusInside) {
|
if(motionPlusInside) {
|
||||||
hci_remote_name(); // We need to know the name to distinguish between a Wiimote and a Wii U Pro Controller
|
hci_remote_name(); // We need to know the name to distinguish between a Wiimote and a Wii U Pro Controller
|
||||||
hci_state = HCI_REMOTE_NAME_STATE;
|
hci_state = HCI_REMOTE_NAME_STATE;
|
||||||
} else
|
} else
|
||||||
|
@ -730,9 +730,9 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_CONNECT_DEVICE_STATE:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
if (pairWithWii)
|
if(pairWithWii)
|
||||||
Notify(PSTR("\r\nConnecting to Wiimote"), 0x80);
|
Notify(PSTR("\r\nConnecting to Wiimote"), 0x80);
|
||||||
else
|
else
|
||||||
Notify(PSTR("\r\nConnecting to HID device"), 0x80);
|
Notify(PSTR("\r\nConnecting to HID device"), 0x80);
|
||||||
|
@ -743,10 +743,10 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_CONNECTED_DEVICE_STATE:
|
case HCI_CONNECTED_DEVICE_STATE:
|
||||||
if (hci_check_flag(HCI_FLAG_CONNECT_EVENT)) {
|
if(hci_check_flag(HCI_FLAG_CONNECT_EVENT)) {
|
||||||
if (hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) {
|
if(hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
if (pairWithWii)
|
if(pairWithWii)
|
||||||
Notify(PSTR("\r\nConnected to Wiimote"), 0x80);
|
Notify(PSTR("\r\nConnected to Wiimote"), 0x80);
|
||||||
else
|
else
|
||||||
Notify(PSTR("\r\nConnected to HID device"), 0x80);
|
Notify(PSTR("\r\nConnected to HID device"), 0x80);
|
||||||
|
@ -763,7 +763,7 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_SCANNING_STATE:
|
case HCI_SCANNING_STATE:
|
||||||
if (!connectToWii && !pairWithWii && !connectToHIDDevice && !pairWithHIDDevice) {
|
if(!connectToWii && !pairWithWii && !connectToHIDDevice && !pairWithHIDDevice) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nWait For Incoming Connection Request"), 0x80);
|
Notify(PSTR("\r\nWait For Incoming Connection Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -774,38 +774,38 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_CONNECT_IN_STATE:
|
case HCI_CONNECT_IN_STATE:
|
||||||
if (hci_check_flag(HCI_FLAG_INCOMING_REQUEST)) {
|
if(hci_check_flag(HCI_FLAG_INCOMING_REQUEST)) {
|
||||||
watingForConnection = false;
|
watingForConnection = false;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nIncoming Connection Request"), 0x80);
|
Notify(PSTR("\r\nIncoming Connection Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
hci_remote_name();
|
hci_remote_name();
|
||||||
hci_state = HCI_REMOTE_NAME_STATE;
|
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;
|
hci_state = HCI_DISCONNECT_STATE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_REMOTE_NAME_STATE:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nRemote Name: "), 0x80);
|
Notify(PSTR("\r\nRemote Name: "), 0x80);
|
||||||
for (uint8_t i = 0; i < 30; i++) {
|
for(uint8_t i = 0; i < 30; i++) {
|
||||||
if (remote_name[i] == '\0') // End of string
|
if(remote_name[i] == '\0') // End of string
|
||||||
break;
|
break;
|
||||||
Notifyc(remote_name[i], 0x80);
|
Notifyc(remote_name[i], 0x80);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (strncmp((const char*)remote_name, "Nintendo", 8) == 0) {
|
if(strncmp((const char*)remote_name, "Nintendo", 8) == 0) {
|
||||||
incomingWii = true;
|
incomingWii = true;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nWiimote is connecting"), 0x80);
|
Notify(PSTR("\r\nWiimote is connecting"), 0x80);
|
||||||
#endif
|
#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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR(" with Motion Plus Inside"), 0x80);
|
Notify(PSTR(" with Motion Plus Inside"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
motionPlusInside = true;
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR(" - Wii U Pro Controller"), 0x80);
|
Notify(PSTR(" - Wii U Pro Controller"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -816,7 +816,7 @@ void BTD::HCI_task() {
|
||||||
wiiUProController = false;
|
wiiUProController = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pairWithWii && motionPlusInside)
|
if(pairWithWii && motionPlusInside)
|
||||||
hci_state = HCI_CONNECT_DEVICE_STATE;
|
hci_state = HCI_CONNECT_DEVICE_STATE;
|
||||||
else {
|
else {
|
||||||
hci_accept_connection();
|
hci_accept_connection();
|
||||||
|
@ -826,10 +826,10 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_CONNECTED_STATE:
|
case HCI_CONNECTED_STATE:
|
||||||
if (hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) {
|
if(hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nConnected to Device: "), 0x80);
|
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);
|
D_PrintHex<uint8_t > (disc_bdaddr[i], 0x80);
|
||||||
Notify(PSTR(":"), 0x80);
|
Notify(PSTR(":"), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -847,14 +847,14 @@ void BTD::HCI_task() {
|
||||||
|
|
||||||
case HCI_DONE_STATE:
|
case HCI_DONE_STATE:
|
||||||
hci_counter++;
|
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_counter = 0;
|
||||||
hci_state = HCI_SCANNING_STATE;
|
hci_state = HCI_SCANNING_STATE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_DISCONNECT_STATE:
|
case HCI_DISCONNECT_STATE:
|
||||||
if (hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE)) {
|
if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE)) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHCI Disconnected from Device"), 0x80);
|
Notify(PSTR("\r\nHCI Disconnected from Device"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -879,22 +879,22 @@ void BTD::ACL_event_task() {
|
||||||
uint16_t length = BULK_MAXPKTSIZE;
|
uint16_t length = BULK_MAXPKTSIZE;
|
||||||
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_DATAIN_PIPE ].epAddr, &length, l2capinbuf); // Input on endpoint 2
|
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_DATAIN_PIPE ].epAddr, &length, l2capinbuf); // Input on endpoint 2
|
||||||
|
|
||||||
if (!rcode) { // Check for errors
|
if(!rcode) { // Check for errors
|
||||||
if (length > 0) { // Check if any data was read
|
if(length > 0) { // Check if any data was read
|
||||||
for (uint8_t i = 0; i < BTD_NUMSERVICES; i++) {
|
for(uint8_t i = 0; i < BTD_NUMSERVICES; i++) {
|
||||||
if (btService[i])
|
if(btService[i])
|
||||||
btService[i]->ACLData(l2capinbuf);
|
btService[i]->ACLData(l2capinbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
else if (rcode != hrNAK) {
|
else if(rcode != hrNAK) {
|
||||||
Notify(PSTR("\r\nACL data in error: "), 0x80);
|
Notify(PSTR("\r\nACL data in error: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (rcode, 0x80);
|
D_PrintHex<uint8_t > (rcode, 0x80);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
for (uint8_t i = 0; i < BTD_NUMSERVICES; i++)
|
for(uint8_t i = 0; i < BTD_NUMSERVICES; i++)
|
||||||
if (btService[i])
|
if(btService[i])
|
||||||
btService[i]->Run();
|
btService[i]->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -921,7 +921,7 @@ void BTD::hci_write_scan_enable() {
|
||||||
hcibuf[0] = 0x1A; // HCI OCF = 1A
|
hcibuf[0] = 0x1A; // HCI OCF = 1A
|
||||||
hcibuf[1] = 0x03 << 2; // HCI OGF = 3
|
hcibuf[1] = 0x03 << 2; // HCI OGF = 3
|
||||||
hcibuf[2] = 0x01; // parameter length = 1
|
hcibuf[2] = 0x01; // parameter length = 1
|
||||||
if (btdName != NULL)
|
if(btdName != NULL)
|
||||||
hcibuf[3] = 0x03; // Inquiry Scan enabled. Page Scan enabled.
|
hcibuf[3] = 0x03; // Inquiry Scan enabled. Page Scan enabled.
|
||||||
else
|
else
|
||||||
hcibuf[3] = 0x02; // Inquiry Scan disabled. Page Scan enabled.
|
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[1] = 0x03 << 2; // HCI OGF = 3
|
||||||
hcibuf[2] = strlen(name) + 1; // parameter length = the length of the string + end byte
|
hcibuf[2] = strlen(name) + 1; // parameter length = the length of the string + end byte
|
||||||
uint8_t i;
|
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] = name[i];
|
||||||
hcibuf[i + 3] = 0x00; // End of string
|
hcibuf[i + 3] = 0x00; // End of string
|
||||||
|
|
||||||
|
@ -1061,26 +1061,26 @@ void BTD::hci_pin_code_request_reply() {
|
||||||
hcibuf[6] = disc_bdaddr[3];
|
hcibuf[6] = disc_bdaddr[3];
|
||||||
hcibuf[7] = disc_bdaddr[4];
|
hcibuf[7] = disc_bdaddr[4];
|
||||||
hcibuf[8] = disc_bdaddr[5];
|
hcibuf[8] = disc_bdaddr[5];
|
||||||
if (pairWithWii) {
|
if(pairWithWii) {
|
||||||
hcibuf[9] = 6; // Pin length is the length of the Bluetooth address
|
hcibuf[9] = 6; // Pin length is the length of the Bluetooth address
|
||||||
if (wiiUProController) {
|
if(wiiUProController) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nParing with Wii U Pro Controller"), 0x80);
|
Notify(PSTR("\r\nParing with Wii U Pro Controller"), 0x80);
|
||||||
#endif
|
#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
|
hcibuf[10 + i] = my_bdaddr[i]; // The pin is the Bluetooth dongles Bluetooth address backwards
|
||||||
} else {
|
} 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
|
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
|
hcibuf[i] = 0x00; // The rest should be 0
|
||||||
} else {
|
} else {
|
||||||
hcibuf[9] = strlen(btdPin); // Length of pin
|
hcibuf[9] = strlen(btdPin); // Length of pin
|
||||||
uint8_t i;
|
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];
|
hcibuf[i + 10] = btdPin[i];
|
||||||
for (; i < 16; i++)
|
for(; i < 16; i++)
|
||||||
hcibuf[i + 10] = 0x00; // The rest should be 0
|
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[6] = channelLow;
|
||||||
buf[7] = channelHigh;
|
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];
|
buf[8 + i] = data[i];
|
||||||
|
|
||||||
uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf);
|
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
|
delay(100); // This small delay prevents it from overflowing if it fails
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nError sending L2CAP message: 0x"), 0x80);
|
Notify(PSTR("\r\nError sending L2CAP message: 0x"), 0x80);
|
||||||
|
@ -1317,7 +1317,7 @@ void BTD::setBdaddr(uint8_t* bdaddr) {
|
||||||
buf[0] = 0x01;
|
buf[0] = 0x01;
|
||||||
buf[1] = 0x00;
|
buf[1] = 0x00;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
for(uint8_t i = 0; i < 6; i++)
|
||||||
buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first
|
buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first
|
||||||
|
|
||||||
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
||||||
|
@ -1333,7 +1333,7 @@ void BTD::setMoveBdaddr(uint8_t* bdaddr) {
|
||||||
buf[9] = 0x02;
|
buf[9] = 0x02;
|
||||||
buf[10] = 0x12;
|
buf[10] = 0x12;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
for(uint8_t i = 0; i < 6; i++)
|
||||||
buf[i + 1] = bdaddr[i];
|
buf[i + 1] = bdaddr[i];
|
||||||
|
|
||||||
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
||||||
|
|
11
BTD.h
11
BTD.h
|
@ -262,12 +262,15 @@ public:
|
||||||
virtual bool isReady() {
|
virtual bool isReady() {
|
||||||
return bPollEnable;
|
return bPollEnable;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by the USB core to check what this driver support.
|
* Used by the USB core to check what this driver support.
|
||||||
* @param klass The device's USB class.
|
* @param klass The device's USB class.
|
||||||
* @return Returns true if the device's USB class matches this driver.
|
* @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.
|
* 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.
|
* @return Returns true if the device's VID and PID matches this driver.
|
||||||
*/
|
*/
|
||||||
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) {
|
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) {
|
||||||
if (vid == IOGEAR_GBU521_VID && pid == IOGEAR_GBU521_PID)
|
if(vid == IOGEAR_GBU521_VID && pid == IOGEAR_GBU521_PID)
|
||||||
return true;
|
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(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(vid == PS3_VID && (pid == PS3_PID || pid == PS3NAVIGATION_PID || pid == PS3MOVE_PID))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
108
BTHID.cpp
108
BTHID.cpp
|
@ -22,16 +22,15 @@
|
||||||
|
|
||||||
BTHID::BTHID(BTD *p, bool pair, const char *pin) :
|
BTHID::BTHID(BTD *p, bool pair, const char *pin) :
|
||||||
pBtd(p), // pointer to USB class instance - mandatory
|
pBtd(p), // pointer to USB class instance - mandatory
|
||||||
protocolMode(HID_BOOT_PROTOCOL)
|
protocolMode(HID_BOOT_PROTOCOL) {
|
||||||
{
|
for(uint8_t i = 0; i < NUM_PARSERS; i++)
|
||||||
for (uint8_t i = 0; i < NUM_PARSERS; i++)
|
|
||||||
pRptParser[i] = NULL;
|
pRptParser[i] = NULL;
|
||||||
|
|
||||||
if (pBtd)
|
if(pBtd)
|
||||||
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
||||||
|
|
||||||
pBtd->pairWithHIDDevice = pair;
|
pBtd->pairWithHIDDevice = pair;
|
||||||
pBtd->btdPin= pin;
|
pBtd->btdPin = pin;
|
||||||
|
|
||||||
/* Set device cid for the control and intterrupt channelse - LSB */
|
/* Set device cid for the control and intterrupt channelse - LSB */
|
||||||
control_dcid[0] = 0x70; // 0x0070
|
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) {
|
void BTHID::ACLData(uint8_t* l2capinbuf) {
|
||||||
if (!pBtd->l2capConnectionClaimed && pBtd->incomingHIDDevice && !connected && !activeConnection) {
|
if(!pBtd->l2capConnectionClaimed && pBtd->incomingHIDDevice && !connected && !activeConnection) {
|
||||||
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||||
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
|
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
|
||||||
pBtd->incomingHIDDevice = false;
|
pBtd->incomingHIDDevice = false;
|
||||||
pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service
|
pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service
|
||||||
activeConnection = true;
|
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[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[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // l2cap_control - Channel ID for ACL-U
|
||||||
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
||||||
|
@ -85,15 +84,15 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
||||||
#endif
|
#endif
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) {
|
||||||
if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success
|
if(((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success
|
||||||
if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) {
|
if(l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) {
|
||||||
//Notify(PSTR("\r\nHID Control Connection Complete"), 0x80);
|
//Notify(PSTR("\r\nHID Control Connection Complete"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
control_scid[0] = l2capinbuf[12];
|
control_scid[0] = l2capinbuf[12];
|
||||||
control_scid[1] = l2capinbuf[13];
|
control_scid[1] = l2capinbuf[13];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONTROL_CONNECTED);
|
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);
|
//Notify(PSTR("\r\nHID Interrupt Connection Complete"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
interrupt_scid[0] = l2capinbuf[12];
|
interrupt_scid[0] = l2capinbuf[12];
|
||||||
|
@ -101,7 +100,7 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
|
||||||
l2cap_set_flag(L2CAP_FLAG_INTERRUPT_CONNECTED);
|
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
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
|
Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
||||||
|
@ -114,46 +113,46 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
|
||||||
Notify(PSTR(" Identifier: "), 0x80);
|
Notify(PSTR(" Identifier: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
|
||||||
#endif
|
#endif
|
||||||
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
|
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
control_scid[0] = l2capinbuf[14];
|
control_scid[0] = l2capinbuf[14];
|
||||||
control_scid[1] = l2capinbuf[15];
|
control_scid[1] = l2capinbuf[15];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST);
|
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];
|
identifier = l2capinbuf[9];
|
||||||
interrupt_scid[0] = l2capinbuf[14];
|
interrupt_scid[0] = l2capinbuf[14];
|
||||||
interrupt_scid[1] = l2capinbuf[15];
|
interrupt_scid[1] = l2capinbuf[15];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST);
|
l2cap_set_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST);
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
|
||||||
if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
|
if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
|
||||||
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
||||||
//Notify(PSTR("\r\nHID Control Configuration Complete"), 0x80);
|
//Notify(PSTR("\r\nHID Control Configuration Complete"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS);
|
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);
|
//Notify(PSTR("\r\nHID Interrupt Configuration Complete"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS);
|
l2cap_set_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
|
||||||
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
||||||
//Notify(PSTR("\r\nHID Control Configuration Request"), 0x80);
|
//Notify(PSTR("\r\nHID Control Configuration Request"), 0x80);
|
||||||
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], control_scid);
|
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);
|
//Notify(PSTR("\r\nHID Interrupt Configuration Request"), 0x80);
|
||||||
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], interrupt_scid);
|
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], interrupt_scid);
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
|
||||||
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnect Request: Control Channel"), 0x80);
|
Notify(PSTR("\r\nDisconnect Request: Control Channel"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid);
|
pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid);
|
||||||
Reset();
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"), 0x80);
|
Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -161,12 +160,12 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
|
||||||
pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid);
|
pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid);
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
|
||||||
if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
|
if(l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
|
||||||
//Notify(PSTR("\r\nDisconnect Response: Control Channel"), 0x80);
|
//Notify(PSTR("\r\nDisconnect Response: Control Channel"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE);
|
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);
|
//Notify(PSTR("\r\nDisconnect Response: Interrupt Channel"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE);
|
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);
|
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifdef PRINTREPORT
|
||||||
Notify(PSTR("\r\nL2CAP Interrupt: "), 0x80);
|
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);
|
D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
|
if(l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
|
||||||
switch (l2capinbuf[9]) {
|
switch(l2capinbuf[9]) {
|
||||||
case 0x01: // Keyboard events
|
case 0x01: // Keyboard events
|
||||||
if (pRptParser[KEYBOARD_PARSER_ID]) {
|
if(pRptParser[KEYBOARD_PARSER_ID]) {
|
||||||
uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
|
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
|
pRptParser[KEYBOARD_PARSER_ID]->Parse(reinterpret_cast<HID *>(this), 0, (uint8_t)length, &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x02: // Mouse events
|
case 0x02: // Mouse events
|
||||||
if (pRptParser[MOUSE_PARSER_ID]) {
|
if(pRptParser[MOUSE_PARSER_ID]) {
|
||||||
uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
|
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
|
pRptParser[MOUSE_PARSER_ID]->Parse(reinterpret_cast<HID *>(this), 0, (uint8_t)length, &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
@ -210,10 +209,10 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
|
||||||
#endif
|
#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
|
#ifdef PRINTREPORT
|
||||||
Notify(PSTR("\r\nL2CAP Control: "), 0x80);
|
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);
|
D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -228,7 +227,7 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
|
||||||
|
|
||||||
Notify(PSTR("\r\nData: "), 0x80);
|
Notify(PSTR("\r\nData: "), 0x80);
|
||||||
Notify(PSTR("\r\n"), 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);
|
D_PrintHex<uint8_t > (l2capinbuf[i + 8], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -239,10 +238,10 @@ void BTHID::ACLData(uint8_t* l2capinbuf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTHID::L2CAP_task() {
|
void BTHID::L2CAP_task() {
|
||||||
switch (l2cap_state) {
|
switch(l2cap_state) {
|
||||||
/* These states are used if the HID device is the host */
|
/* These states are used if the HID device is the host */
|
||||||
case L2CAP_CONTROL_SUCCESS:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
|
Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -252,7 +251,7 @@ void BTHID::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_INTERRUPT_SETUP:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
|
Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -269,7 +268,7 @@ void BTHID::L2CAP_task() {
|
||||||
|
|
||||||
/* These states are used if the Arduino is the host */
|
/* These states are used if the Arduino is the host */
|
||||||
case L2CAP_CONTROL_CONNECT_REQUEST:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nSend HID Control Config Request"), 0x80);
|
Notify(PSTR("\r\nSend HID Control Config Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -280,7 +279,7 @@ void BTHID::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONTROL_CONFIG_REQUEST:
|
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
|
setProtocol(); // Set protocol before establishing HID interrupt channel
|
||||||
delay(1); // Short delay between commands - just to be sure
|
delay(1); // Short delay between commands - just to be sure
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
@ -293,7 +292,7 @@ void BTHID::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_INTERRUPT_CONNECT_REQUEST:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nSend HID Interrupt Config Request"), 0x80);
|
Notify(PSTR("\r\nSend HID Interrupt Config Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -304,7 +303,7 @@ void BTHID::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_INTERRUPT_CONFIG_REQUEST:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Channels Established"), 0x80);
|
Notify(PSTR("\r\nHID Channels Established"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -320,7 +319,7 @@ void BTHID::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_INTERRUPT_DISCONNECT:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80);
|
Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -331,7 +330,7 @@ void BTHID::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONTROL_DISCONNECT:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnected Control Channel"), 0x80);
|
Notify(PSTR("\r\nDisconnected Control Channel"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -345,9 +344,9 @@ void BTHID::L2CAP_task() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTHID::Run() {
|
void BTHID::Run() {
|
||||||
switch (l2cap_state) {
|
switch(l2cap_state) {
|
||||||
case L2CAP_WAIT:
|
case L2CAP_WAIT:
|
||||||
if (pBtd->connectToHIDDevice && !pBtd->l2capConnectionClaimed && !connected && !activeConnection) {
|
if(pBtd->connectToHIDDevice && !pBtd->l2capConnectionClaimed && !connected && !activeConnection) {
|
||||||
pBtd->l2capConnectionClaimed = true;
|
pBtd->l2capConnectionClaimed = true;
|
||||||
activeConnection = true;
|
activeConnection = true;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
@ -358,7 +357,7 @@ void BTHID::Run() {
|
||||||
identifier = 0;
|
identifier = 0;
|
||||||
pBtd->l2cap_connection_request(hci_handle, identifier, control_dcid, HID_CTRL_PSM);
|
pBtd->l2cap_connection_request(hci_handle, identifier, control_dcid, HID_CTRL_PSM);
|
||||||
l2cap_state = L2CAP_CONTROL_CONNECT_REQUEST;
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80);
|
Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -376,6 +375,7 @@ void BTHID::Run() {
|
||||||
|
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
/* HID Commands */
|
/* HID Commands */
|
||||||
|
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
void BTHID::setProtocol() {
|
void BTHID::setProtocol() {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
|
5
BTHID.h
5
BTHID.h
|
@ -48,6 +48,7 @@ public:
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
/** Used this to disconnect any of the controllers. */
|
/** Used this to disconnect any of the controllers. */
|
||||||
virtual void disconnect();
|
virtual void disconnect();
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
HIDReportParser *GetReportParser(uint8_t id) {
|
HIDReportParser *GetReportParser(uint8_t id) {
|
||||||
|
@ -71,7 +72,7 @@ public:
|
||||||
|
|
||||||
/** Call this to start the paring sequence with a controller */
|
/** Call this to start the paring sequence with a controller */
|
||||||
void pair(void) {
|
void pair(void) {
|
||||||
if (pBtd)
|
if(pBtd)
|
||||||
pBtd->pairWithHID();
|
pBtd->pairWithHID();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ private:
|
||||||
* This is useful for instance if you want to set the LEDs in a specific way.
|
* This is useful for instance if you want to set the LEDs in a specific way.
|
||||||
*/
|
*/
|
||||||
void onInit() {
|
void onInit() {
|
||||||
if (pFuncOnInit)
|
if(pFuncOnInit)
|
||||||
pFuncOnInit(); // Call the user function
|
pFuncOnInit(); // Call the user function
|
||||||
}
|
}
|
||||||
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
||||||
|
|
196
PS3BT.cpp
196
PS3BT.cpp
|
@ -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) :
|
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
|
pBtd(p) // pointer to USB class instance - mandatory
|
||||||
{
|
{
|
||||||
if (pBtd)
|
if(pBtd)
|
||||||
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
||||||
|
|
||||||
pBtd->my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
|
pBtd->my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
|
||||||
|
@ -69,15 +69,15 @@ uint8_t PS3BT::getAnalogHat(AnalogHat a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t PS3BT::getSensor(Sensor a) {
|
int16_t PS3BT::getSensor(Sensor a) {
|
||||||
if (PS3Connected) {
|
if(PS3Connected) {
|
||||||
if (a == aX || a == aY || a == aZ || a == gZ)
|
if(a == aX || a == aY || a == aZ || a == gZ)
|
||||||
return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]);
|
return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
} else if (PS3MoveConnected) {
|
} else if(PS3MoveConnected) {
|
||||||
if (a == mXmove || a == mYmove) // These are all 12-bits long
|
if(a == mXmove || a == mYmove) // These are all 12-bits long
|
||||||
return (((l2capinbuf[(uint16_t)a] & 0x0F) << 8) | (l2capinbuf[(uint16_t)a + 1]));
|
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));
|
return ((l2capinbuf[(uint16_t)a] << 4) | ((l2capinbuf[(uint16_t)a + 1] & 0xF0) >> 4));
|
||||||
else // aXmove, aYmove, aZmove, gXmove, gYmove and gZmove
|
else // aXmove, aYmove, aZmove, gXmove, gYmove and gZmove
|
||||||
return (l2capinbuf[(uint16_t)a] | (l2capinbuf[(uint16_t)a + 1] << 8));
|
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 PS3BT::getAngle(Angle a) {
|
||||||
double accXval, accYval, accZval;
|
double accXval, accYval, accZval;
|
||||||
|
|
||||||
if (PS3Connected) {
|
if(PS3Connected) {
|
||||||
// Data for the Kionix KXPC4 used in the DualShock 3
|
// Data for the Kionix KXPC4 used in the DualShock 3
|
||||||
const double zeroG = 511.5; // 1.65/3.3*1023 (1.65V)
|
const double zeroG = 511.5; // 1.65/3.3*1023 (1.65V)
|
||||||
accXval = -((double)getSensor(aX) - zeroG);
|
accXval = -((double)getSensor(aX) - zeroG);
|
||||||
accYval = -((double)getSensor(aY) - zeroG);
|
accYval = -((double)getSensor(aY) - zeroG);
|
||||||
accZval = -((double)getSensor(aZ) - zeroG);
|
accZval = -((double)getSensor(aZ) - zeroG);
|
||||||
} else if (PS3MoveConnected) {
|
} else if(PS3MoveConnected) {
|
||||||
// It's a Kionix KXSC4 inside the Motion controller
|
// It's a Kionix KXSC4 inside the Motion controller
|
||||||
const uint16_t zeroG = 0x8000;
|
const uint16_t zeroG = 0x8000;
|
||||||
accXval = -(int16_t)(getSensor(aXmove) - zeroG);
|
accXval = -(int16_t)(getSensor(aXmove) - zeroG);
|
||||||
|
@ -106,34 +106,34 @@ double PS3BT::getAngle(Angle a) {
|
||||||
// Convert to 360 degrees resolution
|
// Convert to 360 degrees resolution
|
||||||
// atan2 outputs the value of -π to π (radians)
|
// atan2 outputs the value of -π to π (radians)
|
||||||
// We are then converting it to 0 to 2π and then to degrees
|
// We are then converting it to 0 to 2π and then to degrees
|
||||||
if (a == Pitch)
|
if(a == Pitch)
|
||||||
return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
|
return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
|
||||||
else
|
else
|
||||||
return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
|
return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
|
||||||
}
|
}
|
||||||
|
|
||||||
double PS3BT::get9DOFValues(Sensor a) { // Thanks to Manfred Piendl
|
double PS3BT::get9DOFValues(Sensor a) { // Thanks to Manfred Piendl
|
||||||
if (!PS3MoveConnected)
|
if(!PS3MoveConnected)
|
||||||
return 0;
|
return 0;
|
||||||
int16_t value = getSensor(a);
|
int16_t value = getSensor(a);
|
||||||
if (a == mXmove || a == mYmove || a == mZmove) {
|
if(a == mXmove || a == mYmove || a == mZmove) {
|
||||||
if (value > 2047)
|
if(value > 2047)
|
||||||
value -= 0x1000;
|
value -= 0x1000;
|
||||||
return (double)value / 3.2; // unit: muT = 10^(-6) Tesla
|
return (double)value / 3.2; // unit: muT = 10^(-6) Tesla
|
||||||
} else if (a == aXmove || a == aYmove || a == aZmove) {
|
} else if(a == aXmove || a == aYmove || a == aZmove) {
|
||||||
if (value < 0)
|
if(value < 0)
|
||||||
value += 0x8000;
|
value += 0x8000;
|
||||||
else
|
else
|
||||||
value -= 0x8000;
|
value -= 0x8000;
|
||||||
return (double)value / 442.0; // unit: m/(s^2)
|
return (double)value / 442.0; // unit: m/(s^2)
|
||||||
} else if (a == gXmove || a == gYmove || a == gZmove) {
|
} else if(a == gXmove || a == gYmove || a == gZmove) {
|
||||||
if (value < 0)
|
if(value < 0)
|
||||||
value += 0x8000;
|
value += 0x8000;
|
||||||
else
|
else
|
||||||
value -= 0x8000;
|
value -= 0x8000;
|
||||||
if (a == gXmove)
|
if(a == gXmove)
|
||||||
return (double)value / 11.6; // unit: deg/s
|
return (double)value / 11.6; // unit: deg/s
|
||||||
else if (a == gYmove)
|
else if(a == gYmove)
|
||||||
return (double)value / 11.2; // unit: deg/s
|
return (double)value / 11.2; // unit: deg/s
|
||||||
else // gZmove
|
else // gZmove
|
||||||
return (double)value / 9.6; // unit: deg/s
|
return (double)value / 9.6; // unit: deg/s
|
||||||
|
@ -142,12 +142,12 @@ double PS3BT::get9DOFValues(Sensor a) { // Thanks to Manfred Piendl
|
||||||
}
|
}
|
||||||
|
|
||||||
String PS3BT::getTemperature() {
|
String PS3BT::getTemperature() {
|
||||||
if (PS3MoveConnected) {
|
if(PS3MoveConnected) {
|
||||||
int16_t input = getSensor(tempMove);
|
int16_t input = getSensor(tempMove);
|
||||||
|
|
||||||
String output = String(input / 100);
|
String output = String(input / 100);
|
||||||
output += ".";
|
output += ".";
|
||||||
if (input % 100 < 10)
|
if(input % 100 < 10)
|
||||||
output += "0";
|
output += "0";
|
||||||
output += String(input % 100);
|
output += String(input % 100);
|
||||||
|
|
||||||
|
@ -161,48 +161,48 @@ bool PS3BT::getStatus(Status c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
String PS3BT::getStatusString() {
|
String PS3BT::getStatusString() {
|
||||||
if (PS3Connected || PS3NavigationConnected) {
|
if(PS3Connected || PS3NavigationConnected) {
|
||||||
char statusOutput[100]; // Max string length plus null character
|
char statusOutput[100]; // Max string length plus null character
|
||||||
|
|
||||||
strcpy_P(statusOutput, PSTR("ConnectionStatus: "));
|
strcpy_P(statusOutput, PSTR("ConnectionStatus: "));
|
||||||
|
|
||||||
if (getStatus(Plugged)) strcat_P(statusOutput, PSTR("Plugged"));
|
if(getStatus(Plugged)) strcat_P(statusOutput, PSTR("Plugged"));
|
||||||
else if (getStatus(Unplugged)) strcat_P(statusOutput, PSTR("Unplugged"));
|
else if(getStatus(Unplugged)) strcat_P(statusOutput, PSTR("Unplugged"));
|
||||||
else strcat_P(statusOutput, PSTR("Error"));
|
else strcat_P(statusOutput, PSTR("Error"));
|
||||||
|
|
||||||
|
|
||||||
strcat_P(statusOutput, PSTR(" - PowerRating: "));
|
strcat_P(statusOutput, PSTR(" - PowerRating: "));
|
||||||
if (getStatus(Charging)) strcat_P(statusOutput, PSTR("Charging"));
|
if(getStatus(Charging)) strcat_P(statusOutput, PSTR("Charging"));
|
||||||
else if (getStatus(NotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
|
else if(getStatus(NotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
|
||||||
else if (getStatus(Shutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
|
else if(getStatus(Shutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
|
||||||
else if (getStatus(Dying)) strcat_P(statusOutput, PSTR("Dying"));
|
else if(getStatus(Dying)) strcat_P(statusOutput, PSTR("Dying"));
|
||||||
else if (getStatus(Low)) strcat_P(statusOutput, PSTR("Low"));
|
else if(getStatus(Low)) strcat_P(statusOutput, PSTR("Low"));
|
||||||
else if (getStatus(High)) strcat_P(statusOutput, PSTR("High"));
|
else if(getStatus(High)) strcat_P(statusOutput, PSTR("High"));
|
||||||
else if (getStatus(Full)) strcat_P(statusOutput, PSTR("Full"));
|
else if(getStatus(Full)) strcat_P(statusOutput, PSTR("Full"));
|
||||||
else strcat_P(statusOutput, PSTR("Error"));
|
else strcat_P(statusOutput, PSTR("Error"));
|
||||||
|
|
||||||
strcat_P(statusOutput, PSTR(" - WirelessStatus: "));
|
strcat_P(statusOutput, PSTR(" - WirelessStatus: "));
|
||||||
|
|
||||||
if (getStatus(CableRumble)) strcat_P(statusOutput, PSTR("Cable - Rumble is on"));
|
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(Cable)) strcat_P(statusOutput, PSTR("Cable - Rumble is off"));
|
||||||
else if (getStatus(BluetoothRumble)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is on"));
|
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 if(getStatus(Bluetooth)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is off"));
|
||||||
else strcat_P(statusOutput, PSTR("Error"));
|
else strcat_P(statusOutput, PSTR("Error"));
|
||||||
|
|
||||||
return statusOutput;
|
return statusOutput;
|
||||||
|
|
||||||
} else if (PS3MoveConnected) {
|
} else if(PS3MoveConnected) {
|
||||||
char statusOutput[26]; // Max string length plus null character
|
char statusOutput[26]; // Max string length plus null character
|
||||||
|
|
||||||
strcpy_P(statusOutput, PSTR("PowerRating: "));
|
strcpy_P(statusOutput, PSTR("PowerRating: "));
|
||||||
|
|
||||||
if (getStatus(MoveCharging)) strcat_P(statusOutput, PSTR("Charging"));
|
if(getStatus(MoveCharging)) strcat_P(statusOutput, PSTR("Charging"));
|
||||||
else if (getStatus(MoveNotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
|
else if(getStatus(MoveNotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
|
||||||
else if (getStatus(MoveShutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
|
else if(getStatus(MoveShutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
|
||||||
else if (getStatus(MoveDying)) strcat_P(statusOutput, PSTR("Dying"));
|
else if(getStatus(MoveDying)) strcat_P(statusOutput, PSTR("Dying"));
|
||||||
else if (getStatus(MoveLow)) strcat_P(statusOutput, PSTR("Low"));
|
else if(getStatus(MoveLow)) strcat_P(statusOutput, PSTR("Low"));
|
||||||
else if (getStatus(MoveHigh)) strcat_P(statusOutput, PSTR("High"));
|
else if(getStatus(MoveHigh)) strcat_P(statusOutput, PSTR("High"));
|
||||||
else if (getStatus(MoveFull)) strcat_P(statusOutput, PSTR("Full"));
|
else if(getStatus(MoveFull)) strcat_P(statusOutput, PSTR("Full"));
|
||||||
else strcat_P(statusOutput, PSTR("Error"));
|
else strcat_P(statusOutput, PSTR("Error"));
|
||||||
|
|
||||||
return statusOutput;
|
return statusOutput;
|
||||||
|
@ -219,7 +219,7 @@ void PS3BT::Reset() {
|
||||||
l2cap_state = L2CAP_WAIT;
|
l2cap_state = L2CAP_WAIT;
|
||||||
|
|
||||||
// Needed for PS3 Dualshock Controller commands to work via Bluetooth
|
// 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
|
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) {
|
void PS3BT::ACLData(uint8_t* ACLData) {
|
||||||
if (!pBtd->l2capConnectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected && !activeConnection && !pBtd->connectToWii && !pBtd->incomingWii && !pBtd->pairWithWii) {
|
if(!pBtd->l2capConnectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected && !activeConnection && !pBtd->connectToWii && !pBtd->incomingWii && !pBtd->pairWithWii) {
|
||||||
if (ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
if(ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||||
if ((ACLData[12] | (ACLData[13] << 8)) == HID_CTRL_PSM) {
|
if((ACLData[12] | (ACLData[13] << 8)) == HID_CTRL_PSM) {
|
||||||
pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service
|
pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service
|
||||||
activeConnection = true;
|
activeConnection = true;
|
||||||
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
||||||
l2cap_state = L2CAP_WAIT;
|
l2cap_state = L2CAP_WAIT;
|
||||||
for (uint8_t i = 0; i < 30; i++)
|
for(uint8_t i = 0; i < 30; i++)
|
||||||
remote_name[i] = pBtd->remote_name[i]; // Store the remote name for the connection
|
remote_name[i] = pBtd->remote_name[i]; // Store the remote name for the connection
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
if (pBtd->hci_version < 3) { // Check the HCI Version of the Bluetooth dongle
|
if(pBtd->hci_version < 3) { // Check the HCI Version of the Bluetooth dongle
|
||||||
Notify(PSTR("\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour HCI Version is: "), 0x80);
|
Notify(PSTR("\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour HCI Version is: "), 0x80);
|
||||||
Notify(pBtd->hci_version, 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);
|
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);
|
memcpy(l2capinbuf, ACLData, BULK_MAXPKTSIZE);
|
||||||
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
|
if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
|
||||||
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
||||||
|
@ -268,7 +268,7 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
||||||
#endif
|
#endif
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
|
Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
||||||
|
@ -281,44 +281,44 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
||||||
Notify(PSTR(" Identifier: "), 0x80);
|
Notify(PSTR(" Identifier: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
|
||||||
#endif
|
#endif
|
||||||
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
|
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
control_scid[0] = l2capinbuf[14];
|
control_scid[0] = l2capinbuf[14];
|
||||||
control_scid[1] = l2capinbuf[15];
|
control_scid[1] = l2capinbuf[15];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST);
|
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];
|
identifier = l2capinbuf[9];
|
||||||
interrupt_scid[0] = l2capinbuf[14];
|
interrupt_scid[0] = l2capinbuf[14];
|
||||||
interrupt_scid[1] = l2capinbuf[15];
|
interrupt_scid[1] = l2capinbuf[15];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST);
|
l2cap_set_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST);
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
|
||||||
if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
|
if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
|
||||||
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
||||||
//Notify(PSTR("\r\nHID Control Configuration Complete"), 0x80);
|
//Notify(PSTR("\r\nHID Control Configuration Complete"), 0x80);
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS);
|
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);
|
//Notify(PSTR("\r\nHID Interrupt Configuration Complete"), 0x80);
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS);
|
l2cap_set_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
|
||||||
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
||||||
//Notify(PSTR("\r\nHID Control Configuration Request"), 0x80);
|
//Notify(PSTR("\r\nHID Control Configuration Request"), 0x80);
|
||||||
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], control_scid);
|
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);
|
//Notify(PSTR("\r\nHID Interrupt Configuration Request"), 0x80);
|
||||||
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], interrupt_scid);
|
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], interrupt_scid);
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
|
||||||
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnect Request: Control Channel"), 0x80);
|
Notify(PSTR("\r\nDisconnect Request: Control Channel"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid);
|
pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid);
|
||||||
Reset();
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"), 0x80);
|
Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -326,12 +326,12 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
||||||
pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid);
|
pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid);
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
|
||||||
if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
|
if(l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
|
||||||
//Notify(PSTR("\r\nDisconnect Response: Control Channel"), 0x80);
|
//Notify(PSTR("\r\nDisconnect Response: Control Channel"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE);
|
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);
|
//Notify(PSTR("\r\nDisconnect Response: Interrupt Channel"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE);
|
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);
|
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
//Notify(PSTR("\r\nL2CAP Interrupt"), 0x80);
|
||||||
if (PS3Connected || PS3MoveConnected || PS3NavigationConnected) {
|
if(PS3Connected || PS3MoveConnected || PS3NavigationConnected) {
|
||||||
/* Read Report */
|
/* Read Report */
|
||||||
if (l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
|
if(l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
|
||||||
if (PS3Connected || PS3NavigationConnected)
|
if(PS3Connected || PS3NavigationConnected)
|
||||||
ButtonState = (uint32_t)(l2capinbuf[11] | ((uint16_t)l2capinbuf[12] << 8) | ((uint32_t)l2capinbuf[13] << 16));
|
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));
|
ButtonState = (uint32_t)(l2capinbuf[10] | ((uint16_t)l2capinbuf[11] << 8) | ((uint32_t)l2capinbuf[12] << 16));
|
||||||
|
|
||||||
//Notify(PSTR("\r\nButtonState", 0x80);
|
//Notify(PSTR("\r\nButtonState", 0x80);
|
||||||
//PrintHex<uint32_t>(ButtonState, 0x80);
|
//PrintHex<uint32_t>(ButtonState, 0x80);
|
||||||
|
|
||||||
if (ButtonState != OldButtonState) {
|
if(ButtonState != OldButtonState) {
|
||||||
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
|
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
|
||||||
OldButtonState = ButtonState;
|
OldButtonState = ButtonState;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
|
#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);
|
D_PrintHex<uint8_t > (l2capinbuf[i], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -376,9 +376,9 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3BT::L2CAP_task() {
|
void PS3BT::L2CAP_task() {
|
||||||
switch (l2cap_state) {
|
switch(l2cap_state) {
|
||||||
case L2CAP_WAIT:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80);
|
Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -393,7 +393,7 @@ void PS3BT::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONTROL_SUCCESS:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
|
Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -402,7 +402,7 @@ void PS3BT::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_INTERRUPT_SETUP:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
|
Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -418,11 +418,11 @@ void PS3BT::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_INTERRUPT_CONFIG_REQUEST:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Interrupt Successfully Configured"), 0x80);
|
Notify(PSTR("\r\nHID Interrupt Successfully Configured"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
if (remote_name[0] == 'M') { // First letter in Motion Controller ('M')
|
if(remote_name[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
|
memset(l2capinbuf, 0, BULK_MAXPKTSIZE); // Reset l2cap in buffer as it sometimes read it as a button has been pressed
|
||||||
l2cap_state = TURN_ON_LED;
|
l2cap_state = TURN_ON_LED;
|
||||||
} else
|
} else
|
||||||
|
@ -434,7 +434,7 @@ void PS3BT::L2CAP_task() {
|
||||||
/* These states are handled in Run() */
|
/* These states are handled in Run() */
|
||||||
|
|
||||||
case L2CAP_INTERRUPT_DISCONNECT:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80);
|
Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -445,7 +445,7 @@ void PS3BT::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONTROL_DISCONNECT:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnected Control Channel"), 0x80);
|
Notify(PSTR("\r\nDisconnected Control Channel"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -459,11 +459,11 @@ void PS3BT::L2CAP_task() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3BT::Run() {
|
void PS3BT::Run() {
|
||||||
switch (l2cap_state) {
|
switch(l2cap_state) {
|
||||||
case PS3_ENABLE_SIXAXIS:
|
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
|
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
|
l2capinbuf[i] = 0x7F; // Set the analog joystick values to center position
|
||||||
enable_sixaxis();
|
enable_sixaxis();
|
||||||
l2cap_state = TURN_ON_LED;
|
l2cap_state = TURN_ON_LED;
|
||||||
|
@ -472,18 +472,18 @@ void PS3BT::Run() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TURN_ON_LED:
|
case TURN_ON_LED:
|
||||||
if (millis() - timer > 1000) { // loop 1 second before sending the command
|
if(millis() - timer > 1000) { // loop 1 second before sending the command
|
||||||
if (remote_name[0] == 'P') { // First letter in PLAYSTATION(R)3 Controller ('P')
|
if(remote_name[0] == 'P') { // First letter in PLAYSTATION(R)3 Controller ('P')
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n"), 0x80);
|
Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
PS3Connected = true;
|
PS3Connected = true;
|
||||||
} else if (remote_name[0] == 'N') { // First letter in Navigation Controller ('N')
|
} else if(remote_name[0] == 'N') { // First letter in Navigation Controller ('N')
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nNavigation Controller Enabled\r\n"), 0x80);
|
Notify(PSTR("\r\nNavigation Controller Enabled\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
PS3NavigationConnected = true;
|
PS3NavigationConnected = true;
|
||||||
} else if (remote_name[0] == 'M') { // First letter in Motion Controller ('M')
|
} else if(remote_name[0] == 'M') { // First letter in Motion Controller ('M')
|
||||||
timerBulbRumble = millis();
|
timerBulbRumble = millis();
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nMotion Controller Enabled\r\n"), 0x80);
|
Notify(PSTR("\r\nMotion Controller Enabled\r\n"), 0x80);
|
||||||
|
@ -500,8 +500,8 @@ void PS3BT::Run() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_DONE:
|
case L2CAP_DONE:
|
||||||
if (PS3MoveConnected) { // The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on
|
if(PS3MoveConnected) { // The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on
|
||||||
if (millis() - timerBulbRumble > 4000) { // Send at least every 4th second
|
if(millis() - timerBulbRumble > 4000) { // Send at least every 4th second
|
||||||
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on
|
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on
|
||||||
timerBulbRumble = millis();
|
timerBulbRumble = millis();
|
||||||
}
|
}
|
||||||
|
@ -517,7 +517,7 @@ void PS3BT::Run() {
|
||||||
// Playstation Sixaxis Dualshock and Navigation Controller commands
|
// Playstation Sixaxis Dualshock and Navigation Controller commands
|
||||||
|
|
||||||
void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) {
|
void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) {
|
||||||
if (millis() - timerHID <= 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
|
delay((uint32_t)(150 - (millis() - timerHID))); // There have to be a delay between commands
|
||||||
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]); // Both the Navigation and Dualshock controller sends data via the control channel
|
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]); // Both the Navigation and Dualshock controller sends data via the control channel
|
||||||
timerHID = millis();
|
timerHID = millis();
|
||||||
|
@ -544,8 +544,8 @@ void PS3BT::setRumbleOff() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3BT::setRumbleOn(Rumble mode) {
|
void PS3BT::setRumbleOn(Rumble mode) {
|
||||||
uint8_t power[2] = { 0xff, 0x00 }; // Defaults to RumbleLow
|
uint8_t power[2] = {0xff, 0x00}; // Defaults to RumbleLow
|
||||||
if (mode == RumbleHigh) {
|
if(mode == RumbleHigh) {
|
||||||
power[0] = 0x00;
|
power[0] = 0x00;
|
||||||
power[1] = 0xff;
|
power[1] = 0xff;
|
||||||
}
|
}
|
||||||
|
@ -595,7 +595,7 @@ void PS3BT::enable_sixaxis() { // Command used to enable the Dualshock 3 and Nav
|
||||||
// Playstation Move Controller commands
|
// Playstation Move Controller commands
|
||||||
|
|
||||||
void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) {
|
void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) {
|
||||||
if (millis() - timerHID <= 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
|
delay((uint32_t)(150 - (millis() - timerHID))); // There have to be a delay between commands
|
||||||
pBtd->L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]); // The Move controller sends it's data via the intterrupt channel
|
pBtd->L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]); // The Move controller sends it's data via the intterrupt channel
|
||||||
timerHID = millis();
|
timerHID = millis();
|
||||||
|
@ -616,7 +616,7 @@ void PS3BT::moveSetBulb(Colors color) { //Use this to set the Color using the pr
|
||||||
|
|
||||||
void PS3BT::moveSetRumble(uint8_t rumble) {
|
void PS3BT::moveSetRumble(uint8_t rumble) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#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);
|
Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
// Set the rumble value into the write buffer
|
// Set the rumble value into the write buffer
|
||||||
|
@ -626,10 +626,10 @@ void PS3BT::moveSetRumble(uint8_t rumble) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3BT::onInit() {
|
void PS3BT::onInit() {
|
||||||
if (pFuncOnInit)
|
if(pFuncOnInit)
|
||||||
pFuncOnInit(); // Call the user function
|
pFuncOnInit(); // Call the user function
|
||||||
else {
|
else {
|
||||||
if (PS3MoveConnected)
|
if(PS3MoveConnected)
|
||||||
moveSetBulb(Red);
|
moveSetBulb(Red);
|
||||||
else // Dualshock 3 or Navigation controller
|
else // Dualshock 3 or Navigation controller
|
||||||
setLedOn(LED1);
|
setLedOn(LED1);
|
||||||
|
|
1
PS3BT.h
1
PS3BT.h
|
@ -143,6 +143,7 @@ public:
|
||||||
* @param value See: ::LED enum.
|
* @param value See: ::LED enum.
|
||||||
*/
|
*/
|
||||||
void setLedRaw(uint8_t value);
|
void setLedRaw(uint8_t value);
|
||||||
|
|
||||||
/** Turn all LEDs off. */
|
/** Turn all LEDs off. */
|
||||||
void setLedOff() {
|
void setLedOff() {
|
||||||
setLedRaw(0);
|
setLedRaw(0);
|
||||||
|
|
110
PS3USB.cpp
110
PS3USB.cpp
|
@ -25,14 +25,14 @@ pUsb(p), // pointer to USB class instance - mandatory
|
||||||
bAddress(0), // device address - mandatory
|
bAddress(0), // device address - mandatory
|
||||||
bPollEnable(false) // don't start polling before dongle is connected
|
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].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
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
|
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
|
||||||
|
|
||||||
my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
|
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);
|
Notify(PSTR("\r\nPS3USB Init"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
// check if address has already been assigned to an instance
|
// check if address has already been assigned to an instance
|
||||||
if (bAddress) {
|
if(bAddress) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress in use"), 0x80);
|
Notify(PSTR("\r\nAddress in use"), 0x80);
|
||||||
#endif
|
#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
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
p = addrPool.GetUsbDevicePtr(0);
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
|
|
||||||
if (!p) {
|
if(!p) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress not found"), 0x80);
|
Notify(PSTR("\r\nAddress not found"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p->epinfo) {
|
if(!p->epinfo) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nepinfo is null"), 0x80);
|
Notify(PSTR("\r\nepinfo is null"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -95,19 +95,19 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Restore p->epinfo
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
|
|
||||||
VID = udd->idVendor;
|
VID = udd->idVendor;
|
||||||
PID = udd->idProduct;
|
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;
|
goto FailUnknownDevice;
|
||||||
|
|
||||||
// Allocate new address according to device class
|
// Allocate new address according to device class
|
||||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||||
|
|
||||||
if (!bAddress)
|
if(!bAddress)
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
// Extract Max Packet Size from device descriptor
|
// 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
|
// Assign new address to the device
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
rcode = pUsb->setAddr(0, 0, bAddress);
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
@ -135,14 +135,14 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
//get pointer to assigned address record
|
//get pointer to assigned address record
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
p->lowspeed = lowspeed;
|
p->lowspeed = lowspeed;
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer - only EP0 is known
|
// Assign epInfo to epinfo pointer - only EP0 is known
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,17 +165,17 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = 0;
|
epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = 0;
|
||||||
|
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
delay(200); //Give time for address change
|
delay(200); //Give time for address change
|
||||||
|
|
||||||
rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1);
|
rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
if (PID == PS3_PID || PID == PS3NAVIGATION_PID) {
|
if(PID == PS3_PID || PID == PS3NAVIGATION_PID) {
|
||||||
if (PID == PS3_PID) {
|
if(PID == PS3_PID) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
|
Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
|
||||||
#endif
|
#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
|
enable_sixaxis(); // The PS3 controller needs a special command before it starts sending data
|
||||||
|
|
||||||
// Needed for PS3 Dualshock and Navigation commands to work
|
// 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]);
|
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
|
readBuf[i] = 0x7F; // Set the analog joystick values to center position
|
||||||
} else { // must be a Motion controller
|
} else { // must be a Motion controller
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
@ -201,15 +201,15 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
PS3MoveConnected = true;
|
PS3MoveConnected = true;
|
||||||
writeBuf[0] = 0x02; // Set report ID, this is needed for Move commands to work
|
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(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(PS3MoveConnected)
|
||||||
setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address
|
setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address
|
||||||
else
|
else
|
||||||
setBdaddr(my_bdaddr); // Set internal Bluetooth address
|
setBdaddr(my_bdaddr); // Set internal Bluetooth address
|
||||||
|
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
|
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);
|
D_PrintHex<uint8_t > (my_bdaddr[i], 0x80);
|
||||||
Notify(PSTR(":"), 0x80);
|
Notify(PSTR(":"), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -269,20 +269,20 @@ uint8_t PS3USB::Release() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t PS3USB::Poll() {
|
uint8_t PS3USB::Poll() {
|
||||||
if (!bPollEnable)
|
if(!bPollEnable)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (PS3Connected || PS3NavigationConnected) {
|
if(PS3Connected || PS3NavigationConnected) {
|
||||||
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
|
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
|
||||||
pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
|
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();
|
readReport();
|
||||||
#ifdef PRINTREPORT
|
#ifdef PRINTREPORT
|
||||||
printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
|
printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else if (PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
|
} else if(PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
|
||||||
if (millis() - timer > 4000) { // Send at least every 4th second
|
if(millis() - timer > 4000) { // Send at least every 4th second
|
||||||
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on
|
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on
|
||||||
timer = millis();
|
timer = millis();
|
||||||
}
|
}
|
||||||
|
@ -296,7 +296,7 @@ void PS3USB::readReport() {
|
||||||
//Notify(PSTR("\r\nButtonState", 0x80);
|
//Notify(PSTR("\r\nButtonState", 0x80);
|
||||||
//PrintHex<uint32_t>(ButtonState, 0x80);
|
//PrintHex<uint32_t>(ButtonState, 0x80);
|
||||||
|
|
||||||
if (ButtonState != OldButtonState) {
|
if(ButtonState != OldButtonState) {
|
||||||
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
|
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
|
||||||
OldButtonState = ButtonState;
|
OldButtonState = ButtonState;
|
||||||
}
|
}
|
||||||
|
@ -304,7 +304,7 @@ void PS3USB::readReport() {
|
||||||
|
|
||||||
void PS3USB::printReport() { // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
|
void PS3USB::printReport() { // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
|
||||||
#ifdef PRINTREPORT
|
#ifdef PRINTREPORT
|
||||||
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) {
|
for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) {
|
||||||
D_PrintHex<uint8_t > (readBuf[i], 0x80);
|
D_PrintHex<uint8_t > (readBuf[i], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -336,7 +336,7 @@ uint16_t PS3USB::getSensor(Sensor a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
double PS3USB::getAngle(Angle a) {
|
double PS3USB::getAngle(Angle a) {
|
||||||
if (PS3Connected) {
|
if(PS3Connected) {
|
||||||
double accXval;
|
double accXval;
|
||||||
double accYval;
|
double accYval;
|
||||||
double accZval;
|
double accZval;
|
||||||
|
@ -350,7 +350,7 @@ double PS3USB::getAngle(Angle a) {
|
||||||
// Convert to 360 degrees resolution
|
// Convert to 360 degrees resolution
|
||||||
// atan2 outputs the value of -π to π (radians)
|
// atan2 outputs the value of -π to π (radians)
|
||||||
// We are then converting it to 0 to 2π and then to degrees
|
// We are then converting it to 0 to 2π and then to degrees
|
||||||
if (a == Pitch)
|
if(a == Pitch)
|
||||||
return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
|
return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
|
||||||
else
|
else
|
||||||
return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
|
return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
|
||||||
|
@ -363,33 +363,33 @@ bool PS3USB::getStatus(Status c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
String PS3USB::getStatusString() {
|
String PS3USB::getStatusString() {
|
||||||
if (PS3Connected || PS3NavigationConnected) {
|
if(PS3Connected || PS3NavigationConnected) {
|
||||||
char statusOutput[100];
|
char statusOutput[100];
|
||||||
|
|
||||||
strcpy(statusOutput, "ConnectionStatus: ");
|
strcpy(statusOutput, "ConnectionStatus: ");
|
||||||
|
|
||||||
if (getStatus(Plugged)) strcat(statusOutput, "Plugged");
|
if(getStatus(Plugged)) strcat(statusOutput, "Plugged");
|
||||||
else if (getStatus(Unplugged)) strcat(statusOutput, "Unplugged");
|
else if(getStatus(Unplugged)) strcat(statusOutput, "Unplugged");
|
||||||
else strcat(statusOutput, "Error");
|
else strcat(statusOutput, "Error");
|
||||||
|
|
||||||
|
|
||||||
strcat(statusOutput, " - PowerRating: ");
|
strcat(statusOutput, " - PowerRating: ");
|
||||||
|
|
||||||
if (getStatus(Charging)) strcat(statusOutput, "Charging");
|
if(getStatus(Charging)) strcat(statusOutput, "Charging");
|
||||||
else if (getStatus(NotCharging)) strcat(statusOutput, "Not Charging");
|
else if(getStatus(NotCharging)) strcat(statusOutput, "Not Charging");
|
||||||
else if (getStatus(Shutdown)) strcat(statusOutput, "Shutdown");
|
else if(getStatus(Shutdown)) strcat(statusOutput, "Shutdown");
|
||||||
else if (getStatus(Dying)) strcat(statusOutput, "Dying");
|
else if(getStatus(Dying)) strcat(statusOutput, "Dying");
|
||||||
else if (getStatus(Low)) strcat(statusOutput, "Low");
|
else if(getStatus(Low)) strcat(statusOutput, "Low");
|
||||||
else if (getStatus(High)) strcat(statusOutput, "High");
|
else if(getStatus(High)) strcat(statusOutput, "High");
|
||||||
else if (getStatus(Full)) strcat(statusOutput, "Full");
|
else if(getStatus(Full)) strcat(statusOutput, "Full");
|
||||||
else strcat(statusOutput, "Error");
|
else strcat(statusOutput, "Error");
|
||||||
|
|
||||||
strcat(statusOutput, " - WirelessStatus: ");
|
strcat(statusOutput, " - WirelessStatus: ");
|
||||||
|
|
||||||
if (getStatus(CableRumble)) strcat(statusOutput, "Cable - Rumble is on");
|
if(getStatus(CableRumble)) strcat(statusOutput, "Cable - Rumble is on");
|
||||||
else if (getStatus(Cable)) strcat(statusOutput, "Cable - Rumble is off");
|
else if(getStatus(Cable)) strcat(statusOutput, "Cable - Rumble is off");
|
||||||
else if (getStatus(BluetoothRumble)) strcat(statusOutput, "Bluetooth - Rumble is on");
|
else if(getStatus(BluetoothRumble)) strcat(statusOutput, "Bluetooth - Rumble is on");
|
||||||
else if (getStatus(Bluetooth)) strcat(statusOutput, "Bluetooth - Rumble is off");
|
else if(getStatus(Bluetooth)) strcat(statusOutput, "Bluetooth - Rumble is off");
|
||||||
else strcat(statusOutput, "Error");
|
else strcat(statusOutput, "Error");
|
||||||
|
|
||||||
return statusOutput;
|
return statusOutput;
|
||||||
|
@ -404,7 +404,7 @@ void PS3USB::PS3_Command(uint8_t *data, uint16_t nbytes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::setAllOff() {
|
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
|
writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer
|
||||||
|
|
||||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||||
|
@ -420,9 +420,9 @@ void PS3USB::setRumbleOff() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::setRumbleOn(Rumble mode) {
|
void PS3USB::setRumbleOn(Rumble mode) {
|
||||||
if ((mode & 0x30) > 0x00) {
|
if((mode & 0x30) > 0x00) {
|
||||||
uint8_t power[2] = {0xff, 0x00}; // Defaults to RumbleLow
|
uint8_t power[2] = {0xff, 0x00}; // Defaults to RumbleLow
|
||||||
if (mode == RumbleHigh) {
|
if(mode == RumbleHigh) {
|
||||||
power[0] = 0x00;
|
power[0] = 0x00;
|
||||||
power[1] = 0xff;
|
power[1] = 0xff;
|
||||||
}
|
}
|
||||||
|
@ -464,7 +464,7 @@ void PS3USB::setBdaddr(uint8_t *bdaddr) {
|
||||||
buf[0] = 0x01;
|
buf[0] = 0x01;
|
||||||
buf[1] = 0x00;
|
buf[1] = 0x00;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
for(uint8_t i = 0; i < 6; i++)
|
||||||
buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first
|
buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first
|
||||||
|
|
||||||
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
||||||
|
@ -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
|
// 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);
|
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
|
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) {
|
void PS3USB::moveSetRumble(uint8_t rumble) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#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);
|
Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
writeBuf[6] = rumble; // Set the rumble value into the write buffer
|
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[9] = 0x02;
|
||||||
buf[10] = 0x12;
|
buf[10] = 0x12;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
for(uint8_t i = 0; i < 6; i++)
|
||||||
buf[i + 1] = bdaddr[i];
|
buf[i + 1] = bdaddr[i];
|
||||||
|
|
||||||
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
|
||||||
|
@ -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
|
// 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);
|
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];
|
bdaddr[i] = buf[10 + i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::getMoveCalibration(uint8_t *data) {
|
void PS3USB::getMoveCalibration(uint8_t *data) {
|
||||||
uint8_t buf[49];
|
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
|
// 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);
|
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];
|
data[49 * i + j] = buf[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3USB::onInit() {
|
void PS3USB::onInit() {
|
||||||
if (pFuncOnInit)
|
if(pFuncOnInit)
|
||||||
pFuncOnInit(); // Call the user function
|
pFuncOnInit(); // Call the user function
|
||||||
else {
|
else {
|
||||||
if (PS3MoveConnected)
|
if(PS3MoveConnected)
|
||||||
moveSetBulb(Red);
|
moveSetBulb(Red);
|
||||||
else // Dualshock 3 or Navigation controller
|
else // Dualshock 3 or Navigation controller
|
||||||
setLedOn(LED1);
|
setLedOn(LED1);
|
||||||
|
|
1
PS3USB.h
1
PS3USB.h
|
@ -220,6 +220,7 @@ public:
|
||||||
* @param value See: ::LED enum.
|
* @param value See: ::LED enum.
|
||||||
*/
|
*/
|
||||||
void setLedRaw(uint8_t value);
|
void setLedRaw(uint8_t value);
|
||||||
|
|
||||||
/** Turn all LEDs off. */
|
/** Turn all LEDs off. */
|
||||||
void setLedOff() {
|
void setLedOff() {
|
||||||
setLedRaw(0);
|
setLedRaw(0);
|
||||||
|
|
168
SPP.cpp
168
SPP.cpp
|
@ -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) :
|
SPP::SPP(BTD *p, const char* name, const char* pin) :
|
||||||
pBtd(p) // Pointer to BTD class instance - mandatory
|
pBtd(p) // Pointer to BTD class instance - mandatory
|
||||||
{
|
{
|
||||||
if (pBtd)
|
if(pBtd)
|
||||||
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
||||||
|
|
||||||
pBtd->btdName = name;
|
pBtd->btdName = name;
|
||||||
|
@ -74,32 +74,32 @@ void SPP::Reset() {
|
||||||
void SPP::disconnect() {
|
void SPP::disconnect() {
|
||||||
connected = false;
|
connected = false;
|
||||||
// First the two L2CAP channels has to be disconnected and then the HCI connection
|
// 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);
|
pBtd->l2cap_disconnection_request(hci_handle, ++identifier, rfcomm_scid, rfcomm_dcid);
|
||||||
if (RFCOMMConnected && SDPConnected)
|
if(RFCOMMConnected && SDPConnected)
|
||||||
delay(1); // Add delay between commands
|
delay(1); // Add delay between commands
|
||||||
if (SDPConnected)
|
if(SDPConnected)
|
||||||
pBtd->l2cap_disconnection_request(hci_handle, ++identifier, sdp_scid, sdp_dcid);
|
pBtd->l2cap_disconnection_request(hci_handle, ++identifier, sdp_scid, sdp_dcid);
|
||||||
l2cap_sdp_state = L2CAP_DISCONNECT_RESPONSE;
|
l2cap_sdp_state = L2CAP_DISCONNECT_RESPONSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPP::ACLData(uint8_t* l2capinbuf) {
|
void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
if (!connected) {
|
if(!connected) {
|
||||||
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||||
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM && !pBtd->sdpConnectionClaimed) {
|
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM && !pBtd->sdpConnectionClaimed) {
|
||||||
pBtd->sdpConnectionClaimed = true;
|
pBtd->sdpConnectionClaimed = true;
|
||||||
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
||||||
l2cap_sdp_state = L2CAP_SDP_WAIT; // Reset state
|
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;
|
pBtd->rfcommConnectionClaimed = true;
|
||||||
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
||||||
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT; // Reset state
|
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT; // Reset state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((l2capinbuf[0] | (uint16_t)l2capinbuf[1] << 8) == (hci_handle | 0x2000U)) { // acl_handle_ok
|
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[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
|
||||||
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
||||||
|
@ -114,7 +114,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
||||||
#endif
|
#endif
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
|
Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
||||||
|
@ -127,56 +127,56 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
Notify(PSTR(" Identifier: "), 0x80);
|
Notify(PSTR(" Identifier: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
|
||||||
#endif
|
#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];
|
identifier = l2capinbuf[9];
|
||||||
sdp_scid[0] = l2capinbuf[14];
|
sdp_scid[0] = l2capinbuf[14];
|
||||||
sdp_scid[1] = l2capinbuf[15];
|
sdp_scid[1] = l2capinbuf[15];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONNECTION_SDP_REQUEST);
|
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];
|
identifier = l2capinbuf[9];
|
||||||
rfcomm_scid[0] = l2capinbuf[14];
|
rfcomm_scid[0] = l2capinbuf[14];
|
||||||
rfcomm_scid[1] = l2capinbuf[15];
|
rfcomm_scid[1] = l2capinbuf[15];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST);
|
l2cap_set_flag(L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST);
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
|
||||||
if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
|
if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
|
||||||
if (l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
|
if(l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
|
||||||
//Notify(PSTR("\r\nSDP Configuration Complete"), 0x80);
|
//Notify(PSTR("\r\nSDP Configuration Complete"), 0x80);
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONFIG_SDP_SUCCESS);
|
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);
|
//Notify(PSTR("\r\nRFCOMM Configuration Complete"), 0x80);
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS);
|
l2cap_set_flag(L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
|
||||||
if (l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
|
if(l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
|
||||||
//Notify(PSTR("\r\nSDP Configuration Request"), 0x80);
|
//Notify(PSTR("\r\nSDP Configuration Request"), 0x80);
|
||||||
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], sdp_scid);
|
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);
|
//Notify(PSTR("\r\nRFCOMM Configuration Request"), 0x80);
|
||||||
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], rfcomm_scid);
|
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], rfcomm_scid);
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
|
||||||
if (l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
|
if(l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
|
||||||
//Notify(PSTR("\r\nDisconnect Request: SDP Channel"), 0x80);
|
//Notify(PSTR("\r\nDisconnect Request: SDP Channel"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_SDP_REQUEST);
|
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);
|
//Notify(PSTR("\r\nDisconnect Request: RFCOMM Channel"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST);
|
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST);
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
|
||||||
if (l2capinbuf[12] == sdp_scid[0] && l2capinbuf[13] == sdp_scid[1]) {
|
if(l2capinbuf[12] == sdp_scid[0] && l2capinbuf[13] == sdp_scid[1]) {
|
||||||
//Notify(PSTR("\r\nDisconnect Response: SDP Channel"), 0x80);
|
//Notify(PSTR("\r\nDisconnect Response: SDP Channel"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_RESPONSE);
|
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);
|
//Notify(PSTR("\r\nDisconnect Response: RFCOMM Channel"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_RESPONSE);
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nInformation request"), 0x80);
|
Notify(PSTR("\r\nInformation request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -189,18 +189,18 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else if (l2capinbuf[6] == sdp_dcid[0] && l2capinbuf[7] == sdp_dcid[1]) { // SDP
|
} else if(l2capinbuf[6] == sdp_dcid[0] && l2capinbuf[7] == sdp_dcid[1]) { // SDP
|
||||||
if (l2capinbuf[8] == SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST_PDU) {
|
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(((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) {
|
if(firstMessage) {
|
||||||
serialPortResponse1(l2capinbuf[9], l2capinbuf[10]);
|
serialPortResponse1(l2capinbuf[9], l2capinbuf[10]);
|
||||||
firstMessage = false;
|
firstMessage = false;
|
||||||
} else {
|
} else {
|
||||||
serialPortResponse2(l2capinbuf[9], l2capinbuf[10]); // Serialport continuation state
|
serialPortResponse2(l2capinbuf[9], l2capinbuf[10]); // Serialport continuation state
|
||||||
firstMessage = true;
|
firstMessage = true;
|
||||||
}
|
}
|
||||||
} else if (((l2capinbuf[16] << 8 | l2capinbuf[17]) == L2CAP_UUID) || ((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000 && (l2capinbuf[18] << 8 | l2capinbuf[19]) == L2CAP_UUID)) {
|
} else if(((l2capinbuf[16] << 8 | l2capinbuf[17]) == L2CAP_UUID) || ((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000 && (l2capinbuf[18] << 8 | l2capinbuf[19]) == L2CAP_UUID)) {
|
||||||
if (firstMessage) {
|
if(firstMessage) {
|
||||||
l2capResponse1(l2capinbuf[9], l2capinbuf[10]);
|
l2capResponse1(l2capinbuf[9], l2capinbuf[10]);
|
||||||
firstMessage = false;
|
firstMessage = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -216,14 +216,14 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
uuid = (l2capinbuf[18] << 8 | l2capinbuf[19]);
|
uuid = (l2capinbuf[18] << 8 | l2capinbuf[19]);
|
||||||
else // Short UUID
|
else // Short UUID
|
||||||
uuid = (l2capinbuf[16] << 8 | l2capinbuf[17]);
|
uuid = (l2capinbuf[16] << 8 | l2capinbuf[17]);
|
||||||
D_PrintHex<uint16_t> (uuid, 0x80);
|
D_PrintHex<uint16_t > (uuid, 0x80);
|
||||||
|
|
||||||
Notify(PSTR("\r\nLength: "), 0x80);
|
Notify(PSTR("\r\nLength: "), 0x80);
|
||||||
uint16_t length = l2capinbuf[11] << 8 | l2capinbuf[12];
|
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);
|
Notify(PSTR("\r\nData: "), 0x80);
|
||||||
for (uint8_t i = 0; i < length; i++) {
|
for(uint8_t i = 0; i < length; i++) {
|
||||||
D_PrintHex<uint8_t> (l2capinbuf[13+i], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[13 + i], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -234,14 +234,14 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
rfcommChannel = l2capinbuf[8] & 0xF8;
|
||||||
rfcommDirection = l2capinbuf[8] & 0x04;
|
rfcommDirection = l2capinbuf[8] & 0x04;
|
||||||
rfcommCommandResponse = l2capinbuf[8] & 0x02;
|
rfcommCommandResponse = l2capinbuf[8] & 0x02;
|
||||||
rfcommChannelType = l2capinbuf[9] & 0xEF;
|
rfcommChannelType = l2capinbuf[9] & 0xEF;
|
||||||
rfcommPfBit = l2capinbuf[9] & 0x10;
|
rfcommPfBit = l2capinbuf[9] & 0x10;
|
||||||
|
|
||||||
if (rfcommChannel >> 3 != 0x00)
|
if(rfcommChannel >> 3 != 0x00)
|
||||||
rfcommChannelConnection = rfcommChannel;
|
rfcommChannelConnection = rfcommChannel;
|
||||||
|
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
|
@ -256,7 +256,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
Notify(PSTR(" PF_BIT: "), 0x80);
|
Notify(PSTR(" PF_BIT: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (rfcommPfBit, 0x80);
|
D_PrintHex<uint8_t > (rfcommPfBit, 0x80);
|
||||||
#endif
|
#endif
|
||||||
if (rfcommChannelType == RFCOMM_DISC) {
|
if(rfcommChannelType == RFCOMM_DISC) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nReceived Disconnect RFCOMM Command on channel: "), 0x80);
|
Notify(PSTR("\r\nReceived Disconnect RFCOMM Command on channel: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (rfcommChannel >> 3, 0x80);
|
D_PrintHex<uint8_t > (rfcommChannel >> 3, 0x80);
|
||||||
|
@ -264,15 +264,15 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
connected = false;
|
connected = false;
|
||||||
sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse, RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00); // UA Command
|
sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse, RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00); // UA Command
|
||||||
}
|
}
|
||||||
if (connected) {
|
if(connected) {
|
||||||
/* Read the incoming message */
|
/* Read the incoming message */
|
||||||
if (rfcommChannelType == RFCOMM_UIH && rfcommChannel == rfcommChannelConnection) {
|
if(rfcommChannelType == RFCOMM_UIH && rfcommChannel == rfcommChannelConnection) {
|
||||||
uint8_t length = l2capinbuf[10] >> 1; // Get length
|
uint8_t length = l2capinbuf[10] >> 1; // Get length
|
||||||
uint8_t offset = l2capinbuf[4] - length - 4; // Check if there is credit
|
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;
|
uint8_t i = 0;
|
||||||
for (; i < length; i++) {
|
for(; i < length; i++) {
|
||||||
if (rfcommAvailable + i >= sizeof (rfcommDataBuffer)) {
|
if(rfcommAvailable + i >= sizeof (rfcommDataBuffer)) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nWarning: Buffer is full!"), 0x80);
|
Notify(PSTR("\r\nWarning: Buffer is full!"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -284,7 +284,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("\r\nRFCOMM Data Available: "), 0x80);
|
Notify(PSTR("\r\nRFCOMM Data Available: "), 0x80);
|
||||||
Notify(rfcommAvailable, 0x80);
|
Notify(rfcommAvailable, 0x80);
|
||||||
if (offset) {
|
if(offset) {
|
||||||
Notify(PSTR(" - Credit: 0x"), 0x80);
|
Notify(PSTR(" - Credit: 0x"), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[11], 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);
|
Notify(PSTR("\r\nError in FCS checksum!"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send to the Arduino via Bluetooth
|
#ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send to the Arduino via Bluetooth
|
||||||
for (uint8_t i = 0; i < length; i++)
|
for(uint8_t i = 0; i < length; i++)
|
||||||
Notifyc(l2capinbuf[i + 11 + offset], 0x80);
|
Notifyc(l2capinbuf[i + 11 + offset], 0x80);
|
||||||
#endif
|
#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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
|
Notify(PSTR("\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -313,7 +313,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
rfcommbuf[8] = l2capinbuf[19]; // MaxRatransm.
|
rfcommbuf[8] = l2capinbuf[19]; // MaxRatransm.
|
||||||
rfcommbuf[9] = l2capinbuf[20]; // Number of Frames
|
rfcommbuf[9] = l2capinbuf[20]; // Number of Frames
|
||||||
sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A); // UIH Remote Port Negotiation Response
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nSend UIH Modem Status Response"), 0x80);
|
Notify(PSTR("\r\nSend UIH Modem Status Response"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -324,12 +324,12 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
|
sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nReceived SABM Command"), 0x80);
|
Notify(PSTR("\r\nReceived SABM Command"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse, RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00); // UA Command
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nReceived UIH Parameter Negotiation Command"), 0x80);
|
Notify(PSTR("\r\nReceived UIH Parameter Negotiation Command"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -344,7 +344,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
rfcommbuf[8] = 0x00; // MaxRatransm.
|
rfcommbuf[8] = 0x00; // MaxRatransm.
|
||||||
rfcommbuf[9] = 0x00; // Number of Frames
|
rfcommbuf[9] = 0x00; // Number of Frames
|
||||||
sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A);
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nSend UIH Modem Status Response"), 0x80);
|
Notify(PSTR("\r\nSend UIH Modem Status Response"), 0x80);
|
||||||
#endif
|
#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)
|
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);
|
sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
|
||||||
} else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_RSP) { // UIH Modem Status Response
|
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_RSP) { // UIH Modem Status Response
|
||||||
if (!creditSent) {
|
if(!creditSent) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nSend UIH Command with credit"), 0x80);
|
Notify(PSTR("\r\nSend UIH Command with credit"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -374,11 +374,11 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
timer = millis();
|
timer = millis();
|
||||||
waitForLastCommand = true;
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nReceived UIH Command with credit"), 0x80);
|
Notify(PSTR("\r\nReceived UIH Command with credit"), 0x80);
|
||||||
#endif
|
#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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
|
Notify(PSTR("\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -402,7 +402,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
sppIndex = 0;
|
sppIndex = 0;
|
||||||
}
|
}
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
else if (rfcommChannelType != RFCOMM_DISC) {
|
else if(rfcommChannelType != RFCOMM_DISC) {
|
||||||
Notify(PSTR("\r\nUnsupported RFCOMM Data - ChannelType: "), 0x80);
|
Notify(PSTR("\r\nUnsupported RFCOMM Data - ChannelType: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (rfcommChannelType, 0x80);
|
D_PrintHex<uint8_t > (rfcommChannelType, 0x80);
|
||||||
Notify(PSTR(" Command: "), 0x80);
|
Notify(PSTR(" Command: "), 0x80);
|
||||||
|
@ -425,7 +425,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPP::Run() {
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"), 0x80);
|
Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -438,9 +438,9 @@ void SPP::Run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPP::SDP_task() {
|
void SPP::SDP_task() {
|
||||||
switch (l2cap_sdp_state) {
|
switch(l2cap_sdp_state) {
|
||||||
case L2CAP_SDP_WAIT:
|
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
|
l2cap_clear_flag(L2CAP_FLAG_CONNECTION_SDP_REQUEST); // Clear flag
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nSDP Incoming Connection Request"), 0x80);
|
Notify(PSTR("\r\nSDP Incoming Connection Request"), 0x80);
|
||||||
|
@ -452,7 +452,7 @@ void SPP::SDP_task() {
|
||||||
delay(1);
|
delay(1);
|
||||||
pBtd->l2cap_config_request(hci_handle, identifier, sdp_scid);
|
pBtd->l2cap_config_request(hci_handle, identifier, sdp_scid);
|
||||||
l2cap_sdp_state = L2CAP_SDP_SUCCESS;
|
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
|
l2cap_clear_flag(L2CAP_FLAG_DISCONNECT_SDP_REQUEST); // Clear flag
|
||||||
SDPConnected = false;
|
SDPConnected = false;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
@ -462,7 +462,7 @@ void SPP::SDP_task() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case L2CAP_SDP_SUCCESS:
|
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
|
l2cap_clear_flag(L2CAP_FLAG_CONFIG_SDP_SUCCESS); // Clear flag
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nSDP Successfully Configured"), 0x80);
|
Notify(PSTR("\r\nSDP Successfully Configured"), 0x80);
|
||||||
|
@ -474,7 +474,7 @@ void SPP::SDP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_DISCONNECT_RESPONSE: // This is for both disconnection response from the RFCOMM and SDP channel if they were connected
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnected L2CAP Connection"), 0x80);
|
Notify(PSTR("\r\nDisconnected L2CAP Connection"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -487,9 +487,9 @@ void SPP::SDP_task() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPP::RFCOMM_task() {
|
void SPP::RFCOMM_task() {
|
||||||
switch (l2cap_rfcomm_state) {
|
switch(l2cap_rfcomm_state) {
|
||||||
case L2CAP_RFCOMM_WAIT:
|
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
|
l2cap_clear_flag(L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST); // Clear flag
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nRFCOMM Incoming Connection Request"), 0x80);
|
Notify(PSTR("\r\nRFCOMM Incoming Connection Request"), 0x80);
|
||||||
|
@ -501,7 +501,7 @@ void SPP::RFCOMM_task() {
|
||||||
delay(1);
|
delay(1);
|
||||||
pBtd->l2cap_config_request(hci_handle, identifier, rfcomm_scid);
|
pBtd->l2cap_config_request(hci_handle, identifier, rfcomm_scid);
|
||||||
l2cap_rfcomm_state = L2CAP_RFCOMM_SUCCESS;
|
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
|
l2cap_clear_flag(L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST); // Clear flag
|
||||||
RFCOMMConnected = false;
|
RFCOMMConnected = false;
|
||||||
connected = false;
|
connected = false;
|
||||||
|
@ -512,7 +512,7 @@ void SPP::RFCOMM_task() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case L2CAP_RFCOMM_SUCCESS:
|
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
|
l2cap_clear_flag(L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS); // Clear flag
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nRFCOMM Successfully Configured"), 0x80);
|
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[1] = channelType | pfBit; // RFCOMM Control
|
||||||
l2capoutbuf[2] = length << 1 | 0x01; // Length and format (always 0x01 bytes format)
|
l2capoutbuf[2] = length << 1 | 0x01; // Length and format (always 0x01 bytes format)
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
for (; i < length; i++)
|
for(; i < length; i++)
|
||||||
l2capoutbuf[i + 3] = data[i];
|
l2capoutbuf[i + 3] = data[i];
|
||||||
l2capoutbuf[i + 3] = calcFcs(l2capoutbuf);
|
l2capoutbuf[i + 3] = calcFcs(l2capoutbuf);
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR(" - RFCOMM Data: "), 0x80);
|
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);
|
D_PrintHex<uint8_t > (l2capoutbuf[i], 0x80);
|
||||||
Notify(PSTR(" "), 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);
|
l2capoutbuf[4] = calcFcs(l2capoutbuf);
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR(" - RFCOMM Credit Data: "), 0x80);
|
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);
|
D_PrintHex<uint8_t > (l2capoutbuf[i], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -707,7 +707,7 @@ uint8_t SPP::crc(uint8_t *data) {
|
||||||
/* Calculate FCS */
|
/* Calculate FCS */
|
||||||
uint8_t SPP::calcFcs(uint8_t *data) {
|
uint8_t SPP::calcFcs(uint8_t *data) {
|
||||||
uint8_t temp = crc(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
|
return (0xFF - temp); // FCS on 2 bytes
|
||||||
else
|
else
|
||||||
return (0xFF - pgm_read_byte(&rfcomm_crc_table[temp ^ data[2]])); // FCS on 3 bytes
|
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 */
|
/* Check FCS */
|
||||||
bool SPP::checkFcs(uint8_t *data, uint8_t fcs) {
|
bool SPP::checkFcs(uint8_t *data, uint8_t fcs) {
|
||||||
uint8_t temp = crc(data);
|
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
|
temp = pgm_read_byte(&rfcomm_crc_table[temp ^ data[2]]); // FCS on 3 bytes
|
||||||
return (pgm_read_byte(&rfcomm_crc_table[temp ^ fcs]) == 0xCF);
|
return (pgm_read_byte(&rfcomm_crc_table[temp ^ fcs]) == 0xCF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Serial commands */
|
/* Serial commands */
|
||||||
#if defined(ARDUINO) && ARDUINO >=100
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
|
||||||
size_t SPP::write(uint8_t data) {
|
size_t SPP::write(uint8_t data) {
|
||||||
return write(&data, 1);
|
return write(&data, 1);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void SPP::write(uint8_t data) {
|
void SPP::write(uint8_t data) {
|
||||||
write(&data, 1);
|
write(&data, 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ARDUINO) && ARDUINO >=100
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
|
||||||
size_t SPP::write(const uint8_t *data, size_t size) {
|
size_t SPP::write(const uint8_t *data, size_t size) {
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void SPP::write(const uint8_t *data, size_t size) {
|
void SPP::write(const uint8_t *data, size_t size) {
|
||||||
#endif
|
#endif
|
||||||
for(uint8_t i = 0; i < size; i++) {
|
for(uint8_t i = 0; i < size; i++) {
|
||||||
if(sppIndex >= sizeof(sppOutputBuffer)/sizeof(sppOutputBuffer[0]))
|
if(sppIndex >= sizeof (sppOutputBuffer) / sizeof (sppOutputBuffer[0]))
|
||||||
send(); // Send the current data in the buffer
|
send(); // Send the current data in the buffer
|
||||||
sppOutputBuffer[sppIndex++] = data[i]; // All the bytes are put into a buffer and then send using the send() function
|
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() {
|
void SPP::send() {
|
||||||
if (!connected || !sppIndex)
|
if(!connected || !sppIndex)
|
||||||
return;
|
return;
|
||||||
uint8_t length; // This is the length of the string we are sending
|
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
|
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[0] = rfcommChannelConnection | 0 | 0 | extendAddress; // RFCOMM Address
|
||||||
l2capoutbuf[1] = RFCOMM_UIH; // RFCOMM Control
|
l2capoutbuf[1] = RFCOMM_UIH; // RFCOMM Control
|
||||||
|
|
||||||
while (sppIndex) { // We will run this while loop until this variable is 0
|
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
|
if(sppIndex > (sizeof (l2capoutbuf) - 4)) // Check if the string is larger than the outgoing buffer
|
||||||
length = sizeof (l2capoutbuf) - 4;
|
length = sizeof (l2capoutbuf) - 4;
|
||||||
else
|
else
|
||||||
length = sppIndex;
|
length = sppIndex;
|
||||||
|
|
||||||
l2capoutbuf[2] = length << 1 | 1; // Length
|
l2capoutbuf[2] = length << 1 | 1; // Length
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
for (; i < length; i++)
|
for(; i < length; i++)
|
||||||
l2capoutbuf[i + 3] = sppOutputBuffer[i + offset];
|
l2capoutbuf[i + 3] = sppOutputBuffer[i + offset];
|
||||||
l2capoutbuf[i + 3] = calcFcs(l2capoutbuf); // Calculate checksum
|
l2capoutbuf[i + 3] = calcFcs(l2capoutbuf); // Calculate checksum
|
||||||
|
|
||||||
|
@ -784,20 +788,20 @@ void SPP::discard(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int SPP::peek(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 -1;
|
||||||
return rfcommDataBuffer[0];
|
return rfcommDataBuffer[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
int SPP::read(void) {
|
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;
|
return -1;
|
||||||
uint8_t output = rfcommDataBuffer[0];
|
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
|
rfcommDataBuffer[i - 1] = rfcommDataBuffer[i]; // Shift the buffer one left
|
||||||
rfcommAvailable--;
|
rfcommAvailable--;
|
||||||
bytesRead++;
|
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;
|
bytesRead = 0;
|
||||||
sendRfcommCredit(rfcommChannelConnection, rfcommDirection, 0, RFCOMM_UIH, 0x10, sizeof (rfcommDataBuffer)); // Send more credit
|
sendRfcommCredit(rfcommChannelConnection, rfcommDirection, 0, RFCOMM_UIH, 0x10, sizeof (rfcommDataBuffer)); // Send more credit
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
|
|
1
SPP.h
1
SPP.h
|
@ -98,6 +98,7 @@ public:
|
||||||
* @return Return the number of bytes ready to be read.
|
* @return Return the number of bytes ready to be read.
|
||||||
*/
|
*/
|
||||||
virtual int available(void);
|
virtual int available(void);
|
||||||
|
|
||||||
/** Send out all bytes in the buffer. */
|
/** Send out all bytes in the buffer. */
|
||||||
virtual void flush(void) {
|
virtual void flush(void) {
|
||||||
send();
|
send();
|
||||||
|
|
173
Usb.cpp
173
Usb.cpp
|
@ -44,13 +44,13 @@ void USB::setUsbTaskState(uint8_t state) {
|
||||||
EpInfo* USB::getEpInfoEntry(uint8_t addr, uint8_t ep) {
|
EpInfo* USB::getEpInfoEntry(uint8_t addr, uint8_t ep) {
|
||||||
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
|
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
|
||||||
|
|
||||||
if (!p || !p->epinfo)
|
if(!p || !p->epinfo)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
EpInfo *pep = p->epinfo;
|
EpInfo *pep = p->epinfo;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < p->epcount; i++) {
|
for(uint8_t i = 0; i < p->epcount; i++) {
|
||||||
if ((pep)->epAddr == ep)
|
if((pep)->epAddr == ep)
|
||||||
return pep;
|
return pep;
|
||||||
|
|
||||||
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 */
|
/* 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) {
|
uint8_t USB::setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr) {
|
||||||
if (!eprecord_ptr)
|
if(!eprecord_ptr)
|
||||||
return USB_ERROR_INVALID_ARGUMENT;
|
return USB_ERROR_INVALID_ARGUMENT;
|
||||||
|
|
||||||
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
|
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
p->address.devAddress = addr;
|
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) {
|
uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t &nak_limit) {
|
||||||
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
|
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
if (!p->epinfo)
|
if(!p->epinfo)
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
return USB_ERROR_EPINFO_IS_NULL;
|
||||||
|
|
||||||
*ppep = getEpInfoEntry(addr, ep);
|
*ppep = getEpInfoEntry(addr, ep);
|
||||||
|
|
||||||
if (!*ppep)
|
if(!*ppep)
|
||||||
return USB_ERROR_EP_NOT_FOUND_IN_TBL;
|
return USB_ERROR_EP_NOT_FOUND_IN_TBL;
|
||||||
|
|
||||||
nak_limit = (0x0001UL << (((*ppep)->bmNakPower > USB_NAK_MAX_POWER) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower));
|
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);
|
rcode = SetAddress(addr, ep, &pep, nak_limit);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
return rcode;
|
return rcode;
|
||||||
|
|
||||||
direction = ((bmReqType & 0x80) > 0);
|
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
|
rcode = dispatchPkt(tokSETUP, ep, nak_limit); //dispatch packet
|
||||||
|
|
||||||
if (rcode) //return HRSLT if not zero
|
if(rcode) //return HRSLT if not zero
|
||||||
return ( rcode);
|
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;
|
uint16_t left = total;
|
||||||
|
|
||||||
pep->bmRcvToggle = 1; //bmRCVTOG1;
|
pep->bmRcvToggle = 1; //bmRCVTOG1;
|
||||||
|
|
||||||
while (left) {
|
while(left) {
|
||||||
// Bytes read into buffer
|
// Bytes read into buffer
|
||||||
uint16_t read = nbytes;
|
uint16_t read = nbytes;
|
||||||
//uint16_t read = (left<nbytes) ? left : nbytes;
|
//uint16_t read = (left<nbytes) ? left : nbytes;
|
||||||
|
|
||||||
rcode = InTransfer(pep, nak_limit, &read, dataptr);
|
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!
|
// yes, we flip it wrong here so that next time it is actually correct!
|
||||||
pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
|
pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
return rcode;
|
return rcode;
|
||||||
|
|
||||||
// Invoke callback function if inTransfer completed successfully and callback function pointer is specified
|
// 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);
|
((USBReadParser*)p)->Parse(read, dataptr, total - left);
|
||||||
|
|
||||||
left -= read;
|
left -= read;
|
||||||
|
|
||||||
if (read < nbytes)
|
if(read < nbytes)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else //OUT transfer
|
} 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;
|
pep->bmSndToggle = 1; //bmSNDTOG1;
|
||||||
rcode = OutTransfer(pep, nak_limit, nbytes, dataptr);
|
rcode = OutTransfer(pep, nak_limit, nbytes, dataptr);
|
||||||
}
|
}
|
||||||
if (rcode) //return error
|
if(rcode) //return error
|
||||||
return ( rcode);
|
return ( rcode);
|
||||||
}
|
}
|
||||||
// Status stage
|
// 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);
|
uint8_t rcode = SetAddress(addr, ep, &pep, nak_limit);
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
USBTRACE3("(USB::InTransfer) SetAddress Failed ", rcode, 0x81);
|
USBTRACE3("(USB::InTransfer) SetAddress Failed ", rcode, 0x81);
|
||||||
USBTRACE3("(USB::InTransfer) addr requested ", addr, 0x81);
|
USBTRACE3("(USB::InTransfer) addr requested ", addr, 0x81);
|
||||||
USBTRACE3("(USB::InTransfer) ep requested ", ep, 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;
|
*nbytesptr = 0;
|
||||||
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
|
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.
|
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!
|
// yes, we flip it wrong here so that next time it is actually correct!
|
||||||
pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
|
pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
|
||||||
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
|
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
//printf(">>>>>>>> Problem! dispatchPkt %2.2x\r\n", rcode);
|
//printf(">>>>>>>> Problem! dispatchPkt %2.2x\r\n", rcode);
|
||||||
break; //should be 0, indicating ACK. Else return error code.
|
break; //should be 0, indicating ACK. Else return error code.
|
||||||
}
|
}
|
||||||
/* check for RCVDAVIRQ and generate error if not present */
|
/* 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 */
|
/* 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");
|
//printf(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n");
|
||||||
rcode = 0xf0; //receive error
|
rcode = 0xf0; //receive error
|
||||||
break;
|
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);
|
//printf("Got %i bytes \r\n", pktsize);
|
||||||
// This would be OK, but...
|
// This would be OK, but...
|
||||||
//assert(pktsize <= nbytes);
|
//assert(pktsize <= nbytes);
|
||||||
if (pktsize > nbytes) {
|
if(pktsize > nbytes) {
|
||||||
// This can happen. Use of assert on Arduino locks up the Arduino.
|
// This can happen. Use of assert on Arduino locks up the Arduino.
|
||||||
// So I will trim the value, and hope for the best.
|
// So I will trim the value, and hope for the best.
|
||||||
//printf(">>>>>>>> Problem! Wanted %i bytes but got %i.\r\n", nbytes, pktsize);
|
//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);
|
int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr);
|
||||||
|
|
||||||
if (mem_left < 0)
|
if(mem_left < 0)
|
||||||
mem_left = 0;
|
mem_left = 0;
|
||||||
|
|
||||||
data = bytesRd(rRCVFIFO, ((pktsize > mem_left) ? mem_left : pktsize), data);
|
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: */
|
/* The transfer is complete under two conditions: */
|
||||||
/* 1. The device sent a short packet (L.T. maxPacketSize) */
|
/* 1. The device sent a short packet (L.T. maxPacketSize) */
|
||||||
/* 2. 'nbytes' have been transferred. */
|
/* 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
|
// Save toggle value
|
||||||
pep->bmRcvToggle = ((regRd(rHRSL) & bmRCVTOGRD)) ? 1 : 0;
|
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);
|
uint8_t rcode = SetAddress(addr, ep, &pep, nak_limit);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
return rcode;
|
return rcode;
|
||||||
|
|
||||||
return OutTransfer(pep, nak_limit, nbytes, data);
|
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;
|
uint8_t maxpktsize = pep->maxPktSize;
|
||||||
|
|
||||||
if (maxpktsize < 1 || maxpktsize > 64)
|
if(maxpktsize < 1 || maxpktsize > 64)
|
||||||
return USB_ERROR_INVALID_MAX_PKT_SIZE;
|
return USB_ERROR_INVALID_MAX_PKT_SIZE;
|
||||||
|
|
||||||
unsigned long timeout = millis() + USB_XFER_TIMEOUT;
|
unsigned long timeout = millis() + USB_XFER_TIMEOUT;
|
||||||
|
|
||||||
regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
|
regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
|
||||||
|
|
||||||
while (bytes_left) {
|
while(bytes_left) {
|
||||||
retry_count = 0;
|
retry_count = 0;
|
||||||
nak_count = 0;
|
nak_count = 0;
|
||||||
bytes_tosend = (bytes_left >= maxpktsize) ? maxpktsize : bytes_left;
|
bytes_tosend = (bytes_left >= maxpktsize) ? maxpktsize : bytes_left;
|
||||||
bytesWr(rSNDFIFO, bytes_tosend, data_p); //filling output FIFO
|
bytesWr(rSNDFIFO, bytes_tosend, data_p); //filling output FIFO
|
||||||
regWr(rSNDBC, bytes_tosend); //set number of bytes
|
regWr(rSNDBC, bytes_tosend); //set number of bytes
|
||||||
regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
|
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
|
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
|
||||||
rcode = (regRd(rHRSL) & 0x0f);
|
rcode = (regRd(rHRSL) & 0x0f);
|
||||||
|
|
||||||
while (rcode && (timeout > millis())) {
|
while(rcode && (timeout > millis())) {
|
||||||
switch (rcode) {
|
switch(rcode) {
|
||||||
case hrNAK:
|
case hrNAK:
|
||||||
nak_count++;
|
nak_count++;
|
||||||
if (nak_limit && (nak_count == nak_limit))
|
if(nak_limit && (nak_count == nak_limit))
|
||||||
goto breakout;
|
goto breakout;
|
||||||
//return ( rcode);
|
//return ( rcode);
|
||||||
break;
|
break;
|
||||||
case hrTIMEOUT:
|
case hrTIMEOUT:
|
||||||
retry_count++;
|
retry_count++;
|
||||||
if (retry_count == USB_RETRY_LIMIT)
|
if(retry_count == USB_RETRY_LIMIT)
|
||||||
goto breakout;
|
goto breakout;
|
||||||
//return ( rcode);
|
//return ( rcode);
|
||||||
break;
|
break;
|
||||||
|
@ -355,7 +355,7 @@ uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8
|
||||||
regWr(rSNDFIFO, *data_p);
|
regWr(rSNDFIFO, *data_p);
|
||||||
regWr(rSNDBC, bytes_tosend);
|
regWr(rSNDBC, bytes_tosend);
|
||||||
regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
|
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
|
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
|
||||||
rcode = (regRd(rHRSL) & 0x0f);
|
rcode = (regRd(rHRSL) & 0x0f);
|
||||||
}//while( rcode && ....
|
}//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;
|
uint8_t retry_count = 0;
|
||||||
uint16_t nak_count = 0;
|
uint16_t nak_count = 0;
|
||||||
|
|
||||||
while (timeout > millis()) {
|
while(timeout > millis()) {
|
||||||
regWr(rHXFR, (token | ep)); //launch the transfer
|
regWr(rHXFR, (token | ep)); //launch the transfer
|
||||||
rcode = USB_ERROR_TRANSFER_TIMEOUT;
|
rcode = USB_ERROR_TRANSFER_TIMEOUT;
|
||||||
|
|
||||||
while (timeout > millis()) //wait for transfer completion
|
while(timeout > millis()) //wait for transfer completion
|
||||||
{
|
{
|
||||||
tmpdata = regRd(rHIRQ);
|
tmpdata = regRd(rHIRQ);
|
||||||
|
|
||||||
if (tmpdata & bmHXFRDNIRQ) {
|
if(tmpdata & bmHXFRDNIRQ) {
|
||||||
regWr(rHIRQ, bmHXFRDNIRQ); //clear the interrupt
|
regWr(rHIRQ, bmHXFRDNIRQ); //clear the interrupt
|
||||||
rcode = 0x00;
|
rcode = 0x00;
|
||||||
break;
|
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
|
rcode = (regRd(rHRSL) & 0x0f); //analyze transfer result
|
||||||
|
|
||||||
switch (rcode) {
|
switch(rcode) {
|
||||||
case hrNAK:
|
case hrNAK:
|
||||||
nak_count++;
|
nak_count++;
|
||||||
if (nak_limit && (nak_count == nak_limit))
|
if(nak_limit && (nak_count == nak_limit))
|
||||||
return (rcode);
|
return (rcode);
|
||||||
break;
|
break;
|
||||||
case hrTIMEOUT:
|
case hrTIMEOUT:
|
||||||
retry_count++;
|
retry_count++;
|
||||||
if (retry_count == USB_RETRY_LIMIT)
|
if(retry_count == USB_RETRY_LIMIT)
|
||||||
return (rcode);
|
return (rcode);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -434,13 +434,13 @@ void USB::Task(void) //USB state machine
|
||||||
tmpdata = getVbusState();
|
tmpdata = getVbusState();
|
||||||
|
|
||||||
/* modify USB task state if Vbus changed */
|
/* modify USB task state if Vbus changed */
|
||||||
switch (tmpdata) {
|
switch(tmpdata) {
|
||||||
case SE1: //illegal state
|
case SE1: //illegal state
|
||||||
usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
|
usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
|
||||||
lowspeed = false;
|
lowspeed = false;
|
||||||
break;
|
break;
|
||||||
case SE0: //disconnected
|
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;
|
usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
|
||||||
lowspeed = false;
|
lowspeed = false;
|
||||||
break;
|
break;
|
||||||
|
@ -449,23 +449,23 @@ void USB::Task(void) //USB state machine
|
||||||
lowspeed = true;
|
lowspeed = true;
|
||||||
//intentional fallthrough
|
//intentional fallthrough
|
||||||
case FSHOST: //attached
|
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;
|
delay = millis() + USB_SETTLE_DELAY;
|
||||||
usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
|
usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}// switch( tmpdata
|
}// switch( tmpdata
|
||||||
|
|
||||||
for (uint8_t i = 0; i < USB_NUMDEVICES; i++)
|
for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
|
||||||
if (devConfig[i])
|
if(devConfig[i])
|
||||||
rcode = devConfig[i]->Poll();
|
rcode = devConfig[i]->Poll();
|
||||||
|
|
||||||
switch (usb_task_state) {
|
switch(usb_task_state) {
|
||||||
case USB_DETACHED_SUBSTATE_INITIALIZE:
|
case USB_DETACHED_SUBSTATE_INITIALIZE:
|
||||||
init();
|
init();
|
||||||
|
|
||||||
for (uint8_t i = 0; i < USB_NUMDEVICES; i++)
|
for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
|
||||||
if (devConfig[i])
|
if(devConfig[i])
|
||||||
rcode = devConfig[i]->Release();
|
rcode = devConfig[i]->Release();
|
||||||
|
|
||||||
usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
|
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
|
case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
|
||||||
break;
|
break;
|
||||||
case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device
|
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;
|
usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
|
||||||
else break; // don't fall through
|
else break; // don't fall through
|
||||||
case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
|
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;
|
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
|
||||||
break;
|
break;
|
||||||
case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
|
case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
|
||||||
if ((regRd(rHCTL) & bmBUSRST) == 0) {
|
if((regRd(rHCTL) & bmBUSRST) == 0) {
|
||||||
tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation
|
tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation
|
||||||
regWr(rMODE, tmpdata);
|
regWr(rMODE, tmpdata);
|
||||||
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
|
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
|
||||||
|
@ -491,7 +491,7 @@ void USB::Task(void) //USB state machine
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
|
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
|
//when first SOF received _and_ 20ms has passed we can continue
|
||||||
/*
|
/*
|
||||||
if (delay < millis()) //20ms passed
|
if (delay < millis()) //20ms passed
|
||||||
|
@ -502,7 +502,7 @@ void USB::Task(void) //USB state machine
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case USB_ATTACHED_SUBSTATE_WAIT_RESET:
|
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
|
else break; // don't fall through
|
||||||
case USB_STATE_CONFIGURING:
|
case USB_STATE_CONFIGURING:
|
||||||
|
|
||||||
|
@ -511,8 +511,8 @@ void USB::Task(void) //USB state machine
|
||||||
|
|
||||||
rcode = Configuring(0, 0, lowspeed);
|
rcode = Configuring(0, 0, lowspeed);
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) {
|
if(rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) {
|
||||||
usb_error = rcode;
|
usb_error = rcode;
|
||||||
usb_task_state = USB_STATE_ERROR;
|
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
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
p0 = addrPool.GetUsbDevicePtr(0);
|
p0 = addrPool.GetUsbDevicePtr(0);
|
||||||
|
|
||||||
if (!p0)
|
if(!p0)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
if (!p0->epinfo)
|
if(!p0->epinfo)
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
return USB_ERROR_EPINFO_IS_NULL;
|
||||||
|
|
||||||
p0->lowspeed = (lowspeed) ? true : false;
|
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
|
// Allocate new address according to device class
|
||||||
uint8_t bAddress = addrPool.AllocAddress(parent, false, port);
|
uint8_t bAddress = addrPool.AllocAddress(parent, false, port);
|
||||||
|
|
||||||
if (!bAddress)
|
if(!bAddress)
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
p->lowspeed = lowspeed;
|
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
|
// Assign new address to the device
|
||||||
rcode = setAddr(0, 0, bAddress);
|
rcode = setAddr(0, 0, bAddress);
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
return rcode;
|
return rcode;
|
||||||
|
@ -573,8 +573,8 @@ uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lo
|
||||||
|
|
||||||
again:
|
again:
|
||||||
uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed);
|
uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed);
|
||||||
if (rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) {
|
if(rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) {
|
||||||
if (parent == 0) {
|
if(parent == 0) {
|
||||||
// Send a bus reset on the root interface.
|
// Send a bus reset on the root interface.
|
||||||
regWr(rHCTL, bmBUSRST); //issue bus reset
|
regWr(rHCTL, bmBUSRST); //issue bus reset
|
||||||
delay(102); // delay 102ms, compensate for clock inaccuracy.
|
delay(102); // delay 102ms, compensate for clock inaccuracy.
|
||||||
|
@ -582,22 +582,22 @@ again:
|
||||||
// reset parent port
|
// reset parent port
|
||||||
devConfig[parent]->ResetHubPort(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);
|
delay(100);
|
||||||
retries++;
|
retries++;
|
||||||
goto again;
|
goto again;
|
||||||
} else if (rcode)
|
} else if(rcode)
|
||||||
return rcode;
|
return rcode;
|
||||||
|
|
||||||
rcode = devConfig[driver]->Init(parent, port, lowspeed);
|
rcode = devConfig[driver]->Init(parent, port, lowspeed);
|
||||||
if (rcode == hrJERR && 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);
|
delay(100);
|
||||||
retries++;
|
retries++;
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
// Issue a bus reset, because the device may be in a limbo state
|
// 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.
|
// Send a bus reset on the root interface.
|
||||||
regWr(rHCTL, bmBUSRST); //issue bus reset
|
regWr(rHCTL, bmBUSRST); //issue bus reset
|
||||||
delay(102); // delay 102ms, compensate for clock inaccuracy.
|
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();
|
AddressPool &addrPool = GetAddressPool();
|
||||||
// Get pointer to pseudo device with address 0 assigned
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
p = addrPool.GetUsbDevicePtr(0);
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
if (!p) {
|
if(!p) {
|
||||||
//printf("Configuring error: USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL\r\n");
|
//printf("Configuring error: USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL\r\n");
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
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
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
//printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n");
|
//printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n");
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
@ -705,30 +705,30 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
uint8_t klass = udd->bDeviceClass;
|
uint8_t klass = udd->bDeviceClass;
|
||||||
|
|
||||||
// Attempt to configure if VID/PID or device class matches with a driver
|
// Attempt to configure if VID/PID or device class matches with a driver
|
||||||
for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
|
for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
|
||||||
if (!devConfig[devConfigIndex]) continue; // no driver
|
if(!devConfig[devConfigIndex]) continue; // no driver
|
||||||
if (devConfig[devConfigIndex]->GetAddress()) continue; // consumed
|
if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed
|
||||||
if (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass)) {
|
if(devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass)) {
|
||||||
rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (devConfigIndex < USB_NUMDEVICES) {
|
if(devConfigIndex < USB_NUMDEVICES) {
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// blindly attempt to configure
|
// blindly attempt to configure
|
||||||
for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
|
for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
|
||||||
if (!devConfig[devConfigIndex]) continue;
|
if(!devConfig[devConfigIndex]) continue;
|
||||||
if (devConfig[devConfigIndex]->GetAddress()) continue; // consumed
|
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
|
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);
|
rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
|
||||||
|
|
||||||
//printf("ERROR ENUMERATING %2.2x\r\n", rcode);
|
//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 case of an error dev_index should be reset to 0
|
||||||
// in order to start from the very beginning the
|
// in order to start from the very beginning the
|
||||||
// next time the program gets here
|
// 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) {
|
uint8_t USB::ReleaseDevice(uint8_t addr) {
|
||||||
if (!addr)
|
if(!addr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < USB_NUMDEVICES; i++) {
|
for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
|
||||||
if (!devConfig[i]) continue;
|
if(!devConfig[i]) continue;
|
||||||
if (devConfig[i]->GetAddress() == addr)
|
if(devConfig[i]->GetAddress() == addr)
|
||||||
return devConfig[i]->Release();
|
return devConfig[i]->Release();
|
||||||
}
|
}
|
||||||
return 0;
|
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);
|
uint8_t ret = getConfDescr(addr, ep, 9, conf, buf);
|
||||||
|
|
||||||
if (ret)
|
if(ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
uint16_t total = ucd->wTotalLength;
|
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)
|
#endif // defined(USB_METHODS_INLINE)
|
||||||
|
|
||||||
|
|
55
UsbCore.h
55
UsbCore.h
|
@ -104,14 +104,38 @@ typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega
|
||||||
|
|
||||||
class USBDeviceConfig {
|
class USBDeviceConfig {
|
||||||
public:
|
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 Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
virtual uint8_t Release() { return 0; }
|
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 uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) { return false; }
|
return 0;
|
||||||
virtual boolean DEVCLASSOK(uint8_t klass) { return false; }
|
}
|
||||||
|
|
||||||
|
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 */
|
/* USB Setup Packet Structure */
|
||||||
|
@ -138,7 +162,7 @@ typedef struct {
|
||||||
} wVal_u;
|
} wVal_u;
|
||||||
uint16_t wIndex; // 4 Depends on bRequest
|
uint16_t wIndex; // 4 Depends on bRequest
|
||||||
uint16_t wLength; // 6 Depends on bRequest
|
uint16_t wLength; // 6 Depends on bRequest
|
||||||
}__attribute__((packed)) SETUP_PKT, *PSETUP_PKT;
|
} __attribute__((packed)) SETUP_PKT, *PSETUP_PKT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,7 +190,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
AddressPool& GetAddressPool() {
|
AddressPool& GetAddressPool() {
|
||||||
return(AddressPool&) addrPool;
|
return (AddressPool&)addrPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev) {
|
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev) {
|
||||||
|
@ -225,30 +249,29 @@ private:
|
||||||
//get device descriptor
|
//get device descriptor
|
||||||
|
|
||||||
inline uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) {
|
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
|
//get configuration descriptor
|
||||||
|
|
||||||
inline uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
|
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
|
//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) {
|
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
|
//set address
|
||||||
|
|
||||||
inline uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) {
|
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
|
//set configuration
|
||||||
|
|
||||||
inline uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) {
|
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 // defined(USB_METHODS_INLINE)
|
||||||
|
|
||||||
#endif /* USBCORE_H */
|
#endif /* USBCORE_H */
|
||||||
|
|
||||||
|
|
275
Wii.cpp
275
Wii.cpp
|
@ -84,7 +84,7 @@ const uint32_t PROCONTROLLERBUTTONS[] PROGMEM = {
|
||||||
WII::WII(BTD *p, bool pair) :
|
WII::WII(BTD *p, bool pair) :
|
||||||
pBtd(p) // pointer to USB class instance - mandatory
|
pBtd(p) // pointer to USB class instance - mandatory
|
||||||
{
|
{
|
||||||
if (pBtd)
|
if(pBtd)
|
||||||
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
pBtd->registerServiceClass(this); // Register it as a Bluetooth service
|
||||||
|
|
||||||
pBtd->pairWithWii = pair;
|
pBtd->pairWithWii = pair;
|
||||||
|
@ -115,8 +115,8 @@ void WII::Reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WII::disconnect() { // Use this void to disconnect any of the controllers
|
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(!motionPlusInside) { // The old Wiimote needs a delay after the first command or it will automatically reconnect
|
||||||
if (motionPlusConnected) {
|
if(motionPlusConnected) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDeactivating Motion Plus"), 0x80);
|
Notify(PSTR("\r\nDeactivating Motion Plus"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -132,9 +132,9 @@ void WII::disconnect() { // Use this void to disconnect any of the controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
void WII::ACLData(uint8_t* l2capinbuf) {
|
void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
if (!pBtd->l2capConnectionClaimed && pBtd->incomingWii && !wiimoteConnected && !activeConnection) {
|
if(!pBtd->l2capConnectionClaimed && pBtd->incomingWii && !wiimoteConnected && !activeConnection) {
|
||||||
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||||
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
|
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
|
||||||
motionPlusInside = pBtd->motionPlusInside;
|
motionPlusInside = pBtd->motionPlusInside;
|
||||||
pBtd->incomingWii = false;
|
pBtd->incomingWii = false;
|
||||||
pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service
|
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[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[6] | (l2capinbuf[7] << 8)) == 0x0001U) { //l2cap_control - Channel ID for ACL-U
|
||||||
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
if(l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
||||||
|
@ -161,15 +161,15 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
||||||
#endif
|
#endif
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) {
|
||||||
if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success
|
if(((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success
|
||||||
if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) {
|
if(l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) {
|
||||||
//Notify(PSTR("\r\nHID Control Connection Complete"), 0x80);
|
//Notify(PSTR("\r\nHID Control Connection Complete"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
control_scid[0] = l2capinbuf[12];
|
control_scid[0] = l2capinbuf[12];
|
||||||
control_scid[1] = l2capinbuf[13];
|
control_scid[1] = l2capinbuf[13];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONTROL_CONNECTED);
|
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);
|
//Notify(PSTR("\r\nHID Interrupt Connection Complete"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
interrupt_scid[0] = l2capinbuf[12];
|
interrupt_scid[0] = l2capinbuf[12];
|
||||||
|
@ -177,7 +177,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
l2cap_set_flag(L2CAP_FLAG_INTERRUPT_CONNECTED);
|
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
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
|
Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
||||||
|
@ -190,46 +190,46 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
Notify(PSTR(" Identifier: "), 0x80);
|
Notify(PSTR(" Identifier: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
|
||||||
#endif
|
#endif
|
||||||
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
|
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
control_scid[0] = l2capinbuf[14];
|
control_scid[0] = l2capinbuf[14];
|
||||||
control_scid[1] = l2capinbuf[15];
|
control_scid[1] = l2capinbuf[15];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST);
|
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];
|
identifier = l2capinbuf[9];
|
||||||
interrupt_scid[0] = l2capinbuf[14];
|
interrupt_scid[0] = l2capinbuf[14];
|
||||||
interrupt_scid[1] = l2capinbuf[15];
|
interrupt_scid[1] = l2capinbuf[15];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST);
|
l2cap_set_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST);
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
|
||||||
if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
|
if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
|
||||||
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
||||||
//Notify(PSTR("\r\nHID Control Configuration Complete"), 0x80);
|
//Notify(PSTR("\r\nHID Control Configuration Complete"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS);
|
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);
|
//Notify(PSTR("\r\nHID Interrupt Configuration Complete"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS);
|
l2cap_set_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
|
||||||
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
||||||
//Notify(PSTR("\r\nHID Control Configuration Request"), 0x80);
|
//Notify(PSTR("\r\nHID Control Configuration Request"), 0x80);
|
||||||
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], control_scid);
|
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);
|
//Notify(PSTR("\r\nHID Interrupt Configuration Request"), 0x80);
|
||||||
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], interrupt_scid);
|
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], interrupt_scid);
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
|
||||||
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnect Request: Control Channel"), 0x80);
|
Notify(PSTR("\r\nDisconnect Request: Control Channel"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid);
|
pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid);
|
||||||
Reset();
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"), 0x80);
|
Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -237,12 +237,12 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid);
|
pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid);
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
} else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
|
} else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
|
||||||
if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
|
if(l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
|
||||||
//Notify(PSTR("\r\nDisconnect Response: Control Channel"), 0x80);
|
//Notify(PSTR("\r\nDisconnect Response: Control Channel"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE);
|
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);
|
//Notify(PSTR("\r\nDisconnect Response: Interrupt Channel"), 0x80);
|
||||||
identifier = l2capinbuf[9];
|
identifier = l2capinbuf[9];
|
||||||
l2cap_set_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE);
|
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);
|
D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
//Notify(PSTR("\r\nL2CAP Interrupt"), 0x80);
|
||||||
if (l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
|
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] >= 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[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));
|
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));
|
ButtonState = (uint32_t)(((~l2capinbuf[23]) & 0xFE) | ((uint16_t)(~l2capinbuf[24]) << 8) | ((uint32_t)((~l2capinbuf[25]) & 0x03) << 16));
|
||||||
else if (motionPlusConnected) {
|
else if(motionPlusConnected) {
|
||||||
if (l2capinbuf[20] & 0x02) // Only update the wiimote buttons, since the extension bytes are from the Motion Plus
|
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)));
|
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));
|
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(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));
|
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(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));
|
ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8));
|
||||||
#ifdef PRINTREPORT
|
#ifdef PRINTREPORT
|
||||||
Notify(PSTR("ButtonState: "), 0x80);
|
Notify(PSTR("ButtonState: "), 0x80);
|
||||||
D_PrintHex<uint32_t > (ButtonState, 0x80);
|
D_PrintHex<uint32_t > (ButtonState, 0x80);
|
||||||
Notify(PSTR("\r\n"), 0x80);
|
Notify(PSTR("\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
if (ButtonState != OldButtonState) {
|
if(ButtonState != OldButtonState) {
|
||||||
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
|
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
|
||||||
OldButtonState = ButtonState;
|
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;
|
accXwiimote = ((l2capinbuf[12] << 2) | (l2capinbuf[10] & 0x60 >> 5)) - 500;
|
||||||
accYwiimote = ((l2capinbuf[13] << 2) | (l2capinbuf[11] & 0x20 >> 4)) - 500;
|
accYwiimote = ((l2capinbuf[13] << 2) | (l2capinbuf[11] & 0x20 >> 4)) - 500;
|
||||||
accZwiimote = ((l2capinbuf[14] << 2) | (l2capinbuf[11] & 0x40 >> 5)) - 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
|
case 0x20: // Status Information - (a1) 20 BB BB LF 00 00 VV
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("\r\nStatus report was received"), 0x80);
|
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)
|
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
|
batteryLevel = l2capinbuf[15]; // Update battery level
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
if (l2capinbuf[12] & 0x01)
|
if(l2capinbuf[12] & 0x01)
|
||||||
Notify(PSTR("\r\nWARNING: Battery is nearly empty"), 0x80);
|
Notify(PSTR("\r\nWARNING: Battery is nearly empty"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
if (checkExtension) { // If this is false it means that the user must have called getBatteryLevel()
|
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(l2capinbuf[12] & 0x02) { // Check if a extension is connected
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
if (!unknownExtensionConnected)
|
if(!unknownExtensionConnected)
|
||||||
Notify(PSTR("\r\nExtension connected"), 0x80);
|
Notify(PSTR("\r\nExtension connected"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
unknownExtensionConnected = true;
|
unknownExtensionConnected = true;
|
||||||
#ifdef WIICAMERA
|
#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
|
#endif
|
||||||
setReportMode(false, 0x35); // Also read the extension
|
setReportMode(false, 0x35); // Also read the extension
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nExtension disconnected"), 0x80);
|
Notify(PSTR("\r\nExtension disconnected"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
if (motionPlusConnected) {
|
if(motionPlusConnected) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR(" - from Motion Plus"), 0x80);
|
Notify(PSTR(" - from Motion Plus"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
wii_clear_flag(WII_FLAG_NUNCHUCK_CONNECTED);
|
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;
|
nunchuckConnected = false;
|
||||||
//else if(classicControllerConnected)
|
//else if(classicControllerConnected)
|
||||||
} else if (nunchuckConnected) {
|
} else if(nunchuckConnected) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR(" - Nunchuck"), 0x80);
|
Notify(PSTR(" - Nunchuck"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -338,28 +338,28 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
checkExtension = true; // Check for extensions by default
|
checkExtension = true; // Check for extensions by default
|
||||||
break;
|
break;
|
||||||
case 0x21: // Read Memory Data
|
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
|
// 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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nNunchuck connected"), 0x80);
|
Notify(PSTR("\r\nNunchuck connected"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
wii_set_flag(WII_FLAG_NUNCHUCK_CONNECTED);
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nMotion Plus connected"), 0x80);
|
Notify(PSTR("\r\nMotion Plus connected"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
wii_set_flag(WII_FLAG_MOTION_PLUS_CONNECTED);
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nMotion Plus activated in normal mode"), 0x80);
|
Notify(PSTR("\r\nMotion Plus activated in normal mode"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
motionPlusConnected = true;
|
motionPlusConnected = true;
|
||||||
#ifdef WIICAMERA
|
#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
|
#endif
|
||||||
setReportMode(false, 0x35); // Also read the extension
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nMotion Plus activated in Nunchuck pass-through mode"), 0x80);
|
Notify(PSTR("\r\nMotion Plus activated in Nunchuck pass-through mode"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -367,16 +367,16 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
motionPlusConnected = true;
|
motionPlusConnected = true;
|
||||||
nunchuckConnected = true;
|
nunchuckConnected = true;
|
||||||
#ifdef WIICAMERA
|
#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
|
#endif
|
||||||
setReportMode(false, 0x35); // Also read the extension
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nInactive Wii Motion Plus"), 0x80);
|
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);
|
Notify(PSTR("\r\nPlease unplug the Motion Plus, disconnect the Wiimote and then replug the Motion Plus Extension"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
stateCounter = 300; // Skip the rest in "WII_CHECK_MOTION_PLUS_STATE"
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nWii U Pro Controller connected"), 0x80);
|
Notify(PSTR("\r\nWii U Pro Controller connected"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -388,7 +388,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
||||||
Notify(PSTR("\r\nData: "), 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);
|
D_PrintHex<uint8_t > (l2capinbuf[15 + i], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -405,7 +405,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
break;
|
break;
|
||||||
case 0x22: // Acknowledge output report, return function result
|
case 0x22: // Acknowledge output report, return function result
|
||||||
#ifdef DEBUG_USB_HOST
|
#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);
|
Notify(PSTR("\r\nCommand failed: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
|
D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
|
||||||
}
|
}
|
||||||
|
@ -461,9 +461,9 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
break;
|
break;
|
||||||
case 0x35: // Core Buttons and Accelerometer with 16 Extension Bytes
|
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
|
// (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(motionPlusConnected) {
|
||||||
if (l2capinbuf[20] & 0x02) { // Check if it's a report from the Motion controller or the extension
|
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(motionValuesReset) { // We will only use the values when the gyro value has been set
|
||||||
gyroYawRaw = ((l2capinbuf[15] | ((l2capinbuf[18] & 0xFC) << 6)) - gyroYawZero);
|
gyroYawRaw = ((l2capinbuf[15] | ((l2capinbuf[18] & 0xFC) << 6)) - gyroYawZero);
|
||||||
gyroRollRaw = ((l2capinbuf[16] | ((l2capinbuf[19] & 0xFC) << 6)) - gyroRollZero);
|
gyroRollRaw = ((l2capinbuf[16] | ((l2capinbuf[19] & 0xFC) << 6)) - gyroRollZero);
|
||||||
gyroPitchRaw = ((l2capinbuf[17] | ((l2capinbuf[20] & 0xFC) << 6)) - gyroPitchZero);
|
gyroPitchRaw = ((l2capinbuf[17] | ((l2capinbuf[20] & 0xFC) << 6)) - gyroPitchZero);
|
||||||
|
@ -473,11 +473,11 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
pitchGyroSpeed = (double)gyroPitchRaw / ((double)gyroPitchZero / pitchGyroScale);
|
pitchGyroSpeed = (double)gyroPitchRaw / ((double)gyroPitchZero / pitchGyroScale);
|
||||||
|
|
||||||
/* The onboard gyro has two ranges for slow and fast mode */
|
/* The onboard gyro has two ranges for slow and fast mode */
|
||||||
if (!(l2capinbuf[18] & 0x02)) // Check if fast mode is used
|
if(!(l2capinbuf[18] & 0x02)) // Check if fast mode is used
|
||||||
yawGyroSpeed *= 4.545;
|
yawGyroSpeed *= 4.545;
|
||||||
if (!(l2capinbuf[18] & 0x01)) // Check if fast mode is used
|
if(!(l2capinbuf[18] & 0x01)) // Check if fast mode is used
|
||||||
pitchGyroSpeed *= 4.545;
|
pitchGyroSpeed *= 4.545;
|
||||||
if (!(l2capinbuf[19] & 0x02)) // Check if fast mode is used
|
if(!(l2capinbuf[19] & 0x02)) // Check if fast mode is used
|
||||||
rollGyroSpeed *= 4.545;
|
rollGyroSpeed *= 4.545;
|
||||||
|
|
||||||
compPitch = (0.93 * (compPitch + (pitchGyroSpeed * (double)(micros() - timer) / 1000000)))+(0.07 * getWiimotePitch()); // Use a complimentary filter to calculate the angle
|
compPitch = (0.93 * (compPitch + (pitchGyroSpeed * (double)(micros() - timer) / 1000000)))+(0.07 * getWiimotePitch()); // Use a complimentary filter to calculate the angle
|
||||||
|
@ -503,7 +503,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
Notify(wiimotePitch, 0x80);
|
Notify(wiimotePitch, 0x80);
|
||||||
*/
|
*/
|
||||||
} else {
|
} 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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nThe gyro values has been reset"), 0x80);
|
Notify(PSTR("\r\nThe gyro values has been reset"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -524,7 +524,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (nunchuckConnected) {
|
if(nunchuckConnected) {
|
||||||
hatValues[HatX] = l2capinbuf[15];
|
hatValues[HatX] = l2capinbuf[15];
|
||||||
hatValues[HatY] = l2capinbuf[16];
|
hatValues[HatY] = l2capinbuf[16];
|
||||||
accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x10 >> 3)) - 416;
|
accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x10 >> 3)) - 416;
|
||||||
|
@ -533,8 +533,8 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
}
|
}
|
||||||
//else if(classicControllerConnected) { }
|
//else if(classicControllerConnected) { }
|
||||||
}
|
}
|
||||||
if (l2capinbuf[19] & 0x01) {
|
if(l2capinbuf[19] & 0x01) {
|
||||||
if (!extensionConnected) {
|
if(!extensionConnected) {
|
||||||
extensionConnected = true;
|
extensionConnected = true;
|
||||||
unknownExtensionConnected = true;
|
unknownExtensionConnected = true;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
@ -542,7 +542,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (extensionConnected && !unknownExtensionConnected) {
|
if(extensionConnected && !unknownExtensionConnected) {
|
||||||
extensionConnected = false;
|
extensionConnected = false;
|
||||||
unknownExtensionConnected = true;
|
unknownExtensionConnected = true;
|
||||||
#ifdef DEBUG_USB_HOST
|
#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[HatX] = l2capinbuf[15];
|
||||||
hatValues[HatY] = l2capinbuf[16];
|
hatValues[HatY] = l2capinbuf[16];
|
||||||
accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x0C >> 2)) - 416;
|
accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x0C >> 2)) - 416;
|
||||||
accYnunchuck = ((l2capinbuf[18] << 2) | (l2capinbuf[20] & 0x30 >> 4)) - 416;
|
accYnunchuck = ((l2capinbuf[18] << 2) | (l2capinbuf[20] & 0x30 >> 4)) - 416;
|
||||||
accZnunchuck = ((l2capinbuf[19] << 2) | (l2capinbuf[20] & 0xC0 >> 6)) - 416;
|
accZnunchuck = ((l2capinbuf[19] << 2) | (l2capinbuf[20] & 0xC0 >> 6)) - 416;
|
||||||
} else if (wiiUProControllerConnected) {
|
} else if(wiiUProControllerConnected) {
|
||||||
hatValues[LeftHatX] = (l2capinbuf[15] | l2capinbuf[16] << 8);
|
hatValues[LeftHatX] = (l2capinbuf[15] | l2capinbuf[16] << 8);
|
||||||
hatValues[RightHatX] = (l2capinbuf[17] | l2capinbuf[18] << 8);
|
hatValues[RightHatX] = (l2capinbuf[17] | l2capinbuf[18] << 8);
|
||||||
hatValues[LeftHatY] = (l2capinbuf[19] | l2capinbuf[20] << 8);
|
hatValues[LeftHatY] = (l2capinbuf[19] | l2capinbuf[20] << 8);
|
||||||
|
@ -579,10 +579,10 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WII::L2CAP_task() {
|
void WII::L2CAP_task() {
|
||||||
switch (l2cap_state) {
|
switch(l2cap_state) {
|
||||||
/* These states are used if the Wiimote is the host */
|
/* These states are used if the Wiimote is the host */
|
||||||
case L2CAP_CONTROL_SUCCESS:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
|
Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -591,7 +591,7 @@ void WII::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_INTERRUPT_SETUP:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
|
Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -608,7 +608,7 @@ void WII::L2CAP_task() {
|
||||||
|
|
||||||
/* These states are used if the Arduino is the host */
|
/* These states are used if the Arduino is the host */
|
||||||
case L2CAP_CONTROL_CONNECT_REQUEST:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nSend HID Control Config Request"), 0x80);
|
Notify(PSTR("\r\nSend HID Control Config Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -619,7 +619,7 @@ void WII::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONTROL_CONFIG_REQUEST:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nSend HID Interrupt Connection Request"), 0x80);
|
Notify(PSTR("\r\nSend HID Interrupt Connection Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -630,7 +630,7 @@ void WII::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_INTERRUPT_CONNECT_REQUEST:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nSend HID Interrupt Config Request"), 0x80);
|
Notify(PSTR("\r\nSend HID Interrupt Config Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -641,7 +641,7 @@ void WII::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_INTERRUPT_CONFIG_REQUEST:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Channels Established"), 0x80);
|
Notify(PSTR("\r\nHID Channels Established"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -655,7 +655,7 @@ void WII::L2CAP_task() {
|
||||||
/* The next states are in run() */
|
/* The next states are in run() */
|
||||||
|
|
||||||
case L2CAP_INTERRUPT_DISCONNECT:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80);
|
Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -666,7 +666,7 @@ void WII::L2CAP_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONTROL_DISCONNECT:
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nDisconnected Control Channel"), 0x80);
|
Notify(PSTR("\r\nDisconnected Control Channel"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -680,12 +680,12 @@ void WII::L2CAP_task() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WII::Run() {
|
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
|
L2CAP_task(); // Call the rest of the disconnection routine after we have waited long enough
|
||||||
|
|
||||||
switch (l2cap_state) {
|
switch(l2cap_state) {
|
||||||
case L2CAP_WAIT:
|
case L2CAP_WAIT:
|
||||||
if (pBtd->connectToWii && !pBtd->l2capConnectionClaimed && !wiimoteConnected && !activeConnection) {
|
if(pBtd->connectToWii && !pBtd->l2capConnectionClaimed && !wiimoteConnected && !activeConnection) {
|
||||||
pBtd->l2capConnectionClaimed = true;
|
pBtd->l2capConnectionClaimed = true;
|
||||||
activeConnection = true;
|
activeConnection = true;
|
||||||
motionPlusInside = pBtd->motionPlusInside;
|
motionPlusInside = pBtd->motionPlusInside;
|
||||||
|
@ -697,7 +697,7 @@ void WII::Run() {
|
||||||
identifier = 0;
|
identifier = 0;
|
||||||
pBtd->l2cap_connection_request(hci_handle, identifier, control_dcid, HID_CTRL_PSM);
|
pBtd->l2cap_connection_request(hci_handle, identifier, control_dcid, HID_CTRL_PSM);
|
||||||
l2cap_state = L2CAP_CONTROL_CONNECT_REQUEST;
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80);
|
Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -713,25 +713,25 @@ void WII::Run() {
|
||||||
|
|
||||||
case WII_CHECK_MOTION_PLUS_STATE:
|
case WII_CHECK_MOTION_PLUS_STATE:
|
||||||
#ifdef DEBUG_USB_HOST
|
#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);
|
Notify(PSTR("\r\nChecking if a Motion Plus is connected"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
stateCounter++;
|
stateCounter++;
|
||||||
if (stateCounter % 200 == 0)
|
if(stateCounter % 200 == 0)
|
||||||
checkMotionPresent(); // Check if there is a motion plus connected
|
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;
|
stateCounter = 0;
|
||||||
l2cap_state = WII_INIT_MOTION_PLUS_STATE;
|
l2cap_state = WII_INIT_MOTION_PLUS_STATE;
|
||||||
timer = micros();
|
timer = micros();
|
||||||
|
|
||||||
if (unknownExtensionConnected) {
|
if(unknownExtensionConnected) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nA extension is also connected"), 0x80);
|
Notify(PSTR("\r\nA extension is also connected"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
activateNunchuck = true; // For we will just set this to true as this the only extension supported so far
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nNo Motion Plus was detected"), 0x80);
|
Notify(PSTR("\r\nNo Motion Plus was detected"), 0x80);
|
||||||
#endif
|
#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
|
case WII_CHECK_EXTENSION_STATE: // This is used to check if there is anything plugged in to the extension port
|
||||||
#ifdef DEBUG_USB_HOST
|
#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);
|
Notify(PSTR("\r\nChecking if there is any extension connected"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
stateCounter++; // We use this counter as there has to be a short delay between the commands
|
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
|
statusRequest(); // See if a new device has connected
|
||||||
if (stateCounter == 100) {
|
if(stateCounter == 100) {
|
||||||
if (unknownExtensionConnected) // Check if there is a extension is connected to the port
|
if(unknownExtensionConnected) // Check if there is a extension is connected to the port
|
||||||
initExtension1();
|
initExtension1();
|
||||||
else
|
else
|
||||||
stateCounter = 399;
|
stateCounter = 399;
|
||||||
} else if (stateCounter == 200)
|
} else if(stateCounter == 200)
|
||||||
initExtension2();
|
initExtension2();
|
||||||
else if (stateCounter == 300) {
|
else if(stateCounter == 300) {
|
||||||
readExtensionType();
|
readExtensionType();
|
||||||
unknownExtensionConnected = false;
|
unknownExtensionConnected = false;
|
||||||
} else if (stateCounter == 400) {
|
} else if(stateCounter == 400) {
|
||||||
stateCounter = 0;
|
stateCounter = 0;
|
||||||
l2cap_state = TURN_ON_LED;
|
l2cap_state = TURN_ON_LED;
|
||||||
}
|
}
|
||||||
|
@ -766,13 +766,13 @@ void WII::Run() {
|
||||||
|
|
||||||
case WII_INIT_MOTION_PLUS_STATE:
|
case WII_INIT_MOTION_PLUS_STATE:
|
||||||
stateCounter++;
|
stateCounter++;
|
||||||
if (stateCounter == 1)
|
if(stateCounter == 1)
|
||||||
initMotionPlus();
|
initMotionPlus();
|
||||||
else if (stateCounter == 100)
|
else if(stateCounter == 100)
|
||||||
activateMotionPlus();
|
activateMotionPlus();
|
||||||
else if (stateCounter == 200)
|
else if(stateCounter == 200)
|
||||||
readExtensionType(); // Check if it has been activated
|
readExtensionType(); // Check if it has been activated
|
||||||
else if (stateCounter == 300) {
|
else if(stateCounter == 300) {
|
||||||
stateCounter = 0;
|
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
|
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;
|
l2cap_state = TURN_ON_LED;
|
||||||
|
@ -780,7 +780,7 @@ void WII::Run() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TURN_ON_LED:
|
case TURN_ON_LED:
|
||||||
if (wii_check_flag(WII_FLAG_NUNCHUCK_CONNECTED))
|
if(wii_check_flag(WII_FLAG_NUNCHUCK_CONNECTED))
|
||||||
nunchuckConnected = true;
|
nunchuckConnected = true;
|
||||||
wiimoteConnected = true;
|
wiimoteConnected = true;
|
||||||
onInit();
|
onInit();
|
||||||
|
@ -788,46 +788,46 @@ void WII::Run() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_DONE:
|
case L2CAP_DONE:
|
||||||
if (unknownExtensionConnected) {
|
if(unknownExtensionConnected) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
if (stateCounter == 0) // Only print once
|
if(stateCounter == 0) // Only print once
|
||||||
Notify(PSTR("\r\nChecking extension port"), 0x80);
|
Notify(PSTR("\r\nChecking extension port"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
stateCounter++; // We will use this counter as there has to be a short delay between the commands
|
stateCounter++; // We will use this counter as there has to be a short delay between the commands
|
||||||
if (stateCounter == 50)
|
if(stateCounter == 50)
|
||||||
statusRequest();
|
statusRequest();
|
||||||
else if (stateCounter == 100)
|
else if(stateCounter == 100)
|
||||||
initExtension1();
|
initExtension1();
|
||||||
else if (stateCounter == 150)
|
else if(stateCounter == 150)
|
||||||
if ((extensionConnected && motionPlusConnected) || (unknownExtensionConnected && !motionPlusConnected))
|
if((extensionConnected && motionPlusConnected) || (unknownExtensionConnected && !motionPlusConnected))
|
||||||
initExtension2();
|
initExtension2();
|
||||||
else
|
else
|
||||||
stateCounter = 299; // There is no extension connected
|
stateCounter = 299; // There is no extension connected
|
||||||
else if (stateCounter == 200)
|
else if(stateCounter == 200)
|
||||||
readExtensionType();
|
readExtensionType();
|
||||||
else if (stateCounter == 250) {
|
else if(stateCounter == 250) {
|
||||||
if (wii_check_flag(WII_FLAG_NUNCHUCK_CONNECTED)) {
|
if(wii_check_flag(WII_FLAG_NUNCHUCK_CONNECTED)) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nNunchuck was reconnected"), 0x80);
|
Notify(PSTR("\r\nNunchuck was reconnected"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
activateNunchuck = true;
|
activateNunchuck = true;
|
||||||
nunchuckConnected = true;
|
nunchuckConnected = true;
|
||||||
}
|
}
|
||||||
if (!motionPlusConnected)
|
if(!motionPlusConnected)
|
||||||
stateCounter = 449;
|
stateCounter = 449;
|
||||||
} else if (stateCounter == 300) {
|
} else if(stateCounter == 300) {
|
||||||
if (motionPlusConnected) {
|
if(motionPlusConnected) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nReactivating the Motion Plus"), 0x80);
|
Notify(PSTR("\r\nReactivating the Motion Plus"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
initMotionPlus();
|
initMotionPlus();
|
||||||
} else
|
} else
|
||||||
stateCounter = 449;
|
stateCounter = 449;
|
||||||
} else if (stateCounter == 350)
|
} else if(stateCounter == 350)
|
||||||
activateMotionPlus();
|
activateMotionPlus();
|
||||||
else if (stateCounter == 400)
|
else if(stateCounter == 400)
|
||||||
readExtensionType(); // Check if it has been activated
|
readExtensionType(); // Check if it has been activated
|
||||||
else if (stateCounter == 450) {
|
else if(stateCounter == 450) {
|
||||||
onInit();
|
onInit();
|
||||||
stateCounter = 0;
|
stateCounter = 0;
|
||||||
unknownExtensionConnected = false;
|
unknownExtensionConnected = false;
|
||||||
|
@ -843,7 +843,7 @@ void WII::Run() {
|
||||||
|
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
void WII::HID_Command(uint8_t* data, uint8_t nbytes) {
|
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
|
pBtd->L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]); // It's the new wiimote with the Motion Plus Inside
|
||||||
else
|
else
|
||||||
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
|
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
|
||||||
|
@ -878,6 +878,7 @@ void WII::setLedRaw(uint8_t value) {
|
||||||
HIDBuffer[2] = value | (HIDBuffer[2] & 0x01); // Keep the rumble bit
|
HIDBuffer[2] = value | (HIDBuffer[2] & 0x01); // Keep the rumble bit
|
||||||
HID_Command(HIDBuffer, 3);
|
HID_Command(HIDBuffer, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WII::setLedOff(LED a) {
|
void WII::setLedOff(LED a) {
|
||||||
HIDBuffer[1] = 0x11;
|
HIDBuffer[1] = 0x11;
|
||||||
HIDBuffer[2] &= ~(pgm_read_byte(&LEDS[(uint8_t)a]));
|
HIDBuffer[2] &= ~(pgm_read_byte(&LEDS[(uint8_t)a]));
|
||||||
|
@ -899,11 +900,11 @@ void WII::setLedToggle(LED a) {
|
||||||
void WII::setLedStatus() {
|
void WII::setLedStatus() {
|
||||||
HIDBuffer[1] = 0x11;
|
HIDBuffer[1] = 0x11;
|
||||||
HIDBuffer[2] = (HIDBuffer[2] & 0x01); // Keep the rumble bit
|
HIDBuffer[2] = (HIDBuffer[2] & 0x01); // Keep the rumble bit
|
||||||
if (wiimoteConnected)
|
if(wiimoteConnected)
|
||||||
HIDBuffer[2] |= 0x10; // If it's connected LED1 will light up
|
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
|
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
|
HIDBuffer[2] |= 0x40; // If it's connected LED3 will light up
|
||||||
|
|
||||||
HID_Command(HIDBuffer, 3);
|
HID_Command(HIDBuffer, 3);
|
||||||
|
@ -919,7 +920,7 @@ void WII::setReportMode(bool continuous, uint8_t mode) {
|
||||||
uint8_t cmd_buf[4];
|
uint8_t cmd_buf[4];
|
||||||
cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
||||||
cmd_buf[1] = 0x12;
|
cmd_buf[1] = 0x12;
|
||||||
if (continuous)
|
if(continuous)
|
||||||
cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01); // Keep the rumble bit
|
cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01); // Keep the rumble bit
|
||||||
else
|
else
|
||||||
cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01); // Keep the rumble bit
|
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[5] = (uint8_t)(offset & 0xFF);
|
||||||
cmd_buf[6] = size;
|
cmd_buf[6] = size;
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
for (; i < size; i++)
|
for(; i < size; i++)
|
||||||
cmd_buf[7 + i] = data[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;
|
cmd_buf[7 + i] = 0x00;
|
||||||
HID_Command(cmd_buf, 23);
|
HID_Command(cmd_buf, 23);
|
||||||
}
|
}
|
||||||
|
@ -976,17 +977,17 @@ void WII::initMotionPlus() {
|
||||||
|
|
||||||
void WII::activateMotionPlus() {
|
void WII::activateMotionPlus() {
|
||||||
uint8_t buf[1];
|
uint8_t buf[1];
|
||||||
if (pBtd->wiiUProController) {
|
if(pBtd->wiiUProController) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nActivating Wii U Pro Controller"), 0x80);
|
Notify(PSTR("\r\nActivating Wii U Pro Controller"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
buf[0] = 0x00; // It seems like you can send anything but 0x04, 0x05, and 0x07
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nActivating Motion Plus in pass-through mode"), 0x80);
|
Notify(PSTR("\r\nActivating Motion Plus in pass-through mode"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
buf[0] = 0x05; // Activate nunchuck pass-through mode
|
buf[0] = 0x05; // Activate nunchuck pass-through mode
|
||||||
} //else if(classicControllerConnected && extensionConnected)
|
}//else if(classicControllerConnected && extensionConnected)
|
||||||
//buf[0] = 0x07;
|
//buf[0] = 0x07;
|
||||||
else {
|
else {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
@ -1001,7 +1002,7 @@ void WII::readData(uint32_t offset, uint16_t size, bool EEPROM) {
|
||||||
uint8_t cmd_buf[8];
|
uint8_t cmd_buf[8];
|
||||||
cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
||||||
cmd_buf[1] = 0x17; // Read data
|
cmd_buf[1] = 0x17; // Read data
|
||||||
if (EEPROM)
|
if(EEPROM)
|
||||||
cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01); // Read from EEPROM
|
cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01); // Read from EEPROM
|
||||||
else
|
else
|
||||||
cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01); // Read from memory
|
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
|
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]));
|
return (ButtonState & pgm_read_dword(&PROCONTROLLERBUTTONS[(uint8_t)b]));
|
||||||
else
|
else
|
||||||
return (ButtonState & pgm_read_dword(&BUTTONS[(uint8_t)b]));
|
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
|
bool WII::getButtonClick(Button b) { // Only return true when a button is clicked
|
||||||
uint32_t button;
|
uint32_t button;
|
||||||
if (wiiUProControllerConnected)
|
if(wiiUProControllerConnected)
|
||||||
button = pgm_read_dword(&PROCONTROLLERBUTTONS[(uint8_t)b]);
|
button = pgm_read_dword(&PROCONTROLLERBUTTONS[(uint8_t)b]);
|
||||||
else
|
else
|
||||||
button = pgm_read_dword(&BUTTONS[(uint8_t)b]);
|
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) {
|
uint8_t WII::getAnalogHat(Hat a) {
|
||||||
if (!nunchuckConnected)
|
if(!nunchuckConnected)
|
||||||
return 127; // Return center position
|
return 127; // Return center position
|
||||||
else {
|
else {
|
||||||
uint8_t output = hatValues[(uint8_t)a];
|
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;
|
return 127;
|
||||||
else
|
else
|
||||||
return output;
|
return output;
|
||||||
|
@ -1062,11 +1063,11 @@ uint8_t WII::getAnalogHat(Hat a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t WII::getAnalogHat(AnalogHat a) {
|
uint16_t WII::getAnalogHat(AnalogHat a) {
|
||||||
if (!wiiUProControllerConnected)
|
if(!wiiUProControllerConnected)
|
||||||
return 2000;
|
return 2000;
|
||||||
else {
|
else {
|
||||||
uint16_t output = hatValues[(uint8_t)a];
|
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;
|
return 2000;
|
||||||
else
|
else
|
||||||
return output;
|
return output;
|
||||||
|
@ -1074,7 +1075,7 @@ uint16_t WII::getAnalogHat(AnalogHat a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WII::onInit() {
|
void WII::onInit() {
|
||||||
if (pFuncOnInit)
|
if(pFuncOnInit)
|
||||||
pFuncOnInit(); // Call the user function
|
pFuncOnInit(); // Call the user function
|
||||||
else
|
else
|
||||||
setLedStatus();
|
setLedStatus();
|
||||||
|
|
13
Wii.h
13
Wii.h
|
@ -85,6 +85,7 @@ public:
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
/** @name Wii Controller functions */
|
/** @name Wii Controller functions */
|
||||||
|
|
||||||
/** Call this to start the paring sequence with a controller */
|
/** Call this to start the paring sequence with a controller */
|
||||||
void pair(void) {
|
void pair(void) {
|
||||||
if(pBtd)
|
if(pBtd)
|
||||||
|
@ -108,7 +109,7 @@ public:
|
||||||
* @return Pitch in the range from 0-360.
|
* @return Pitch in the range from 0-360.
|
||||||
*/
|
*/
|
||||||
double getPitch() {
|
double getPitch() {
|
||||||
if (motionPlusConnected)
|
if(motionPlusConnected)
|
||||||
return compPitch;
|
return compPitch;
|
||||||
return getWiimotePitch();
|
return getWiimotePitch();
|
||||||
};
|
};
|
||||||
|
@ -118,7 +119,7 @@ public:
|
||||||
* @return Roll in the range from 0-360.
|
* @return Roll in the range from 0-360.
|
||||||
*/
|
*/
|
||||||
double getRoll() {
|
double getRoll() {
|
||||||
if (motionPlusConnected)
|
if(motionPlusConnected)
|
||||||
return compRoll;
|
return compRoll;
|
||||||
return getWiimoteRoll();
|
return getWiimoteRoll();
|
||||||
};
|
};
|
||||||
|
@ -147,6 +148,7 @@ public:
|
||||||
* @param value See: ::LED enum.
|
* @param value See: ::LED enum.
|
||||||
*/
|
*/
|
||||||
void setLedRaw(uint8_t value);
|
void setLedRaw(uint8_t value);
|
||||||
|
|
||||||
/** Turn all LEDs off. */
|
/** Turn all LEDs off. */
|
||||||
void setLedOff() {
|
void setLedOff() {
|
||||||
setLedRaw(0);
|
setLedRaw(0);
|
||||||
|
@ -180,6 +182,7 @@ public:
|
||||||
* @return The battery level in the range 0-255.
|
* @return The battery level in the range 0-255.
|
||||||
*/
|
*/
|
||||||
uint8_t getBatteryLevel();
|
uint8_t getBatteryLevel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Wiimote state.
|
* Return the Wiimote state.
|
||||||
* @return See: http://wiibrew.org/wiki/Wiimote#0x20:_Status.
|
* @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 */
|
/* 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. */
|
/** Pitch and roll calculated from the accelerometer inside the Wiimote. */
|
||||||
double getWiimotePitch() {
|
double getWiimotePitch() {
|
||||||
return (atan2(accYwiimote, accZwiimote) + PI) * RAD_TO_DEG;
|
return (atan2(accYwiimote, accZwiimote) + PI) * RAD_TO_DEG;
|
||||||
};
|
};
|
||||||
|
|
||||||
double getWiimoteRoll() {
|
double getWiimoteRoll() {
|
||||||
return (atan2(accXwiimote, accZwiimote) + PI) * RAD_TO_DEG;
|
return (atan2(accXwiimote, accZwiimote) + PI) * RAD_TO_DEG;
|
||||||
};
|
};
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
/**@{*/
|
/**@{*/
|
||||||
|
|
||||||
/** Pitch and roll calculated from the accelerometer inside the Nunchuck. */
|
/** Pitch and roll calculated from the accelerometer inside the Nunchuck. */
|
||||||
double getNunchuckPitch() {
|
double getNunchuckPitch() {
|
||||||
return (atan2(accYnunchuck, accZnunchuck) + PI) * RAD_TO_DEG;
|
return (atan2(accYnunchuck, accZnunchuck) + PI) * RAD_TO_DEG;
|
||||||
};
|
};
|
||||||
|
|
||||||
double getNunchuckRoll() {
|
double getNunchuckRoll() {
|
||||||
return (atan2(accXnunchuck, accZnunchuck) + PI) * RAD_TO_DEG;
|
return (atan2(accXnunchuck, accZnunchuck) + PI) * RAD_TO_DEG;
|
||||||
};
|
};
|
||||||
|
@ -381,7 +388,7 @@ public:
|
||||||
* @return True if it's enabled, false if not.
|
* @return True if it's enabled, false if not.
|
||||||
*/
|
*/
|
||||||
bool isIRCameraEnabled() {
|
bool isIRCameraEnabled() {
|
||||||
return(wiiState & 0x08);
|
return (wiiState & 0x08);
|
||||||
};
|
};
|
||||||
/**@}*/
|
/**@}*/
|
||||||
#endif
|
#endif
|
||||||
|
|
48
XBOXOLD.cpp
48
XBOXOLD.cpp
|
@ -48,14 +48,14 @@ XBOXOLD::XBOXOLD(USB *p) :
|
||||||
pUsb(p), // pointer to USB class instance - mandatory
|
pUsb(p), // pointer to USB class instance - mandatory
|
||||||
bAddress(0), // device address - mandatory
|
bAddress(0), // device address - mandatory
|
||||||
bPollEnable(false) { // don't start polling before dongle is connected
|
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].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
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
|
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);
|
Notify(PSTR("\r\nXBOXUSB Init"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
// check if address has already been assigned to an instance
|
// check if address has already been assigned to an instance
|
||||||
if (bAddress) {
|
if(bAddress) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress in use"), 0x80);
|
Notify(PSTR("\r\nAddress in use"), 0x80);
|
||||||
#endif
|
#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
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
p = addrPool.GetUsbDevicePtr(0);
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
|
|
||||||
if (!p) {
|
if(!p) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress not found"), 0x80);
|
Notify(PSTR("\r\nAddress not found"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p->epinfo) {
|
if(!p->epinfo) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nepinfo is null"), 0x80);
|
Notify(PSTR("\r\nepinfo is null"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -111,19 +111,19 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Restore p->epinfo
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
|
|
||||||
VID = udd->idVendor;
|
VID = udd->idVendor;
|
||||||
PID = udd->idProduct;
|
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;
|
goto FailUnknownDevice;
|
||||||
|
|
||||||
// Allocate new address according to device class
|
// Allocate new address according to device class
|
||||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||||
|
|
||||||
if (!bAddress)
|
if(!bAddress)
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
// Extract Max Packet Size from device descriptor
|
// 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
|
// Assign new address to the device
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
rcode = pUsb->setAddr(0, 0, bAddress);
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
@ -151,14 +151,14 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
//get pointer to assigned address record
|
//get pointer to assigned address record
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
p->lowspeed = lowspeed;
|
p->lowspeed = lowspeed;
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer - only EP0 is known
|
// Assign epInfo to epinfo pointer - only EP0 is known
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
/* The application will work in reduced host mode, so we can save program and data
|
/* 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;
|
epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = 0;
|
||||||
|
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
delay(200); // Give time for address change
|
delay(200); // Give time for address change
|
||||||
|
|
||||||
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
|
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nXbox Controller Connected\r\n"), 0x80);
|
Notify(PSTR("\r\nXbox Controller Connected\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
if (pFuncOnInit)
|
if(pFuncOnInit)
|
||||||
pFuncOnInit(); // Call the user function
|
pFuncOnInit(); // Call the user function
|
||||||
XboxConnected = true;
|
XboxConnected = true;
|
||||||
bPollEnable = true;
|
bPollEnable = true;
|
||||||
|
@ -242,7 +242,7 @@ uint8_t XBOXOLD::Release() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t XBOXOLD::Poll() {
|
uint8_t XBOXOLD::Poll() {
|
||||||
if (!bPollEnable)
|
if(!bPollEnable)
|
||||||
return 0;
|
return 0;
|
||||||
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
|
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
|
||||||
pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
|
pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
|
||||||
|
@ -256,7 +256,7 @@ uint8_t XBOXOLD::Poll() {
|
||||||
void XBOXOLD::readReport() {
|
void XBOXOLD::readReport() {
|
||||||
ButtonState = readBuf[2];
|
ButtonState = readBuf[2];
|
||||||
|
|
||||||
for (uint8_t i = 0; i < sizeof(buttonValues); i++)
|
for(uint8_t i = 0; i < sizeof (buttonValues); i++)
|
||||||
buttonValues[i] = readBuf[i + 4]; // A, B, X, Y, BLACK, WHITE, L1, and R1
|
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[LeftHatX] = (int16_t)(((uint16_t)readBuf[12] << 8) | readBuf[13]);
|
||||||
|
@ -267,12 +267,12 @@ void XBOXOLD::readReport() {
|
||||||
//Notify(PSTR("\r\nButtonState"), 0x80);
|
//Notify(PSTR("\r\nButtonState"), 0x80);
|
||||||
//PrintHex<uint8_t>(ButtonState, 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
|
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
|
||||||
OldButtonState = ButtonState;
|
OldButtonState = ButtonState;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < sizeof(buttonValues); i++) {
|
for(uint8_t i = 0; i < sizeof (buttonValues); i++) {
|
||||||
if (oldButtonValues[i] == 0 && buttonValues[i] != 0)
|
if(oldButtonValues[i] == 0 && buttonValues[i] != 0)
|
||||||
buttonClicked[i] = true; // Update A, B, X, Y, BLACK, WHITE, L1, and R1 click state
|
buttonClicked[i] = true; // Update A, B, X, Y, BLACK, WHITE, L1, and R1 click state
|
||||||
oldButtonValues[i] = buttonValues[i];
|
oldButtonValues[i] = buttonValues[i];
|
||||||
}
|
}
|
||||||
|
@ -281,9 +281,9 @@ void XBOXOLD::readReport() {
|
||||||
|
|
||||||
void XBOXOLD::printReport(uint16_t length) { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox controller
|
void XBOXOLD::printReport(uint16_t length) { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox controller
|
||||||
#ifdef PRINTREPORT
|
#ifdef PRINTREPORT
|
||||||
if (readBuf == NULL)
|
if(readBuf == NULL)
|
||||||
return;
|
return;
|
||||||
for (uint8_t i = 0; i < length; i++) {
|
for(uint8_t i = 0; i < length; i++) {
|
||||||
D_PrintHex<uint8_t > (readBuf[i], 0x80);
|
D_PrintHex<uint8_t > (readBuf[i], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -293,15 +293,15 @@ void XBOXOLD::printReport(uint16_t length) { //Uncomment "#define PRINTREPORT" t
|
||||||
|
|
||||||
uint8_t XBOXOLD::getButtonPress(Button b) {
|
uint8_t XBOXOLD::getButtonPress(Button b) {
|
||||||
uint8_t button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]);
|
uint8_t button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]);
|
||||||
if (b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons
|
if(b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons
|
||||||
return buttonValues[button]; // Analog buttons
|
return buttonValues[button]; // Analog buttons
|
||||||
return (ButtonState & button); // Digital buttons
|
return (ButtonState & button); // Digital buttons
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XBOXOLD::getButtonClick(Button b) {
|
bool XBOXOLD::getButtonClick(Button b) {
|
||||||
uint8_t button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]);
|
uint8_t button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]);
|
||||||
if (b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) { // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons
|
if(b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) { // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons
|
||||||
if (buttonClicked[button]) {
|
if(buttonClicked[button]) {
|
||||||
buttonClicked[button] = false;
|
buttonClicked[button] = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
106
XBOXRECV.cpp
106
XBOXRECV.cpp
|
@ -26,14 +26,14 @@ XBOXRECV::XBOXRECV(USB *p) :
|
||||||
pUsb(p), // pointer to USB class instance - mandatory
|
pUsb(p), // pointer to USB class instance - mandatory
|
||||||
bAddress(0), // device address - mandatory
|
bAddress(0), // device address - mandatory
|
||||||
bPollEnable(false) { // don't start polling before dongle is connected
|
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].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
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
|
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);
|
Notify(PSTR("\r\nXBOXRECV Init"), 0x80);
|
||||||
#endif
|
#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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress in use"), 0x80);
|
Notify(PSTR("\r\nAddress in use"), 0x80);
|
||||||
#endif
|
#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
|
p = addrPool.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned
|
||||||
|
|
||||||
if (!p) {
|
if(!p) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress not found"), 0x80);
|
Notify(PSTR("\r\nAddress not found"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p->epinfo) {
|
if(!p->epinfo) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nepinfo is null"), 0x80);
|
Notify(PSTR("\r\nepinfo is null"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,13 +82,13 @@ uint8_t XBOXRECV::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
p->epinfo = oldep_ptr; // Restore p->epinfo
|
p->epinfo = oldep_ptr; // Restore p->epinfo
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
|
|
||||||
VID = udd->idVendor;
|
VID = udd->idVendor;
|
||||||
PID = udd->idProduct;
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nYou'll need a wireless receiver for this libary to work"), 0x80);
|
Notify(PSTR("\r\nYou'll need a wireless receiver for this libary to work"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -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
|
bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class
|
||||||
|
|
||||||
if (!bAddress) {
|
if(!bAddress) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nOut of address space"), 0x80);
|
Notify(PSTR("\r\nOut of address space"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -115,13 +115,13 @@ FailGetDevDescr:
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
NotifyFailGetDevDescr(rcode);
|
NotifyFailGetDevDescr(rcode);
|
||||||
#endif
|
#endif
|
||||||
if (rcode != hrJERR)
|
if(rcode != hrJERR)
|
||||||
rcode = USB_ERROR_FailGetDevDescr;
|
rcode = USB_ERROR_FailGetDevDescr;
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailUnknownDevice:
|
FailUnknownDevice:
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
NotifyFailUnknownDevice(VID,PID);
|
NotifyFailUnknownDevice(VID, PID);
|
||||||
#endif
|
#endif
|
||||||
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
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
|
#endif
|
||||||
UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
|
UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
|
||||||
|
|
||||||
if (!p) {
|
if(!p) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress not found"), 0x80);
|
Notify(PSTR("\r\nAddress not found"), 0x80);
|
||||||
#endif
|
#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
|
delay(300); // Assign new address to the device
|
||||||
|
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress); // 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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nsetAddr: "), 0x80);
|
Notify(PSTR("\r\nsetAddr: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (rcode, 0x80);
|
D_PrintHex<uint8_t > (rcode, 0x80);
|
||||||
|
@ -169,7 +169,7 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
|
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
|
p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record
|
||||||
if (!p) {
|
if(!p) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress not found"), 0x80);
|
Notify(PSTR("\r\nAddress not found"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -179,7 +179,7 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
p->lowspeed = lowspeed;
|
p->lowspeed = lowspeed;
|
||||||
|
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known
|
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
/* The application will work in reduced host mode, so we can save program and data
|
/* 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;
|
epInfo[ XBOX_OUTPUT_PIPE_4 ].bmRcvToggle = 0;
|
||||||
|
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 9, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 9, epInfo);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
delay(200); //Give time for address change
|
delay(200); //Give time for address change
|
||||||
|
|
||||||
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
|
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
@ -281,7 +281,7 @@ Fail:
|
||||||
/* Performs a cleanup after failed Init() attempt */
|
/* Performs a cleanup after failed Init() attempt */
|
||||||
uint8_t XBOXRECV::Release() {
|
uint8_t XBOXRECV::Release() {
|
||||||
XboxReceiverConnected = false;
|
XboxReceiverConnected = false;
|
||||||
for (uint8_t i = 0; i < 4; i++)
|
for(uint8_t i = 0; i < 4; i++)
|
||||||
Xbox360Connected[i] = 0x00;
|
Xbox360Connected[i] = 0x00;
|
||||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
@ -290,28 +290,28 @@ uint8_t XBOXRECV::Release() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t XBOXRECV::Poll() {
|
uint8_t XBOXRECV::Poll() {
|
||||||
if (!bPollEnable)
|
if(!bPollEnable)
|
||||||
return 0;
|
return 0;
|
||||||
if (!checkStatusTimer || ((millis() - checkStatusTimer) > 3000)) { // Run checkStatus every 3 seconds
|
if(!checkStatusTimer || ((millis() - checkStatusTimer) > 3000)) { // Run checkStatus every 3 seconds
|
||||||
checkStatusTimer = millis();
|
checkStatusTimer = millis();
|
||||||
checkStatus();
|
checkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t inputPipe;
|
uint8_t inputPipe;
|
||||||
uint16_t bufferSize;
|
uint16_t bufferSize;
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for(uint8_t i = 0; i < 4; i++) {
|
||||||
if (i == 0)
|
if(i == 0)
|
||||||
inputPipe = XBOX_INPUT_PIPE_1;
|
inputPipe = XBOX_INPUT_PIPE_1;
|
||||||
else if (i == 1)
|
else if(i == 1)
|
||||||
inputPipe = XBOX_INPUT_PIPE_2;
|
inputPipe = XBOX_INPUT_PIPE_2;
|
||||||
else if (i == 2)
|
else if(i == 2)
|
||||||
inputPipe = XBOX_INPUT_PIPE_3;
|
inputPipe = XBOX_INPUT_PIPE_3;
|
||||||
else
|
else
|
||||||
inputPipe = XBOX_INPUT_PIPE_4;
|
inputPipe = XBOX_INPUT_PIPE_4;
|
||||||
|
|
||||||
bufferSize = EP_MAXPKTSIZE; // This is the maximum number of bytes we want to receive
|
bufferSize = EP_MAXPKTSIZE; // This is the maximum number of bytes we want to receive
|
||||||
pUsb->inTransfer(bAddress, epInfo[ inputPipe ].epAddr, &bufferSize, readBuf);
|
pUsb->inTransfer(bAddress, epInfo[ inputPipe ].epAddr, &bufferSize, readBuf);
|
||||||
if (bufferSize > 0) { // The number of received bytes
|
if(bufferSize > 0) { // The number of received bytes
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
Notify(PSTR("Bytes Received: "), 0x80);
|
Notify(PSTR("Bytes Received: "), 0x80);
|
||||||
D_PrintHex<uint16_t > (bufferSize, 0x80);
|
D_PrintHex<uint16_t > (bufferSize, 0x80);
|
||||||
|
@ -327,19 +327,19 @@ uint8_t XBOXRECV::Poll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XBOXRECV::readReport(uint8_t controller) {
|
void XBOXRECV::readReport(uint8_t controller) {
|
||||||
if (readBuf == NULL)
|
if(readBuf == NULL)
|
||||||
return;
|
return;
|
||||||
// This report is send when a controller is connected and disconnected
|
// 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];
|
Xbox360Connected[controller] = readBuf[1];
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("Controller "), 0x80);
|
Notify(PSTR("Controller "), 0x80);
|
||||||
Notify(controller, 0x80);
|
Notify(controller, 0x80);
|
||||||
#endif
|
#endif
|
||||||
if (Xbox360Connected[controller]) {
|
if(Xbox360Connected[controller]) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
const char* str = 0;
|
const char* str = 0;
|
||||||
switch (readBuf[1]) {
|
switch(readBuf[1]) {
|
||||||
case 0x80: str = PSTR(" as controller\r\n");
|
case 0x80: str = PSTR(" as controller\r\n");
|
||||||
break;
|
break;
|
||||||
case 0x40: str = PSTR(" as headset\r\n");
|
case 0x40: str = PSTR(" as headset\r\n");
|
||||||
|
@ -359,15 +359,15 @@ void XBOXRECV::readReport(uint8_t controller) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Controller status report
|
// 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];
|
controllerStatus[controller] = ((uint16_t)readBuf[3] << 8) | readBuf[4];
|
||||||
return;
|
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;
|
return;
|
||||||
|
|
||||||
// A controller must be connected if it's sending data
|
// A controller must be connected if it's sending data
|
||||||
if (!Xbox360Connected[controller])
|
if(!Xbox360Connected[controller])
|
||||||
Xbox360Connected[controller] |= 0x80;
|
Xbox360Connected[controller] |= 0x80;
|
||||||
|
|
||||||
ButtonState[controller] = (uint32_t)(readBuf[9] | ((uint16_t)readBuf[8] << 8) | ((uint32_t)readBuf[7] << 16) | ((uint32_t)readBuf[6] << 24));
|
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);
|
//Notify(PSTR("\r\nButtonState: "), 0x80);
|
||||||
//PrintHex<uint32_t>(ButtonState[controller], 0x80);
|
//PrintHex<uint32_t>(ButtonState[controller], 0x80);
|
||||||
|
|
||||||
if (ButtonState[controller] != OldButtonState[controller]) {
|
if(ButtonState[controller] != OldButtonState[controller]) {
|
||||||
buttonStateChanged[controller] = true;
|
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
|
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;
|
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;
|
L2Clicked[controller] = true;
|
||||||
OldButtonState[controller] = ButtonState[controller];
|
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
|
void XBOXRECV::printReport(uint8_t controller, uint8_t nBytes) { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
|
||||||
#ifdef PRINTREPORT
|
#ifdef PRINTREPORT
|
||||||
if (readBuf == NULL)
|
if(readBuf == NULL)
|
||||||
return;
|
return;
|
||||||
Notify(PSTR("Controller "), 0x80);
|
Notify(PSTR("Controller "), 0x80);
|
||||||
Notify(controller, 0x80);
|
Notify(controller, 0x80);
|
||||||
Notify(PSTR(": "), 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);
|
D_PrintHex<uint8_t > (readBuf[i], 0x80);
|
||||||
Notify(PSTR(" "), 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) {
|
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);
|
return (uint8_t)(ButtonState[controller] >> 8);
|
||||||
else if (b == R2)
|
else if(b == R2)
|
||||||
return (uint8_t)ButtonState[controller];
|
return (uint8_t)ButtonState[controller];
|
||||||
return (bool)(ButtonState[controller] & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16));
|
return (bool)(ButtonState[controller] & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XBOXRECV::getButtonClick(Button b, uint8_t controller) {
|
bool XBOXRECV::getButtonClick(Button b, uint8_t controller) {
|
||||||
if (b == L2) {
|
if(b == L2) {
|
||||||
if (L2Clicked[controller]) {
|
if(L2Clicked[controller]) {
|
||||||
L2Clicked[controller] = false;
|
L2Clicked[controller] = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else if (b == R2) {
|
} else if(b == R2) {
|
||||||
if (R2Clicked[controller]) {
|
if(R2Clicked[controller]) {
|
||||||
R2Clicked[controller] = false;
|
R2Clicked[controller] = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -472,7 +472,7 @@ void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) {
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
#endif
|
#endif
|
||||||
uint8_t outputPipe;
|
uint8_t outputPipe;
|
||||||
switch (controller) {
|
switch(controller) {
|
||||||
case 0: outputPipe = XBOX_OUTPUT_PIPE_1;
|
case 0: outputPipe = XBOX_OUTPUT_PIPE_1;
|
||||||
break;
|
break;
|
||||||
case 1: outputPipe = XBOX_OUTPUT_PIPE_2;
|
case 1: outputPipe = XBOX_OUTPUT_PIPE_2;
|
||||||
|
@ -489,7 +489,7 @@ void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) {
|
||||||
#endif
|
#endif
|
||||||
pUsb->outTransfer(bAddress, epInfo[ outputPipe ].epAddr, nbytes, data);
|
pUsb->outTransfer(bAddress, epInfo[ outputPipe ].epAddr, nbytes, data);
|
||||||
#ifdef EXTRADEBUG
|
#ifdef EXTRADEBUG
|
||||||
if (rcode)
|
if(rcode)
|
||||||
Notify(PSTR("Error sending Xbox message\r\n"), 0x80);
|
Notify(PSTR("Error sending Xbox message\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -513,7 +513,7 @@ void XBOXRECV::setLedRaw(uint8_t value, uint8_t controller) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XBOXRECV::setLedOn(LED led, 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);
|
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
|
Found by timstamp.co.uk
|
||||||
*/
|
*/
|
||||||
void XBOXRECV::checkStatus() {
|
void XBOXRECV::checkStatus() {
|
||||||
if (!bPollEnable)
|
if(!bPollEnable)
|
||||||
return;
|
return;
|
||||||
// Get controller info
|
// Get controller info
|
||||||
writeBuf[0] = 0x08;
|
writeBuf[0] = 0x08;
|
||||||
writeBuf[1] = 0x00;
|
writeBuf[1] = 0x00;
|
||||||
writeBuf[2] = 0x0f;
|
writeBuf[2] = 0x0f;
|
||||||
writeBuf[3] = 0xc0;
|
writeBuf[3] = 0xc0;
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for(uint8_t i = 0; i < 4; i++) {
|
||||||
XboxCommand(i, writeBuf, 4);
|
XboxCommand(i, writeBuf, 4);
|
||||||
}
|
}
|
||||||
// Get battery status
|
// Get battery status
|
||||||
|
@ -545,8 +545,8 @@ void XBOXRECV::checkStatus() {
|
||||||
writeBuf[1] = 0x00;
|
writeBuf[1] = 0x00;
|
||||||
writeBuf[2] = 0x00;
|
writeBuf[2] = 0x00;
|
||||||
writeBuf[3] = 0x40;
|
writeBuf[3] = 0x40;
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for(uint8_t i = 0; i < 4; i++) {
|
||||||
if (Xbox360Connected[i])
|
if(Xbox360Connected[i])
|
||||||
XboxCommand(i, writeBuf, 4);
|
XboxCommand(i, writeBuf, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -564,15 +564,15 @@ void XBOXRECV::setRumbleOn(uint8_t lValue, uint8_t rValue, uint8_t controller) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XBOXRECV::onInit(uint8_t controller) {
|
void XBOXRECV::onInit(uint8_t controller) {
|
||||||
if (pFuncOnInit)
|
if(pFuncOnInit)
|
||||||
pFuncOnInit(); // Call the user function
|
pFuncOnInit(); // Call the user function
|
||||||
else {
|
else {
|
||||||
LED led;
|
LED led;
|
||||||
if (controller == 0)
|
if(controller == 0)
|
||||||
led = LED1;
|
led = LED1;
|
||||||
else if (controller == 1)
|
else if(controller == 1)
|
||||||
led = LED2;
|
led = LED2;
|
||||||
else if (controller == 2)
|
else if(controller == 2)
|
||||||
led = LED3;
|
led = LED3;
|
||||||
else
|
else
|
||||||
led = LED4;
|
led = LED4;
|
||||||
|
|
64
XBOXUSB.cpp
64
XBOXUSB.cpp
|
@ -24,14 +24,14 @@ XBOXUSB::XBOXUSB(USB *p) :
|
||||||
pUsb(p), // pointer to USB class instance - mandatory
|
pUsb(p), // pointer to USB class instance - mandatory
|
||||||
bAddress(0), // device address - mandatory
|
bAddress(0), // device address - mandatory
|
||||||
bPollEnable(false) { // don't start polling before dongle is connected
|
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].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
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
|
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);
|
Notify(PSTR("\r\nXBOXUSB Init"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
// check if address has already been assigned to an instance
|
// check if address has already been assigned to an instance
|
||||||
if (bAddress) {
|
if(bAddress) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress in use"), 0x80);
|
Notify(PSTR("\r\nAddress in use"), 0x80);
|
||||||
#endif
|
#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
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
p = addrPool.GetUsbDevicePtr(0);
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
|
|
||||||
if (!p) {
|
if(!p) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nAddress not found"), 0x80);
|
Notify(PSTR("\r\nAddress not found"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p->epinfo) {
|
if(!p->epinfo) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nepinfo is null"), 0x80);
|
Notify(PSTR("\r\nepinfo is null"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
|
@ -87,31 +87,31 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Restore p->epinfo
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
|
|
||||||
VID = udd->idVendor;
|
VID = udd->idVendor;
|
||||||
PID = udd->idProduct;
|
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;
|
goto FailUnknownDevice;
|
||||||
if (PID == XBOX_WIRELESS_PID) {
|
if(PID == XBOX_WIRELESS_PID) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nYou have plugged in a wireless Xbox 360 controller - it doesn't support USB communication"), 0x80);
|
Notify(PSTR("\r\nYou have plugged in a wireless Xbox 360 controller - it doesn't support USB communication"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
goto FailUnknownDevice;
|
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
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nThis library only supports Xbox 360 controllers via USB"), 0x80);
|
Notify(PSTR("\r\nThis library only supports Xbox 360 controllers via USB"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
goto FailUnknownDevice;
|
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;
|
goto FailUnknownDevice;
|
||||||
|
|
||||||
// Allocate new address according to device class
|
// Allocate new address according to device class
|
||||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||||
|
|
||||||
if (!bAddress)
|
if(!bAddress)
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
// Extract Max Packet Size from device descriptor
|
// 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
|
// Assign new address to the device
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
rcode = pUsb->setAddr(0, 0, bAddress);
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
@ -139,14 +139,14 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
//get pointer to assigned address record
|
//get pointer to assigned address record
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
p->lowspeed = lowspeed;
|
p->lowspeed = lowspeed;
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer - only EP0 is known
|
// Assign epInfo to epinfo pointer - only EP0 is known
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
/* The application will work in reduced host mode, so we can save program and data
|
/* 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;
|
epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = 0;
|
||||||
|
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
delay(200); // Give time for address change
|
delay(200); // Give time for address change
|
||||||
|
|
||||||
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
|
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
@ -229,7 +229,7 @@ uint8_t XBOXUSB::Release() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t XBOXUSB::Poll() {
|
uint8_t XBOXUSB::Poll() {
|
||||||
if (!bPollEnable)
|
if(!bPollEnable)
|
||||||
return 0;
|
return 0;
|
||||||
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
|
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
|
||||||
pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
|
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() {
|
void XBOXUSB::readReport() {
|
||||||
if (readBuf == NULL)
|
if(readBuf == NULL)
|
||||||
return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,11 +257,11 @@ void XBOXUSB::readReport() {
|
||||||
//Notify(PSTR("\r\nButtonState"), 0x80);
|
//Notify(PSTR("\r\nButtonState"), 0x80);
|
||||||
//PrintHex<uint32_t>(ButtonState, 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
|
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;
|
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;
|
L2Clicked = true;
|
||||||
OldButtonState = ButtonState;
|
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
|
void XBOXUSB::printReport() { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
|
||||||
#ifdef PRINTREPORT
|
#ifdef PRINTREPORT
|
||||||
if (readBuf == NULL)
|
if(readBuf == NULL)
|
||||||
return;
|
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);
|
D_PrintHex<uint8_t > (readBuf[i], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -280,22 +280,22 @@ void XBOXUSB::printReport() { //Uncomment "#define PRINTREPORT" to print the rep
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t XBOXUSB::getButtonPress(Button b) {
|
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);
|
return (uint8_t)(ButtonState >> 8);
|
||||||
else if (b == R2)
|
else if(b == R2)
|
||||||
return (uint8_t)ButtonState;
|
return (uint8_t)ButtonState;
|
||||||
return (bool)(ButtonState & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16));
|
return (bool)(ButtonState & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XBOXUSB::getButtonClick(Button b) {
|
bool XBOXUSB::getButtonClick(Button b) {
|
||||||
if (b == L2) {
|
if(b == L2) {
|
||||||
if (L2Clicked) {
|
if(L2Clicked) {
|
||||||
L2Clicked = false;
|
L2Clicked = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else if (b == R2) {
|
} else if(b == R2) {
|
||||||
if (R2Clicked) {
|
if(R2Clicked) {
|
||||||
R2Clicked = false;
|
R2Clicked = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -326,7 +326,7 @@ void XBOXUSB::setLedRaw(uint8_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XBOXUSB::setLedOn(LED led) {
|
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);
|
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() {
|
void XBOXUSB::onInit() {
|
||||||
if (pFuncOnInit)
|
if(pFuncOnInit)
|
||||||
pFuncOnInit(); // Call the user function
|
pFuncOnInit(); // Call the user function
|
||||||
else
|
else
|
||||||
setLedOn(LED1);
|
setLedOn(LED1);
|
||||||
|
|
10
address.h
10
address.h
|
@ -111,6 +111,7 @@ class AddressPoolImpl : public AddressPool {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns thePool index for a given address
|
// Returns thePool index for a given address
|
||||||
|
|
||||||
uint8_t FindAddressIndex(uint8_t address = 0) {
|
uint8_t FindAddressIndex(uint8_t address = 0) {
|
||||||
for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) {
|
for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) {
|
||||||
if(thePool[i].address.devAddress == address)
|
if(thePool[i].address.devAddress == address)
|
||||||
|
@ -120,6 +121,7 @@ class AddressPoolImpl : public AddressPool {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns thePool child index for a given parent
|
// Returns thePool child index for a given parent
|
||||||
|
|
||||||
uint8_t FindChildIndex(UsbDeviceAddress addr, uint8_t start = 1) {
|
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++) {
|
for(uint8_t i = (start < 1 || start >= MAX_DEVICES_ALLOWED) ? 1 : start; i < MAX_DEVICES_ALLOWED; i++) {
|
||||||
if(thePool[i].address.bmParent == addr.bmAddress)
|
if(thePool[i].address.bmParent == addr.bmAddress)
|
||||||
|
@ -129,6 +131,7 @@ class AddressPoolImpl : public AddressPool {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Frees address entry specified by index parameter
|
// Frees address entry specified by index parameter
|
||||||
|
|
||||||
void FreeAddressByIndex(uint8_t index) {
|
void FreeAddressByIndex(uint8_t index) {
|
||||||
// Zero field is reserved and should not be affected
|
// Zero field is reserved and should not be affected
|
||||||
if(index == 0)
|
if(index == 0)
|
||||||
|
@ -148,6 +151,7 @@ class AddressPoolImpl : public AddressPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes the whole address pool at once
|
// Initializes the whole address pool at once
|
||||||
|
|
||||||
void InitAllAddresses() {
|
void InitAllAddresses() {
|
||||||
for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
|
for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
|
||||||
InitEntry(i);
|
InitEntry(i);
|
||||||
|
@ -172,16 +176,18 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a pointer to a specified address entry
|
// Returns a pointer to a specified address entry
|
||||||
|
|
||||||
virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) {
|
virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) {
|
||||||
if(!addr)
|
if(!addr)
|
||||||
return thePool;
|
return thePool;
|
||||||
|
|
||||||
uint8_t index = FindAddressIndex(addr);
|
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
|
// Performs an operation specified by pfunc for each addressed device
|
||||||
|
|
||||||
void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) {
|
void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) {
|
||||||
if(!pfunc)
|
if(!pfunc)
|
||||||
return;
|
return;
|
||||||
|
@ -192,6 +198,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Allocates new address
|
// Allocates new address
|
||||||
|
|
||||||
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0) {
|
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0) {
|
||||||
/* if (parent != 0 && port == 0)
|
/* if (parent != 0 && port == 0)
|
||||||
USB_HOST_SERIAL.println("PRT:0"); */
|
USB_HOST_SERIAL.println("PRT:0"); */
|
||||||
|
@ -243,6 +250,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Empties pool entry
|
// Empties pool entry
|
||||||
|
|
||||||
virtual void FreeAddress(uint8_t addr) {
|
virtual void FreeAddress(uint8_t addr) {
|
||||||
// if the root hub is disconnected all the addresses should be initialized
|
// if the root hub is disconnected all the addresses should be initialized
|
||||||
if(addr == 0x41) {
|
if(addr == 0x41) {
|
||||||
|
|
48
adk.cpp
48
adk.cpp
|
@ -13,7 +13,7 @@ Contact information
|
||||||
Circuits At Home, LTD
|
Circuits At Home, LTD
|
||||||
Web : http://www.circuitsathome.com
|
Web : http://www.circuitsathome.com
|
||||||
e-mail : support@circuitsathome.com
|
e-mail : support@circuitsathome.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Google ADK interface */
|
/* Google ADK interface */
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ bConfNum(0), //configuration number
|
||||||
bNumEP(1), //if config descriptor needs to be parsed
|
bNumEP(1), //if config descriptor needs to be parsed
|
||||||
ready(false) {
|
ready(false) {
|
||||||
// initialize endpoint data structures
|
// 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].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
|
@ -50,7 +50,7 @@ ready(false) {
|
||||||
}//for(uint8_t i=0; i<ADK_MAX_ENDPOINTS; i++...
|
}//for(uint8_t i=0; i<ADK_MAX_ENDPOINTS; i++...
|
||||||
|
|
||||||
// register in USB subsystem
|
// register in USB subsystem
|
||||||
if (pUsb) {
|
if(pUsb) {
|
||||||
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
|
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");
|
USBTRACE("\r\nADK Init");
|
||||||
|
|
||||||
// check if address has already been assigned to an instance
|
// check if address has already been assigned to an instance
|
||||||
if (bAddress) {
|
if(bAddress) {
|
||||||
USBTRACE("\r\nAddress in use");
|
USBTRACE("\r\nAddress in use");
|
||||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_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
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
p = addrPool.GetUsbDevicePtr(0);
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
|
|
||||||
if (!p) {
|
if(!p) {
|
||||||
USBTRACE("\r\nAddress not found");
|
USBTRACE("\r\nAddress not found");
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p->epinfo) {
|
if(!p->epinfo) {
|
||||||
USBTRACE("epinfo is null\r\n");
|
USBTRACE("epinfo is null\r\n");
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
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
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
// Assign new address to the device
|
// Assign new address to the device
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
rcode = pUsb->setAddr(0, 0, bAddress);
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
@ -134,7 +134,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
//get pointer to assigned address record
|
//get pointer to assigned address record
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||||
if (!p) {
|
if(!p) {
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
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
|
// Assign epInfo to epinfo pointer - only EP0 is known
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if ADK device is already in accessory mode; if yes, configure and exit
|
//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)) {
|
(udd->idProduct == ADK_PID || udd->idProduct == ADB_PID)) {
|
||||||
USBTRACE("\r\nAcc.mode device detected");
|
USBTRACE("\r\nAcc.mode device detected");
|
||||||
/* go through configurations, find first bulk-IN, bulk-OUT EP, fill epInfo and quit */
|
/* go through configurations, find first bulk-IN, bulk-OUT EP, fill epInfo and quit */
|
||||||
num_of_conf = udd->bNumConfigurations;
|
num_of_conf = udd->bNumConfigurations;
|
||||||
|
|
||||||
//USBTRACE2("\r\nNC:",num_of_conf);
|
//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);
|
ConfigDescParser < 0, 0, 0, 0 > confDescrParser(this);
|
||||||
delay(1);
|
delay(1);
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||||
#if defined(XOOM)
|
#if defined(XOOM)
|
||||||
//added by Jaylen Scott Vanorden
|
//added by Jaylen Scott Vanorden
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
USBTRACE2("\r\nGot 1st bad code for config: ", rcode);
|
USBTRACE2("\r\nGot 1st bad code for config: ", rcode);
|
||||||
// Try once more
|
// Try once more
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
}
|
}
|
||||||
if (bNumEP > 2) {
|
if(bNumEP > 2) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // for (uint8_t i=0; i<num_of_conf; i++...
|
} // 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
|
// Assign epInfo to epinfo pointer - this time all 3 endpoins
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
}
|
}
|
||||||
/* print endpoint structure */
|
/* print endpoint structure */
|
||||||
|
@ -216,13 +216,13 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
rcode = getProto((uint8_t*) & adkproto);
|
rcode = getProto((uint8_t*) & adkproto);
|
||||||
#if defined(XOOM)
|
#if defined(XOOM)
|
||||||
//added by Jaylen Scott Vanorden
|
//added by Jaylen Scott Vanorden
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
USBTRACE2("\r\nGot 1st bad code for proto: ", rcode);
|
USBTRACE2("\r\nGot 1st bad code for proto: ", rcode);
|
||||||
// Try once more
|
// Try once more
|
||||||
rcode = getProto((uint8_t*) & adkproto);
|
rcode = getProto((uint8_t*) & adkproto);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
goto FailGetProto; //init fails
|
goto FailGetProto; //init fails
|
||||||
}
|
}
|
||||||
USBTRACE2("\r\nADK protocol rev. ", adkproto);
|
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
|
//switch to accessory mode
|
||||||
//the Android phone will reset
|
//the Android phone will reset
|
||||||
rcode = switchAcc();
|
rcode = switchAcc();
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
goto FailSwAcc; //init fails
|
goto FailSwAcc; //init fails
|
||||||
}
|
}
|
||||||
rcode = USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET;
|
rcode = USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET;
|
||||||
|
@ -292,7 +292,7 @@ FailSwAcc:
|
||||||
goto Fail;
|
goto Fail;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//FailOnInit:
|
//FailOnInit:
|
||||||
// USBTRACE("OnInit:");
|
// USBTRACE("OnInit:");
|
||||||
// goto Fail;
|
// 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);
|
//ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
|
||||||
|
|
||||||
//added by Yuuichi Akagawa
|
//added by Yuuichi Akagawa
|
||||||
if (bNumEP == 3) {
|
if(bNumEP == 3) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bConfNum = conf;
|
bConfNum = conf;
|
||||||
|
|
||||||
if ((pep->bmAttributes & 0x02) == 2) {
|
if((pep->bmAttributes & 0x02) == 2) {
|
||||||
uint8_t index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
|
uint8_t index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
|
||||||
// Fill in the endpoint info structure
|
// Fill in the endpoint info structure
|
||||||
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
|
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
|
||||||
|
|
12
adk.h
12
adk.h
|
@ -13,7 +13,7 @@ Contact information
|
||||||
Circuits At Home, LTD
|
Circuits At Home, LTD
|
||||||
Web : http://www.circuitsathome.com
|
Web : http://www.circuitsathome.com
|
||||||
e-mail : support@circuitsathome.com
|
e-mail : support@circuitsathome.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Google ADK interface support header */
|
/* Google ADK interface support header */
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@ e-mail : support@circuitsathome.com
|
||||||
#define ADB_PID 0x2D01
|
#define ADB_PID 0x2D01
|
||||||
|
|
||||||
#define XOOM //enables repeating getProto() and getConf() attempts
|
#define XOOM //enables repeating getProto() and getConf() attempts
|
||||||
//necessary for slow devices such as Motorola XOOM
|
//necessary for slow devices such as Motorola XOOM
|
||||||
//defined by default, can be commented out to save memory
|
//defined by default, can be commented out to save memory
|
||||||
|
|
||||||
/* requests */
|
/* requests */
|
||||||
|
|
||||||
|
@ -124,17 +124,17 @@ public:
|
||||||
|
|
||||||
/* returns 2 bytes in *adkproto */
|
/* returns 2 bytes in *adkproto */
|
||||||
inline uint8_t ADK::getProto(uint8_t* 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 */
|
/* send ADK string */
|
||||||
inline uint8_t ADK::sendStr(uint8_t index, const char* str) {
|
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 */
|
/* switch to accessory mode */
|
||||||
inline uint8_t ADK::switchAcc(void) {
|
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_
|
#endif // _ADK_H_
|
||||||
|
|
|
@ -218,7 +218,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t IsSet() {
|
static uint8_t IsSet() {
|
||||||
return PORT::PinRead() & (uint8_t) (1 << PIN);
|
return PORT::PinRead() & (uint8_t)(1 << PIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WaiteForSet() {
|
static void WaiteForSet() {
|
||||||
|
|
40
cdcacm.cpp
40
cdcacm.cpp
|
@ -30,7 +30,7 @@ bNumEP(1),
|
||||||
qNextPollTime(0),
|
qNextPollTime(0),
|
||||||
bPollEnable(false),
|
bPollEnable(false),
|
||||||
ready(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].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
|
@ -40,7 +40,7 @@ ready(false) {
|
||||||
//if (!i)
|
//if (!i)
|
||||||
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
||||||
}
|
}
|
||||||
if (pUsb)
|
if(pUsb)
|
||||||
pUsb->RegisterDeviceClass(this);
|
pUsb->RegisterDeviceClass(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,16 +59,16 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
USBTRACE("ACM Init\r\n");
|
USBTRACE("ACM Init\r\n");
|
||||||
|
|
||||||
if (bAddress)
|
if(bAddress)
|
||||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||||
|
|
||||||
// Get pointer to pseudo device with address 0 assigned
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
p = addrPool.GetUsbDevicePtr(0);
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
if (!p->epinfo) {
|
if(!p->epinfo) {
|
||||||
USBTRACE("epinfo\r\n");
|
USBTRACE("epinfo\r\n");
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
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
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
|
|
||||||
// Allocate new address according to device class
|
// Allocate new address according to device class
|
||||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||||
|
|
||||||
if (!bAddress)
|
if(!bAddress)
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
// Extract Max Packet Size from the device descriptor
|
// 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
|
// Assign new address to the device
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
rcode = pUsb->setAddr(0, 0, bAddress);
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
@ -116,7 +116,7 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
p->lowspeed = lowspeed;
|
p->lowspeed = lowspeed;
|
||||||
|
@ -126,12 +126,12 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Assign epInfo to epinfo pointer
|
// Assign epInfo to epinfo pointer
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
USBTRACE2("NC:", num_of_conf);
|
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,
|
ConfigDescParser< USB_CLASS_COM_AND_CDC_CTRL,
|
||||||
CDC_SUBCLASS_ACM,
|
CDC_SUBCLASS_ACM,
|
||||||
CDC_PROTOCOL_ITU_T_V_250,
|
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);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &CdcControlParser);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
|
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &CdcDataParser);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &CdcDataParser);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
|
|
||||||
if (bNumEP > 1)
|
if(bNumEP > 1)
|
||||||
break;
|
break;
|
||||||
} // for
|
} // for
|
||||||
|
|
||||||
if (bNumEP < 4)
|
if(bNumEP < 4)
|
||||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer
|
// Assign epInfo to epinfo pointer
|
||||||
|
@ -167,12 +167,12 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
rcode = pAsync->OnInit(this);
|
rcode = pAsync->OnInit(this);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailOnInit;
|
goto FailOnInit;
|
||||||
|
|
||||||
USBTRACE("ACM configured\r\n");
|
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;
|
uint8_t index;
|
||||||
|
|
||||||
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
||||||
index = epInterruptInIndex;
|
index = epInterruptInIndex;
|
||||||
else
|
else
|
||||||
if ((pep->bmAttributes & 0x02) == 2)
|
if((pep->bmAttributes & 0x02) == 2)
|
||||||
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
|
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
@ -264,7 +264,7 @@ uint8_t ACM::Release() {
|
||||||
uint8_t ACM::Poll() {
|
uint8_t ACM::Poll() {
|
||||||
uint8_t rcode = 0;
|
uint8_t rcode = 0;
|
||||||
|
|
||||||
if (!bPollEnable)
|
if(!bPollEnable)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//uint32_t time_now = millis();
|
//uint32_t time_now = millis();
|
||||||
|
|
5
cdcacm.h
5
cdcacm.h
|
@ -114,8 +114,7 @@ typedef struct {
|
||||||
uint8_t bDataBits; // Data bits (5, 6, 7, 8 or 16)
|
uint8_t bDataBits; // Data bits (5, 6, 7, 8 or 16)
|
||||||
} LINE_CODING;
|
} LINE_CODING;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
uint8_t bmRequestType; // 0xa1 for class-specific notifications
|
uint8_t bmRequestType; // 0xa1 for class-specific notifications
|
||||||
uint8_t bNotification;
|
uint8_t bNotification;
|
||||||
uint16_t wValue;
|
uint16_t wValue;
|
||||||
|
@ -167,7 +166,7 @@ public:
|
||||||
uint8_t GetLineCoding(LINE_CODING *dataptr);
|
uint8_t GetLineCoding(LINE_CODING *dataptr);
|
||||||
uint8_t SetControlLineState(uint8_t state);
|
uint8_t SetControlLineState(uint8_t state);
|
||||||
uint8_t SendBreak(uint16_t duration);
|
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
|
// Methods for recieving and sending data
|
||||||
uint8_t RcvData(uint16_t *nbytesptr, uint8_t *dataptr);
|
uint8_t RcvData(uint16_t *nbytesptr, uint8_t *dataptr);
|
||||||
|
|
56
cdcftdi.cpp
56
cdcftdi.cpp
|
@ -26,7 +26,7 @@ pUsb(p),
|
||||||
bAddress(0),
|
bAddress(0),
|
||||||
bNumEP(1),
|
bNumEP(1),
|
||||||
wFTDIType(0) {
|
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].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
|
@ -34,7 +34,7 @@ wFTDIType(0) {
|
||||||
//if (!i)
|
//if (!i)
|
||||||
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
||||||
}
|
}
|
||||||
if (pUsb)
|
if(pUsb)
|
||||||
pUsb->RegisterDeviceClass(this);
|
pUsb->RegisterDeviceClass(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,16 +56,16 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
USBTRACE("FTDI Init\r\n");
|
USBTRACE("FTDI Init\r\n");
|
||||||
|
|
||||||
if (bAddress)
|
if(bAddress)
|
||||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||||
|
|
||||||
// Get pointer to pseudo device with address 0 assigned
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
p = addrPool.GetUsbDevicePtr(0);
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
if (!p->epinfo) {
|
if(!p->epinfo) {
|
||||||
USBTRACE("epinfo\r\n");
|
USBTRACE("epinfo\r\n");
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
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
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetDevDescr;
|
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;
|
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
// Save type of FTDI chip
|
// 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
|
// Allocate new address according to device class
|
||||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||||
|
|
||||||
if (!bAddress)
|
if(!bAddress)
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
// Extract Max Packet Size from the device descriptor
|
// 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
|
// Assign new address to the device
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
rcode = pUsb->setAddr(0, 0, bAddress);
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
@ -118,7 +118,7 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
p->lowspeed = lowspeed;
|
p->lowspeed = lowspeed;
|
||||||
|
@ -128,30 +128,30 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Assign epInfo to epinfo pointer
|
// Assign epInfo to epinfo pointer
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
USBTRACE2("NC:", num_of_conf);
|
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;
|
HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
|
||||||
ConfigDescParser < 0xFF, 0xFF, 0xFF, CP_MASK_COMPARE_ALL> confDescrParser(this);
|
ConfigDescParser < 0xFF, 0xFF, 0xFF, CP_MASK_COMPARE_ALL> confDescrParser(this);
|
||||||
|
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
|
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
|
|
||||||
if (bNumEP > 1)
|
if(bNumEP > 1)
|
||||||
break;
|
break;
|
||||||
} // for
|
} // for
|
||||||
|
|
||||||
if (bNumEP < 2)
|
if(bNumEP < 2)
|
||||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
USBTRACE2("NumEP:", bNumEP);
|
USBTRACE2("NumEP:", bNumEP);
|
||||||
|
@ -164,12 +164,12 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
rcode = pAsync->OnInit(this);
|
rcode = pAsync->OnInit(this);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailOnInit;
|
goto FailOnInit;
|
||||||
|
|
||||||
USBTRACE("FTDI configured\r\n");
|
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;
|
uint8_t index;
|
||||||
|
|
||||||
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
||||||
index = epInterruptInIndex;
|
index = epInterruptInIndex;
|
||||||
else
|
else
|
||||||
if ((pep->bmAttributes & 0x02) == 2)
|
if((pep->bmAttributes & 0x02) == 2)
|
||||||
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
|
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
@ -270,19 +270,19 @@ uint8_t FTDI::SetBaudRate(uint32_t baud) {
|
||||||
|
|
||||||
divisor3 = 48000000 / 2 / baud; // divisor shifted 3 bits to the left
|
divisor3 = 48000000 / 2 / baud; // divisor shifted 3 bits to the left
|
||||||
|
|
||||||
if (wFTDIType == FT232AM) {
|
if(wFTDIType == FT232AM) {
|
||||||
if ((divisor3 & 0x7) == 7)
|
if((divisor3 & 0x7) == 7)
|
||||||
divisor3++; // round x.7/8 up to x+1
|
divisor3++; // round x.7/8 up to x+1
|
||||||
|
|
||||||
baud_value = divisor3 >> 3;
|
baud_value = divisor3 >> 3;
|
||||||
divisor3 &= 0x7;
|
divisor3 &= 0x7;
|
||||||
|
|
||||||
if (divisor3 == 1) baud_value |= 0xc000;
|
if(divisor3 == 1) baud_value |= 0xc000;
|
||||||
else // 0.125
|
else // 0.125
|
||||||
if (divisor3 >= 4) baud_value |= 0x4000;
|
if(divisor3 >= 4) baud_value |= 0x4000;
|
||||||
else // 0.5
|
else // 0.5
|
||||||
if (divisor3 != 0) baud_value |= 0x8000; // 0.25
|
if(divisor3 != 0) baud_value |= 0x8000; // 0.25
|
||||||
if (baud_value == 1) baud_value = 0; /* special case for maximum baud rate */
|
if(baud_value == 1) baud_value = 0; /* special case for maximum baud rate */
|
||||||
} else {
|
} else {
|
||||||
static const unsigned char divfrac [8] = {0, 3, 2, 0, 1, 1, 2, 3};
|
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};
|
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];
|
baud_index = divindex[divisor3 & 0x7];
|
||||||
|
|
||||||
/* Deal with special cases for highest baud rates. */
|
/* 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
|
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_value:", baud_value);
|
||||||
USBTRACE2("baud_index:", baud_index);
|
USBTRACE2("baud_index:", baud_index);
|
||||||
|
|
|
@ -35,16 +35,16 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
USBTRACE("PL Init\r\n");
|
USBTRACE("PL Init\r\n");
|
||||||
|
|
||||||
if (bAddress)
|
if(bAddress)
|
||||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||||
|
|
||||||
// Get pointer to pseudo device with address 0 assigned
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
p = addrPool.GetUsbDevicePtr(0);
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
if (!p->epinfo) {
|
if(!p->epinfo) {
|
||||||
USBTRACE("epinfo\r\n");
|
USBTRACE("epinfo\r\n");
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
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
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetDevDescr;
|
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;
|
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
// Save type of PL chip
|
// 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
|
// Allocate new address according to device class
|
||||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||||
|
|
||||||
if (!bAddress)
|
if(!bAddress)
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
// Extract Max Packet Size from the device descriptor
|
// 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
|
// Assign new address to the device
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
rcode = pUsb->setAddr(0, 0, bAddress);
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
@ -98,7 +98,7 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
p->lowspeed = lowspeed;
|
p->lowspeed = lowspeed;
|
||||||
|
@ -108,30 +108,30 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Assign epInfo to epinfo pointer
|
// Assign epInfo to epinfo pointer
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
USBTRACE2("NC:", num_of_conf);
|
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;
|
HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
|
||||||
ConfigDescParser < 0xFF, 0, 0, CP_MASK_COMPARE_CLASS> confDescrParser(this);
|
ConfigDescParser < 0xFF, 0, 0, CP_MASK_COMPARE_CLASS> confDescrParser(this);
|
||||||
|
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
|
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
|
|
||||||
if (bNumEP > 1)
|
if(bNumEP > 1)
|
||||||
break;
|
break;
|
||||||
} // for
|
} // for
|
||||||
|
|
||||||
if (bNumEP < 2)
|
if(bNumEP < 2)
|
||||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer
|
// Assign epInfo to epinfo pointer
|
||||||
|
@ -142,12 +142,12 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
rcode = pAsync->OnInit(this);
|
rcode = pAsync->OnInit(this);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailOnInit;
|
goto FailOnInit;
|
||||||
|
|
||||||
USBTRACE("PL configured\r\n");
|
USBTRACE("PL configured\r\n");
|
||||||
|
@ -208,5 +208,3 @@ Fail:
|
||||||
// //}
|
// //}
|
||||||
// return rcode;
|
// return rcode;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,10 @@ class ConfigDescParser : public USBReadParser {
|
||||||
void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
|
void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void SetOR(void) { UseOr = true; }
|
|
||||||
|
void SetOR(void) {
|
||||||
|
UseOr = true;
|
||||||
|
}
|
||||||
ConfigDescParser(UsbConfigXtracter *xtractor);
|
ConfigDescParser(UsbConfigXtracter *xtractor);
|
||||||
virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset);
|
virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset);
|
||||||
};
|
};
|
||||||
|
@ -75,11 +78,10 @@ UseOr(false) {
|
||||||
theSkipper.Initialize(&theBuffer);
|
theSkipper.Initialize(&theBuffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
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) {
|
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;
|
uint16_t cntdn = (uint16_t)len;
|
||||||
uint8_t *p = (uint8_t*) pbuf;
|
uint8_t *p = (uint8_t*)pbuf;
|
||||||
|
|
||||||
while(cntdn)
|
while(cntdn)
|
||||||
if(!ParseDescriptor(&p, &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 */
|
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>
|
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) {
|
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_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR*>(varBuffer);
|
||||||
USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*> (varBuffer);
|
USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*>(varBuffer);
|
||||||
switch(stateParseDescr) {
|
switch(stateParseDescr) {
|
||||||
case 0:
|
case 0:
|
||||||
theBuffer.valueSize = 2;
|
theBuffer.valueSize = 2;
|
||||||
|
@ -100,8 +102,8 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
|
||||||
case 1:
|
case 1:
|
||||||
if(!valParser.Parse(pp, pcntdn))
|
if(!valParser.Parse(pp, pcntdn))
|
||||||
return false;
|
return false;
|
||||||
dscrLen = *((uint8_t*) theBuffer.pValue);
|
dscrLen = *((uint8_t*)theBuffer.pValue);
|
||||||
dscrType = *((uint8_t*) theBuffer.pValue + 1);
|
dscrType = *((uint8_t*)theBuffer.pValue + 1);
|
||||||
stateParseDescr = 2;
|
stateParseDescr = 2;
|
||||||
case 2:
|
case 2:
|
||||||
// This is a sort of hack. Assuming that two bytes are all ready in the buffer
|
// 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:
|
case USB_DESCRIPTOR_INTERFACE:
|
||||||
isGoodInterface = false;
|
isGoodInterface = false;
|
||||||
case USB_DESCRIPTOR_CONFIGURATION:
|
case USB_DESCRIPTOR_CONFIGURATION:
|
||||||
theBuffer.valueSize = sizeof(USB_CONFIGURATION_DESCRIPTOR) - 2;
|
theBuffer.valueSize = sizeof (USB_CONFIGURATION_DESCRIPTOR) - 2;
|
||||||
break;
|
break;
|
||||||
case USB_DESCRIPTOR_ENDPOINT:
|
case USB_DESCRIPTOR_ENDPOINT:
|
||||||
theBuffer.valueSize = sizeof(USB_ENDPOINT_DESCRIPTOR) - 2;
|
theBuffer.valueSize = sizeof (USB_ENDPOINT_DESCRIPTOR) - 2;
|
||||||
break;
|
break;
|
||||||
case HID_DESCRIPTOR_HID:
|
case HID_DESCRIPTOR_HID:
|
||||||
theBuffer.valueSize = dscrLen - 2;
|
theBuffer.valueSize = dscrLen - 2;
|
||||||
|
@ -158,7 +160,7 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
|
||||||
return false;
|
return false;
|
||||||
if(isGoodInterface)
|
if(isGoodInterface)
|
||||||
if(theXtractor)
|
if(theXtractor)
|
||||||
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*) varBuffer);
|
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer);
|
||||||
break;
|
break;
|
||||||
//case HID_DESCRIPTOR_HID:
|
//case HID_DESCRIPTOR_HID:
|
||||||
// if (!valParser.Parse(pp, pcntdn))
|
// if (!valParser.Parse(pp, pcntdn))
|
||||||
|
|
3
hid.cpp
3
hid.cpp
|
@ -1,6 +1,7 @@
|
||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
|
|
||||||
//get HID report descriptor
|
//get HID report descriptor
|
||||||
|
|
||||||
/* WRONG! Endpoint is _ALWAYS_ ZERO for HID! We want the _INTERFACE_ value here!
|
/* WRONG! Endpoint is _ALWAYS_ ZERO for HID! We want the _INTERFACE_ value here!
|
||||||
uint8_t HID::GetReportDescr(uint8_t ep, USBReadParser *parser) {
|
uint8_t HID::GetReportDescr(uint8_t ep, USBReadParser *parser) {
|
||||||
const uint8_t constBufLen = 64;
|
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 != hrSTALL) ? rcode : 0);
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
uint8_t HID::GetReportDescr(uint16_t wIndex, USBReadParser *parser) {
|
uint8_t HID::GetReportDescr(uint16_t wIndex, USBReadParser *parser) {
|
||||||
const uint8_t constBufLen = 64;
|
const uint8_t constBufLen = 64;
|
||||||
uint8_t buf[constBufLen];
|
uint8_t buf[constBufLen];
|
||||||
|
|
1
hid.h
1
hid.h
|
@ -140,7 +140,6 @@ public:
|
||||||
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) = 0;
|
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class HID : public USBDeviceConfig, public UsbConfigXtracter {
|
class HID : public USBDeviceConfig, public UsbConfigXtracter {
|
||||||
protected:
|
protected:
|
||||||
USB *pUsb; // USB class instance pointer
|
USB *pUsb; // USB class instance pointer
|
||||||
|
|
|
@ -980,7 +980,7 @@ void ReportDescParserBase::Parse(const uint16_t len, const uint8_t *pbuf, const
|
||||||
|
|
||||||
totalSize = 0;
|
totalSize = 0;
|
||||||
|
|
||||||
while (cntdn) {
|
while(cntdn) {
|
||||||
//USB_HOST_SERIAL.println("");
|
//USB_HOST_SERIAL.println("");
|
||||||
//PrintHex<uint16_t>(offset + len - cntdn);
|
//PrintHex<uint16_t>(offset + len - cntdn);
|
||||||
//USB_HOST_SERIAL.print(":");
|
//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) {
|
void ReportDescParserBase::PrintValue(uint8_t *p, uint8_t len) {
|
||||||
E_Notify(PSTR("("), 0x80);
|
E_Notify(PSTR("("), 0x80);
|
||||||
for (; len; p++, len--)
|
for(; len; p++, len--)
|
||||||
PrintHex<uint8_t > (*p, 0x80);
|
PrintHex<uint8_t > (*p, 0x80);
|
||||||
E_Notify(PSTR(")"), 0x80);
|
E_Notify(PSTR(")"), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -1007,7 +1007,7 @@ void ReportDescParserBase::PrintByteValue(uint8_t data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReportDescParserBase::PrintItemTitle(uint8_t prefix) {
|
void ReportDescParserBase::PrintItemTitle(uint8_t prefix) {
|
||||||
switch (prefix & (TYPE_MASK | TAG_MASK)) {
|
switch(prefix & (TYPE_MASK | TAG_MASK)) {
|
||||||
case (TYPE_GLOBAL | TAG_GLOBAL_PUSH):
|
case (TYPE_GLOBAL | TAG_GLOBAL_PUSH):
|
||||||
E_Notify(PSTR("\r\nPush"), 0x80);
|
E_Notify(PSTR("\r\nPush"), 0x80);
|
||||||
break;
|
break;
|
||||||
|
@ -1074,9 +1074,9 @@ void ReportDescParserBase::PrintItemTitle(uint8_t prefix) {
|
||||||
uint8_t ReportDescParserBase::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
|
uint8_t ReportDescParserBase::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
|
||||||
//uint8_t ret = enErrorSuccess;
|
//uint8_t ret = enErrorSuccess;
|
||||||
//reinterpret_cast<>(varBuffer);
|
//reinterpret_cast<>(varBuffer);
|
||||||
switch (itemParseState) {
|
switch(itemParseState) {
|
||||||
case 0:
|
case 0:
|
||||||
if (**pp == HID_LONG_ITEM_PREFIX)
|
if(**pp == HID_LONG_ITEM_PREFIX)
|
||||||
USBTRACE("\r\nLONG\r\n");
|
USBTRACE("\r\nLONG\r\n");
|
||||||
else {
|
else {
|
||||||
uint8_t size = ((**pp) & DATA_SIZE_MASK);
|
uint8_t size = ((**pp) & DATA_SIZE_MASK);
|
||||||
|
@ -1091,10 +1091,10 @@ switch (itemParseState) {
|
||||||
itemSize--;
|
itemSize--;
|
||||||
itemParseState = 1;
|
itemParseState = 1;
|
||||||
|
|
||||||
if (!itemSize)
|
if(!itemSize)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!pcntdn)
|
if(!pcntdn)
|
||||||
return enErrorIncomplete;
|
return enErrorIncomplete;
|
||||||
case 1:
|
case 1:
|
||||||
//USBTRACE2("\r\niSz:",itemSize);
|
//USBTRACE2("\r\niSz:",itemSize);
|
||||||
|
@ -1103,17 +1103,17 @@ switch (itemParseState) {
|
||||||
valParser.Initialize(&theBuffer);
|
valParser.Initialize(&theBuffer);
|
||||||
itemParseState = 2;
|
itemParseState = 2;
|
||||||
case 2:
|
case 2:
|
||||||
if (!valParser.Parse(pp, pcntdn))
|
if(!valParser.Parse(pp, pcntdn))
|
||||||
return enErrorIncomplete;
|
return enErrorIncomplete;
|
||||||
itemParseState = 3;
|
itemParseState = 3;
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
uint8_t data = *((uint8_t*)varBuffer);
|
uint8_t data = *((uint8_t*)varBuffer);
|
||||||
|
|
||||||
switch (itemPrefix & (TYPE_MASK | TAG_MASK)) {
|
switch(itemPrefix & (TYPE_MASK | TAG_MASK)) {
|
||||||
case (TYPE_LOCAL | TAG_LOCAL_USAGE):
|
case (TYPE_LOCAL | TAG_LOCAL_USAGE):
|
||||||
if (pfUsage) {
|
if(pfUsage) {
|
||||||
if (theBuffer.valueSize > 1) {
|
if(theBuffer.valueSize > 1) {
|
||||||
uint16_t* ui16 = reinterpret_cast<uint16_t *>(varBuffer);
|
uint16_t* ui16 = reinterpret_cast<uint16_t *>(varBuffer);
|
||||||
pfUsage(*ui16);
|
pfUsage(*ui16);
|
||||||
} else
|
} else
|
||||||
|
@ -1149,7 +1149,7 @@ switch (itemParseState) {
|
||||||
break;
|
break;
|
||||||
case (TYPE_MAIN | TAG_MAIN_COLLECTION):
|
case (TYPE_MAIN | TAG_MAIN_COLLECTION):
|
||||||
case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION):
|
case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION):
|
||||||
switch (data) {
|
switch(data) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
E_Notify(PSTR(" Physical"), 0x80);
|
E_Notify(PSTR(" Physical"), 0x80);
|
||||||
break;
|
break;
|
||||||
|
@ -1216,7 +1216,7 @@ ReportDescParserBase::UsagePageFunc ReportDescParserBase::usagePageFunctions[] /
|
||||||
void ReportDescParserBase::SetUsagePage(uint16_t page) {
|
void ReportDescParserBase::SetUsagePage(uint16_t page) {
|
||||||
pfUsage = NULL;
|
pfUsage = NULL;
|
||||||
|
|
||||||
if (VALUE_BETWEEN(page, 0x00, 0x11))
|
if(VALUE_BETWEEN(page, 0x00, 0x11))
|
||||||
pfUsage = (usagePageFunctions[page - 1]);
|
pfUsage = (usagePageFunctions[page - 1]);
|
||||||
|
|
||||||
// Dead code...
|
// Dead code...
|
||||||
|
@ -1232,7 +1232,7 @@ void ReportDescParserBase::SetUsagePage(uint16_t page) {
|
||||||
// E_Notify(pstrUsagePageVendorDefined);
|
// E_Notify(pstrUsagePageVendorDefined);
|
||||||
//
|
//
|
||||||
else
|
else
|
||||||
switch (page) {
|
switch(page) {
|
||||||
case 0x14:
|
case 0x14:
|
||||||
pfUsage = &ReportDescParserBase::PrintAlphanumDisplayPageUsage;
|
pfUsage = &ReportDescParserBase::PrintAlphanumDisplayPageUsage;
|
||||||
break;
|
break;
|
||||||
|
@ -1248,14 +1248,14 @@ void ReportDescParserBase::PrintUsagePage(uint16_t page) {
|
||||||
|
|
||||||
output_if_between(page, 0x00, 0x11, w, E_Notify, usagePageTitles0, 0x80)
|
output_if_between(page, 0x00, 0x11, w, E_Notify, usagePageTitles0, 0x80)
|
||||||
else output_if_between(page, 0x8b, 0x92, w, E_Notify, usagePageTitles1, 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);
|
E_Notify(pstrUsagePageMonitor, 0x80);
|
||||||
else if (VALUE_BETWEEN(page, 0x83, 0x8c))
|
else if(VALUE_BETWEEN(page, 0x83, 0x8c))
|
||||||
E_Notify(pstrUsagePagePower, 0x80);
|
E_Notify(pstrUsagePagePower, 0x80);
|
||||||
else if (page > 0xfeff /* && page <= 0xffff */)
|
else if(page > 0xfeff /* && page <= 0xffff */)
|
||||||
E_Notify(pstrUsagePageVendorDefined, 0x80);
|
E_Notify(pstrUsagePageVendorDefined, 0x80);
|
||||||
else
|
else
|
||||||
switch (page) {
|
switch(page) {
|
||||||
case 0x14:
|
case 0x14:
|
||||||
E_Notify(pstrUsagePageAlphaNumericDisplay, 0x80);
|
E_Notify(pstrUsagePageAlphaNumericDisplay, 0x80);
|
||||||
break;
|
break;
|
||||||
|
@ -1409,8 +1409,8 @@ void ReportDescParserBase::PrintMedicalInstrumentPageUsage(uint16_t usage) {
|
||||||
const char * const * w;
|
const char * const * w;
|
||||||
E_Notify(pstrSpace, 0x80);
|
E_Notify(pstrSpace, 0x80);
|
||||||
|
|
||||||
if (usage == 1) E_Notify(pstrUsageMedicalUltrasound, 0x80);
|
if(usage == 1) E_Notify(pstrUsageMedicalUltrasound, 0x80);
|
||||||
else if (usage == 0x70)
|
else if(usage == 0x70)
|
||||||
E_Notify(pstrUsageDepthGainCompensation, 0x80);
|
E_Notify(pstrUsageDepthGainCompensation, 0x80);
|
||||||
else output_if_between(usage, 0x1f, 0x28, w, E_Notify, medInstrTitles0, 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)
|
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 ReportDescParser2::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
|
||||||
//uint8_t ret = enErrorSuccess;
|
//uint8_t ret = enErrorSuccess;
|
||||||
|
|
||||||
switch (itemParseState) {
|
switch(itemParseState) {
|
||||||
case 0:
|
case 0:
|
||||||
if (**pp == HID_LONG_ITEM_PREFIX)
|
if(**pp == HID_LONG_ITEM_PREFIX)
|
||||||
USBTRACE("\r\nLONG\r\n");
|
USBTRACE("\r\nLONG\r\n");
|
||||||
else {
|
else {
|
||||||
uint8_t size = ((**pp) & DATA_SIZE_MASK);
|
uint8_t size = ((**pp) & DATA_SIZE_MASK);
|
||||||
|
@ -1437,27 +1437,27 @@ uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
|
||||||
itemSize--;
|
itemSize--;
|
||||||
itemParseState = 1;
|
itemParseState = 1;
|
||||||
|
|
||||||
if (!itemSize)
|
if(!itemSize)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!pcntdn)
|
if(!pcntdn)
|
||||||
return enErrorIncomplete;
|
return enErrorIncomplete;
|
||||||
case 1:
|
case 1:
|
||||||
theBuffer.valueSize = itemSize;
|
theBuffer.valueSize = itemSize;
|
||||||
valParser.Initialize(&theBuffer);
|
valParser.Initialize(&theBuffer);
|
||||||
itemParseState = 2;
|
itemParseState = 2;
|
||||||
case 2:
|
case 2:
|
||||||
if (!valParser.Parse(pp, pcntdn))
|
if(!valParser.Parse(pp, pcntdn))
|
||||||
return enErrorIncomplete;
|
return enErrorIncomplete;
|
||||||
itemParseState = 3;
|
itemParseState = 3;
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
uint8_t data = *((uint8_t*)varBuffer);
|
uint8_t data = *((uint8_t*)varBuffer);
|
||||||
|
|
||||||
switch (itemPrefix & (TYPE_MASK | TAG_MASK)) {
|
switch(itemPrefix & (TYPE_MASK | TAG_MASK)) {
|
||||||
case (TYPE_LOCAL | TAG_LOCAL_USAGE):
|
case (TYPE_LOCAL | TAG_LOCAL_USAGE):
|
||||||
if (pfUsage) {
|
if(pfUsage) {
|
||||||
if (theBuffer.valueSize > 1) {
|
if(theBuffer.valueSize > 1) {
|
||||||
uint16_t* ui16 = reinterpret_cast<uint16_t *>(varBuffer);
|
uint16_t* ui16 = reinterpret_cast<uint16_t *>(varBuffer);
|
||||||
pfUsage(*ui16);
|
pfUsage(*ui16);
|
||||||
} else
|
} else
|
||||||
|
@ -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 bit_offset = totalSize - tmp; // number of bits in the current byte already handled
|
||||||
uint8_t *p = pBuf + byte_offset; // current byte pointer
|
uint8_t *p = pBuf + byte_offset; // current byte pointer
|
||||||
|
|
||||||
if (bit_offset)
|
if(bit_offset)
|
||||||
*p >>= bit_offset;
|
*p >>= bit_offset;
|
||||||
|
|
||||||
uint8_t usage = useMin;
|
uint8_t usage = useMin;
|
||||||
|
@ -1522,7 +1522,7 @@ void ReportDescParser2::OnInputItem(uint8_t itm) {
|
||||||
uint8_t bits_of_byte = 8;
|
uint8_t bits_of_byte = 8;
|
||||||
|
|
||||||
// for each field in field array defined by rptCount
|
// 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 {
|
union {
|
||||||
uint8_t bResult[4];
|
uint8_t bResult[4];
|
||||||
|
@ -1533,7 +1533,7 @@ void ReportDescParser2::OnInputItem(uint8_t itm) {
|
||||||
result.dwResult = 0;
|
result.dwResult = 0;
|
||||||
uint8_t mask = 0;
|
uint8_t mask = 0;
|
||||||
|
|
||||||
if (print_usemin_usemax)
|
if(print_usemin_usemax)
|
||||||
pfUsage(usage);
|
pfUsage(usage);
|
||||||
|
|
||||||
// bits_left - number of bits in the field(array of fields, depending on Report Count) left to process
|
// 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
|
// bits_to_copy - number of bits to copy to result buffer
|
||||||
|
|
||||||
// for each bit in a field
|
// 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_left -= bits_to_copy) {
|
||||||
bits_to_copy = (bits_left > bits_of_byte) ? bits_of_byte : bits_left;
|
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;
|
mask = 0;
|
||||||
|
|
||||||
for (uint8_t j = bits_to_copy; j; j--) {
|
for(uint8_t j = bits_to_copy; j; j--) {
|
||||||
mask <<= 1;
|
mask <<= 1;
|
||||||
mask |= 1;
|
mask |= 1;
|
||||||
}
|
}
|
||||||
|
@ -1562,7 +1562,7 @@ void ReportDescParser2::OnInputItem(uint8_t itm) {
|
||||||
|
|
||||||
bits_of_byte -= bits_to_copy;
|
bits_of_byte -= bits_to_copy;
|
||||||
|
|
||||||
if (bits_of_byte < 1) {
|
if(bits_of_byte < 1) {
|
||||||
bits_of_byte = 8;
|
bits_of_byte = 8;
|
||||||
p++;
|
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);
|
uint8_t ret = hid->GetReportDescr(0, &prs);
|
||||||
|
|
||||||
if (ret)
|
if(ret)
|
||||||
ErrorMessage<uint8_t > (PSTR("GetReportDescr-2"), ret);
|
ErrorMessage<uint8_t > (PSTR("GetReportDescr-2"), ret);
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ protected:
|
||||||
MultiValueBuffer theBuffer;
|
MultiValueBuffer theBuffer;
|
||||||
MultiByteValueParser valParser;
|
MultiByteValueParser valParser;
|
||||||
ByteSkipper theSkipper;
|
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 itemParseState; // Item parser state variable
|
||||||
uint8_t itemSize; // Item size
|
uint8_t itemSize; // Item size
|
||||||
|
@ -126,8 +126,7 @@ public:
|
||||||
itemPrefix(0),
|
itemPrefix(0),
|
||||||
rptSize(0),
|
rptSize(0),
|
||||||
rptCount(0),
|
rptCount(0),
|
||||||
pfUsage(NULL)
|
pfUsage(NULL) {
|
||||||
{
|
|
||||||
theBuffer.pValue = varBuffer;
|
theBuffer.pValue = varBuffer;
|
||||||
valParser.Initialize(&theBuffer);
|
valParser.Initialize(&theBuffer);
|
||||||
theSkipper.Initialize(&theBuffer);
|
theSkipper.Initialize(&theBuffer);
|
||||||
|
|
104
hiduniversal.cpp
104
hiduniversal.cpp
|
@ -7,14 +7,14 @@ bPollEnable(false),
|
||||||
bHasReportId(false) {
|
bHasReportId(false) {
|
||||||
Initialize();
|
Initialize();
|
||||||
|
|
||||||
if (pUsb)
|
if(pUsb)
|
||||||
pUsb->RegisterDeviceClass(this);
|
pUsb->RegisterDeviceClass(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t HIDUniversal::GetHidClassDescrLen(uint8_t type, uint8_t num) {
|
uint16_t HIDUniversal::GetHidClassDescrLen(uint8_t type, uint8_t num) {
|
||||||
for (uint8_t i = 0, n = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
|
for(uint8_t i = 0, n = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
|
||||||
if (descrInfo[i].bDescrType == type) {
|
if(descrInfo[i].bDescrType == type) {
|
||||||
if (n == num)
|
if(n == num)
|
||||||
return descrInfo[i].wDescriptorLength;
|
return descrInfo[i].wDescriptorLength;
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
@ -23,22 +23,22 @@ uint16_t HIDUniversal::GetHidClassDescrLen(uint8_t type, uint8_t num) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HIDUniversal::Initialize() {
|
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].rptId = 0;
|
||||||
rptParsers[i].rptParser = NULL;
|
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].bDescrType = 0;
|
||||||
descrInfo[i].wDescriptorLength = 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].bmInterface = 0;
|
||||||
hidInterfaces[i].bmProtocol = 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;
|
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].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
|
@ -52,8 +52,8 @@ void HIDUniversal::Initialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HIDUniversal::SetReportParser(uint8_t id, HIDReportParser *prs) {
|
bool HIDUniversal::SetReportParser(uint8_t id, HIDReportParser *prs) {
|
||||||
for (uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
|
for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
|
||||||
if (rptParsers[i].rptId == 0 && rptParsers[i].rptParser == NULL) {
|
if(rptParsers[i].rptId == 0 && rptParsers[i].rptParser == NULL) {
|
||||||
rptParsers[i].rptId = id;
|
rptParsers[i].rptId = id;
|
||||||
rptParsers[i].rptParser = prs;
|
rptParsers[i].rptParser = prs;
|
||||||
return true;
|
return true;
|
||||||
|
@ -63,11 +63,11 @@ bool HIDUniversal::SetReportParser(uint8_t id, HIDReportParser *prs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HIDReportParser* HIDUniversal::GetReportParser(uint8_t id) {
|
HIDReportParser* HIDUniversal::GetReportParser(uint8_t id) {
|
||||||
if (!bHasReportId)
|
if(!bHasReportId)
|
||||||
return ((rptParsers[0].rptParser) ? rptParsers[0].rptParser : NULL);
|
return ((rptParsers[0].rptParser) ? rptParsers[0].rptParser : NULL);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
|
for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
|
||||||
if (rptParsers[i].rptId == id)
|
if(rptParsers[i].rptId == id)
|
||||||
return rptParsers[i].rptParser;
|
return rptParsers[i].rptParser;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -90,16 +90,16 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
USBTRACE("HU Init\r\n");
|
USBTRACE("HU Init\r\n");
|
||||||
|
|
||||||
if (bAddress)
|
if(bAddress)
|
||||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||||
|
|
||||||
// Get pointer to pseudo device with address 0 assigned
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
p = addrPool.GetUsbDevicePtr(0);
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
if (!p->epinfo) {
|
if(!p->epinfo) {
|
||||||
USBTRACE("epinfo\r\n");
|
USBTRACE("epinfo\r\n");
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
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
|
// Get device descriptor
|
||||||
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
|
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
|
||||||
|
|
||||||
if (!rcode)
|
if(!rcode)
|
||||||
len = (buf[0] > constBufSize) ? constBufSize : buf[0];
|
len = (buf[0] > constBufSize) ? constBufSize : buf[0];
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
// Restore p->epinfo
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
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
|
// Allocate new address according to device class
|
||||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||||
|
|
||||||
if (!bAddress)
|
if(!bAddress)
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
// Extract Max Packet Size from the device descriptor
|
// 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
|
// Assign new address to the device
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
rcode = pUsb->setAddr(0, 0, bAddress);
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
@ -156,15 +156,15 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
p->lowspeed = lowspeed;
|
p->lowspeed = lowspeed;
|
||||||
|
|
||||||
if (len)
|
if(len)
|
||||||
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
|
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
|
|
||||||
num_of_conf = udd->bNumConfigurations;
|
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
|
// Assign epInfo to epinfo pointer
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
USBTRACE2("NC:", num_of_conf);
|
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;
|
//HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
|
||||||
ConfigDescParser<USB_CLASS_HID, 0, 0,
|
ConfigDescParser<USB_CLASS_HID, 0, 0,
|
||||||
CP_MASK_COMPARE_CLASS> confDescrParser(this);
|
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, &HexDump);
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
|
|
||||||
if (bNumEP > 1)
|
if(bNumEP > 1)
|
||||||
break;
|
break;
|
||||||
} // for
|
} // for
|
||||||
|
|
||||||
if (bNumEP < 2)
|
if(bNumEP < 2)
|
||||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer
|
// Assign epInfo to epinfo pointer
|
||||||
|
@ -203,16 +203,16 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < bNumIface; i++) {
|
for(uint8_t i = 0; i < bNumIface; i++) {
|
||||||
if (hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
|
if(hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
|
rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
|
||||||
|
|
||||||
if (rcode && rcode != hrSTALL)
|
if(rcode && rcode != hrSTALL)
|
||||||
goto FailSetIdle;
|
goto FailSetIdle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,8 +262,8 @@ Fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
HIDUniversal::HIDInterface* HIDUniversal::FindInterface(uint8_t iface, uint8_t alt, uint8_t proto) {
|
HIDUniversal::HIDInterface* HIDUniversal::FindInterface(uint8_t iface, uint8_t alt, uint8_t proto) {
|
||||||
for (uint8_t i = 0; i < bNumIface && i < maxHidInterfaces; i++)
|
for(uint8_t i = 0; i < bNumIface && i < maxHidInterfaces; i++)
|
||||||
if (hidInterfaces[i].bmInterface == iface && hidInterfaces[i].bmAltSet == alt
|
if(hidInterfaces[i].bmInterface == iface && hidInterfaces[i].bmAltSet == alt
|
||||||
&& hidInterfaces[i].bmProtocol == proto)
|
&& hidInterfaces[i].bmProtocol == proto)
|
||||||
return hidInterfaces + i;
|
return hidInterfaces + i;
|
||||||
return NULL;
|
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) {
|
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 the first configuration satisfies, the others are not concidered.
|
||||||
if (bNumEP > 1 && conf != bConfNum)
|
if(bNumEP > 1 && conf != bConfNum)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
|
//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);
|
HIDInterface *piface = FindInterface(iface, alt, proto);
|
||||||
|
|
||||||
// Fill in interface structure in case of new interface
|
// Fill in interface structure in case of new interface
|
||||||
if (!piface) {
|
if(!piface) {
|
||||||
piface = hidInterfaces + bNumIface;
|
piface = hidInterfaces + bNumIface;
|
||||||
piface->bmInterface = iface;
|
piface->bmInterface = iface;
|
||||||
piface->bmAltSet = alt;
|
piface->bmAltSet = alt;
|
||||||
|
@ -292,12 +292,12 @@ void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint
|
||||||
bNumIface++;
|
bNumIface++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
||||||
index = epInterruptInIndex;
|
index = epInterruptInIndex;
|
||||||
else
|
else
|
||||||
index = epInterruptOutIndex;
|
index = epInterruptOutIndex;
|
||||||
|
|
||||||
if (index) {
|
if(index) {
|
||||||
// Fill in the endpoint info structure
|
// Fill in the endpoint info structure
|
||||||
epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
|
epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
|
||||||
epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
|
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) {
|
bool HIDUniversal::BuffersIdentical(uint8_t len, uint8_t *buf1, uint8_t *buf2) {
|
||||||
for (uint8_t i = 0; i < len; i++)
|
for(uint8_t i = 0; i < len; i++)
|
||||||
if (buf1[i] != buf2[i])
|
if(buf1[i] != buf2[i])
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HIDUniversal::ZeroMemory(uint8_t len, uint8_t *buf) {
|
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;
|
buf[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HIDUniversal::SaveBuffer(uint8_t len, uint8_t *src, uint8_t *dest) {
|
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];
|
dest[i] = src[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HIDUniversal::Poll() {
|
uint8_t HIDUniversal::Poll() {
|
||||||
uint8_t rcode = 0;
|
uint8_t rcode = 0;
|
||||||
|
|
||||||
if (!bPollEnable)
|
if(!bPollEnable)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (qNextPollTime <= millis()) {
|
if(qNextPollTime <= millis()) {
|
||||||
qNextPollTime = millis() + 50;
|
qNextPollTime = millis() + 50;
|
||||||
|
|
||||||
uint8_t buf[constBuffLen];
|
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];
|
uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
|
||||||
uint16_t read = (uint16_t)epInfo[index].maxPktSize;
|
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);
|
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf);
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
if (rcode != hrNAK)
|
if(rcode != hrNAK)
|
||||||
USBTRACE3("(hiduniversal.h) Poll:", rcode, 0x81);
|
USBTRACE3("(hiduniversal.h) Poll:", rcode, 0x81);
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read > constBuffLen)
|
if(read > constBuffLen)
|
||||||
read = constBuffLen;
|
read = constBuffLen;
|
||||||
|
|
||||||
bool identical = BuffersIdentical(read, buf, prevBuf);
|
bool identical = BuffersIdentical(read, buf, prevBuf);
|
||||||
|
|
||||||
SaveBuffer(read, buf, prevBuf);
|
SaveBuffer(read, buf, prevBuf);
|
||||||
|
|
||||||
if (identical)
|
if(identical)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Notify(PSTR("\r\nBuf: "), 0x80);
|
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);
|
D_PrintHex<uint8_t > (buf[i], 0x80);
|
||||||
|
|
||||||
Notify(PSTR("\r\n"), 0x80);
|
Notify(PSTR("\r\n"), 0x80);
|
||||||
|
|
||||||
HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0));
|
HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0));
|
||||||
|
|
||||||
if (prs)
|
if(prs)
|
||||||
prs->Parse(this, bHasReportId, (uint8_t)read, buf);
|
prs->Parse(this, bHasReportId, (uint8_t)read, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
macros.h
1
macros.h
|
@ -63,6 +63,7 @@
|
||||||
* Debug macros: Strings are stored in progmem (flash) instead of RAM.
|
* Debug macros: Strings are stored in progmem (flash) instead of RAM.
|
||||||
*/
|
*/
|
||||||
#define USBTRACE(s) (Notify(PSTR(s), 0x80))
|
#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 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))
|
#define USBTRACE3(s,r,l) (Notify(PSTR(s), l), D_PrintHex((r), l), Notify(PSTR("\r\n"), l))
|
||||||
|
|
||||||
|
|
216
masstorage.cpp
216
masstorage.cpp
|
@ -17,7 +17,7 @@ const uint8_t BulkOnly::epInterruptInIndex = 3;
|
||||||
* @return media capacity
|
* @return media capacity
|
||||||
*/
|
*/
|
||||||
uint32_t BulkOnly::GetCapacity(uint8_t lun) {
|
uint32_t BulkOnly::GetCapacity(uint8_t lun) {
|
||||||
if (LUNOk[lun])
|
if(LUNOk[lun])
|
||||||
return CurrentCapacity[lun];
|
return CurrentCapacity[lun];
|
||||||
return 0LU;
|
return 0LU;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ uint32_t BulkOnly::GetCapacity(uint8_t lun) {
|
||||||
* @return media sector size
|
* @return media sector size
|
||||||
*/
|
*/
|
||||||
uint16_t BulkOnly::GetSectorSize(uint8_t lun) {
|
uint16_t BulkOnly::GetSectorSize(uint8_t lun) {
|
||||||
if (LUNOk[lun])
|
if(LUNOk[lun])
|
||||||
return CurrentSectorSize[lun];
|
return CurrentSectorSize[lun];
|
||||||
return 0U;
|
return 0U;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ uint8_t BulkOnly::MediaCTL(uint8_t lun, uint8_t ctl) {
|
||||||
Notify(PSTR("-----------------\r\n"), 0x80);
|
Notify(PSTR("-----------------\r\n"), 0x80);
|
||||||
|
|
||||||
uint8_t rcode = MASS_ERR_UNIT_NOT_READY;
|
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);
|
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);
|
rcode = SCSITransaction6(&cdb, (uint16_t)0, NULL, (uint8_t)MASS_CMD_DIR_OUT);
|
||||||
} else {
|
} else {
|
||||||
|
@ -135,7 +135,7 @@ uint8_t BulkOnly::MediaCTL(uint8_t lun, uint8_t ctl) {
|
||||||
* @return 0 on success
|
* @return 0 on success
|
||||||
*/
|
*/
|
||||||
uint8_t BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf) {
|
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);
|
Notify(PSTR("\r\nRead LUN:\t"), 0x80);
|
||||||
D_PrintHex<uint8_t > (lun, 0x90);
|
D_PrintHex<uint8_t > (lun, 0x90);
|
||||||
Notify(PSTR("\r\nLBA:\t\t"), 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:
|
again:
|
||||||
uint8_t er = SCSITransaction10(&cdb, ((uint16_t)bsize * blocks), buf, (uint8_t)MASS_CMD_DIR_IN);
|
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);
|
MediaCTL(lun, 1);
|
||||||
delay(150);
|
delay(150);
|
||||||
if (!TestUnitReady(lun)) goto again;
|
if(!TestUnitReady(lun)) goto again;
|
||||||
}
|
}
|
||||||
return er;
|
return er;
|
||||||
}
|
}
|
||||||
|
@ -169,8 +169,8 @@ again:
|
||||||
* @return 0 on success
|
* @return 0 on success
|
||||||
*/
|
*/
|
||||||
uint8_t BulkOnly::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t * buf) {
|
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(!LUNOk[lun]) return MASS_ERR_NO_MEDIA;
|
||||||
if (!WriteOk[lun]) return MASS_ERR_WRITE_PROTECTED;
|
if(!WriteOk[lun]) return MASS_ERR_WRITE_PROTECTED;
|
||||||
Notify(PSTR("\r\nWrite LUN:\t"), 0x80);
|
Notify(PSTR("\r\nWrite LUN:\t"), 0x80);
|
||||||
D_PrintHex<uint8_t > (lun, 0x90);
|
D_PrintHex<uint8_t > (lun, 0x90);
|
||||||
Notify(PSTR("\r\nLBA:\t\t"), 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:
|
again:
|
||||||
uint8_t er = SCSITransaction10(&cdb, ((uint16_t)bsize * blocks), (void*)buf, (uint8_t)MASS_CMD_DIR_OUT);
|
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);
|
MediaCTL(lun, 1);
|
||||||
delay(150);
|
delay(150);
|
||||||
if (!TestUnitReady(lun)) goto again;
|
if(!TestUnitReady(lun)) goto again;
|
||||||
}
|
}
|
||||||
return er;
|
return er;
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ bPollEnable(false),
|
||||||
bLastUsbError(0) {
|
bLastUsbError(0) {
|
||||||
ClearAllEP();
|
ClearAllEP();
|
||||||
dCBWTag = 0;
|
dCBWTag = 0;
|
||||||
if (pUsb)
|
if(pUsb)
|
||||||
pUsb->RegisterDeviceClass(this);
|
pUsb->RegisterDeviceClass(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,17 +245,17 @@ uint8_t BulkOnly::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
AddressPool &addrPool = pUsb->GetAddressPool();
|
AddressPool &addrPool = pUsb->GetAddressPool();
|
||||||
|
|
||||||
|
|
||||||
if (bAddress)
|
if(bAddress)
|
||||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||||
|
|
||||||
// <TECHNICAL>
|
// <TECHNICAL>
|
||||||
// Get pointer to pseudo device with address 0 assigned
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
p = addrPool.GetUsbDevicePtr(0);
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
if (!p) {
|
if(!p) {
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p->epinfo) {
|
if(!p->epinfo) {
|
||||||
USBTRACE("epinfo\r\n");
|
USBTRACE("epinfo\r\n");
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
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
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
}
|
}
|
||||||
// Allocate new address according to device class
|
// Allocate new address according to device class
|
||||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||||
|
|
||||||
if (!bAddress)
|
if(!bAddress)
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
// Extract Max Packet Size from the device descriptor
|
// 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();
|
AddressPool &addrPool = pUsb->GetAddressPool();
|
||||||
UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress);
|
UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
// Assign new address to the device
|
// Assign new address to the device
|
||||||
delay(2000);
|
delay(2000);
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
rcode = pUsb->setAddr(0, 0, bAddress);
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
@ -336,7 +336,7 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
p->lowspeed = lowspeed;
|
p->lowspeed = lowspeed;
|
||||||
|
@ -344,12 +344,12 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Assign epInfo to epinfo pointer
|
// Assign epInfo to epinfo pointer
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
USBTRACE2("NC:", num_of_conf);
|
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,
|
ConfigDescParser< USB_CLASS_MASS_STORAGE,
|
||||||
MASS_SUBCLASS_SCSI,
|
MASS_SUBCLASS_SCSI,
|
||||||
MASS_PROTO_BBB,
|
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);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &BulkOnlyParser);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
|
|
||||||
if (bNumEP > 1)
|
if(bNumEP > 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bNumEP < 3)
|
if(bNumEP < 3)
|
||||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer
|
// Assign epInfo to epinfo pointer
|
||||||
|
@ -377,38 +377,38 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
//Linux does a 1sec delay after this.
|
//Linux does a 1sec delay after this.
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
rcode = GetMaxLUN(&bMaxLUN);
|
rcode = GetMaxLUN(&bMaxLUN);
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetMaxLUN;
|
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);
|
ErrorMessage<uint8_t > (PSTR("MaxLUN"), bMaxLUN);
|
||||||
|
|
||||||
delay(1000); // Delay a bit for slow firmware.
|
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;
|
InquiryResponse response;
|
||||||
rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response);
|
rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response);
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
ErrorMessage<uint8_t > (PSTR("Inquiry"), rcode);
|
ErrorMessage<uint8_t > (PSTR("Inquiry"), rcode);
|
||||||
} else {
|
} else {
|
||||||
#if 0
|
#if 0
|
||||||
printf("LUN %i `", lun);
|
printf("LUN %i `", lun);
|
||||||
uint8_t *buf = response.VendorID;
|
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("'\r\nQualifier %1.1X ", response.PeripheralQualifier);
|
||||||
printf("Device type %2.2X ", response.DeviceType);
|
printf("Device type %2.2X ", response.DeviceType);
|
||||||
printf("RMB %1.1X ", response.Removable);
|
printf("RMB %1.1X ", response.Removable);
|
||||||
printf("SSCS %1.1X ", response.SCCS);
|
printf("SSCS %1.1X ", response.SCCS);
|
||||||
uint8_t sv = response.Version;
|
uint8_t sv = response.Version;
|
||||||
printf("SCSI version %2.2X\r\nDevice conforms to ", sv);
|
printf("SCSI version %2.2X\r\nDevice conforms to ", sv);
|
||||||
switch (sv) {
|
switch(sv) {
|
||||||
case 0:
|
case 0:
|
||||||
printf("No specific");
|
printf("No specific");
|
||||||
break;
|
break;
|
||||||
|
@ -436,20 +436,20 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
printf(" standards.\r\n");
|
printf(" standards.\r\n");
|
||||||
#endif
|
#endif
|
||||||
uint8_t tries = 0xf0;
|
uint8_t tries = 0xf0;
|
||||||
while ((rcode = TestUnitReady(lun))) {
|
while((rcode = TestUnitReady(lun))) {
|
||||||
if (rcode == 0x08) break; // break on no media, this is OK to do.
|
if(rcode == 0x08) break; // break on no media, this is OK to do.
|
||||||
// try to lock media and spin up
|
// try to lock media and spin up
|
||||||
if (tries < 14) {
|
if(tries < 14) {
|
||||||
LockMedia(lun, 1);
|
LockMedia(lun, 1);
|
||||||
MediaCTL(lun, 1); // I actually have a USB stick that needs this!
|
MediaCTL(lun, 1); // I actually have a USB stick that needs this!
|
||||||
} else delay(2 * (tries + 1));
|
} else delay(2 * (tries + 1));
|
||||||
tries++;
|
tries++;
|
||||||
if (!tries) break;
|
if(!tries) break;
|
||||||
}
|
}
|
||||||
if (!rcode) {
|
if(!rcode) {
|
||||||
delay(1000);
|
delay(1000);
|
||||||
LUNOk[lun] = CheckLUN(lun);
|
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();
|
rcode = OnInit();
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailOnInit;
|
goto FailOnInit;
|
||||||
|
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
@ -489,11 +489,11 @@ FailGetMaxLUN:
|
||||||
goto Fail;
|
goto Fail;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#ifdef DEBUG_USB_HOST
|
//#ifdef DEBUG_USB_HOST
|
||||||
//FailInvalidSectorSize:
|
//FailInvalidSectorSize:
|
||||||
// USBTRACE("Sector Size is NOT VALID: ");
|
// USBTRACE("Sector Size is NOT VALID: ");
|
||||||
// goto Fail;
|
// goto Fail;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
#ifdef DEBUG_USB_HOST
|
#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;
|
uint8_t index;
|
||||||
|
|
||||||
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
||||||
index = epInterruptInIndex;
|
index = epInterruptInIndex;
|
||||||
else
|
else
|
||||||
if ((pep->bmAttributes & 0x02) == 2)
|
if((pep->bmAttributes & 0x02) == 2)
|
||||||
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
|
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
@ -570,35 +570,35 @@ uint8_t BulkOnly::Release() {
|
||||||
boolean BulkOnly::CheckLUN(uint8_t lun) {
|
boolean BulkOnly::CheckLUN(uint8_t lun) {
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
Capacity capacity;
|
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);
|
rcode = ReadCapacity10(lun, (uint8_t*)capacity.data);
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
//printf(">>>>>>>>>>>>>>>>ReadCapacity returned %i\r\n", rcode);
|
//printf(">>>>>>>>>>>>>>>>ReadCapacity returned %i\r\n", rcode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ErrorMessage<uint8_t > (PSTR(">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun);
|
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);
|
D_PrintHex<uint8_t > (capacity.data[i], 0x80);
|
||||||
Notify(PSTR("\r\n\r\n"), 0x80);
|
Notify(PSTR("\r\n\r\n"), 0x80);
|
||||||
// Only 512/1024/2048/4096 are valid values!
|
// Only 512/1024/2048/4096 are valid values!
|
||||||
uint32_t c = BMAKE32(capacity.data[4], capacity.data[5], capacity.data[6], capacity.data[7]);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
// Store capacity information.
|
// Store capacity information.
|
||||||
CurrentSectorSize[lun] = (uint16_t)(c); // & 0xFFFF);
|
CurrentSectorSize[lun] = (uint16_t)(c); // & 0xFFFF);
|
||||||
|
|
||||||
CurrentCapacity[lun] = BMAKE32(capacity.data[0], capacity.data[1], capacity.data[2], capacity.data[3]) + 1;
|
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
|
// 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);
|
ErrorMessage<uint8_t > (PSTR(">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
delay(20);
|
delay(20);
|
||||||
Page3F(lun);
|
Page3F(lun);
|
||||||
if (!TestUnitReady(lun)) return true;
|
if(!TestUnitReady(lun)) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,18 +608,18 @@ boolean BulkOnly::CheckLUN(uint8_t lun) {
|
||||||
* Scan for media change on all LUNs
|
* Scan for media change on all LUNs
|
||||||
*/
|
*/
|
||||||
void BulkOnly::CheckMedia() {
|
void BulkOnly::CheckMedia() {
|
||||||
for (uint8_t lun = 0; lun <= bMaxLUN; lun++) {
|
for(uint8_t lun = 0; lun <= bMaxLUN; lun++) {
|
||||||
if (TestUnitReady(lun)) {
|
if(TestUnitReady(lun)) {
|
||||||
LUNOk[lun] = false;
|
LUNOk[lun] = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!LUNOk[lun])
|
if(!LUNOk[lun])
|
||||||
LUNOk[lun] = CheckLUN(lun);
|
LUNOk[lun] = CheckLUN(lun);
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
printf("}}}}}}}}}}}}}}}}STATUS ");
|
printf("}}}}}}}}}}}}}}}}STATUS ");
|
||||||
for (uint8_t lun = 0; lun <= bMaxLUN; lun++) {
|
for(uint8_t lun = 0; lun <= bMaxLUN; lun++) {
|
||||||
if (LUNOk[lun])
|
if(LUNOk[lun])
|
||||||
printf("#");
|
printf("#");
|
||||||
else printf(".");
|
else printf(".");
|
||||||
}
|
}
|
||||||
|
@ -636,10 +636,10 @@ void BulkOnly::CheckMedia() {
|
||||||
uint8_t BulkOnly::Poll() {
|
uint8_t BulkOnly::Poll() {
|
||||||
//uint8_t rcode = 0;
|
//uint8_t rcode = 0;
|
||||||
|
|
||||||
if (!bPollEnable)
|
if(!bPollEnable)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (qNextPollTime <= millis()) {
|
if(qNextPollTime <= millis()) {
|
||||||
CheckMedia();
|
CheckMedia();
|
||||||
}
|
}
|
||||||
//rcode = 0;
|
//rcode = 0;
|
||||||
|
@ -664,7 +664,7 @@ uint8_t BulkOnly::Poll() {
|
||||||
uint8_t BulkOnly::GetMaxLUN(uint8_t *plun) {
|
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);
|
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;
|
*plun = 0;
|
||||||
|
|
||||||
return 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) {
|
uint8_t BulkOnly::TestUnitReady(uint8_t lun) {
|
||||||
//SetCurLUN(lun);
|
//SetCurLUN(lun);
|
||||||
if (!bAddress)
|
if(!bAddress)
|
||||||
return MASS_ERR_UNIT_NOT_READY;
|
return MASS_ERR_UNIT_NOT_READY;
|
||||||
|
|
||||||
Notify(PSTR("\r\nTestUnitReady\r\n"), 0x80);
|
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 BulkOnly::Page3F(uint8_t lun) {
|
||||||
uint8_t buf[192];
|
uint8_t buf[192];
|
||||||
for (int i = 0; i < 192; i++) {
|
for(int i = 0; i < 192; i++) {
|
||||||
buf[i] = 0x00;
|
buf[i] = 0x00;
|
||||||
}
|
}
|
||||||
WriteOk[lun] = true;
|
WriteOk[lun] = true;
|
||||||
uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
|
uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
|
||||||
if (!rc) {
|
if(!rc) {
|
||||||
WriteOk[lun] = ((buf[2] & 0x80) == 0);
|
WriteOk[lun] = ((buf[2] & 0x80) == 0);
|
||||||
Notify(PSTR("Mode Sense: "), 0x80);
|
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);
|
D_PrintHex<uint8_t > (buf[i], 0x80);
|
||||||
Notify(PSTR(" "), 0x80);
|
Notify(PSTR(" "), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -803,15 +803,15 @@ uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
|
uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
|
||||||
if (index == 0)
|
if(index == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint8_t ret = 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);
|
delay(6);
|
||||||
|
|
||||||
if (ret) {
|
if(ret) {
|
||||||
ErrorMessage<uint8_t > (PSTR("ClearEpHalt"), ret);
|
ErrorMessage<uint8_t > (PSTR("ClearEpHalt"), ret);
|
||||||
ErrorMessage<uint8_t > (PSTR("EP"), ((index == epDataInIndex) ? (0x80 | epInfo[index].epAddr) : epInfo[index].epAddr));
|
ErrorMessage<uint8_t > (PSTR("EP"), ((index == epDataInIndex) ? (0x80 | epInfo[index].epAddr) : epInfo[index].epAddr));
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -827,7 +827,7 @@ uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void BulkOnly::Reset() {
|
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
|
* Clear all EP data and clear all LUN status
|
||||||
*/
|
*/
|
||||||
void BulkOnly::ClearAllEP() {
|
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].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
|
@ -863,7 +863,7 @@ void BulkOnly::ClearAllEP() {
|
||||||
epInfo[i].bmNakPower = USB_NAK_DEFAULT;
|
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;
|
LUNOk[i] = false;
|
||||||
WriteOk[i] = false;
|
WriteOk[i] = false;
|
||||||
CurrentCapacity[i] = 0lu;
|
CurrentCapacity[i] = 0lu;
|
||||||
|
@ -888,11 +888,11 @@ void BulkOnly::ClearAllEP() {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool BulkOnly::IsValidCSW(CommandStatusWrapper *pcsw, CommandBlockWrapperBase *pcbw) {
|
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);
|
Notify(PSTR("CSW:Sig error\r\n"), 0x80);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (pcsw->dCSWTag != pcbw->dCBWTag) {
|
if(pcsw->dCSWTag != pcbw->dCBWTag) {
|
||||||
Notify(PSTR("CSW:Wrong tag\r\n"), 0x80);
|
Notify(PSTR("CSW:Wrong tag\r\n"), 0x80);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -912,12 +912,12 @@ uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
|
||||||
bLastUsbError = error;
|
bLastUsbError = error;
|
||||||
//if (error)
|
//if (error)
|
||||||
//ClearEpHalt(index);
|
//ClearEpHalt(index);
|
||||||
while (error && count) {
|
while(error && count) {
|
||||||
if (error != hrSUCCESS) {
|
if(error != hrSUCCESS) {
|
||||||
ErrorMessage<uint8_t > (PSTR("USB Error"), error);
|
ErrorMessage<uint8_t > (PSTR("USB Error"), error);
|
||||||
ErrorMessage<uint8_t > (PSTR("Index"), index);
|
ErrorMessage<uint8_t > (PSTR("Index"), index);
|
||||||
}
|
}
|
||||||
switch (error) {
|
switch(error) {
|
||||||
// case hrWRONGPID:
|
// case hrWRONGPID:
|
||||||
case hrSUCCESS:
|
case hrSUCCESS:
|
||||||
return MASS_ERR_SUCCESS;
|
return MASS_ERR_SUCCESS;
|
||||||
|
@ -927,15 +927,15 @@ uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
|
||||||
case hrTIMEOUT:
|
case hrTIMEOUT:
|
||||||
case hrJERR: return MASS_ERR_DEVICE_DISCONNECTED;
|
case hrJERR: return MASS_ERR_DEVICE_DISCONNECTED;
|
||||||
case hrSTALL:
|
case hrSTALL:
|
||||||
if (index == 0)
|
if(index == 0)
|
||||||
return MASS_ERR_STALL;
|
return MASS_ERR_STALL;
|
||||||
ClearEpHalt(index);
|
ClearEpHalt(index);
|
||||||
if (index != epDataInIndex)
|
if(index != epDataInIndex)
|
||||||
return MASS_ERR_WRITE_STALL;
|
return MASS_ERR_WRITE_STALL;
|
||||||
return MASS_ERR_STALL;
|
return MASS_ERR_STALL;
|
||||||
|
|
||||||
case hrNAK:
|
case hrNAK:
|
||||||
if (index == 0)
|
if(index == 0)
|
||||||
return MASS_ERR_UNIT_BUSY;
|
return MASS_ERR_UNIT_BUSY;
|
||||||
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
|
// 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.
|
// the only clean way to get back into sync with the buggy device firmware.
|
||||||
// --AJK
|
// --AJK
|
||||||
if (bAddress && bConfNum) {
|
if(bAddress && bConfNum) {
|
||||||
error = pUsb->setConf(bAddress, 0, bConfNum);
|
error = pUsb->setConf(bAddress, 0, bConfNum);
|
||||||
|
|
||||||
if (error)
|
if(error)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return MASS_ERR_SUCCESS;
|
return MASS_ERR_SUCCESS;
|
||||||
|
@ -999,33 +999,33 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
|
||||||
SetCurLUN(pcbw->bmCBWLUN);
|
SetCurLUN(pcbw->bmCBWLUN);
|
||||||
ErrorMessage<uint32_t > (PSTR("CBW.dCBWTag"), pcbw->dCBWTag);
|
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(usberr, epDataOutIndex);
|
||||||
//ret = HandleUsbError(pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw), 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);
|
ErrorMessage<uint8_t > (PSTR("============================ CBW"), ret);
|
||||||
} else {
|
} else {
|
||||||
if (bytes) {
|
if(bytes) {
|
||||||
if (!write) {
|
if(!write) {
|
||||||
#if MS_WANT_PARSER
|
#if MS_WANT_PARSER
|
||||||
if (callback) {
|
if(callback) {
|
||||||
uint8_t rbuf[bytes];
|
uint8_t rbuf[bytes];
|
||||||
while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, rbuf)) == hrBUSY) delay(1);
|
while((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, rbuf)) == hrBUSY) delay(1);
|
||||||
if (usberr == hrSUCCESS) ((USBReadParser*)buf)->Parse(bytes, rbuf, 0);
|
if(usberr == hrSUCCESS) ((USBReadParser*)buf)->Parse(bytes, rbuf, 0);
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#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
|
#if MS_WANT_PARSER
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ret = HandleUsbError(usberr, epDataInIndex);
|
ret = HandleUsbError(usberr, epDataInIndex);
|
||||||
} else {
|
} 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);
|
ret = HandleUsbError(usberr, epDataOutIndex);
|
||||||
}
|
}
|
||||||
if (ret) {
|
if(ret) {
|
||||||
ErrorMessage<uint8_t > (PSTR("============================ DAT"), 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);
|
bytes = sizeof (CommandStatusWrapper);
|
||||||
int tries = 2;
|
int tries = 2;
|
||||||
while (tries--) {
|
while(tries--) {
|
||||||
while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*) & csw)) == hrBUSY) delay(1);
|
while((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*) & csw)) == hrBUSY) delay(1);
|
||||||
if (!usberr) break;
|
if(!usberr) break;
|
||||||
ClearEpHalt(epDataInIndex);
|
ClearEpHalt(epDataInIndex);
|
||||||
if (tries) ResetRecovery();
|
if(tries) ResetRecovery();
|
||||||
}
|
}
|
||||||
if (!ret) {
|
if(!ret) {
|
||||||
Notify(PSTR("CBW:\t\tOK\r\n"), 0x80);
|
Notify(PSTR("CBW:\t\tOK\r\n"), 0x80);
|
||||||
Notify(PSTR("Data Stage:\tOK\r\n"), 0x80);
|
Notify(PSTR("Data Stage:\tOK\r\n"), 0x80);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1049,11 +1049,11 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = HandleUsbError(usberr, epDataInIndex);
|
ret = HandleUsbError(usberr, epDataInIndex);
|
||||||
if (ret) {
|
if(ret) {
|
||||||
ErrorMessage<uint8_t > (PSTR("============================ CSW"), ret);
|
ErrorMessage<uint8_t > (PSTR("============================ CSW"), ret);
|
||||||
}
|
}
|
||||||
if (usberr == hrSUCCESS) {
|
if(usberr == hrSUCCESS) {
|
||||||
if (IsValidCSW(&csw, pcbw)) {
|
if(IsValidCSW(&csw, pcbw)) {
|
||||||
//ErrorMessage<uint32_t > (PSTR("CSW.dCBWTag"), csw.dCSWTag);
|
//ErrorMessage<uint32_t > (PSTR("CSW.dCBWTag"), csw.dCSWTag);
|
||||||
//ErrorMessage<uint8_t > (PSTR("bCSWStatus"), csw.bCSWStatus);
|
//ErrorMessage<uint8_t > (PSTR("bCSWStatus"), csw.bCSWStatus);
|
||||||
//ErrorMessage<uint32_t > (PSTR("dCSWDataResidue"), csw.dCSWDataResidue);
|
//ErrorMessage<uint32_t > (PSTR("dCSWDataResidue"), csw.dCSWDataResidue);
|
||||||
|
@ -1082,7 +1082,7 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
|
uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
|
||||||
if (lun > bMaxLUN)
|
if(lun > bMaxLUN)
|
||||||
return MASS_ERR_INVALID_LUN;
|
return MASS_ERR_INVALID_LUN;
|
||||||
bTheLUN = lun;
|
bTheLUN = lun;
|
||||||
return MASS_ERR_SUCCESS;
|
return MASS_ERR_SUCCESS;
|
||||||
|
@ -1097,7 +1097,7 @@ uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
|
||||||
uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
|
uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
|
||||||
uint8_t ret = 0;
|
uint8_t ret = 0;
|
||||||
|
|
||||||
switch (status) {
|
switch(status) {
|
||||||
case 0: return MASS_ERR_SUCCESS;
|
case 0: return MASS_ERR_SUCCESS;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -1113,13 +1113,13 @@ uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
|
||||||
|
|
||||||
ret = RequestSense(bTheLUN, sizeof (RequestSenseResponce), (uint8_t*) & rsp);
|
ret = RequestSense(bTheLUN, sizeof (RequestSenseResponce), (uint8_t*) & rsp);
|
||||||
|
|
||||||
if (ret) {
|
if(ret) {
|
||||||
return MASS_ERR_GENERAL_SCSI_ERROR;
|
return MASS_ERR_GENERAL_SCSI_ERROR;
|
||||||
}
|
}
|
||||||
ErrorMessage<uint8_t > (PSTR("Response Code"), rsp.bResponseCode);
|
ErrorMessage<uint8_t > (PSTR("Response Code"), rsp.bResponseCode);
|
||||||
if (rsp.bResponseCode & 0x80) {
|
if(rsp.bResponseCode & 0x80) {
|
||||||
Notify(PSTR("Information field: "), 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);
|
D_PrintHex<uint8_t > (rsp.CmdSpecificInformation[i], 0x80);
|
||||||
Notify(PSTR(" "), 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 Code"), rsp.bAdditionalSenseCode);
|
||||||
ErrorMessage<uint8_t > (PSTR("Add Sense Qual"), rsp.bAdditionalSenseQualifier);
|
ErrorMessage<uint8_t > (PSTR("Add Sense Qual"), rsp.bAdditionalSenseQualifier);
|
||||||
// warning, this is not testing ASQ, only SK and ASC.
|
// warning, this is not testing ASQ, only SK and ASC.
|
||||||
switch (rsp.bmSenseKey) {
|
switch(rsp.bmSenseKey) {
|
||||||
case SCSI_S_UNIT_ATTENTION:
|
case SCSI_S_UNIT_ATTENTION:
|
||||||
switch (rsp.bAdditionalSenseCode) {
|
switch(rsp.bAdditionalSenseCode) {
|
||||||
case SCSI_ASC_MEDIA_CHANGED:
|
case SCSI_ASC_MEDIA_CHANGED:
|
||||||
return MASS_ERR_MEDIA_CHANGED;
|
return MASS_ERR_MEDIA_CHANGED;
|
||||||
default:
|
default:
|
||||||
return MASS_ERR_UNIT_NOT_READY;
|
return MASS_ERR_UNIT_NOT_READY;
|
||||||
}
|
}
|
||||||
case SCSI_S_NOT_READY:
|
case SCSI_S_NOT_READY:
|
||||||
switch (rsp.bAdditionalSenseCode) {
|
switch(rsp.bAdditionalSenseCode) {
|
||||||
case SCSI_ASC_MEDIUM_NOT_PRESENT:
|
case SCSI_ASC_MEDIUM_NOT_PRESENT:
|
||||||
return MASS_ERR_NO_MEDIA;
|
return MASS_ERR_NO_MEDIA;
|
||||||
default:
|
default:
|
||||||
return MASS_ERR_UNIT_NOT_READY;
|
return MASS_ERR_UNIT_NOT_READY;
|
||||||
}
|
}
|
||||||
case SCSI_S_ILLEGAL_REQUEST:
|
case SCSI_S_ILLEGAL_REQUEST:
|
||||||
switch (rsp.bAdditionalSenseCode) {
|
switch(rsp.bAdditionalSenseCode) {
|
||||||
case SCSI_ASC_LBA_OUT_OF_RANGE:
|
case SCSI_ASC_LBA_OUT_OF_RANGE:
|
||||||
return MASS_ERR_BAD_LBA;
|
return MASS_ERR_BAD_LBA;
|
||||||
default:
|
default:
|
||||||
|
@ -1207,7 +1207,7 @@ void BulkOnly::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR * ep_ptr) {
|
||||||
/* We won't be needing this... */
|
/* We won't be needing this... */
|
||||||
uint8_t BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, USBReadParser * prs) {
|
uint8_t BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, USBReadParser * prs) {
|
||||||
#if MS_WANT_PARSER
|
#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\nRead (With parser)\r\n"), 0x80);
|
||||||
Notify(PSTR("---------\r\n"), 0x80);
|
Notify(PSTR("---------\r\n"), 0x80);
|
||||||
|
|
||||||
|
|
|
@ -396,7 +396,7 @@ public:
|
||||||
// Type punning can cause optimization problems and bugs.
|
// Type punning can cause optimization problems and bugs.
|
||||||
// Using reinterpret_cast to a dreinterpretifferent object is the proper way to do this.
|
// Using reinterpret_cast to a dreinterpretifferent object is the proper way to do this.
|
||||||
//(((BASICCDB_t *) CBWCB)->LUN) = cmd;
|
//(((BASICCDB_t *) CBWCB)->LUN) = cmd;
|
||||||
BASICCDB_t *x = reinterpret_cast<BASICCDB_t *> (CBWCB);
|
BASICCDB_t *x = reinterpret_cast<BASICCDB_t *>(CBWCB);
|
||||||
x->LUN = cmd;
|
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 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) {
|
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);
|
uint8_t SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
|
||||||
|
|
10
max_LCD.cpp
10
max_LCD.cpp
|
@ -52,14 +52,14 @@ void Max_LCD::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Max_LCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
|
void Max_LCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
|
||||||
if (lines > 1) {
|
if(lines > 1) {
|
||||||
_displayfunction |= LCD_2LINE;
|
_displayfunction |= LCD_2LINE;
|
||||||
}
|
}
|
||||||
_numlines = lines;
|
_numlines = lines;
|
||||||
_currline = 0;
|
_currline = 0;
|
||||||
|
|
||||||
// for some 1 line displays you can select a 10 pixel high font
|
// 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;
|
_displayfunction |= LCD_5x10DOTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ void Max_LCD::home() {
|
||||||
|
|
||||||
void Max_LCD::setCursor(uint8_t col, uint8_t row) {
|
void Max_LCD::setCursor(uint8_t col, uint8_t row) {
|
||||||
int row_offsets[] = {0x00, 0x40, 0x14, 0x54};
|
int row_offsets[] = {0x00, 0x40, 0x14, 0x54};
|
||||||
if (row > _numlines) {
|
if(row > _numlines) {
|
||||||
row = _numlines - 1; // we count rows starting w/0
|
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[]) {
|
void Max_LCD::createChar(uint8_t location, uint8_t charmap[]) {
|
||||||
location &= 0x7; // we only have 8 locations 0-7
|
location &= 0x7; // we only have 8 locations 0-7
|
||||||
command(LCD_SETCGRAMADDR | (location << 3));
|
command(LCD_SETCGRAMADDR | (location << 3));
|
||||||
for (int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
write(charmap[i]);
|
write(charmap[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,11 +224,13 @@ inline void Max_LCD::command(uint8_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ARDUINO) && ARDUINO >=100
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
|
||||||
inline size_t Max_LCD::write(uint8_t value) {
|
inline size_t Max_LCD::write(uint8_t value) {
|
||||||
LCD_sendchar(value);
|
LCD_sendchar(value);
|
||||||
return 1; // Assume success
|
return 1; // Assume success
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
inline void Max_LCD::write(uint8_t value) {
|
inline void Max_LCD::write(uint8_t value) {
|
||||||
LCD_sendchar(value);
|
LCD_sendchar(value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,7 @@ e-mail : support@circuitsathome.com
|
||||||
#define LCD_5x10DOTS 0x04
|
#define LCD_5x10DOTS 0x04
|
||||||
#define LCD_5x8DOTS 0x00
|
#define LCD_5x8DOTS 0x00
|
||||||
|
|
||||||
class Max_LCD : public Print
|
class Max_LCD : public Print {
|
||||||
{
|
|
||||||
USB *pUsb;
|
USB *pUsb;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
20
message.cpp
20
message.cpp
|
@ -22,7 +22,7 @@ e-mail : support@circuitsathome.com
|
||||||
int UsbDEBUGlvl = 0x80;
|
int UsbDEBUGlvl = 0x80;
|
||||||
|
|
||||||
void E_Notifyc(char c, int lvl) {
|
void E_Notifyc(char c, int lvl) {
|
||||||
if (UsbDEBUGlvl < lvl) return;
|
if(UsbDEBUGlvl < lvl) return;
|
||||||
#if defined(ARDUINO) && ARDUINO >=100
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
USB_HOST_SERIAL.print(c);
|
USB_HOST_SERIAL.print(c);
|
||||||
#else
|
#else
|
||||||
|
@ -32,23 +32,23 @@ void E_Notifyc(char c, int lvl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void E_Notify(char const * msg, int lvl) {
|
void E_Notify(char const * msg, int lvl) {
|
||||||
if (UsbDEBUGlvl < lvl) return;
|
if(UsbDEBUGlvl < lvl) return;
|
||||||
if (!msg) return;
|
if(!msg) return;
|
||||||
char c;
|
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) {
|
void E_NotifyStr(char const * msg, int lvl) {
|
||||||
if (UsbDEBUGlvl < lvl) return;
|
if(UsbDEBUGlvl < lvl) return;
|
||||||
if (!msg) return;
|
if(!msg) return;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
while ((c = *msg++)) E_Notifyc(c, lvl);
|
while((c = *msg++)) E_Notifyc(c, lvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void E_Notify(uint8_t b, int lvl) {
|
void E_Notify(uint8_t b, int lvl) {
|
||||||
if (UsbDEBUGlvl < lvl) return;
|
if(UsbDEBUGlvl < lvl) return;
|
||||||
#if defined(ARDUINO) && ARDUINO >=100
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
USB_HOST_SERIAL.print(b);
|
USB_HOST_SERIAL.print(b);
|
||||||
#else
|
#else
|
||||||
|
@ -58,12 +58,13 @@ void E_Notify(uint8_t b, int lvl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void E_Notify(double d, 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.print(d);
|
||||||
//USB_HOST_SERIAL.flush();
|
//USB_HOST_SERIAL.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
|
|
||||||
void NotifyFailGetDevDescr(void) {
|
void NotifyFailGetDevDescr(void) {
|
||||||
Notify(PSTR("\r\ngetDevDescr "), 0x80);
|
Notify(PSTR("\r\ngetDevDescr "), 0x80);
|
||||||
}
|
}
|
||||||
|
@ -71,6 +72,7 @@ void NotifyFailGetDevDescr(void) {
|
||||||
void NotifyFailSetDevTblEntry(void) {
|
void NotifyFailSetDevTblEntry(void) {
|
||||||
Notify(PSTR("\r\nsetDevTblEn "), 0x80);
|
Notify(PSTR("\r\nsetDevTblEn "), 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifyFailGetConfDescr(void) {
|
void NotifyFailGetConfDescr(void) {
|
||||||
Notify(PSTR("\r\ngetConf "), 0x80);
|
Notify(PSTR("\r\ngetConf "), 0x80);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,14 +17,14 @@ e-mail : support@circuitsathome.com
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
|
||||||
bool MultiByteValueParser::Parse(uint8_t **pp, uint16_t *pcntdn) {
|
bool MultiByteValueParser::Parse(uint8_t **pp, uint16_t *pcntdn) {
|
||||||
if (!pBuf) {
|
if(!pBuf) {
|
||||||
Notify(PSTR("Buffer pointer is NULL!\r\n"), 0x80);
|
Notify(PSTR("Buffer pointer is NULL!\r\n"), 0x80);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (; countDown && (*pcntdn); countDown--, (*pcntdn)--, (*pp)++)
|
for(; countDown && (*pcntdn); countDown--, (*pcntdn)--, (*pp)++)
|
||||||
pBuf[valueSize - countDown] = (**pp);
|
pBuf[valueSize - countDown] = (**pp);
|
||||||
|
|
||||||
if (countDown)
|
if(countDown)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
countDown = valueSize;
|
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) {
|
bool PTPListParser::Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me) {
|
||||||
switch (nStage) {
|
switch(nStage) {
|
||||||
case 0:
|
case 0:
|
||||||
pBuf->valueSize = lenSize;
|
pBuf->valueSize = lenSize;
|
||||||
theParser.Initialize(pBuf);
|
theParser.Initialize(pBuf);
|
||||||
nStage = 1;
|
nStage = 1;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
if (!theParser.Parse(pp, pcntdn))
|
if(!theParser.Parse(pp, pcntdn))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
arLen = 0;
|
arLen = 0;
|
||||||
|
@ -53,11 +53,11 @@ bool PTPListParser::Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf,
|
||||||
nStage = 3;
|
nStage = 3;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
for (; arLenCntdn; arLenCntdn--) {
|
for(; arLenCntdn; arLenCntdn--) {
|
||||||
if (!theParser.Parse(pp, pcntdn))
|
if(!theParser.Parse(pp, pcntdn))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (pf)
|
if(pf)
|
||||||
pf(pBuf, (arLen - arLenCntdn), me);
|
pf(pBuf, (arLen - arLenCntdn), me);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void Initialize(MultiValueBuffer * const pbuf) {
|
void Initialize(MultiValueBuffer * const pbuf) {
|
||||||
pBuf = (uint8_t*) pbuf->pValue;
|
pBuf = (uint8_t*)pbuf->pValue;
|
||||||
countDown = valueSize = pbuf->valueSize;
|
countDown = valueSize = pbuf->valueSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void Initialize(MultiValueBuffer *pbuf) {
|
void Initialize(MultiValueBuffer *pbuf) {
|
||||||
pBuf = (uint8_t*) pbuf->pValue;
|
pBuf = (uint8_t*)pbuf->pValue;
|
||||||
countDown = 0;
|
countDown = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ public:
|
||||||
if(!countDown)
|
if(!countDown)
|
||||||
nStage = 0;
|
nStage = 0;
|
||||||
};
|
};
|
||||||
return(!countDown);
|
return (!countDown);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
14
printhex.h
14
printhex.h
|
@ -24,7 +24,7 @@ void E_Notifyc(char c, int lvl);
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void PrintHex(T val, int lvl) {
|
void PrintHex(T val, int lvl) {
|
||||||
int num_nibbles = sizeof(T) * 2;
|
int num_nibbles = sizeof (T) * 2;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
||||||
|
@ -35,7 +35,7 @@ void PrintHex(T val, int lvl) {
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void PrintBin(T val, int lvl) {
|
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)
|
if(val & mask)
|
||||||
E_Notifyc('1', lvl);
|
E_Notifyc('1', lvl);
|
||||||
else
|
else
|
||||||
|
@ -44,7 +44,7 @@ void PrintBin(T val, int lvl) {
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void SerialPrintHex(T val) {
|
void SerialPrintHex(T val) {
|
||||||
int num_nibbles = sizeof(T) * 2;
|
int num_nibbles = sizeof (T) * 2;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
||||||
|
@ -55,7 +55,7 @@ void SerialPrintHex(T val) {
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void PrintHex2(Print *prn, T val) {
|
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) {
|
while(mask > 1) {
|
||||||
if(val < mask)
|
if(val < mask)
|
||||||
|
@ -63,19 +63,19 @@ void PrintHex2(Print *prn, T val) {
|
||||||
|
|
||||||
mask >>= 4;
|
mask >>= 4;
|
||||||
}
|
}
|
||||||
prn->print((T) val, HEX);
|
prn->print((T)val, HEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> void D_PrintHex(T val, int lvl) {
|
template <class T> void D_PrintHex(T val, int lvl) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
PrintHex<T>(val, lvl);
|
PrintHex<T > (val, lvl);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void D_PrintBin(T val, int lvl) {
|
void D_PrintBin(T val, int lvl) {
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
PrintBin<T>(val, lvl);
|
PrintBin<T > (val, lvl);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,14 +22,19 @@ e-mail : support@circuitsathome.com
|
||||||
extern int UsbDEBUGlvl;
|
extern int UsbDEBUGlvl;
|
||||||
|
|
||||||
// This parser does absolutely nothing with the data, just swallows it.
|
// This parser does absolutely nothing with the data, just swallows it.
|
||||||
|
|
||||||
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
|
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
|
||||||
class SinkParser : public BASE_CLASS {
|
class SinkParser : public BASE_CLASS {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SinkParser() {};
|
SinkParser() {
|
||||||
void Initialize() {};
|
};
|
||||||
void Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset) {};
|
|
||||||
|
void Initialize() {
|
||||||
|
};
|
||||||
|
|
||||||
|
void Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset) {
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
22
usbhost.h
22
usbhost.h
|
@ -162,7 +162,7 @@ uint8_t* MAX3421e< SPI_SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t*
|
||||||
#endif
|
#endif
|
||||||
SPI_SS::Set();
|
SPI_SS::Set();
|
||||||
XMEM_RELEASE_SPI();
|
XMEM_RELEASE_SPI();
|
||||||
return( data_p);
|
return ( data_p);
|
||||||
}
|
}
|
||||||
/* GPIO write */
|
/* GPIO write */
|
||||||
/*GPIO byte is split between 2 registers, so two writes are needed to write one byte */
|
/*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;
|
uint8_t rv = SPDR;
|
||||||
#endif
|
#endif
|
||||||
XMEM_RELEASE_SPI();
|
XMEM_RELEASE_SPI();
|
||||||
return(rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
/* multiple-byte register read */
|
/* multiple-byte register read */
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ uint8_t* MAX3421e< SPI_SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t*
|
||||||
#endif
|
#endif
|
||||||
SPI_SS::Set();
|
SPI_SS::Set();
|
||||||
XMEM_RELEASE_SPI();
|
XMEM_RELEASE_SPI();
|
||||||
return( data_p);
|
return ( data_p);
|
||||||
}
|
}
|
||||||
/* GPIO read. See gpioWr for explanation */
|
/* GPIO read. See gpioWr for explanation */
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ uint8_t MAX3421e< SPI_SS, INTR >::gpioRd() {
|
||||||
gpin = regRd(rIOPINS2); //pins 4-7
|
gpin = regRd(rIOPINS2); //pins 4-7
|
||||||
gpin &= 0xf0; //clean lower nibble
|
gpin &= 0xf0; //clean lower nibble
|
||||||
gpin |= (regRd(rIOPINS1) >> 4); //shift low bits and OR with upper from previous operation.
|
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
|
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return( i);
|
return ( i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
|
/* 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));
|
regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL));
|
||||||
|
|
||||||
if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
|
if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
|
||||||
return( -1);
|
return ( -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST); // set pull-downs, Host
|
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(rHIRQ, bmCONDETIRQ); //clear connection detect interrupt
|
||||||
regWr(rCPUCTL, 0x01); //enable interrupt pin
|
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 */
|
/* 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));
|
regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL | GPX_VBDET));
|
||||||
|
|
||||||
if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
|
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.
|
// 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.
|
// GPX pin on. This is done here so that busprobe will fail if we have a switch connected.
|
||||||
regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL));
|
regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL));
|
||||||
|
|
||||||
return( 0);
|
return ( 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* probe bus to determine device presence and speed and switch host to this speed */
|
/* 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();
|
// GpxHandler();
|
||||||
// }
|
// }
|
||||||
// usbSM(); //USB state machine
|
// usbSM(); //USB state machine
|
||||||
return( rcode);
|
return ( rcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename SPI_SS, typename INTR >
|
template< typename SPI_SS, typename INTR >
|
||||||
|
@ -408,7 +408,7 @@ uint8_t MAX3421e< SPI_SS, INTR >::IntHandler() {
|
||||||
}
|
}
|
||||||
/* End HIRQ interrupts handling, clear serviced IRQs */
|
/* End HIRQ interrupts handling, clear serviced IRQs */
|
||||||
regWr(rHIRQ, HIRQ_sendback);
|
regWr(rHIRQ, HIRQ_sendback);
|
||||||
return( HIRQ_sendback);
|
return ( HIRQ_sendback);
|
||||||
}
|
}
|
||||||
//template< typename SPI_SS, typename INTR >
|
//template< typename SPI_SS, typename INTR >
|
||||||
//uint8_t MAX3421e< SPI_SS, INTR >::GpxHandler()
|
//uint8_t MAX3421e< SPI_SS, INTR >::GpxHandler()
|
||||||
|
|
78
usbhub.cpp
78
usbhub.cpp
|
@ -35,7 +35,7 @@ bPollEnable(false) {
|
||||||
epInfo[1].epAttribs = 0;
|
epInfo[1].epAttribs = 0;
|
||||||
epInfo[1].bmNakPower = USB_NAK_NOWAIT;
|
epInfo[1].bmNakPower = USB_NAK_NOWAIT;
|
||||||
|
|
||||||
if (pUsb)
|
if(pUsb)
|
||||||
pUsb->RegisterDeviceClass(this);
|
pUsb->RegisterDeviceClass(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,16 +57,16 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
//switch (bInitState) {
|
//switch (bInitState) {
|
||||||
// case 0:
|
// case 0:
|
||||||
if (bAddress)
|
if(bAddress)
|
||||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||||
|
|
||||||
// Get pointer to pseudo device with address 0 assigned
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
p = addrPool.GetUsbDevicePtr(0);
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
|
|
||||||
if (!p)
|
if(!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
if (!p->epinfo)
|
if(!p->epinfo)
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
return USB_ERROR_EPINFO_IS_NULL;
|
||||||
|
|
||||||
// Save old pointer to EP_RECORD of address 0
|
// Save old pointer to EP_RECORD of address 0
|
||||||
|
@ -82,10 +82,10 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
p->lowspeed = false;
|
p->lowspeed = false;
|
||||||
|
|
||||||
if (!rcode)
|
if(!rcode)
|
||||||
len = (buf[0] > 32) ? 32 : buf[0];
|
len = (buf[0] > 32) ? 32 : buf[0];
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
// Restore p->epinfo
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
return rcode;
|
return rcode;
|
||||||
|
@ -93,13 +93,13 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
// Extract device class from device descriptor
|
// Extract device class from device descriptor
|
||||||
// If device class is not a hub return
|
// If device class is not a hub return
|
||||||
if (udd->bDeviceClass != 0x09)
|
if(udd->bDeviceClass != 0x09)
|
||||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
// Allocate new address according to device class
|
// Allocate new address according to device class
|
||||||
bAddress = addrPool.AllocAddress(parent, (udd->bDeviceClass == 0x09) ? true : false, port);
|
bAddress = addrPool.AllocAddress(parent, (udd->bDeviceClass == 0x09) ? true : false, port);
|
||||||
|
|
||||||
if (!bAddress)
|
if(!bAddress)
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
// Extract Max Packet Size from the device descriptor
|
// Extract Max Packet Size from the device descriptor
|
||||||
|
@ -108,7 +108,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Assign new address to the device
|
// Assign new address to the device
|
||||||
rcode = pUsb->setAddr(0, 0, bAddress);
|
rcode = pUsb->setAddr(0, 0, bAddress);
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
// Restore p->epinfo
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
|
@ -121,16 +121,16 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Restore p->epinfo
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
if (len)
|
if(len)
|
||||||
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
|
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer
|
// Assign epInfo to epinfo pointer
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 2, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 2, epInfo);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
// bInitState = 1;
|
// bInitState = 1;
|
||||||
|
@ -139,7 +139,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Get hub descriptor
|
// Get hub descriptor
|
||||||
rcode = GetHubDescriptor(0, 8, buf);
|
rcode = GetHubDescriptor(0, 8, buf);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetHubDescr;
|
goto FailGetHubDescr;
|
||||||
|
|
||||||
// Save number of ports for future use
|
// Save number of ports for future use
|
||||||
|
@ -151,11 +151,11 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
// Read configuration Descriptor in Order To Obtain Proper Configuration Value
|
// Read configuration Descriptor in Order To Obtain Proper Configuration Value
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, 8, 0, buf);
|
rcode = pUsb->getConfDescr(bAddress, 0, 8, 0, buf);
|
||||||
|
|
||||||
if (!rcode) {
|
if(!rcode) {
|
||||||
cd_len = ucd->wTotalLength;
|
cd_len = ucd->wTotalLength;
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, cd_len, 0, buf);
|
rcode = pUsb->getConfDescr(bAddress, 0, cd_len, 0, buf);
|
||||||
}
|
}
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
|
|
||||||
// The following code is of no practical use in real life applications.
|
// The following code is of no practical use in real life applications.
|
||||||
|
@ -165,21 +165,21 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, buf[0], 0, buf2);
|
rcode = pUsb->getConfDescr(bAddress, 0, buf[0], 0, buf2);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
rcode = pUsb->setConf(bAddress, 0, buf[5]);
|
rcode = pUsb->setConf(bAddress, 0, buf[5]);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
// bInitState = 3;
|
// bInitState = 3;
|
||||||
|
|
||||||
// case 3:
|
// case 3:
|
||||||
// Power on all ports
|
// Power on all ports
|
||||||
for (uint8_t j = 1; j <= bNbrPorts; j++)
|
for(uint8_t j = 1; j <= bNbrPorts; j++)
|
||||||
SetPortFeature(HUB_FEATURE_PORT_POWER, j, 0); //HubPortPowerOn(j);
|
SetPortFeature(HUB_FEATURE_PORT_POWER, j, 0); //HubPortPowerOn(j);
|
||||||
|
|
||||||
pUsb->SetHubPreMask();
|
pUsb->SetHubPreMask();
|
||||||
|
@ -214,7 +214,7 @@ Fail:
|
||||||
uint8_t USBHub::Release() {
|
uint8_t USBHub::Release() {
|
||||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||||
|
|
||||||
if (bAddress == 0x41)
|
if(bAddress == 0x41)
|
||||||
pUsb->SetHubPreMask();
|
pUsb->SetHubPreMask();
|
||||||
|
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
|
@ -227,10 +227,10 @@ uint8_t USBHub::Release() {
|
||||||
uint8_t USBHub::Poll() {
|
uint8_t USBHub::Poll() {
|
||||||
uint8_t rcode = 0;
|
uint8_t rcode = 0;
|
||||||
|
|
||||||
if (!bPollEnable)
|
if(!bPollEnable)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (qNextPollTime <= millis()) {
|
if(qNextPollTime <= millis()) {
|
||||||
rcode = CheckHubStatus();
|
rcode = CheckHubStatus();
|
||||||
qNextPollTime = millis() + 100;
|
qNextPollTime = millis() + 100;
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ uint8_t USBHub::CheckHubStatus() {
|
||||||
|
|
||||||
rcode = pUsb->inTransfer(bAddress, 1, &read, buf);
|
rcode = pUsb->inTransfer(bAddress, 1, &read, buf);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
return rcode;
|
return rcode;
|
||||||
|
|
||||||
//if (buf[0] & 0x01) // Hub Status Change
|
//if (buf[0] & 0x01) // Hub Status Change
|
||||||
|
@ -258,36 +258,36 @@ uint8_t USBHub::CheckHubStatus() {
|
||||||
// return rcode;
|
// return rcode;
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
for (uint8_t port = 1, mask = 0x02; port < 8; mask <<= 1, port++) {
|
for(uint8_t port = 1, mask = 0x02; port < 8; mask <<= 1, port++) {
|
||||||
if (buf[0] & mask) {
|
if(buf[0] & mask) {
|
||||||
HubEvent evt;
|
HubEvent evt;
|
||||||
evt.bmEvent = 0;
|
evt.bmEvent = 0;
|
||||||
|
|
||||||
rcode = GetPortStatus(port, 4, evt.evtBuff);
|
rcode = GetPortStatus(port, 4, evt.evtBuff);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rcode = PortStatusChange(port, evt);
|
rcode = PortStatusChange(port, evt);
|
||||||
|
|
||||||
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
if(rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
} // for
|
} // for
|
||||||
|
|
||||||
for (uint8_t port = 1; port <= bNbrPorts; port++) {
|
for(uint8_t port = 1; port <= bNbrPorts; port++) {
|
||||||
HubEvent evt;
|
HubEvent evt;
|
||||||
evt.bmEvent = 0;
|
evt.bmEvent = 0;
|
||||||
|
|
||||||
rcode = GetPortStatus(port, 4, evt.evtBuff);
|
rcode = GetPortStatus(port, 4, evt.evtBuff);
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
continue;
|
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;
|
continue;
|
||||||
|
|
||||||
// Emulate connection event for the port
|
// Emulate connection event for the port
|
||||||
|
@ -295,10 +295,10 @@ uint8_t USBHub::CheckHubStatus() {
|
||||||
|
|
||||||
rcode = PortStatusChange(port, evt);
|
rcode = PortStatusChange(port, evt);
|
||||||
|
|
||||||
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
if(rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (rcode)
|
if(rcode)
|
||||||
return rcode;
|
return rcode;
|
||||||
} // for
|
} // for
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -314,10 +314,10 @@ void USBHub::ResetHubPort(uint8_t port) {
|
||||||
SetPortFeature(HUB_FEATURE_PORT_RESET, port, 0);
|
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);
|
rcode = GetPortStatus(port, 4, evt.evtBuff);
|
||||||
if (rcode) break; // Some kind of error, bail.
|
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(evt.bmEvent == bmHUB_PORT_EVENT_RESET_COMPLETE || evt.bmEvent == bmHUB_PORT_EVENT_LS_RESET_COMPLETE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
delay(100); // simulate polling.
|
delay(100); // simulate polling.
|
||||||
|
@ -328,11 +328,11 @@ void USBHub::ResetHubPort(uint8_t port) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t USBHub::PortStatusChange(uint8_t port, HubEvent &evt) {
|
uint8_t USBHub::PortStatusChange(uint8_t port, HubEvent &evt) {
|
||||||
switch (evt.bmEvent) {
|
switch(evt.bmEvent) {
|
||||||
// Device connected event
|
// Device connected event
|
||||||
case bmHUB_PORT_EVENT_CONNECT:
|
case bmHUB_PORT_EVENT_CONNECT:
|
||||||
case bmHUB_PORT_EVENT_LS_CONNECT:
|
case bmHUB_PORT_EVENT_LS_CONNECT:
|
||||||
if (bResetInitiated)
|
if(bResetInitiated)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ClearPortFeature(HUB_FEATURE_C_PORT_ENABLE, port, 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);
|
rcode = hubptr->GetPortStatus(port, 4, evt.evtBuff);
|
||||||
|
|
||||||
if (rcode) {
|
if(rcode) {
|
||||||
USB_HOST_SERIAL.println("ERROR!");
|
USB_HOST_SERIAL.println("ERROR!");
|
||||||
return;
|
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.print("INDICATOR:\t");
|
||||||
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_INDICATOR) > 0, DEC);
|
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_INDICATOR) > 0, DEC);
|
||||||
|
|
||||||
if (!print_changes)
|
if(!print_changes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
USB_HOST_SERIAL.println("\r\nChange");
|
USB_HOST_SERIAL.println("\r\nChange");
|
||||||
|
|
24
usbhub.h
24
usbhub.h
|
@ -170,7 +170,7 @@ class USBHub : USBDeviceConfig {
|
||||||
|
|
||||||
uint8_t bAddress; // address
|
uint8_t bAddress; // address
|
||||||
uint8_t bNbrPorts; // number of ports
|
uint8_t bNbrPorts; // number of ports
|
||||||
// uint8_t bInitState; // initialization state variable
|
// uint8_t bInitState; // initialization state variable
|
||||||
uint32_t qNextPollTime; // next poll time
|
uint32_t qNextPollTime; // next poll time
|
||||||
bool bPollEnable; // poll enable flag
|
bool bPollEnable; // poll enable flag
|
||||||
|
|
||||||
|
@ -195,52 +195,56 @@ public:
|
||||||
virtual uint8_t Release();
|
virtual uint8_t Release();
|
||||||
virtual uint8_t Poll();
|
virtual uint8_t Poll();
|
||||||
virtual void ResetHubPort(uint8_t port);
|
virtual void ResetHubPort(uint8_t port);
|
||||||
|
|
||||||
virtual uint8_t GetAddress() {
|
virtual uint8_t GetAddress() {
|
||||||
return bAddress;
|
return bAddress;
|
||||||
};
|
};
|
||||||
virtual boolean DEVCLASSOK(uint8_t klass) { return (klass == 0x09); }
|
|
||||||
|
virtual boolean DEVCLASSOK(uint8_t klass) {
|
||||||
|
return (klass == 0x09);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clear Hub Feature
|
// Clear Hub Feature
|
||||||
|
|
||||||
inline uint8_t USBHub::ClearHubFeature(uint8_t fid) {
|
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
|
// Clear Port Feature
|
||||||
|
|
||||||
inline uint8_t USBHub::ClearPortFeature(uint8_t fid, uint8_t port, uint8_t sel) {
|
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
|
// Get Hub Descriptor
|
||||||
|
|
||||||
inline uint8_t USBHub::GetHubDescriptor(uint8_t index, uint16_t nbytes, uint8_t *dataptr) {
|
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
|
// Get Hub Status
|
||||||
|
|
||||||
inline uint8_t USBHub::GetHubStatus(uint16_t nbytes, uint8_t* dataptr) {
|
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
|
// Get Port Status
|
||||||
|
|
||||||
inline uint8_t USBHub::GetPortStatus(uint8_t port, uint16_t nbytes, uint8_t* dataptr) {
|
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
|
// Set Hub Descriptor
|
||||||
|
|
||||||
inline uint8_t USBHub::SetHubDescriptor(uint8_t port, uint16_t nbytes, uint8_t* dataptr) {
|
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
|
// Set Hub Feature
|
||||||
|
|
||||||
inline uint8_t USBHub::SetHubFeature(uint8_t fid) {
|
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
|
// Set Port Feature
|
||||||
|
|
||||||
inline uint8_t USBHub::SetPortFeature(uint8_t fid, uint8_t port, uint8_t sel) {
|
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);
|
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes = false);
|
||||||
|
|
Loading…
Reference in a new issue