Skip to content

Commit dfc6661

Browse files
committed
This code sets the LED of a 1473 Kinect or K4W Kinect to red on startup. This seems to fix a known issue for OS X users where the device renumerates within a small time period and causes a freeze. Closes #340 and addresses #316. Signed-off-by: Theodore Watson <[email protected]> (ofTheo)
1 parent 300faff commit dfc6661

File tree

3 files changed

+233
-0
lines changed

3 files changed

+233
-0
lines changed

src/keep_alive.c

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
//
2+
// keep_alive.c
3+
// Created by Theodore Watson on 1/23/14.
4+
5+
//This file is part of the OpenKinect Project. http://www.openkinect.org
6+
//
7+
// Copyright (c) 2010 individual OpenKinect contributors. See the CONTRIB file
8+
// for details.
9+
//
10+
// This code is licensed to you under the terms of the Apache License, version
11+
// 2.0, or, at your option, the terms of the GNU General Public License,
12+
// version 2.0. See the APACHE20 and GPL20 files for the text of the licenses,
13+
// or the following URLs:
14+
// http://www.apache.org/licenses/LICENSE-2.0
15+
// http://www.gnu.org/licenses/gpl-2.0.txt
16+
//
17+
// If you redistribute this file in source form, modified or unmodified,
18+
// you may:
19+
// 1) Leave this header intact and distribute it under the same terms,
20+
// accompanying it with the APACHE20 and GPL20 files, or
21+
// 2) Delete the Apache 2.0 clause and accompany it with the GPL20 file, or
22+
// 3) Delete the GPL v2.0 clause and accompany it with the APACHE20 file
23+
// In all cases you must keep the copyright notice intact and include a copy
24+
// of the CONTRIB file.
25+
// Binary distributions must follow the binary distribution requirements of
26+
// either License.
27+
28+
29+
//Based on code provided by Drew Fisher
30+
31+
/*
32+
* Copyright 2011 Drew Fisher <[email protected]>. All rights reserved.
33+
*
34+
* Redistribution and use in source and binary forms, with or without
35+
* modification, are permitted provided that the following conditions
36+
* are met:
37+
*
38+
* 1. Redistributions of source code must retain the above copyright
39+
* notice, this list of conditions and the following disclaimer.
40+
*
41+
* 2. Redistributions in binary form must reproduce the above copyright
42+
* notice, this list of conditions and the following disclaimer in the
43+
* documentation and/or other materials provided with the distribution.
44+
*
45+
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND
46+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48+
* ARE DISCLAIMED. IN NO EVENT SHALL DREW FISHER OR CONTRIBUTORS BE LIABLE
49+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55+
* SUCH DAMAGE.
56+
*
57+
* The views and conclusions contained in the software and documentation are
58+
* those of the authors and should not be interpreted as representing official
59+
* policies, either expressed or implied, of Drew Fisher.
60+
*/
61+
62+
63+
64+
65+
#include "keep_alive.h"
66+
67+
#include <libusb-1.0/libusb.h>
68+
#include <stdio.h>
69+
#include <stdlib.h>
70+
#include <string.h>
71+
#include <stdint.h>
72+
#include <unistd.h> // For usleep()
73+
74+
#define le32(X) (X)
75+
#define LOG(...) fprintf(stderr, __VA_ARGS__)
76+
77+
static uint32_t tag_seq = 1;
78+
static uint32_t tag_next_ack = 1;
79+
80+
typedef struct {
81+
uint32_t magic;
82+
uint32_t tag;
83+
uint32_t status;
84+
} motor_reply;
85+
86+
typedef struct {
87+
uint32_t magic;
88+
uint32_t tag;
89+
uint32_t arg1;
90+
uint32_t cmd;
91+
uint32_t arg2;
92+
} motor_command;
93+
94+
static int get_reply(libusb_device_handle* dev){
95+
unsigned char buffer[512];
96+
memset(buffer, 0, 512);
97+
int transferred = 0;
98+
int res = 0;
99+
res = libusb_bulk_transfer(dev, 0x81, buffer, 512, &transferred, 0);
100+
if (res != 0) {
101+
LOG("freenect_extra_keep_alive get_reply(): libusb_bulk_transfer failed: %d (transferred = %d)\n", res, transferred);
102+
} else if (transferred != 12) {
103+
LOG("freenect_extra_keep_alive get_reply(): weird - got %d bytes (expected 12)\n", transferred);
104+
} else {
105+
motor_reply reply;
106+
memcpy(&reply, buffer, sizeof(reply));
107+
if (reply.magic != 0x0a6fe000) {
108+
LOG("freenect_extra_keep_alive Bad magic: %08X (expected 0A6FE000\n", reply.magic);
109+
res = -1;
110+
}
111+
if (reply.tag != tag_next_ack) {
112+
LOG("freenect_extra_keep_alive Reply tag out of order: expected %d, got %d\n", tag_next_ack, reply.tag);
113+
res = -1;
114+
}
115+
if (reply.status != 0) {
116+
LOG("freenect_extra_keep_alive reply status != 0: failure?\n");
117+
res = -1;
118+
}
119+
tag_next_ack++;
120+
// LOG("freenect_extra_keep_alive get_reply(): got %d bytes:", transferred);
121+
// int i;
122+
// for (i = 0; i < transferred; i++) {
123+
// LOG(" %02X", buffer[i]);
124+
// }
125+
// LOG("\n");
126+
}
127+
return res;
128+
}
129+
130+
static int set_led(libusb_device_handle* dev, int state) {
131+
int transferred = 0;
132+
int res = 0;
133+
motor_command cmd;
134+
cmd.magic = le32(0x06022009);
135+
cmd.tag = le32(tag_seq++);
136+
cmd.arg1 = le32(0);
137+
cmd.cmd = le32(0x10);
138+
cmd.arg2 = (uint32_t)(le32((int32_t)state));
139+
unsigned char buffer[20];
140+
memcpy(buffer, &cmd, 20);
141+
// Send command to set LED to solid green
142+
// LOG("About to send bulk transfer:");
143+
// int i;
144+
// for(i = 0; i < 20 ; i++) {
145+
// LOG(" %02X", buffer[i]);
146+
// }
147+
// LOG("\n");
148+
res = libusb_bulk_transfer(dev, 0x01, buffer, 20, &transferred, 0);
149+
if (res != 0) {
150+
LOG("freenect_extra_keep_alive set_led(): libusb_bulk_transfer failed: %d (transferred = %d)\n", res, transferred);
151+
return res;
152+
}
153+
return get_reply(dev);
154+
}
155+
156+
//this is for K4W or 1473 devices - pass in the PID of the audio device that needs the LED set.
157+
void freenect_extra_keep_alive(int pid){
158+
159+
int res;
160+
int state_to_set = 4;
161+
162+
libusb_context* ctx = NULL;
163+
libusb_init(&ctx);
164+
165+
libusb_device_handle* dev = NULL;
166+
dev = libusb_open_device_with_vid_pid(ctx, 0x045e, pid);
167+
if (dev == NULL) {
168+
LOG("freenect extra keepAlive: Failed to open audio device\n");
169+
libusb_exit(ctx);
170+
return;
171+
}
172+
173+
res = libusb_claim_interface(dev, 0);
174+
if (res != 0) {
175+
LOG("freenect extra keepAlive: Failed to claim interface 1: %d\n", res);
176+
libusb_close(dev);
177+
libusb_exit(ctx);
178+
return;
179+
}
180+
181+
res = set_led(dev, state_to_set);
182+
if (res != 0) {
183+
LOG("freenect extra keepAlive: set_led failed\n");
184+
libusb_close(dev);
185+
libusb_exit(ctx);
186+
return;
187+
}
188+
189+
libusb_close(dev);
190+
libusb_exit(ctx);
191+
}

