SDRAMの初期化
PLLを設定した後にSDRAMを設定します。NGWの使っているSDRAMはMicronのMT48LC16M16A2で、16bit bus/256MBitのSDRAMです。詳細はMicronのサイトにPDFが転がっていますのでそちらを参照してください。このSDRAMをOSC 20MHzを6てい倍÷2=60MHz(1CLK=16.666ns)で動作させる設定をしてみます。
必要なパラメータは以下の通り。タイミング設定をきちんと設定する必要がありますから、CLKへ入れる同期クロックによって計算が必要です。SDRAMのタイミングは、データシートのスペック表に書いてありますので、それを見ながらパラメータを決定します。Micronのデータシートでは、Table 19: Electrical Characteristics and Recommended AC Operating Conditionsに当たります。
CLK=60MHzのとき、1clk=1/(60*10^6Hz)=16.666*10^-9s(16.7ns)ですので、これを元に計算します。
column size = 13 row size = 9 bank = 4 (2bit)
tWR = 2clk
tRC = 60ns (4clk) PRECHARGE最小サイクル = 15ns(1clk)
tRCD = 15ns (1clk) tRAS = 37ns (3clk) tXSR = 67ns (4clk)
SDRAMの初期化処理例
SDRAMは非同期SRAMなどとことなり、RAM自体に対してコマンドを発行して動作させます。このコマンドは、制御線のRAS,CAS,WE,CSの組み合わせです。特定の組み合わせにして、CLKの立ち上がりでREAD、WRITE、PRECHARGEなどの動作をSDRAMは行います。
初期化処理はこの中のコマンドの一つで、これを行うことでSDRAMのバースト転送長やCASレイテンシ、データ転送方法を決定します。このパラメータはAVR32のSDRAMコントローラへ与える設定と同じにしておく必要があります。このパラメータはアドレスで与えます。↓がMicronのデータシートにあるものですが、SDRAMの場合は基本的に全部同じです(Mobile系のSDRAMの場合、Standbyに入れるときにどの部分をセルフリフレッシュをかけるかなどのオプションがあります)。
AVR32の場合バースト長1、シーケンシャル転送しかサポートしてません。また、今回はレイテンシ2で動作させますので、コマンドはアドレスA5のみを1にします。回路図を見ればわかるとおり、NGWの場合、SDRAMのメモリのA5は実際にはCPUのA7と繋がっていますので、コマンドを出すときはA7=1、つまり0x80のアドレスに書き込みします。
初期化後にリフレッシュサイクルを起動します。リフレッシュは特定の時間(tREF)で全ROWアドレスに1回発行する必要があります。これを行わないとSDRAMへアクセスしない場所で、データを記憶してあるチップ内のキャパシタの電荷が抜けてデータ化けが起こります。
NGWのSDRAMの場合、ROWアドレスは13bit、つまり2^13=8192ありますから、tREF=64msの場合で周期は64ms/8192=15.6usとなります。この周期をSDRAMクロック 60MHz から作り出すための分周カウンタの設定を行います。60MHzで1clkは16.666nsですから15.6us/16.666ns=936を設定すればよいことになります。
AVR32のポート制御
基本的にIO関連の定義はavr32/io.hにありますので、起動時のアセンブリコードを除けば、ここのヘッダを使うだけで全機能にアクセスできます。すべての機能ブロックのIO設定がtypedefで構造体に切られていますから、例えばPIOをアクセスするときは、ローカルかグローバルでvolatile struct avr32_pio_t *pio = &AVR32_PIOA;を定義すれば、pio構造体を使ってPIOAをアクセスできます(コンパイラのオプティマイザによって不要と見なされるコードが消されることがあるので、volatileを必ずつける)
NGWではPortA16,18,PortE19がLED表示ポートで、ポート出力はLEDのカソード側に繋がっていますから、1の時にOFF,0設定でONになります。
// led port初期化
// PA16 : SYS PA18 : A PE19 : B
void init_ports(void)
{
volatile struct avr32_pio_t *pioa = &AVR32_PIOA;
volatile struct avr32_pio_t *pioe = &AVR32_PIOE;
pioa->per=0x00090000; // portとして使用するビットを指定
pioe->per=0x00080000;
pioa->oer=0x00090000; // 出力ポートとして使用するポートを指定
pioe->oer=0x00080000;
pioa->sodr=0x00090000; // 指定するポートの出力データを1に設定
pioe->sodr=0x00080000; //
}
取りあえずここまで。次はデバッグモニタ用にRS232C周りを割り込み含めて動かしましょうか。
主にドールや電子工作関連を中心にしたブログです。