Skip to content

Commit

Permalink
Kinect for Windows and Xbox 360 Model 1473 support
Browse files Browse the repository at this point in the history
This patch does auto detection of all three models and
disables motor subdevice for the 2 newer ones. It also
adds a function to test for the presence of the motor
and audio devices on newer models.

Signed-off-by: Yannis Gravezas <[email protected]> (wizgrav)
  • Loading branch information
wizgrav authored and Yannis Grv committed Jul 18, 2013
1 parent ec04a63 commit 3ef8258
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 9 deletions.
9 changes: 9 additions & 0 deletions include/libfreenect.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,15 @@ FREENECTAPI int freenect_supported_subdevices(void);
*/
FREENECTAPI void freenect_select_subdevices(freenect_context *ctx, freenect_device_flags subdevs);

/**
* Returns the devices that are enabled after calls to freenect_open_device()
* On newer kinects the motor and audio are automatically disabled for now
*
* @param ctx Context to set future subdevice selection for
* @return Flags representing the subdevices that were actually opened (see freenect_device_flags)
*/
FREENECTAPI freenect_device_flags freenect_enabled_subdevices(freenect_context *ctx);

/**
* Opens a kinect device via a context. Index specifies the index of
* the device on the current state of the bus. Bus resets may cause
Expand Down
1 change: 1 addition & 0 deletions platform/windows/libusb10emu/libusb-1.0/libusb.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ int libusb_get_string_descriptor(libusb_device_handle *dev_handle, uint8_t desc_
int libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle, uint8_t desc_index, unsigned char *data, int length);

int libusb_set_configuration(libusb_device_handle *dev, int configuration);
int libusb_set_interface_alt_setting(libusb_device_handle *dev,int interface_number,int alternate_setting);
int libusb_claim_interface(libusb_device_handle* dev, int interface_number);
int libusb_release_interface(libusb_device_handle* dev, int interface_number);

Expand Down
11 changes: 11 additions & 0 deletions platform/windows/libusb10emu/libusb-1.0/libusbemu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,17 @@ int libusb_set_configuration(libusb_device_handle *dev, int configuration)
return 0;
}

int libusb_set_interface_alt_setting(libusb_device_handle *dev, int interface_number,int alternate_setting){
RAIIMutex lock (dev->dev->ctx->mutex);
if (0 != usb_set_altinterface(dev->handle, alternate_setting))
{
LIBUSBEMU_ERROR_LIBUSBWIN32();
return(LIBUSB_ERROR_OTHER);
}

return(0);
}

int libusb_claim_interface(libusb_device_handle* dev, int interface_number)
{
RAIIMutex lock (dev->dev->ctx->mutex);
Expand Down
6 changes: 3 additions & 3 deletions src/cameras.c
Original file line number Diff line number Diff line change
Expand Up @@ -904,9 +904,9 @@ static int freenect_fetch_zero_plane_info(freenect_device *dev)
uint16_t cmd[5] = {0}; // Offset is the only field in this command, and it's 0

int res;
res = send_cmd(dev, 0x04, cmd, 10, reply, 322); //OPCODE_GET_FIXED_PARAMS = 4,
if (res != 322) {
FN_ERROR("freenect_fetch_zero_plane_info: send_cmd read %d bytes (expected 322)\n", res);
res = send_cmd(dev, 0x04, cmd, 10, reply, ctx->zero_plane_res); //OPCODE_GET_FIXED_PARAMS = 4,
if (res != ctx->zero_plane_res) {
FN_ERROR("freenect_fetch_zero_plane_info: send_cmd read %d bytes (expected %d)\n", res,ctx->zero_plane_res);
return -1;
}

Expand Down
4 changes: 4 additions & 0 deletions src/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ FREENECTAPI void freenect_select_subdevices(freenect_context *ctx, freenect_devi
));
}

FREENECTAPI freenect_device_flags freenect_enabled_subdevices(freenect_context *ctx) {
return ctx->enabled_subdevices;
}

FREENECTAPI int freenect_open_device(freenect_context *ctx, freenect_device **dev, int index)
{
int res;
Expand Down
3 changes: 3 additions & 0 deletions src/freenect_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct _freenect_context {
fnusb_ctx usb;
freenect_device_flags enabled_subdevices;
freenect_device *first;
int zero_plane_res;
};

#define LL_FATAL FREENECT_LOG_FATAL
Expand Down Expand Up @@ -131,6 +132,8 @@ static inline int32_t fn_le32s(int32_t s)
#define PID_NUI_AUDIO 0x02ad
#define PID_NUI_CAMERA 0x02ae
#define PID_NUI_MOTOR 0x02b0
#define PID_K4W_CAMERA 0x02bf
#define PID_K4W_AUDIO 0x02be

typedef struct {
int running;
Expand Down
8 changes: 8 additions & 0 deletions src/tilt.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ freenect_raw_tilt_state* freenect_get_tilt_state(freenect_device *dev)
int freenect_update_tilt_state(freenect_device *dev)
{
freenect_context *ctx = dev->parent;
if(!(ctx->enabled_subdevices & FREENECT_DEVICE_MOTOR))
return 0;
uint8_t buf[10];
uint16_t ux, uy, uz;
int ret = fnusb_control(&dev->usb_motor, 0xC0, 0x32, 0x0, 0x0, buf, 10);
Expand All @@ -70,6 +72,9 @@ int freenect_update_tilt_state(freenect_device *dev)

int freenect_set_tilt_degs(freenect_device *dev, double angle)
{
freenect_context *ctx = dev->parent;
if(!(ctx->enabled_subdevices & FREENECT_DEVICE_MOTOR))
return 0;
int ret;
uint8_t empty[0x1];

Expand All @@ -82,6 +87,9 @@ int freenect_set_tilt_degs(freenect_device *dev, double angle)

int freenect_set_led(freenect_device *dev, freenect_led_options option)
{
freenect_context *ctx = dev->parent;
if(!(ctx->enabled_subdevices & FREENECT_DEVICE_MOTOR))
return 0;
int ret;
uint8_t empty[0x1];
ret = fnusb_control(&dev->usb_motor, 0x40, 0x06, (uint16_t)option, 0x0, empty, 0x0);
Expand Down
42 changes: 36 additions & 6 deletions src/usb_libusb10.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ FN_INTERNAL int fnusb_num_devices(fnusb_ctx *ctx)
int r = libusb_get_device_descriptor (devs[i], &desc);
if (r < 0)
continue;
if (desc.idVendor == VID_MICROSOFT && desc.idProduct == PID_NUI_CAMERA)
if (desc.idVendor == VID_MICROSOFT && (desc.idProduct == PID_NUI_CAMERA || desc.idProduct == PID_K4W_CAMERA))
nr++;
}
libusb_free_device_list (devs, 1);
Expand Down Expand Up @@ -76,7 +76,7 @@ FN_INTERNAL int fnusb_list_device_attributes(fnusb_ctx *ctx, struct freenect_dev
int r = libusb_get_device_descriptor (devs[i], &desc);
if (r < 0)
continue;
if (desc.idVendor == VID_MICROSOFT && desc.idProduct == PID_NUI_CAMERA) {
if (desc.idVendor == VID_MICROSOFT && (desc.idProduct == PID_NUI_CAMERA || desc.idProduct == PID_K4W_CAMERA)) {
// Verify that a serial number exists to query. If not, don't touch the device.
if (desc.iSerialNumber == 0) {
continue;
Expand Down Expand Up @@ -188,9 +188,9 @@ FN_INTERNAL int fnusb_open_subdevices(freenect_device *dev, int index)

if (desc.idVendor != VID_MICROSOFT)
continue;

res = 0;
// Search for the camera
if ((ctx->enabled_subdevices & FREENECT_DEVICE_CAMERA) && !dev->usb_cam.dev && desc.idProduct == PID_NUI_CAMERA) {
if ((ctx->enabled_subdevices & FREENECT_DEVICE_CAMERA) && !dev->usb_cam.dev && (desc.idProduct == PID_NUI_CAMERA || desc.idProduct == PID_K4W_CAMERA)) {
// If the index given by the user matches our camera index
if (nr_cam == index) {
res = libusb_open (devs[i], &dev->usb_cam.dev);
Expand All @@ -199,6 +199,15 @@ FN_INTERNAL int fnusb_open_subdevices(freenect_device *dev, int index)
dev->usb_cam.dev = NULL;
break;
}
if(desc.idProduct == PID_K4W_CAMERA || desc.bcdDevice != fn_le32(267)){
/* Not the old kinect so we only set up the camera*/
ctx->enabled_subdevices = FREENECT_DEVICE_CAMERA;
ctx->zero_plane_res = 334;
}else{
/* The good old kinect that tilts and tweets */
ctx->zero_plane_res = 322;
}

