changeset 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 bb5e6c6d9310
children 363b95c527d1
files hid-usb-to-ir.c
diffstat 1 files changed, 168 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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 */

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.