Mercurial > hg > hid-usb-to-ir
comparison hid-usb-to-ir.c @ 2:95b8b8a0b2d0 v0.3
add proximity measurement
| author | Peter Meerwald <p.meerwald@bct-electronic.com> |
|---|---|
| date | Thu, 03 Jan 2013 13:09:20 +0100 |
| parents | c6e3b362f9cf |
| children |
comparison
equal
deleted
inserted
replaced
| 1:bb5e6c6d9310 | 2:95b8b8a0b2d0 |
|---|---|
| 26 #include <string.h> | 26 #include <string.h> |
| 27 #include <unistd.h> | 27 #include <unistd.h> |
| 28 #include "hidapi/hidapi.h" | 28 #include "hidapi/hidapi.h" |
| 29 | 29 |
| 30 #define SI114X_SLAVE_ADDR 0x5a | 30 #define SI114X_SLAVE_ADDR 0x5a |
| 31 #define SI114X_HWKEY 0x07 | 31 |
| 32 #define SI114x_PART_ID 0x00 | 32 #define SI114x_REG_PART_ID 0x00 |
| 33 #define SI114x_REV_ID 0x01 | 33 #define SI114x_REG_REV_ID 0x01 |
| 34 #define SI114x_SEQ_ID 0x02 | 34 #define SI114x_REG_SEQ_ID 0x02 |
| 35 #define SI114X_REG_HWKEY 0x07 | |
| 36 #define SI114X_REG_MEAS_RATE 0x08 | |
| 37 #define SI114X_REG_ALS_RATE 0x09 | |
| 38 #define SI114X_REG_PS_RATE 0x0a | |
| 39 #define SI114X_REG_PS_LED21 0x0f | |
| 40 #define SI114X_REG_PS_LED3 0x10 | |
| 41 #define SI114X_REG_PARAM_WR 0x17 | |
| 42 #define SI114X_REG_COMMAND 0x18 | |
| 43 #define SI114X_REG_ALSVIS_DATA0 0x22 | |
| 44 #define SI114X_REG_ALSVIS_DATA1 0x23 | |
| 45 #define SI114X_REG_ALSIR_DATA0 0x24 | |
| 46 #define SI114X_REG_ALSIR_DATA1 0x25 | |
| 47 #define SI114X_REG_PS1_DATA0 0x26 | |
| 48 #define SI114X_REG_PS1_DATA1 0x27 | |
| 49 #define SI114X_REG_PS2_DATA0 0x28 | |
| 50 #define SI114X_REG_PS2_DATA1 0x29 | |
| 51 #define SI114X_REG_PS3_DATA0 0x2a | |
| 52 #define SI114X_REG_PS3_DATA1 0x2b | |
| 53 #define SI114X_REG_AUX_DATA0 0x2c | |
| 54 #define SI114X_REG_AUX_DATA1 0x2d | |
| 55 | |
| 56 /* Commands for COMMAND */ | |
| 57 #define SI114X_CMD_NOP 0x00 | |
| 58 #define SI114X_CMD_RESET 0x01 | |
| 59 #define SI114X_CMD_BUSADDR 0x02 | |
| 60 #define SI114X_CMD_PS_FORCE 0x05 | |
| 61 #define SI114X_CMD_ALS_FORCE 0x06 | |
| 62 #define SI114X_CMD_PSALS_FORCE 0x07 | |
| 63 #define SI114X_CMD_PS_PAUSE 0x09 | |
| 64 #define SI114X_CMD_ALS_PAUSE 0x0a | |
| 65 #define SI114X_CMD_PSALS_PAUSE 0x0b | |
| 66 #define SI114X_CMD_PS_AUTO 0x0d | |
| 67 #define SI114X_CMD_ALS_AUTO 0x0e | |
| 68 #define SI114X_CMD_PSALS_AUTO 0x0f | |
| 69 #define SI114X_CMD_PARAM_QUERY 0x80 | |
| 70 #define SI114X_CMD_PARAM_SET 0xa0 | |
| 71 #define SI114X_CMD_PARAM_AND 0xc0 | |
| 72 #define SI114X_CMD_PARAM_OR 0xe0 | |
| 73 | |
| 74 /* Parameter offsets */ | |
| 75 #define SI114X_PARAM_CHLIST 0x01 | |
| 76 #define SI114X_PARAM_PSLED12_SELECT 0x02 | |
| 77 #define SI114X_PARAM_PSLED3_SELECT 0x03 | |
| 78 #define SI114X_PARAM_PS_ADC_COUNTER 0x0a | |
| 79 #define SI114X_PARAM_PS_ADC_GAIN 0x0b | |
| 80 #define SI114X_PARAM_PS_ADC_MISC 0x0c | |
| 81 | |
| 82 /* Channel enable masks for CHLIST parameter */ | |
| 83 #define SI114X_CHLIST_EN_PS1 0x01 | |
| 84 #define SI114X_CHLIST_EN_PS2 0x02 | |
| 85 #define SI114X_CHLIST_EN_PS3 0x04 | |
| 86 #define SI114X_CHLIST_EN_ALSVIS 0x10 | |
| 87 #define SI114X_CHLIST_EN_ALSIR 0x20 | |
| 88 #define SI114X_CHLIST_EN_AUX 0x40 | |
| 89 | |
| 90 /* Measurement rate settings */ | |
| 91 #define SI114X_MEAS_RATE_FORCED 0x00 | |
| 92 #define SI114X_MEAS_RATE_10MS 0x84 | |
| 93 #define SI114X_MEAS_RATE_20MS 0x94 | |
| 94 #define SI114X_MEAS_RATE_100MS 0xb9 | |
| 95 #define SI114X_MEAS_RATE_496MS 0xdf | |
| 96 #define SI114X_MEAS_RATE_1984MS 0xff | |
| 97 | |
| 98 /* ALS rate settings relative to measurement rate */ | |
| 99 #define SI114X_ALS_RATE_OFF 0x00 | |
| 100 #define SI114X_ALS_RATE_1X 0x08 | |
| 101 #define SI114X_ALS_RATE_10X 0x32 | |
| 102 #define SI114X_ALS_RATE_100X 0x69 | |
| 103 | |
| 104 /* PS rate settings relative to measurement rate */ | |
| 105 #define SI114X_PS_RATE_OFF 0x00 | |
| 106 #define SI114X_PS_RATE_1X 0x08 | |
| 107 #define SI114X_PS_RATE_10X 0x32 | |
| 108 #define SI114X_PS_RATE_100X 0x69 | |
| 35 | 109 |
| 36 #define CP2112_GETSET_GPIO_CONFIG 0x02 | 110 #define CP2112_GETSET_GPIO_CONFIG 0x02 |
| 37 #define CP2112_GET_GPIO 0x03 | 111 #define CP2112_GET_GPIO 0x03 |
| 38 #define CP2112_SET_GPIO 0x04 | 112 #define CP2112_SET_GPIO 0x04 |
| 39 #define CP2122_GET_VERSION_INFO 0x05 | 113 #define CP2122_GET_VERSION_INFO 0x05 |
| 128 } | 202 } |
| 129 | 203 |
| 130 return 0; | 204 return 0; |
| 131 } | 205 } |
| 132 | 206 |
| 207 static int cp2112_write_param_byte(hid_device *hd, unsigned char param, unsigned char data) { | |
| 208 if (cp2112_write_byte(hd, SI114X_REG_PARAM_WR, data) < 0) | |
| 209 return -1; | |
| 210 if (cp2112_write_byte(hd, SI114X_REG_COMMAND, param | SI114X_CMD_PARAM_SET) < 0) | |
| 211 return -1; | |
| 212 return 0; | |
| 213 } | |
| 214 | |
| 133 /* read a data byte from register reg of the si1143 */ | 215 /* read a data byte from register reg of the si1143 */ |
| 134 static int cp2112_read_byte(hid_device *hd, unsigned char reg, unsigned char data[1]) { | 216 static int cp2112_read_byte(hid_device *hd, unsigned char reg, unsigned char data[1]) { |
| 135 /* 0x5a is the 7-bit SMBus slave address of the si1143 */ | 217 /* 0x5a is the 7-bit SMBus slave address of the si1143 */ |
| 136 unsigned char buf_out[6] = { CP2112_DATA_WRITE_READ_REQ, | 218 unsigned char buf_out[6] = { CP2112_DATA_WRITE_READ_REQ, |
| 137 SI114X_SLAVE_ADDR<<1, 0x00, 0x01, 0x01, }; | 219 SI114X_SLAVE_ADDR<<1, 0x00, 0x01, 0x01, }; |
| 153 hid_error(hd)); | 235 hid_error(hd)); |
| 154 return -1; | 236 return -1; |
| 155 } | 237 } |
| 156 | 238 |
| 157 | 239 |
| 158 if (buf_in[0] == CP2112_TRANSFER_STATUS_REQ) | 240 if (buf_in[0] == CP2112_TRANSFER_STATUS_REQ) |
| 159 continue; | 241 continue; |
| 160 | 242 |
| 161 if (buf_in[0] == CP2112_DATA_READ_RESP) { | 243 if (buf_in[0] == CP2112_DATA_READ_RESP) { |
| 162 if (buf_in[1] == 0x02 && buf_in[2] == 0x00) | 244 if (buf_in[1] == 0x02 && buf_in[2] == 0x00) |
| 163 continue; /* no data yet */ | 245 continue; /* no data yet */ |
| 169 } | 251 } |
| 170 | 252 |
| 171 return -1; | 253 return -1; |
| 172 } | 254 } |
| 173 | 255 |
| 256 static int cp2112_read_word(hid_device *hd, unsigned char reg, unsigned short data[1]) { | |
| 257 unsigned char lsb, msb; | |
| 258 | |
| 259 if (cp2112_read_byte(hd, reg, &lsb) < 0) | |
| 260 return -1; | |
| 261 if (cp2112_read_byte(hd, reg+1, &msb) < 0) | |
| 262 return -1; | |
| 263 | |
| 264 data[0] = (msb << 8) | lsb; | |
| 265 return 0; | |
| 266 } | |
| 267 | |
| 174 /* configure cp2112 GPIO pins */ | 268 /* configure cp2112 GPIO pins */ |
| 175 static int cp2112_config_gpio(hid_device *hd) { | 269 static int cp2112_config_gpio(hid_device *hd) { |
| 176 unsigned char buf[5] = { CP2112_GETSET_GPIO_CONFIG, }; | 270 unsigned char buf[5] = { CP2112_GETSET_GPIO_CONFIG, }; |
| 177 int ret = hid_get_feature_report(hd, buf, sizeof(buf)); | 271 int ret = hid_get_feature_report(hd, buf, sizeof(buf)); |
| 178 if (ret < 0) { | 272 if (ret < 0) { |
| 233 | 327 |
| 234 if (cp2112_set_auto_send_read(hd, 1) < 0) | 328 if (cp2112_set_auto_send_read(hd, 1) < 0) |
| 235 exit(EXIT_FAILURE); | 329 exit(EXIT_FAILURE); |
| 236 | 330 |
| 237 /* write 0x17 to si114x HW_KEY register as per datasheet */ | 331 /* write 0x17 to si114x HW_KEY register as per datasheet */ |
| 238 if (cp2112_write_byte(hd, SI114X_HWKEY, 0x17) < 0) | 332 if (cp2112_write_byte(hd, SI114X_REG_HWKEY, 0x17) < 0) |
| 239 exit(EXIT_FAILURE); | 333 exit(EXIT_FAILURE); |
| 240 | 334 |
| 241 unsigned char part, rev, seq; | 335 unsigned char part, rev, seq; |
| 242 if (cp2112_read_byte(hd, SI114x_PART_ID, &part) < 0) | 336 if (cp2112_read_byte(hd, SI114x_REG_PART_ID, &part) < 0) |
| 243 exit(EXIT_FAILURE); | 337 exit(EXIT_FAILURE); |
| 244 | 338 |
| 245 if (cp2112_read_byte(hd, SI114x_REV_ID, &rev) < 0) | 339 if (cp2112_read_byte(hd, SI114x_REG_REV_ID, &rev) < 0) |
| 246 exit(EXIT_FAILURE); | 340 exit(EXIT_FAILURE); |
| 247 | 341 |
| 248 if (cp2112_read_byte(hd, SI114x_SEQ_ID, &seq) < 0) | 342 if (cp2112_read_byte(hd, SI114x_REG_SEQ_ID, &seq) < 0) |
| 249 exit(EXIT_FAILURE); | 343 exit(EXIT_FAILURE); |
| 250 printf("si114x part number 0x%02x, revision 0x%02x, sequencer 0x%02x\n", | 344 printf("si114x part number 0x%02x, revision 0x%02x, sequencer 0x%02x\n", |
| 251 part, rev, seq); | 345 part, rev, seq); |
| 252 | 346 |
| 347 if (cp2112_write_byte(hd, SI114X_REG_COMMAND, SI114X_CMD_RESET) < 0) | |
| 348 exit(EXIT_FAILURE); | |
| 349 usleep(20000); | |
| 350 | |
| 351 if (cp2112_write_byte(hd, SI114X_REG_HWKEY, 0x17) < 0) | |
| 352 exit(EXIT_FAILURE); | |
| 353 usleep(20000); | |
| 354 | |
| 253 cp2112_is_idle(hd); | 355 cp2112_is_idle(hd); |
| 254 | 356 |
| 357 /* set LED currents to maximum */ | |
| 358 if (cp2112_write_byte(hd, SI114X_REG_PS_LED3, 0x04)) | |
| 359 exit(EXIT_FAILURE); | |
| 360 if (cp2112_write_byte(hd, SI114X_REG_PS_LED21, 0x32)) | |
| 361 exit(EXIT_FAILURE); | |
| 362 | |
| 363 if (cp2112_write_param_byte(hd, SI114X_PARAM_PS_ADC_MISC, 0x00 | 0x04)) | |
| 364 exit(EXIT_FAILURE); | |
| 365 | |
| 366 if (cp2112_write_param_byte(hd, SI114X_PARAM_PSLED12_SELECT, 0x21)) | |
| 367 exit(EXIT_FAILURE); | |
| 368 | |
| 369 if (cp2112_write_param_byte(hd, SI114X_PARAM_PSLED3_SELECT, 0x04)) | |
| 370 exit(EXIT_FAILURE); | |
| 371 | |
| 372 if (cp2112_write_param_byte(hd, SI114X_PARAM_CHLIST, | |
| 373 SI114X_CHLIST_EN_ALSVIS | | |
| 374 SI114X_CHLIST_EN_PS3 | | |
| 375 SI114X_CHLIST_EN_PS2 | | |
| 376 SI114X_CHLIST_EN_PS1)) | |
| 377 exit(EXIT_FAILURE); | |
| 378 | |
| 379 if (cp2112_write_param_byte(hd, SI114X_PARAM_PS_ADC_GAIN, 0x01)) | |
| 380 exit(EXIT_FAILURE); | |
| 381 | |
| 382 if (cp2112_write_param_byte(hd, SI114X_PARAM_PS_ADC_COUNTER, 0x06 << 4)) | |
| 383 exit(EXIT_FAILURE); | |
| 384 | |
| 385 /* in autonomous mode, wakeup every 100 ms */ | |
| 386 if (cp2112_write_byte(hd, SI114X_REG_MEAS_RATE, SI114X_MEAS_RATE_100MS)) | |
| 387 exit(EXIT_FAILURE); | |
| 388 | |
| 389 /* measure ALS every time device wakes up */ | |
| 390 if (cp2112_write_byte(hd, SI114X_REG_ALS_RATE, SI114X_ALS_RATE_1X)) | |
| 391 exit(EXIT_FAILURE); | |
| 392 | |
| 393 /* measure proximity every time device wakes up */ | |
| 394 if (cp2112_write_byte(hd, SI114X_REG_PS_RATE, SI114X_PS_RATE_1X)) | |
| 395 exit(EXIT_FAILURE); | |
| 396 | |
| 397 if (cp2112_write_byte(hd, SI114X_REG_COMMAND, SI114X_CMD_PSALS_AUTO)) | |
| 398 exit(EXIT_FAILURE); | |
| 399 | |
| 400 cp2112_is_idle(hd); | |
| 401 | |
| 255 if (cp2112_config_gpio(hd) < 0) | 402 if (cp2112_config_gpio(hd) < 0) |
| 256 exit(EXIT_FAILURE); | 403 exit(EXIT_FAILURE); |
| 257 | 404 |
| 258 while (1) { | 405 while (1) { |
| 406 unsigned short als, ps1, ps2, ps3; | |
| 259 if (cp2112_set_gpio(hd, CP2112_LEDS_MASK, CP2112_LED_DOWN) < 0) | 407 if (cp2112_set_gpio(hd, CP2112_LEDS_MASK, CP2112_LED_DOWN) < 0) |
| 260 exit(EXIT_FAILURE); | 408 exit(EXIT_FAILURE); |
| 261 usleep(50*1000); | 409 usleep(50*1000); |
| 262 if (cp2112_set_gpio(hd, CP2112_LEDS_MASK, CP2112_LED_RIGHT) < 0) | 410 if (cp2112_set_gpio(hd, CP2112_LEDS_MASK, CP2112_LED_RIGHT) < 0) |
| 263 exit(EXIT_FAILURE); | 411 exit(EXIT_FAILURE); |
| 266 exit(EXIT_FAILURE); | 414 exit(EXIT_FAILURE); |
| 267 usleep(50*1000); | 415 usleep(50*1000); |
| 268 if (cp2112_set_gpio(hd, CP2112_LEDS_MASK, CP2112_LED_LEFT) < 0) | 416 if (cp2112_set_gpio(hd, CP2112_LEDS_MASK, CP2112_LED_LEFT) < 0) |
| 269 exit(EXIT_FAILURE); | 417 exit(EXIT_FAILURE); |
| 270 usleep(50*1000); | 418 usleep(50*1000); |
| 419 | |
| 420 if (cp2112_read_word(hd, SI114X_REG_ALSVIS_DATA0, &als) < 0) | |
| 421 exit(EXIT_FAILURE); | |
| 422 if (cp2112_read_word(hd, SI114X_REG_PS1_DATA0, &ps1) < 0) | |
| 423 exit(EXIT_FAILURE); | |
| 424 if (cp2112_read_word(hd, SI114X_REG_PS2_DATA0, &ps2) < 0) | |
| 425 exit(EXIT_FAILURE); | |
| 426 if (cp2112_read_word(hd, SI114X_REG_PS3_DATA0, &ps3) < 0) | |
| 427 exit(EXIT_FAILURE); | |
| 428 | |
| 429 printf("%d %d %d %d\n", ps1, ps2, ps3, als); | |
| 271 } | 430 } |
| 272 | 431 |
| 273 /* never get here */ | 432 /* never get here */ |
| 274 printf("done\n"); | 433 printf("done\n"); |
| 275 | 434 |
