パスワードを忘れた? アカウント作成
386425 journal

g26a345の日記: USB-IO その3

日記 by g26a345
おもちゃとしてモルフィーのUSBIOで遊んでいるけど、Linux標準のHIDの使い方がよく判らないままだった。
色々調べるとlibusbなるものがあり、それを使うと結構簡単に行けそうな感じ。
で、やってみた。

ハード的には、USB-IOの12本の信号(PortA 8本、PortB 4本)にそれぞれLEDがついてたり、また、その信号をH/Lに固定できたりするハードがあるとして。

大体以下のような感じで行けるようだ。

まずは出力。12個のLEDをON/OFFが出来た。
--- ここから ---
#include <usb.h>
#include <stdio.h>
#include <string.h>

#define USB_VENDOR 0x12ed
#define USB_PRODUCT 0x1003

/* USB初期化 */
struct usb_bus *morphy_init()
{
        usb_init();
        usb_find_busses();
        usb_find_devices();
        return( usb_get_busses() );
}

/* Morphy-USBIOを見つける */
struct usb_device *morphy_find(struct usb_bus *busses, struct usb_device *dev)
{
        struct usb_bus *bus;
        for(bus=busses; bus; bus=bus->next){
                for(dev=bus->devices; dev; dev=dev->next) {
                        if( (dev->descriptor.idVendor==USB_VENDOR) && (dev->descriptor.idProduct==USB_PRODUCT) ){
                                return( dev );
                        }
                }
        }
        return( NULL );
}

/* USBIOオープン */
struct usb_dev_handle *morphy_open(struct usb_device *dev)
{
        struct usb_dev_handle *udev = NULL;

        udev=usb_open(dev);
        if( (udev=usb_open(dev))==NULL ){
                printf("!!Can not Open USB-Device\n");
                exit(0);
        }

        if( usb_set_configuration(udev,dev->config->bConfigurationValue)<0 ){
                printf("!!usb_set_configuration Error.\n");
        }

        if( usb_claim_interface(udev,dev->config->interface->altsetting->bInterfaceNumber)<0 ){
                printf("!!usb_claim_interface Error.\n");
        }

        return(udev);
}

/* USBIOクローズ */
void morphy_close(struct usb_dev_handle *udev)
{
        if( usb_close(udev)<0 ){
                printf("Can not Close USB-Device.\n");
        }
}

/* ------------ */
/* MAIN */
/* ------------ */

int main(void)
{
        int ret;
        int c,i,a;
        struct usb_bus *bus;
        struct usb_device *dev;
        usb_dev_handle *udev;
        unsigned char ctl[8];

        bus = morphy_init();
        dev = morphy_find(bus,dev);

        if( dev!=NULL ){
                udev=morphy_open(dev);

                ctl[2]=ctl[3]=ctl[4]=ctl[5]=ctl[6]=ctl[7]=0;

                /* Port0 -> Write 00(LED On) */
                ctl[0]=0x01; ctl[1]=0x00;
                ret=usb_control_msg(udev,0x21,0x09,0x00,0x00,ctl,8,5000);
                if( ret<0 ){
                        printf("!!usb_control_msg Error(01-00)\n");
                }

                sleep(1);

                /* Port0 -> Write FF(LED Off) */
                ctl[0]=0x01; ctl[1]=0xff;
                ret=usb_control_msg(udev,0x21,0x09,0x00,0x00,ctl,8,5000);
                if( ret<0 ){
                        printf("!!usb_control_msg Error(01-FF)\n");
                }

                sleep(1);

                /* Port1 -> Write 00(LED On) */
                ctl[0]=0x02; ctl[1]=0x00;
                ret=usb_control_msg(udev,0x21,0x09,0x00,0x00,ctl,8,5000);
                if( ret<0 ){
                        printf("!!usb_control_msg Error(02-00)\n");
                }

                sleep(1);

                /* Port1 -> Write FF(LED Off) */
                ctl[0]=0x02; ctl[1]=0xff;
                ret=usb_control_msg(udev,0x21,0x09,0x00,0x00,ctl,8,5000);
                if( ret<0 ){
                        printf("!!usb_control_msg Error(02-FF)\n");
                }
        }else{
                printf("USBIO not found.\n");
        }

        morphy_close(udev);
        return(0);
}
--- ここまで ---

