PS3 controller using USB Host

I am currently modifying the XBOXController class from the projects section to create a PS3controller class. I have been using the guide here for the PS3 controller on the arduino host shield which has been really helpful.
http://www.circuitsathome.com/mcu/programming/ps3-and-wiimote-game-controllers-on-the-arduino-host-shield-part-2
I have written all the code to decode the messages received from the controller.

        public enum Button
        {
            // byte location | bit location
            // these need to be confirmed
            SELECT = (3 << 8) | 0x01,
            L3 = (3 << 8) | 0x02,
            R3 = (3 << 8) | 0x04,
            START = (3 << 8) | 0x08,
            UP = (3 << 8) | 0x10,
            RIGHT = (3 << 8) | 0x20,
            DOWN = (3 << 8) | 0x40,
            LEFT = (3 << 8) | 0x80,

            L2 = (4 << 8) | 0x01,
            R2 = (4 << 8) | 0x02,
            L1 = (4 << 8) | 0x04,
            R1 = (4 << 8) | 0x08,
            TRIANGLE = (4 << 8) | 0x10,
            CIRCLE = (4 << 8) | 0x20,
            CROSS = (4 << 8) | 0x40,
            SQUARE = (4 << 8) | 0x80,

            PS = (5 <> 8] & ((byte)b & 0xff)) > 0)
                    return true;
            }
            return false;
        }
        public byte GetAnalogButton(AnalogButton a)
        {
            if (PS3_joystickData == null)
                return 0;
            lock (PS3_joystickData)
            {
                return (byte)(PS3_joystickData[(uint)a]);
            }
        }
        public byte GetAnalogHat(AnalogHat a)
        {
            if (PS3_joystickData == null)
                return 0;
            lock (PS3_joystickData)
            {
                return (byte)(PS3_joystickData[(uint)a]);
            }
        }
        public short GetSensor(Sensor a)
        {
            if (PS3_joystickData == null)
                return 0;
            lock (PS3_joystickData)
            {
                return (short)((PS3_joystickData[(uint)a+1] << 8) | PS3_joystickData[(uint)a]);
            }
        }

but i am now currently stuck and am searching for some help with the connection of the device (sounds like the most important part, yep its fairly crucial).

from reading the guide i highlighted earlier it seems i need to connect to 2 additional endpoints.

also with this i need to send the configuration as described in the guide here

[quote]Between the setting of the configuration and the receipt of data on the input pipe , there are two commands sent to the PS3 game controller. The first sets the game controller to send 01 type reports to the input pipe whenever any changes occur on the controller.
SetupPacket:
0000: 21 09 f4 03 00 00 04 00
bmRequestType: 21
DIR: Host-To-Device
TYPE: Class
RECIPIENT: Interface
bRequest: 09
TransferBuffer: 0×00000004 (4) length
0000: 42 0c 00 00[/quote]

i guess this could be achieved using the sendsetuptransfer as below but when i try i always has a choke.

                            // set configuration 
                            byte[] buf = new byte[] {0x42, 0x0c, 0x00, 0x00};
                            PS3_Joystick.SendSetupTransfer(0x21, 0x09, 0x01, 0x00, buf, 0x00, 0x04);

i know its a fair bit to take in at once but if anyone has some pointer for me that would be great.
cheers jc

Very nice! I didn’t know PS3 uses USB :confused:
You should join the contest with your project :wink: Or anyways, add it to the project website if you like. Other will find it very useful (link removed)

Do not forget about the other cool things like guitar hero too.

Have you seen this?
(link removed)

About your question, usually devices have 3 EP. The control EP that is used only for initialization but then there is one in and one out endpoint. I would say just take the XBOX class and read from a your controller and yo should get data back. In some rare cases, you would need to send a command to ask the controller to start sending data.

cheers Chimpanzee, i had a browse of the RockBandStageKit. it was helpful and showed me a few things that i didn’t get from the XBOXcontroller class on the projects page.
i did what you said

and used the RockBandStageKit just modifying the RBSK_VENDOR_ID and RBSK_PRODUCT_ID and buffer sizes. connects fine but i need to send a command to the controller so that it writes changes of button states back through the usb pipe. is the command i should use the raw.SendSetupTransfer or should i use the writePipe.TransferData?

awesome work jc may need to plug this in a play in the morning when i wake up.

Did you hook this up via PlayStation to USB converter?

I have a PS2 gamepad connected to usb host via a ps2-usb converter and using the joystick class.

I was reading online and I am not sure if I got this right but PS3 supports USB HID class and so it is very possible that the PS3 joystick will simply work with FEZ with no need fro drivers?

Let me ask you this, when you plug the PS3 controller to a PC, does the PC recognize it as an HID joystick or windows asks for drivers?

If you ignore the other stuff, I mean just read the data like in XBOX, what do you get?..
I am not sure if this is necessary but it is done incorrectly,

