]> sigrok.org Git - libsigrok.git/blob - hardware/zeroplus-logic-cube/gl_usb.c
Start of code base layout restructuring.
[libsigrok.git] / hardware / zeroplus-logic-cube / gl_usb.c
1 /*
2  Copyright (c) 2010 Sven Peter <sven@fail0verflow.com>
3  Copyright (c) 2010 Haxx Enterprises <bushing@gmail.com>
4  All rights reserved.
5
6  Redistribution and use in source and binary forms, with or
7  without modification, are permitted provided that the following
8  conditions are met:
9
10  * Redistributions of source code must retain the above copyright notice,
11    this list of conditions and the following disclaimer.
12
13  * Redistributions in binary form must reproduce the above copyright notice,
14    this list of conditions and the following disclaimer in the documentation
15    and/or other materials provided with the distribution.
16
17   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27   THE POSSIBILITY OF SUCH DAMAGE.
28
29 */
30 #include <libusb.h>
31 #include <stdio.h>
32 #include "gl_usb.h"
33
34 #define CTRL_IN                 (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_INTERFACE)
35 #define CTRL_OUT                (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT | LIBUSB_RECIPIENT_INTERFACE)
36 const int PACKET_CTRL_LEN=2;
37
38 const int PACKET_INT_LEN=2;
39 const int PACKET_BULK_LEN=64;
40 const int INTERFACE=0;
41 const int ENDPOINT_INT_IN=0x81; /* endpoint 0x81 address for IN */
42 const int ENDPOINT_INT_OUT=0x01; /* endpoint 1 address for OUT */
43 const int ENDPOINT_BULK_IN=0x81; /* endpoint 0x81 address for IN */
44 const int ENDPOINT_BULK_OUT=0x02; /* endpoint 1 address for OUT */
45 const int TIMEOUT=5000; /* timeout in ms */
46
47 enum {
48         REQ_READBULK = 0x82,
49         REQ_WRITEADDR,
50         REQ_READDATA,
51         REQ_WRITEDATA,
52 };
53
54 static struct libusb_device_handle *g_devh = NULL;
55
56 int gl_write_address(libusb_device_handle *devh, unsigned int address)
57 {
58         unsigned char packet[8] = {address & 0xFF};
59         int retval = libusb_control_transfer(devh, CTRL_OUT, 0xc, REQ_WRITEADDR, 0, packet, 1,TIMEOUT);
60         if (retval != 1) printf("%s: libusb_control_transfer returned %d\n", __FUNCTION__, retval);
61         return retval;
62 }
63
64 int gl_write_data(libusb_device_handle *devh, unsigned int val)
65 {
66         unsigned char packet[8] = {val & 0xFF};
67         int retval = libusb_control_transfer(devh, CTRL_OUT, 0xc, REQ_WRITEDATA, 0, packet, 1,TIMEOUT);
68         if (retval != 1) printf("%s: libusb_control_transfer returned %d\n", __FUNCTION__, retval);
69         return retval;
70 }
71
72 int gl_read_data(libusb_device_handle *devh)
73 {
74         unsigned char packet[8] = {0};
75         int retval = libusb_control_transfer(devh, CTRL_IN, 0xc, REQ_READDATA, 0, packet, 1,TIMEOUT);
76         if (retval != 1) printf("%s: libusb_control_transfer returned %d, val=%hhx\n", __FUNCTION__, retval, packet[0]);
77         return retval == 1 ? packet[0] : retval;
78 }
79
80 int gl_read_bulk(libusb_device_handle *devh, void *buffer, unsigned int size)
81 {
82         unsigned char packet[8] = {0, 0, 0, 0, size & 0xff, (size & 0xff00) >> 8, (size & 0xff0000) >> 16, (size & 0xff000000)>>24};
83         int transferred = 0;
84
85         int retval = libusb_control_transfer(devh, CTRL_OUT, 0x4, REQ_READBULK, 0, packet, 8, TIMEOUT);
86         if (retval != 8) printf("%s: libusb_control_transfer returned %d\n", __FUNCTION__, retval);
87
88         retval = libusb_bulk_transfer(devh, ENDPOINT_BULK_IN, buffer, size,
89                                                                   &transferred, TIMEOUT);
90         if (retval < 0) {
91                 fprintf(stderr, "Bulk read error %d\n", retval);
92         }
93         return transferred;
94 }
95
96 int gl_reg_write(libusb_device_handle *devh, unsigned int reg, unsigned int val)
97 {
98         int retval;
99         retval = gl_write_address(devh, reg);
100         if (retval < 0)
101                 return retval;
102         retval = gl_write_data(devh, val);
103         return retval;
104 }
105
106 int gl_reg_read(libusb_device_handle *devh, unsigned int reg)
107 {
108         int retval;
109         retval = gl_write_address(devh, reg);
110         if (retval < 0)
111                 return retval;
112         retval = gl_read_data(devh);
113         return retval;
114 }
115
116 int gl_open(int vid)
117 {
118         int r = 1;
119
120         r = libusb_init(NULL);
121         if (r < 0)
122                 return GL_ELIBUSB;
123
124         libusb_set_debug(NULL, 0);
125
126         struct libusb_device **devs;
127         struct libusb_device *dev;
128         size_t i = 0;
129
130         if (libusb_get_device_list(NULL, &devs) < 0) {
131                 r = GL_EOPEN;
132                 goto gl_open_error;
133         }
134
135         while ((dev = devs[i++]) != NULL) {
136                 struct libusb_device_descriptor desc;
137                 if (libusb_get_device_descriptor(dev, &desc) < 0)
138                         break;
139
140                 if (desc.idVendor == vid) {
141                         if (libusb_open(dev, &g_devh) < 0)
142                                 g_devh = NULL;
143                         break;
144                 }
145         }
146
147         libusb_free_device_list(devs, 1);
148
149         if (!g_devh) {
150                 r = GL_EOPEN;
151                 goto gl_open_error;
152         }
153
154         r = libusb_set_configuration(g_devh, 1);
155         if (r < 0) {
156                 r = GL_ESETCONFIG;
157                 goto gl_open_error;
158         }
159
160         r = libusb_claim_interface(g_devh, 0);
161         if (r < 0) {
162                 r = GL_ECLAIM;
163                 goto gl_open_error;
164         }
165
166         return GL_OK;
167
168 gl_open_error:
169         gl_close();
170         return r;
171 }
172
173 int gl_close(void)
174 {
175         if (g_devh) {
176                 libusb_release_interface(g_devh, 0);
177                 libusb_reset_device(g_devh);
178                 libusb_close(g_devh);
179         }
180         libusb_exit(NULL);
181
182         return 0;
183 }