March 07, 2006

EZUSB FX2LP Keilからsdccへ

順調に作業が進んでいるUSB-ADC2ですが、USB-ADCと同じく作業環境をKeilとsdccの両面から攻めことにしました。そこで前の『EZUSB Keilからsdccへ、EZUSB.lib等の移植』と同じく、FX2LP向けにEZUSB.lib等を移植してみました。

ヘッダファイルライブラリの改変ソースを公開します。ライブラリは落としたあと、Makefile内のディレクトリを適切に設定してmakeをするとできます。
方法はほぼ同じですが、FX2LPとEZUSBではファイルが異なるようです。Development Kitの中のTarget/Lib/EzUSBとTarget/Lib/LPの内容を比較してみてください。

ついでにサンプルプログラムのbulkloopをKeilとsdccの両方からコンパイルできるようにしました。改変ソースを置いておきますので、USBJmpTb.asmやdscr.asmはこちらを参考にしてください。ディレクトリを適切に設定後makeをするとsdcc版が、同じくbulkloop_keil.Uv2を使うとKeil版がでてきます。動作確認済みです。
補足ですが、Development Kitの中のFX2LP向けbulkloop(Examples/FX2LP/Bulkloop/bulkloop.Uv2)をKeilでビルドしようとすると、

*** FATAL ERROR L220: INVALID INPUT MODULE
というエラーがでてできませんでした。どうやらUSBJmpTb.OBJとEZUSB.LIBが原因のようです。問題解決のためには
  1. USBJmpTb.OBJとEZUSB.LIBをターゲットからはずす
  2. ライブラリのソース(Target/Lib/LPの中の*.a51と*.c)をターゲットに加える
  3. この状態でコンパイルするとfx2reg.incがおかしいといわれるのでfx2reg.inc内の重複している定義をコメントアウトする(fx2reg.incはヘッダファイルと同じ場所にあります)
とうまくいきました。上記のKeil版もそのようにしてあります。

最後にですが、FX2で検証してくださったhamaさん、コメントをくださったhangさん、ありがとうございました。

※(2008/2) これらの情報をTeamKnoxさんが役立ててくださったようで、大変幸せです。

※(2008/10) ファイル階層を整理したついでに内容も見直しました。1) USBのディスクリプタ(dscr.asm)の配置が奇数番地だとうまく動かないことが多いので絶対番地(0x1900)に固定しました。2) SDCCマニュアル 4.1.1にある、MOVX命令によって下位アドレスへアクセス際に必要となるSFRの定義_XPAGEをfx2reg.hに書き加えました。

23:59 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/469
コメント

fenrirさんのおかげでbulkloopをSDCCコンパイルできました。
ホストプログラムで動作確認しました。
ありがとうございます!

ただ、、、何かお知恵があれば拝借したい件があります。
bulkloopのソースに少しでも変更を加えると、Windowsで認識されなくなります。
例えば、periph.cの
  EXTAUTODAT2 = EXTAUTODAT1;
ここを
  EXTAUTODAT2 = EXTAUTODAT1+10;
にするとダメです。
(KEILだと動くのですが、、、)

SDCCでは、2つ以上の引数がある時はグローバル変数で渡す、という制約があるらしいのは分かっているのですが、それ以外に何か制約があれば教えていただけないでしょうか。

ちょっとあつかましいですが、よろしくお願いいたします。

Posted by: Hirata : March 30, 2006 11:29 PM

Hirataさん、こんにちは。お役に立てたようで何よりです。
問題の件ですが、コンパイルは通るのですよね?申し訳ないのですが原因はよくわかりません。
sdcc、たまに動作しないコードを吐くことがあります(バグ?)ので、コードの配置を変えてみる、またはバイナリレベルで+10ありとなしの比較をされてみると何かわかるかもしれません。

Posted by: fenrir : March 31, 2006 11:07 AM

fenrirさん、アドバイスありがとうございます。
最終的には動作しました。
上記の場合ですと、変更したTD_poll()関数の最後にnopを入れるとWindowsに認識されるようになりました。(コードサイズ依存というか、SDCCが自動でつける初期化ルーチンの先頭アドレスに制約があるような気がしてなりません)
fw.cとperiph.cはあまりさわらない方が良いみたいですね~。
何がともあれ、SDCC&FX2LPで遊ぶ事が先です:-)