[quote]Between the setting of the configuration and the receipt of data on the input pipe , there are two commands sent to the PS3 game controller. The first sets the game controller to send 01 type reports to the input pipe whenever any changes occur on the controller.
SetupPacket:
0000: 21 09 f4 03 00 00 04 00
bmRequestType: 21
DIR: Host-To-Device
TYPE: Class
RECIPIENT: Interface
bRequest: 09
TransferBuffer: 0�00000004 (4) length
0000: 42 0c 00 00[/quote]
It says to send it after the configuration request, but you modified the configuration request and ignored some bytes…
So leave the configuration request:
raw.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);
And then send the other request: (I assume little endian and switched the bytes around)
raw.SendSetupTransfer(0x21, 0x09, 0x03F4, 0x0000, buf, 0, 4);

thanks for the feedback, guess its update time.

Foekie - the PS3 controllers can work with the PS3 over either bluetooth or USB. for the controller to work over bluetooth you first need to assign the address of the bluetooth dongle that it will send the controller data to. for usb you need to request to send over usb.

Chimpanzee - when i plug the controller into my PC it comes up a HID compliant game controller. does this mean that i could use the USBH_Joystick class instead of reading the data with the rawdevice way that i am trying to?

Supa - if i ignore trying to send the second config the controller doesnt send any data back to the Fez. i checked this by debug.print ing the readbuffer. i also tried the original sendsetuptransfer and added the other but it chokes with an exception when i plug in the controller and it trys to send the second setup transfer.
raw.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);
raw.SendSetupTransfer(0x21, 0x09, 0x03F4, 0x0000, buf, 0, 4);

this is the exception

[quote] #### Exception System.Exception - 0xffffffff (3) ####
#### GHIElectronics.NETMF.USBHost.USBH_RawDevice::SendSetupTransfer [IP: 0000] ####
#### RockBandStageKit.RBSKController::.ctor [IP: 00a7] ####
#### RockBandStageKit.Program::USBHostController_DeviceConnectedEvent [IP: 0037] ####
#### GHIElectronics.NETMF.USBHost.USBH_DeviceConnectionEventHandler::Invoke [IP: 4ea29] ####
#### GHIElectronics.NETMF.USBHost.USBHostController::nativeEventDispatcher_OnInterrupt [IP: 0037] ####
#### GHIElectronics.NETMF.System.InternalEvent::nativeEventDispatcher_OnInterrupt [IP: 0054] ####
A first chance exception of type ‘System.Exception’ occurred in GHIElectronics.NETMF.USBHost.dll
An unhandled exception of type ‘System.Exception’ occurred in GHIElectronics.NETMF.USBHost.dll[/quote]

guess a little more work is required on my part.

Well, if it’s HID I would say it should work with the joystick.
Try it out and let us know. :wink:

WE HAVE CONNECTION!
sorted it out. just ironing out a few minor bugs with connection and pressing of the PS button and will upload the complete code by the weekend.
turns out you do need to send the
raw.SendSetupTransfer(0x21, 0x09, 0x03F4, 0x0000, buf, 0, 4);
command but it seems as though you need to wait a little between setup transfers.
also i was having issues because i had my read and write endpoints around the wrong way, rookie mistake.

Very curious now… Glad you got it to work! Good job! :wink:

Will you add the drivers to the project website?

The PS3Controller class is on the projects website. Thanks everyone for your help. I dare say i will need more once i go for the bluetooth communication.

Check it out
(link removed)

Things still to implement
-Bluetooth communication, this is major and i haven’t started
-Rumbe features, still working on this. i can make it rumble but then the controller disconnects and has a choke.

very nice…are you joining the contest?

I got some problems, I am completely new to the .NET framework and the Fez.
I saw your post: http://wiki.tinyclr.com/index.ph​p?title=PS3_Controller, but I simple can not figure out how to use your program.
Should I write something like this:

PS3Controller PS3 = new PS3Controller();

or what? If I do so, it tells me: “FEZ_Panda_II_Application1.PS3Co​ntroller’ does not contain a constructor that takes 0 arguments”, but what should I write between the brackets?

Start with free ebook and learn about USB Host usage. Start with a mouse/joystick/keyboard and then everything else will be easy.

What FEZ are you using?

@ Gus: he is using a panda 2

@ Lauszus:
The error provided already gives you the solution for your problem.
You are not parsing any of the required parameters when creating a new PS3Controller instance.

Looking at the source code you will need to parse a USBH_Device as parameter when creating a new instance.

How to detect and parse a USBH_Device with fez is, as stated by Gus, in the free ebook.

I have already read the book, but I still can not figure it out. I have tried several things. Including:

PS3 = new PS3Controller(USBH_Device);

and

PS3 = new PS3Controller(USBH_Device device);

but it still not working.
The problem as I see it, is that there are not any “DeviceConnectedEvent”.
I have also tried this:

USBHostController.DeviceConnectedEvent += PS3Controller;

But nothing works!
Thanks for your help.

I’m not familiar with the PS3Controller class, but at the very least you have to instantiate a usb device object before passing it into the PS3Controller constructor. Take a look at the online help for an example of this for a raw device: [url]http://www.ghielectronics.com/downloads/NETMF/Library%20Documentation/html/cad016bc-c045-3553-16a5-a86db398c68f.htm[/url]

You will need to detect a device when connecting it via usb.
Next create a reference for that device
This reference should then be parsed as parameter when creating a new PS3Controller instance.

Please try out the mouse and keyboard examples. They are easy and you will understand what to do.