|
|
2017/12/18(Mon) 10:43:52|NO.82056
お世話になります。
サンハヤトのUSB・I2C変換モジュール MM-CP2112AをHSPで使いたいです。
CP2112のメーカーが無償で提供しているwin用dllが、そのまま使えると思います。
C、C++、VB用のincludeヘッダファイルも提供されています。
これらからHSP用asファイルを作ることは可能でしょうか?
|
|
2017/12/23(Sat) 00:37:51|NO.82073
HSPをお使い頂きありがとうございます。
USB・I2C変換、なかなか面白そうですね。
MM-CP2112AのSDKをちょっと見てみたのですが、普通のdllなのでHSPから呼び出すことは可能です。
手元に現物のデバイスがないので確認はできないのですが、HSP用のヘッダファイルを作るとすればこんな感じだと思います。
http://www.onionsoft.net/hsp/file/slabhid_as.zip
ただし、dllの関数名しかリストアップしていないので、引数(パラメーターの個数)などはSDKの仕様に合わせて追記する必要があります。
機会があれば、こちらでも試してみたいと思います。
|
|
2017/12/23(Sat) 10:42:38|NO.82074
おにたま様、ご対応いただきありがとうございます。
小生、62歳になりながら未だにAPI関係のことが良く理解できておりません。
引数の追記など、どのようにすればよろしいのでしょうか?
お手間をとらせ、恐縮しております。
|
|
2017/12/29(Fri) 12:41:05|NO.82102
途中経過:おにたま様にお示しいただいた
asファイルのfuncをcfuncに変更して、たちまち必要な関数に引数を追記しました。
返り値を見る限り、デバイスのopen、close、writeは出来ているが、readができない。センサーなのに。
openの戻り値デバイスポインタがintなのですが、関数の中に引数intではエラーになるものが有る。
未だお悩み中。
|
|
2017/12/30(Sat) 13:42:40|NO.82105
引用URLが、めちゃくちゃ長かったですね(^^;
見づらくてすみません。
|
|
2017/12/30(Sat) 14:09:29|NO.82106
ぜーっと様 ご心配いただきありがとうございます。
その不具合は承知しております。デフォルトで無効になっていますし。
#cfunc global HidSmbus_AddressReadRequest "HidSmbus_AddressReadRequest" int,int,int,int,int
アプリケーションノート496によると5個の引数の一個目がintになると思うのですが
システムエラーが起こります。var,double等ではシステムエラーにはなりませんが、
返り値がエラーを示しています。
よろしくお願いいたします。
|
|
2017/12/30(Sat) 17:24:27|NO.82110
インクルードファイル及びアプリケーションノートから関連しそうなところを抜粋してみました。
関数定義は見やすくするためTABを入れたので、表示がずれていたら申し訳ありません。
typedef int HID_SMBUS_STATUS;
typedef void* HID_SMBUS_DEVICE;
HID_SMBUS_STATUS HidSmbus_AddressReadRequest (HID_SMBUS_DEVICE device,
BYTE slaveAddress,
WORD numBytesToRead,
BYTE targetAddressSize,
BYTE targetAddress[16])
戻り値はint型 32bit
第1引数 ポインタ 32bit
第2引数 BYTE型 8bit
第3引数 WORD型 16bit
第4引数 BYTE型 8bit
第5引数 BYTE型配列変数[16] 8bit*16= 128bit
第5引数以外はint(32bit)でいけそうですが、
最後の引数部分はsptrにして
sdim xxx, 16 などのように128bit分確保してみるといけるかもしれませんね。
ときどきAPI使う程度でDLLはめったに使わないので間違っていたらごめんなさい。
|
|
2017/12/31(Sun) 10:33:07|NO.82118
あらま様、ありがとうございます。
ご指摘通り、第5引数をsptrにして、レジスタアドレスを文字列で渡したらエラーは起こりませんでした。
しかし、今度は、HidSmbus_GetReadResponseでパラメーターがおかしいと怒られます。
こちらも、よろしくお願いします。
|
|
2017/12/31(Sun) 11:17:58|NO.82122
前回と同じく関連箇所の抜粋してみました。
typedef BYTE HID_SMBUS_S0;
HID_SMBUS_STATUS HidSmbus_GetReadResponse (
HID_SMBUS_DEVICE device,
HID_SMBUS_S0* status,
BYTE* buffer,
BYTE bufferSize,
BYTE* numBytesRead)
戻り値は同じくint
第1引数 ポインタ 32bit
第2引数 BYTE型のポインタ 32bit
第3引数 BYTE型のポインタ 32bit
第4引数 BYTE型 8bit
第5引数 BYTE型のポインタ 32bit
2番、3番、5番は変数のポインタを渡してやらないといけないので、
ここもsptrで宣言し、
関数を使用するときは2、3、5の引数をvarptr(xxx)などとすればいいと思います。
関数のソースが無く、実機も無いので確認できませんが、
ポインタを渡すということは関数使用の前後で変数の数値が変わっているかもしれませんので
ご注意ください。
ほかはおそらくintで大丈夫かと。
それにしても、WIN32APIを利用するときにもときどき思いますが
[HID_SMBUS_STATUS]も [HID_SMBUS_S0]も そのまま[INT]や[BYTE]でいいだろうと……
少々愚痴を言いたくなりますね。
|
|
2017/12/31(Sun) 12:18:56|NO.82125
あまら様、大変失礼しました。お名前を間違えてしまいました。
おかげさまで、エラーは出なくなりましたが、希望のアドレスを読めません。
HidSmbus_AddressReadRequestの第五引数の渡し方がおかしいようなのですが、
16バイト以下のアドレスの渡し方は、文字列ですかね?
|
|
2017/12/31(Sun) 14:01:22|NO.82127
皆様、無事に読み書きできるようになりました。ありがとうございました。
;(SLABHIDtoSMBus.as)
#ifdef __hsp30__
#ifndef __SLABHIDtoSMBus__
#define global __SLABHIDtoSMBus__
#uselib "SLABHIDtoSMBus.dll"
#cfunc global HidSmbus_GetHidLibraryVersion "HidSmbus_GetHidLibraryVersion" var,var,var
#cfunc global HidSmbus_AddressReadRequest "HidSmbus_AddressReadRequest" int,int,int,int,var
#cfunc global HidSmbus_CancelIo "HidSmbus_CancelIo"
#cfunc global HidSmbus_CancelTransfer "HidSmbus_CancelTransfer"
#cfunc global HidSmbus_Close "HidSmbus_Close" int
#cfunc global HidSmbus_ForceReadResponse "HidSmbus_ForceReadResponse" int,int
#cfunc global HidSmbus_GetAttributes "HidSmbus_GetAttributes"
#cfunc global HidSmbus_GetGpioConfig "HidSmbus_GetGpioConfig"
#cfunc global HidSmbus_GetHidGuid "HidSmbus_GetHidGuid"
#cfunc global HidSmbus_GetIndexedString "HidSmbus_GetIndexedString"
#cfunc global HidSmbus_GetLibraryVersion "HidSmbus_GetLibraryVersion" var,var,var
#cfunc global HidSmbus_GetLock "HidSmbus_GetLock"
#cfunc global HidSmbus_GetManufacturingString "HidSmbus_GetManufacturingString"
#cfunc global HidSmbus_GetNumDevices "HidSmbus_GetNumDevices" var,int,int
#cfunc global HidSmbus_GetOpenedAttributes "HidSmbus_GetOpenedAttributes"
#cfunc global HidSmbus_GetOpenedIndexedString "HidSmbus_GetOpenedIndexedString"
#cfunc global HidSmbus_GetOpenedString "HidSmbus_GetOpenedString"
#cfunc global HidSmbus_GetPartNumber "HidSmbus_GetPartNumber"
#cfunc global HidSmbus_GetProductString "HidSmbus_GetProductString"
#cfunc global HidSmbus_GetReadResponse "HidSmbus_GetReadResponse" int,var,var,int,var
#cfunc global HidSmbus_GetSerialString "HidSmbus_GetSerialString"
#cfunc global HidSmbus_GetSmbusConfig "HidSmbus_GetSmbusConfig" int,int,int,int,int,int,int,int
#cfunc global HidSmbus_GetString "HidSmbus_GetString" int,int,int,var,var
#cfunc global HidSmbus_GetTimeouts "HidSmbus_GetTimeouts"
#cfunc global HidSmbus_GetTransferStatusResponse "HidSmbus_GetTransferStatusResponse" int,var,var,var,var
#cfunc global HidSmbus_GetUsbConfig "HidSmbus_GetUsbConfig"
#cfunc global HidSmbus_IsOpened "HidSmbus_IsOpened" int,var
#cfunc global HidSmbus_Open "HidSmbus_Open" var,int,int,int
#cfunc global HidSmbus_ReadLatch "HidSmbus_ReadLatch"
#cfunc global HidSmbus_ReadRequest "HidSmbus_ReadRequest" int,int,int
#cfunc global HidSmbus_Reset "HidSmbus_Reset"
#cfunc global HidSmbus_SetGpioConfig "HidSmbus_SetGpioConfig"
#cfunc global HidSmbus_SetLock "HidSmbus_SetLock"
#cfunc global HidSmbus_SetManufacturingString "HidSmbus_SetManufacturingString"
#cfunc global HidSmbus_SetProductString "HidSmbus_SetProductString"
#cfunc global HidSmbus_SetSerialString "HidSmbus_SetSerialString"
#cfunc global HidSmbus_SetSmbusConfig "HidSmbus_SetSmbusConfig" int,int,int,int,int,int,int,int
#cfunc global HidSmbus_SetTimeouts "HidSmbus_SetTimeouts"
#cfunc global HidSmbus_SetUsbConfig "HidSmbus_SetUsbConfig"
#cfunc global HidSmbus_TransferStatusRequest "HidSmbus_TransferStatusRequest" int
#cfunc global HidSmbus_WriteLatch "HidSmbus_WriteLatch"
#cfunc global HidSmbus_WriteRequest "HidSmbus_WriteRequest" int,int,var,int
#endif
#endif
未完成ですが、たちまちこれだけあれば、大丈夫です。
このデバイスにスレイブアドレスを渡すときは、必ず8ビットの書き込みアドレスを渡します。
センサーチップの場合、1バイトづつしか読めないようです。
書き込みの際は、データ、アドレスの2バイトを変数で渡します。(data=$0f20:内部アドレス0x20に0x0fを書きます。)
大変お世話になりました。
| |
|
2017/12/31(Sun) 14:01:45|NO.82128
> あまら様、大変失礼しました。お名前を間違えてしまいました。
いえいえ、こちらこそ言われてから気づいたのでお気になさらず。
> HidSmbus_AddressReadRequestの第五引数の渡し方がおかしいようなのですが、
> 16バイト以下のアドレスの渡し方は、文字列ですかね?
すでに解決されているようですし、ご存知かもしれませんが少し解説させていただきます。
C、C++、Java等では変数の型に整数値の型だけでも
1bit用 (bit, bool)
8bit用 (char, byte)
16bit用(short)
32bit用(int, long)
(コンパイラ等の環境によって微妙に違います)
などなど色々ですが、
HSPでは文字型(sdim系) 整数型(int) 小数型(double)の3種類だけなので
今回のような外部DLLを利用するときに BYTE targetAddress[16](符号付8bit整数型 16配列変数)を求められた場合、
とりあえずなんでもいいから16バイト(128bit)分のメモリを確保して渡せばいいや
的な解決方法になってしまいます。
なのでsdim xxx, 16 ではなく、dim xxx, 4 なんかでも
一応メモリが確保できるので可能ということになります。
dimだとビット演算なんかが面倒になりそうなのでsdimで代用したというわけです。
sdimで確保したメモリでもDLL内部では文字列ではなく数値として扱われているはずなので、
その数値をHSPで使う場合には文字と数値の変換が必要となるので、利用する場合には
dim xxx_int, 16;
sdim xxx_byte, 16;
// 文字型(8bit)を符号付数値型(32bit)に変換
repeat 16
if( xxx_byte(cnt) < 128 ) {
xxx_int(cnt) = peek(xxx_byte(cnt), cnt);
}
else {
xxx_int(cnt) = peek(xxx_byte(cnt), cnt) - 256;
}
loop
// 符号付数値型(32bit)を文字型(8bit)に変換
repeat 16
if( xxx_int(cnt) >= 0 ) {
poke xxx_byte(cnt), cnt, xxx_int(cnt);
}
else {
poke xxx_byte(cnt), cnt, xxx_int(cnt) + 256;
}
loop
このように一旦変換をしなくてはいけません。
重要なのは数値か文字かではなくメモリが足りているかどうかなので、
BYTE slaveAddress(符号付8bit整数型)を求められている場合でも
HSP側はint(符号付32bit整数型)を渡せば問題ないはずです。
ついでに説明させていただくと、DLL側でポインタ(BYTE* など "*"が付いている場合)や
配列変数(targetAddress[16]のように"[]"が付いた変数)を求められたら、
varptrで渡すのが無難だと思います。
これは配列もポインタ的な扱われ方をすることがあるためです。
> しかし、読んでみたら、writeができていないことが分かりました。
> #cfunc global HidSmbus_WriteRequest "HidSmbus_WriteRequest" int,int,var,int
> asファイルの書き込みの部分はこんなです。
第3引数でポインタを求められているようですが、これもvarptrで渡す必要があるかと思います。
長文失礼しました。
| |
|
2017/12/31(Sun) 14:03:21|NO.82130
Σ(゚Д゚)
長文書いてたら解決してた!
|
|
2017/12/31(Sun) 14:08:47|NO.82131
あまら様、丁寧な解説、ありがとうございます。参考にさせていただきます。
|
|
2018/1/1(Mon) 09:38:01|NO.82142
参考までに、動作確認に使ったコードを載せときます。
;#include "SLABHIDDevice.as";要らなかった
#include "SLABHIDtoSMBus.as"
onexit goto *bye
vid=0x10c4;MM-CP2112Aのデフォルト
pid=0xea90;MM-CP2112Aのデフォルト
sadd=$d6;スレイブアドレス、8bit、write
regadd=0x0f;内部レジスタのアドレス
res=HidSmbus_GetNumDevices( numDev,vid,pid)
mes "GN="+res+":"+strf("numDev=[%x]",numDev)
res=HidSmbus_Open( devptr,numDev-1,vid,pid )
mes "O="+res+":"+strf("devptr=[%x]",devptr)
res=HidSmbus_SetSmbusConfig(devptr, 400000, 0x02, 0, 100, 100, 0, 2)
mes "SC="+res
data=$0f20;0fが書き込みデータ、20が内部レジスタのアドレス
res=HidSmbus_WriteRequest(devptr,$d6,data,2);"HidSmbus_WriteRequest" int,int,var,int
mes "WR="+res
res=HidSmbus_TransferStatusRequest(devptr)
mes "TSR="+res
res=HidSmbus_GetTransferStatusResponse(devptr,gtstat,rt,br,nn)
mes "GTS="+res+":"+gtstat+":rt="+rt+":br="+br+":nn="+nn
res=HidSmbus_AddressReadRequest( devptr,sadd,1,1,regadd);"HidSmbus_AddressReadRequest" int,int,int,int,var
mes "AR="+res
res=HidSmbus_TransferStatusRequest( devptr)
mes "TSR="+res
res=HidSmbus_GetTransferStatusResponse( devptr,gtstat,rt,br,nn)
mes "GTS="+res+":"+gtstat+":rt="+rt+":br="+br+":nn="+nn
res=HidSmbus_ForceReadResponse( devptr,1 )
mes "FRR="+res
res=HidSmbus_GetReadResponse( devptr,GRSTAT,p1,61,p2 );"HidSmbus_GetReadResponse" int,var,var,int,var
mes "GRR="+res+":grstat="+grstat+":p1="+p1+":p2="+p2
readData=p1 & 0xffffff;読み込みデータは4バイトのintでしたが、先頭1バイトは読み込んだバイト数になっていたのでマスクします。
mes strf("readData=[%x]",readData)
stop
*bye
res=HidSmbus_Close( devptr)
mes "C="+res
assert
end
| |
|