ENGLISH page is here.
GET DinopSearchBar
サイト内検索:
HOME
VC++ TIPS
ダウンロード
DinopExifReader
DinopSearchBar
DinopSearchBar mini
DinopTabbingBar
for Firefox
大阪湾の生き物
甲子園浜の自然
甲子園浜の干潟
甲子園浜の水中
甲子園浜の野鳥
近畿の山々
植物図鑑
箕面マップ
水中機材
カメラ
ランキング
望遠鏡の世界
顕微鏡の世界
Googleのすべて
GoogleマップAPI
ニュース
読んだ本
日記
変な料理の作り方
遺伝子操作
論文紹介
デイトレード
自動売買でFX
ネットで小遣い稼ぎ
Solaris
電子工作
その他
問い合わせ
VC++用コード集
大阪湾の生き物
水中用機材
since:2000/11/15
dinopcom@gmail.com
www.dinop.comは
だいのっぷ・どっと・こむ
と読んでください。







« PSoCで割り込みによりロータリーエンコーダーを2つ使う | メイン | PSoCをUSB(HID)デバイスとして接続しデータを受信する »

PSoCでUSBマウスを作る




usb_mouse_01.gif
今回はUSB機能を内蔵したPSoC「CY8C24794-24LFXI」を利用してUSBマウスを作る。
PSoC Designerの「USBFS」モジュールはHIDデバイスをサポートしているため簡単にUSBマウスやUSBキーボードを作れる。

usb_mouse_02.gif
プロジェクトの作成時に「CY8C24794-24LFXI」を選択するのを忘れないように注意する。今回もC言語で開発を行った。

usb_mouse_03.gif
PSoC Designerが起動したら「Protocol」にある「USBFS」をダブルクリックする。

usb_mouse_04.gif
するとUSBのデバイスクラスを問われる。ここで「Human Interface Device(HID)」を選択する。

usb_mouse_05.gif
これで「USBFS_1」がプロジェクトに追加された。確認したら「Config」メニューの「Interconnect」を選択して画面を切り替える。

usb_mouse_06.gif
そして「USBFS_1」のアイコンを右クリックして現れるメニューから「Place」を選択して配置する。

usb_mouse_07.gif
配置したらもう一度「USBFS_1」を右クリックする。すると「USB Setup Wizard」メニューが有効になるのでこれを選択する。

usb_mouse_08.gif
「USB Setup Wizard」が開いた。
ここでは作成したい機器のUSB部分関する各種情報(USB Descriptor)を設定できる。

usb_mouse_09.gif
まず「HID Report Descriptor Root」の「Import HID Report Template」をクリックする。

usb_mouse_10.gif
するとテンプレートの選択欄が現れる。ここで「3 Button Mouse」を選択し「Apply」をクリックする。

usb_mouse_11.gif
これでUSBマウス用のでスクリプターが自動的に作成される。作成したいUSB機器用のテンプレートが用意されていない場合は機器に応じてこれらの項目を1つずつ手動で作成する。

usb_mouse_12.gif
次にインターフェース属性の設定をする。「USB User Module Descriptor Root」-「Device Descriptor」-「Configuration Descriptor」-Interface Descriptor」の下にある「Interface Attribute」の「Class」欄を「HID」に、「HID Class Descriptor」の「HID Report」欄を「3 Button Mouse」にする。
本来はベンダーID(デフォルトは0xFFFF)やプロダクトID(デフォルトは0xFFFF)を設定しなければいけないが、今回は省略しこれで「OK」ボタンを押してUSBセットアップウイザードを閉じる。

usb_mouse_13.gif
これで「USBFS」に関する設定は終わりだ。「View」メニューの「Application Editor」を選択してソースコードを書くための画面に切り替える。

usb_mouse_14.gif
まずはUSB機器として動作することを確認するためサンプルコードを動かそう。ツールバーの「Protocols」にある「USBFS」を選択して「User Module Datasheet」ボタンを押す。

usb_mouse_15.gif
そしてサンプルコードをすべて選択してコピーする。

usb_mouse_16.gif
コピーしたコードを「main.c」に貼り付ける。
このとき「USBFS_」の部分を「USBFS_1_」に修正する...ただしサンプルコードは記述ミスがあるためそれだけではビルドできない。「USBFS_5V_OPERATION」を「USB_5V_OPERATION」に、「USBFS_NO_TOGGLE」を「USB_NO_TOGGLE」にそれぞれ修正する。


//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules


BYTE abMouseData[3] = {0,0,0};
BYTE i = 0;
void main()
{
M8C_EnableGInt; //Enable Global Interrupts
USBFS_1_Start(0, USB_5V_OPERATION); //Start USBFS Operation using device 0
//and with 5V operation
while(!USBFS_1_bGetConfiguration()); //Wait for Device to enumerate
//Enumeration is completed load endpoint 1. Do not toggle the first time
USBFS_1_LoadInEP(1, abMouseData, 3, USB_NO_TOGGLE);

while(1)
{
while(!USBFS_1_bGetEPAckState(1)); //Wait for ACK before loading data
//ACK has occurred, load the endpoint and toggle the data bit
USBFS_1_LoadInEP(1, abMouseData, 3, USB_TOGGLE);

if(i==128) //When our count hits 128
abMouseData[1] = 0x05; //Start moving the mouse to the right
else if(i==255) //When our counts hits 255
abMouseData[1] = 0xFB; //Start moving the mouse to the left
i++;
}
}





_DSC9080.JPG
これでビルドしてPSoCへ書き込みUSBケーブルを接続する。

usb_mouse_17.gif
すると「USB ヒューマン インターフェース デバイス」として認識され自動的にドライバーがインストールされる。

