Subversion Repositories group.NITPanels

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pfowler 1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
26 pfowler 4
 
5
/* this is libusb, see http://libusb.sourceforge.net/ */
2 pfowler 6
#include <usb.h>
7
 
8
 
9
static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid, char *buf, int buflen);
10
static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName, int product, char *productName);
11
 
26 pfowler 12
char getDisplayInput(uint8_t disnum);
13
char getDisplayCount();
14
char getControllerVersion();
15
char getDisplayMeta(uint8_t disnum);
2 pfowler 16
 
26 pfowler 17
char setDisplayLatch(uint8_t disnum);
18
char setDisplayDigit(uint8_t disnum, uint8_t digit, uint8_t value);
2 pfowler 19
 
20
usb_dev_handle *handle = NULL;
21
char usbReplyBuf[64];
22
 
26 pfowler 23
typedef unsigned char uint8_t;
24
typedef unsigned short uint16_t;
25
 
26
#define MAX_DISPLAYS			4
27
 
28
#define USB_GET_VERSION			01
29
#define USB_GET_DISPLAY_COUNT	10
30
#define USB_GET_DISPLAY_META	11
31
 
32
#define USB_SET_LATCH			20
33
#define USB_SET_DISPLAY_DIGIT	21
34
#define USB_SET_POINTS			23
35
#define USB_GET_DISPLAY_INPUT	30
36
 
2 pfowler 37
typedef struct display {
26 pfowler 38
	uint8_t address;
39
	unsigned short version;
40
	char config;
41
 
2 pfowler 42
	char digits[10];
26 pfowler 43
 
44
	char outer;
45
	char inner;
2 pfowler 46
	char buttons;
26 pfowler 47
 
2 pfowler 48
} display_t;
49
 
50
typedef struct controller_t {
26 pfowler 51
	unsigned char display_count;
52
	unsigned short version;
53
	display_t* dis[MAX_DISPLAYS];
2 pfowler 54
} controller_t;
55
 
56
controller_t controller;
57
 
26 pfowler 58
int main(int argc, char **argv) {
59
    int nBytes = 0;
60
    char buffer[256];
2 pfowler 61
 
26 pfowler 62
    handle = usbOpenDevice(0x20a0, "newioit.com.au", 0x4236, "NIT Comm/Nav");
2 pfowler 63
 
26 pfowler 64
    if(handle == NULL) {
65
	    fprintf(stderr, "Could not find USB device!\n");
66
	    exit(1);
67
    }
2 pfowler 68
 
26 pfowler 69
    getControllerVersion();
70
    printf("Controller Version: %x\n", controller.version);
71
 
72
    getDisplayCount();
73
    printf("Displays attached: %d\n", controller.display_count);
74
    int i=0;
75
    for (i=0; i<controller.display_count; i++) { 
76
      controller.dis[i] = malloc(sizeof(display_t));
77
      getDisplayMeta(i);
2 pfowler 78
 
26 pfowler 79
      printf("Display #%i\n", i);
80
      printf("\tAddress: %x\n", controller.dis[i]->address);
81
      printf("\tVersion: %x\n", controller.dis[i]->version);
82
      printf("\tConfig: %x\n", controller.dis[i]->config);
2 pfowler 83
 
26 pfowler 84
      // Clear the current digits
85
      int j=0;
86
      for (j=0;j<10;j++)
87
    	  setDisplayDigit(i,j,0x0a);
2 pfowler 88
 
26 pfowler 89
      setDisplayDigit(i, 0, controller.dis[i]->config);
90
      setDisplayLatch(i);
2 pfowler 91
 
26 pfowler 92
      getDisplayInput(i);
2 pfowler 93
 
26 pfowler 94
      printf("\n");
95
      printf("\tButton: %x\n", controller.dis[i]->buttons);
96
      printf("\tOuter: %x\n", controller.dis[i]->outer);
97
      printf("\tInner: %x\n", controller.dis[i]->inner);
98
    }
2 pfowler 99
 
100
 
26 pfowler 101
    for (i=0; i<controller.display_count; i++) {
102
    	free(controller.dis[i]);
103
    }
2 pfowler 104
 
26 pfowler 105
    if (handle!=NULL)
106
    	usb_close(handle);
2 pfowler 107
 
26 pfowler 108
    printf("Exiting\n");
2 pfowler 109
 
26 pfowler 110
    return 0;
111
}
2 pfowler 112
 
