Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* this is libusb, see http://libusb.sourceforge.net/ */
#include <usb.h>
static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid, char *buf, int buflen);
static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName, int product, char *productName);
char getDisplayInput(uint8_t disnum);
char getDisplayCount();
char getControllerVersion();
char getDisplayMeta(uint8_t disnum);
char setDisplayLatch(uint8_t disnum);
char setDisplayDigit(uint8_t disnum, uint8_t digit, uint8_t value);
usb_dev_handle *handle = NULL;
char usbReplyBuf[64];
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
#define MAX_DISPLAYS 4
#define USB_GET_VERSION 01
#define USB_GET_DISPLAY_COUNT 10
#define USB_GET_DISPLAY_META 11
#define USB_SET_LATCH 20
#define USB_SET_DISPLAY_DIGIT 21
#define USB_SET_POINTS 23
#define USB_GET_DISPLAY_INPUT 30
typedef struct display {
uint8_t address;
unsigned short version;
char config;
char digits[10];
char outer;
char inner;
char buttons;
} display_t;
typedef struct controller_t {
unsigned char display_count;
unsigned short version;
display_t* dis[MAX_DISPLAYS];
} controller_t;
controller_t controller;
int main(int argc, char **argv) {
int nBytes = 0;
char buffer[256];
handle = usbOpenDevice(0x20a0, "newioit.com.au", 0x4236, "NIT Comm/Nav");
if(handle == NULL) {
fprintf(stderr, "Could not find USB device!\n");
exit(1);
}
getControllerVersion();
printf("Controller Version: %x\n", controller.version);
getDisplayCount();
printf("Displays attached: %d\n", controller.display_count);
int i=0;
for (i=0; i<controller.display_count; i++) {
controller.dis[i] = malloc(sizeof(display_t));
getDisplayMeta(i);
printf("Display #%i\n", i);
printf("\tAddress: %x\n", controller.dis[i]->address);
printf("\tVersion: %x\n", controller.dis[i]->version);
printf("\tConfig: %x\n", controller.dis[i]->config);
// Clear the current digits
int j=0;
for (j=0;j<10;j++)
setDisplayDigit(i,j,0x0a);
setDisplayDigit(i, 0, controller.dis[i]->config);
setDisplayLatch(i);
getDisplayInput(i);
printf("\n");
printf("\tButton: %x\n", controller.dis[i]->buttons);
printf("\tOuter: %x\n", controller.dis[i]->outer);
printf("\tInner: %x\n", controller.dis[i]->inner);
}
for (i=0; i<controller.display_count; i++) {
free(controller.dis[i]);
}
if (handle!=NULL)
usb_close(handle);
printf("Exiting\n");
return 0;
}
char setDisplayLatch(uint8_t disnum) {
char nBytes = 0;
nBytes = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_ENDPOINT_IN,
USB_SET_LATCH,
disnum, // What value should be displayed
0,
(char*)usbReplyBuf,
sizeof(usbReplyBuf),
5000);
return nBytes;
}
char setDisplayDigit(uint8_t disnum, uint8_t digit, uint8_t value) {
char nBytes = 0;
nBytes = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_ENDPOINT_IN,
USB_SET_DISPLAY_DIGIT,
(uint16_t)disnum << 8 |(uint16_t)digit, // HN of display #, LN the digit #
value, // What value should be displayed
(char*)usbReplyBuf,
sizeof(usbReplyBuf),
5000);
return nBytes;
}
char getDisplayInput(uint8_t disnum) {
char nBytes = 0;
nBytes = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_ENDPOINT_IN,
USB_GET_DISPLAY_INPUT,
disnum,
0,
(char*)usbReplyBuf,
sizeof(usbReplyBuf),
5000);
controller.dis[disnum]->buttons = usbReplyBuf[0];
controller.dis[disnum]->outer = usbReplyBuf[1];
controller.dis[disnum]->inner = usbReplyBuf[2];
return nBytes;
}
char getDisplayCount() {
char nBytes = 0;
nBytes = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_ENDPOINT_IN,
USB_GET_DISPLAY_COUNT,
0,
0,
(char*)usbReplyBuf,
sizeof(usbReplyBuf),
5000);
controller.display_count = usbReplyBuf[0];
return nBytes;
}
char getDisplayMeta(uint8_t disnum) {
char nBytes = 0;
nBytes = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_ENDPOINT_IN,
USB_GET_DISPLAY_META,
disnum,
0,
(char*)usbReplyBuf,
sizeof(usbReplyBuf),
5000);
controller.dis[disnum]->version = (uint16_t)(usbReplyBuf[0] << 8);
controller.dis[disnum]->version |= (uint16_t)usbReplyBuf[1] & 0xff;
controller.dis[disnum]->address = usbReplyBuf[2];
controller.dis[disnum]->config = usbReplyBuf[3];
return nBytes;
}
char getControllerVersion() {
char nBytes = 0;
nBytes = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_ENDPOINT_IN,
USB_GET_VERSION,
0,
0,
(char*)usbReplyBuf,
sizeof(usbReplyBuf),
5000);
controller.version = ((unsigned short)usbReplyBuf[0]) << 8;
controller.version |= (usbReplyBuf[1] & 0xff);
return nBytes;
}
/* Used to get descriptor strings for device identification */
static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid,
char *buf, int buflen) {
char buffer[256];
int rval, i;
// make standard request GET_DESCRIPTOR, type string and given index
// (e.g. dev->iProduct)
rval = usb_control_msg(dev,
USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid,
buffer, sizeof(buffer), 1000);
if(rval < 0) // error
return rval;
// rval should be bytes read, but buffer[0] contains the actual response size
if((unsigned char)buffer[0] < rval)
rval = (unsigned char)buffer[0]; // string is shorter than bytes read
if(buffer[1] != USB_DT_STRING) // second byte is the data type
return 0; // invalid return type
// we're dealing with UTF-16LE here so actual chars is half of rval,
// and index 0 doesn't count
rval /= 2;
/* lossy conversion to ISO Latin1 */
for(i = 1; i < rval && i < buflen; i++) {
if(buffer[2 * i + 1] == 0)
buf[i-1] = buffer[2 * i];
else
buf[i-1] = '?'; /* outside of ISO Latin1 range */
}
buf[i-1] = 0;
return i-1;
}
static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName,
int product, char *productName) {
struct usb_bus *bus;
struct usb_device *dev;
char devVendor[256], devProduct[256];
usb_dev_handle * handle = NULL;
usb_init();
usb_find_busses();
usb_find_devices();
for(bus=usb_get_busses(); bus; bus=bus->next) {
for(dev=bus->devices; dev; dev=dev->next) {
if(dev->descriptor.idVendor != vendor ||
dev->descriptor.idProduct != product)
continue;
/* we need to open the device in order to query strings */
if(!(handle = usb_open(dev))) {
fprintf(stderr, "Warning: cannot open USB device: %s\n",
usb_strerror());
continue;
}
/* get vendor name */
if(usbGetDescriptorString(handle, dev->descriptor.iManufacturer, 0x0409, devVendor, sizeof(devVendor)) < 0) {
fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror());
usb_close(handle);
continue;
}
/* get product name */
if(usbGetDescriptorString(handle, dev->descriptor.iProduct, 0x0409, devProduct, sizeof(devVendor)) < 0) {
fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror()); usb_close(handle);
continue;
}
if(strcmp(devVendor, vendorName) == 0 && strcmp(devProduct, productName) == 0)
return handle;
else
usb_close(handle);
}
}
return NULL;
}