EZ-USBプロジェクト
概要
ハードウェア
ソフトウェア(EZ-USB側)
ソフトウェア(PC側 Delphi6)
ソフトウェアダウンロード
参考文献
変更履歴
2003年5月11日修正
USB基板( AN2131N実装) MINI EZ-USB ( オプティマイズから購入)
制御ソフトウェア (PC側) Delphi6使用
EZ-USB----- 概要
すべての情報は、 カメレオンUSB の情報源を中心に収集しました。
現時点では、7セグメントLEDに対するPC側からのデータ表示と4つのスイッチのON/OFF情報をPCに表示するだけの簡単な入出力を実現しています。
制御仕様
データ表示:8桁までの数字を入力し、[SEND DATA]ボタンを押した時点でPC側からEZ-USB側にデータが送られ、7セグメントLEDに表示されます。
スイッチ状態:100ms毎にPC側からスイッチ状態要求のコマンドを送出し、それに応答してZ-USB側からスイッチ状態が送られPC画面に表示されます。
EZ-USB側のプログラムは、 KeilのCコンパイラで作成し、PC側の制御ソフトウェアは Delphi6で開発しました。
EZ-USB側は、オプティマイズのMINI EZ-USBの<FWのスケルトン>を使わせてもらいました。
PC側のプログラムは、オプティマイズのカメレオンUSBで紹介されている カメレオンUSBライブラリ(Cプログラム)をDelphi用に書き換えたもので、Delphiでのプログラム開発を初めて3ヶ月程度(2003年5月時点)しか経っていない為に、単に動くという程度しか検証が済んでいません。汎用基板に組み込んだ回路は、 ここを見てください。 MINI EZ-USB側の回路図は、オプティマイズさんから ここで公開されています。
7セグメントLEDは、AN2131SCのポートC(PC0〜PC7)からインバータ経由で駆動しています。AN2131は3.3Vで動作していますので、+5VでLED駆動するためにCMOSタイプではなく、LSタイプのSN74LS04を使用しています。
AN2131 Voh(Min)=2.4V (@Vcc=3.0V) 74LS04 Vih(Min)=2.0V
スイッチ入力は、ポートB(PB0〜PB3)を使用し、+5Vでプルアップしています。AN2131は、5V系の入力電圧の印加が保証されていますので問題ありません。
AN2131 Vih=2.0V(Min) to 5.25V(Max)
EZ-USB ----- ソフトウェア(EZ-USB 8051)
8051側のソフトウェアは、KeilのCコンパイラを使用しています。使い方は、オプティマイズさんのこのページに詳しい解説があります。私も下記のような設定で使用しています。
今回手を加えた部分は、 periph.cの一部だけです。
periph.c
#pragma NOIV // Do not generate interrupt vectors
//----------------------------------------------------------------------------
// File: periph.c
// Contents: Hooks requiredto implement USB peripheral function.
//
// Copyright (c) 1997 AnchorChips, Inc. All rights reserved
// Source code from Optimize
// http://optimize.ath.cx/mini_ezusb/index.html
//
// Modified by Kenji Arai
// http://www.page.sannet.ne.jp/kenjia/
// February 23, 2003 Start modification
// April 28, 2003 Auto increment function
// April 30, 2003 Display DDS data format
//
//-----------------------------------------------------------------------------
#include <ezusb.h>
#include <ezregs.h>typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned long u32;
typedef signed long s32;extern BOOL GotSUD; // Received setup data flag
extern BOOL Sleep;
extern BOOL Rwuen;
extern BOOL Selfpwr;BYTE Configuration; // Current configuration
BYTE AlternateSetting; // Alternate settings
BYTE suspCount;
// ************** Modified by K.Arai ******************************************
#define DdsDtLen 8
#define DOT 0x02 // Dot display data on LED
#define SegBlnk 0 // Blank display data on LED
#define DDS_SET 0x55 // Command from Host #1-> Set frequency data to DDS
#define SW_READ 0xaa // Command from Host #2-> Send Switch data to Host// ************** Modified by K.Arai ******************************************
//-----------------------------------------------------------------------------
// Grobal Vriables
//-----------------------------------------------------------------------------
u8 dds_freq_dt[DdsDtLen]; // DDS frequency data -> buffer for received data
u8 current_freq_dt[DdsDtLen]; // DDS frequency data -> current display data
u8 flg_newdt; // Flag for new data
// ************** Modified by K.Arai ******************************************
//-----------------------------------------------------------------------------
// Constants //7セグメントLEDに表示するデータを定義しています。
// 16進表示と10進表示用データです。
//-----------------------------------------------------------------------------
const BYTE led_seg[16] =
{0xf5, 0x81, 0xf8, 0xd9, 0x8d, 0x5d, 0x3d, 0xc5, 0xfd, 0xcd, 0xed, 0x3d, 0x74, 0xb9, 0x7c, 0x6c};
// 0 1 2 3 4 5 6 7 8 9 a b c d e fconst BYTE led_segdec[16] =
{0xf5, 0x81, 0xf8, 0xd9, 0x8d, 0x5d, 0x3d, 0xc5, 0xfd, 0xcd, DOT, DOT, DOT, DOT, DOT, DOT};
// 0 1 2 3 4 5 6 7 8 9 a b d e f
const BYTE led_seg0[7] = {0x0a, 0x10, 0x20, 0x04, 0x40, 0x80, 0x01};
// 0 1 2 3 4 5 6
//-----------------------------------------------------------------------------
// Task Dispatcher hooks
// The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------void TD_Init(void) // Called once at startup
// ************** Modified by K.Arai ******************************************
// Enable endpoints 0-7 IN and OUT
// IN07VAL |= bmEP1+ bmEP2 + bmEP3 + bmEP4 + bmEP5 + bmEP6 + bmEP7;
// OUT07VAL |= bmEP1 + bmEP2 + bmEP3 + bmEP4 + bmEP5 + bmEP6 + bmEP7;
IN07VAL |= bmEP1;
OUT07VAL |= bmEP1// ************** Modified by K.Arai ******************************************
// Enable interrupts for the OUT endpoints
// OUT07IEN |= bmEP1 + bmEP2 + bmEP3 + bmEP4 + bmEP5 + bmEP6 + bmEP7;
// IN07IEN |= bmEP1+ bmEP2 + bmEP3 + bmEP4 + bmEP5 + bmEP6 + bmEP7;
OUT07IEN |= bmEP1;
IN07IEN |= 0;// ************** Modified by K.Arai ******************************************
// Initialize I/O port
OEC = 0xff; // Port C set to output port //ポートCをLED駆動用に出力設定suspCount = 1;
OEA = 0xff;
Rwuen = TRUE; // Enable remote-wakeup
// ************** Modified by K.Arai ******************************************
void TD_Poll(void) // Called repeatedly while the device is idle
{
static int state;
static int tmr;
u8i;
if(flg_newdt == 1){ //新しいデータが入って来たときにフラグが1になります。
flg_newdt = 0;
for (i = 0; i < DdsDtLen; i++){ //受け取ったデータを表示用にセーブして置きます。
current_freq_dt[i] = dds_freq_dt[i];// Copy data
}
state = 0;
OUTC = SegBlnk; // LED is blanking
tmr = 0;
}
else{
tmr--;
if (tmr == 0){ //タイマーをカウントダウンしてゼロになった時点で次のデータを表示します。
if (state == 8){
state = 0;
OUTC = SegBlnk; // LED is blanking
}
else{
i = current_freq_dt[state];
// OUTC = led_seg[i]; // Show Hex data
OUTC = led_segdec[i]; // Show Decimal data
state++;
}
}
}
OUT1BC = 0;
}BOOL TD_Suspend(void) // Called before the device goes into suspend mode
{
return(TRUE);
}BOOL TD_Resume(void) // Called after the device resumes
{
return(TRUE);
}EZ-USB ----- ソフトウェア (Delphi program)
ezusb.pas
unit ezusb;
{*******************************************************************************
Test program for EZ-USB
Programmed by Kenji Arai/JH1PJL
E-mail: kenjia@sannet.ne.jp jh1pjl@arrl.net
URL: http://www.page.sannet.ne.jp/kenjia/
April 27, 2003 Started programing
May 2, 2003 modified
mm dd,yyyy fixed a release version
Copyright (C) 2003 Kenji Arai/JH1PJL
All rights reserved. Permission is granted to use, modify,
or redistribute this software so long as it is not sold
or exploited for profit.
THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED
*******************************************************************************}
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, EZUSBDRV, ComCtrls, ExtCtrls;
type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
CheckBox3: TCheckBox;
CheckBox4: TCheckBox;
Button1: TButton;
Button2: TButton;
UpDown1: TUpDown;
Edit1: TEdit;
Button3: TButton;
Timer1: TTimer;
procedure FormActivate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure UpDown1Click(Sender: TObject; Button: TUDBtnType);
procedure Timer1Timer(Sender: TObject);
private
public
end;
var
Form1: TForm1;
{$INCLUDE fw.pas}
const
CMD_DDS_SET = $55;
CMD_SW_READ = $aa;
LOOP_CNT = 2000;
CRLF = #13 + #10; // Crarrige Return & Line Feed
implementation
{$R *.dfm}
const
DataLn = 8;
var
number: integer;
buf_usb: array[0..DataLn] of Byte;
Flg_send: boolean;
function Switch_Read(): boolean;
var
buf: Byte;
begin
buf := CMD_SW_READ;
if usb_bulk_write(0, @buf, 1) <> 0 then
begin
ShowMessage('Cannot write data stream');
Result := False;
Exit;
end;
if usb_bulk_read(7, @buf, 1) = -1 then
begin
ShowMessage('Cannot read data stream');
Result := False;
Exit;
end
else
begin
Form1.CheckBox1.Checked := Boolean(buf and $01);
Form1.CheckBox2.Checked := Boolean(buf and $02);
Form1.CheckBox3.Checked := Boolean(buf and $04);
Form1.CheckBox4.Checked := Boolean(buf and $08);
end;
Result := True;
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
Form1.Caption := 'EZ-USB Interface -->Now Loading!';
number := 0;
flg_send := False;
if cusb_init(0, @fw_prog) <> 0 then
begin
ShowMessage('Cannot open USB I/F'+CRLF+'Please check your I/F');
Button1.Caption := 'Close';
Edit1.MaxLength := 12;
Edit1.Color := clRed;
Edit1.Text := 'Cannot use!';
Exit;
end
else
Edit1.Text := '0';
Timer1.Interval := 100; // Set 100ms interval
Form1.Caption := 'EZ-USB Interface';
end;
Procedure TForm1.Button1Click(Sender: TObject);
begin
usb_close();
Close();
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage (
' (c)2003 Kenji Arai / JH1PJL '+CRLF+
' May 1st, 2003 '+CRLF+
' '+CRLF+
'http://www.page.sannet.ne.jp/kenjia/'+CRLF+
'http://www.cypress.com/ '+CRLF+
'EZ-USB (AN2131) '
);
end;
procedure TForm1.Button3Click(Sender: TObject);
var
s,p: PChar;
i,j: integer;
begin
buf_usb[0] := CMD_DDS_SET;
s := PChar(Edit1.Text);
i := (DataLn-length(s))+1;
p := StrEnd(s);
for j := DataLn downto 1 do
buf_usb[j] := $0f;
for j := DataLn downto i do
begin
p := p-1;
buf_usb[j] := Byte(StrToInt(p[0]));
end;
flg_send := True;
end;
procedure TForm1.UpDown1Click(Sender: TObject; Button: TUDBtnType);
begin
try
number := StrToInt(Edit1.Text);
except
ShowMessage('Please enter Decimal number');
end;
if Button = btNext then
begin
number := number + 1;
Edit1.Text := IntToStr(number);
if length(Edit1.Text) > 8 then
begin
number := number - 1;
Edit1.Text := IntToStr(number);
end;
end
else
begin
number := number - 1;
Edit1.Text := IntToStr(number);
if length(Edit1.Text) > 8 then
begin
number := number + 1;
Edit1.Text := IntToStr(number);
end;
end;
Edit1.Text := IntToStr(number);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if Switch_Read() = False then
Close();
if flg_send = True then
begin
flg_send := False;
if usb_bulk_write(0, @buf_usb, sizeof(buf_usb)) <> 0 then
begin
ShowMessage('Cannot write data stream');
Close()
end;
end;
end;
end.
EZUSBDRV.pas
unit EZUSBDRV;
{*******************************************************************************
Interface program between application program & ezusb.sys driver
Programmed by Kenji Arai/JH1PJL
E-mail: kenjia@sannet.ne.jp jh1pjl@arrl.net
URL: http://www.page.sannet.ne.jp/kenjia/
April 13, 2003 Started programing
April 27, 2003 modified
mm dd,yyyy fixed a release version
Reference
---- Chameleon USB ---------------------------------------
http://optimize.ath.cx/
cusb.c ->//2002.1.30 Ver1.1 by optimize
cusb.h ->//2002.1.14 Ver1.0 by optimize
---- EZ-USB Device driver --------------------------------
http://www.cypress.com/
ezusbsys.c ->Version 6 Date:9/17/01 Time:10:54a
ezusbsys.h ->Version 5 Date:10/06/00 Time:10:08a
---- Visual Basic sample program for bulktest ------------
http://www.asahi-net.or.jp/~qx5k-iskw/index.html
ezusb.bas -> Date:9/16/01 Time:16:58:42
Copyright (C) 2003 Kenji Arai/JH1PJL
All rights reserved. Permission is granted to use, modify,
or redistribute this software so long as it is not sold
or exploited for profit.
THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED
*******************************************************************************}
interface
{ ---- Following functions are used of Windows units -------------
function CreateFile(lpFileName: PChar; dwDesiredAccess, dwShareMode: DWORD;
lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition,
dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall;
function CloseHandle(hObject: THandle): BOOL; stdcall;
function DeviceIoControl(hDevice: THandle; dwIoControlCode: DWORD;
lpInBuffer: Pointer; nInBufferSize: DWORD; lpOutBuffer: Pointer;
nOutBufferSize: DWORD; var lpBytesReturned: DWORD;
lpOverlapped: POverlapped): BOOL; stdcall;
}
uses windows, Dialogs, SysUtils;
type
PByte = ^Byte;
type
VENDOR_REQUEST_IN = record
bRequest: Byte;
wValue: Word;
wIndex: Word;
wLength: Word;
direction: Byte;
bData: Byte;
end;
type
GET_STRING_DESCRIPTOR_IN = record
Index: Byte;
LanguageId: Word;
end;
type
BULK_TRANSFER_CONTROL = record
pipeNum: DWORD;
end;
// Exported Functions
{ --------------- by optimize -----------------
s32 usb_open(s32 n,HANDLE *h);
s32 usb_close(HANDLE *h);
s32 usb_halt(HANDLE *h);
s32 usb_run(HANDLE *h);
s32 usb_dwnload(HANDLE *h,u8 *image,s32 len);
s32 usb_resetpipe(HANDLE *h,ULONG p);
s32 usb_bulk_write(HANDLE *h,s32 pipe,u8 *buf,s32 len);
s32 usb_bulk_read(HANDLE *h,s32 pipe,u8 *buf,s32 len);
s32 cusb_init(s32 n,HANDLE *h,u8 *fw,s8 *str1,s8 *str2);
}
Function
usb_open(n:Integer): Integer;
Function
usb_close(): Integer;
Function
usb_halt(): Integer;
Function
usb_run(): Integer;
Function
usb_dwnload(image:PByte; len:Integer): Integer;
Function
usb_resetpipe(p:DWORD): Integer;
Function
usb_bulk_write(pipe:Integer; buf:PByte; len:Integer): Integer;
Function
usb_bulk_read(pipe:Integer; buf:PByte; len:Integer): Integer;
Function
cusb_init(n:Integer; image:PByte): Integer;
var
IOCTL_Ezusb_GET_PIPE_INFO : DWORD;
IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR : DWORD;
IOCTL_Ezusb_GET_CONFIGURATION_DESCRIPTOR : DWORD;
IOCTL_Ezusb_BULK_OR_INTERRUPT_WRITE : DWORD;
IOCTL_Ezusb_BULK_OR_INTERRUPT_READ : DWORD;
IOCTL_Ezusb_VENDOR_REQUEST : DWORD;
IOCTL_Ezusb_GET_CURRENT_CONFIG : DWORD;
IOCTL_Ezusb_ANCHOR_DOWNLOAD : DWORD;
IOCTL_Ezusb_RESET : DWORD;
IOCTL_Ezusb_RESETPIPE : DWORD;
IOCTL_Ezusb_ABORTPIPE : DWORD;
IOCTL_Ezusb_SETINTERFACE : DWORD;
IOCTL_Ezusb_GET_STRING_DESCRIPTOR : DWORD;
IOCTL_EZUSB_BULK_READ : DWORD;
IOCTL_EZUSB_BULK_WRITE : DWORD;
IOCTL_EZUSB_GET_CURRENT_FRAME_NUMBER : DWORD;
IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST : DWORD;
IOCTL_EZUSB_GET_LAST_ERROR : DWORD;
IOCTL_EZUSB_ISO_READ : DWORD;
IOCTL_EZUSB_ISO_WRITE : DWORD;
IOCTL_EZUSB_GET_DRIVER_VERSION : DWORD;
IOCTL_EZUSB_START_ISO_STREAM : DWORD;
IOCTL_EZUSB_STOP_ISO_STREAM : DWORD;
IOCTL_EZUSB_READ_ISO_BUFFER : DWORD;
IOCTL_EZUSB_ANCHOR_DOWNLOAD_ADR : DWORD;
hdl: THandle;
const
FILE_SHARE_READ = $1;
FILE_SHARE_WRITE = $2;
OPEN_EXISTING = 3;
FILE_DEVICE_UNKNOWN = $22;
METHOD_BUFFERED = 0;
METHOD_IN_DIRECT = 1;
METHOD_OUT_DIRECT = 2;
METHOD_NEITHER = 3;
FILE_ANY_ACCESS = 0;
FILE_READ_ACCESS = 1;
FILE_WRITE_ACCESS = 2;
Ezusb_IOCTL_INDEX = $0800;
CUSB_DWLSIZE = $8000;
implementation
{
The macro can be used for defining IOCTL and FSCTL function control codes.
All IOCTLs must be defined this way to ensure that no overlaps occur
between Microsoft and OEMs/IHVs.
The resulting IOCTL has the following format.
|31----------16|15...13|12-------2| 1,0 |
| Device Type | Access| Function |Method|
}
Function
CTL_CODE(lngDeviceType:word; lngFunction:word; lngMethod:word; lngAccess:word):
DWORD;
begin
Result :=
lngDeviceType * $10000 + lngAccess * $400 + lngFunction * 4 + lngMethod;
end;
procedure InitEzUsb;
begin
IOCTL_Ezusb_GET_PIPE_INFO :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 0,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 1,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_Ezusb_GET_CONFIGURATION_DESCRIPTOR :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 2,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_Ezusb_BULK_OR_INTERRUPT_WRITE :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 3,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_Ezusb_BULK_OR_INTERRUPT_READ :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 4,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_Ezusb_VENDOR_REQUEST :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 5,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_Ezusb_GET_CURRENT_CONFIG :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 6,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_Ezusb_ANCHOR_DOWNLOAD :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 7,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_Ezusb_RESET :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 12,
METHOD_IN_DIRECT, FILE_ANY_ACCESS);
IOCTL_Ezusb_RESETPIPE :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 13,
METHOD_IN_DIRECT, FILE_ANY_ACCESS);
IOCTL_Ezusb_ABORTPIPE :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 15,
METHOD_IN_DIRECT, FILE_ANY_ACCESS);
IOCTL_Ezusb_SETINTERFACE :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 16,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_Ezusb_GET_STRING_DESCRIPTOR :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 17,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_EZUSB_BULK_READ :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 19,
METHOD_OUT_DIRECT,FILE_ANY_ACCESS);
IOCTL_EZUSB_BULK_WRITE :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 20,
METHOD_IN_DIRECT, FILE_ANY_ACCESS);
IOCTL_EZUSB_GET_CURRENT_FRAME_NUMBER :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 21,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 22,
METHOD_IN_DIRECT, FILE_ANY_ACCESS);
IOCTL_EZUSB_GET_LAST_ERROR :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 23,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_EZUSB_ISO_READ :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 25,
METHOD_OUT_DIRECT,FILE_ANY_ACCESS);
IOCTL_EZUSB_ISO_WRITE :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 26,
METHOD_IN_DIRECT, FILE_ANY_ACCESS);
IOCTL_EZUSB_ANCHOR_DOWNLOAD_ADR :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 27,
METHOD_IN_DIRECT, FILE_ANY_ACCESS);
IOCTL_EZUSB_GET_DRIVER_VERSION :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 29,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_EZUSB_START_ISO_STREAM :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 30,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_EZUSB_STOP_ISO_STREAM :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 31,
METHOD_BUFFERED, FILE_ANY_ACCESS);
IOCTL_EZUSB_READ_ISO_BUFFER :=
CTL_CODE(FILE_DEVICE_UNKNOWN, Ezusb_IOCTL_INDEX + 32,
METHOD_OUT_DIRECT,FILE_ANY_ACCESS);
End;
(* --------------- by optimize -----------------
s32 usb_open(s32 n,HANDLE *h){
s8 dev_name[256];
sprintf((char *//)dev_name,(char *//)"\\\\.\\ezusb-%d",n);
*h = CreateFile((char *//)dev_name,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if(*h == INVALID_HANDLE_VALUE) {
return(-1);
}
return(0);
}
*)
function usb_open(n:Integer): Integer;
var
dev_name: string;
i: Byte;
begin
if (n >10) then
begin
Result := -1;
Exit
end
else
i := Byte(n)+$30;
dev_name := '\\.\\ezusb-'+ Char(i);
hdl := CreateFile(PChar(dev_name),
GENERIC_WRITE,
FILE_SHARE_WRITE,
nil,
OPEN_EXISTING,
0,
0);
if hdl = INVALID_HANDLE_VALUE then
Result := -1
else
Result := 0;
end;
(* --------------- by optimize -----------------
s32 usb_close(HANDLE *h){
CloseHandle(*h);
return(0);
}
*)
function usb_close(): Integer;
begin
CloseHandle(hdl);
Result := 0;
end;
(* --------------- by optimize -----------------
s32 usb_halt(HANDLE *h){
unsigned long nbyte;
BOOLEAN ret = False;
VENDOR_REQUEST_IN vreq;
vreq.bRequest = 0xA0;
vreq.wValue = 0x7F92;
vreq.wIndex = 0x00;
vreq.wLength = 0x01;
vreq.bData = 1;
vreq.direction = 0x00;
ret = DeviceIoControl (*h,
IOCTL_Ezusb_VENDOR_REQUEST,
&vreq,
sizeof(VENDOR_REQUEST_IN),
NULL,
0,
&nbyte,
NULL);
if(ret==False){
printf("i8051 halt err.\n");
return(-1);
}
return(0);
}
*)
function usb_halt(): Integer;
var
vreq: VENDOR_REQUEST_IN;
nbyte: DWORD;
ret: Boolean;
begin
with vreq do
begin
bRequest := $A0;
wValue := $7F92;
wIndex := $00;
wLength := $01;
bData := 1;
direction := $00;
end;
ret := DeviceIoControl (hdl, // hDevice: THandle
IOCTL_Ezusb_VENDOR_REQUEST, // dwIoControlCode: DWORD
@vreq, // lpInBuffer: Pointer
sizeof(VENDOR_REQUEST_IN), // nInBufferSize: DWORD
nil, // lpOutBuffer: Pointer
0, // nOutBufferSize: DWORD
nbyte, // var IpBytesReturned: DWORD
nil); // lpOverlapped: POverlapped
if ret = False then
begin
ShowMessage('i8051 halt error!');
Result := -1;
end
else
Result := 0
end;
(* --------------- by optimize -----------------
s32 usb_run(HANDLE *h){
unsigned long nbyte;
BOOLEAN ret = False;
VENDOR_REQUEST_IN vreq;
vreq.bRequest = 0xA0;
vreq.wValue = 0x7F92;
vreq.wIndex = 0x00;
vreq.wLength = 0x01;
vreq.bData = 0;
vreq.direction = 0x00;
ret = DeviceIoControl (*h,
IOCTL_Ezusb_VENDOR_REQUEST,
&vreq,
sizeof(VENDOR_REQUEST_IN),
NULL,
0,
&nbyte,
NULL);
if(ret==False){
printf("i8051 run err.\n");
return(-1);
}
return(0);
}
*)
function usb_run(): Integer;
var
vreq: VENDOR_REQUEST_IN;
nbyte: DWORD;
ret: Boolean;
begin
with vreq do
begin
bRequest := $A0;
wValue := $7F92;
wIndex := $00;
wLength := $01;
bData := 0;
direction := $00;
end;
ret := DeviceIoControl (hdl, // hDevice: THandle
IOCTL_Ezusb_VENDOR_REQUEST, // dwIoControlCode: DWORD
@vreq, // lpInBuffer: Pointer
sizeof(VENDOR_REQUEST_IN), // nInBufferSize: DWORD
nil, // lpOutBuffer: Pointer
0, // nOutBufferSize: DWORD
nbyte, // var lpBytesReturned: DWORD
nil); // lpOverlapped: POverlapped
if ret = False then
begin
ShowMessage('i8051 run error!');
Result := -1;
end
else
Result := 0
end;
(* --------------- by optimize -----------------
s32 usb_dwnload(HANDLE *h,u8 *image,s32 len){
unsigned long nbyte;
BOOLEAN ret = False;
ret = DeviceIoControl (*h,
IOCTL_Ezusb_ANCHOR_DOWNLOAD,
image,
len,
NULL,
0,
&nbyte,
NULL);
if(ret==False){
printf("usb dwnload err.\n");
return(-1);
}
return(0);
}
*)
function usb_dwnload(image:PByte; len:Integer): Integer;
var
nbyte: DWORD;
ret: Boolean;
begin
ret := DeviceIoControl (hdl, // hDevice: THandle
IOCTL_Ezusb_ANCHOR_DOWNLOAD,// dwIoControlCode: DWORD
image, // lpInBuffer: Pointer
len, // nInBufferSize: DWORD
nil, // lpOutBuffer: Pointer
0, // nOutBufferSize: DWORD
nbyte, // var lpBytesReturned: DWORD
nil); // lpOverlapped: POverlapped
if ret = False then
begin
ShowMessage('usb dwnload error!');
Result := -1;
end
else
Result := 0
end;
(* --------------- by optimize -----------------
s32 usb_resetpipe(HANDLE *h,ULONG p){
unsigned long nbyte;
BOOLEAN ret = False;
ret = DeviceIoControl (*h,
IOCTL_Ezusb_RESETPIPE,
&p,
sizeof(ULONG),
NULL,
0,
&nbyte,
NULL);
if(ret==False){
return(-1);
}
return(0);
}
*)
function usb_resetpipe(p:DWORD): Integer;
var
nbyte: DWORD;
ret: Boolean;
begin
ret := DeviceIoControl (hdl, // hDevice: THandle
IOCTL_Ezusb_RESETPIPE, // dwIoControlCode: DWORD
@p, // lpInBuffer: Pointer
sizeof(DWORD), // nInBufferSize: DWORD
nil, // lpOutBuffer: Pointer
0, // nOutBufferSize: DWORD
nbyte, // var lpBytesReturned: DWORD
nil); // lpOverlapped: POverlapped
if ret = False then
Result := -1
else
Result := 0
end;
(* --------------- by optimize -----------------
s32 usb_bulk_write(HANDLE *h,s32 pipe,u8 *buf,s32 len){
unsigned long nbyte;
s32 i,l;
BOOLEAN ret = False;
BULK_TRANSFER_CONTROL bulk_control;
bulk_control.pipeNum = pipe;
for(i=0;len>0;){
if(len>0x8000){
l=0x8000;
}
else{
l=len;
}
ret = DeviceIoControl (*h,
IOCTL_EZUSB_BULK_WRITE,
&bulk_control,
sizeof(BULK_TRANSFER_CONTROL),
buf+i,
l,
&nbyte,
NULL);
if(ret==False){
return(-1);
}
i+=l;
len-=l;
}
return(0);
}
*)
function
usb_bulk_write(pipe:Integer; buf:PByte; len:Integer): Integer;
var
nbyte: DWORD;
i,l: Integer;
ret: Boolean;
bulk_control: BULK_TRANSFER_CONTROL;
p: PByte;
begin
bulk_control.pipeNum := pipe;
i := 0;
while len > 0 do
begin
if len > $8000 then
l := $8000
else
l :=len;
p := buf;
Inc(p,i);
ret := DeviceIoControl (hdl, // hDevice: THandle
IOCTL_EZUSB_BULK_WRITE, // dwIoControlCode: DWORD
@bulk_control, // lpInBuffer: Pointer
sizeof(BULK_TRANSFER_CONTROL),
// nInBufferSize: DWORD
p, // lpOutBuffer: Pointer
l, // nOutBufferSize: DWORD
nbyte, // var lpBytesReturned: DWORD
nil); // lpOverlapped: POverlapped
if ret = False then
begin
Result := -1;
Exit
end;
i := i + l;
len := len - l;
end;
Result := 0;
end;
(* --------------- by optimize -----------------
s32 usb_bulk_read(HANDLE *h,s32 pipe,u8 *buf,s32 len){
unsigned long nbyte;
s32 i,l,cnt;
BOOLEAN ret = False;
BULK_TRANSFER_CONTROL bulk_control;
bulk_control.pipeNum = pipe;
for(i=cnt=0;len>0;){
if(len>0x8000){
l=0x8000;
}
else{
l=len;
}
ret = DeviceIoControl (*h,
IOCTL_EZUSB_BULK_READ,
&bulk_control,
sizeof(BULK_TRANSFER_CONTROL),
buf+i,
l,
&nbyte,
NULL);
if(ret==False){
return(-1);
}
i+=l;
len-=l;
cnt+=nbyte;
}
return(cnt);
}
#if CUSB_DEBUG==1
void tty_thread(void *p){
HANDLE tty_h;
u8 buf[1024];
usb_open(0,&tty_h);
for(;;){
usb_bulk_read(&tty_h,13,buf,64);
printf("recv %s\n",buf);
}
usb_close(&tty_h);
}
#endif
*)
function
usb_bulk_read(pipe:Integer; buf:PByte; len:Integer): Integer;
var
nbyte: DWORD;
i,l,cnt: Integer;
ret: Boolean;
bulk_control: BULK_TRANSFER_CONTROL;
p: PByte;
begin
bulk_control.pipeNum := DWORD(pipe);
i := 0;
cnt := 0;
while len > 0 do
begin
if len > $8000 then
l := $8000
else
l :=len;
p := buf;
Inc(p,i);
ret := DeviceIoControl (hdl, // hDevice: THandle
IOCTL_EZUSB_BULK_READ, // dwIoControlCode: DWORD
@bulk_control, // lpInBuffer: Pointer
sizeof(BULK_TRANSFER_CONTROL),
// nInBufferSize: DWORD
p, // lpOutBuffer: Pointer
l, // nOutBufferSize: DWORD
nbyte, // var lpBytesReturned: DWORD
nil); // lpOverlapped: POverlapped
if ret = False then
begin
Result := -1;
Exit
end;
i := i + l;
len := len - l;
cnt := cnt + Integer(nbyte);
end;
Result := cnt;
end;
(* --------------- by optimize -----------------
s32 cusb_init(s32 n,HANDLE *h,u8 *fw,s8 *str1,s8 *str2){
s8 s1[128],s2[128];
if(usb_open(n,h)) return(-1);
if(usb_get_string(h,1,s1)) return(-1);
if(usb_get_string(h,2,s2)) return(-1);
if(strcmp((const char *//)str1,(const char *//)s1)
||strcmp((const char *//)str2,(const char *//)s2)){
if(usb_halt(h)) return(-1);
if(usb_dwnload(h,fw,CUSB_DWLSIZE)) return(-1);
if(usb_run(h)) return(-1);
usb_close(h);
for(;;){
s32 err=0;
Sleep(2000);
if(usb_open(n,h)) err=1;
if(err==0){
break;
}
}
}
#if CUSB_DEBUG==1
{
s32 i;
i=_beginthread(tty_thread,0,0);
if(i<0){
printf("Can't Create Thread.\n");
return(-1);
}
}
#endif
return(0);
}
*)
function
cusb_init(n:Integer; image:PByte): Integer;
var
err: DWORD;
begin
InitEzUsb();
if usb_open(n) <> 0 then
begin
Result := -1;
Exit
end;
if usb_halt() <>0 then
begin
Result := -1;
Exit
end;
if usb_dwnload(image,CUSB_DWLSIZE) <> 0 then
begin
Result := -1;
Exit
end;
if usb_run() <>0 then
begin
Result := -1;
Exit
end;
usb_close();
while TRUE do
begin
err := 0;
Sleep(2000);
if usb_open(n) <> 0 then
err := 1;
if err = 0 then
break;
end;
Result := 0;
end;
end.
EZ-USB ----- ソフトウェアダウンロード
EZ-USB ----- 参考
CypressのHP
http://www.cypress.com/オプティマイズ (カメレオンUSB , MINI EZ-USB)
http://optimize.ath.cx/index.html
http://optimize.ath.cx/mini_ezusb/index.html
いしかわきょーすけさん
http://www.asahi-net.or.jp/~qx5k-iskw/robot/ezusb.html