Mercurial > rcctl_linux
view rcctl.c @ 0:e1a1a181c0d7
initial import
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Thu, 16 Dec 2010 20:30:11 +0900 |
parents | |
children | 05cc06e88a57 |
line wrap: on
line source
/* rcctl.c --------------------------------------------- $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 の履歴も参照のこと】 ------------------------------------------------------*/ #include <fcntl.h> #include <stdio.h> #include <termios.h> #include <unistd.h> #include <libusb.h> #include <sys/ioctl.h> #include <dev/usb/usb.h> #include <dev/usb/usbhid.h> /* #define VERBOSE */ /* #define NOCTSCHK */ #ifndef SDEV #define SDEV "/dev/cuaa0" #endif #ifndef UDEV #define UDEV "/dev/uhid0" #endif #ifndef S_VERS #define S_VERS "0.40" #endif int fd; int cdcnv(int buf[], char *mak, char *cod); extern char *cverrstr[]; int init_sio(void) { #ifndef NOCTSCHK int tcnt = 0; #endif struct termios tios; int md; if ((fd = open(SDEV, O_RDWR)) == -1) { fprintf(stderr, "Cannot open %s.\n", SDEV); return 255; } 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); md = TIOCM_LE|TIOCM_DTR|TIOCM_RTS; ioctl(fd, TIOCMBIS, &md); /* wait for CTS: 充電待ち */ #ifndef NOCTSCHK for(;;) { ioctl(fd, TIOCMGET, &md); if (md & TIOCM_CTS) break; if (tcnt == 0) { fprintf(stderr, "Waiting...."); } if (tcnt++ >= 30) { fprintf(stderr, "Device timeout.\n"); close(fd); return 1; } sleep(1); } #endif /* NOCTSCHK */ md = TIOCM_RTS; ioctl(fd, TIOCMBIC, &md); usleep(10000); /* 10ms */ ioctl(fd, TIOCMBIS, &md); usleep(50000); /* 50ms */ 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]; 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; } #ifdef VERBOSE printf("Initializing...."); #endif if (init_usb()) /* if (init_sio()) */ return 255; #ifdef VERBOSE 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"); #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); #ifdef VERBOSE printf(" --- got %d chars.\n", read(fd, sbuf, 8)); #else read(fd, sbuf, 8); #endif } } /* charge(); */ close(fd); return 0; }