]> sigrok.org Git - libsigrok.git/blame - hardware/zeroplus-logic-cube/gl_usb.c
Start of code base layout restructuring.
[libsigrok.git] / hardware / zeroplus-logic-cube / gl_usb.c
CommitLineData
a1bb33af
UH
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)
36const int PACKET_CTRL_LEN=2;
37
38const int PACKET_INT_LEN=2;
39const int PACKET_BULK_LEN=64;
40const int INTERFACE=0;
41const int ENDPOINT_INT_IN=0x81; /* endpoint 0x81 address for IN */
42const int ENDPOINT_INT_OUT=0x01; /* endpoint 1 address for OUT */
43const int ENDPOINT_BULK_IN=0x81; /* endpoint 0x81 address for IN */
44const int ENDPOINT_BULK_OUT=0x02; /* endpoint 1 address for OUT */
45const int TIMEOUT=5000; /* timeout in ms */
46
47enum {
48 REQ_READBULK = 0x82,
49 REQ_WRITEADDR,
50 REQ_READDATA,
51 REQ_WRITEDATA,
52};
53
54static struct libusb_device_handle *g_devh = NULL;
55
56int 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
64int 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
72int 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
80int 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
96int 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
106int 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
116int 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
168gl_open_error:
169 gl_close();
170 return r;
171}
172
173int 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}