usb_mouse_18.gif
これでUSB機器が認識・動作すると、サンプルコード通りマウスカーソルが自動的に左右に動きだす。



「USBUART」の場合はデバイスドライバーはWindows標準で備わっているもののインストールは手動で行わなければならない。しかしこの「USBFS」はHIDとして作成すれば手動インストールの必要もなく非常に使い勝手がいい。




usb_mouse_19.gif
次に実際に「USBマウス」として操作できるようにプロジェクトを修正する。今回はマウスカーソルの移動には2つのロータリーエンコーダー、左右のボタンにはスイッチを使うことにした。それら用のポート設定をするため「View」メニューの「Device Editor」からデバイスエディターを開く。

usb_mouse_20.gif
ここで...
「Port_1_2」の「Drive」を「Pull Up」に「Interrupt」を「FallingEdge」に、(1つ目のロータリーエンコーダー用、A端子)
「Port_1_3」の「Drive」を「Pull Up」に、(1つ目のロータリーエンコーダー用、B端子)
「Port_1_4」の「Drive」を「Pull Down」に「Interrupt」を「RisingEdge」に、(スイッチ用)
「Port_1_5」の「Drive」を「Pull Down」に「Interrupt」を「RisingEdge」に、(スイッチ用)
「Port_1_6」の「Drive」を「Pull Up」に「Interrupt」を「FallingEdge」に、(2つ目のロータリーエンコーダー用、A端子)
「Port_1_7」の「Drive」を「Pull Up」(2つ目のロータリーエンコーダー用、B端子)にする。
設定が済んだら「View」メニューの「Application Editor」で再びソースコード編集画面に戻る。

usb_mouse_21.gif
アプリケーションエディターに切り替わったら一度ビルドする。

usb_mouse_22.gif
するとポートの割り込み設定用ファイル「psocgpioint.asm」が自動作成されるので開き、「ljmp _GPIO_INT」の1行を追加する。

usb_mouse_23.gif
そして「main.c」の中に処理を書く。
ロータリーエンコーダーとスイッチは割り込み処理で扱う。基本的に前回の「PSoCで割り込みによりロータリーエンコーダーを2つ使う」と同じだ。ロータリーエンコーダーの回転を検出したら前回は液晶モジュールに数値を表示したが、今回は「abMouseData[1]」や「abMouseData[2]」を増減している。この「abMouseData」はPCに送られるデータで書式はHIDにより規定されている。1バイト目はマウスのボタン関係(1ビット目が右ボタン、2ビット目が左ボタン、3ビット目がミドルボタン)、2バイト目は左右への移動、3バイト目は上下への移動データが格納される。

_DSC9081.JPG
これでロータリーエンコーダーのA端子とB端子をそれぞれポート12と13およびポート16と17に、スイッチをポート14と15に接続するとUSBマウスと同じように操作ができた。
(手持ちにプッシュスイッチがなかったので今回はジャンパーをブレッドボードに抜き差ししてテストした)


//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules


BYTE abMouseData[3] = {0,0,0};

#define SW_1_PORT PRT1DR
#define SW_1_A 0x04
#define SW_1_B 0x08

#define SW_2_PORT PRT1DR
#define SW_2_A 0x40
#define SW_2_B 0x80

#pragma interrupt_handler GPIO_INT
void GPIO_INT(void)
{
if((SW_1_PORT & SW_1_A) == 0)
{
if(SW_1_PORT & SW_1_B)
abMouseData[1] -= 10; //move to left
else
abMouseData[1] += 10; //move to right
}

if((SW_2_PORT & SW_2_A) == 0)
{
if(SW_2_PORT & SW_2_B)
abMouseData[2] -= 10; //move to up
else
abMouseData[2] += 10; //move to down
}

if(PRT1DR & 0x10)
abMouseData[0] |= 0x01; //left button down
else
abMouseData[0] &= ~0x01; //left button up

if(PRT1DR & 0x20)
abMouseData[0] |= 0x02; //right button down
else
abMouseData[0] &= ~0x02; //right button up
}

void main()
{
M8C_EnableGInt; //Enable Global Interrupts
USBFS_1_Start(0, USB_5V_OPERATION); //Start USBFS Operation using device 0
//and with 5V operation
while(!USBFS_1_bGetConfiguration()); //Wait for Device to enumerate
//Enumeration is completed load endpoint 1. Do not toggle the first time
USBFS_1_LoadInEP(1, abMouseData, 3, USB_NO_TOGGLE);

SW_1_PORT |= SW_1_A | SW_1_B; //Enable Pull-UP
SW_2_PORT |= SW_2_A | SW_2_B; //Enable Pull-UP
M8C_EnableIntMask(INT_MSK0, INT_MSK0_GPIO);

while(1)
{
while(!USBFS_1_bGetEPAckState(1)); //Wait for ACK before loading data
//ACK has occurred, load the endpoint and toggle the data bit
USBFS_1_LoadInEP(1, abMouseData, 3, USB_TOGGLE);
abMouseData[1] = 0x00; //clear mouse move data
abMouseData[2] = 0x00; //clear mouse move data
}
}





コメント (2)

貴重な情報を図を入れてありがとうございます。
この状態で、休止/スリープからのOS復帰の際でも、
マウスとして機能するのでしょうか?

issei:

挙動自体は市販のUSBマウスとほぼ同じなので、市販のUSBマウスがOS復帰の際にマウスとして機能するPCであれば機能すると思います。

コメントを投稿

名前:
メールアドレス:
URL:






Copyright (c) 1999-2007 issei. All rights reserved. (運営者情報