ちなみに、お役に立つかどうか分かりませんが、私の方ではドライバはUusbd.sysで動かしています。バルク転送はできました。
でも、ファームの転送までやる時間がなさそうです。すいません。

Posted by: Hirata : April 1, 2006 12:09 AM

お久しぶりです。社会人になってすっかりご無沙汰してました。
FX2のSDCC対応うまくいったようでなによりです。
私は謝辞をいただくほどのことは何もしてないですよ(汗)
こちらこそ、ソースコードを参考にさせていただきます。

ちなみに私は携帯電話メーカに就職しました。
早く設計に携わりたい!

Posted by: hama : April 18, 2006 09:13 PM

>hamaさん
いえいえ、動作報告があるのとないのとでは、やはりモチベーションが全然違いますよ(笑)、ありがどうございます。
携帯電話メーカですか、面白い製品を期待しています、がんばってください!

Posted by: fenrir : April 20, 2006 01:15 AM

はじめまして。
私もSDCCでコンパイルできるようになりました。
ありがとうございました。
私はFX2LPを使って、PC間のデータ転送をするような回路を
作っているのですが、私が書いたオリジナルソースも
コンパイルでき、問題なく動作できるようになりました。
感謝感謝です。

Hirataさんがおっしゃったように、
Windowsで認識できなくなる現象に遭遇しました。
mapファイルを覗いて、現象とつき合わせたのですが、
external_startupのアドレスが奇数番地だと認識されて、
偶数番地だと認識されなくなるようです。(なぜ?)
しょうがないので、コンパイル後、偶数番地になった場合は
意味のないレジスタ設定の命令を入れて再コンパイルし、
奇数番地になるようにしています。
(苦肉の策ですが・・・)

Posted by: yuki : May 3, 2006 04:34 PM

yukiさん、こんにちは。
お役に立てようでなりより & 貴重な報告ありがとうございます。偶数番地ですか、何かいい方法ないですかね。HEXフォーマットは単純なので、コンパイル後、適当なスクリプトでチェックをかけて処理するというのが意外と便利な解決策かな、と考えています。

Posted by: fenrir : May 5, 2006 12:19 AM

私もfenrirさんのサンプルのおかげでbulkloop,pingnakをSDCCコンパイルして動作確認出来ました。多謝。
ターゲットはFX2LPです。

external_startup問題ですが、コードを追加して行くと同じ現象に遭遇しました。
ただ、私の場合は偶数番地だと動作して奇数番地だと駄目でしばらくすると番地に関係なく動作するようになりました。
おそらくスタックかなにかがオーバフローしてエラーを起こしているのではないかと思い、
現在はSDCCのコンパイルオプションをつかってスタック位置を変えてトライしています。
追加したオプション
--code-size 0x3000 --xram-loc 0x3000 --xram-size 0x1000 --xstack-loc 0xe200

Posted by: km : June 20, 2006 07:59 PM

訂正します。
その後いろいろやっていると、奇数番地で動作し偶数番地だとUSBを認識しなくなりました。
スタック指定のオプションも効いているのかどうかわからないような。
もう少しはっきりしたことがわかったらまた報告致します。

Posted by: km : June 21, 2006 10:56 AM

8051のスタックポインタが8bitしかなくしかもメモリの
後ろに向かって伸びるなんて知りませんでした。
勉強不足でお恥ずかしい限りです。

やっと原因が見えてきたような気がします。
どうもdscr.asmで定義している_DeviceDscrなどが偶数番地に
割り当てられてないとenumerationに失敗するようです。
そういえばwindriverの体験版が生成するFX2LP用のテンプレートで
パイプの数を減らしたときに_FullSpeedConfigDscrの位置を
調整するために1byteのダミーデータが入れてありました。

どう探してもSDCCには.align疑似命令が無いようですし
最初にmain()のあるモジュールをリンクしなければならないと
いう制約があるので、fw.relの次にdscr.relをリンクするように
してその次に呼び出すモジュールで試行錯誤するようにしたことで
プログラムを変更するたびに動作したりしなかったりする現象は
収まりました。

コンパイラの信頼性を疑っていたりしたのですが、SDCC自体は
結構良く出来ているような気がします。