#ifndef _WIN32
// Detach an existing kernel driver for the device
res = libusb_kernel_driver_active(dev->usb_cam.dev, 0);
Expand All @@ -219,12 +228,33 @@ FN_INTERNAL int fnusb_open_subdevices(freenect_device *dev, int index)
dev->usb_cam.dev = NULL;
break;
}
if(desc.idProduct == PID_K4W_CAMERA){
res = libusb_set_interface_alt_setting(dev->usb_cam.dev, 0, 1);
if (res != 0) {
FN_ERROR("Failed to set alternate interface #1 for K4W: %d\n", res);
libusb_close(dev->usb_cam.dev);
dev->usb_cam.dev = NULL;
break;
}

}
} else {
nr_cam++;
}
}

}

if(ctx->enabled_subdevices == FREENECT_DEVICE_CAMERA || res < 0) cnt = 0;

// Search for the motor

for (i = 0; i < cnt; i++) {
int r = libusb_get_device_descriptor (devs[i], &desc);
if (r < 0)
continue;

if (desc.idVendor != VID_MICROSOFT)
continue;
if ((ctx->enabled_subdevices & FREENECT_DEVICE_MOTOR) && !dev->usb_motor.dev && desc.idProduct == PID_NUI_MOTOR) {
// If the index given by the user matches our camera index
if (nr_mot == index) {
Expand All @@ -249,7 +279,7 @@ FN_INTERNAL int fnusb_open_subdevices(freenect_device *dev, int index)
#ifdef BUILD_AUDIO
// TODO: check that the firmware has already been loaded; if not, upload firmware.
// Search for the audio
if ((ctx->enabled_subdevices & FREENECT_DEVICE_AUDIO) && !dev->usb_audio.dev && desc.idProduct == PID_NUI_AUDIO) {
if ((ctx->enabled_subdevices & FREENECT_DEVICE_AUDIO) && !dev->usb_audio.dev && (desc.idProduct == PID_NUI_AUDIO || desc.idProduct == PID_K4W_AUDIO)) {
// If the index given by the user matches our audio index
if (nr_audio == index) {
res = libusb_open (devs[i], &dev->usb_audio.dev);
Expand Down

0 comments on commit 3ef8258

Please sign in to comment.