summaryrefslogtreecommitdiffstats
path: root/libk8055.c
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy@asynk.ch>2011-02-19 00:06:20 +0100
committerJérémy Zurcher <jeremy@asynk.ch>2011-02-19 00:06:20 +0100
commit876d6f498bbf358a23b47edaf8b0d967724b1b94 (patch)
tree01f50dcb0fc680bbad756f6d4d2bf8a9e791530e /libk8055.c
parent9bfdbb1d569eea229fd9f10823891234c8676145 (diff)
downloadk8055-876d6f498bbf358a23b47edaf8b0d967724b1b94.zip
k8055-876d6f498bbf358a23b47edaf8b0d967724b1b94.tar.gz
libk8055 uses cmake
Diffstat (limited to 'libk8055.c')
-rw-r--r--libk8055.c600
1 files changed, 0 insertions, 600 deletions
diff --git a/libk8055.c b/libk8055.c
deleted file mode 100644
index 9556294..0000000
--- a/libk8055.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/* $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);
-}