Hi folks,
I'm trying to port support for the PS3 Controller to the Arduinio Due using it's hosting feature. My code is inspired from the work of the folks over at circuits-at-home. Here's the inspirational source code that I started from.
Currently, I can read the device descriptors, but I'm getting a STALL message when I try to set the configuration 200ms afterwards.
I've chopped up a USB cable to probe the lines with a logic analyzer. Here's the raw information being sent for the setConf function:
Time [s], Analyzer Name, Decoded Protocol Result
1.540221,USB LS and FS,SYNC
1.540222,USB LS and FS,PID SETUP
1.540223,USB LS and FS,Address=0x00 Endpoint=0x00
1.540224,USB LS and FS,CRC OK 0x02
1.540224,USB LS and FS,EOP
1.540225,USB LS and FS,SYNC
1.540225,USB LS and FS,PID DATA0
1.540226,USB LS and FS,bmRequestType=0x00 Data direction=No data, Type=Standard, Recipient=Device
1.540227,USB LS and FS,bRequest=0x09 SET_CONFIGURATION
1.540227,USB LS and FS,wValue=0x0001
1.540229,USB LS and FS,wIndex=0x0000
1.540230,USB LS and FS,wLength=0x0000
1.540231,USB LS and FS,CRC OK 0x2527
1.540233,USB LS and FS,EOP
1.540233,USB LS and FS,SYNC
1.540234,USB LS and FS,PID ACK
1.540234,USB LS and FS,EOP
and then a few micros later...
1.540398,USB LS and FS,SYNC
1.540399,USB LS and FS,PID NAK
1.540399,USB LS and FS,EOP
1.540400,USB LS and FS,SYNC
1.540401,USB LS and FS,PID IN
1.540402,USB LS and FS,Address=0x00 Endpoint=0x00
1.540403,USB LS and FS,CRC OK 0x02
1.540403,USB LS and FS,EOP
1.540404,USB LS and FS,SYNC
1.540404,USB LS and FS,PID STALL
1.540405,USB LS and FS,EOP
I'm guessing I'm making some wrong assumptions about how USB works, so here are my questions:
- Does anyone see anything egregiously wrong with this setup?
- I omitted changing the USB device address, which the first example does do. Is that necessary?
- Does the Arduino Due need any additional hardware besides a cable for USB Hosting? Currently, it's just plugged in via a usb cable and powered externally from a 9V wall wart.
Here's a truncated version of the code, for reference. Thanks for taking a look!
#define PS3_ADDR 0
USBHost my_usb_host;
void loop() {
my_usb_host.Task();
if( my_usb_host.getUsbTaskState() == USB_STATE_CONFIGURING ) { //wait for addressing state
Serial.println("Initializing controller.");
PS3_init();
process_report();
my_usb_host.setUsbTaskState( USB_STATE_RUNNING );
}
if( my_usb_host.getUsbTaskState() == USB_STATE_RUNNING ) { //poll the PS3 Controller
PS3_poll();
}
delay(100);
}
void PS3_init( void )
{
byte rcode = 0; //return code
byte i;
USB_DEVICE_DESCRIPTOR* device_descriptor;
/* Initialize data structures for endpoints of device */
ep_record[ CONTROL_PIPE ].epAddr = 0x00;
ep_record[ OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint
ep_record[ OUTPUT_PIPE ].Attr = EP_INTERRUPT;
ep_record[ OUTPUT_PIPE ].MaxPktSize = EP_MAXPKTSIZE;
ep_record[ OUTPUT_PIPE ].Interval = EP_POLL;
//ep_record[ OUTPUT_PIPE ].sndToggle = bmSNDTOG0;
//ep_record[ OUTPUT_PIPE ].rcvToggle = bmRCVTOG0;
ep_record[ INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint
ep_record[ INPUT_PIPE ].Attr = EP_INTERRUPT;
ep_record[ INPUT_PIPE ].MaxPktSize = EP_MAXPKTSIZE;
ep_record[ INPUT_PIPE ].Interval = EP_POLL;
//ep_record[ INPUT_PIPE ].sndToggle = bmSNDTOG0;
//ep_record[ INPUT_PIPE ].rcvToggle = bmRCVTOG0;
//my_usb_host.setDevTableEntry( PS3_ADDR, ep_record );
/* read the device descriptor and check VID and PID*/
rcode = my_usb_host.getDevDescr( PS3_ADDR, ep_record[ CONTROL_PIPE ].epAddr, DEV_DESCR_LEN , (uint8_t*)buf );
if( rcode ) {
Serial.print("Error attempting read device descriptor. Return code :");
Serial.println( rcode, HEX );
while(1); //stop
}
device_descriptor = (USB_DEVICE_DESCRIPTOR *) &buf;
delay(200);
if(
(device_descriptor->idVendor != PS3_VID) ||(device_descriptor->idProduct != PS3_PID) ) {
Serial.println("Unsupported USB Device");
while(1); //stop
}
delay(200);
/* Configure device */
Serial.println("Configuring device...");
rcode = my_usb_host.setConf( PS3_ADDR, ep_record[ CONTROL_PIPE ].epAddr, PS3_CONFIGURATION );
if( rcode ) {
Serial.print("Error attempting to configure PS3 controller. Return code :");
Serial.println( rcode, HEX );
while(1); //stop
}
delay(200);