26 pfowler 113
char setDisplayLatch(uint8_t disnum) {
114
	char nBytes = 0;
2 pfowler 115
 
26 pfowler 116
	nBytes = usb_control_msg(handle,
117
		USB_TYPE_VENDOR | USB_ENDPOINT_IN,
118
		USB_SET_LATCH,
119
		disnum,								// What value should be displayed
120
		0,
121
		(char*)usbReplyBuf,
122
		sizeof(usbReplyBuf),
123
		5000);
2 pfowler 124
 
26 pfowler 125
	return nBytes;
2 pfowler 126
}
127
 
26 pfowler 128
char setDisplayDigit(uint8_t disnum, uint8_t digit, uint8_t value) {
129
	char nBytes = 0;
130
  	nBytes = usb_control_msg(handle,
131
		USB_TYPE_VENDOR | USB_ENDPOINT_IN,
132
		USB_SET_DISPLAY_DIGIT,
133
		(uint16_t)disnum << 8 |(uint16_t)digit,	// HN of display #, LN the digit #
134
		value,					// What value should be displayed
135
		(char*)usbReplyBuf,
136
		sizeof(usbReplyBuf),
137
		5000);
2 pfowler 138
 
26 pfowler 139
	return nBytes;
2 pfowler 140
}
141
 
26 pfowler 142
char getDisplayInput(uint8_t disnum) {
2 pfowler 143
	char nBytes = 0;
144
 
145
	nBytes = usb_control_msg(handle,
26 pfowler 146
		USB_TYPE_VENDOR | USB_ENDPOINT_IN,
147
		USB_GET_DISPLAY_INPUT,
148
		disnum,
2 pfowler 149
		0,
150
		(char*)usbReplyBuf,
151
		sizeof(usbReplyBuf),
152
		5000);
153
 
26 pfowler 154
	controller.dis[disnum]->buttons = usbReplyBuf[0];
155
	controller.dis[disnum]->outer = usbReplyBuf[1];
156
	controller.dis[disnum]->inner = usbReplyBuf[2];
157
 
2 pfowler 158
	return nBytes;
159
}
160
 
26 pfowler 161
char getDisplayCount() {
2 pfowler 162
	char nBytes = 0;
163
 
164
	nBytes = usb_control_msg(handle,
26 pfowler 165
		USB_TYPE_VENDOR | USB_ENDPOINT_IN,
166
		USB_GET_DISPLAY_COUNT,
2 pfowler 167
		0,
26 pfowler 168
		0,
2 pfowler 169
		(char*)usbReplyBuf,
170
		sizeof(usbReplyBuf),
171
		5000);
172
 
26 pfowler 173
	controller.display_count = usbReplyBuf[0];
2 pfowler 174
	return nBytes;
175
}
176
 
26 pfowler 177
char getDisplayMeta(uint8_t disnum) {
2 pfowler 178
	char nBytes = 0;
179
 
180
	nBytes = usb_control_msg(handle,
26 pfowler 181
		USB_TYPE_VENDOR | USB_ENDPOINT_IN,
182
		USB_GET_DISPLAY_META,
183
		disnum,
184
		0,
2 pfowler 185
		(char*)usbReplyBuf,
186
		sizeof(usbReplyBuf),
187
		5000);
26 pfowler 188
 
189
	controller.dis[disnum]->version = (uint16_t)(usbReplyBuf[0] << 8);
190
	controller.dis[disnum]->version |= (uint16_t)usbReplyBuf[1] & 0xff;
191
	controller.dis[disnum]->address = usbReplyBuf[2];
192
	controller.dis[disnum]->config = usbReplyBuf[3];
193
	return nBytes;
2 pfowler 194
}
195
 
