Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send data to a PS3 DualShock3 controller from a Mac (IOHIDDeviceSetReport)

I've been playing around with the HID part of IOKit lately on my Mac with a PS3 controller. I've managed to look though the sample code and connect to my controller, receive a stream of data and parse it (Everything, including the accelerometer and gyro).

However, today I decided I wanted to start setting the LEDs on the back of the device and triggering the rumble motors, but I just can't get it to work!

Looking though the sample code Apple provides for IOHID there isn't much I can see on setting things on the HID device, only receiving data. From looking on the web (for petty much half a day) I've got what I think is a working send method which uses IOHIDDeviceSetReport(). However, I can't work out what data I should be sending.

I've found several sites that list data examples:

  • http://www.circuitsathome.com/mcu/ps3-and-wiimote-game-controllers-on-the-arduino-host-shield-part-2
  • https://github.com/ribbotson/USB-Host/blob/master/ps3/PS3USB/ps3_usb.h
  • http://wiibrew.org/wiki/Sixaxis

(I know not all these examples are for between Mac an a PS3 controller)

A lot of people seem to be talking about this and even doing it (I refuse to believe no one has got this working) but I can't seem to find anything about actually how to do it that works!

I feel like I am missing a simple step here, so if anyone has any ideas, help or a solution please let me know.

Thanks.

Example Code of how I'm trying to send a report (is is returning success):

CFIndex len = 64;
uint8_t report[64] = {0x0};

IOReturn  tIOReturn = IOHIDDeviceSetReport(deviceRef,
                                           kIOHIDReportTypeOutput,
                                           reportID,
                                           report,
                                           len);

This is just sending a lot of nothing (literally) but it's just an example of what I'm using just incase it's not correct.

Extra: I've also just noticed that Apples defenition of IOHIDDeviceSetReport differes from there example given.

https://developer.apple.com/library/mac/documentation/DeviceDrivers/Conceptual/HID/new_api_10_5/tn2187.html#//apple_ref/doc/uid/TP40000970-CH214-SW81

There it says report should be "address of report buffer". But...

https://developer.apple.com/library/mac/documentation/IOKit/Reference/IOHIDDevice_iokit_header_reference/Reference/reference.html#//apple_ref/doc/uid/TP40012408-CHIOHIDDevicehFunctions-DontLinkElementID_23

There it say *report (being a pointer) is "The report bytes to be sent to the device.".

like image 218
Baza207 Avatar asked Oct 15 '13 23:10

Baza207


1 Answers

there's an example at: http://www.circuitsathome.com/mcu/ps3-and-wiimote-game-controllers-on-the-arduino-host-shield-part-2

with the code describing the LED and Rumble control at: https://github.com/ribbotson/USB-Host/blob/master/ps3/PS3USB/ps3_usb.cpp#L187

It seems that the bytes that you sent as report need to have a certain format:

 prog_char output_01_report[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                     0x00, 0x02, 0xff, 0x27, 0x10, 0x00, 0x32, 0xff, 
                                     0x27, 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00, 
                                     0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0x00, 0x00, 
                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };

In the LEDRumble function, these bytes are copied into buf and then buf[9] is overridden to set the LED state and the bytes from buf[1] through buf[4] are used to configure the Rumble. The the bytes are all sent to the controller.

There are some constants defined here: https://github.com/ribbotson/USB-Host/blob/master/ps3/PS3USB/ps3_usb.h#L100

#define psLED1 0x01
#define psLED2 0x02
#define psLED3 0x04
#define psLED4 0x08
#define psRumbleHigh 0x10
#define psRumbleLow 0x20

These constants are passed to the LEDRumble function as parameters.

like image 187
Karsten Avatar answered Nov 03 '22 06:11

Karsten