Posted by: km : June 21, 2006 07:28 PM

>kmさん
fenrirです。大変貴重な情報ありがとうございます。なんとなく変数足して動いたり動かなかったりする謎が、ようやく解けたような気がします。偶数番地に_DeviceDscrが配置されなければならないというのは8051というよりかはEZUSBの仕様なのでしょうか。マイコンにはやはり『御作法』があるものが多いようですね。

Posted by: fenrir : June 22, 2006 01:12 AM

>fenrirさん
コメントありがとうございます。
シンプルなアーキテクチャーでも『御作法』ではまってしまうことが多いですね。

掲示板
http://sourceforge.net/forum/message.php?msg_id=3453032
でこのテーマが話題になっていまして
.even という疑似命令が使えるのを見つけました。
これをデバイスデスクリプタテーブルの前に置くと
ちゃんと偶数番地に配置してくれるようです。
確認したコンパイラは SDCC-2.5.6(shapshot)です。

Posted by: km : June 22, 2006 11:00 AM

申し訳ありません。
.evenが使えるというのは早とちりだったようです。
確認が間違っていました。
コンパイラは.even疑似命令を受け付けるけれども
リンカが認識しないので出力には反映されないというのが
正解みたいです。

Posted by: km : June 23, 2006 06:24 PM

.even 疑似命令を使って少し楽が出来る方法を思いつきました。
お騒がせついでに情報を追加させて下さい。

.even 疑似命令はソースモジュールの中で位置を調整しますが
リンカはそれを無視します。
そのため、ソースモジュールの先頭アドレスが奇数ならば
.evenに続くシンボルの位置は必ず奇数になります。

それならば..

(1) main()のあるソース(fw.c)の最後の関数に .even 疑似命令を追加する
(例)
void resume_isr(void) interrupt WKUP_VECT
{
EZUSB_CLEAR_RSMIRQ();
// alignment end of fw.c
_asm;
.even
nop; // comment out this if needed
_endasm;
}

(2)リンカスクリプトテーブル(dscr.rel)がfw.relの後にリンクされるよう配置する。

(3)一度コンパイルしてマップファイルを確認し必要ならばnop命令を
コメントアウトしてシンボル_DeviceDscrが偶数番地になるようにする。

これでfw.c中の関数を修正しても_DeviceDscrの位置は偶数のままになります。

Posted by: km : June 23, 2006 07:59 PM

>kmさん
コメントありがとうございます。そうですか、リンカでは認識されないのですか、残念です。なかなか楽はできないようになっているみたいですね(笑)。

Posted by: fenrir : June 27, 2006 01:57 AM

 はじめまして、JUNと申します。
初めてなのに、長文ですいません。m(_ _)m
 まずFX2LPのCPUにCypressのフレームワークをKeilを使って元々のBulkLoopのテストをコンパイルしました。リンクは0x1400からコードスタートで、Keilコンパイラではデバイスも再認識され、ホスト側のBulkテストもうまく動作することを確認しました。

 次にこのサイトを大いに参考にさせていただき、SDCCでコンパイルして動作させようとしています。このサイトにもとづいてSDCCでライブラリも含め、そのKeilのBulkLoopのテストをコンパイル、リンクしました。ところが、新しいデバイスをロードしようとして、私のPCの環境ではホスト側が途中で暴走してしまう始末です。(他のCPU環境では、不明なデバイスとなる)
 仕方ないので、まずは、このサイトにあるfenrirさんのソースに全て置き換え、ライブラリを生成し、Bulkloopを動作させようと、がんばったのですが、同じ現象でした。
 ただfenrirさんとの開発環境の大きな違いは、私の場合は、WindowsのCygwinだということです。そして妙なことに、fenrirさんの生成したbulkloop.hexそのままだと、暴走せずにちゃんとエニュメレーションを行い、デバイス名も出てくるのです。
 どうも新しくロードしたプログラムのデバイスディスクリプタがちゃんと認識されてないか、そもそも、ちゃんと初期化されてメインのプログラムに飛んでいってないのかなー、なんて混乱状態になってしまっています。(T-T)
 そもそも8051のアーキテクチャで33番地、43番地、53番地がベクタジャンプのコードがはいっていて、なおかつ、そこがデータエリアとしても読み書きされる、という自体、こんなの大丈夫って気がするもんで。