src/keep_alive.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// keep_alive.h
2+
//
3+
// Created by Theodore Watson on 1/23/14.
4+
5+
//This file is part of the OpenKinect Project. http://www.openkinect.org
6+
//
7+
// Copyright (c) 2010 individual OpenKinect contributors. See the CONTRIB file
8+
// for details.
9+
//
10+
// This code is licensed to you under the terms of the Apache License, version
11+
// 2.0, or, at your option, the terms of the GNU General Public License,
12+
// version 2.0. See the APACHE20 and GPL20 files for the text of the licenses,
13+
// or the following URLs:
14+
// http://www.apache.org/licenses/LICENSE-2.0
15+
// http://www.gnu.org/licenses/gpl-2.0.txt
16+
//
17+
// If you redistribute this file in source form, modified or unmodified,
18+
// you may:
19+
// 1) Leave this header intact and distribute it under the same terms,
20+
// accompanying it with the APACHE20 and GPL20 files, or
21+
// 2) Delete the Apache 2.0 clause and accompany it with the GPL20 file, or
22+
// 3) Delete the GPL v2.0 clause and accompany it with the APACHE20 file
23+
// In all cases you must keep the copyright notice intact and include a copy
24+
// of the CONTRIB file.
25+
// Binary distributions must follow the binary distribution requirements of
26+
// either License.
27+
28+
29+
#pragma once
30+
void freenect_extra_keep_alive(int pid);
31+

src/usb_libusb10.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include "freenect_internal.h"
3333
#include "loader.h"
3434

35+
#include "keep_alive.h"
36+
3537
FN_INTERNAL int fnusb_num_devices(fnusb_ctx *ctx)
3638
{
3739
libusb_device **devs;
@@ -203,6 +205,15 @@ FN_INTERNAL int fnusb_open_subdevices(freenect_device *dev, int index)
203205
/* Not the old kinect so we only set up the camera*/
204206
ctx->enabled_subdevices = FREENECT_DEVICE_CAMERA;
205207
ctx->zero_plane_res = 334;
208+
209+
//lets also set the LED ON
210+
//this keeps the camera alive for some systems which get freezes
211+
if( desc.idProduct == PID_K4W_CAMERA ){
212+
freenect_extra_keep_alive(PID_K4W_AUDIO);
213+
}else{
214+
freenect_extra_keep_alive(PID_NUI_AUDIO);
215+
}
216+
206217
}else{
207218
/* The good old kinect that tilts and tweets */
208219
ctx->zero_plane_res = 322;

0 commit comments

Comments
 (0)