From 1fc407cac055599496c8bda955e0a3689e7c79ed Mon Sep 17 00:00:00 2001 From: Peter Farsinsen <peter@farsinsen.dk> Date: Thu, 13 Sep 2012 20:03:51 +0200 Subject: [PATCH] Initial commit of pcsensor v. 1.0.1 --- 99-tempsensor.rules | 1 + Makefile | 12 ++ pcsensor | Bin 0 -> 17090 bytes pcsensor.c | 450 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 463 insertions(+) create mode 100644 99-tempsensor.rules create mode 100644 Makefile create mode 100755 pcsensor create mode 100644 pcsensor.c diff --git a/99-tempsensor.rules b/99-tempsensor.rules new file mode 100644 index 0000000..30a2e1e --- /dev/null +++ b/99-tempsensor.rules @@ -0,0 +1 @@ +SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7401", MODE="666" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0557550 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +all: pcsensor + +CFLAGS = -O2 -Wall + +pcsensor: pcsensor.c + ${CC} -DUNIT_TEST -o $@ $^ -lusb + +clean: + rm -f pcsensor *.o + +rules-install: # must be superuser to do this + cp 99-tempsensor.rules /etc/udev/rules.d diff --git a/pcsensor b/pcsensor new file mode 100755 index 0000000000000000000000000000000000000000..ea22415784610780d5666d1afd7dbbda6ff4db40 GIT binary patch literal 17090 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 literal 0 HcmV?d00001 diff --git a/pcsensor.c b/pcsensor.c new file mode 100644 index 0000000..ea2b03b --- /dev/null +++ b/pcsensor.c @@ -0,0 +1,450 @@ +/* + * pcsensor.c by Juan Carlos Perez (c) 2011 (cray@isp-sl.com) + * based on Temper.c by Robert Kavaler (c) 2009 (relavak.com) + * All rights reserved. + * + * 2011/08/30 Thanks to EdorFaus: bugfix to support negative temperatures + * + * 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 Juan Carlos Perez ''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 <usb.h> +#include <stdio.h> +#include <time.h> + +#include <string.h> +#include <errno.h> +#include <signal.h> + + +#define VERSION "1.0.1" + +#define VENDOR_ID 0x0c45 +#define PRODUCT_ID 0x7401 + +#define INTERFACE1 0x00 +#define INTERFACE2 0x01 + +const static int reqIntLen=8; +const static int reqBulkLen=8; +const static int endpoint_Int_in=0x82; /* endpoint 0x81 address for IN */ +const static int endpoint_Int_out=0x00; /* endpoint 1 address for OUT */ +const static int endpoint_Bulk_in=0x82; /* endpoint 0x81 address for IN */ +const static int endpoint_Bulk_out=0x00; /* endpoint 1 address for OUT */ +const static int timeout=5000; /* timeout in ms */ + +const static char uTemperatura[] = { 0x01, 0x80, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00 }; +const static char uIni1[] = { 0x01, 0x82, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00 }; +const static char uIni2[] = { 0x01, 0x86, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00 }; + +static int bsalir=1; +static int debug=0; +static int seconds=5; +static int formato=0; +static int mrtg=0; +static int calibration=0; + + +void bad(const char *why) { + fprintf(stderr,"Fatal error> %s\n",why); + exit(17); +} + + +usb_dev_handle *find_lvr_winusb(); + +void usb_detach(usb_dev_handle *lvr_winusb, int iInterface) { + int ret; + + ret = usb_detach_kernel_driver_np(lvr_winusb, iInterface); + if(ret) { + if(errno == ENODATA) { + if(debug) { + printf("Device already detached\n"); + } + } else { + if(debug) { + printf("Detach failed: %s[%d]\n", + strerror(errno), errno); + printf("Continuing anyway\n"); + } + } + } else { + if(debug) { + printf("detach successful\n"); + } + } +} + +usb_dev_handle* setup_libusb_access() { + usb_dev_handle *lvr_winusb; + + if(debug) { + usb_set_debug(255); + } else { + usb_set_debug(0); + } + usb_init(); + usb_find_busses(); + usb_find_devices(); + + + if(!(lvr_winusb = find_lvr_winusb())) { + printf("Couldn't find the USB device, Exiting\n"); + return NULL; + } + + + usb_detach(lvr_winusb, INTERFACE1); + + + usb_detach(lvr_winusb, INTERFACE2); + + + if (usb_set_configuration(lvr_winusb, 0x01) < 0) { + printf("Could not set configuration 1\n"); + return NULL; + } + + + // Microdia tiene 2 interfaces + if (usb_claim_interface(lvr_winusb, INTERFACE1) < 0) { + printf("Could not claim interface\n"); + return NULL; + } + + if (usb_claim_interface(lvr_winusb, INTERFACE2) < 0) { + printf("Could not claim interface\n"); + return NULL; + } + + return lvr_winusb; +} + + + +usb_dev_handle *find_lvr_winusb() { + + struct usb_bus *bus; + struct usb_device *dev; + + for (bus = usb_busses; bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + if (dev->descriptor.idVendor == VENDOR_ID && + dev->descriptor.idProduct == PRODUCT_ID ) { + usb_dev_handle *handle; + if(debug) { + printf("lvr_winusb with Vendor Id: %x and Product Id: %x found.\n", VENDOR_ID, PRODUCT_ID); + } + + if (!(handle = usb_open(dev))) { + printf("Could not open USB device\n"); + return NULL; + } + return handle; + } + } + } + return NULL; +} + + +void ini_control_transfer(usb_dev_handle *dev) { + int r,i; + + char question[] = { 0x01,0x01 }; + + r = usb_control_msg(dev, 0x21, 0x09, 0x0201, 0x00, (char *) question, 2, timeout); + if( r < 0 ) + { + perror("USB control write"); bad("USB write failed"); + } + + + if(debug) { + for (i=0;i<reqIntLen; i++) printf("%02x ",question[i] & 0xFF); + printf("\n"); + } +} + +void control_transfer(usb_dev_handle *dev, const char *pquestion) { + int r,i; + + char question[reqIntLen]; + + memcpy(question, pquestion, sizeof question); + + r = usb_control_msg(dev, 0x21, 0x09, 0x0200, 0x01, (char *) question, reqIntLen, timeout); + if( r < 0 ) + { + perror("USB control write"); bad("USB write failed"); + } + + if(debug) { + for (i=0;i<reqIntLen; i++) printf("%02x ",question[i] & 0xFF); + printf("\n"); + } +} + +void interrupt_transfer(usb_dev_handle *dev) { + + int r,i; + char answer[reqIntLen]; + char question[reqIntLen]; + for (i=0;i<reqIntLen; i++) question[i]=i; + r = usb_interrupt_write(dev, endpoint_Int_out, question, reqIntLen, timeout); + if( r < 0 ) + { + perror("USB interrupt write"); bad("USB write failed"); + } + r = usb_interrupt_read(dev, endpoint_Int_in, answer, reqIntLen, timeout); + if( r != reqIntLen ) + { + perror("USB interrupt read"); bad("USB read failed"); + } + + if(debug) { + for (i=0;i<reqIntLen; i++) printf("%i, %i, \n",question[i],answer[i]); + } + + usb_release_interface(dev, 0); +} + +void interrupt_read(usb_dev_handle *dev) { + + int r,i; + unsigned char answer[reqIntLen]; + bzero(answer, reqIntLen); + + r = usb_interrupt_read(dev, 0x82, answer, reqIntLen, timeout); + if( r != reqIntLen ) + { + perror("USB interrupt read"); bad("USB read failed"); + } + + if(debug) { + for (i=0;i<reqIntLen; i++) printf("%02x ",answer[i] & 0xFF); + + printf("\n"); + } +} + +void interrupt_read_temperatura(usb_dev_handle *dev, float *tempC) { + + int r,i, temperature; + unsigned char answer[reqIntLen]; + bzero(answer, reqIntLen); + + r = usb_interrupt_read(dev, 0x82, answer, reqIntLen, timeout); + if( r != reqIntLen ) + { + perror("USB interrupt read"); bad("USB read failed"); + } + + + if(debug) { + for (i=0;i<reqIntLen; i++) printf("%02x ",answer[i] & 0xFF); + + printf("\n"); + } + + temperature = (answer[3] & 0xFF) + ((signed char)answer[2] << 8); + temperature += calibration; + *tempC = temperature * (125.0 / 32000.0); + +} + +void bulk_transfer(usb_dev_handle *dev) { + + int r,i; + char answer[reqBulkLen]; + + r = usb_bulk_write(dev, endpoint_Bulk_out, NULL, 0, timeout); + if( r < 0 ) + { + perror("USB bulk write"); bad("USB write failed"); + } + r = usb_bulk_read(dev, endpoint_Bulk_in, answer, reqBulkLen, timeout); + if( r != reqBulkLen ) + { + perror("USB bulk read"); bad("USB read failed"); + } + + + if(debug) { + for (i=0;i<reqBulkLen; i++) printf("%02x ",answer[i] & 0xFF); + } + + usb_release_interface(dev, 0); +} + + +void ex_program(int sig) { + bsalir=1; + + (void) signal(SIGINT, SIG_DFL); +} + +int main( int argc, char **argv) { + + usb_dev_handle *lvr_winusb = NULL; + float tempc; + int c; + struct tm *local; + time_t t; + + while ((c = getopt (argc, argv, "mfcvhl::a:")) != -1) + switch (c) + { + case 'v': + debug = 1; + break; + case 'c': + formato=1; //Celsius + break; + case 'f': + formato=2; //Fahrenheit + break; + case 'm': + mrtg=1; + break; + case 'l': + if (optarg!=NULL){ + if (!sscanf(optarg,"%i",&seconds)==1) { + fprintf (stderr, "Error: '%s' is not numeric.\n", optarg); + exit(EXIT_FAILURE); + } else { + bsalir = 0; + break; + } + } else { + bsalir = 0; + seconds = 5; + break; + } + case 'a': + if (!sscanf(optarg,"%i",&calibration)==1) { + fprintf (stderr, "Error: '%s' is not numeric.\n", optarg); + exit(EXIT_FAILURE); + } else { + break; + } + case '?': + case 'h': + printf("pcsensor version %s\n",VERSION); + printf(" Aviable options:\n"); + printf(" -h help\n"); + printf(" -v verbose\n"); + printf(" -l[n] loop every 'n' seconds, default value is 5s\n"); + printf(" -c output only in Celsius\n"); + printf(" -f output only in Fahrenheit\n"); + printf(" -a[n] increase or decrease temperature in 'n' degrees for device calibration\n"); + printf(" -m output for mrtg integration\n"); + + exit(EXIT_FAILURE); + default: + if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, + "Unknown option character `\\x%x'.\n", + optopt); + exit(EXIT_FAILURE); + } + + if (optind < argc) { + fprintf(stderr, "Non-option ARGV-elements, try -h for help.\n"); + exit(EXIT_FAILURE); + } + + if ((lvr_winusb = setup_libusb_access()) == NULL) { + exit(EXIT_FAILURE); + } + + (void) signal(SIGINT, ex_program); + + ini_control_transfer(lvr_winusb); + + control_transfer(lvr_winusb, uTemperatura ); + interrupt_read(lvr_winusb); + + control_transfer(lvr_winusb, uIni1 ); + interrupt_read(lvr_winusb); + + control_transfer(lvr_winusb, uIni2 ); + interrupt_read(lvr_winusb); + interrupt_read(lvr_winusb); + + + + do { + control_transfer(lvr_winusb, uTemperatura ); + interrupt_read_temperatura(lvr_winusb, &tempc); + + t = time(NULL); + local = localtime(&t); + + if (mrtg) { + if (formato==2) { + printf("%.2f\n", (9.0 / 5.0 * tempc + 32.0)); + printf("%.2f\n", (9.0 / 5.0 * tempc + 32.0)); + } else { + printf("%.2f\n", tempc); + printf("%.2f\n", tempc); + } + + printf("%02d:%02d\n", + local->tm_hour, + local->tm_min); + + printf("pcsensor\n"); + } else { + printf("%04d/%02d/%02d %02d:%02d:%02d ", + local->tm_year +1900, + local->tm_mon + 1, + local->tm_mday, + local->tm_hour, + local->tm_min, + local->tm_sec); + + if (formato==2) { + printf("Temperature %.2fF\n", (9.0 / 5.0 * tempc + 32.0)); + } else if (formato==1) { + printf("Temperature %.2fC\n", tempc); + } else { + printf("Temperature %.2fF %.2fC\n", (9.0 / 5.0 * tempc + 32.0), tempc); + } + } + + if (!bsalir) + sleep(seconds); + } while (!bsalir); + + usb_release_interface(lvr_winusb, INTERFACE1); + usb_release_interface(lvr_winusb, INTERFACE2); + + usb_close(lvr_winusb); + + return 0; +}