summaryrefslogtreecommitdiffstats
path: root/libk8055
diff options
context:
space:
mode:
Diffstat (limited to 'libk8055')
-rw-r--r--libk8055/CMakeLists.txt24
-rw-r--r--libk8055/k8055.1.gzbin0 -> 1843 bytes
-rw-r--r--libk8055/k8055.h55
-rw-r--r--libk8055/libk8055.c600
-rw-r--r--libk8055/main.c295
-rwxr-xr-xlibk8055/test4
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
new file mode 100644
index 0000000..042fdf4
--- /dev/null
+++ b/libk8055/k8055.1.gz
Binary files differ
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