From 7abee0b545577025434acc555cd9bf9b18318973 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Sun, 6 Oct 2013 15:46:15 +0200 Subject: [PATCH 01/18] Include pins_arduino.h manually if the old Arduino IDE is used --- settings.h | 1 + 1 file changed, 1 insertion(+) diff --git a/settings.h b/settings.h index d22361a0..29904b13 100644 --- a/settings.h +++ b/settings.h @@ -61,6 +61,7 @@ #else #include // I am not sure what WProgram.h does not include, so these are here. --xxxajk +#include #include #include #endif From 47ff8e55c55d84404222313ba857c96d5e069d5f Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Mon, 7 Oct 2013 00:41:49 +0200 Subject: [PATCH 02/18] Retry if device returns hrJERR --- Usb.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Usb.cpp b/Usb.cpp index 122420bc..d1a3592c 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -581,7 +581,12 @@ uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lo } } rcode = devConfig[driver]->Init(parent, port, lowspeed); - if(rcode) { + if (rcode == hrJERR) { // Some devices returns this when plugged in - trying to initialize the device again usually works + delay(100); + devConfig[driver]->ConfigureDevice(parent, port, lowspeed); // Just ignore the returned value + rcode = devConfig[driver]->Init(parent, port, lowspeed); + } + if (rcode) { // Issue a bus reset, because the device may be in a limbo state if (parent == 0) { // Send a bus reset on the root interface. From b76ddedd59fade5ca82eca0122cf4ec82211c2bd Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Mon, 7 Oct 2013 00:47:53 +0200 Subject: [PATCH 03/18] Implement ConfigureDevice() before Init() Also added clearAllVariables() - see: https://github.com/felis/USB_Host_Shield_2.0/pull/63 --- BTD.cpp | 160 +++++++++++++++++++++++++++++++++++--------------------- BTD.h | 9 ++++ 2 files changed, 108 insertions(+), 61 deletions(-) diff --git a/BTD.cpp b/BTD.cpp index 254f104e..8c846303 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -34,45 +34,37 @@ qNextPollTime(0), // Reset NextPollTime pollInterval(0), bPollEnable(false) // Don't start polling before dongle is connected { - uint8_t i; - for (i = 0; i < BTD_MAX_ENDPOINTS; i++) { - epInfo[i].epAddr = 0; - epInfo[i].maxPktSize = (i) ? 0 : 8; - epInfo[i].epAttribs = 0; - epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER; - } - for (i = 0; i < BTD_NUMSERVICES; i++) + for (uint8_t i = 0; i < BTD_NUMSERVICES; i++) btService[i] = NULL; - if (pUsb) // register in USB subsystem - pUsb->RegisterDeviceClass(this); //set devConfig[] entry + clearAllVariables(); // Set all variables, endpoint structs etc. to default values + + if (pUsb) // Register in USB subsystem + pUsb->RegisterDeviceClass(this); // Set devConfig[] entry } -uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) { - uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; +uint8_t BTD::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) { + const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR); + uint8_t buf[constBufSize]; uint8_t rcode; UsbDevice *p = NULL; EpInfo *oldep_ptr = NULL; - uint8_t num_of_conf; // number of configurations - uint16_t PID; - uint16_t VID; - // get memory address of USB device address pool - AddressPool &addrPool = pUsb->GetAddressPool(); + clearAllVariables(); // Set all variables, endpoint structs etc. to default values + + AddressPool &addrPool = pUsb->GetAddressPool(); // Get memory address of USB device address pool #ifdef EXTRADEBUG - Notify(PSTR("\r\nBTD Init"), 0x80); + Notify(PSTR("\r\nBTD ConfigureDevice"), 0x80); #endif - // check if address has already been assigned to an instance - if (bAddress) { + + if (bAddress) { // Check if address has already been assigned to an instance #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nAddress in use"), 0x80); #endif return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; } - // Get pointer to pseudo device with address 0 assigned - p = addrPool.GetUsbDevicePtr(0); - + p = addrPool.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned if (!p) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nAddress not found"), 0x80); @@ -87,66 +79,97 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) { return USB_ERROR_EPINFO_IS_NULL; } - // Save old pointer to EP_RECORD of address 0 - oldep_ptr = p->epinfo; - - // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence - p->epinfo = epInfo; - + oldep_ptr = p->epinfo; // Save old pointer to EP_RECORD of address 0 + p->epinfo = epInfo; // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence p->lowspeed = lowspeed; + rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data - // Get device descriptor - rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data - - // Restore p->epinfo - p->epinfo = oldep_ptr; + p->epinfo = oldep_ptr; // Restore p->epinfo if (rcode) goto FailGetDevDescr; - // Allocate new address according to device class - bAddress = addrPool.AllocAddress(parent, false, port); + bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class - if (!bAddress) + if (!bAddress) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nOut of address space"), 0x80); +#endif return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; + } - // Extract Max Packet Size from device descriptor - epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; + epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; // Extract Max Packet Size from device descriptor + epInfo[1].epAddr = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; // Steal and abuse from epInfo structure to save memory - // Assign new address to the device - rcode = pUsb->setAddr(0, 0, bAddress); + return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET; + +FailGetDevDescr: +#ifdef DEBUG_USB_HOST + NotifyFailGetDevDescr(rcode); +#endif + rcode = USB_ERROR_FailGetDevDescr; + Release(); + return rcode; +}; + +uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) { + uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; + uint8_t rcode; + uint8_t num_of_conf = epInfo[1].epAddr; // Number of configurations + epInfo[1].epAddr = 0; + uint16_t PID; + uint16_t VID; + + AddressPool &addrPool = pUsb->GetAddressPool(); +#ifdef EXTRADEBUG + Notify(PSTR("\r\nBTD Init"), 0x80); +#endif + UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record + + if (!p) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nAddress not found"), 0x80); +#endif + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + } + + delay(300); // Assign new address to the device + + rcode = pUsb->setAddr(0, 0, bAddress); // Assign new address to the device if (rcode) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nsetAddr: "), 0x80); D_PrintHex (rcode, 0x80); #endif + p->lowspeed = false; goto Fail; } #ifdef EXTRADEBUG Notify(PSTR("\r\nAddr: "), 0x80); D_PrintHex (bAddress, 0x80); #endif - delay(300); // Spec says you should wait at least 200ms p->lowspeed = false; - //get pointer to assigned address record - p = addrPool.GetUsbDevicePtr(bAddress); - if (!p) + p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record + if (!p) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nAddress not found"), 0x80); +#endif return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + } p->lowspeed = lowspeed; - // Assign epInfo to epinfo pointer - only EP0 is known - rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); + rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known if (rcode) goto FailSetDevTblEntry; + VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor; PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct; if (VID == PS3_VID && (PID == PS3_PID || PID == PS3NAVIGATION_PID || PID == PS3MOVE_PID)) { - /* 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); + 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) goto FailSetConfDescr; @@ -184,8 +207,6 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) { Release(); // Release device return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; // Return } else { - num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; - // Check if attached device is a Bluetooth dongle and fill endpoint data structure // First interface in the configuration must have Bluetooth assigned Class/Subclass/Protocol // And 3 endpoints - interrupt-IN, bulk-IN, bulk-OUT, not necessarily in this order @@ -211,8 +232,6 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) { if (rcode) goto FailSetDevTblEntry; - delay(200); // Give time for address change - // Set Configuration Value rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, bConfNum); if (rcode) @@ -270,6 +289,28 @@ Fail: return rcode; } +void BTD::clearAllVariables() { + uint8_t i; + for (i = 0; i < BTD_MAX_ENDPOINTS; i++) { + epInfo[i].epAddr = 0; + epInfo[i].maxPktSize = (i) ? 0 : 8; + epInfo[i].epAttribs = 0; + epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER; + } + for (i = 0; i < BTD_NUMSERVICES; i++) { + if (btService[i]) + btService[i]->Reset(); // Reset all Bluetooth services + } + + connectToWii = false; + pairWithWii = false; + bAddress = 0; // Clear device address + bNumEP = 1; // Must have to be reset to 1 + qNextPollTime = 0; // Reset next poll time + pollInterval = 0; + bPollEnable = false; // Don't start polling before dongle is connected +} + /* Extracts interrupt-IN, bulk-IN, bulk-OUT endpoint information from config descriptor */ void BTD::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) { //ErrorMessage(PSTR("Conf.Val"),conf); @@ -323,15 +364,8 @@ void BTD::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) { /* Performs a cleanup after failed Init() attempt */ uint8_t BTD::Release() { - for (uint8_t i = 0; i < BTD_NUMSERVICES; i++) { - if (btService[i]) - btService[i]->Reset(); // Reset all Bluetooth services - } - + clearAllVariables(); // Set all variables, endpoint structs etc. to default values pUsb->GetAddressPool().FreeAddress(bAddress); - bAddress = 0; - bPollEnable = false; - bNumEP = 1; // must have to be reset to 1 return 0; } @@ -780,6 +814,10 @@ void BTD::HCI_task() { for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) l2capinbuf[i] = 0; + connectToWii = false; + incomingWii = false; + pairWithWii = false; + hci_state = HCI_SCANNING_STATE; } break; diff --git a/BTD.h b/BTD.h index 097b66f6..7927380f 100755 --- a/BTD.h +++ b/BTD.h @@ -162,6 +162,14 @@ public: BTD(USB *p); /** @name USBDeviceConfig implementation */ + /** + * Address assignment and basic initilization is done here. + * @param parent Hub number. + * @param port Port number on the hub. + * @param lowspeed Speed of the device. + * @return 0 on success. + */ + virtual uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed); /** * Initialize the Bluetooth dongle. * @param parent Hub number. @@ -455,6 +463,7 @@ protected: void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr); private: + void clearAllVariables(); // Set all variables, endpoint structs etc. to default values BluetoothService* btService[BTD_NUMSERVICES]; bool bPollEnable; From 90dba7193740d568b2efaf290c735c2cd42f3b94 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Mon, 7 Oct 2013 01:45:21 +0200 Subject: [PATCH 04/18] Moved PID and VID readings --- BTD.cpp | 9 +++------ BTD.h | 2 ++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/BTD.cpp b/BTD.cpp index 8c846303..993e2540 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -101,6 +101,9 @@ uint8_t BTD::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) { epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; // Extract Max Packet Size from device descriptor epInfo[1].epAddr = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; // Steal and abuse from epInfo structure to save memory + VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor; + PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct; + return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET; FailGetDevDescr: @@ -113,12 +116,9 @@ FailGetDevDescr: }; uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) { - uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; uint8_t rcode; uint8_t num_of_conf = epInfo[1].epAddr; // Number of configurations epInfo[1].epAddr = 0; - uint16_t PID; - uint16_t VID; AddressPool &addrPool = pUsb->GetAddressPool(); #ifdef EXTRADEBUG @@ -165,9 +165,6 @@ uint8_t BTD::Init(uint8_t parent, uint8_t port, bool lowspeed) { if (rcode) goto FailSetDevTblEntry; - VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor; - PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct; - if (VID == PS3_VID && (PID == PS3_PID || PID == PS3NAVIGATION_PID || PID == PS3MOVE_PID)) { 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) diff --git a/BTD.h b/BTD.h index 7927380f..a2e3d62d 100755 --- a/BTD.h +++ b/BTD.h @@ -466,6 +466,8 @@ private: void clearAllVariables(); // Set all variables, endpoint structs etc. to default values BluetoothService* btService[BTD_NUMSERVICES]; + uint16_t PID, VID; // PID and VID of device connected + bool bPollEnable; uint8_t pollInterval; From 332f56f46d76e57bf12425ba9b589dee9e28a574 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Tue, 8 Oct 2013 16:02:20 +0200 Subject: [PATCH 05/18] Fixed getButtonClick for analog buttons --- XBOXOLD.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/XBOXOLD.cpp b/XBOXOLD.cpp index f766e329..4c9bcb20 100644 --- a/XBOXOLD.cpp +++ b/XBOXOLD.cpp @@ -299,9 +299,11 @@ bool XBOXOLD::getButtonClick(Button b) { uint8_t button; if (b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) { // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]); - if (buttonClicked[button]) + if (buttonClicked[button]) { buttonClicked[button] = false; - return buttonClicked[button]; + return true; + } + return false; } button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]); // Digital buttons From 02b685e329839ddc1b0ba9805d9a320e02e76c87 Mon Sep 17 00:00:00 2001 From: "Andrew J. Kroll" Date: Tue, 8 Oct 2013 11:36:15 -0400 Subject: [PATCH 06/18] lock settings for spi (unused at this time) --- settings.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/settings.h b/settings.h index ba5da5c5..0d780e18 100644 --- a/settings.h +++ b/settings.h @@ -40,6 +40,9 @@ /* Set this to 1 if you are using a Black Widdow */ #define USE_UHS_BLACK_WIDDOW 0 +/* Set this to 1 if you are using xmem2 and expanded memory and multitasking */ +#define USE_XMEM_SPI_LOCK 0 + //////////////////////////////////////////////////////////////////////////////// // MASS STORAGE //////////////////////////////////////////////////////////////////////////////// @@ -75,4 +78,11 @@ #include #endif +#if USE_XMEM_SPI_LOCK +#include +#else +#define XMEM_ACQUIRE_SPI() (void(0)) +#define XMEM_RELEASE_SPI() (void(0)) +#endif + #endif /* SETTINGS_H */ From 7990c32ad63d087a042842fca8b504da633ff920 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Tue, 8 Oct 2013 18:07:36 +0200 Subject: [PATCH 07/18] Don't call init if an error is returned --- Usb.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/Usb.cpp b/Usb.cpp index d1a3592c..3ffbfbe4 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -580,23 +580,24 @@ uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lo devConfig[parent]->ResetHubPort(port); } } - rcode = devConfig[driver]->Init(parent, port, lowspeed); - if (rcode == hrJERR) { // Some devices returns this when plugged in - trying to initialize the device again usually works - delay(100); - devConfig[driver]->ConfigureDevice(parent, port, lowspeed); // Just ignore the returned value + if (!rcode || rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) { rcode = devConfig[driver]->Init(parent, port, lowspeed); - } - if (rcode) { - // Issue a bus reset, because the device may be in a limbo state - if (parent == 0) { - // Send a bus reset on the root interface. - regWr(rHCTL, bmBUSRST); //issue bus reset - delay(102); // delay 102ms, compensate for clock inaccuracy. - } else { - // reset parent port - devConfig[parent]->ResetHubPort(port); + if (rcode == hrJERR) { // Some devices returns this when plugged in - trying to initialize the device again usually works + delay(100); + devConfig[driver]->ConfigureDevice(parent, port, lowspeed); // Just ignore the returned value + rcode = devConfig[driver]->Init(parent, port, lowspeed); + } + if (rcode) { + // Issue a bus reset, because the device may be in a limbo state + if (parent == 0) { + // Send a bus reset on the root interface. + regWr(rHCTL, bmBUSRST); //issue bus reset + delay(102); // delay 102ms, compensate for clock inaccuracy. + } else { + // reset parent port + devConfig[parent]->ResetHubPort(port); + } } - } return rcode; } From 6adc0843d573070c5b68f8a2e530fb5a3639984c Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Tue, 8 Oct 2013 18:14:16 +0200 Subject: [PATCH 08/18] More elegant way of doing: 7990c32ad63d087a042842fca8b504da633ff920 --- Usb.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Usb.cpp b/Usb.cpp index 3ffbfbe4..d7fd44ce 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -579,24 +579,24 @@ uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lo // reset parent port devConfig[parent]->ResetHubPort(port); } - } - if (!rcode || rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) { + } else if (rcode) + return rcode; + + rcode = devConfig[driver]->Init(parent, port, lowspeed); + if (rcode == hrJERR) { // Some devices returns this when plugged in - trying to initialize the device again usually works + delay(100); + devConfig[driver]->ConfigureDevice(parent, port, lowspeed); // Just ignore the returned value rcode = devConfig[driver]->Init(parent, port, lowspeed); - if (rcode == hrJERR) { // Some devices returns this when plugged in - trying to initialize the device again usually works - delay(100); - devConfig[driver]->ConfigureDevice(parent, port, lowspeed); // Just ignore the returned value - rcode = devConfig[driver]->Init(parent, port, lowspeed); - } - if (rcode) { - // Issue a bus reset, because the device may be in a limbo state - if (parent == 0) { - // Send a bus reset on the root interface. - regWr(rHCTL, bmBUSRST); //issue bus reset - delay(102); // delay 102ms, compensate for clock inaccuracy. - } else { - // reset parent port - devConfig[parent]->ResetHubPort(port); - } + } + if (rcode) { + // Issue a bus reset, because the device may be in a limbo state + if (parent == 0) { + // Send a bus reset on the root interface. + regWr(rHCTL, bmBUSRST); //issue bus reset + delay(102); // delay 102ms, compensate for clock inaccuracy. + } else { + // reset parent port + devConfig[parent]->ResetHubPort(port); } } return rcode; From 3b733fc962fd7412bc7b2e2bbd986f2993e8e9e8 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Tue, 8 Oct 2013 18:27:51 +0200 Subject: [PATCH 09/18] Better way to retry when hrJERR is returned --- Usb.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Usb.cpp b/Usb.cpp index d7fd44ce..f1e6bc49 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -566,10 +566,10 @@ uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) { }; uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed) { - uint8_t rcode = 0; //printf("AttemptConfig: parent = %i, port = %i\r\n", parent, port); - rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed); +again: + uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed); if (rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) { if (parent == 0) { // Send a bus reset on the root interface. @@ -585,8 +585,7 @@ uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lo rcode = devConfig[driver]->Init(parent, port, lowspeed); if (rcode == hrJERR) { // Some devices returns this when plugged in - trying to initialize the device again usually works delay(100); - devConfig[driver]->ConfigureDevice(parent, port, lowspeed); // Just ignore the returned value - rcode = devConfig[driver]->Init(parent, port, lowspeed); + goto again; } if (rcode) { // Issue a bus reset, because the device may be in a limbo state From 01e0e6cf2d0aea1da8512d979c904dae889efe15 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Tue, 8 Oct 2013 18:52:37 +0200 Subject: [PATCH 10/18] Don't clear pairWithWii --- BTD.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BTD.cpp b/BTD.cpp index 993e2540..921b0714 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -300,7 +300,7 @@ void BTD::clearAllVariables() { } connectToWii = false; - pairWithWii = false; + incomingWii = false; bAddress = 0; // Clear device address bNumEP = 1; // Must have to be reset to 1 qNextPollTime = 0; // Reset next poll time @@ -413,7 +413,7 @@ void BTD::HCI_event_task() { break; case EV_INQUIRY_COMPLETE: - if (inquiry_counter >= 5) { + if (inquiry_counter >= 5 && pairWithWii) { inquiry_counter = 0; #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nCouldn't find Wiimote"), 0x80); From 81ed31e1fe6512be4598747718381973098027db Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Tue, 8 Oct 2013 19:05:08 +0200 Subject: [PATCH 11/18] Check for hrJERR after ConfigureDevice too --- Usb.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Usb.cpp b/Usb.cpp index f1e6bc49..caa931ce 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -579,6 +579,9 @@ again: // reset parent port devConfig[parent]->ResetHubPort(port); } + } else if (rcode == hrJERR) { // Some devices returns this when plugged in - trying to initialize the device again usually works + delay(100); + goto again; } else if (rcode) return rcode; From 7a02a0762054cde165efc176e7100d18b9c26b33 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Tue, 8 Oct 2013 19:51:20 +0200 Subject: [PATCH 12/18] Don't change error code if it returned hrJERR --- BTD.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BTD.cpp b/BTD.cpp index 921b0714..5ed762a5 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -110,7 +110,8 @@ FailGetDevDescr: #ifdef DEBUG_USB_HOST NotifyFailGetDevDescr(rcode); #endif - rcode = USB_ERROR_FailGetDevDescr; + if (rcode != hrJERR) + rcode = USB_ERROR_FailGetDevDescr; Release(); return rcode; }; From a312a45d0b30e68db5ba3ee68e8bc9597edc6ca3 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Tue, 8 Oct 2013 19:51:41 +0200 Subject: [PATCH 13/18] Print if connection failed --- BTD.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BTD.cpp b/BTD.cpp index 5ed762a5..a714b5d6 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -467,7 +467,7 @@ void BTD::HCI_event_task() { hci_handle = hcibuf[3] | ((hcibuf[4] & 0x0F) << 8); // store the handle for the ACL connection hci_event_flag |= HCI_FLAG_CONN_COMPLETE; // set connection complete flag } -#ifdef EXTRADEBUG +#ifdef DEBUG_USB_HOST else { Notify(PSTR("\r\nConnection Failed"), 0x80); hci_state = HCI_CHECK_WII_SERVICE; From a21edc66989f622d4909750989b9842fb4984f9b Mon Sep 17 00:00:00 2001 From: "Andrew J. Kroll" Date: Tue, 8 Oct 2013 14:25:23 -0400 Subject: [PATCH 14/18] Speed up core task --- Usb.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Usb.cpp b/Usb.cpp index d1a3592c..4566733e 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -475,7 +475,7 @@ void USB::Task(void) //USB state machine case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device if (delay < millis()) usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE; - break; + else break; // don't fall through case USB_ATTACHED_SUBSTATE_RESET_DEVICE: regWr(rHCTL, bmBUSRST); //issue bus reset usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE; @@ -501,7 +501,7 @@ void USB::Task(void) //USB state machine break; case USB_ATTACHED_SUBSTATE_WAIT_RESET: if (delay < millis()) usb_task_state = USB_STATE_CONFIGURING; - break; + else break; // don't fall through case USB_STATE_CONFIGURING: //Serial.print("\r\nConf.LS: "); @@ -656,7 +656,7 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) { epInfo.epAttribs = 0; epInfo.bmNakPower = USB_NAK_MAX_POWER; - delay(2000); + //delay(2000); AddressPool &addrPool = GetAddressPool(); // Get pointer to pseudo device with address 0 assigned p = addrPool.GetUsbDevicePtr(0); From 42fc48d12920ab3ae8796e0ca02e01f0435d21ff Mon Sep 17 00:00:00 2001 From: "Andrew J. Kroll" Date: Tue, 8 Oct 2013 15:52:24 -0400 Subject: [PATCH 15/18] locks and constructor/init fixes --- usbhost.h | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/usbhost.h b/usbhost.h index f6ee510f..8015d379 100644 --- a/usbhost.h +++ b/usbhost.h @@ -91,31 +91,26 @@ template< typename SS, typename INTR > /* constructor */ template< typename SS, typename INTR > MAX3421e< SS, INTR >::MAX3421e() { - /* pin and peripheral setup */ - SS::SetDirWrite(); - SS::Set(); - spi::init(); - INTR::SetDirRead(); +// Leaving ADK hardware setup in here, for now. This really belongs with the other parts. #ifdef BOARD_MEGA_ADK /* For Mega ADK, which has Max3421e on-board, set MAX_RESET to Output mode, and pull Reset to HIGH */ DDRJ |= _BV(PJ2); PORTJ &= ~_BV(PJ2); PORTJ |= _BV(PJ2); #endif - - /* MAX3421E - full-duplex SPI, level interrupt */ - regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL | GPX_VBDET)); }; /* write single byte into MAX3421 register */ template< typename SS, typename INTR > void MAX3421e< SS, INTR >::regWr(uint8_t reg, uint8_t data) { + XMEM_ACQUIRE_SPI(); SS::Clear(); SPDR = (reg | 0x02); while(!(SPSR & (1 << SPIF))); SPDR = data; while(!(SPSR & (1 << SPIF))); SS::Set(); + XMEM_RELEASE_SPI(); return; }; /* multiple-byte write */ @@ -123,6 +118,7 @@ void MAX3421e< SS, INTR >::regWr(uint8_t reg, uint8_t data) { /* returns a pointer to memory position after last written */ template< typename SS, typename INTR > uint8_t* MAX3421e< SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) { + XMEM_ACQUIRE_SPI(); SS::Clear(); SPDR = (reg | 0x02); //set WR bit and send register number while(nbytes--) { @@ -132,6 +128,7 @@ uint8_t* MAX3421e< SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* dat } while(!(SPSR & (1 << SPIF))); SS::Set(); + XMEM_RELEASE_SPI(); return( data_p); } /* GPIO write */ @@ -149,19 +146,23 @@ void MAX3421e< SS, INTR >::gpioWr(uint8_t data) { /* single host register read */ template< typename SS, typename INTR > uint8_t MAX3421e< SS, INTR >::regRd(uint8_t reg) { + XMEM_ACQUIRE_SPI(); SS::Clear(); SPDR = reg; while(!(SPSR & (1 << SPIF))); SPDR = 0; //send empty byte while(!(SPSR & (1 << SPIF))); SS::Set(); - return( SPDR); + uint8_t rv = SPDR; + XMEM_RELEASE_SPI(); + return(rv); } /* multiple-byte register read */ /* returns a pointer to a memory position after last read */ template< typename SS, typename INTR > uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) { + XMEM_ACQUIRE_SPI(); SS::Clear(); SPDR = reg; while(!(SPSR & (1 << SPIF))); //wait @@ -182,6 +183,7 @@ uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* dat } #endif SS::Set(); + XMEM_RELEASE_SPI(); return( data_p); } /* GPIO read. See gpioWr for explanation */ @@ -214,13 +216,24 @@ uint16_t MAX3421e< SS, INTR >::reset() { /* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */ template< typename SS, typename INTR > int8_t MAX3421e< SS, INTR >::Init() { + XMEM_ACQUIRE_SPI(); + // Moved here. + // you really should not init hardware in the constructor when it involves locks. + // Also avoids the vbus flicker issue confusing some devices. + /* pin and peripheral setup */ + SS::SetDirWrite(); + SS::Set(); + spi::init(); + INTR::SetDirRead(); + XMEM_RELEASE_SPI(); + /* MAX3421E - full-duplex SPI, level interrupt */ + // GPX pin on. Moved here, otherwise we flicker the vbus. + regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL)); + if(reset() == 0) { //OSCOKIRQ hasn't asserted in time return( -1); } - // GPX pin on. - regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL)); - regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST); // set pull-downs, Host regWr(rHIEN, bmCONDETIE | bmFRAMEIE); //connection detection @@ -240,6 +253,19 @@ int8_t MAX3421e< SS, INTR >::Init() { /* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */ template< typename SS, typename INTR > int8_t MAX3421e< SS, INTR >::Init(int mseconds) { + XMEM_ACQUIRE_SPI(); + // Moved here. + // you really should not init hardware in the constructor when it involves locks. + // Also avoids the vbus flicker issue confusing some devices. + /* pin and peripheral setup */ + SS::SetDirWrite(); + SS::Set(); + spi::init(); + INTR::SetDirRead(); + XMEM_RELEASE_SPI(); + /* MAX3421E - full-duplex SPI, level interrupt, vbus off */ + regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL | GPX_VBDET)); + if(reset() == 0) { //OSCOKIRQ hasn't asserted in time return( -1); } From 5cde2e07d351412172e63b52267e6fb4739c7f56 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Wed, 9 Oct 2013 17:13:37 +0200 Subject: [PATCH 16/18] Arduino Mega ADK will be activated automatically in Arduino 1.5.5 See: https://github.com/arduino/Arduino/pull/1605 --- README.md | 1 + avrpins.h | 2 +- settings.h | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e2ce776a..f282ce5c 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ Currently the following boards are supported by the library: The following boards need to be activated manually in [settings.h](settings.h): * Arduino Mega ADK + * If you are using Arduino 1.5.5 or newer there is no need to activate the Arduino Mega ADK manually * Black Widdow Simply set the corresponding value to 1 instead of 0. diff --git a/avrpins.h b/avrpins.h index 17f832b5..61ae5883 100644 --- a/avrpins.h +++ b/avrpins.h @@ -23,7 +23,7 @@ e-mail : support@circuitsathome.com #define _avrpins_h_ // Support for these boards needs to be manually activated in settings.h or in a makefile -#if !defined(BOARD_MEGA_ADK) && defined(__AVR_ATmega2560__) && USE_UHS_MEGA_ADK +#if !defined(BOARD_MEGA_ADK) && defined(__AVR_ATmega2560__) && (USE_UHS_MEGA_ADK || defined(ARDUINO_AVR_ADK)) #define BOARD_MEGA_ADK #elif !defined(BOARD_BLACK_WIDDOW) && USE_UHS_BLACK_WIDDOW #define BOARD_BLACK_WIDDOW diff --git a/settings.h b/settings.h index 40f97979..89a765f9 100644 --- a/settings.h +++ b/settings.h @@ -29,7 +29,7 @@ //////////////////////////////////////////////////////////////////////////////// /* Set this to 1 if you are using an Arduino Mega ADK board with MAX3421e built-in */ -#define USE_UHS_MEGA_ADK 0 +#define USE_UHS_MEGA_ADK 0 // If you are using Arduino 1.5.5 or newer there is no need to do this manually /* Set this to 1 if you are using a Black Widdow */ #define USE_UHS_BLACK_WIDDOW 0 From cdeaf9e0f26e0bc1bdf43e9d7179b93c5eaaa821 Mon Sep 17 00:00:00 2001 From: "Andrew J. Kroll" Date: Sat, 12 Oct 2013 10:36:03 -0400 Subject: [PATCH 17/18] better wording --- settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.h b/settings.h index 40f97979..bedc7700 100644 --- a/settings.h +++ b/settings.h @@ -34,7 +34,7 @@ /* Set this to 1 if you are using a Black Widdow */ #define USE_UHS_BLACK_WIDDOW 0 -/* Set this to 1 if you are using xmem2 and expanded memory and multitasking */ +/* Set this to a one to use the xmem2 lock. This is needed for multitasking and threading */ #define USE_XMEM_SPI_LOCK 0 //////////////////////////////////////////////////////////////////////////////// From 4d145ca3e0d81ca8f65c692d4a0671f5b3a26bd0 Mon Sep 17 00:00:00 2001 From: "Andrew J. Kroll" Date: Tue, 15 Oct 2013 21:16:34 -0400 Subject: [PATCH 18/18] Multitask API check --- settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.h b/settings.h index 985664c4..add3ee03 100644 --- a/settings.h +++ b/settings.h @@ -69,7 +69,7 @@ #include #endif -#if USE_XMEM_SPI_LOCK +#if USE_XMEM_SPI_LOCK | defined(USE_MULTIPLE_APP_API) #include #else #define XMEM_ACQUIRE_SPI() (void(0))