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