HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
1218
うしサンハヤトのUSB・I2C変換モジュール MM-CP2112AをHSPで15解決


うし

リンク

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:40:19|NO.82104

よくわかりませんが、サンハヤトのサイトに以下の文がありました。
関係あるかどうかまでは判りませんが、なにかヒントになりませんか?

引用元 http://www.sunhayato.co.jp/material2/index.php/item?cell003=%E6%95%99%E8%82%B2%E5%AE%9F%E7%BF%92%E3%83%BB%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C%E8%A3%BD%E5%93%81&cell004=IC%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB&name=USB%E3%83%BBI2C%EF%BC%88SMBus%EF%BC%89%E5%A4%89%E6%8F%9B%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB+MM-CP2112A&id=1083&label=1
■CP2112のアプリケーション開発時の注意
Auto read response設定には不具合があります。(2015/8/20時点) HidSmbus_SetSmbusConfig()にてautoReadResponseを有効(1)に設定した際、不定なデータまたはデータが読み出せない場合があります。 データを読み出す際は、autoReadResponseを無効(0)に設定し、全てのアドレスリードリクエストの後にForce Read Responseを開始してください。手順は以下のようになります。 HidSmbus_AddressReadRequest() HidSmbus_ForceReadResponse() HidSmbus_GetReadResponse()



ぜーっと!

リンク

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



ONION software Copyright 1997-2023(c) All rights reserved.