Subversion Repositories group.NITPanels

Rev

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;
}