C:\Cypress\USB\CY3684_EZ-USB_FX2LP_DVK\1.0\Firmware\Bulkloopのファームウェアを開くと、以下のような図になる。
ここで、左のfw.cがソースコード(人間が読めるプログラムファイル)であって、
c言語で書かれている。(これに対し、.hexファイルが、機械が読めるコード。)
cpuは、最初に、fw.cから実行します。
fw.cのところをたたくと、
「#include “fx2.h”
#include “fx2regs.h”
#include “syncdly.h” // SYNCDELAY macro」とあり、
左には、fw.cにぶら下がる4つのヘッダファイルがある。
includeとは引用するの意味で、プログラムをすっきり見せるために、末端の定義を別ファイルでまとめる手法です。
ヘッダファイルは、定義ファイルであって、変数や定数を定義しているファイルです。
fx2.hは、基本的な定数の定義が書いてあります(ほとんどいじる必要はありません)。
「#define」は、定数を「定義する」意味であって、
「INTERNAL_DSCR_ADDR 0x0080」は、INTERNAL_DSCR_ADDR(内部ディスクリプタアドレス?)を0x0080と定義するという意味です。係る定義は、機械に指示すべきアドレスは、0x0080だけれども、人間が理解しづらいので、人間が理解できるよう、代わりの名称をつけ、いちいちtrmマニュアルを読まなくても、プログラムできるようにということです(これはstm32の徹底解説の本にも載ってます)。
fx2regs.hは、レジスタの「アドレス」の定義が載っています。
たとえば、「EXTERN xdata volatile BYTE GPIF_WAVE_DATA _AT_ 0xE400;」において、0xE400は、レジスタのアドレス(番地)です。
cpuは、レジスタ(登録)という領域があり、
これは、cpuが動作するための、ルールや状態が格納された領域であって、
人間がcpuに対し、一定のルールで動作してほしい旨を登録したり、
または、cpu自身が、cpu自身の状態を、登録したりします。
アドレスは、町の番地のように場所がそれぞれ割り振られており、
「BYTE GPIF_WAVE_DATA」という内容は、0xE400番地に割り振られています。
そして、テクニカルマニュアルのp384から、レジスタのまとめが書いてあります。
(クリックして、拡大して見てください。)
384ページの0xE400において、〔b7~b0〕は、2ビット列を表しており、
アドレス(0xE400番地)の内容は、〔b7~b0〕の2ビット列です。
実際には、16進数に直して、値を代入します。trmマニュアルは、おおむね、この番地の順に沿って、解説されていますから、
例えば、「EP2BCL」のレジスタを調べたいという場合には、
fx2regs.hで検索して、レジスタの番地を調べ、それからマニュアルを引けば、容易に説明にたどり着くと思います。
また、この図には、IFCONFIGも表示されています。
これの方が分かりやすいので、これを用いて説明しますと、
b5~b2は、0ビットと決まっています。
後で後述します。bulkloop.cでは、IFCONFIG |= 0x40;と記述がされており、
IFCONFIG、つまりE601という番地のレジスタには、0010 0000という内容を、16進数に直した、0x40(0xは16進数を表す)を入力する、という意味です。b6のみ1、ほかは0です。
ウィンドウズのスタート>全てのプログラム>アクセサリ>「電卓」において、
表示を関数電卓の表示にして、2ビットと16ビットを切り替えます。
(以上の点も、stm32の徹底解説にあったと思います)。
「syncdly.h」は、シンクデレィ(同期させるための時間遅れ)を計算するファイルです。
・「IFCONFIG |= 0x40;」のように、レジスタに値を登録するには、時間がかかるようです。
なんらの措置も講じなければ、cpuは、その登録の間に、次のコードを解読して、命令を下します。それでは、先の登録を前提にcpuが動作すべきところ、まずい場合があるので、登録が終わってから、次の命令を実行させるよう、ディレイを入れる必要があるのです(これもstm32の徹底解説にありました。)。
・ソースコードの「fw.c」の内部で、「SYNCDELAY; 」というコードを入れると、
クロック速度などを踏まえて、自動的に、適正な時間遅れを計算するので、プログラム作成者は、どの程度遅らせるべきかを、意識して計算する必要がありません。
計算方法は、trmマニュアルの15.15(p366)に書いてあります。
・例として、bulkloop.cには、
「EP1INCFG = 0xA0;
SYNCDELAY; // see TRM section 15.14
EP2CFG = 0xA2;
SYNCDELAY;」というディレイが入っています。
・どのレジスタを登録するときに、ディレイが必要かは、
trmマニュアルのレジスタのまとめのところで、
以下のとおり、15.15参照となっているかで判断します。
INTRINS.Hは、変数の定義の時、extern unsigned charなどの長い定義は、
プログラム作成者に負担になるので、略語を定義しています。
bulkloop.cは、メインのfw.cから呼び出されて、実行されるサブルーチンですが、
実際には、こちらがメインといっても、いいぐらいの内容で、
fx2lpが動作している間、はじめ以外は、bulkloop.cのTD_Pollが、常時繰り返し動作しています。
bulkloop.cでも、上記の4つのヘッダファイルを参照(include)します。
dscr.a51は、ディスクリプタファイルで、fx2lpの内容、例えば、製造者データ、エンドポイントの開始アドレス、1パケットの長さなど、PCへusb機器の内容を知らせる情報が記載されています。現状のbulkloopは、バルク転送を目的として書かれているので、アイソクロナス転送にする場合には、1パケットの長さを1024にすることができます。その他、機器を販売する場合には、製造者データをusbの大本から取得して、変える必要が出てくるでしょう。
その他のファイルは、読めませんので、説明を割愛します。