• 締切済み

FTDIのFT2232Dでのハンドシェイク通信について

FTDIのFT2232Dでのハンドシェイク通信について FTDIのFT2232とCPLDを接続してROMライターを作ろうとしています。 CPLDとの接続にパラレルのハンドシェイクで通信させたいと思っています。 (できれば、FT245を使う可能性もあるのでMPSSEモードは使いたくないんです) PC側のアプリはD2XXの.netラッパーをかませています。(ラッパーはFTDI純正で、言語はC#で書いています) FTDI device = new FTDI(); FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK; インスタンスを作って、 ftStatus = device.OpenByIndex(0); if (ftStatus != FTDI.FT_STATUS.FT_OK) { MessageBox.Show("Error"); } ftStatus = device.SetBitMode(0xFF, 0x00); if (ftStatus != FTDI.FT_STATUS.FT_OK) { MessageBox.Show("Error"); } ftStatus = device.SetBaudRate(9600); if (ftStatus != FTDI.FT_STATUS.FT_OK) { MessageBox.Show("Error"); } SetBItModeで第2引数で0x00を与えてハンドシェイクモードにしています。 byte[] data = new byte[1]; data[0] = 0x0A; uint rcount = 0; ftStatus = device.Write(data, 1, ref rcount); if (ftStatus == FTDI.FT_STATUS.FT_OK) { MessageBox.Show(rcount.ToString()); uint buffcount = 0; ftStatus = device.GetTxBytesWaiting(ref buffcount); if (ftStatus == FTDI.FT_STATUS.FT_OK) { MessageBox.Show(buffcount.ToString()); } else { MessageBox.Show("Buff Count Error"); } } else { MessageBox.Show("Error Write"); } FTDIチップのFIFOへの書き込みですが、このようにしています。 本来、書き込みが正常に完了したら、buffcountが増えていてほしいのですが、 0のままで、チップにLEDを付けて動作を見ていると、PC側アプリでWriteしてから、 すぐにチップが出力しているようでした。 ハンドシェイクにしているので、制御ピンをいじるまでFIFOにとどまっているはずですが、 困ったものです。何かおかしい点ありましたら指摘していただけないでしょうか? よろしくお願いします。

みんなの回答

  • uruz
  • ベストアンサー率49% (417/840)
回答No.4

>やはりFIFOにのこらず 残らないという判断はどこでされているのでしょうか FTD2XX_NETのドキュメントが見つけられなかったので確認出来てませんが GetTxBytesWaiting() はFIFO内のデータ数を返す関数なのでしょうか?ドライバー内に残ってるデータ数のような気もするのですが・・・・ FTD2XX_NETに FT_GetStatus() に相当する関数はありませんか FT_GetStatus() もどこのデータ数なのかよく解らないのですが RD#、WR の信号レベルは適切ですか >チップにLEDを付けて動作を見ていると どこにLEDを付けているのでしょうか、RXF#に付けているならRXF#は読み出し可能なデータが存在することを示す信号ですのでPC側アプリでWrite時点で点灯するのは正常です

takeru_okwave
質問者

補足

LEDはDB0~3と、¥RXFにつけています。 先ほど確認したところ、正常にハンドシェイクされていました。 秋月のFT245モジュールを使っているのですが、ブレッドボード の刺す位置が1つずれていたという初歩的なミスでした。お手数掛けました。 私も、FTD2XX_NETの資料が見当たらずに困っています。 FT_GetStatus()相当の関数が見当たりません。 バッファに関係ありそうなのがGetTxBytesWaiting()くらいしか見当たりませんでした。 ハンドシェイクはできるようにはりましたが、FIFOのバッファリング数の取得は .NETラッパーでは不可能なのでしょうか?

  • uruz
  • ベストアンサー率49% (417/840)
回答No.3

またまた失礼しました、質問を読み返して気付いたのですが >パラレルのハンドシェイクで通信させたいと思っています。 FT2232DをFT245モードで動かそうとしているのでしょうか? FT2232DをFT245モードで動かすためにはEEPROMを実装しEEPROMに動作モード書き込んでおく必要があるようです EEPROMが未実装の場合SetBitMode()で0x00だとUART(FT232相当)で動作します 参考にされているページはFT245ですのでSetBitMode()で0x00でいいのですがFT2232Dの場合はEEPROMで設定していなければUARTモードになります EEPROMが実装済みであれば下記URLより「MProg 3.5 - EEPROM Programming Utility」を入手して書き込んでください http://www.ftdichip.com/Resources/Utilities.htm

takeru_okwave
質問者

補足

ご回答どうもありがとうございます。 FT245を友人から借りて、実験してみました。 しかしSetBitMode()の第2引数で0x00を送ってもやはりFIFOにのこらず すぐに出力されているようです。

  • uruz
  • ベストアンサー率49% (417/840)
回答No.2

失礼しました FT_SetBitmode()はPC-FTxxxx間(USB)の通信でBit BangモードはI/Oとして使う時の設定なので関係ないですね RS-232C側のフロー制御はFT_SetFlowControl()ですのでD2XXの.netラッパーで確答する関数を探してください FT_SetFlowControl (FT_HANDLE ftHandle,        USHORT usFlowControl,UCHAR uXon, UCHAR uXoff) ●ftHandle:Handle of the device. ●usFlowControl:Must beone one of        FT_FLOW_NONE        FT_FLOW_RTS_CTS        FT_FLOW_DTR_DSR        FT_FLOW_XON_XOFF ●uXon: Character used to signal Xon.     Only used if flow control is     FT_FLOW_XON_XOFF. ●uXoff: Character used to signal Xoff.     Only used if flow control is     FT_FLOW_XON_XOFF. --------------------------------------- サンプルコード FT_HANDLE ftHandle; FT_STATUS ftStatus; ftStatus = FT_Open(0, &ftHandle); if(ftStatus != FT_OK) { // FT_Open failed return; } // Set RTS/CTS flow control ftStatus = FT_SetFlowControl(ftHandle, FT_FLOW_RTS_CTS, 0x11, 0x13); if (ftStatus == FT_OK) { // FT_SetFlowControl OK } else { // FT_SetFlowControl Failed } } FT_Close(ftHandle);

  • uruz
  • ベストアンサー率49% (417/840)
回答No.1

>SetBItModeで第2引数で0x00を与えてハンドシェイクモードにしています。 D2XXの.netラッパーの定義までは確認していませんが 「D2XX_Programmer's_Guide」で FT_SetBitmode((FT_HANDLE ftHandle, UCHAR ucMask, UCHAR ucMode) のucModeは以下のようになってますので 0x0 = Reset 0x1 = Asynchronous Bit Bang 0x2 = MPSSE (FT4232H, FT2232H and FT2232 devices only) 0x4 = Synchronous Bit Bang (FT4232H, FT2232H, FT232R, FT245R and FT2232 devices only) ハンドシェイクモードなら"0x4"ではないでしょうか?

takeru_okwave
質問者

補足

0x4で実験してみましたが、0x00のときと同じでした。 たしか、Synchronous Bit BangとAsynchronous Bit Bangの違いは、 ハンドシェイクを行うか行わないかではなく、出力するタイミングのときに現在チップ に入力されているデータを取り込むか取り込まないかということだったと思います。 ハンドシェイクは0x00というのは、 http://ioio.at.infoseek.co.jp/FT245RL/FT245DllHowTo.html ここで読みました。

関連するQ&A

  • VB IF なぜ構文エラーにならないのですか?

    Dim x, y, z As Integer x = 1 y = 1 z = 1 If x = y And y = z Then MessageBox.Show("OK") End If 3つの値が同じならアラートを出したいのです。このソースでできるかとおもいます。。。 しかし・・・・ If x = y = z Then MessageBox.Show("OK") End If とするとアラートが出ません。関数的に使い方が間違っているのでしょうか? もしそうならなぜ構文エラーが出ないのでしょうか? よろしくお願いします。 言語Microsoft Visual Basic 2008 Express Edition

  • VB2010で、シリアル通信をするには

    VB2010で、シリアル通信をするには シリアルポートをopenしようとすると、エラーで弾かれてしまいます。 どのように対処したら良いですか? 使っているソースコードは、下記の通り。 Private Sub ButtonRsStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonRsStart.Click Try '例外処理のはじまり If SerialPort1.IsOpen = True Then 'ポートはオープン済み MessageBox.Show("すでに" & SerialPort1.PortName & "は接続されています。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Sub End If SerialPort1.PortName = "COM1" 'オープンするポート名を格納 SerialPort1.Open() 'ポートオープン PORT_STATE.Text = "OPEN" Catch ex As Exception '例外処理 MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub --------------- エラーが発生する場所は、「Catch 」になります。 エラーメッセージは、「ポート 'COM1' へのアクセスが拒否されました。」です。 何が原因なのか、さっぱり分かりません。 ヒントになりそうな解答を頂けないでしょうか?

  • DirectXによる通信ができなくて困っています。

    DirectX9のDirectPlayで通信をしようとしているのですが、セッションへの接続が出来なくて困っています。 言語はC++で開発環境はVisualC++6.0です。プログラムは自分で組んだもので、ピアツーピア型。ホストとピア両方が出来るようにプログラムを組んで、同じプログラムを二つ起動して同一のマシンで実行しています。 接続が出来ない原因を調べたところ以下のセッションへの接続部分でプログラムが1~2分ほど固まり、その後接続に失敗していました。 hr = lpDirectPlay8Peer->Connect(&dpnAppDesc2, prgHostAddr,prgDeviceInfo2, NULL, NULL, NULL, 0, NULL, NULL, NULL,DPNCONNECT_OKTOQUERYFORADDRESSING | DPNCONNECT_SYNC); 接続に失敗した後、このエラー処理で接続に失敗した事は分かるのですが原因が分かりません。又、アドレスの設定やホストが確立しているかも同様の方法でエラーの判断をしています。 if (FAILED(hr)) //エラー処理 {MessageBox("セッションの接続に失敗", "PeerVoice", MB_OK | MB_ICONWARNING);} else {MessageBox("セッションの接続に成功", "PeerVoice", MB_OK | MB_ICONWARNING);} MSDNのIDirectPlay8Peer::Connectメソッドの項を見るとエラー時の戻り値でエラー原因が分かるようなので以下の様なコードを書きました。 switch (hr){ case S_OK: MessageBox("成功1", "PeerVoice", MB_OK |MB_ICONWARNING); break; case DPNSUCCESS_PENDING:("成功2", "PeerVoice", MB_OK |MB_ICONWARNING);break; case DPNERR_HOSTREJECTEDCONNECTION: MessageBox("失敗1", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDAPPLICATION : MessageBox("失敗2", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDDEVICEADDRESS : MessageBox("失敗3", "PeerVoice", MB_OK | MB_ICONWARNING); break; case DPNERR_INVALIDFLAGS: MessageBox("失敗4", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDHOSTADDRESS: MessageBox("失敗5", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDINSTANCE: MessageBox("失敗6", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDINTERFACE: MessageBox("失敗7", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDPASSWORD: MessageBox("失敗8", "PeerVoice", MB_OK | MB_ICONWARNING); break; case DPNERR_NOCONNECTION: MessageBox("失敗9","PeerVoice", MB_OK| MB_ICONWARNING);break; case DPNERR_NOTHOST: MessageBox("失敗10", "PeerVoice", MB_OK|MB_ICONWARNING);break; case DPNERR_SESSIONFULL: MessageBox("失敗11", "PeerVoice",MB_OK| MB_ICONWARNING);break; default: MessageBox("失敗0", "PeerVoice",B_OK|MB_ICONWARNING);break; } しかし、これでもdefaultの失敗0のメッセージボックスが出てきてしまいます。何かの設定ミスやホストがいないのなら上記のエラー処理で原因が特定できると思ったのですが、全くわけが分かりません。どうか理由が分かる方回答をお願いいたします。

  • VB2010から外部機器へのシリアル通信によるデー

    VB2010をのserialport機能を用いて,外部機器にデータを送るプログラムを作成しています。 外部機器から送信されてきたデータの受信は問題なくできましたが,PCからの送信がうまく出来ません。 Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click If TextBox2.Text.Length = 0 Then MessageBox.Show("送信文字列を入力してください", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) TextBox2.Focus() Exit Sub End If Try SerialPort1.WriteLine(TextBox2.Text) Catch ex As Exception MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub プログラムは上記のようになります。(microsoftのサンプルそのままです。) 上記のプログラムで 数字の「1」を送信したいのですが,うまく送ることができません。 外部機器は,データが送信されたことは感知していますが, 「1」 が送られたことは認識できていないようです。 serialdebug2というソフトを使用して,「1」 を送信した場合は,問題ありませんでした。 どうすれば,上記のような問題を解決できるdしょうか?

  • ポインター引数の関数でコンパイルエラーが出る。

    現在ATmega88というアトメル社製のマイコンのプログラミングを行っています。コンパイラはwin_avrを使用しています。 現在void tx_test(cc1101_client * client)というcc1101_clientポインターを引数とした関数を作成したのですが、この関数内でu16 tx_fifo_set(txfifo_data * txfifo)という txfifo_dataポインターを引数とする関数を呼び出したいと思っているのですが、これをコンパイルすると error: incompatible type for argument 1 of 'tx_fifo_set'というエラーが出力されコンパイルできない状態になります。なぜこのようなエラーになるのでしょうか? u16 tx_fifo_set(txfifo_data * txfifo) { -------------------(中略)------------------------------------------------------------- } void tx_test(cc1101_client * client) { u8 i=0; u8 new_input_data=0; -------------------(中略)------------------------------------------------------------- while(1) { switch(status) { -------------------(中略)------------------------------------------------------------- case FIFO_SETUP: if(cnt_sent_packet > 100) { status = DATA_WAVEOUT_QUIT; break; } //alert_data_get(&client); cc1100_cmd_flush_tx(); cc1100_cmd_idle(); cc1100_cmd_calibrate(); cc1100_cfg_gdo0(CC1100_GDOx_SYNC_WORD); mdelay(5); client->status.sessionflag = 0x02; //SYN flag set client->status.ivent_flag = 0xa5; //tx_length = tx_fifo_set(client); //tx_fifo_set(&client); tx_fifo_set(client->txfifo); udelay(10); #if 1 cc1100_read_reg_uartout((CC1100_REG_TXBYTES | CC1100_ACCESS_STATUS)); #endif status = DATA_WAVEOUT; break; -------------------(中略)------------------------------------------------------------- }

  • OnTimer()時にクリックされたことを知るには?

    環境 WIN98 VC++6.0 MFC にて OnTimer()時にクリックされたことを知るにはどうすれば良いですか? void CAbcdView::OnTimer(UINT nIDEvent) { KillTimer( 1 ); if ( どのように記述すれば良いですか?) //左クリックされたことを知りたい MessageBox( "クリックされました。", "左", MB_OK ); CView::OnTimer(nIDEvent); }

  • UDP通信について

    前回のことでかなり言われたので改変版を見てもらいたいと思います。 TCPと伝えていましたが今回、UDPに変えました。 ヘッダーはこのようになっております。 ==wsock.h== #include <Windows.h> #include <stdio.h> #pragma comment(lib,"WSock32.lib") #define PORT_NO 8000 ポート番号 #define SERVER_NAME "" enum MINE{ NONE, SERVER, CLIENT }; ソケット通信 class WSOCK{ private: WSADATA wsaData; SOCKET s; SOCKADDR_IN saddr; int rtn; int state; MINE mineFlg; char szStr[256]; エラーメッセージ用 u_short port; 変換後のポート番号 int fromlen; 受信したサイズ HOSTENT *lpHost; ホスト情報 ファイルディスクプリタをまとめた構造体 //→ソケット判別する為の管理情報 fd_set fds,readfds; public: char szRcvBuf[1024]; 受信バッファ char szSndBuf[1024]; 送信バッファ SOCKADDR_IN from; ソケットアドレス構造体 WSOCK(); ~WSOCK(); bool ServerRcv(); 受信 bool ServerSnd();送信 bool CliantRcv();受信 bool CliantSnd();送信 void SarverSet(); void ClientSet(); bool EnumMyIPAddress(); }; ==wsock.cpp== #include "wsock.h" コンストラクタ WSOCK::WSOCK(){ //WinSock初期化 rtn = WSAStartup(MAKEWORD(2,2),&wsaData); if(rtn != 0){ MessageBox(NULL,"WSAStartup失敗", "ERROR",MB_OK); state = -1; } ソケットを開く s = socket(AF_INET,SOCK_DGRAM,0); if(s<0){ MessageBox(NULL,"ソケットをオープンできません", "eRROR",MB_OK); WSACleanup(); state = 2; } 0で初期化 memset(&saddr,0,sizeof(SOCKADDR_IN)); saddr.sin_family = AF_INET;//アドレスファミリー saddr.sin_port = htons(PORT_NO);//ポート mineFlg = SERVER; サーバ側設定 if(mineFlg == SERVER) { SarverSet(); } if(mineFlg == CLIENT) {クライアント ClientSet(); } } WSOCK::~WSOCK(){ closesocket(s); ソケットのリソース解放 rtn = WSACleanup(); if(rtn == SOCKET_ERROR){ MessageBox(NULL,"WSACleanup失敗","ERrOR",MB_OK); state = -2; } } //受信 bool WSOCK::ServerRcv(){ 読み込み用fd_setの初期化 selectが毎回内容を上書きしてしまうので毎回初期化 memcpy(&fds,&readfds,sizeof(fd_set)); struct timeval timeout = {0,0};   //{1秒以上の部分()s、1秒以下の部分(ms)} fdsに設定されたソケットが読み込み可能になるまで待つ select(0,&fds,NULL,NULL,&timeout); ソケット読み込み可能データがある場合 if(FD_ISSET(s,&fds)){ fromlen = (int)sizeof(from); //nullで初期化 memset(szRcvBuf,'\0',sizeof(szRcvBuf)); //受信処理 rtn = recvfrom(s,szRcvBuf,(int)sizeof(szRcvBuf)-1,0, (SOCKADDR*)&from,&fromlen); if(rtn == SOCKET_ERROR){ MessageBox(NULL,"recvfromエラー","ERRoR",MB_OK); return false; } } szRcvBuf[rtn] | '\0';//NULLコード if(strcmp(szRcvBuf,"c_end") == 0){ MessageBox(NULL,"クライアントが接続を切りました","ERROr",MB_OK); return false; } return true; } 送信 bool WSOCK::ServerSnd(){ char buf[1024]; memset(buf,0,sizeof(buf)); //_snprintf:書式指定文字付きデータ書き込み _snprintf(buf,sizeof(buf),"data to port 8000"); //送信処理 rtn = sendto(s,szSndBuf,(int)strlen(szSndBuf)+1, 0,(LPSOCKADDR)&from, 送り先サーバ/クライアント sizeof(from)); サイズ if(rtn != (int)strlen(szSndBuf)+1){ MessageBox(NULL,"sendtoエラー","サーバーエラ",MB_OK); closesocket(s); WSACleanup(); return false; } return true; } 受信 bool WSOCK::CliantRcv(){ fromlen = (int)sizeof(from); //nullで初期化 memset(szRcvBuf,'\0',sizeof(szRcvBuf)); //受信処理 rtn = recvfrom(s,szRcvBuf,(int)sizeof(szRcvBuf)-1,0, (SOCKADDR*)&from,&fromlen); if(rtn == SOCKET_ERROR){ MessageBox(NULL,"recvfromエラー","ERRoR",MB_OK); return false; } szRcvBuf[rtn] | '\0'; //NULLコード if(strcmp(szRcvBuf,"s_end") == 0){ MessageBox(NULL,"接続を切りました","ERROr",MB_OK); return false; } return true; } 送信 bool WSOCK::CliantSnd(){ 送信処理 rtn = sendto(s,szSndBuf,(int)strlen(szSndBuf)+1, 0,(LPSOCKADDR)&saddr, 送り先サーバ/クライアント sizeof(saddr)); サイズ if(rtn != (int)strlen(szSndBuf)+1){ MessageBox(NULL,"sendtoエラー","erROR",MB_OK); closesocket(s); WSACleanup(); return false; } return true; } void WSOCK::SarverSet(){ saddr.sin_addr.s_addr = htonl(INADDR_ANY); ソケットにローカルアドレスを関連付ける if(bind(s,(LPSOCKADDR)&saddr, (int)sizeof(saddr)) == SOCKET_ERROR){ MessageBox(NULL,"bindエラー","er",MB_OK); closesocket(s); WSACleanup(); state = -3; } FD_ZERO(&readfds); FD_SET(s,&readfds); } void WSOCK::ClientSet(){    クライアント側設定    ホスト名からホスト情報を取得 lpHost = gethostbyname(SERVER_NAME); サーバのアドレスをセット memcpy(&(saddr.sin_addr), lpHost->h_addr_list[0], //サーバのアドレス lpHost->h_length); } となっております。

  • 自作関数で元の値を変更したい

    ポインタとかが分からないので教えてください。 元のプロセスで  case WM_KEYDOWN:   MyFunc(hWnd);   if(!hWnd)MessageBox(NULL, "成功", "", MB_OK);   else MessageBox(NULL, "エラー", "", MB_OK);  break; 元のプロセスの自作関数で void MyFunc(HWND wnd){  SetWindowText(wnd, "てすと");//これはちゃんとできた。  wnd = NULL;//ここが失敗で、この関数を抜けるまでしか効果がない。 } これで MessageBox(NULL, "エラー", "", MB_OK); が実行されてしまいました。

  • シェイクハンドの握り方

    ラケットを浅く握ったときと深く握ったときの違い(長所と短所)を教えて下さい。

  • (株)シェイクハンドとは?

    こんにちは。精神保健福祉士をやってます。 クライアントさんから相談があったのですが、精神障害者でも入れる、「シェイクハンドクラブ」という保険について質問があったのですが、ここは信頼できる保険会社なのでしょうか。 精神障害者でも癌、脳卒中になった場合、入院保険や通院保険が受けられるそうですが、本当に大丈夫なのでしょうか。 普通、保険会社は精神障害者を排除していると聞いてます。 信頼できる保険会社であればこのクライアントさんに薦めるのですが。