diff options
Diffstat (limited to 'modules/temper')
| -rw-r--r-- | modules/temper/99-tempsensor.rules | 1 | ||||
| -rw-r--r-- | modules/temper/Makefile | 12 | ||||
| -rwxr-xr-x | modules/temper/temper | bin | 0 -> 9753 bytes | |||
| -rw-r--r-- | modules/temper/temper.c | 301 | ||||
| -rw-r--r-- | modules/temper/temper.h | 39 | 
5 files changed, 353 insertions, 0 deletions
| diff --git a/modules/temper/99-tempsensor.rules b/modules/temper/99-tempsensor.rules new file mode 100644 index 00000000..441a469e --- /dev/null +++ b/modules/temper/99-tempsensor.rules @@ -0,0 +1 @@ +SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="1130", ATTRS{idProduct}=="660c", MODE="666" diff --git a/modules/temper/Makefile b/modules/temper/Makefile new file mode 100644 index 00000000..db6233fe --- /dev/null +++ b/modules/temper/Makefile @@ -0,0 +1,12 @@ +all:	temper + +CFLAGS = -O2 -Wall + +temper:	temper.c +	${CC} -DUNIT_TEST -o $@ $^ -lusb + +clean:		 +	rm -f temper *.o + +rules-install:			# must be superuser to do this +	cp 99-tempsensor.rules /etc/udev/rules.d diff --git a/modules/temper/temper b/modules/temper/temperBinary files differ new file mode 100755 index 00000000..9f9927fb --- /dev/null +++ b/modules/temper/temper diff --git a/modules/temper/temper.c b/modules/temper/temper.c new file mode 100644 index 00000000..e591c9fa --- /dev/null +++ b/modules/temper/temper.c @@ -0,0 +1,301 @@ +#include <stdio.h> +#include <string.h> +#include <usb.h> +#include <errno.h> + +/* + * Temper.c by Robert Kavaler (c) 2009 (relavak.com) + * All rights reserved. + * + * Temper driver for linux. This program can be compiled either as a library + * or as a standalone program (-DUNIT_TEST). The driver will work with some + * TEMPer usb devices from RDing (www.PCsensor.com). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + *     * Redistributions of source code must retain the above copyright + *       notice, this list of conditions and the following disclaimer. + *  + * THIS SOFTWARE IS PROVIDED BY Robert Kavaler ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Robert kavaler BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *  + */ + +#include "temper.h" + +#define VENDOR_ID  0x1130 +#define PRODUCT_ID 0x660c +#define DEBUG_MODE 0 +#define SLEEP_TIMEOUT 10 + +struct Temper { +	struct usb_device *device; +	usb_dev_handle *handle; +	int debug; +	int timeout; +}; + +Temper * +TemperCreate(struct usb_device *dev, int timeout, int debug) +{ +	Temper *t; +	int ret; + +	t = calloc(1, sizeof(*t)); +	t->device = dev; +	t->debug = debug; +	t->timeout = timeout; +	t->handle = usb_open(t->device); +	if(!t->handle) { +		free(t); +		return NULL; +	} +	if(t->debug) { +		printf("Trying to detach kernel driver\n"); +	} + +	ret = usb_detach_kernel_driver_np(t->handle, 0); +	if(ret) { +		if(errno == ENODATA) { +			if(t->debug) { +				printf("Device already detached\n"); +			} +		} else { +			if(t->debug) { +				printf("Detach failed: %s[%d]\n", +				       strerror(errno), errno); +				printf("Continuing anyway\n"); +			} +		} +	} else { +		if(t->debug) { +			printf("detach successful\n"); +		} +	} +	ret = usb_detach_kernel_driver_np(t->handle, 1); +	if(ret) { +		if(errno == ENODATA) { +			if(t->debug) +				printf("Device already detached\n"); +		} else { +			if(t->debug) { +				printf("Detach failed: %s[%d]\n", +				       strerror(errno), errno); +				printf("Continuing anyway\n"); +			} +		} +	} else { +		if(t->debug) { +			printf("detach successful\n"); +		} +	} + +	if(usb_set_configuration(t->handle, 1) < 0 || +	   usb_claim_interface(t->handle, 0) < 0 || +	   usb_claim_interface(t->handle, 1)) { +		usb_close(t->handle); +		free(t); +		return NULL; +	} +	return t; +} + +Temper * +TemperCreateFromDeviceNumber(int deviceNum, int timeout, int debug) +{ +	struct usb_bus *bus; +	int n; + +	n = 0; +	for(bus=usb_get_busses(); bus; bus=bus->next) { +	    struct usb_device *dev; + +	    for(dev=bus->devices; dev; dev=dev->next) { +		if(debug) { +			printf("Found device: %04x:%04x\n", +			       dev->descriptor.idVendor, +			       dev->descriptor.idProduct); +		} +		if(dev->descriptor.idVendor == VENDOR_ID && +		   dev->descriptor.idProduct == PRODUCT_ID) { +			if(debug) { +			    printf("Found deviceNum %d\n", n); +			} +			if(n == deviceNum) { +				return TemperCreate(dev, timeout, debug); +			} +			n++; +		} +	    } +	} +	return NULL; +} + +void +TemperFree(Temper *t) +{ +	if(t) { +		if(t->handle) { +			usb_close(t->handle); +		} +		free(t); +	} +} + +static int +TemperSendCommand(Temper *t, int a, int b, int c, int d, int e, int f, int g, int h) +{ +	unsigned char buf[32]; +	int ret; + +	bzero(buf, 32); +	buf[0] = a; +	buf[1] = b; +	buf[2] = c; +	buf[3] = d; +	buf[4] = e; +	buf[5] = f; +	buf[6] = g; +	buf[7] = h; + +	if(t->debug) { +		printf("sending bytes %d, %d, %d, %d, %d, %d, %d, %d\n", +		       a, b, c, d, e, f, g, h); +	} + +	ret = usb_control_msg(t->handle, 0x21, 9, 0x200, 0x01, +			    (char *) buf, 32, t->timeout); +	if(ret != 32) { +		perror("usb_control_msg failed"); +		return -1; +	} +	return 0; +} + +static int +TemperGetData(Temper *t, char *buf, int len) +{ +	int ret; + +	return usb_control_msg(t->handle, 0xa1, 1, 0x300, 0x01, +			    (char *) buf, len, t->timeout); +} + +int +TemperGetTemperatureInC(Temper *t, float *tempC) +{ +	char buf[256]; +	int ret, temperature, i; + +	TemperSendCommand(t, 10, 11, 12, 13, 0, 0, 2, 0); +	TemperSendCommand(t, 0x54, 0, 0, 0, 0, 0, 0, 0); +	for(i = 0; i < 7; i++) { +		TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0); +	} +	TemperSendCommand(t, 10, 11, 12, 13, 0, 0, 1, 0); +	ret = TemperGetData(t, buf, 256); +	if(ret < 2) { +		return -1; +	} + +	temperature = (buf[1] & 0xFF) + (buf[0] << 8);	 +	temperature += 1152;			// calibration value +	*tempC = temperature * (125.0 / 32000.0); +	return 0; +} + +int +TemperGetOtherStuff(Temper *t, char *buf, int length) +{ +	TemperSendCommand(t, 10, 11, 12, 13, 0, 0, 2, 0); +	TemperSendCommand(t, 0x52, 0, 0, 0, 0, 0, 0, 0); +	TemperSendCommand(t, 10, 11, 12, 13, 0, 0, 1, 0); +	return TemperGetData(t, buf, length); +} + + +#ifdef UNIT_TEST + +#define USB_TIMEOUT 1000	/* milliseconds */ + +int +main(int argv,char** args) +{ + + +	Temper *t; +	char buf[256]; +	int i, ret,oneshot=0; +  if (argv == 2 && (args[1][1] == 'h' || args[1][0] == 'h')) +  { +    printf("Temper, does the right thing\n"); +    printf("use %s -1 to do one-shot\n"); +    printf("recompile with DEBUG_MODE = 1 for all the debug printing\n"); +    printf("recompile with SLEEP_TIMEOUT = XX for a different polling interval\n"); +    exit(0); +  } + +  if (argv == 2 && (args[1][0] == '1' || args[1][1] == '1')) +    oneshot = 1; + +	usb_set_debug(DEBUG_MODE); +	usb_init(); +	usb_find_busses(); +	usb_find_devices(); + +	t = TemperCreateFromDeviceNumber(0, USB_TIMEOUT, DEBUG_MODE); +	if(!t) { +		perror("TemperCreate"); +		exit(-1); +	} + +/* +	TemperSendCommand(t, 10, 11, 12, 13, 0, 0, 2, 0); +	TemperSendCommand(t, 0x43, 0, 0, 0, 0, 0, 0, 0); +	TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0); +	TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0); +	TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0); +	TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0); +	TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0); +	TemperSendCommand(t, 0, 0, 0, 0, 0, 0, 0, 0); +*/ + +	bzero(buf, 256); +	ret = TemperGetOtherStuff(t, buf, 256); +  if (DEBUG_MODE){ +    printf("Other Stuff (%d bytes):\n", ret); +    for(i = 0; i < ret; i++) { +      printf(" %02x", buf[i] & 0xFF); +      if(i % 16 == 15) { +        printf("\n"); +      } +    } +    printf("\n"); +  } +   +	for(;;) { +		float tempc; + +		if(TemperGetTemperatureInC(t, &tempc) < 0) { +			perror("TemperGetTemperatureInC"); +			exit(1); +		} +		printf("%.2fF %.2fC\n", (9.0 / 5.0 * tempc + 32.0), +		       tempc); +    if (oneshot) +      exit(0); + +		sleep(SLEEP_TIMEOUT); +	} +	return 0; +} + +#endif diff --git a/modules/temper/temper.h b/modules/temper/temper.h new file mode 100644 index 00000000..7ea6280a --- /dev/null +++ b/modules/temper/temper.h @@ -0,0 +1,39 @@ +#ifndef TEMPER_H +#define TEMPER_H + +/* + * Temper.h by Robert Kavaler (c) 2009 (relavak.com) + * All rights reserved. + * + * Temper driver for linux. This program can be compiled either as a library + * or as a standalone program (-DUNIT_TEST). The driver will work with some + * TEMPer usb devices from RDing (www.PCsensor.com). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + *     * Redistributions of source code must retain the above copyright + *       notice, this list of conditions and the following disclaimer. + *  + * THIS SOFTWARE IS PROVIDED BY Robert Kavaler ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Robert kavaler BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *  + */ + +typedef struct Temper Temper; + + +Temper *TemperCreateFromDeviceNumber(int deviceNum, int timeout, int debug); +void TemperFree(Temper *t); + +int TemperGetTemperatureInC(Temper *t, float *tempC); +int TempterGetOtherStuff(Temper *t, char *buf, int length); + +#endif | 
