Mercurial > rcctl_linux
diff rcctl.c @ 1:05cc06e88a57
modified to make use of libhid to access the device
| author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
|---|---|
| date | Fri, 24 Dec 2010 15:28:04 +0900 |
| parents | e1a1a181c0d7 |
| children | b16b82dbfe87 |
line wrap: on
line diff
--- a/rcctl.c Thu Dec 16 20:30:11 2010 +0900 +++ b/rcctl.c Fri Dec 24 15:28:04 2010 +0900 @@ -1,207 +1,229 @@ /* rcctl.c --------------------------------------------- -$Id: rcctl.c,v 1.1 2002/12/21 01:13:28 tosy Exp $ + $Id: rcctl.c,v 1.1 2002/12/21 01:13:28 tosy Exp $ - v0.10 97.08.15 初期版(コミケット52) - v0.11 97.08.27 通信タイミング修正 - v0.12 97.09.12 U-kara-2サポート - v0.12a 97.09.15 返り値設定 - v0.12b 97.09.20 Bug fix (JOY:[SP]) - v0.20 97.10.01 FreeBSD版 - v0.20a 97.10.18 Bug fix (X2k:[SP],[ST]) - v0.21 97.12.10 ALISA-3シーケンス修正 - v0.30 97.12.13 コード変換部(cdcnv.c)分離 - v0.40 02.12.16 USB版対応 - 【cdcnv.c の履歴も参照のこと】 -------------------------------------------------------*/ - + v0.10 97.08.15 初期版(コミケット52) + v0.11 97.08.27 通信タイミング修正 + v0.12 97.09.12 U-kara-2サポート + v0.12a 97.09.15 返り値設定 + v0.12b 97.09.20 Bug fix (JOY:[SP]) + v0.20 97.10.01 FreeBSD版 + v0.20a 97.10.18 Bug fix (X2k:[SP],[ST]) + v0.21 97.12.10 ALISA-3シーケンス修正 + v0.30 97.12.13 コード変換部(cdcnv.c)分離 + v0.40 02.12.16 USB版対応 + 【cdcnv.c の履歴も参照のこと】 + ------------------------------------------------------*/ +#define __LINUX__ #include <fcntl.h> #include <stdio.h> #include <termios.h> #include <unistd.h> +#include <sys/ioctl.h> + +#define HID_MAX_USAGES 16 +typedef unsigned int __u32; +typedef unsigned int kernel_ulong_t; + +#include <hid.h> #include <libusb.h> -#include <sys/ioctl.h> -#include <dev/usb/usb.h> -#include <dev/usb/usbhid.h> -/* #define VERBOSE */ -/* #define NOCTSCHK */ +#include <linux/types.h> + +#define BITS_PER_LONG 32 -#ifndef SDEV -#define SDEV "/dev/cuaa0" +#include <asm/types.h> +#include <errno.h> +#include <string.h> + + +#ifndef S_VERS +#define S_VERS "0.41" #endif -#ifndef UDEV -#define UDEV "/dev/uhid0" -#endif +/* globals */ +HIDInterface *hidif; +extern int errno; -#ifndef S_VERS -#define S_VERS "0.40" -#endif - -int fd; - +/* prototypes */ int cdcnv(int buf[], char *mak, char *cod); extern char *cverrstr[]; -int init_sio(void) +int init_usb(void) { -#ifndef NOCTSCHK - int tcnt = 0; -#endif - struct termios tios; - int md; + hid_return ret; + +// unsigned int report_id; +// unsigned int report_type; +// unsigned int size; + + /* vendor id and product id of okecon */ + HIDInterfaceMatcher matcher = { 0x0bfe, 0x2022, NULL, NULL, 0 }; + + /* see include/debug.h for possible values */ + hid_set_debug(HID_DEBUG_ALL); + hid_set_debug_stream(stderr); + /* passed directly to libusb */ + hid_set_usb_debug(0); + + ret = hid_init(); + if (ret != HID_RET_SUCCESS) { + fprintf(stderr, "hid_init failed with return code %d\n", ret); + return 1; + } - if ((fd = open(SDEV, O_RDWR)) == -1) { - fprintf(stderr, "Cannot open %s.\n", SDEV); - return 255; - } + hidif = hid_new_HIDInterface(); + if (hidif == 0) { + fprintf(stderr, "hid_new_HIDInterface() failed, out of memory?\n"); + return 1; + } + + ret = hid_force_open(hidif, 0, &matcher, 3); + if (ret != HID_RET_SUCCESS) { + fprintf(stderr, "hid_force_open failed with return code %d\n", ret); + return 1; + } - tcgetattr(fd, &tios); - tios.c_iflag = 0; - tios.c_oflag = 0; - tios.c_cflag = B9600|CS8|CLOCAL; - tios.c_lflag = 0; -/* - cfmakeraw(&tios); - cfsetspeed(&tios, B9600); -*/ - tcsetattr(fd, TCSANOW, &tios); - tcflush(fd, TCOFLUSH); + + +#if 0 + /* read feature */ + ret = hid_get_feature_report(hidif, path, depth, buffer, size); + if(ret != HID_RET_SUCCESS) { + fprintf(stderr, "hid_get_feature_report failed with return code %d\n", ret); + return 1; + } + + /* parse */ - md = TIOCM_LE|TIOCM_DTR|TIOCM_RTS; - ioctl(fd, TIOCMBIS, &md); + /* prepare buffers */ + hid_get_report_size(hidif, report_id, report_type, &size); + if(size != 8) { + fprintf(stderr, "%s is not 'OKCon/USB'?\n", UDEV); + return 1; + }; + - /* wait for CTS: 充電待ち */ -#ifndef NOCTSCHK - for(;;) { - ioctl(fd, TIOCMGET, &md); - if (md & TIOCM_CTS) - break; - if (tcnt == 0) { - fprintf(stderr, "Waiting...."); +// BSD + /* read header */ + if ((rd = hid_get_report_desc(fd)) == 0) { + fprintf(stderr, "Failed on USB_GET_REPORT_DESC.\n"); + return 1; + } + + /* parse */ + hd = hid_start_parse(rd, 1<<hid_output); + while ( hid_get_item(hd, &shi) ) { + if(shi.kind == hid_output) + break; } - if (tcnt++ >= 30) { - fprintf(stderr, "Device timeout.\n"); - close(fd); - return 1; + hid_end_parse(hd); + + /* prepare buffers */ + hid_get_report_size(&hidif, report_id, report_type, &size); + if(size != 8) { + fprintf(stderr, "%s is not 'OKCon/USB'?\n", UDEV); + return 1; + }; + + hid_dispose_report_desc(rd); +#endif + + return 0; +} /* end of init_usb() */ + + +int fin_usb() +{ + hid_return ret; + + ret = hid_close(hidif); + if (ret != HID_RET_SUCCESS) { + fprintf(stderr, "hid_close failed with return code %d\n", ret); + return 1; } - sleep(1); - } -#endif /* NOCTSCHK */ + + hid_delete_HIDInterface(&hidif); - md = TIOCM_RTS; - ioctl(fd, TIOCMBIC, &md); - usleep(10000); /* 10ms */ - ioctl(fd, TIOCMBIS, &md); - usleep(50000); /* 50ms */ + ret = hid_cleanup(); + if (ret != HID_RET_SUCCESS) { + fprintf(stderr, "hid_cleanup failed with return code %d\n", ret); + return 1; + } - return 0; + return 0; } -/* CTS が 0.5 秒以上連続して ON になるまで待つ */ -void charge(void) -{ -#ifndef NOCTSCHK - int i, md; - for( i=0; i<50; i++ ) { - usleep(10000); /* 10ms */ - ioctl(fd, TIOCMGET, &md); - if (!(md & TIOCM_CTS)) - i = 0; - } -#endif /* NOCTSCHK */ -} - -int init_usb(void) -{ - report_desc_t rd; - hid_data_t hd; - hid_item_t shi; - - hid_init(NULL); - - if((fd = open(UDEV, O_RDWR)) < 0) { - fprintf(stderr, "Cannot open %s.\n", UDEV); - return 1; - } - - /* read header */ - if ((rd = hid_get_report_desc(fd)) == 0) { - fprintf(stderr, "Failed on USB_GET_REPORT_DESC.\n"); - return 1; - } - - /* parse */ - hd = hid_start_parse(rd, 1<<hid_output); - while ( hid_get_item(hd, &shi) ) { - if(shi.kind == hid_output) - break; - } - hid_end_parse(hd); - - /* prepare buffers */ - if (hid_report_size(rd, hid_output, 0) != 8) { - fprintf(stderr, "%s is not 'OKCon/USB'?\n", UDEV); - return 1; - }; - - hid_dispose_report_desc(rd); - - return 0; -} int main(int ac, char *av[]) { - int i, u, buf[16]; - u_char sbuf[8]; + int i, u, buf[16]; + unsigned char sbuf[8]; + hid_return ret; - if (ac < 3) { - printf("'Oke-Con' controller, version " S_VERS ".\n"); - printf("Copyright (C) 1997-2002 by Tosy / W341IG.\n"); - printf("Usage: rcctl <maker> <code>\n"); - return 255; - } + if (ac < 3) { + printf("'Oke-Con' controller, version " S_VERS ".\n"); + printf("Copyright (C) 1997-2002 by Tosy / W341IG.\n"); + printf("Usage: rcctl <maker> <code>\n"); + return 255; + } - if ((u = cdcnv(buf, av[1], av[2])) < 0) { - fprintf(stderr, "%s: %s\n", av[0], cverrstr[~u]); - return 1; - } + if ((u = cdcnv(buf, av[1], av[2])) < 0) { + fprintf(stderr, "%s: %s\n", av[0], cverrstr[~u]); + return 1; + } + printf("cdcnv %d\n", u); #ifdef VERBOSE - printf("Initializing...."); + printf("Initializing....\n"); #endif - if (init_usb()) - /* if (init_sio()) */ - return 255; + + if (init_usb()) + return 255; + #ifdef VERBOSE - printf(" done.\n"); + printf(" done.\n"); #endif #ifdef VERBOSE -/* printf("maker %d (%c).\n", maker, mks[maker]); */ - for(i=0; i<u; i++ ) { - printf("%02x ", buf[i]); - } - printf("\n"); + for(i=0; i<u; i++ ) { + printf("%02x ", buf[i]); + } + printf("\n"); #endif - for(i=1; i<u; i++ ) { - sbuf[(i-1)%8] = buf[i] & 0x00ff; -#ifdef VERBOSE - printf("%02x ", sbuf[(i-1)%8]); -#endif - if ((i == 8)||(i == (u-1))) { - write(fd, sbuf, 8); + /* xxx */ + const int PATH_IN[1] = { 0xffa10004 }; +// const int PATH_OUT[1] = { 0xffa10008 }; + + /* u is the total length of the packet to send */ + for(i=1; i<u; i++ ) { + sbuf[(i-1)%8] = buf[i] & 0x00ff; #ifdef VERBOSE - printf(" --- got %d chars.\n", read(fd, sbuf, 8)); -#else - read(fd, sbuf, 8); + printf("%02x ", sbuf[(i-1)%8]); #endif + if ((i == 8)||(i == (u-1))) { + ret = hid_set_output_report(hidif, PATH_IN, 2, (char *)sbuf, 8); + fprintf(stderr, "**WRITE**\n"); + if (ret != HID_RET_SUCCESS) { + fprintf(stderr, "hid_set_output_report failed with return code %d\n", ret); + } + +#if 0 + char packet[8]; + ret = hid_get_input_report(hidif, PATH_OUT, 2, packet, 8); + if (ret != HID_RET_SUCCESS) { + fprintf(stderr, "hid_get_input_report failed with return code %d\n", ret); + } +#endif + } } - } +#ifdef VERBOSE + printf("\n"); +#endif - /* charge(); */ - close(fd); - return 0; + if(fin_usb()) + return 255; + + return 0; }
