flags.c
Go to the documentation of this file.
1 /*
2  * This file is part of the OpenKinect Project. http://www.openkinect.org
3  *
4  * Copyright (c) 2010-2011 individual OpenKinect contributors. See the CONTRIB
5  * file for details.
6  *
7  * This code is licensed to you under the terms of the Apache License, version
8  * 2.0, or, at your option, the terms of the GNU General Public License,
9  * version 2.0. See the APACHE20 and GPL2 files for the text of the licenses,
10  * or the following URLs:
11  * http://www.apache.org/licenses/LICENSE-2.0
12  * http://www.gnu.org/licenses/gpl-2.0.txt
13  *
14  * If you redistribute this file in source form, modified or unmodified, you
15  * may:
16  * 1) Leave this header intact and distribute it under the same terms,
17  * accompanying it with the APACHE20 and GPL20 files, or
18  * 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
19  * 3) Delete the GPL v2 clause and accompany it with the APACHE20 file
20  * In all cases you must keep the copyright notice intact and include a copy
21  * of the CONTRIB file.
22  *
23  * Binary distributions must follow the binary distribution requirements of
24  * either License.
25  */
26 
27 #include <string.h> // for memcpy
28 #include "freenect_internal.h"
29 #include "flags.h"
30 
31 
32 // freenect_set_flag is the only function exposed in libfreenect.h
33 // The rest are available internally via #include flags.h
34 
36 {
37  switch(flag)
38  {
40  return 0x17;
42  return 0x47;
43  default:
44  return -1;
45  }
46 }
47 
49 {
50  if (flag >= (1 << 16))
51  {
52  int reg = register_for_flag(flag);
53  if (reg < 0)
54  return reg;
55  return write_register(dev, reg, value);
56  }
57 
58  uint16_t cmos_value = read_cmos_register(dev, 0x0106);
59  if (cmos_value == UINT16_MAX)
60  {
61  return -1;
62  }
63  if (value == FREENECT_ON)
64  cmos_value |= flag;
65  else
66  cmos_value &= ~flag;
67  return write_cmos_register(dev, 0x0106, cmos_value);
68 }
69 
70 typedef struct {
71  uint8_t magic[2];
75 } cam_hdr;
76 
77 FN_INTERNAL int send_cmd(freenect_device *dev, uint16_t cmd, void *cmdbuf, unsigned int cmd_len, void *replybuf, int reply_len)
78 {
79  freenect_context *ctx = dev->parent;
80  int res, actual_len;
81  uint8_t obuf[0x400];
82  uint8_t ibuf[0x200];
83  cam_hdr *chdr = (cam_hdr*)obuf;
84  cam_hdr *rhdr = (cam_hdr*)ibuf;
85 
86  if (cmd_len & 1 || cmd_len > (0x400 - sizeof(*chdr))) {
87  FN_ERROR("send_cmd: Invalid command length (0x%x)\n", cmd_len);
88  return -1;
89  }
90 
91  chdr->magic[0] = 0x47;
92  chdr->magic[1] = 0x4d;
93  chdr->cmd = fn_le16(cmd);
94  chdr->tag = fn_le16(dev->cam_tag);
95  chdr->len = fn_le16(cmd_len / 2);
96 
97  memcpy(obuf+sizeof(*chdr), cmdbuf, cmd_len);
98 
99  res = fnusb_control(&dev->usb_cam, 0x40, 0, 0, 0, obuf, cmd_len + sizeof(*chdr));
100  FN_SPEW("send_cmd: cmd=%04x tag=%04x len=%04x: %d\n", cmd, dev->cam_tag, cmd_len, res);
101  if (res < 0) {
102  FN_ERROR("send_cmd: Output control transfer failed (%d)\n", res);
103  return res;
104  }
105 
106  do {
107  actual_len = fnusb_control(&dev->usb_cam, 0xc0, 0, 0, 0, ibuf, 0x200);
108  FN_FLOOD("send_cmd: actual length = %d\n", actual_len);
109  } while ((actual_len == 0) || (actual_len == 0x200));
110  FN_SPEW("Control reply: %d\n", res);
111  if (actual_len < (int)sizeof(*rhdr)) {
112  FN_ERROR("send_cmd: Input control transfer failed (%d)\n", res);
113  return res;
114  }
115  actual_len -= sizeof(*rhdr);
116 
117  if (rhdr->magic[0] != 0x52 || rhdr->magic[1] != 0x42) {
118  FN_ERROR("send_cmd: Bad magic %02x %02x\n", rhdr->magic[0], rhdr->magic[1]);
119  return -1;
120  }
121  if (rhdr->cmd != chdr->cmd) {
122  FN_ERROR("send_cmd: Bad cmd %02x != %02x\n", rhdr->cmd, chdr->cmd);
123  return -1;
124  }
125  if (rhdr->tag != chdr->tag) {
126  FN_ERROR("send_cmd: Bad tag %04x != %04x\n", rhdr->tag, chdr->tag);
127  return -1;
128  }
129  if (fn_le16(rhdr->len) != (actual_len/2)) {
130  FN_ERROR("send_cmd: Bad len %04x != %04x\n", fn_le16(rhdr->len), (int)(actual_len/2));
131  return -1;
132  }
133 
134  if (actual_len > reply_len) {
135  FN_WARNING("send_cmd: Data buffer is %d bytes long, but got %d bytes\n", reply_len, actual_len);
136  memcpy(replybuf, ibuf+sizeof(*rhdr), reply_len);
137  } else {
138  memcpy(replybuf, ibuf+sizeof(*rhdr), actual_len);
139  }
140 
141  dev->cam_tag++;
142 
143  return actual_len;
144 }
145 
146 // returns UINT16_MAX on error
148 {
149  freenect_context *ctx = dev->parent;
150 
151  uint16_t reply[2];
152  uint16_t cmd = fn_le16(reg);
153 
154  int res = send_cmd(dev, 0x02, &cmd, 2, reply, 4);
155  if (res < 0)
156  {
157  FN_ERROR("read_register: send_cmd() failed: %d\n", res);
158  return UINT16_MAX;
159  }
160  if (res != 4)
161  FN_WARNING("read_register: send_cmd() returned %d [%04x %04x], 0000 expected\n", res, reply[0], reply[1]);
162 
163  FN_DEBUG("read_register: 0x%04x => 0x%04x\n", reg, reply[1]);
164  return reply[1];
165 }
166 
168 {
169  freenect_context *ctx = dev->parent;
170  uint16_t reply[2];
171  uint16_t cmd[2];
172 
173  cmd[0] = fn_le16(reg);
174  cmd[1] = fn_le16(data);
175 
176  FN_DEBUG("write_register: 0x%04x <= 0x%02x\n", reg, data);
177  int res = send_cmd(dev, 0x03, cmd, 4, reply, 4);
178  if (res < 0)
179  {
180  FN_ERROR("write_register: send_cmd() returned %d\n", res);
181  return res;
182  }
183  if (res != 2)
184  FN_WARNING("write_register: send_cmd() returned %d [%04x %04x], 0000 expected\n", res, reply[0], reply[1]);
185 
186  return 0;
187 }
188 
189 // returns UINT16_MAX on error
191 {
192  freenect_context *ctx = dev->parent;
193  uint16_t replybuf[0x200];
194  uint16_t cmdbuf[3];
195 
196  cmdbuf[0] = 1;
197  cmdbuf[1] = reg & 0x7fff;
198  cmdbuf[2] = 0;
199 
200  int res = send_cmd(dev, 0x95, cmdbuf, 6, replybuf, 6);
201  if (res < 0)
202  {
203  FN_ERROR("read_cmos_register: send_cmd() returned %d\n", res);
204  return UINT16_MAX;
205  }
206 
207  FN_DEBUG("read_cmos_register: 0x%04x => 0x%04x\n", reg, replybuf[2]);
208  return replybuf[2];
209 }
210 
212 {
213  freenect_context *ctx = dev->parent;
214  uint16_t replybuf[0x200];
215  uint16_t cmdbuf[3];
216 
217  cmdbuf[0] = 1;
218  cmdbuf[1] = reg | 0x8000;
219  cmdbuf[2] = value;
220 
221  FN_DEBUG("write_cmos_register: 0x%04x <= 0x%04x\n", reg, value);
222  int res = send_cmd(dev, 0x95, cmdbuf, 6, replybuf, 6);
223  if (res < 0)
224  FN_ERROR("write_cmos_register: send_cmd() returned %d\n", res);
225  return res;
226 }
freenect_flag
Enumeration of flags to toggle features with freenect_set_flag()
Definition: libfreenect.h:110
freenect_context * parent
freenect_flag_value
Possible values for setting each freenect_flag
Definition: libfreenect.h:121
uint16_t tag
Definition: flags.c:74
unsigned short uint16_t
#define FN_ERROR(...)
#define FN_FLOOD(...)
FN_INTERNAL int register_for_flag(int flag)
Definition: flags.c:35
#define fn_le16(x)
unsigned char uint8_t
#define FN_DEBUG(...)
uint16_t cmd
Definition: flags.c:73
#define FN_WARNING(...)
FN_INTERNAL uint16_t read_cmos_register(freenect_device *dev, uint16_t reg)
Definition: flags.c:190
FN_INTERNAL int fnusb_control(fnusb_dev *dev, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t wLength)
Definition: usb_libusb10.c:823
uint16_t len
Definition: flags.c:72
int freenect_set_flag(freenect_device *dev, freenect_flag flag, freenect_flag_value value)
Definition: flags.c:48
#define FN_SPEW(...)
FN_INTERNAL uint16_t read_register(freenect_device *dev, uint16_t reg)
Definition: flags.c:147
Definition: flags.c:70
static freenect_context * ctx
FN_INTERNAL int write_register(freenect_device *dev, uint16_t reg, uint16_t data)
Definition: flags.c:167
#define FN_INTERNAL
FN_INTERNAL int write_cmos_register(freenect_device *dev, uint16_t reg, uint16_t value)
Definition: flags.c:211
FN_INTERNAL int send_cmd(freenect_device *dev, uint16_t cmd, void *cmdbuf, unsigned int cmd_len, void *replybuf, int reply_len)
Definition: flags.c:77
uint8_t magic[2]
Definition: flags.c:71


libfreenect
Author(s): Hector Martin, Josh Blake, Kyle Machulis, OpenKinect community
autogenerated on Mon Jun 10 2019 13:46:42