Socket Debuggerを使ってみる! ポート:2! 受信データをチェックしてみる [NETWORK]
SocketDebugger
こことか、 https://www.udom.co.jp/sdg/
こことか、 http://sdg.ex-group.jp/lua.html
をまず見てね!
前回ではエコーサーバーに対してユーザークライアントが適当なデータを投げて、サーバーから返ってきたデータを受信するまでをやりました、、、うーん受信したデータは大丈夫?って疑念が湧きますよね普通。
なので今回はスクリプトを自作して送信データと受信データの比較をしてみます。
以下の様なテーブル同士を比較するユーザー関数を作成してみました。ポート2のスクリプトファイルの一番最後にでも置いておきます。
微妙な違いですが送信ボタンのイベントの変数名を変えました。変数はlocal修飾子を付けないとグローバル変数扱いです。
受信イベントを以下の様に変えました。
テーブル同士を比較してログ出力メッセージを変えています。
成功しているようです。
こことか、 https://www.udom.co.jp/sdg/
こことか、 http://sdg.ex-group.jp/lua.html
をまず見てね!
前回ではエコーサーバーに対してユーザークライアントが適当なデータを投げて、サーバーから返ってきたデータを受信するまでをやりました、、、うーん受信したデータは大丈夫?って疑念が湧きますよね普通。
なので今回はスクリプトを自作して送信データと受信データの比較をしてみます。
以下の様なテーブル同士を比較するユーザー関数を作成してみました。ポート2のスクリプトファイルの一番最後にでも置いておきます。
--------------------------------------------- -- compare table A and table B. --------------------------------------------- function compareTbl( tableA, tableB ) local tableALen = #tableA -- テーブルAの要素数を変数に代入 local tableBLen = #tableB -- テーブィBの要素数を変数に代入 if tableALen ~= tableBLen then return -1 end -- 要素数を比較して違うならエラーで帰る for i = 1, #tableA do -- テーブル(配列)は1から始まり、要素数までループ if tableA[ i ] ~= tableB[ i ] then return -1 -- 要素同士を比較して違うならエラーで帰る end end return 0 end
微妙な違いですが送信ボタンのイベントの変数名を変えました。変数はlocal修飾子を付けないとグローバル変数扱いです。
--------------------------------------------- -- 送信ボタン押下 --------------------------------------------- function OnSendPush() Logput(1,'OnSendPush') sendData = GetEditorData() SendData( sendData ) return 0 end
受信イベントを以下の様に変えました。
テーブル同士を比較してログ出力メッセージを変えています。
--------------------------------------------- -- 受信通知 --------------------------------------------- function OnReceive( recv ) Logput( 1, 'OnReceive' ) if compareTbl( sendData, recv ) == 0 then Logput( 1, 'Receive data was good.' ) else Logput( 2, 'Receive data was not good.' ) -- 引数に2を指定すると注意、1なら情報、3なら警告 end return 0 end
成功しているようです。
M5Stick ミニ開発キットESP32 1.3'OLEDオプションのブザーIRトランスミッタMpu9250
- 出版社/メーカー: M5Stack
- メディア:
Socket Debuggerを使ってみる! ポート:1! [NETWORK]
SocketDebugger
こことか、 https://www.udom.co.jp/sdg/
こことか、 http://sdg.ex-group.jp/lua.html
をまず見てね!
ネットワークデバイスのデバックで最近利用を始めたSocketDebugger、無償版と有償版があります。
有償版に比較して無償版ではいくつかの機能が制限されますが、それでもとても有用なツールだと感じています。
特に、標準で備わっている機能だけでもデータの送受信を自動的に行うなどは容易に設定してできますが、Luaスクリプトを組むことでより詳細な動きを制御できます。
無償版は基本的な設定項目を保存することができませんが、Luaスクリプト自体はユーザーがエディタで作成し、保存、読み出しができますので、なるべくLuaスクリプトで処理をした方が同じようなデバックを何度も行うなら楽だと思います。
Lua?
ウイキペディア https://ja.wikipedia.org/wiki/Lua
参考にしているサイト
https://qiita.com/rohinomiya/items/abeb1d69c640a27d97c5
https://qiita.com/dwarfJP/items/e033728f5cbecbabe11f
http://amlaid.air-nifty.com/blog/2015/10/serial-debugger.html
https://qiita.com/satorimon/items/d65872659f7d6dc453fd
SocketDebuggerは2つのポート(ポート1とポート2)が同時に操作できますんで、わざわざターゲットを用意しなくてもSocketDebuggerだけでお試しやスクリプトの実行を行うことができます。
以下例ではポート1をTCPのエコーサーバー、ポート2をTCPのユーザークライアントだとします。
ポート1の通信設定->接続の項目:TCPサーバー、IPアドレス127.0.0.1は自分自身を指定、ポート番号を1024で起動します。
ポート2の通信設定->接続の項目:TCPクライアント、IPアドレス127.0.0.1は自分自身を指定、接続先ポート番号を1024で起動します。localポート番号を0にしておけば、適宜接続の度に適当なポート番号を割り当てるのでしょう。
ポート1の通信設定->動作の項目:5000ms以内にデータの受信が無い時は切断します。また、受信時動作は受信データをそのまま返します。
ポート2の通信設定->動作の項目:スクリプトで制御を行います。
スクリプト2のタブを開けばエディタが開き、スクリプトを編集できます。
標準の内容はそれぞれ発生したイベントに対する動作となっています。コメントはこちらで付けました。
今回はポート2の送信ボタンが押された時の動作、function OnSendPush()を使う訳ですが、送信データエディタ上の内容をそのまま送信するならこのままで大丈夫です。
※送信データエディタ上に何もデータが無ければ、送信動作は行われません。
エディタ上ではバイナリーデータですが、テキスト入力機能を使えばテキストを扱えます。
これで準備が整いました。まずポート1のTCPサーバーを通信開始ボタンをクリックして起動します。画面にSocket処理開始と表示されている筈です。IDが1なのはポート1を示しています。
ポート2のユーザーTCPクライアントを通信開始ボタンをクリックして起動します。画面上にID:2のイベントが複数表示されます。何もしなければ5秒後に向こうから切断されてしまいます。
もう一度ポート2の通信開始ボタンで起動し、そのボタンの右隣のデータ送信ボタンをクリックしてみます。
左上の画面で一連の送受信の様子や接続、切断処理が判ります。まずはこんな具合につこうてみて下さい。
成功しているようです。
こことか、 https://www.udom.co.jp/sdg/
こことか、 http://sdg.ex-group.jp/lua.html
をまず見てね!
ネットワークデバイスのデバックで最近利用を始めたSocketDebugger、無償版と有償版があります。
有償版に比較して無償版ではいくつかの機能が制限されますが、それでもとても有用なツールだと感じています。
特に、標準で備わっている機能だけでもデータの送受信を自動的に行うなどは容易に設定してできますが、Luaスクリプトを組むことでより詳細な動きを制御できます。
無償版は基本的な設定項目を保存することができませんが、Luaスクリプト自体はユーザーがエディタで作成し、保存、読み出しができますので、なるべくLuaスクリプトで処理をした方が同じようなデバックを何度も行うなら楽だと思います。
Lua?
ウイキペディア https://ja.wikipedia.org/wiki/Lua
参考にしているサイト
https://qiita.com/rohinomiya/items/abeb1d69c640a27d97c5
https://qiita.com/dwarfJP/items/e033728f5cbecbabe11f
http://amlaid.air-nifty.com/blog/2015/10/serial-debugger.html
https://qiita.com/satorimon/items/d65872659f7d6dc453fd
SocketDebuggerは2つのポート(ポート1とポート2)が同時に操作できますんで、わざわざターゲットを用意しなくてもSocketDebuggerだけでお試しやスクリプトの実行を行うことができます。
以下例ではポート1をTCPのエコーサーバー、ポート2をTCPのユーザークライアントだとします。
ポート1の通信設定->接続の項目:TCPサーバー、IPアドレス127.0.0.1は自分自身を指定、ポート番号を1024で起動します。
ポート2の通信設定->接続の項目:TCPクライアント、IPアドレス127.0.0.1は自分自身を指定、接続先ポート番号を1024で起動します。localポート番号を0にしておけば、適宜接続の度に適当なポート番号を割り当てるのでしょう。
ポート1の通信設定->動作の項目:5000ms以内にデータの受信が無い時は切断します。また、受信時動作は受信データをそのまま返します。
ポート2の通信設定->動作の項目:スクリプトで制御を行います。
スクリプト2のタブを開けばエディタが開き、スクリプトを編集できます。
標準の内容はそれぞれ発生したイベントに対する動作となっています。コメントはこちらで付けました。
--------------------------------------------- -- 接続完了通知 --------------------------------------------- function OnConnected() -- 相手先と接続すると呼ばれるハンドラ Logput(1,'OnConnected') -- 詳細ログデータ画面にメッセージを表示 return 0 end --------------------------------------------- -- 送信ボタン押下 --------------------------------------------- function OnSendPush() -- 送信ボタンをクリックすると呼ばれるハンドラ Logput(1,'OnSendPush') a = GetEditorData() -- 送信データエディタ上の内容を変数に代入 SendData(a) -- 変数の内容を送信 return 0 end --------------------------------------------- -- タイマー通知 --------------------------------------------- function OnTimer(id) -- タイマーで設定した時間に呼ばれるハンドラ Logput(1,'OnTimer') return 0 end --------------------------------------------- -- 受信通知 --------------------------------------------- function OnReceive(recv) -- 相手から受信した時に呼ばれるハンドラ、引数のテーブル(recv)に受信データが格納されている Logput(1,'OnReceive') return 0 end --------------------------------------------- -- 切断通知 --------------------------------------------- function OnDisConnected() -- 切断された時に呼ばれるハンドラ Logput(1,'OnDisConnected') return 0 end
今回はポート2の送信ボタンが押された時の動作、function OnSendPush()を使う訳ですが、送信データエディタ上の内容をそのまま送信するならこのままで大丈夫です。
※送信データエディタ上に何もデータが無ければ、送信動作は行われません。
エディタ上ではバイナリーデータですが、テキスト入力機能を使えばテキストを扱えます。
これで準備が整いました。まずポート1のTCPサーバーを通信開始ボタンをクリックして起動します。画面にSocket処理開始と表示されている筈です。IDが1なのはポート1を示しています。
ポート2のユーザーTCPクライアントを通信開始ボタンをクリックして起動します。画面上にID:2のイベントが複数表示されます。何もしなければ5秒後に向こうから切断されてしまいます。
もう一度ポート2の通信開始ボタンで起動し、そのボタンの右隣のデータ送信ボタンをクリックしてみます。
左上の画面で一連の送受信の様子や接続、切断処理が判ります。まずはこんな具合につこうてみて下さい。
成功しているようです。
M5Stick ミニ開発キットESP32 1.3'OLEDオプションのブザーIRトランスミッタMpu9250
- 出版社/メーカー: M5Stack
- メディア:
Wiznet W5500とGR-KURUMIで始めるお手軽ネットワーキング? [NETWORK]
Arduino互換?だよね、そのGR-KURUMIを搭載するネットワーク基板を作成してみました。多分Arduino Pro Miniでも同様に使える筈。
こんな感じでぐぐるのhtml文章をシリアルに出力できます。
/*GR-KURUMI Sketch Template Version: V1.04*/ #include <RLduino78.h> #include <SPI.h> #include <Ethernet.h> char server[] = "www.google.com"; // name address for Google (using DNS) // if you don't want to use DNS (and reduce your sketch size) // use the numeric IP instead of the name for the server: //IPAddress server(74,125,232,128); // numeric IP for Google (no DNS) IPAddress ip(192,168,100,177); byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; EthernetClient client; const int RSTn = 4; // LOW active // the setup routine runs once when you press reset: void setup() { // initialize the digital pin as an output. Serial.begin(9600); Serial.println("initialize w5500..."); pinMode(RSTn, OUTPUT); digitalWrite(RSTn, LOW); //w5500 reset start delay(10); digitalWrite(RSTn, HIGH); //w5500 reset end if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); // no point in carrying on, so do nothing forevermore: // try to congifure using IP address instead of DHCP: //Ethernet.begin(ip); Ethernet.begin(mac, ip); } delay(1000); Serial.println("connecting..."); // if you get a connection, report back via serial: if (client.connect(server, 80)) { Serial.println("connected"); // Make a HTTP request: client.println("GET /search?q=arduino HTTP/1.1"); client.println("Host: www.google.com"); client.println("Connection: close"); client.println(); } else { // if you didn't get a connection to the server: Serial.println("connection failed"); } } // the loop routine runs over and over again forever: void loop() { // if there are incoming bytes available // from the server, read them and print them: if (client.available()) { char c = client.read(); Serial.print(c); } // if the server's disconnected, stop the client: if (!client.connected()) { Serial.println(); Serial.println("disconnecting."); client.stop(); // do nothing forevermore: while(true); } }
ネットワークコントロールチップにはWiznetのW5500を採用。
かつてW5100とか使っていましたが、あれは熱かった(笑)。正常に動いているんだけれど物凄くその熱さに不安が、、、
ですがw5500はほんのり温かい程度で心理的に安心です(笑)。
多分w5200からだと思うけれどSPI廻りを刷新していて、データ転送の効率化が計られています。
GR-KURUMIにTCPのDISCARDのサーバーを仕立ててPC上のTera termから適当なファイルを転送した場合、120Kbyte/s程度で受信可能でした。
なかなか素晴らしいです。しかもw5500の受信バッファのチューニングをしたりせず、またネットワークは無線LANを有線に変換するコンバーター経由ですから。
w5500は今、ストロベリーリナックスさんから三百数十円で購入できますんで、みなさんもお試しを!。
ルネサスのH8/300H用コンパイラバージョン7でNavajoのプロジェクトを再構築 [NETWORK]
してみた。
netclock3と言うプロジェクトがそれ。
このリンク先から右クリックでローカルにダウンロードし、拡張子をjpgからzipに変更して使ってね。
それとは別にKPITのツールチェインを落として試しているのだけれど、まだちゃんと動かせていない。
netclock3と言うプロジェクトがそれ。
このリンク先から右クリックでローカルにダウンロードし、拡張子をjpgからzipに変更して使ってね。
それとは別にKPITのツールチェインを落として試しているのだけれど、まだちゃんと動かせていない。
ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発
- 作者: 濱原 和明
- 出版社/メーカー: オーム社
- 発売日: 2005/04/25
- メディア: 単行本
Arduino Webサーバーっぽい物の微妙な改修 [NETWORK]
このページでやった
http://hamayan.blog.so-net.ne.jp/2009-06-20
WEBサーバーアプリケーションをちょっと改修してみました。具体的には現在のArduino IDEのバージョンに合わせてコメントなどの日本語をUTFに変更しています。
組み込んでブラウザでアクセスするとちょびちゃんを見る事が出来ます。
このスケッチではオリジナルのライブラリにも修正が必要です。
オリジナルのEthernetライブラリには、ROM領域のデータを引っ張ってくるメソッドが無いので、以下のコードの追加が必要です。
またClient.hには上記メソッドをpublicに追加と、<avr/pgmspace.h>をインクルードしておきます。
このファイルをローカルにダウンロード後、拡張子をzipに変更してから解凍すると、今回のスケッチ一式が入手可能です。
http://hamayan.blog.so-net.ne.jp/2009-06-20
WEBサーバーアプリケーションをちょっと改修してみました。具体的には現在のArduino IDEのバージョンに合わせてコメントなどの日本語をUTFに変更しています。
組み込んでブラウザでアクセスするとちょびちゃんを見る事が出来ます。
このスケッチではオリジナルのライブラリにも修正が必要です。
オリジナルのEthernetライブラリには、ROM領域のデータを引っ張ってくるメソッドが無いので、以下のコードの追加が必要です。
/* this code was added by hamayan. */ #define TEMP_HEAP_SIZE 256 void Client::write_P( PGM_VOID_P buf, int size ) { uint8_t *temp = (uint8_t *)malloc( TEMP_HEAP_SIZE ); int sz; PGM_P ptr = (PGM_P)buf; for( ; size > 0; ) { sz = ( size < TEMP_HEAP_SIZE ) ? size : TEMP_HEAP_SIZE; memcpy_P( temp, ptr, sz ); send( _sock, (const uint8_t *)temp, sz ); size -= sz; ptr += sz; } free( temp ); }
またClient.hには上記メソッドをpublicに追加と、<avr/pgmspace.h>をインクルードしておきます。
#ifndef Client_h #define Client_h #include "Print.h" #include <avr/pgmspace.h> class Client : public Print { private: static uint16_t _srcport; uint8_t _sock; uint8_t *_ip; uint16_t _port; public: Client(uint8_t); Client(uint8_t *, uint16_t); uint8_t status(); uint8_t connect(); virtual void write(uint8_t); virtual void write(const char *str); virtual void write(const uint8_t *buf, size_t size); virtual void write_P( PGM_VOID_P buf, int size ); int available(); int read(); void flush(); void stop(); uint8_t connected(); uint8_t operator==(int); uint8_t operator!=(int); operator bool(); friend class Server; }; #endif
このファイルをローカルにダウンロード後、拡張子をzipに変更してから解凍すると、今回のスケッチ一式が入手可能です。
Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ
- 作者: 小林 茂
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/05/27
- メディア: 大型本
SX基板を大いに盛り上げるしがない電子工作団 活動日誌3 [NETWORK]
組み込みにWEBサーバーを実現する場合、一番考えられる用途が計測/制御を行わせると言ったものでしょう。わざわざ静的コンテンツをWEBコンテンツとして提供する理由はあまり無い。
と言う事は組み込みのコンテンツと言うのはイコール動的コンテンツを主に考える方がよさそうだ!と言うのが私の実感です。
計測の場面ですが、動的コンテンツとなるとサーバーサイドでプログラムが動いてくれる、つまりSSIの実装が必要です。
以下の図はW5300を使って作成したWEBサーバーの画面の一部です。
FORMタグとは別に例えば「サンプリング回数は2500000回に設定されています。」の”2500000”はSSIで生成しています。
html文章の中に以下の文字を埋め込む事で実際にはプログラムがその数字を生成しています。
<!--#SMPL_TIME-->
同様にゲインの数値、オフセット電圧、較正の有無、稼働時間、IPアドレス、バージョン番号、署名などもSSIとしてhtml文章に埋め込み、WEBサーバー内に作った構文解析プログラムにて該当するプログラムが実行されています。
サンプリング回数を出力するプログラムの実体は以下です。
おまけで作ったこんな物もあります(笑)。勿論55を表示します。
<!--#CALC 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10-->
こんな感じでしょうか。しばらくこの日誌はこの辺の実装について解説する事になりそうです。他にネタが無いですしね(笑)。
と言う事は組み込みのコンテンツと言うのはイコール動的コンテンツを主に考える方がよさそうだ!と言うのが私の実感です。
計測の場面ですが、動的コンテンツとなるとサーバーサイドでプログラムが動いてくれる、つまりSSIの実装が必要です。
以下の図はW5300を使って作成したWEBサーバーの画面の一部です。
FORMタグとは別に例えば「サンプリング回数は2500000回に設定されています。」の”2500000”はSSIで生成しています。
html文章の中に以下の文字を埋め込む事で実際にはプログラムがその数字を生成しています。
<!--#SMPL_TIME-->
同様にゲインの数値、オフセット電圧、較正の有無、稼働時間、IPアドレス、バージョン番号、署名などもSSIとしてhtml文章に埋め込み、WEBサーバー内に作った構文解析プログラムにて該当するプログラムが実行されています。
サンプリング回数を出力するプログラムの実体は以下です。
/*************************************************************************/ /* SSI実行:サンプリング時間の表示 */ /*************************************************************************/ static int ssi_smpl_time( int soc, int argc, char *argv[] ) { char buf[32]; itoa( buf, sample_time ); return W5300_Data_Write( soc, buf, strlen( buf ) ); }
おまけで作ったこんな物もあります(笑)。勿論55を表示します。
<!--#CALC 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10-->
/*************************************************************************/ /* SSI実行:引数の計算を行って表示 */ /*************************************************************************/ static int ssi_calc( int soc, int argc, char *argv[] ) { enum ENZAN_PATTERN { PULS, MINUS, MULTI, DIVID, MODULO }; int i,enzan; long temp; char buf[32],*ptr; if( argc < 4 ) return 0; for( i = 2, temp = atoi(argv[1]); i < argc; i++ ) { ptr = argv[i]; if( isdigit( *ptr ) && (i & 1) ) /*数字の時の処理。今の処理では数字は奇数番号で出現する*/ { if( enzan == PULS ) temp += atoi( argv[i] ); else if( enzan == MINUS ) temp -= atoi( argv[i] ); else if( enzan == MULTI ) temp *= atoi( argv[i] ); else if( enzan == DIVID ) temp /= atoi( argv[i] ); else if( enzan == MODULO ) temp %= atoi( argv[i] ); else {} } else { if( *ptr == '+' ) enzan = PULS; else if( *ptr == '-' ) enzan = MINUS; else if( *ptr == '*' ) enzan = MULTI; else if( *ptr == '/' ) enzan = DIVID; else if( *ptr == '%' ) enzan = MODULO; else break; } } itoa( buf, (int)temp ); return W5300_Data_Write( soc, buf, strlen( buf ) ); }
こんな感じでしょうか。しばらくこの日誌はこの辺の実装について解説する事になりそうです。他にネタが無いですしね(笑)。
SX基板を大いに盛り上げるしがない電子工作団 活動日誌2 [NETWORK]
前回の配線図を元に配線をちゃっちゃと終わらしたら、早速動かしてみましょう。
デバックは勿論この辺を参考にどうぞ。
http://hamayan.blog.so-net.ne.jp/2010-03-01
W5300に関係する処理を以下に記載します。
実は平行してSTM32Fでもやっていたりするので、2つのCPUに関する記載が有ったりします。
とりあえず低レベルのIO処理と、TCPソケットの実現までは書いてあります。
W5300_Initが完了するとpingを受け付けるようになります。
Cソース
ヘッダーファイル
デバックは勿論この辺を参考にどうぞ。
http://hamayan.blog.so-net.ne.jp/2010-03-01
W5300に関係する処理を以下に記載します。
実は平行してSTM32Fでもやっていたりするので、2つのCPUに関する記載が有ったりします。
とりあえず低レベルのIO処理と、TCPソケットの実現までは書いてあります。
W5300_Initが完了するとpingを受け付けるようになります。
Cソース
/***********************************************************************/ /* */ /* FILE :w5300.c */ /* DATE :Wed, Mar 03, 2010 */ /* DESCRIPTION :w5300 low level access driver Program */ /* CPU TYPE :H8SX/1658 */ /* CPU TYPE :STM32F103ZET */ /* */ /* This file is generated by Renesas Project Generator (Ver.4.16). */ /* */ /***********************************************************************/ #include <string.h> #include <ctype.h> #if !defined( __H8SXA__ ) #include "stm32f10x.h" #include "peripheral.h" #endif #include "strutil.h" #include "w5300.h" #include "timer.h" /*************************************************************************/ /* 端子定義 */ /* W5300の割込みはIRQ0-Bに接続 */ /*************************************************************************/ /*************************************************************************/ /* その他の定義 */ /*************************************************************************/ /*************************************************************************/ /* IOレジスタ定義 */ /*************************************************************************/ /*************************************************************************/ /* プロトタイプ宣言 */ /*************************************************************************/ static unsigned short w5300_read( unsigned short addr ); static void w5300_write( unsigned short addr, unsigned short data ); static void w5300_mac_write( const unsigned char *mac ); static void w5300_mac_read( unsigned char *mac ); static void w5300_gateway_write( const unsigned char *gateway ); static void w5300_gateway_read( unsigned char *gateway ); static void w5300_subnet_write( const unsigned char *subnet ); static void w5300_subnet_read( unsigned char *subnet ); static void w5300_sip_write( const unsigned char *sip ); static void w5300_sip_read( unsigned char *sip ); static void w5300_dmac_write( unsigned short adr, const unsigned char *dmac ); static void w5300_dmac_read( unsigned short adr, unsigned char *dmac ); static void w5300_dip_write( unsigned short adr, const unsigned char *dip ); static void w5300_dip_read( unsigned short adr, unsigned char *dip ); /*************************************************************************/ /* 大域変数宣言 */ /*************************************************************************/ static char first_snd[8]; /*************************************************************************/ /* W5300のポート及びそれ自身の初期化 */ /*************************************************************************/ int W5300_Init( void ) { // volatile unsigned char uc_buf[ 8 ]; volatile unsigned short temp; #if !defined( __H8SXA__ ) /*W5300_INT*/ GPIO_Terminal_Init( GPIOG, GPIO_Speed_2MHz, GPIO_Mode_IPU, GPIO_Pin_14 ); /*W5300_RST*/ GPIO_Terminal_Init( GPIOG, GPIO_Speed_2MHz, GPIO_Mode_Out_PP, GPIO_Pin_11 ); #endif #if !defined( __H8SXA__ ) /*デバイスリセット*/ W5300_RST_HI; W5300_RST_LO; WaitMs( 5 ); /*パルス幅としては2μs有れば良い*/ W5300_RST_HI; WaitMs( 10 ); /*立ち上がり後は10ms必要*/ #endif /*ソフトウエアリセット*/ temp = W5300_MR; #if defined( __H8SXA__ ) temp |= 0x0080; W5300_MR = temp; while( (temp = W5300_MR) & 0x0080 ); #else /*defined( __H8SXA__ )*/ temp |= 0x0080; W5300_MR = temp; while( (temp = W5300_MR) & 0x0080 ); #endif /*defined( __H8SXA__ )*/ /*MR設定*/ /*インダイレクトモードに設定*/ #if defined( __H8SXA__ ) temp |= 0x0001; /*これ以降、ビッグエンディアンでアクセスできる筈*/ temp &= ~0x3800; /*書き込み時のフェッチタイミング*/ temp |= 7 << 11; /*PLLは150M?(周期が6.67ns) 、CSアサートから6.67ns単位で調整?*/ W5300_MR = temp; /*実は長くても問題にならない?*/ #else /*defined( __H8SXA__ )*/ temp |= 0x0101; /*DBSとINDを立てている。これ以降、???エンディアンでアクセスできる筈*/ temp &= ~0x3800; /*書き込み時のフェッチタイミング*/ temp |= 7 << 11; /*PLLは150M?(周期が6.67ns) 、CSアサートから6.67ns単位で調整?*/ W5300_MR = temp; /*実は長くても問題にならない?*/ #endif /*defined( __H8SXA__ )*/ /*ID Registerの確認*/ temp = w5300_read( COMM_IDR ); if( temp != 0x5300 ) return (-1); /*正常に読み出せない時*/ /*IMR設定*/ w5300_write( COMM_IMR, 0x8000 | 0x4000 | 0x0000 ); /*IP衝突と相手先未到達位はサポートするか*/ /*mac addressの書き込み*/ w5300_mac_write( smac ); // w5300_mac_read( uc_buf ); /*ip addressの書き込み*/ w5300_sip_write( sip ); // w5300_sip_read( uc_buf ); /*sub net maskの書き込み*/ w5300_subnet_write( mask ); // w5300_subnet_read( uc_buf ); /*gatewayの書き込み*/ w5300_gateway_write( gateway ); // w5300_gateway_read( uc_buf ); /*RTR設定*/ w5300_write( COMM_RTR, 200 / 1 * 10 ); /*再送間隔の設定*/ /*RCR設定*/ w5300_write( COMM_RCR, 10 ); /*再送回数の設定*/ /*メモリ割付*/ w5300_write( COMM_MTYPER, 0x00ff ); /*取り敢えず送信と受信の振り分けは半々としてみる*/ /*ソケット別メモリ割付 TX*/ w5300_write( COMM_TMSR01, (8 << 8) | 8 ); /*socket0=8kbyte,socket1=8kbyte*/ w5300_write( COMM_TMSR23, (8 << 8) | 8 ); /*socket2=8kbyte,socket3=8kbyte*/ w5300_write( COMM_TMSR45, (8 << 8) | 8 ); /*socket4=8kbyte,socket5=8kbyte*/ w5300_write( COMM_TMSR67, (8 << 8) | 8 ); /*socket6=8kbyte,socket7=8kbyte*/ /*ソケット別メモリ割付 RX*/ w5300_write( COMM_RMSR01, (8 << 8) | 8 ); /*socket0=8kbyte,socket1=8kbyte*/ w5300_write( COMM_RMSR23, (8 << 8) | 8 ); /*socket2=8kbyte,socket3=8kbyte*/ w5300_write( COMM_RMSR45, (8 << 8) | 8 ); /*socket4=8kbyte,socket5=8kbyte*/ w5300_write( COMM_RMSR67, (8 << 8) | 8 ); /*socket6=8kbyte,socket7=8kbyte*/ return 0; } /*************************************************************************/ /* インダイレクトモードでW5300からの読み出し */ /*************************************************************************/ static unsigned short w5300_read( unsigned short addr ) { unsigned short data; IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = addr; data = IDM_DR; IINCHIP_CRITICAL_SECTION_EXIT(); return data; } /*************************************************************************/ /* インダイレクトモードでW5300からの書き込み */ /*************************************************************************/ static void w5300_write( unsigned short addr, unsigned short data ) { IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = addr; IDM_DR = data; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* ソースハードウエアアドレス(MACアドレス)の書き込み */ /*************************************************************************/ static void w5300_mac_write( const unsigned char *mac ) { IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = COMM_SHAR01; IDM_DR = (mac[0] << 8) | mac[1]; IDM_AR = COMM_SHAR23; IDM_DR = (mac[2] << 8) | mac[3]; IDM_AR = COMM_SHAR45; IDM_DR = (mac[4] << 8) | mac[5]; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* ソースハードウエアアドレス(MACアドレス)の読み込み */ /*************************************************************************/ static void w5300_mac_read( unsigned char *mac ) { unsigned short temp; IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = COMM_SHAR01; temp = IDM_DR; mac[0] = temp >> 8; mac[1] = temp; IDM_AR = COMM_SHAR23; temp = IDM_DR; mac[2] = temp >> 8; mac[3] = temp; IDM_AR = COMM_SHAR45; temp = IDM_DR; mac[4] = temp >> 8; mac[5] = temp; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* GATEWAY IP アドレスの書き込み */ /*************************************************************************/ static void w5300_gateway_write( const unsigned char *gw ) { IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = COMM_GAR01; IDM_DR = (gw[0] << 8) | gw[1]; IDM_AR = COMM_GAR23; IDM_DR = (gw[2] << 8) | gw[3]; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* GATEWAY IP アドレスの読み込み */ /*************************************************************************/ static void w5300_gateway_read( unsigned char *gw ) { unsigned short temp; IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = COMM_GAR01; temp = IDM_DR; gw[0] = temp >> 8; gw[1] = temp; IDM_AR = COMM_GAR23; temp = IDM_DR; gw[2] = temp >> 8; gw[3] = temp; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* サブネットマスクの書き込み */ /*************************************************************************/ static void w5300_subnet_write( const unsigned char *subnet ) { IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = COMM_SUBR01; IDM_DR = (subnet[0] << 8) | subnet[1]; IDM_AR = COMM_SUBR23; IDM_DR = (subnet[2] << 8) | subnet[3]; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* サブネットマスクの読み込み */ /*************************************************************************/ static void w5300_subnet_read( unsigned char *subnet ) { unsigned short temp; IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = COMM_SUBR01; temp = IDM_DR; subnet[0] = temp >> 8; subnet[1] = temp; IDM_AR = COMM_SUBR23; temp = IDM_DR; subnet[2] = temp >> 8; subnet[3] = temp; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* 送信元IPアドレスの書き込み */ /*************************************************************************/ static void w5300_sip_write( const unsigned char *ip ) { IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = COMM_SIPR01; IDM_DR = (ip[0] << 8) | ip[1]; IDM_AR = COMM_SIPR23; IDM_DR = (ip[2] << 8) | ip[3]; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* 送信元IPアドレスの読み込み */ /*************************************************************************/ static void w5300_sip_read( unsigned char *ip ) { unsigned short temp; IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = COMM_SIPR01; temp = IDM_DR; ip[0] = temp >> 8; ip[1] = temp; IDM_AR = COMM_SIPR23; temp = IDM_DR; ip[2] = temp >> 8; ip[3] = temp; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* ディスティネーションハードウエアアドレス(MACアドレス)の書き込み */ /* 注意!RAWレベルでの通信にしか使わない */ /*************************************************************************/ static void w5300_dmac_write( unsigned short adr, const unsigned char *dmac ) { IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = adr; adr += 2; IDM_DR = (dmac[0] << 8) | dmac[1]; IDM_AR = adr; adr += 2; IDM_DR = (dmac[2] << 8) | dmac[3]; IDM_AR = COMM_SHAR45; IDM_DR = (dmac[4] << 8) | dmac[5]; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* ディスティネーションハードウエアアドレス(MACアドレス)の読み込み */ /* 注意!RAWレベルでの通信にしか使わない */ /*************************************************************************/ static void w5300_dmac_read( unsigned short adr, unsigned char *dmac ) { unsigned short temp; IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = adr; adr += 2; temp = IDM_DR; dmac[0] = temp >> 8; dmac[1] = temp; IDM_AR = adr; adr += 2; temp = IDM_DR; dmac[2] = temp >> 8; dmac[3] = temp; IDM_AR = adr; temp = IDM_DR; dmac[4] = temp >> 8; dmac[5] = temp; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* 相手先IPアドレスの書き込み */ /*************************************************************************/ static void w5300_dip_write( unsigned short adr, const unsigned char *dip ) { IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = adr; adr += 2; IDM_DR = (dip[0] << 8) | dip[1]; IDM_AR = adr; IDM_DR = (dip[2] << 8) | dip[3]; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* 相手先IPアドレスの読み込み */ /*************************************************************************/ static void w5300_dip_read( unsigned short adr, unsigned char *dip ) { unsigned short temp; IINCHIP_CRITICAL_SECTION_ENTER(); IDM_AR = adr; adr += 2; temp = IDM_DR; dip[0] = temp >> 8; dip[1] = temp; IDM_AR = adr; temp = IDM_DR; dip[2] = temp >> 8; dip[3] = temp; IINCHIP_CRITICAL_SECTION_EXIT(); } /*************************************************************************/ /* W5300のソケットをOPENする。 */ /* 引数はソケット番号と自ポート番号。 */ /* 戻り値は成功すれば0、失敗で-1を返す。 */ /* ソケット番号は0からスタート */ /*************************************************************************/ int W5300_TCP_Open( int soc, unsigned short sport ) { static unsigned short ephemeral_port = 1024; /*ソケットがCLOSEDである事*/ if( (w5300_read( (soc * 0x40) + S0_SSR ) & 0x00ff) != SOCK_CLOSED ) return (-1); /*IMR再設定*/ w5300_write( COMM_IMR, w5300_read( COMM_IMR ) | (0x0001 << soc) ); /*ソケットモードレジスタの設定*/ w5300_write( (soc * 0x40) + S0_MR, 0x0020 | Sn_MR_TCP ); /*アライメント無し、マルチキャスト無し、即時ACK返し、TCP*/ /*自己ポート番号の設定*/ if( sport == 0 ) /*0番地の時はエフェメラルポートから割付を行う*/ { IINCHIP_CRITICAL_SECTION_ENTER(); sport = ephemeral_port; if( ++ephemeral_port > 5000 ) ephemeral_port = 1024; IINCHIP_CRITICAL_SECTION_EXIT(); } w5300_write( (soc * 0x40) + S0_PORTR, sport ); /*0番の時はBINDしない*/ /*OPEN*/ w5300_write( (soc * 0x40) + S0_CR, CMD_OPEN ); /**/ WaitMs( 1 ); /*ソケットがINITとなった事を確認*/ if( (w5300_read( (soc * 0x40) + S0_SSR ) & 0x00ff) != SOCK_INIT ) { w5300_write( (soc * 0x40) + S0_CR, CMD_CLOSE ); /*ソケットを閉じてから終了*/ w5300_write( (soc * 0x40) + S0_IMR, 0x0000 ); /*割込みの禁止*/ w5300_write( COMM_IMR, w5300_read( COMM_IMR ) & ~(0x0001 << soc) ); /*割込みも解除*/ return (-1); } w5300_write( (soc * 0x40) + S0_IMR, 0x001f ); /*割込みの許可*/ return 0; } /*************************************************************************/ /* W5300のソケットをLISTENする。 */ /* 戻り値は成功すれば0、失敗で-1を返す。 */ /*************************************************************************/ int W5300_TCP_Listen( int soc ) { /*ソケットがINITである事*/ if( (w5300_read( (soc * 0x40) + S0_SSR ) & 0x00ff) != SOCK_INIT ) return (-1); /*LISTEN*/ w5300_write( (soc * 0x40) + S0_CR, CMD_LISTEN ); /**/ WaitMs( 1 ); /*ソケットがLISTENとなった事を確認*/ if( (w5300_read( (soc * 0x40) + S0_SSR ) & 0x00ff) != SOCK_LISTEN ) { w5300_write( (soc * 0x40) + S0_CR, CMD_CLOSE ); /*ソケットを閉じてから終了*/ w5300_write( (soc * 0x40) + S0_IMR, 0x0000 ); /*割込みの禁止*/ w5300_write( COMM_IMR, w5300_read( COMM_IMR ) & ~(0x0001 << soc) ); /*割込みも解除*/ return (-1); } return 0; } /*************************************************************************/ /* W5300のソケットをCLOSEする。 */ /* 引数はソケット番号。 */ /*************************************************************************/ void W5300_TCP_Close( int soc ) { unsigned short temp; temp = w5300_read( (soc * 0x40) + S0_SSR ) & 0x00ff; /*ソケットがCLOSEDならそのまま終了*/ if( temp == SOCK_CLOSED ) return; else if( temp == SOCK_ESTABLISHED ) { w5300_write( (soc * 0x40) + S0_CR, CMD_DISCON ); /**/ } else if( temp == SOCK_INIT || temp == SOCK_LISTEN ) { w5300_write( (soc * 0x40) + S0_CR, CMD_CLOSE ); /**/ } else if( temp == SOCK_CLOSE_WAIT || temp == SOCK_FIN_WAIT || temp == SOCK_TIME_WAIT || temp == SOCK_LAST_ACK ) {} else return; do { temp = w5300_read( (soc * 0x40) + S0_SSR ) & 0x00ff; } while( temp != SOCK_CLOSED ) ; /*割込み解除*/ w5300_write( (soc * 0x40) + S0_IMR, 0x0000 ); /*割込みの禁止*/ w5300_write( COMM_IMR, w5300_read( COMM_IMR ) & ~(0x0001 << soc) ); } /*************************************************************************/ /* W5300のESTABLISHEDチェック */ /*************************************************************************/ int W5300_TCP_Check_Established( int soc ) { volatile unsigned short temp; if( (temp = w5300_read( (soc * 0x40) + S0_IR )) & 0x0001 ) /*Sn_IRのCONをチェックする*/ { w5300_write( (soc * 0x40) + S0_IR, 0x0001 ); return 0; } return (-1); } /*************************************************************************/ /* W5300のソケットをESTABLISHED待ち */ /*************************************************************************/ void W5300_TCP_Wait_Established( int soc ) { while( W5300_TCP_Check_Established( soc ) != 0 ) {} } /*************************************************************************/ /* W5300のデータ受信確認 */ /* 受信が有れば0以外の値を返す。 */ /*************************************************************************/ int W5300_Rcv_Data_Available( int soc ) { if( w5300_read( (soc * 0x40) + S0_IR ) & 0x0004 ) { w5300_write( (soc * 0x40) + S0_IR, 0x0004 ); return 1; } return 0; } /*************************************************************************/ /* W5300のデータ受信 */ /* 格納用のバッファと、そのバッファのサイズを引数に取る。 */ /* 戻り値は取得したデータのサイズ */ /*************************************************************************/ int W5300_Data_Read( int soc, void *buf, unsigned long buf_sz ) { unsigned short *ptr; unsigned long packet_size,rcv_cnt; if( w5300_read( (soc * 0x40) + S0_MR ) & 0x0100 ) /*アライメントが必要*/ { packet_size = w5300_read( (soc * 0x40) + S0_RX_RSR ) & 0x0001; packet_size = (packet_size << 16) | w5300_read( (soc * 0x40) + S0_RX_RSR2 ); } else /*アライメントは必要とされない*/ { packet_size = w5300_read( (soc * 0x40) + S0_RX_FIFOR ); } /*バッファの上限以上は取らない*/ if( packet_size > buf_sz ) packet_size = buf_sz; /*受信サイズが奇数の場合は1byteパディングして読み込む*/ rcv_cnt = (packet_size & 1) ? (packet_size + 1) / 2 : packet_size / 2; /*受信FIFOのアドレスを設定*/ IDM_AR = (soc * 0x40) + S0_RX_FIFOR; /*受信FIFOからデータを取得*/ for( ptr = (unsigned short *)buf; rcv_cnt > 0; rcv_cnt-- ) { *ptr++ = IDM_DR; } /*受信完了した事を伝える*/ w5300_write( (soc * 0x40) + S0_CR, CMD_RECV ); return packet_size; } /*************************************************************************/ /* W5300のデータ送信 */ /* 格納元のバッファと、送信サイズを引数に取る。 */ /* 戻り値は実際に書けたデータのサイズ */ /*************************************************************************/ int W5300_Data_Write( int soc, const void *buf, unsigned long snd_sz ) { unsigned short temp; unsigned long wrt_cnt,free_size; #if defined( __H8SXA__ ) const unsigned char *bptr; #endif /*defined( __H8SXA__ )*/ const unsigned short *ptr; do { /*送信バッファの空きを調べる*/ free_size = w5300_read( (soc * 0x40) + S0_TX_FSR ) & 0x0001; free_size = (free_size << 16) | w5300_read( (soc * 0x40) + S0_TX_FSR2 ); /*ESTABLISHEDまたはCLOSE_WAITである事の確認*/ temp = w5300_read( (soc * 0x40) + S0_SSR ) & 0x00ff; if( temp != SOCK_ESTABLISHED && temp != SOCK_CLOSE_WAIT ) { w5300_write( (soc * 0x40) + S0_CR, CMD_CLOSE ); /*ソケットを閉じてから終了*/ w5300_write( (soc * 0x40) + S0_IMR, 0x0000 ); /*割込みの禁止*/ w5300_write( COMM_IMR, w5300_read( COMM_IMR ) & ~(0x0001 << soc) ); /*割込みも解除*/ return (-1); } } while( free_size < snd_sz ) ; /*送信サイズが奇数の場合は1byteパディングして書き込む*/ wrt_cnt = (snd_sz & 1) ? (snd_sz + 1) / 2 : snd_sz / 2; /*送信FIFOのアドレスを設定*/ IDM_AR = (soc * 0x40) + S0_TX_FIFOR; #if defined( __H8SXA__ ) /*送信FIFOにデータを転送。但し奇数から書いてしまう事も想定が必要*/ if( (unsigned long)buf & 1 ) /*奇数*/ { for( bptr = (const unsigned char *)buf; wrt_cnt > 0; wrt_cnt-- ) { temp = *bptr++ << 8; temp |= *bptr++; IDM_DR = temp; } } else /*偶数*/ { for( ptr = (const unsigned short *)buf; wrt_cnt > 0; wrt_cnt-- ) { IDM_DR = *ptr++; } } #else /*defined( __H8SXA__ )*/ for( ptr = (const unsigned short *)buf; wrt_cnt > 0; wrt_cnt-- ) { IDM_DR = *ptr++; } #endif /*defined( __H8SXA__ )*/ /*前回の送信が完了していない時は送信処理に入れない*/ if( first_snd[soc] == 0 ) first_snd[soc]++; else { while( (w5300_read( (soc * 0x40) + S0_IR ) & 0x0010) == 0 ) { if( (w5300_read( (soc * 0x40) + S0_SSR ) & 0x00ff) == SOCK_CLOSED ) { /*この隙にソケットクローズとなってしまった場合*/ return 0; } } } /*送信サイズを書き込む*/ w5300_write( (soc * 0x40) + S0_TX_WRSR, snd_sz >> 16 ); w5300_write( (soc * 0x40) + S0_TX_WRSR2, snd_sz ); /*送信実行*/ w5300_write( (soc * 0x40) + S0_CR, CMD_SEND ); return snd_sz; } /*********************************************************************************/ /* end of file */ /* designed by hamayan since 2009/05/21 */ /*********************************************************************************/
ヘッダーファイル
/***********************************************************************/ /* */ /* FILE :w5300.h */ /* DATE :Wed, Mar 03, 2010 */ /* DESCRIPTION :Main Program */ /* CPU TYPE :H8SX/1658 */ /* CPU TYPE :STM32F103ZET */ /* */ /* This file is generated by Renesas Project Generator (Ver.4.16). */ /* */ /***********************************************************************/ /*************************************************************************/ /* 端子定義 */ /* W5300の割込みはIRQ0-Bに接続 */ /*************************************************************************/ #if !defined( __H8SXA__ ) #define W5300_RESET GPIO_Pin_11 /*W5300のリセット。アクティブLO*/ #define W5300_RST_LO GPIOG->BSRR = (W5300_RESET << 16) #define W5300_RST_HI GPIOG->BSRR = (W5300_RESET) #endif /*************************************************************************/ /* その他の定義 */ /*************************************************************************/ #define IINCHIP_CRITICAL_SECTION_ENTER() #define IINCHIP_CRITICAL_SECTION_EXIT() #define Sn_MR_CLOSE 0 #define Sn_MR_TCP 1 #define Sn_MR_UDP 2 #define Sn_MR_IPRAW 3 #define S0_MR_MACRAW 4 #define S0_MR_PPPoE 5 #define CMD_OPEN 0x01 #define CMD_LISTEN 0x02 #define CMD_DISCON 0x08 #define CMD_CLOSE 0x10 #define CMD_SEND 0x20 #define CMD_SEND_MAC 0x21 #define CMD_SEND_KEEP 0x22 #define CMD_RECV 0x40 #define CMD_PCON 0x23 #define CMD_PDISCON 0x24 #define CMD_PCR 0x25 #define CMD_PCN 0x26 #define CMD_PCJ 0x27 #define SOCK_CLOSED 0x00 #define SOCK_INIT 0x13 #define SOCK_LISTEN 0x14 #define SOCK_ESTABLISHED 0x17 #define SOCK_CLOSE_WAIT 0x1c #define SOCK_UDP 0x22 #define SOCK_IPRAW 0x32 #define SOCK_MACRAW 0x42 #define SOCK_PPPoE 0x5f #define SOCK_SYNSENT 0x15 #define SOCK_SYNRECV 0x16 #define SOCK_FIN_WAIT 0x18 #define SOCK_TIME_WAIT 0x1b #define SOCK_LAST_ACK 0x1d #define SOCK_ARP 0x01 /*************************************************************************/ /* IOレジスタ定義 */ /*************************************************************************/ #if defined( __H8SXA__ ) #define W5300_BASE_ADR 0x100000 #else /*defined( __H8SXA__ )*/ #define W5300_BASE_ADR 0x64000000 #endif /*************************************************************************/ /* インダイレクトレジスタ関連定義 */ /*************************************************************************/ #if defined( __H8SXA__ ) #define W5300_MR *(volatile unsigned short *)(W5300_BASE_ADR + 0x00) #define IDM_AR *(volatile unsigned short *)(W5300_BASE_ADR + 0x02) #define IDM_DR *(volatile unsigned short *)(W5300_BASE_ADR + 0x04) #else /*defined( __H8SXA__ )*/ #define W5300_MR *(volatile unsigned short *)(W5300_BASE_ADR + 0x00) #define IDM_AR *(volatile unsigned short *)(W5300_BASE_ADR + 0x04) #define IDM_DR *(volatile unsigned short *)(W5300_BASE_ADR + 0x08) #endif /*************************************************************************/ /* COMMON レジスタ関連定義 */ /*************************************************************************/ #define COMM_IR 0x0002 /*Interrupt Register*/ #define COMM_IMR 0x0004 /*Interrupt Mask Register*/ #define COMM_SHAR01 0x0008 /*Source Hardware Address Register*/ #define COMM_SHAR23 0x000a /*Source Hardware Address Register*/ #define COMM_SHAR45 0x000c /*Source Hardware Address Register*/ #define COMM_GAR01 0x0010 /*Gateway IP Address Register*/ #define COMM_GAR23 0x0012 /*Gateway IP Address Register*/ #define COMM_SUBR01 0x0014 /*Subnet Mask IP Address Register*/ #define COMM_SUBR23 0x0016 /*Subnet Mask IP Address Register*/ #define COMM_SIPR01 0x0018 /*Source IP Address Register*/ #define COMM_SIPR23 0x001a /*Source IP Address Register*/ #define COMM_RTR 0x001c /*Retransmission Time-out Period Register*/ #define COMM_RCR 0x001e /*Retransmission Retry-count Register*/ #define COMM_TMSR01 0x0020 /*TX Memory Size Register*/ #define COMM_TMSR23 0x0022 /*TX Memory Size Register*/ #define COMM_TMSR45 0x0024 /*TX Memory Size Register*/ #define COMM_TMSR67 0x0026 /*TX Memory Size Register*/ #define COMM_RMSR01 0x0028 /*RX Memory Size Register*/ #define COMM_RMSR23 0x002a /*RX Memory Size Register*/ #define COMM_RMSR45 0x002c /*RX Memory Size Register*/ #define COMM_RMSR67 0x002e /*RX Memory Size Register*/ #define COMM_MTYPER 0x0030 /*Memory Type Register*/ #define COMM_PATR 0x0032 /*PPPoE Authentication Type Register*/ #define COMM_PTIMER 0x0036 /*PPP Link Control Request Timer Register*/ #define COMM_PMAGICR 0x0038 /*PPP LCP Magic Number Register*/ #define COMM_PSIDR 0x003c /*PPPoE Session ID Register*/ #define COMM_PDHAR01 0x0040 /*PPPoE Destination Hardware Address Register*/ #define COMM_PDHAR23 0x0042 /*PPPoE Destination Hardware Address Register*/ #define COMM_PDHAR45 0x0044 /*PPPoE Destination Hardware Address Register*/ #define COMM_UIPR01 0x0048 /*Unreachable IP Address Register*/ #define COMM_UIPR23 0x004a /*Unreachable IP Address Register*/ #define COMM_UPORT 0x004c /*Unreachable Port Number Register*/ #define COMM_FMTUR 0x004e /*Fragment MTU Register*/ #define COMM_P0_BRDYR 0x0060 /*BRDY0 Configure Register*/ #define COMM_P1_BRDYR 0x0064 /*BRDY1 Configure Register*/ #define COMM_P2_BRDYR 0x0068 /*BRDY2 Configure Register*/ #define COMM_P3_BRDYR 0x006c /*BRDY3 Configure Register*/ #define COMM_P0_BDPTHR 0x0062 /*PIN BRDY0 Buffer Depth Register*/ #define COMM_P1_BDPTHR 0x0066 /*PIN BRDY1 Buffer Depth Register*/ #define COMM_P2_BDPTHR 0x006a /*PIN BRDY2 Buffer Depth Register*/ #define COMM_P3_BDPTHR 0x006e /*PIN BRDY3 Buffer Depth Register*/ #define COMM_IDR 0x00fe /*Identification Register*/ /*************************************************************************/ /* ソケットレジスタ関連定義 */ /*************************************************************************/ #define S0_BASE_ADR 0x0200 #define S0_MR (S0_BASE_ADR + 0x0000) #define S0_CR (S0_BASE_ADR + 0x0002) #define S0_IMR (S0_BASE_ADR + 0x0004) #define S0_IR (S0_BASE_ADR + 0x0006) #define S0_SSR (S0_BASE_ADR + 0x0008) #define S0_PORTR (S0_BASE_ADR + 0x000a) #define S0_DHAR01 (S0_BASE_ADR + 0x000c) #define S0_DHAR23 (S0_BASE_ADR + 0x000e) #define S0_DHAR45 (S0_BASE_ADR + 0x0010) #define S0_DPORT (S0_BASE_ADR + 0x0012) #define S0_DIPR01 (S0_BASE_ADR + 0x0014) #define S0_DIPR23 (S0_BASE_ADR + 0x0016) #define S0_MSSR (S0_BASE_ADR + 0x0018) #define S0_PORTOR (S0_BASE_ADR + 0x001a) #define S0_TOSR (S0_BASE_ADR + 0x001c) #define S0_TTLR (S0_BASE_ADR + 0x001e) #define S0_TX_WRSR (S0_BASE_ADR + 0x0020) #define S0_TX_WRSR2 (S0_BASE_ADR + 0x0022) #define S0_TX_FSR (S0_BASE_ADR + 0x0024) #define S0_TX_FSR2 (S0_BASE_ADR + 0x0026) #define S0_RX_RSR (S0_BASE_ADR + 0x0028) #define S0_RX_RSR2 (S0_BASE_ADR + 0x002a) #define S0_FRAGR (S0_BASE_ADR + 0x002c) #define S0_TX_FIFOR (S0_BASE_ADR + 0x002e) #define S0_RX_FIFOR (S0_BASE_ADR + 0x0030) #define S1_BASE_ADR 0x0240 #define S1_MR (S1_BASE_ADR + 0x0000) #define S1_CR (S1_BASE_ADR + 0x0002) #define S1_IMR (S1_BASE_ADR + 0x0004) #define S1_IR (S1_BASE_ADR + 0x0006) #define S1_SSR (S1_BASE_ADR + 0x0008) #define S1_PORTR (S1_BASE_ADR + 0x000a) #define S1_DHAR01 (S1_BASE_ADR + 0x000c) #define S1_DHAR23 (S1_BASE_ADR + 0x000e) #define S1_DHAR45 (S1_BASE_ADR + 0x0010) #define S1_DPORT (S1_BASE_ADR + 0x0012) #define S1_DIPR01 (S1_BASE_ADR + 0x0014) #define S1_DIPR23 (S1_BASE_ADR + 0x0016) #define S1_MSSR (S1_BASE_ADR + 0x0018) #define S1_PORTOR (S1_BASE_ADR + 0x001a) #define S1_TOSR (S1_BASE_ADR + 0x001c) #define S1_TTLR (S1_BASE_ADR + 0x001e) #define S1_TX_WRSR (S1_BASE_ADR + 0x0020) #define S1_TX_WRSR2 (S1_BASE_ADR + 0x0022) #define S1_TX_FSR (S1_BASE_ADR + 0x0024) #define S1_TX_FSR2 (S1_BASE_ADR + 0x0026) #define S1_RX_RSR (S1_BASE_ADR + 0x0028) #define S1_RX_RSR2 (S1_BASE_ADR + 0x002a) #define S1_FRAGR (S1_BASE_ADR + 0x002c) #define S1_TX_FIFOR (S1_BASE_ADR + 0x002e) #define S1_RX_FIFOR (S1_BASE_ADR + 0x0030) #define S2_BASE_ADR 0x0280 #define S2_MR (S2_BASE_ADR + 0x0000) #define S2_CR (S2_BASE_ADR + 0x0002) #define S2_IMR (S2_BASE_ADR + 0x0004) #define S2_IR (S2_BASE_ADR + 0x0006) #define S2_SSR (S2_BASE_ADR + 0x0008) #define S2_PORTR (S2_BASE_ADR + 0x000a) #define S2_DHAR01 (S2_BASE_ADR + 0x000c) #define S2_DHAR23 (S2_BASE_ADR + 0x000e) #define S2_DHAR45 (S2_BASE_ADR + 0x0010) #define S2_DPORT (S2_BASE_ADR + 0x0012) #define S2_DIPR01 (S2_BASE_ADR + 0x0014) #define S2_DIPR23 (S2_BASE_ADR + 0x0016) #define S2_MSSR (S2_BASE_ADR + 0x0018) #define S2_PORTOR (S2_BASE_ADR + 0x001a) #define S2_TOSR (S2_BASE_ADR + 0x001c) #define S2_TTLR (S2_BASE_ADR + 0x001e) #define S2_TX_WRSR (S2_BASE_ADR + 0x0020) #define S2_TX_WRSR2 (S2_BASE_ADR + 0x0022) #define S2_TX_FSR (S2_BASE_ADR + 0x0024) #define S2_TX_FSR2 (S2_BASE_ADR + 0x0026) #define S2_RX_RSR (S2_BASE_ADR + 0x0028) #define S2_RX_RSR2 (S2_BASE_ADR + 0x002a) #define S2_FRAGR (S2_BASE_ADR + 0x002c) #define S2_TX_FIFOR (S2_BASE_ADR + 0x002e) #define S2_RX_FIFOR (S2_BASE_ADR + 0x0030) #define S3_BASE_ADR 0x02c0 #define S3_MR (S3_BASE_ADR + 0x0000) #define S3_CR (S3_BASE_ADR + 0x0002) #define S3_IMR (S3_BASE_ADR + 0x0004) #define S3_IR (S3_BASE_ADR + 0x0006) #define S3_SSR (S3_BASE_ADR + 0x0008) #define S3_PORTR (S3_BASE_ADR + 0x000a) #define S3_DHAR01 (S3_BASE_ADR + 0x000c) #define S3_DHAR23 (S3_BASE_ADR + 0x000e) #define S3_DHAR45 (S3_BASE_ADR + 0x0010) #define S3_DPORT (S3_BASE_ADR + 0x0012) #define S3_DIPR01 (S3_BASE_ADR + 0x0014) #define S3_DIPR23 (S3_BASE_ADR + 0x0016) #define S3_MSSR (S3_BASE_ADR + 0x0018) #define S3_PORTOR (S3_BASE_ADR + 0x001a) #define S3_TOSR (S3_BASE_ADR + 0x001c) #define S3_TTLR (S3_BASE_ADR + 0x001e) #define S3_TX_WRSR (S3_BASE_ADR + 0x0020) #define S3_TX_WRSR2 (S3_BASE_ADR + 0x0022) #define S3_TX_FSR (S3_BASE_ADR + 0x0024) #define S3_TX_FSR2 (S3_BASE_ADR + 0x0026) #define S3_RX_RSR (S3_BASE_ADR + 0x0028) #define S3_RX_RSR2 (S3_BASE_ADR + 0x002a) #define S3_FRAGR (S3_BASE_ADR + 0x002c) #define S3_TX_FIFOR (S3_BASE_ADR + 0x002e) #define S3_RX_FIFOR (S3_BASE_ADR + 0x0030) #define S4_BASE_ADR 0x0300 #define S4_MR (S4_BASE_ADR + 0x0000) #define S4_CR (S4_BASE_ADR + 0x0002) #define S4_IMR (S4_BASE_ADR + 0x0004) #define S4_IR (S4_BASE_ADR + 0x0006) #define S4_SSR (S4_BASE_ADR + 0x0008) #define S4_PORTR (S4_BASE_ADR + 0x000a) #define S4_DHAR01 (S4_BASE_ADR + 0x000c) #define S4_DHAR23 (S4_BASE_ADR + 0x000e) #define S4_DHAR45 (S4_BASE_ADR + 0x0010) #define S4_DPORT (S4_BASE_ADR + 0x0012) #define S4_DIPR01 (S4_BASE_ADR + 0x0014) #define S4_DIPR23 (S4_BASE_ADR + 0x0016) #define S4_MSSR (S4_BASE_ADR + 0x0018) #define S4_PORTOR (S4_BASE_ADR + 0x001a) #define S4_TOSR (S4_BASE_ADR + 0x001c) #define S4_TTLR (S4_BASE_ADR + 0x001e) #define S4_TX_WRSR (S4_BASE_ADR + 0x0020) #define S4_TX_WRSR2 (S4_BASE_ADR + 0x0022) #define S4_TX_FSR (S4_BASE_ADR + 0x0024) #define S4_TX_FSR2 (S4_BASE_ADR + 0x0026) #define S4_RX_RSR (S4_BASE_ADR + 0x0028) #define S4_RX_RSR2 (S4_BASE_ADR + 0x002a) #define S4_FRAGR (S4_BASE_ADR + 0x002c) #define S4_TX_FIFOR (S4_BASE_ADR + 0x002e) #define S4_RX_FIFOR (S4_BASE_ADR + 0x0030) #define S5_BASE_ADR 0x0340 #define S5_MR (S5_BASE_ADR + 0x0000) #define S5_CR (S5_BASE_ADR + 0x0002) #define S5_IMR (S5_BASE_ADR + 0x0004) #define S5_IR (S5_BASE_ADR + 0x0006) #define S5_SSR (S5_BASE_ADR + 0x0008) #define S5_PORTR (S5_BASE_ADR + 0x000a) #define S5_DHAR01 (S5_BASE_ADR + 0x000c) #define S5_DHAR23 (S5_BASE_ADR + 0x000e) #define S5_DHAR45 (S5_BASE_ADR + 0x0010) #define S5_DPORT (S5_BASE_ADR + 0x0012) #define S5_DIPR01 (S5_BASE_ADR + 0x0014) #define S5_DIPR23 (S5_BASE_ADR + 0x0016) #define S5_MSSR (S5_BASE_ADR + 0x0018) #define S5_PORTOR (S5_BASE_ADR + 0x001a) #define S5_TOSR (S5_BASE_ADR + 0x001c) #define S5_TTLR (S5_BASE_ADR + 0x001e) #define S5_TX_WRSR (S5_BASE_ADR + 0x0020) #define S5_TX_WRSR2 (S5_BASE_ADR + 0x0022) #define S5_TX_FSR (S5_BASE_ADR + 0x0024) #define S5_TX_FSR2 (S5_BASE_ADR + 0x0026) #define S5_RX_RSR (S5_BASE_ADR + 0x0028) #define S5_RX_RSR2 (S5_BASE_ADR + 0x002a) #define S5_FRAGR (S5_BASE_ADR + 0x002c) #define S5_TX_FIFOR (S5_BASE_ADR + 0x002e) #define S5_RX_FIFOR (S5_BASE_ADR + 0x0030) #define S6_BASE_ADR 0x0380 #define S6_MR (S6_BASE_ADR + 0x0000) #define S6_CR (S6_BASE_ADR + 0x0002) #define S6_IMR (S6_BASE_ADR + 0x0004) #define S6_IR (S6_BASE_ADR + 0x0006) #define S6_SSR (S6_BASE_ADR + 0x0008) #define S6_PORTR (S6_BASE_ADR + 0x000a) #define S6_DHAR01 (S6_BASE_ADR + 0x000c) #define S6_DHAR23 (S6_BASE_ADR + 0x000e) #define S6_DHAR45 (S6_BASE_ADR + 0x0010) #define S6_DPORT (S6_BASE_ADR + 0x0012) #define S6_DIPR01 (S6_BASE_ADR + 0x0014) #define S6_DIPR23 (S6_BASE_ADR + 0x0016) #define S6_MSSR (S6_BASE_ADR + 0x0018) #define S6_PORTOR (S6_BASE_ADR + 0x001a) #define S6_TOSR (S6_BASE_ADR + 0x001c) #define S6_TTLR (S6_BASE_ADR + 0x001e) #define S6_TX_WRSR (S6_BASE_ADR + 0x0020) #define S6_TX_WRSR2 (S6_BASE_ADR + 0x0022) #define S6_TX_FSR (S6_BASE_ADR + 0x0024) #define S6_TX_FSR2 (S6_BASE_ADR + 0x0026) #define S6_RX_RSR (S6_BASE_ADR + 0x0028) #define S6_RX_RSR2 (S6_BASE_ADR + 0x002a) #define S6_FRAGR (S6_BASE_ADR + 0x002c) #define S6_TX_FIFOR (S6_BASE_ADR + 0x002e) #define S6_RX_FIFOR (S6_BASE_ADR + 0x0030) #define S7_BASE_ADR 0x03c0 #define S7_MR (S7_BASE_ADR + 0x0000) #define S7_CR (S7_BASE_ADR + 0x0002) #define S7_IMR (S7_BASE_ADR + 0x0004) #define S7_IR (S7_BASE_ADR + 0x0006) #define S7_SSR (S7_BASE_ADR + 0x0008) #define S7_PORTR (S7_BASE_ADR + 0x000a) #define S7_DHAR01 (S7_BASE_ADR + 0x000c) #define S7_DHAR23 (S7_BASE_ADR + 0x000e) #define S7_DHAR45 (S7_BASE_ADR + 0x0010) #define S7_DPORT (S7_BASE_ADR + 0x0012) #define S7_DIPR01 (S7_BASE_ADR + 0x0014) #define S7_DIPR23 (S7_BASE_ADR + 0x0016) #define S7_MSSR (S7_BASE_ADR + 0x0018) #define S7_PORTOR (S7_BASE_ADR + 0x001a) #define S7_TOSR (S7_BASE_ADR + 0x001c) #define S7_TTLR (S7_BASE_ADR + 0x001e) #define S7_TX_WRSR (S7_BASE_ADR + 0x0020) #define S7_TX_WRSR2 (S7_BASE_ADR + 0x0022) #define S7_TX_FSR (S7_BASE_ADR + 0x0024) #define S7_TX_FSR2 (S7_BASE_ADR + 0x0026) #define S7_RX_RSR (S7_BASE_ADR + 0x0028) #define S7_RX_RSR2 (S7_BASE_ADR + 0x002a) #define S7_FRAGR (S7_BASE_ADR + 0x002c) #define S7_TX_FIFOR (S7_BASE_ADR + 0x002e) #define S7_RX_FIFOR (S7_BASE_ADR + 0x0030) /*************************************************************************/ /* プロトタイプ宣言 */ /*************************************************************************/ int W5300_Init( void ); int W5300_TCP_Open( int soc, unsigned short sport ); int W5300_TCP_Listen( int soc ); void W5300_TCP_Close( int soc ); int W5300_TCP_Check_Established( int soc ); void W5300_TCP_Wait_Established( int soc ); int W5300_Rcv_Data_Available( int soc ); int W5300_Data_Read( int soc, void *buf, unsigned long buf_sz ); int W5300_Data_Write( int soc, const void *buf, unsigned long snd_sz ); /*************************************************************************/ /* 大域変数宣言 */ /*************************************************************************/ extern const unsigned char smac[]; /*自己mac address*/ extern const unsigned char sip[]; /*自己ip address*/ extern const unsigned char mask[]; /*sub net mask*/ extern const unsigned char gateway[]; /*gateway ip address*/ /*********************************************************************************/ /* end of file */ /* designed by hamayan since 2009/05/21 */ /*********************************************************************************/
SX基板を大いに盛り上げるしがない電子工作団 [NETWORK]
やはり団員1号なので。消失は観てきました。面白かったです。
さて、何故かWiznetのW5300を搭載したWIZ830MJが有ったので、H8/SX基板との間にびよーんと配線を飛ばしてお気楽に実験です。
配線図を掲載して置きます。30本位飛ばす事になりますが、まあ作業時間は1~2時間と言ったところでしょう。べらぼうに大変でもないです。
W5300の使い方は16bitバス、インダイレクトモードです。なのでアドレス線はA1とA2のみの使用となります。
インダイレクトモードとダイレクトモードではパフォーマンスに差は殆ど出ないでしょう。肝心のデータ転送に付いて言えば1アドレスに対してのみ行うので、インダイレクトモードでもDMAは問題無く使用できます。
ただ、ここはデータシートのエラーなのですが、A0~A9までの各入力には内部にプルダウン抵抗が入っている筈ですが、実際には入っていません。販売店を経由してメーカーに聞いてデータシートのミスである事を確認しています。
使用しないA0、A3~A9はGNDに接続してしまうか、もっと楽なのはWIZ830MJ上で写真の様にモジュール抵抗でプルダウンしてしまうかをする必要が有ります。
え!、H8/SXボード側にピンヘッダーではなくソケットヘッダーを取り付けちゃった!。そりゃ残念(笑)。
お手軽基板作りたいね。
さて、何故かWiznetのW5300を搭載したWIZ830MJが有ったので、H8/SX基板との間にびよーんと配線を飛ばしてお気楽に実験です。
W5300の使い方は16bitバス、インダイレクトモードです。なのでアドレス線はA1とA2のみの使用となります。
インダイレクトモードとダイレクトモードではパフォーマンスに差は殆ど出ないでしょう。肝心のデータ転送に付いて言えば1アドレスに対してのみ行うので、インダイレクトモードでもDMAは問題無く使用できます。
ただ、ここはデータシートのエラーなのですが、A0~A9までの各入力には内部にプルダウン抵抗が入っている筈ですが、実際には入っていません。販売店を経由してメーカーに聞いてデータシートのミスである事を確認しています。
使用しないA0、A3~A9はGNDに接続してしまうか、もっと楽なのはWIZ830MJ上で写真の様にモジュール抵抗でプルダウンしてしまうかをする必要が有ります。
え!、H8/SXボード側にピンヘッダーではなくソケットヘッダーを取り付けちゃった!。そりゃ残念(笑)。
お手軽基板作りたいね。
今すぐ使える!H8マイコン基板 2010年 04月号 [雑誌]
- 作者:
- 出版社/メーカー: CQ出版
- 発売日: 2010/02/25
- メディア: 雑誌
ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発
- 作者: 濱原 和明
- 出版社/メーカー: オーム社
- 発売日: 2005/04/25
- メディア: 単行本
H8/SX基板とW5300基板で遊ぶ [NETWORK]
W5300は訳の判らないデータシートのミスで(データシートのケンチャナヨはやめて欲しい)とても残念なことになっていますが、でも、でも結構遊べます。
こうなると基板作りたいですよね、H8/SX基板+ネットワーク+α+β+Γって感じで。
今すぐ使える!H8マイコン基板 2010年 04月号 [雑誌]
- 作者:
- 出版社/メーカー: CQ出版
- 発売日: 2010/02/25
- メディア: 雑誌
ディジインターナショナルさんが今度のET2009に出展されるようです。 [NETWORK]
ディジインターナショナルさん
http://www.digi-intl.co.jp/
ET関連情報
http://www.digi-intl.co.jp/news/seminar/2009/ET2009info.html
あのキットがあの値段で購入できるセールも行われるようですね。
それ以外に、XBeeを使った記事を技術系雑誌などに投稿して掲載されるとiPOD Touchがもらえるキャンペーンが延長されていました。
http://www.digi-intl.co.jp/campaign/ipod/index.html
12月末締め切りなのでお急ぎください。
それ以外に、グリーンなコンテストも開催されています。
http://www.digi-intl.co.jp/idigi/index.html#designcontest
以上、XBee関連情報でした。
http://www.digi-intl.co.jp/
ET関連情報
http://www.digi-intl.co.jp/news/seminar/2009/ET2009info.html
あのキットがあの値段で購入できるセールも行われるようですね。
それ以外に、XBeeを使った記事を技術系雑誌などに投稿して掲載されるとiPOD Touchがもらえるキャンペーンが延長されていました。
http://www.digi-intl.co.jp/campaign/ipod/index.html
12月末締め切りなのでお急ぎください。
それ以外に、グリーンなコンテストも開催されています。
http://www.digi-intl.co.jp/idigi/index.html#designcontest
以上、XBee関連情報でした。