# HG changeset patch # User Peter Meerwald # Date 1357214960 -3600 # Node ID 95b8b8a0b2d0b6f8b59a046569e5269076fa3852 # Parent bb5e6c6d93109e3717e714e6e68a85aefe1b2bc1 add proximity measurement diff -r bb5e6c6d9310 -r 95b8b8a0b2d0 hid-usb-to-ir.c --- a/hid-usb-to-ir.c Thu Jan 03 13:08:44 2013 +0100 +++ b/hid-usb-to-ir.c Thu Jan 03 13:09:20 2013 +0100 @@ -28,10 +28,84 @@ #include "hidapi/hidapi.h" #define SI114X_SLAVE_ADDR 0x5a -#define SI114X_HWKEY 0x07 -#define SI114x_PART_ID 0x00 -#define SI114x_REV_ID 0x01 -#define SI114x_SEQ_ID 0x02 + +#define SI114x_REG_PART_ID 0x00 +#define SI114x_REG_REV_ID 0x01 +#define SI114x_REG_SEQ_ID 0x02 +#define SI114X_REG_HWKEY 0x07 +#define SI114X_REG_MEAS_RATE 0x08 +#define SI114X_REG_ALS_RATE 0x09 +#define SI114X_REG_PS_RATE 0x0a +#define SI114X_REG_PS_LED21 0x0f +#define SI114X_REG_PS_LED3 0x10 +#define SI114X_REG_PARAM_WR 0x17 +#define SI114X_REG_COMMAND 0x18 +#define SI114X_REG_ALSVIS_DATA0 0x22 +#define SI114X_REG_ALSVIS_DATA1 0x23 +#define SI114X_REG_ALSIR_DATA0 0x24 +#define SI114X_REG_ALSIR_DATA1 0x25 +#define SI114X_REG_PS1_DATA0 0x26 +#define SI114X_REG_PS1_DATA1 0x27 +#define SI114X_REG_PS2_DATA0 0x28 +#define SI114X_REG_PS2_DATA1 0x29 +#define SI114X_REG_PS3_DATA0 0x2a +#define SI114X_REG_PS3_DATA1 0x2b +#define SI114X_REG_AUX_DATA0 0x2c +#define SI114X_REG_AUX_DATA1 0x2d + +/* Commands for COMMAND */ +#define SI114X_CMD_NOP 0x00 +#define SI114X_CMD_RESET 0x01 +#define SI114X_CMD_BUSADDR 0x02 +#define SI114X_CMD_PS_FORCE 0x05 +#define SI114X_CMD_ALS_FORCE 0x06 +#define SI114X_CMD_PSALS_FORCE 0x07 +#define SI114X_CMD_PS_PAUSE 0x09 +#define SI114X_CMD_ALS_PAUSE 0x0a +#define SI114X_CMD_PSALS_PAUSE 0x0b +#define SI114X_CMD_PS_AUTO 0x0d +#define SI114X_CMD_ALS_AUTO 0x0e +#define SI114X_CMD_PSALS_AUTO 0x0f +#define SI114X_CMD_PARAM_QUERY 0x80 +#define SI114X_CMD_PARAM_SET 0xa0 +#define SI114X_CMD_PARAM_AND 0xc0 +#define SI114X_CMD_PARAM_OR 0xe0 + +/* Parameter offsets */ +#define SI114X_PARAM_CHLIST 0x01 +#define SI114X_PARAM_PSLED12_SELECT 0x02 +#define SI114X_PARAM_PSLED3_SELECT 0x03 +#define SI114X_PARAM_PS_ADC_COUNTER 0x0a +#define SI114X_PARAM_PS_ADC_GAIN 0x0b +#define SI114X_PARAM_PS_ADC_MISC 0x0c + +/* Channel enable masks for CHLIST parameter */ +#define SI114X_CHLIST_EN_PS1 0x01 +#define SI114X_CHLIST_EN_PS2 0x02 +#define SI114X_CHLIST_EN_PS3 0x04 +#define SI114X_CHLIST_EN_ALSVIS 0x10 +#define SI114X_CHLIST_EN_ALSIR 0x20 +#define SI114X_CHLIST_EN_AUX 0x40 + +/* Measurement rate settings */ +#define SI114X_MEAS_RATE_FORCED 0x00 +#define SI114X_MEAS_RATE_10MS 0x84 +#define SI114X_MEAS_RATE_20MS 0x94 +#define SI114X_MEAS_RATE_100MS 0xb9 +#define SI114X_MEAS_RATE_496MS 0xdf +#define SI114X_MEAS_RATE_1984MS 0xff + +/* ALS rate settings relative to measurement rate */ +#define SI114X_ALS_RATE_OFF 0x00 +#define SI114X_ALS_RATE_1X 0x08 +#define SI114X_ALS_RATE_10X 0x32 +#define SI114X_ALS_RATE_100X 0x69 + +/* PS rate settings relative to measurement rate */ +#define SI114X_PS_RATE_OFF 0x00 +#define SI114X_PS_RATE_1X 0x08 +#define SI114X_PS_RATE_10X 0x32 +#define SI114X_PS_RATE_100X 0x69 #define CP2112_GETSET_GPIO_CONFIG 0x02 #define CP2112_GET_GPIO 0x03 @@ -130,6 +204,14 @@ return 0; } +static int cp2112_write_param_byte(hid_device *hd, unsigned char param, unsigned char data) { + if (cp2112_write_byte(hd, SI114X_REG_PARAM_WR, data) < 0) + return -1; + if (cp2112_write_byte(hd, SI114X_REG_COMMAND, param | SI114X_CMD_PARAM_SET) < 0) + return -1; + return 0; +} + /* read a data byte from register reg of the si1143 */ static int cp2112_read_byte(hid_device *hd, unsigned char reg, unsigned char data[1]) { /* 0x5a is the 7-bit SMBus slave address of the si1143 */ @@ -155,7 +237,7 @@ } - if (buf_in[0] == CP2112_TRANSFER_STATUS_REQ) + if (buf_in[0] == CP2112_TRANSFER_STATUS_REQ) continue; if (buf_in[0] == CP2112_DATA_READ_RESP) { @@ -171,6 +253,18 @@ return -1; } +static int cp2112_read_word(hid_device *hd, unsigned char reg, unsigned short data[1]) { + unsigned char lsb, msb; + + if (cp2112_read_byte(hd, reg, &lsb) < 0) + return -1; + if (cp2112_read_byte(hd, reg+1, &msb) < 0) + return -1; + + data[0] = (msb << 8) | lsb; + return 0; +} + /* configure cp2112 GPIO pins */ static int cp2112_config_gpio(hid_device *hd) { unsigned char buf[5] = { CP2112_GETSET_GPIO_CONFIG, }; @@ -235,27 +329,81 @@ exit(EXIT_FAILURE); /* write 0x17 to si114x HW_KEY register as per datasheet */ - if (cp2112_write_byte(hd, SI114X_HWKEY, 0x17) < 0) + if (cp2112_write_byte(hd, SI114X_REG_HWKEY, 0x17) < 0) exit(EXIT_FAILURE); unsigned char part, rev, seq; - if (cp2112_read_byte(hd, SI114x_PART_ID, &part) < 0) + if (cp2112_read_byte(hd, SI114x_REG_PART_ID, &part) < 0) exit(EXIT_FAILURE); - if (cp2112_read_byte(hd, SI114x_REV_ID, &rev) < 0) + if (cp2112_read_byte(hd, SI114x_REG_REV_ID, &rev) < 0) exit(EXIT_FAILURE); - if (cp2112_read_byte(hd, SI114x_SEQ_ID, &seq) < 0) + if (cp2112_read_byte(hd, SI114x_REG_SEQ_ID, &seq) < 0) exit(EXIT_FAILURE); printf("si114x part number 0x%02x, revision 0x%02x, sequencer 0x%02x\n", part, rev, seq); + if (cp2112_write_byte(hd, SI114X_REG_COMMAND, SI114X_CMD_RESET) < 0) + exit(EXIT_FAILURE); + usleep(20000); + + if (cp2112_write_byte(hd, SI114X_REG_HWKEY, 0x17) < 0) + exit(EXIT_FAILURE); + usleep(20000); + + cp2112_is_idle(hd); + + /* set LED currents to maximum */ + if (cp2112_write_byte(hd, SI114X_REG_PS_LED3, 0x04)) + exit(EXIT_FAILURE); + if (cp2112_write_byte(hd, SI114X_REG_PS_LED21, 0x32)) + exit(EXIT_FAILURE); + + if (cp2112_write_param_byte(hd, SI114X_PARAM_PS_ADC_MISC, 0x00 | 0x04)) + exit(EXIT_FAILURE); + + if (cp2112_write_param_byte(hd, SI114X_PARAM_PSLED12_SELECT, 0x21)) + exit(EXIT_FAILURE); + + if (cp2112_write_param_byte(hd, SI114X_PARAM_PSLED3_SELECT, 0x04)) + exit(EXIT_FAILURE); + + if (cp2112_write_param_byte(hd, SI114X_PARAM_CHLIST, + SI114X_CHLIST_EN_ALSVIS | + SI114X_CHLIST_EN_PS3 | + SI114X_CHLIST_EN_PS2 | + SI114X_CHLIST_EN_PS1)) + exit(EXIT_FAILURE); + + if (cp2112_write_param_byte(hd, SI114X_PARAM_PS_ADC_GAIN, 0x01)) + exit(EXIT_FAILURE); + + if (cp2112_write_param_byte(hd, SI114X_PARAM_PS_ADC_COUNTER, 0x06 << 4)) + exit(EXIT_FAILURE); + + /* in autonomous mode, wakeup every 100 ms */ + if (cp2112_write_byte(hd, SI114X_REG_MEAS_RATE, SI114X_MEAS_RATE_100MS)) + exit(EXIT_FAILURE); + + /* measure ALS every time device wakes up */ + if (cp2112_write_byte(hd, SI114X_REG_ALS_RATE, SI114X_ALS_RATE_1X)) + exit(EXIT_FAILURE); + + /* measure proximity every time device wakes up */ + if (cp2112_write_byte(hd, SI114X_REG_PS_RATE, SI114X_PS_RATE_1X)) + exit(EXIT_FAILURE); + + if (cp2112_write_byte(hd, SI114X_REG_COMMAND, SI114X_CMD_PSALS_AUTO)) + exit(EXIT_FAILURE); + cp2112_is_idle(hd); if (cp2112_config_gpio(hd) < 0) exit(EXIT_FAILURE); while (1) { + unsigned short als, ps1, ps2, ps3; if (cp2112_set_gpio(hd, CP2112_LEDS_MASK, CP2112_LED_DOWN) < 0) exit(EXIT_FAILURE); usleep(50*1000); @@ -268,6 +416,17 @@ if (cp2112_set_gpio(hd, CP2112_LEDS_MASK, CP2112_LED_LEFT) < 0) exit(EXIT_FAILURE); usleep(50*1000); + + if (cp2112_read_word(hd, SI114X_REG_ALSVIS_DATA0, &als) < 0) + exit(EXIT_FAILURE); + if (cp2112_read_word(hd, SI114X_REG_PS1_DATA0, &ps1) < 0) + exit(EXIT_FAILURE); + if (cp2112_read_word(hd, SI114X_REG_PS2_DATA0, &ps2) < 0) + exit(EXIT_FAILURE); + if (cp2112_read_word(hd, SI114X_REG_PS3_DATA0, &ps3) < 0) + exit(EXIT_FAILURE); + + printf("%d %d %d %d\n", ps1, ps2, ps3, als); } /* never get here */