Subversion Repositories Projects

Rev

Blame | Last modification | View Log | RSS feed

/* x52pro driver library
 * Copyright (C) 2007 Eduard Hasenleithner <eduard@hasenleithner.at>
 * Licensed under the LGPL. Please see "COPYING".
 */

#include <stdio.h>
#include <string.h>
#include <usb.h>
#include "x52.h"

struct x52 {
        usb_dev_handle *hdl;
};

#define X52PRO_REQUEST 0x91

#define X52PRO_CLEAR1 0xd9
#define X52PRO_CLEAR2 0xda
#define X52PRO_CLEAR3 0xdc
#define X52PRO_WRITE1 0xd1
#define X52PRO_WRITE2 0xd2
#define X52PRO_WRITE3 0xd4
#define X52PRO_SETLED 0xb8
#define X52PRO_MFDBRI 0xb1
#define X52PRO_LEDBRI 0xb2

#define X52PRO_TIME   0xc0
#define X52PRO_DATE   0xc4
#define X52PRO_YEAR   0xc8

int write_idx[3] = {
        X52PRO_WRITE1,
        X52PRO_WRITE2,
        X52PRO_WRITE3,
};

int clear_idx[3] = {
        X52PRO_CLEAR1,
        X52PRO_CLEAR2,
        X52PRO_CLEAR3,
};

int x52_settext(struct x52 *x52, int line, char *text, int length)
{
        int r;
        if (line > 3) return -1;
        r = usb_control_msg(x52->hdl,
                USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_OUT,
                X52PRO_REQUEST, 0x00, clear_idx[line], NULL, 0, 1000);
        if (r < 0) {
                fprintf(stderr, "x52_settext failed at clear command (%s)\n",
                        usb_strerror());
                return -2;
        }

        while (length >= 1) {
                int chars;
                if (length == 1) chars = (' ' << 8) + *text;
                else chars = *(unsigned short*) text;
                r = usb_control_msg(x52->hdl,
                        USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_OUT,
                        X52PRO_REQUEST, chars, write_idx[line], NULL, 0, 1000);
                if (r<0) {
                        fprintf(stderr, "x52_settext failed at write %d (%s)\n",
                                length, usb_strerror());
                        return -2;
                }
                length -= 2;
                text += 2;
        }
        return 0;
}

int x52_setbri(struct x52 *x52, int mfd, int brightness)
{
        int r;
        r = usb_control_msg(x52->hdl,
                USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_OUT,
                X52PRO_REQUEST, brightness, mfd ? X52PRO_MFDBRI : X52PRO_LEDBRI,
                NULL, 0, 1000);
        if (r < 0) {
                fprintf(stderr, "x52_setbri failed (%s)\n", usb_strerror());
                return -2;
        }
        return 0;
}

int x52_setled(struct x52 *x52, int led, int on)
{
        int r;
        r = usb_control_msg(x52->hdl,
                USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_OUT,
                X52PRO_REQUEST, on | (led<<8), X52PRO_SETLED,
                NULL, 0, 1000);
        if (r < 0) {
                fprintf(stderr, "x52_setled failed (%s)\n", usb_strerror());
                return -2;
        }
        return 0;
}

int x52_settime(struct x52 *x52, int h24, int hour, int minute)
{
        int r;
        r = usb_control_msg(x52->hdl,
                USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_OUT,
                X52PRO_REQUEST, minute | (hour<<8) | (h24?0x8000:0), X52PRO_TIME,
                NULL, 0, 1000);
        if (r < 0) {
                fprintf(stderr, "x52_settime failed (%s)\n", usb_strerror());
                return -2;
        }
        return 0;
}

int x52_setdate(struct x52 *x52, int year, int month, int day)
{
        int r;
        r = usb_control_msg(x52->hdl,
                USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_OUT,
                X52PRO_REQUEST, day | (month<<8), X52PRO_DATE,
                NULL, 0, 1000);
        if (r < 0) {
                fprintf(stderr, "x52_setdate failed (%s)\n", usb_strerror());
                return -2;
        }
        r = usb_control_msg(x52->hdl,
                USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_OUT,
                X52PRO_REQUEST, year, X52PRO_YEAR,
                NULL, 0, 1000);
        if (r < 0) {
                fprintf(stderr, "x52_setdate failed for year (%s)\n", usb_strerror());
                return -2;
        }
        return 0;
}

int x52_custom(struct x52 *x52, int index, int value)
{
        int r = usb_control_msg(x52->hdl,
                USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_OUT,
                X52PRO_REQUEST, value, index, NULL, 0, 1000);
        if (r < 0) {
                fprintf(stderr, "x52_settext failed at clear command (%s)\n",
                        usb_strerror());
                return -2;
        }
        return 0;
}

struct x52* x52_init(void)
{
        struct x52 x52, *x52p;

        usb_init();
        usb_find_busses();
        usb_find_devices();

        struct usb_bus *bus;
        struct usb_device *joydev = NULL;
        for (bus = usb_busses; bus; bus = bus->next) {
                struct usb_device *dev;
                for (dev = bus->devices; dev; dev = dev->next) {
                        struct usb_device_descriptor *dsc = &dev->descriptor;
                        if (dsc->idVendor == 0x6a3 && ((dsc->idProduct == 0x75c)||(dsc->idProduct == 0x762)))
                          {
                                joydev = dev;
                                break;
                          }
                }
                if (joydev) break;
        }
        if (!joydev) {
                fprintf(stderr, "joystick not found\n");
                return NULL;
        }
        fprintf(stderr, "joystick found\n");
        x52.hdl = usb_open(joydev);
        if (x52.hdl==NULL) {
                fprintf(stderr, "joystick open failed\n");
                return NULL;
        }
        x52p = malloc(sizeof(*x52p));
        *x52p = x52;
        return x52p;
}


void x52_close(struct x52* x52)
{
        int r;
        r = usb_close(x52->hdl);
        free(x52);
        printf("usb_close: %d\n", r);
}