ハードウェアのマニュアルを何回見ても、その仕組みがよくわからなかった.....(;^_^A
 0-80Hまでって、コードメモリとデータメモリと2重のメモリをもっている、と考えれば納得いくのだけれど、そういう記述はありませんでしたから。
 とにかくこんな迷えるプログラマに何かアドバイスをいただければとお邪魔したしだいです。^^;
 よろしくお願いいたします。
(なおソースプログラムの方は、ここのサイトのをベースにコメントを参考にして修正していきました)

Posted by: JUN : August 21, 2006 07:38 PM

>JUNさん
こんにちは。まずこちらの環境ですが、JUNさんと同じCygwin上のsdccで作業しています。当時の状況をよく覚えていないのですが、bulkloopを作ったときの環境は、確かソースからセルフビルドした少し古めのsdccでコンパイルしたと思います(sdccの最新版は2.6.0ですから2.4.0あたり?)。
現在2.5.6でコンパイルしなおしてみたところ、こちらでもbulkloopが動かない現象に遭遇していますので、ちょっと検討してみます。お役に立てずすいません…。

Posted by: fenrir : August 22, 2006 02:14 AM

fenrirさん、さっそくのご返事ありがとうございます。
こちらでも今いろいろやっていますので、いい知らせがあればお伝えしますね。

Posted by: JUN : August 22, 2006 10:06 AM

USBのStreamscopeを使ったり、LED表示させたりして、
fw.c内の
if(TD_Suspend())
からちゃんと返って来ないことに気づきました。
(TRUEで返しているのに、FALSEとみなしている)
そしたら、このTD_Suspend()の定義がBOOLでExtern宣言されているのに気づいたので、
#define BOOL BYTE
の定義を下記の位置に移動しました。


//-----------------------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------------------
#ifdef SDCC
#define BOOL BYTE
#define GPCR2 FALSE
#define bmFULLSPEEDONLY FALSE
#endif
void SetupCommand(void);
void TD_Init(void);
void TD_Poll(void);
BOOL TD_Suspend(void);
BOOL TD_Resume(void);
・・・・・・・・・・・・・・・・・

この修正だけで、うまく動作するようになりました。
いろいろこのサイトは本当に役に立ちました。
ありがとうございます。

Posted by: JUN : August 23, 2006 11:57 AM

>JUNさん
こちらでもご指摘の修正を施した後sdcc2.6.0でテストしてみた結果、認識するようになりました。
リンカの辺りを疑ってmapファイルばかり眺めていたのですが、実信号を見たほうがよかったですね。大変勉強になりました、本当にありがとうございます。

なおダウンロードファイルは修正したものに切り替えました。以後落とされる方は問題ないと思いますが、なにかありましたらまたここに書き込んでくださるとうれしいです。

Posted by: fenrir : August 24, 2006 01:00 AM

はじめまして、kurihiroと申します。
FX2LPの評価ボードを入手しまして、早速、本ページを参考にして、コンパイル、認識等、問題なく済ませることができました。ありがとうございます。
しかしながら、評価ボードのLED等を使用しようと思ったところ、Keilでは問題なく制御できるI2Cがらみがどうも動作しません。
調べてみると、割り込みルーチンはmain()と同じファイルにないといけないのに、I2Cの割り込みルーチンがEZUSB.libにあるためと分かりました。
マニュアルによるとmain()のあるファイルに割り込みルーチンのプロトタイプだけあればいいということなので、fw.cの最後に、
void i2c_isr(void) interrupt I2C_VECT;
を追加することで対策できました。
以上、報告させていたただきます。

Posted by: kurihiro : September 3, 2006 11:19 AM

>kurihiroさん
情報ありがとうございます。実のところEZUSB.libの動作検証はあまりしていなかった(汗)ので、動作報告を戴けてうれしい限りです。

Posted by: fenrir : September 4, 2006 02:05 AM

>kurihiroさん
ありがとうございます。
また、ここのサイトが役に立ちました。
メインを含まない、別のところにINT0_VECTの処理を書いたのに、割り込みベクタを作ってくれてないので、
インターネットで調べていて、また、ここにいきついて解決したのでした。
 ただ、今も確認しましたが、kurihiroさんの言うように、マニュアルにちゃんと記載してあったんですね。
 うーん、その意味では、わからないことがあったら、原点に戻れ、って言うことか。
(^-^;

 そうそう、割り込みベクタといえば、データ領域と割り込みベクタが
0~100Hでは重なっているところを使う恐れがあって、
コードとデータがちゃんぽんになってるエリアって、
8051のアーキテクチャではどうなっているのか、
いまだに疑問が残ったままです。
(コードとデータのメモリエリアはアドレスは同じでも全然別?
 ->でもHEXファイルにはデータのロードやコードの区別はないから、
 結局、同じ、データとしてコードも書き込まざるを得ない?)

 うーん、わからないなー(SFRのエリア領域だけは別個なのはわかってるのですが)
(^ヘ^;
SDCCはうまくそんな領域を回避してデータを割り当ててるとは思えないし....

Posted by: JUN : September 9, 2006 06:56 PM

>JUNさん
そういえばご質問に返答するのを忘れていました。回答になっているかはわかりません(笑)が、僕の理解を書いてみます。
一般的に、プロセッサではリセット等の割り込みが発生するとあらかじめ決められたアドレスから命令を読み取り実行を開始する仕組みになっていると思います。この決められたアドレス領域がいわゆる割り込みベクタというもので、このような仕組みを実現するためには、割り込みベクタには実行する命令が存在しなければなりません。つまり、割り込みベクタと重なるように、コンパイラが定めるコード領域(<-命令が格納される部分という意味での)は設定されていてる必要があると思います。
しかしJUNさんの思われているとおり、その割り込みベクタにコードやデータがぐちゃぐちゃ書いてあると割り込みベクタとして機能しないと思います。そこで、割り込みベクタにはjmp命令(指定したアドレスに飛んでそこから命令を実行する)だけを書いておいて、割り込みによって実際に行われる命令は同じコード領域であっても割り込みベクタとは別のアドレスに配置されているという手口をとっていると思います。またデータについては、静的(static)なものはコード領域とは別に確保した領域に割り当てられ、動的(ローカル変数など)なものはこれまたコード領域とは違うスタック領域から確保されることになっているので、割り込みベクタとかぶる心配はないと思います。
この方法はマイコンのコンパイラには常套手段だと思いますので、おそらくsdccでもデフォルトで割り込みベクタをうまく回避してメモリ割り当てをしていると考えられます。いかがでしょうか。

Posted by: fenrir : September 12, 2006 11:44 AM

fenrirさん、ご返事遅くなりすいませんでした。
m(_ _)m
私もいろいろ絶対アドレスが割り付けられたアセンブリリスト(.rstファイル)を見たのですが、
そのようなことは配慮されてる気配はありませんでしたね。(^-^;
 以前、評価版の8051のシミュレートで逆アセンブリリストをとったとき気が付いたのですが、
どうも、コードとデータは別々に違った内容が表示されていたので、
なんかやっぱり別々の空間としてとらえられている感じがします。
 なおこれと関係がないのですが、SDCCのマニュアルの4.1.1のpdataアクセスに関して、
xdataの初期化とからんで、個々のCPUごとに_XPAGEのアドレスを設定しておかないと、
ちゃんと初期化を行わない、という記述がありました。
 マップファイルを見ると、デフォルトではA0(SFRのP2ポート)でしたが、
Cypressでは本来0x92(MPAGEポート)を割り当てないといけないのです。
今まで、ある程度、プログラムは動いていたので、よし、としていたのですが、
結構、こういう細かい配慮も必要ですね。(^-^;
 なおこの情報は「USB-MSD-RD KeilからSDCCへの移植」に書かれていました。
http://www.chiaki.cc/Timpy/rev50-keil2sdcc.html

Posted by: JUN : September 16, 2006 04:33 PM

はじめまして。

現在市販されているEZUSB FX2LPについては、資料が少なく、初心者がUSBプログラミングをするには困難を覚えることが多いのです。さらに、lpを使っていても、ソフトはfx2のままというのが、書籍にも多いのです。cypressのapiやツール類がlpで大きく変更されているのに、それに対応しないのはおかしいと思っています。
その意味で、貴サイトは大いに参考となります。
sdccはz80用に使って以来、愛着があるので、
これでプログラミングができることは、ありがたいことです。
とはいっても、USBプログラミング自体が敷居が高いので、ぼつぼつ慣れていきたいと思います。

Posted by: きゅうる村 : January 12, 2007 11:06 AM

>きゅうる村さん
はじめまして。コメントありがとうございます、またご参考にして戴けて光栄です。
資料の少なさについては同意です。FX2LPは最近秋葉原(秋月)でも買えるようになりましたし、参考文献がこれから増えてくることを期待したいものです。8051系でsdccのバグには何度かなかされたことがありますが、z80のsdccはどうでしょうか。

Posted by: fenrir : January 12, 2007 11:07 AM

はじめましてarms22と申します。
何点か気になったのでコメントします。

1._DeviceDscr
Setup Data Pointerレジスタに書き込めるアドレスはWORD境界である必要があります。
取り合えず絶対アドレス指定でプログラムの後ろの方に配置しておけばOKかな。

2.interrupt 0
sdccで、main()のあるファイルにexternしなければinterrupt番号が重複していてもOK。
またUSB関連のinterruptはmain()のあるファイル(fw.c)にexternしないほうが良いと思います。
USB関連の割り込み関数がベクタに追加されてしまいます。

3.__interrupt_vectのサイズ
sdccでmain()のあるファイルで#pragma noivとしてもリセットベクタだけは生成されるみたいです。
またベクタテーブルはinterupt 0からinterupt N(最大値)までしか生成されないので
Nがマイコンの割り込み数以下なら割り込みベクタに通常コードが配置されてしまいます。

Nを最大値にした割り込み関数を用意するか、
ベクタテーブルは自前で用意したほうがいいみたいです。

Posted by: arms22 : January 18, 2007 05:33 PM

>arms22さん
情報ありがとうございます。EZUSB系からは離れて時間が経ってしまったので、当時の稚拙さが皆さんに災いしていなければと願う一心です。
最近またFX2とは別の8051系MCUを使い出したのですが、やはりsdccにお世話になっています。sdccのマニュアル、読めば読むほど奥が深いですね。

Posted by: fenrir : January 23, 2007 12:54 AM

> 補足ですが、Development Kitの中のFX2LP向けbulkloop(Examples/FX2LP/Bulkloop/bulkloop.Uv2)をKeilでビルドしようとすると、
>
> *** FATAL ERROR L220: INVALID INPUT MODULE
> というエラーがでてできませんでした。

FX2用の開発ツールと、FX2LP用の開発ツールとでは、
付属するKeilのバージョンが違います。

SETUP_FX2LP_DVK_1004.exe
Keil V2.10
EZ-USB_devtools_version_261700.zip
Keil V2.38j

objとlibはそれぞれのバージョンで互換性はないようで、
FX2LPのサンプルは、Keil V2.38jでビルドする必要があるようです。

Posted by: chirari : February 10, 2007 07:57 PM

バージョンが逆でした

SETUP_FX2LP_DVK_1004.exe
Keil V2.38j
EZ-USB_devtools_version_261700.zip
Keil V2.10

ですね。

Posted by: chirari : February 10, 2007 08:00 PM

>chirariさん
情報ありがとうございます、コメント返すのが遅くなってしまい申し訳ありません。

どうりでコンパイルがうまくいかないわけですね。ライブラリの形式もバージョンによって互換性がないというのは初めて知りました。

Posted by: fenrir : February 13, 2007 06:42 PM

ferrirさん、ご無沙汰です。hangです。

古いレスへのコメントで恐縮ですが、肝心な事が抜けているようですので....。.evenも重要ですが。
xdata variableの初期化で路頭に迷っている方がいらっしゃるかもしれません。

SDCCのインストール時は、xinitがハードウェアを利用するセットアップ初期化になっています。
EZ-USB FX2ではこれをDUAL_DPTR使用に変更する必要があります。
SDCCのlibフォルダーを探すと、crtxinit.asmが見つかりますので、これを自分のフォルダーにコピーし、ファイル内のDUAL_DPTR=0をDUAL_DPTR=1に変更します。
このアセンブリオブジェクトをリンクします。

初めて使用される方は、これで悩む事が多いと思います。

Posted by: hang : November 30, 2008 01:46 AM

hangです。長い事EZ-USBに触っていなかったので忘れていました。

__mcs51_genXRAMCLEAR::もIOCを介したハードアクセスになっていますので、crtxclear.asmも書き直す必要があります。
これは、練習問題ですね。

おそらく、皆さんの初期不安定の原因は、スタートアップで、デスクリプターテーブルやプログラムを壊しているからだと思われます。


Posted by: hang : November 30, 2008 02:10 PM

>hangさん
情報ありがとうございます。
色々と気になって調べてみたのですが、この問題についてはsfr at 0x92 _XPAGE;が適切な位置で定義されていればDUAL_DPTR=1とせずとも解消される問題なのでないかと考えています。というのもFX2(LP)はXdataアクセス用に、8051の伝統的なアクセス方法であるP2ポートを使う方法ではなく、専用のレジスタ0x92(FX2LPのデータシートではMPAGEと表記)を用いる方法を使っており、コンパイラもこれを考慮して_XPAGEが指定されている場合にスタートアップルーチンもその指示に従うように思われます( http://sdcc.sourceforge.net/doc/sdccman.html/node104.html )。こちらで公開しているプログラムも_XPAGEのsfrはヘッダfx2regs.hで定義していますので、大丈夫ではないかと考えています。

Posted by: fenrir : December 1, 2008 10:16 AM

fenrirさん こんにちは。hangです。

あっと、そうでしたか。
ただ、先ほどnoICE for 8051で確認しましたら、スタートアップは、P2を使用されていた事と、プログラムはStringDescripterを参照できない、xdata変数の初期化ができない状況でした。
古いソースなので、それが原因かな?
SDCCは最新Stable版です。

どなたか、追検証していただければ幸いです。
ちょっと忙しくて8051には手が回らないもので ^^);

Posted by: hang : December 1, 2008 10:34 AM

hangです。失礼。途中で送信しました。

上記不具合は、スタートアップにSDCCオリジナルを使用した場合で、当然、手を加えた場合は安定に動作します。

で、再度、修正スタートアップをリンクし正常な事を確認しました。

Posted by: hang : December 1, 2008 11:05 AM

またまた hangです。フー一服。

ARMやdsPICで忙しく、なかなか8051に触れる機会がなかったのですが、最近感じるのは、EZ-USB FX2のカリスマ性ですね。
EZ-USB FX2+FPGAは最強のように思います。
Xilinx USBⅡ等に使用されているように、海外ではヒットしているのに、国内の寂しさは、SDCCアプリのサポート不足が原因ですかねぇ。
と、このテーマはここの話題ではありませんでした。
失礼!


Posted by: hang : December 1, 2008 05:14 PM

>hangさん
たびたびコメントありがとうございます。そうですね、追試が必要ですね。
ところで8051+sdccといえば、FX2以外にもSilicon LaboratoriesのC8051シリーズ(こちらは1クロック1命令で速い!!)を愛用しているのですが、C8051では_XPAGEを定義しておけばXdataが確実に初期化がされています。うーん。

Posted by: fenrir : December 2, 2008 02:00 AM

>fenrirさん 

正確に記述すればよかったようです。唸らせてしまいました。
古いソースでXPAGEが入っていませんでした。
確かに、XPAGE宣言で解決します。

fenrirさんの作成されたヘッダーファイルがSDCCスタンダードという事になります。

意外と、オプティマイズさんやらあちこちのソースを拾い集めてプログラムを開始するとこの手のバグに陥りますので、問題確認の意味として御勘弁を。


Posted by: hang : December 2, 2008 09:54 AM

>hangさん
確認がとれたようで、ほっとしております。色々と組み合わせて作っているうちにわけがわからなくなることは、僕もよくあります(笑)

Posted by: fenrir : December 5, 2008 01:18 AM
コメントする









名前、アドレスを登録しますか?
(次回以降コメント入力が楽になります)
  • 匿名でのコメントは受け付けておりません。
  • 名前(ハンドル名可)とメールアドレスは必ず入力してください。
  • メールアドレスを表示されたくないときはURLも必ず記入してください。
  • コメント欄でHTMLタグは使用できません。
  • コメント本文に日本語(全角文字)がある程度多く含まれている必要があります。
  • コメント欄内のURLと思われる文字列は自動的にリンクに変換されます。