diff --git a/PS4Parser.cpp b/PS4Parser.cpp index 106d04ed..ca6adce4 100644 --- a/PS4Parser.cpp +++ b/PS4Parser.cpp @@ -62,7 +62,7 @@ uint8_t PS4Parser::getAnalogHat(AnalogHatEnum a) { } void PS4Parser::Parse(uint8_t len, uint8_t *buf) { - if (len > 0 && buf) { + if (len > 1 && buf) { #ifdef PRINTREPORT Notify(PSTR("\r\n"), 0x80); for (uint8_t i = 0; i < len; i++) { @@ -72,10 +72,17 @@ void PS4Parser::Parse(uint8_t len, uint8_t *buf) { #endif if (buf[0] == 0x01) // Check report ID - memcpy(&ps4Data, buf + 1, min(len - 1, sizeof(ps4Data))); - else if (buf[0] == 0x11) // This report is send via Bluetooth, it has an offset of 2 compared to the USB data - memcpy(&ps4Data, buf + 3, min(len - 3, sizeof(ps4Data))); - else { + memcpy(&ps4Data, buf + 1, min((uint8_t)(len - 1), sizeof(ps4Data))); + else if (buf[0] == 0x11) { // This report is send via Bluetooth, it has an offset of 2 compared to the USB data + if (len < 4) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nReport is too short: "), 0x80); + D_PrintHex (len, 0x80); +#endif + return; + } + memcpy(&ps4Data, buf + 3, min((uint8_t)(len - 3), sizeof(ps4Data))); + } else { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nUnknown report id: "), 0x80); D_PrintHex (buf[0], 0x80); diff --git a/PSBuzz.cpp b/PSBuzz.cpp index aa883712..498164d5 100644 --- a/PSBuzz.cpp +++ b/PSBuzz.cpp @@ -21,7 +21,7 @@ //#define PRINTREPORT // Uncomment to print the report send by the PS Buzz Controllers void PSBuzz::ParseHIDData(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) { - if (HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID && len > 0 && buf) { + if (HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID && len > 2 && buf) { #ifdef PRINTREPORT Notify(PSTR("\r\n"), 0x80); for (uint8_t i = 0; i < len; i++) { @@ -29,7 +29,7 @@ void PSBuzz::ParseHIDData(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) { Notify(PSTR(" "), 0x80); } #endif - memcpy(&psbuzzButtons, buf + 2, min(len - 2, sizeof(psbuzzButtons))); + memcpy(&psbuzzButtons, buf + 2, min((uint8_t)(len - 2), sizeof(psbuzzButtons))); if (psbuzzButtons.val != oldButtonState.val) { // Check if anything has changed buttonClickState.val = psbuzzButtons.val & ~oldButtonState.val; // Update click state variable diff --git a/README.md b/README.md index 864516e9..49cd83e0 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,6 @@ Currently the following boards are supported by the library: * All official Arduino AVR boards (Uno, Duemilanove, Mega, Mega 2560, Mega ADK, Leonardo etc.) * Arduino Due, Intel Galileo, Intel Galileo 2, and Intel Edison - * If you are using the Arduino Due, Intel Galileo or Intel Galileo 2, then you must include the Arduino SPI library like so: ```#include ``` in your .ino file. * Note that the Intel Galileo uses pin 2 and 3 as INT and SS pin respectively by default, so some modifications to the shield are needed. See the "Interface modifications" section in the [hardware manual](https://www.circuitsathome.com/usb-host-shield-hardware-manual) for more information. * Teensy (Teensy++ 1.0, Teensy 2.0, Teensy++ 2.0, and Teensy 3.x) * Note if you are using the Teensy 3.x you should download this SPI library as well: . You should then add ```#include ``` to your .ino file. @@ -114,7 +113,6 @@ Currently the following boards are supported by the library: * Sanguino * Black Widdow * RedBearLab nRF51822 - * If you are using the RedBearLab nRF51822, then you must include the RedBearLab SPI library like so: ```#include ``` in your .ino file. * Digilent chipKIT * Please see: . @@ -347,3 +345,7 @@ LeftHatX: 0 LeftHatY: 0 RightHatX: 0 RightHatY: 0 ``` * This means that your dongle does not support 2.0+EDR, so you will need another dongle. Please see the following [list](https://github.com/felis/USB_Host_Shield_2.0/wiki/Bluetooth-dongles) for tested working dongles. + +> When compiling I am getting the following error: "fatal error: SPI.h: No such file or directory". + +* Please make sure to include the SPI library like so: ```#include ``` in your .ino file. diff --git a/Usb.cpp b/Usb.cpp index cd1c3496..14272588 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -92,7 +92,7 @@ uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_l 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--; + (*nak_limit)--; /* USBTRACE2("\r\nAddress: ", addr); USBTRACE2(" EP: ", ep); diff --git a/cdc_XR21B1411.h b/cdc_XR21B1411.h index 347f0df6..c3262754 100644 --- a/cdc_XR21B1411.h +++ b/cdc_XR21B1411.h @@ -55,12 +55,12 @@ e-mail : support@circuitsathome.com #define XR_REG_ERROR_STATUS (0x0C09U) // ERROR STATUS REGISTER #define XR_REG_ERROR_STATUS_MASK (0x00F8U) // ERROR STATUS BITMASK -#define XR_REG_ERROR_STATUS_ERROR (0x0070U) // ERROR STATUS ERROR BITMASK -#define XR_REG_ERROR_STATUS_BREAK (0x0008U) // BREAK HAS BEEN DETECTED -#define XR_REG_ERROR_STATUS_OVERRUN (0x0010U) // RX OVERRUN ERROR -#define XR_REG_ERROR_STATUS_PARITY (0x0020U) // PARITY ERROR -#define XR_REG_ERROR_STATUS_FRAME (0x0040U) // FRAMING ERROR -#define XR_REG_ERROR_STATUS_BREAK (0x0080U) // BREAK IS BEING DETECTED +#define XR_REG_ERROR_STATUS_ERROR (0x0078U) // ERROR STATUS ERROR BITMASK +#define XR_REG_ERROR_STATUS_BREAK (0x0008U) // BREAK ERROR HAS BEEN DETECTED +#define XR_REG_ERROR_STATUS_FRAME (0x0010U) // FRAMING ERROR HAS BEEN DETECTED +#define XR_REG_ERROR_STATUS_PARITY (0x0020U) // PARITY ERROR HAS BEEN DETECTED +#define XR_REG_ERROR_STATUS_OVERRUN (0x0040U) // RX OVERRUN ERROR HAS BEEN DETECTED +#define XR_REG_ERROR_STATUS_BREAK_STATUS (0x0080U) // BREAK CONDITION IS CURRENTLY BEING DETECTED #define XR_REG_TX_BREAK (0x0C0AU) // TRANSMIT BREAK. 0X0001-0XFFE TIME IN MS, 0X0000 STOP, 0X0FFF BREAK ON diff --git a/cdcprolific.cpp b/cdcprolific.cpp index 6490c40e..eceb1df9 100644 --- a/cdcprolific.cpp +++ b/cdcprolific.cpp @@ -30,6 +30,9 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) { UsbDevice *p = NULL; EpInfo *oldep_ptr = NULL; uint8_t num_of_conf; // number of configurations +#ifdef PL2303_COMPAT + enum pl2303_type pltype = unknown; +#endif AddressPool &addrPool = pUsb->GetAddressPool(); @@ -66,9 +69,21 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) { if(rcode) goto FailGetDevDescr; - if(udd->idVendor != PL_VID && udd->idProduct != PL_PID) + if(udd->idVendor != PL_VID && CHECK_PID(udd->idProduct)) return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; + /* determine chip variant */ +#ifdef PL2303_COMPAT + if(udd->bDeviceClass == 0x02 ) + pltype = type_0; + else if(udd->bMaxPacketSize0 == 0x40 ) + pltype = rev_HX; + else if(udd->bDeviceClass == 0x00) + pltype = type_1; + else if(udd->bDeviceClass == 0xff) + pltype = type_1; +#endif + // Save type of PL chip wPLType = udd->bcdDevice; @@ -145,6 +160,28 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) { if(rcode) goto FailSetConfDescr; +#ifdef PL2303_COMPAT + /* Shamanic dance - sending Prolific init data as-is */ + vendorRead( 0x84, 0x84, 0, buf ); + vendorWrite( 0x04, 0x04, 0 ); + vendorRead( 0x84, 0x84, 0, buf ); + vendorRead( 0x83, 0x83, 0, buf ); + vendorRead( 0x84, 0x84, 0, buf ); + vendorWrite( 0x04, 0x04, 1 ); + vendorRead( 0x84, 0x84, 0, buf); + vendorRead( 0x83, 0x83, 0, buf); + vendorWrite( 0, 0, 1 ); + vendorWrite( 1, 0, 0 ); + if( pltype == rev_HX ) { + vendorWrite( 2, 0, 0x44 ); + vendorWrite( 0x06, 0x06, 0 ); // From W7 init + } + else { + vendorWrite( 2, 0, 0x24 ); + } + /* Shamanic dance end */ +#endif + /* Calling post-init callback */ rcode = pAsync->OnInit(this); if(rcode) diff --git a/cdcprolific.h b/cdcprolific.h index 32566585..49914664 100644 --- a/cdcprolific.h +++ b/cdcprolific.h @@ -19,8 +19,10 @@ e-mail : support@circuitsathome.com #include "cdcacm.h" +//#define PL2303_COMPAT // Uncomment it if you have compatibility problems + #define PL_VID 0x067B -#define PL_PID ( 0x2303 || 0x0609 ) +#define CHECK_PID(pid) ( pid != 0x2303 && pid != 0x0609 ) //#define PL_PID 0x0609 @@ -109,8 +111,9 @@ enum tXO_State { enum pl2303_type { unknown, - type_1, /* don't know the difference between type 0 and */ - rev_X, /* type 1, until someone from prolific tells us... */ + type_0, /* don't know the difference between type 0 and */ + type_1, /* type 1, until someone from prolific tells us... */ + rev_X, rev_HX, /* HX version of the pl2303 chip */ rev_H }; @@ -130,6 +133,27 @@ public: //// UsbConfigXtracter implementation //virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); + +#ifdef PL2303_COMPAT +private: + /* Prolific proprietary requests */ + uint8_t vendorRead( uint8_t val_lo, uint8_t val_hi, uint16_t index, uint8_t* buf ); + uint8_t vendorWrite( uint8_t val_lo, uint8_t val_hi, uint8_t index ); +#endif }; +#ifdef PL2303_COMPAT +/* vendor read request */ +inline uint8_t PL2303::vendorRead( uint8_t val_lo, uint8_t val_hi, uint16_t index, uint8_t* buf ) +{ + return( pUsb->ctrlReq(bAddress, 0, VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, val_lo, val_hi, index, 1, 1, buf, NULL )); +} + +/* vendor write request */ +inline uint8_t PL2303::vendorWrite( uint8_t val_lo, uint8_t val_hi, uint8_t index ) +{ + return( pUsb->ctrlReq(bAddress, 0, VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, val_lo, val_hi, index, 0, 0, NULL, NULL )); +} +#endif + #endif // __CDCPROLIFIC_H__ diff --git a/usbhost.h b/usbhost.h index 0a2b7bff..eba480e6 100644 --- a/usbhost.h +++ b/usbhost.h @@ -30,11 +30,7 @@ e-mail : support@circuitsathome.com /* SPI initialization */ template< typename SPI_CLK, typename SPI_MOSI, typename SPI_MISO, typename SPI_SS > class SPi { public: -#if SPI_HAS_TRANSACTION - static void init() { - SPI.begin(); // The SPI library with transaction will take care of setting up the pins - settings is set in beginTransaction() - } -#elif USING_SPI4TEENSY3 +#if USING_SPI4TEENSY3 static void init() { // spi4teensy3 inits everything for us, except /SS // CLK, MOSI and MISO are hard coded for now. @@ -43,6 +39,10 @@ public: SPI_SS::SetDirWrite(); SPI_SS::Set(); } +#elif SPI_HAS_TRANSACTION + static void init() { + SPI.begin(); // The SPI library with transaction will take care of setting up the pins - settings is set in beginTransaction() + } #elif !defined(SPDR) static void init() { SPI_SS::SetDirWrite(); @@ -157,16 +157,16 @@ void MAX3421e< SPI_SS, INTR >::regWr(uint8_t reg, uint8_t data) { #endif SPI_SS::Clear(); -#if SPI_HAS_TRANSACTION - uint8_t c[2]; - c[0] = reg | 0x02; - c[1] = data; - SPI.transfer(c, 2); -#elif USING_SPI4TEENSY3 +#if USING_SPI4TEENSY3 uint8_t c[2]; c[0] = reg | 0x02; c[1] = data; spi4teensy3::send(c, 2); +#elif SPI_HAS_TRANSACTION + uint8_t c[2]; + c[0] = reg | 0x02; + c[1] = data; + SPI.transfer(c, 2); #elif !defined(SPDR) SPI.transfer(reg | 0x02); SPI.transfer(data); @@ -195,14 +195,14 @@ uint8_t* MAX3421e< SPI_SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* #endif SPI_SS::Clear(); -#if SPI_HAS_TRANSACTION - SPI.transfer(reg | 0x02); - SPI.transfer(data_p, nbytes); - data_p += nbytes; -#elif USING_SPI4TEENSY3 +#if USING_SPI4TEENSY3 spi4teensy3::send(reg | 0x02); spi4teensy3::send(data_p, nbytes); data_p += nbytes; +#elif SPI_HAS_TRANSACTION + SPI.transfer(reg | 0x02); + SPI.transfer(data_p, nbytes); + data_p += nbytes; #elif defined(__ARDUINO_X86__) SPI.transfer(reg | 0x02); SPI.transferBuffer(data_p, NULL, nbytes); @@ -253,14 +253,14 @@ uint8_t MAX3421e< SPI_SS, INTR >::regRd(uint8_t reg) { #endif SPI_SS::Clear(); -#if !defined(SPDR) || SPI_HAS_TRANSACTION - SPI.transfer(reg); - uint8_t rv = SPI.transfer(0); // Send empty byte - SPI_SS::Set(); -#elif USING_SPI4TEENSY3 +#if USING_SPI4TEENSY3 spi4teensy3::send(reg); uint8_t rv = spi4teensy3::receive(); SPI_SS::Set(); +#elif !defined(SPDR) || SPI_HAS_TRANSACTION + SPI.transfer(reg); + uint8_t rv = SPI.transfer(0); // Send empty byte + SPI_SS::Set(); #else SPDR = reg; while(!(SPSR & (1 << SPIF))); @@ -287,15 +287,15 @@ uint8_t* MAX3421e< SPI_SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* #endif SPI_SS::Clear(); -#if SPI_HAS_TRANSACTION +#if USING_SPI4TEENSY3 + spi4teensy3::send(reg); + spi4teensy3::receive(data_p, nbytes); + data_p += nbytes; +#elif SPI_HAS_TRANSACTION SPI.transfer(reg); memset(data_p, 0, nbytes); // Make sure we send out empty bytes SPI.transfer(data_p, nbytes); data_p += nbytes; -#elif USING_SPI4TEENSY3 - spi4teensy3::send(reg); - spi4teensy3::receive(data_p, nbytes); - data_p += nbytes; #elif defined(__ARDUINO_X86__) SPI.transfer(reg); SPI.transferBuffer(NULL, data_p, nbytes);