hidmon.dllを使う
Tiny2313を使ったUSBプログラマのハードとファームHIDaspxを汎用USB-IOとして使うプログラムがhidmon.exeですが、汎用のためdll(hidmon.dll)が用意されています。
これをDelphiから呼び出すために試行錯誤して得られた方法を記します。(使えた、ということで「良い使い方」とは別です)
ここでは必要なdllがpathのとおった場所に必ず存在する場合です。Webで調べたところ次のように理解しました。
hidmon.dllに含まれる関数(説明書から)には次のものがあります。
int UsbInit(char *string); 初期化.
int UsbExit(void); 終了.
void UsbPoke(int adr,int arena,int data,int mask); 書き込み
int UsbPeek(int adr,int arena); 1バイト読み出し
int PortAddress(char *string);
これらの関数を使うにはまず、"implementation"の上に
function 任意の関数名(引数:型,・・):関数の型;stdcall; external 'ファイル名.dll' name 'dll内の関数名';
または、
function dll内の関数名(引数:型,・・):関数の型;stdcall; external 'ファイル名.dll';
と宣言します。今回は後者を採りました。
DelphiをCでは型の標記が異なりますから修正して、次のように宣言しました。
var
Form1: TForm1;
function UsbInit(h:pchar):integer; stdcall; external 'hidmon.dll';
function UsbExit():integer; stdcall; external 'hidmon.dll';
function UsbPeek(adr,arena:integer):integer; stdcall; external 'hidmon.dll';
function UsbPoke(adr,arena,data,mask:integer):integer; stdcall; external 'hidmon.dll';
function PortAddress(ch:pchar):integer; stdcall; external 'hidmon.dll';
implementation
これで以後のプログラムからの呼び出しは普通の関数と同様に行えました。ただ、Delphiではpchar型の文字列は一般でなく、pchar()キャストはダメでした。
pchar型で宣言した変数を使いました。もっとも5つ目の関数は使っていないので、'*'だけですが。(その後の調べで、PCharキャストはアドレスを渡すのですが、渡した後に実体がなくなるとアドレスの意味がなくなるので注意とのことがわかりました。そこで、stringをグローバル変数に置きPCharキャストすると正しく動きました。'*'一文字だけですから追試は必要です。→この方式で問題ないことがわかりました。)
なお、引数の内容はマニュアルから引用します。
//----------------------------------------------------------------------
// HIDmon の初期化
// string : デバイス識別文字列(シリアルナンバー文字列)
// 現在未実装。 "*" を渡してください。
// 戻り値:
// 成功 = 0
// 失敗 = -1
DLL_int UsbInit(const char *string);
//----------------------------------------------------------------------
//
// HIDmon の使用終了
//
DLL_int UsbExit(void);
//----------------------------------------------------------------------
//
// デバイス側のポートやメモリーに値を書き込む.
// adr : 書き込むメモリー
// arena : メモリー種別:
// 0x00 RAMもしくはI/O Port
// 0x20 EEPROM (現在未実装)
// data : 書き込みデータ.
// mask : 書き込みマスク.
// mask = 0 の場合は、dataは全ビット有効 (直書きする)
// mask != 0 の場合は、maskビット1に対応したdataのみ更新し、他は変更しない.
//
// 戻り値:
// 成功= 1以上の整数
// 失敗= 0, あるいは-1
DLL_int UsbPoke(int adr,int arena,int data,int mask);
//----------------------------------------------------------------------
//
// デバイス側のポートやメモリーを1バイト読み出す.
// adr : 読み出しメモリー
// arena : メモリー種別:
// 0x00 RAMもしくはI/O Port
// 0x20 EEPROM (現在未実装)
// 0x40 PGMEM (現在未実装)
// 戻り値:
// 成功= 読み出したデータ(0〜255)
// 失敗= -1
DLL_int UsbPeek(int adr,int arena);
//----------------------------------------------------------------------
//
// ATtiny2313のポート名称をアドレスに変換する.
//
// 戻り値:
// 成功= ポートアドレス(0〜255)
// 失敗= -1
DLL_int PortAddress(const char *string);
アドレスは次のテーブルを参照しました。
┃ DIDR = 0x21 GPIOR0 = 0x33 GTCCR = 0x43 TCNT1H = 0x4d ┃
┃ UBRRH = 0x22 GPIOR1 = 0x34 ICR1 = 0x44 TCCR1B = 0x4e ┃
┃ UCSRC = 0x23 GPIOR2 = 0x35 ICR1L = 0x44 TCCR1A = 0x4f ┃
┃ ACSR = 0x28 PINB = 0x36 ICR1H = 0x45 TCCR0A = 0x50 ┃
┃ UBRRL = 0x29 DDRB = 0x37 CLKPR = 0x46 OSCCAL = 0x51 ┃
┃ UCSRB = 0x2a PORTB = 0x38 OCR1B = 0x48 TCNT0 = 0x52 ┃
┃ UCSRA = 0x2b PINA = 0x39 OCR1BL = 0x48 TCCR0B = 0x53 ┃
┃ UDR = 0x2c DDRA = 0x3a OCR1BH = 0x49 MCUSR = 0x54 ┃
┃ RXB = 0x2c PORTA = 0x3b OCR1 = 0x4a MCUCR = 0x55 ┃
┃ TXB = 0x2c EECR = 0x3c OCR1L = 0x4a OCR0A = 0x56 ┃
┃ USICR = 0x2d EEDR = 0x3d OCR1H = 0x4b SPMCSR = 0x57 ┃
┃ USISR = 0x2e EEAR = 0x3e OCR1A = 0x4a TIFR = 0x58 ┃
┃ USIDR = 0x2f EEARL = 0x3e OCR1AL = 0x4a TIMSK = 0x59 ┃
┃ PIND = 0x30 PCMSK = 0x40 OCR1AH = 0x4b EIFR = 0x5a ┃
┃ DDRD = 0x31 WDTCSR = 0x41 TCNT1 = 0x4c GIMSK = 0x5b ┃
┃ PORTD = 0x32 TCCR1C = 0x42 TCNT1L = 0x4c OCR0B = 0x5c ┃