つまるところ、ベンダーIDとかプロダクトIDから、USBIOであるデバイスを選んでオープン(morphy_open)して、あとはデバイスに対して、usb_control_msgでデータを送ってやればいいみたい。
リクエストタイプ等は、共通で、0x21,0x09あたりがそう。
実際のデータはctlという文字変数に入れてるけど、ctl[0]が0ならPortA、1ならPortBになる。ctl[1]が書き込む値で、回路の都合で、1を書けばLEDが消えて、0を書けばLEDが点く。
今回は、PortA全部点灯/消灯、PortB全部点灯/消灯てな感じで動かしている。

次に入力。
プログラムは出力と共通な部分が多いけど。
--- ここから ---
#include <usb.h>
#include <stdio.h>
#include <string.h>

#define USB_VENDOR 0x12ed
#define USB_PRODUCT 0x1003

/* USB初期化 */
struct usb_bus *morphy_init()
{
        usb_init();
        usb_find_busses();
        usb_find_devices();
        return( usb_get_busses() );
}

/* Morphy-USBIOを見つける */
struct usb_device *morphy_find(struct usb_bus *busses, struct usb_device *dev)
{
        struct usb_bus *bus;
        for(bus=busses; bus; bus=bus->next){
                for(dev=bus->devices; dev; dev=dev->next) {
                        if( (dev->descriptor.idVendor==USB_VENDOR) && (dev->descriptor.idProduct==USB_PRODUCT) ){
                                return( dev );
                        }
                }
        }
        return( NULL );
}

/* USBIOオープン */
struct usb_dev_handle *morphy_open(struct usb_device *dev)
{
        struct usb_dev_handle *udev = NULL;

        udev=usb_open(dev);
        if( (udev=usb_open(dev))==NULL ){
                printf("Can not Open USB-Device\n");
                exit(0);
        }

        if( usb_set_configuration(udev,dev->config->bConfigurationValue)<0 ){
                printf("%s\n",usb_strerror());
        }

        if( usb_claim_interface(udev,dev->config->interface->altsetting->bInterfaceNumber)<0 ){
                printf("%s\n",usb_strerror());
        }

        return(udev);
}

/* USBIOクローズ */
void morphy_close(struct usb_dev_handle *udev)
{
        if( usb_close(udev)<0 ){
                printf("Can not Close USB-Device. %s\n",usb_strerror());
        }
}

/* ------------ */
/* MAIN */
/* ------------ */

int main(void)
{
        int ret;
        int c,i,a;
        struct usb_bus *bus;
        struct usb_device *dev;
        usb_dev_handle *udev;
        unsigned char ctl[8];

        bus = morphy_init();
        dev = morphy_find(bus,dev);

        if( dev!=NULL ){
                udev=morphy_open(dev);

                ctl[0]=ctl[1]=ctl[2]=ctl[3]=ctl[4]=ctl[5]=ctl[6]=ctl[7]=0;

                /* CMD:Read Port0 */
                ctl[0]=0x03;
                ret=usb_control_msg(udev,0x21,0x09,0x00,0x00,ctl,8,5000);
                if( ret<0 ){
                        printf("P0 Read-CmdError\n");
                }

                /* Port0 */
                ret=usb_interrupt_read(udev,1,ctl,8,5000);
                if( ret<0 ){
                        printf("P0 Int-Read Error\n");
                }
                for(i=0; i<8; i++){
                        printf(">ctl[%d]=%d\n",i,ctl[i]);
                }

                /* CMD:Read Port1 */
                ctl[0]=0x04;
                ret=usb_control_msg(udev,0x21,0x09,0x00,0x00,ctl,8,5000);
                if( ret<0 ){
                        printf("P1 Read-CmdError\n");
                }

                /* Port1 */
                ret=usb_interrupt_read(udev,1,ctl,8,5000);
                if( ret<0 ){
                        printf("P1 Int-Read Error\n");
                }
                for(i=0; i<8; i++){
                        printf(">ctl[%d]=%d\n",i,ctl[i]);
                }

        }

        morphy_close(udev);
        return(0);
}
--- ここまで ---

MAINを除けば出力側と同じ記述になってるけど。

やり方は、PortA/PortBそれぞれのリードコマンドを発行(usb_control_msgで)し、インタラプト転送でリード(usb_interrupt_read)するだけであった。
PortAとPortBを同時にはリードできない?のかな?
ちなみにリード結果はctl[1]に格納されてる。

もうちょっと遊んでみよう。
typodupeerror

人生unstable -- あるハッカー

読み込み中...