diff options
Diffstat (limited to 'libk8055')
-rw-r--r-- | libk8055/CMakeLists.txt | 24 | ||||
-rw-r--r-- | libk8055/k8055.1.gz | bin | 0 -> 1843 bytes | |||
-rw-r--r-- | libk8055/k8055.h | 55 | ||||
-rw-r--r-- | libk8055/libk8055.c | 600 | ||||
-rw-r--r-- | libk8055/main.c | 295 | ||||
-rwxr-xr-x | libk8055/test | 4 |
6 files changed, 978 insertions, 0 deletions
diff --git a/libk8055/CMakeLists.txt b/libk8055/CMakeLists.txt new file mode 100644 index 0000000..62398ff --- /dev/null +++ b/libk8055/CMakeLists.txt @@ -0,0 +1,24 @@ + +ADD_LIBRARY( k8055-${VERSION} SHARED libk8055.c ) +ADD_LIBRARY( k8055-static-${VERSION} STATIC libk8055.c ) +INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} ) +TARGET_LINK_LIBRARIES( k8055-${VERSION} + usb + m +) +SET_TARGET_PROPERTIES(k8055-${VERSION} PROPERTIES PUBLIC_HEADER k8055.h ) + +INSTALL(TARGETS k8055-${VERSION} + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + PUBLIC_HEADER DESTINATION include +) + +ADD_EXECUTABLE(k8055 WIN32 MACOSX_BUNDLE main.c ) +TARGET_LINK_LIBRARIES(k8055 + k8055-${VERSION} +) +ADD_DEPENDENCIES(k8055 k8055-${VERSION}) + +INSTALL(TARGETS k8055 RUNTIME DESTINATION bin BUNDLE DESTINATION bin ) +INSTALL(FILES k8055.1.gz DESTINATION man/man1/ ) diff --git a/libk8055/k8055.1.gz b/libk8055/k8055.1.gz Binary files differnew file mode 100644 index 0000000..042fdf4 --- /dev/null +++ b/libk8055/k8055.1.gz diff --git a/libk8055/k8055.h b/libk8055/k8055.h new file mode 100644 index 0000000..4d5ae81 --- /dev/null +++ b/libk8055/k8055.h @@ -0,0 +1,55 @@ +/* $Id: k8055.h,v 1.4 2008/05/21 20:25:51 mr_brain Exp $ + + This file is part of the libk8055 Library. + + The libk8055 Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The libk8055 Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the + Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + http://opensource.org/licenses/ +*/ +#ifdef __cplusplus +extern "C" { +#endif + +/* prototypes */ +int OpenDevice(long board_address); +int CloseDevice(); +long ReadAnalogChannel(long Channelno); +int ReadAllAnalog(long* data1, long* data2); +int OutputAnalogChannel(long channel, long data); +int OutputAllAnalog(long data1,long data2); +int ClearAllAnalog(); +int ClearAnalogChannel(long channel); +int SetAnalogChannel(long channel); +int SetAllAnalog(); +int WriteAllDigital(long data); +int ClearDigitalChannel(long channel); +int ClearAllDigital(); +int SetDigitalChannel(long channel); +int SetAllDigital(); +int ReadDigitalChannel(long channel); +long ReadAllDigital(); +int ResetCounter(long counternr); +long ReadCounter(long counterno); +int SetCounterDebounceTime(long counterno, long debouncetime); +int ReadAllValues (long int *data1, long int *data2, long int *data3, long int *data4, long int *data5); +int SetAllValues(int digitaldata, int addata1, int addata2); +long SetCurrentDevice(long deviceno); +long SearchDevices(void); +char *Version(void); +#ifdef __cplusplus +} +#endif + diff --git a/libk8055/libk8055.c b/libk8055/libk8055.c new file mode 100644 index 0000000..9556294 --- /dev/null +++ b/libk8055/libk8055.c @@ -0,0 +1,600 @@ +/* $Id: libk8055.c,v 1.7 2008/08/20 17:00:55 mr_brain Exp $ + + This file is part of the libk8055 Library. + + The libk8055 Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The libk8055 Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the + Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + http://opensource.org/licenses/ + + Copyleft (C) 2005 by Sven Lindberg + k8055@k8055.mine.nu + + Copyright (C) 2007 by Pjetur G. Hjaltason + pjetur@pjetur.net + Commenting, general rearrangement of code, bugfixes, + python interface with swig and simple k8055 python class + + + Input packet format + + +---+---+---+---+---+---+---+---+ + |DIn|Sta|A1 |A2 | C1 | C2 | + +---+---+---+---+---+---+---+---+ + DIn = Digital input in high nibble, except for input 3 in 0x01 + Sta = Status, Board number + 1 + A1 = Analog input 1, 0-255 + A2 = Analog input 2, 0-255 + C1 = Counter 1, 16 bits (lsb) + C2 = Counter 2, 16 bits (lsb) + + Output packet format + + +---+---+---+---+---+---+---+---+ + |CMD|DIG|An1|An2|Rs1|Rs2|Dbv|Dbv| + +---+---+---+---+---+---+---+---+ + CMD = Command + DIG = Digital output bitmask + An1 = Analog output 1 value, 0-255 + An2 = Analog output 2 value, 0-255 + Rs1 = Reset counter 1, command 3 + Rs2 = Reset counter 3, command 4 + Dbv = Debounce value for counter 1 and 2, command 1 and 2 + + Or split by commands + + Cmd 0, Reset ?? + Cmd 1, Set debounce Counter 1 + +---+---+---+---+---+---+---+---+ + |CMD| | | | | |Dbv| | + +---+---+---+---+---+---+---+---+ + Cmd 2, Set debounce Counter 2 + +---+---+---+---+---+---+---+---+ + |CMD| | | | | | |Dbv| + +---+---+---+---+---+---+---+---+ + Cmd 3, Reset counter 1 + +---+---+---+---+---+---+---+---+ + | 3 | | | | 00| | | | + +---+---+---+---+---+---+---+---+ + Cmd 4, Reset counter 2 + +---+---+---+---+---+---+---+---+ + | 4 | | | | | 00| | | + +---+---+---+---+---+---+---+---+ + cmd 5, Set analog/digital + +---+---+---+---+---+---+---+---+ + | 5 |DIG|An1|An2| | | | | + +---+---+---+---+---+---+---+---+ + +**/ + +#include <string.h> +#include <stdio.h> +#include <usb.h> +#include <assert.h> +#include <math.h> +#include "k8055.h" + +#define STR_BUFF 256 +#define PACKET_LEN 8 + +#define K8055_IPID 0x5500 +#define VELLEMAN_VENDOR_ID 0x10cf +#define K8055_MAX_DEV 4 + +#define USB_OUT_EP 0x01 /* USB output endpoint */ +#define USB_INP_EP 0x81 /* USB Input endpoint */ + +#define USB_TIMEOUT 20 +#define K8055_ERROR -1 + +#define DIGITAL_INP_OFFSET 0 +#define DIGITAL_OUT_OFFSET 1 +#define ANALOG_1_OFFSET 2 +#define ANALOG_2_OFFSET 3 +#define COUNTER_1_OFFSET 4 +#define COUNTER_2_OFFSET 6 + +#define CMD_RESET 0x00 +#define CMD_SET_DEBOUNCE_1 0x01 +#define CMD_SET_DEBOUNCE_2 0x01 +#define CMD_RESET_COUNTER_1 0x03 +#define CMD_RESET_COUNTER_2 0x04 +#define CMD_SET_ANALOG_DIGITAL 0x05 + +/* set debug to 0 to not print excess info */ +int DEBUG = 0; + +/* variables for usb */ +static struct usb_bus *bus, *busses; +static struct usb_device *dev; + +/* globals for datatransfer */ +struct k8055_dev { + unsigned char data_in[PACKET_LEN+1]; + unsigned char data_out[PACKET_LEN+1]; + struct usb_dev_handle *device_handle; + int DevNo; +}; + +static struct k8055_dev k8055d[K8055_MAX_DEV]; +static struct k8055_dev *CurrDev; + +/* Keep these globals for now */ +unsigned char *data_in, *data_out; + +/* char* device_id[]; */ + +/* Initialize the usb library - only once */ +static void init_usb(void) +{ + static int Done = 0; /* Only need to do this once */ + if (!Done) + { + usb_init(); + usb_find_busses(); + usb_find_devices(); + busses = usb_get_busses(); + Done = 1; + } +} +/* Actual read of data from the device endpoint, retry 3 times if not responding ok */ +static int ReadK8055Data(void) +{ + int read_status = 0, i = 0; + + if (CurrDev->DevNo == 0) return K8055_ERROR; + + for(i=0; i < 3; i++) + { + read_status = usb_interrupt_read(CurrDev->device_handle, USB_INP_EP, (char *)CurrDev->data_in, PACKET_LEN, USB_TIMEOUT); + if ((read_status == PACKET_LEN) && (CurrDev->data_in[1] == CurrDev->DevNo )) return 0; + if (DEBUG) + fprintf(stderr, "Read retry\n"); + } + return K8055_ERROR; +} + +/* Actual write of data to the device endpont, retry 3 times if not reponding correctly */ +static int WriteK8055Data(unsigned char cmd) +{ + int write_status = 0, i = 0; + + if (CurrDev->DevNo == 0) return K8055_ERROR; + + CurrDev->data_out[0] = cmd; + for(i=0; i < 3; i++) + { + write_status = usb_interrupt_write(CurrDev->device_handle, USB_OUT_EP, (char *)CurrDev->data_out, PACKET_LEN, USB_TIMEOUT); + if (write_status == PACKET_LEN) return 0; + if (DEBUG) + fprintf(stderr, "Write retry\n"); + } + return K8055_ERROR; +} + +/* If device is owned by some kernel driver, try to disconnect it and claim the device*/ +static int takeover_device(usb_dev_handle * udev, int interface) +{ + char driver_name[STR_BUFF]; + + memset(driver_name, 0, STR_BUFF); + int ret = K8055_ERROR; + + assert(udev != NULL); + ret = usb_get_driver_np(udev, interface, driver_name, sizeof(driver_name)); + if (ret == 0) + { + if (DEBUG) + fprintf(stderr, "Got driver name: %s\n", driver_name); + if (0 > usb_detach_kernel_driver_np(udev, interface)) + { + if (DEBUG) + fprintf(stderr, "Disconnect OS driver: %s\n", usb_strerror()); + } + else if (DEBUG) + fprintf(stderr, "Disconnected OS driver: %s\n", usb_strerror()); + } + else if (DEBUG) + fprintf(stderr, "Get driver name: - %s\n", usb_strerror()); + + /* claim interface */ + if (usb_claim_interface(udev, interface) < 0) + { + if (DEBUG) + fprintf(stderr, "Claim interface error: %s\n", usb_strerror()); + return K8055_ERROR; + } + else + usb_set_altinterface(udev, interface); + usb_set_configuration(udev, 1); + + if (DEBUG) + { + fprintf(stderr, "Found interface %d\n", interface); + fprintf(stderr, "Took over the device\n"); + } + + return 0; +} + +/* Open device - scan through usb busses looking for the right device, + claim it and then open the device +*/ +int OpenDevice(long BoardAddress) +{ + + int ipid; + + /* init USB and find all of the devices on all busses */ + init_usb(); + + /* ID of the welleman board is 5500h + address config */ + if (BoardAddress >= 0 && BoardAddress < K8055_MAX_DEV) + ipid = K8055_IPID + (int)BoardAddress; + else + return K8055_ERROR; /* throw error instead of being nice */ + + /* start looping through the devices to find the correct one */ + for (bus = busses; bus; bus = bus->next) + { + for (dev = bus->devices; dev; dev = dev->next) + { + if ((dev->descriptor.idVendor == VELLEMAN_VENDOR_ID) && + (dev->descriptor.idProduct == ipid)) + { + CurrDev = &k8055d[BoardAddress]; + CurrDev->device_handle = usb_open(dev); + if (DEBUG) + fprintf(stderr, + "Velleman Device Found @ Address %s Vendor 0x0%x Product ID 0x0%x\n", + dev->filename, dev->descriptor.idVendor, + dev->descriptor.idProduct); + if (takeover_device(CurrDev->device_handle, 0) < 0) + { + if (DEBUG) + fprintf(stderr, + "Can not take over the device from the OS driver\n"); + usb_close(CurrDev->device_handle); /* close usb if we fail */ + return K8055_ERROR; /* throw K8055_ERROR to show that OpenDevice failed */ + } + else + { + CurrDev->DevNo = BoardAddress + 1; /* Mark as open and valid */ + SetCurrentDevice(BoardAddress); + memset(CurrDev->data_out,0,PACKET_LEN); /* Write cmd 0, read data */ + WriteK8055Data(CMD_RESET); + if (ReadK8055Data() == 0) + return BoardAddress; /* This function should return board address */ + else + return K8055_ERROR; + } + } + } + } + if (DEBUG) + fprintf(stderr, "Could not find Velleman k8055 with address %d\n", + (int)BoardAddress); + return K8055_ERROR; +} + +/* Close the Current device */ +int CloseDevice() +{ + int rc; + + if (CurrDev->DevNo == 0) + { + if (DEBUG) + fprintf(stderr, "Current device is not open\n" ); + return 0; + } + rc = usb_close(CurrDev->device_handle); + if (rc >= 0) + { + CurrDev->DevNo = 0; /* Not active nay more */ + CurrDev->device_handle = NULL; + } + return rc; +} + +/* New function in version 2 of Velleman DLL, should return deviceno if OK */ +long SetCurrentDevice(long deviceno) +{ + if (deviceno >= 0 && deviceno < K8055_MAX_DEV) + { + if (k8055d[deviceno].DevNo != 0) + { + CurrDev = &k8055d[deviceno]; + data_in = CurrDev->data_in; + data_out = CurrDev->data_out; + return deviceno; + } + } + return K8055_ERROR; + +} + +/* New function in version 2 of Velleman DLL, should return devices-found bitmask or 0*/ +long SearchDevices(void) +{ + int retval = 0; + init_usb(); + /* start looping through the devices to find the correct one */ + for (bus = busses; bus; bus = bus->next) + { + for (dev = bus->devices; dev; dev = dev->next) + { + if (dev->descriptor.idVendor == VELLEMAN_VENDOR_ID) { + if(dev->descriptor.idProduct == K8055_IPID + 0) retval |= 0x01; + if(dev->descriptor.idProduct == K8055_IPID + 1) retval |= 0x02; + if(dev->descriptor.idProduct == K8055_IPID + 2) retval |= 0x04; + if(dev->descriptor.idProduct == K8055_IPID + 3) retval |= 0x08; + /* else some other kind of Velleman board */ + } + } + } + return retval; +} + +long ReadAnalogChannel(long Channel) +{ + if (Channel == 1 || Channel == 2) + { + if ( ReadK8055Data() == 0) + { + if (Channel == 2) + return CurrDev->data_in[ANALOG_2_OFFSET]; + else + return CurrDev->data_in[ANALOG_1_OFFSET]; + } + else + return K8055_ERROR; + } + else + return K8055_ERROR; +} + +int ReadAllAnalog(long *data1, long *data2) +{ + if (ReadK8055Data() == 0) + { + *data1 = CurrDev->data_in[ANALOG_1_OFFSET]; + *data2 = CurrDev->data_in[ANALOG_2_OFFSET]; + return 0; + } + else + return K8055_ERROR; +} + +int OutputAnalogChannel(long Channel, long data) +{ + if (Channel == 1 || Channel == 2) + { + if (Channel == 2) + CurrDev->data_out[ANALOG_2_OFFSET] = (unsigned char)data; + else + CurrDev->data_out[ANALOG_1_OFFSET] = (unsigned char)data; + + return WriteK8055Data(CMD_SET_ANALOG_DIGITAL); + } + else + return K8055_ERROR; +} + +int OutputAllAnalog(long data1, long data2) +{ + CurrDev->data_out[2] = (unsigned char)data1; + CurrDev->data_out[3] = (unsigned char)data2; + + return WriteK8055Data(CMD_SET_ANALOG_DIGITAL); +} + +int ClearAllAnalog() +{ + return OutputAllAnalog(0, 0); +} + +int ClearAnalogChannel(long Channel) +{ + if (Channel == 1 || Channel == 2) + { + if (Channel == 2) + return OutputAnalogChannel(2, 0); + else + return OutputAnalogChannel(1, 0); + } + else + return K8055_ERROR; +} + +int SetAnalogChannel(long Channel) +{ + if (Channel == 1 || Channel == 2) + { + if (Channel == 2) + return OutputAnalogChannel(2, 0xff); + else + return OutputAnalogChannel(1, 0xff); + } + else + return K8055_ERROR; + +} + +int SetAllAnalog() +{ + return OutputAllAnalog(0xff, 0xff); +} + +int WriteAllDigital(long data) +{ + CurrDev->data_out[1] = (unsigned char)data; + return WriteK8055Data(CMD_SET_ANALOG_DIGITAL); +} + +int ClearDigitalChannel(long Channel) +{ + unsigned char data; + + if (Channel > 0 && Channel < 9) + { + data = CurrDev->data_out[1] & ~(1 << (Channel-1)); + return WriteAllDigital(data); + } + else + return K8055_ERROR; +} + +int ClearAllDigital() +{ + return WriteAllDigital(0x00); +} + +int SetDigitalChannel(long Channel) +{ + unsigned char data; + + if (Channel > 0 && Channel < 9) + { + data = CurrDev->data_out[1] | (1 << (Channel-1)); + return WriteAllDigital(data); + } + else + return K8055_ERROR; +} + +int SetAllDigital() +{ + return WriteAllDigital(0xff); +} + +int ReadDigitalChannel(long Channel) +{ + int rval; + if (Channel > 0 && Channel < 9) + { + if ((rval = ReadAllDigital()) == K8055_ERROR) return K8055_ERROR; + return ((rval & (1 << (Channel-1))) > 0); + } + else + return K8055_ERROR; +} + +long ReadAllDigital() +{ + int return_data = 0; + + if (ReadK8055Data() == 0) + { + return_data = ( + ((CurrDev->data_in[0] >> 4) & 0x03) | /* Input 1 and 2 */ + ((CurrDev->data_in[0] << 2) & 0x04) | /* Input 3 */ + ((CurrDev->data_in[0] >> 3) & 0x18) ); /* Input 4 and 5 */ + return return_data; + } + else + return K8055_ERROR; +} + +int ReadAllValues(long int *data1, long int * data2, long int * data3, long int * data4, long int * data5) +{ + if (ReadK8055Data() == 0) + { + *data1 = ( + ((CurrDev->data_in[0] >> 4) & 0x03) | /* Input 1 and 2 */ + ((CurrDev->data_in[0] << 2) & 0x04) | /* Input 3 */ + ((CurrDev->data_in[0] >> 3) & 0x18) ); /* Input 4 and 5 */ + *data2 = CurrDev->data_in[ANALOG_1_OFFSET]; + *data3 = CurrDev->data_in[ANALOG_2_OFFSET]; + *data4 = *((short int *)(&CurrDev->data_in[COUNTER_1_OFFSET])); + *data5 = *((short int *)(&CurrDev->data_in[COUNTER_2_OFFSET])); + return 0; + } + else + return K8055_ERROR; +} + +int SetAllValues(int DigitalData, int AdData1, int AdData2) +{ + CurrDev->data_out[1] = (unsigned char)DigitalData; + CurrDev->data_out[2] = (unsigned char)AdData1; + CurrDev->data_out[3] = (unsigned char)AdData2; + + return WriteK8055Data(CMD_SET_ANALOG_DIGITAL); +} + +int ResetCounter(long CounterNo) +{ + if (CounterNo == 1 || CounterNo == 2) + { + CurrDev->data_out[0] = 0x02 + (unsigned char)CounterNo; /* counter selection */ + CurrDev->data_out[3 + CounterNo] = 0x00; + return WriteK8055Data(CurrDev->data_out[0]); + } + else + return K8055_ERROR; +} + +long ReadCounter(long CounterNo) +{ + if (CounterNo == 1 || CounterNo == 2) + { + if (ReadK8055Data() == 0) + { + if (CounterNo == 2) + return *((short int *)(&CurrDev->data_in[COUNTER_2_OFFSET])); + else + return *((short int *)(&CurrDev->data_in[COUNTER_1_OFFSET])); + } + else + return K8055_ERROR; + } + else + return K8055_ERROR; +} + +int SetCounterDebounceTime(long CounterNo, long DebounceTime) +{ + float value; + + if (CounterNo == 1 || CounterNo == 2) + { + CurrDev->data_out[0] = (unsigned char)CounterNo; + /* the velleman k8055 use a exponetial formula to split up the + DebounceTime 0-7450 over value 1-255. I've tested every value and + found that the formula dbt=0,338*value^1,8017 is closest to + vellemans dll. By testing and measuring times on the other hand I + found the formula dbt=0,115*x^2 quite near the actual values, a + little below at really low values and a little above at really + high values. But the time set with this formula is within +-4% */ + if (DebounceTime > 7450) + DebounceTime = 7450; + value = sqrtf(DebounceTime / 0.115); + if (value > ((int)value + 0.49999999)) /* simple round() function) */ + value += 1; + CurrDev->data_out[5 + CounterNo] = (unsigned char)value; + if (DEBUG) + fprintf(stderr, "Debouncetime%d value for k8055:%d\n", + (int)CounterNo, CurrDev->data_out[5 + CounterNo]); + return WriteK8055Data(CurrDev->data_out[0]); + } + else + return K8055_ERROR; +} + +char * Version(void) +{ + return(VERSION); +} diff --git a/libk8055/main.c b/libk8055/main.c new file mode 100644 index 0000000..a6fa602 --- /dev/null +++ b/libk8055/main.c @@ -0,0 +1,295 @@ +/* $Id: main.c,v 1.3 2007/03/15 14:37:58 pjetur Exp $ + *************************************************************************** + * Copyright (C) 2004 by Nicolas Sutre * + * nicolas.sutre@free.fr * + * * + * Copyright (C) 2005 by Bob Dempsey * + * bdempsey_64@msn.com * + * * + * Copyright (C) 2005 by Julien Etelain and Edward Nys * + * Converted to C * + * Commented and improved by Julien Etelain <julien.etelain@utbm.fr> * + * Edward Nys <edward.ny@utbm.fr> * + * * + * Copyleft (L) 2005 by Sven Lindberg * + * k8055@k8055.mine.nu * + * Give it up already :) Simplified (read improved..) and included * + * with k8055 lib and with a functional man page * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <string.h> +#include <stdio.h> +#include <usb.h> +#include <assert.h> +#include <sys/time.h> +#include "k8055.h" + +#define STR_BUFF 256 +#define false 0 +#define true 1 + +extern int DEBUG; + +int ia1 = -1; +int ia2 = -1; +int id8 = -1; +int ipid = 0; + +int numread = 1; + +int debug = 0; + +int dbt1 = -1; // (-1 => not to set) +int dbt2 = -1; // (-1 => not to set) + +int resetcnt1 = false; +int resetcnt2 = false; + +int delay = 0; + +/* + Convert a string on n chars to an integer + Return 1 on sucess + 0 on failure (non number) +*/ +int Convert_StringToInt(char *text, int *i) +{ + return sscanf(text, "%d", i); +} + +/* + Write help to standard output +*/ +void display_help ( char *params[] ) { + + printf("K8055 version %s MrBrain Build\n",Version()); + printf("Copyright (C) 2004 by Nicolas Sutre\n"); + printf("Copyright (C) 2005 by Bob Dempsey\n"); + printf("Copyright (C) 2005 by Julien Etelain and Edward Nys\n"); + printf("Copyleft (L) 2005 by Sven Lindberg\n"); + printf("\n"); + printf("Syntax : %s [-p:(number)] [-d:(value)] [-a1:(value)] [-a2:(value)]\n",params[0]); + printf(" [-num:(number) [-delay:(number)] [-dbt1:(value)]\n"); + printf(" [-dbt2:(value)] [-reset1] [-reset2] [-debug]\n"); + printf(" -p:(number) Set board number\n"); + printf(" -d:(value) Set digital output value (8 bits in decimal)\n"); + printf(" -a1:(value) Set analog output 1 value (0-255)\n"); + printf(" -a2:(value) Set analog output 2 value (0-255)\n"); + printf(" -num:(number) Set number of measures\n"); + printf(" -delay:(number) Set delay between two measure (in msec)\n"); + printf(" -dbt1:(value) Set debounce time for counter 1 (in msec)\n"); + printf(" -dbt2:(value) Set debounce time for counter 2 (in msec)\n"); + printf(" -reset1 Reset counter 1\n"); + printf(" -reset2 Reset counter 2\n"); + printf(" -debug Activate debug mode\n"); + printf("Example : %s -p:1 -d:147 -a1:25 -a2:203\n",params[0]); + printf("\n"); + printf("Output : (timestamp);(digital);(analog 1);(analog 2);(counter 1);(counter 2)\n"); + printf("Note : timestamp is the number of msec when data is read since program start\n"); + printf("Example : 499;16;128;230;9;8\n"); + printf("499 : Measure done 499 msec after program start\n"); + +} + + +/* + Read arguments, and store values + Return true if arguments are valid + else return false +*/ +int read_param(int argc,char *params[]) +{ + int erreurParam = false; + int i; + + ipid = 0; + + for (i=1; i<argc;i++) + { + if ( !strncmp(params[i],"-p:",3) && + !Convert_StringToInt(params[i]+3,&ipid) ) erreurParam = true; + else + if ( !strncmp(params[i],"-a1:",4) && + !Convert_StringToInt(params[i]+4,&ia1) ) erreurParam = true; + else + if ( !strncmp(params[i],"-a2:",4) && + !Convert_StringToInt(params[i]+4,&ia2) ) erreurParam = true; + else + if ( !strncmp(params[i],"-d:",3) && + !Convert_StringToInt(params[i]+3,&id8) ) erreurParam = true; + else + if ( !strncmp(params[i],"-num:",5) && + !Convert_StringToInt(params[i]+5,&numread) ) erreurParam = true; + else + if ( !strncmp(params[i],"-delay:",7) && + !Convert_StringToInt(params[i]+7,&delay) ) erreurParam = true; + else + if ( !strncmp(params[i],"-dbt1:",6) && + !Convert_StringToInt(params[i]+6,&dbt1) ) erreurParam = true; + else + if ( !strncmp(params[i],"-dbt2:",6) && + !Convert_StringToInt(params[i]+6,&dbt2) ) erreurParam = true; + else + if ( !strcmp(params[i],"-debug") ){ + debug = true; + DEBUG = true; + } + else + if ( !strcmp(params[i],"-reset1") ) resetcnt1 = true; + else + if ( !strcmp(params[i],"-reset2") ) resetcnt2 = true; + else + if ( !strcmp(params[i],"--help") ) { + display_help(params); + return false; + } + + } + + + /* + Send parameters to standart error + */ + if ( debug ) + fprintf(stderr,"Parameters : Card=%d Analog1=%d Analog2=%d Digital=%d\n",ipid,ia1,ia2,id8); + + if (ipid<0 || ipid>3){ + printf("Invalid board address!\n"); + return -1; + } + + + if (erreurParam) + { + + printf("Invalid or incomplete options\n"); + + display_help(params); + return false; + } + + + return true; +} + +/* + Give current timestamp in miliseconds +*/ +inline unsigned long int time_msec ( void ) { + struct timeval t; struct timezone tz; + gettimeofday (&t,&tz); + return (1000*t.tv_sec)+(t.tv_usec/1000); +} + + +int main (int argc,char *params[]) +{ + int i,result; + long d=0; + long a1=0,a2=0; + long c1=0, c2=0; + unsigned long int start,mstart=0,lastcall=0; + + start = time_msec(); + + /* + Load parameters + If parameters are valid continue + */ + + if (read_param(argc,params)) + { + /* + Initialise USB system + and enable debug mode + + if ( debug ) + usb_set_debug(2); + */ + /* + Search the device + */ + if ( OpenDevice(ipid)<0 ) { + printf("Could not open the k8055 (port:%d)\nPlease ensure that the device is correctly connected.\n",ipid); + return (-1); + + } else { + + if ( resetcnt1 ) + ResetCounter(1); + if ( resetcnt2 ) + ResetCounter(2); + if ( dbt1 != -1 ) + SetCounterDebounceTime(1,dbt1); + if ( dbt2 != -1 ) + SetCounterDebounceTime(2,dbt1); + + if ((ia1!=-1) && (ia2!=-1) && (id8!=-1)) { + result = SetAllValues(id8,ia1,ia2); + if (debug) printf("SetAllValues=%d - Digital:%d, analog1:%d, analog2:%d\n",result,id8,ia1,ia2); + } + else if ((id8 != -1) && (ia1!=-1)) { + result = SetAllValues(id8,ia1,0); + if (debug) printf("SetAllValues=%d - Digital:%d, analog1:%d\n",result,id8,ia1); + } + else if ((id8 != -1) && (ia2!=-1)) { + result = SetAllValues(id8,0,ia2); + if (debug) printf("SetAllValues=%d - Digital:%d, analog2:%d\n",result,id8,ia2); + } + else if ((ia1 != -1) && (ia2!=-1)) { + result = SetAllValues(0,ia1,ia2); + if (debug) printf("SetAllValues=%d - analog1:%d, analog2:%d\n",result,ia1,ia2); + } + else { + if (ia1!=-1) { + result=OutputAnalogChannel(1,ia1); + if (debug) printf("Set analog1:%d=>%d\n",ia1,result); + } + if (ia2!=-1) { + result=OutputAnalogChannel(2,ia2); + if (debug) printf("Set analog2:%d=>%d\n",ia2,result); + } + if (id8!=-1) { + result=WriteAllDigital((long)id8); + if (debug) printf("Set digital:%d=>%d\n",id8,result); + } + } + + mstart = time_msec(); // Measure start + for (i=0; i<numread; i++) { + + if ( delay ) { + // Wait until next measure + while ( time_msec()-mstart < i*delay ); + } + ReadAllValues( &d,&a1,&a2,&c1,&c2); + +/* ReadAllAnalog(&a1,&a2); + d=ReadAllDigital(); + c1=ReadCounter(1); + c2=ReadCounter(2); +*/ + lastcall = time_msec(); + printf("%d;%d;%d;%d;%d;%d\n", (int)(lastcall-start),(int)d, (int)a1, (int)a2,(int)c1,(int)c2 ); + } + + CloseDevice(); + } + } + return 0; +} diff --git a/libk8055/test b/libk8055/test new file mode 100755 index 0000000..bb46807 --- /dev/null +++ b/libk8055/test @@ -0,0 +1,4 @@ +#! /bin/bash +cpt=0 +while [ $cpt -lt 256 ]; do ./build/libk8055/k8055 -d:$cpt -a1:$cpt -a2:$cpt; ((cpt=cpt+1)); done +./build/libk8055/k8055 -d:0 -a1:0 -a2:0 |