26 pfowler 196
char getControllerVersion() {
2 pfowler 197
	char nBytes = 0;
198
 
199
	nBytes = usb_control_msg(handle,
26 pfowler 200
		USB_TYPE_VENDOR | USB_ENDPOINT_IN,
201
		USB_GET_VERSION,
202
		0,
203
		0,
2 pfowler 204
		(char*)usbReplyBuf,
205
		sizeof(usbReplyBuf),
206
		5000);
26 pfowler 207
 
208
	controller.version = ((unsigned short)usbReplyBuf[0]) << 8;
209
	controller.version |= (usbReplyBuf[1] & 0xff);
2 pfowler 210
	return nBytes;
211
}
212
 
213
 
214
/* Used to get descriptor strings for device identification */
26 pfowler 215
static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid, 
2 pfowler 216
                                  char *buf, int buflen) {
217
    char buffer[256];
218
    int rval, i;
219
 
26 pfowler 220
	// make standard request GET_DESCRIPTOR, type string and given index 
2 pfowler 221
    // (e.g. dev->iProduct)
26 pfowler 222
	rval = usb_control_msg(dev, 
223
        USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_ENDPOINT_IN, 
224
        USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid, 
2 pfowler 225
        buffer, sizeof(buffer), 1000);
26 pfowler 226
 
2 pfowler 227
    if(rval < 0) // error
228
		return rval;
26 pfowler 229
 
2 pfowler 230
    // rval should be bytes read, but buffer[0] contains the actual response size
231
	if((unsigned char)buffer[0] < rval)
26 pfowler 232
		rval = (unsigned char)buffer[0]; // string is shorter than bytes read
233
 
2 pfowler 234
	if(buffer[1] != USB_DT_STRING) // second byte is the data type
235
		return 0; // invalid return type
26 pfowler 236
 
2 pfowler 237
	// we're dealing with UTF-16LE here so actual chars is half of rval,
238
	// and index 0 doesn't count
239
	rval /= 2;
26 pfowler 240
 
2 pfowler 241
	/* lossy conversion to ISO Latin1 */
242
	for(i = 1; i < rval && i < buflen; i++) {
243
		if(buffer[2 * i + 1] == 0)
244
			buf[i-1] = buffer[2 * i];
245
		else
246
			buf[i-1] = '?'; /* outside of ISO Latin1 range */
247
	}
248
	buf[i-1] = 0;
26 pfowler 249
 
2 pfowler 250
	return i-1;
251
}
252
 
26 pfowler 253
static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName, 
2 pfowler 254
                                      int product, char *productName) {
255
	struct usb_bus *bus;
256
	struct usb_device *dev;
257
	char devVendor[256], devProduct[256];
26 pfowler 258
 
2 pfowler 259
	usb_dev_handle * handle = NULL;
26 pfowler 260
 
2 pfowler 261
	usb_init();
262
	usb_find_busses();
263
	usb_find_devices();
26 pfowler 264
 
2 pfowler 265
	for(bus=usb_get_busses(); bus; bus=bus->next) {
26 pfowler 266
		for(dev=bus->devices; dev; dev=dev->next) {			
267
 
2 pfowler 268
			if(dev->descriptor.idVendor != vendor ||
269
               			dev->descriptor.idProduct != product)
270
                		continue;
26 pfowler 271
 
2 pfowler 272
		         /* we need to open the device in order to query strings */
273
            		if(!(handle = usb_open(dev))) {
274
                		fprintf(stderr, "Warning: cannot open USB device: %s\n",
275
                    		usb_strerror());
276
                		continue;
277
            		}
26 pfowler 278
 
2 pfowler 279
			/* get vendor name */
280
            		if(usbGetDescriptorString(handle, dev->descriptor.iManufacturer, 0x0409, devVendor, sizeof(devVendor)) < 0) {
281
                		fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror());
282
                		usb_close(handle);
283
                		continue;
284
            		}
26 pfowler 285
 
2 pfowler 286
            		/* get product name */
287
            		if(usbGetDescriptorString(handle, dev->descriptor.iProduct, 0x0409, devProduct, sizeof(devVendor)) < 0) {
288
                		fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror()); usb_close(handle);
289
                		continue;
290
            		}
26 pfowler 291
 
2 pfowler 292
            		if(strcmp(devVendor, vendorName) == 0 && strcmp(devProduct, productName) == 0)
293
                		return handle;
294
            		else
295
                		usb_close(handle);
296
		}
297
	}
26 pfowler 298
 
2 pfowler 299
	return NULL;
300
}