2009年03月22日

AVR32 AT32AP7000 NGW Network Gateway Reference Boardで遊ぶ 5

NGW100での割り込みですが、いろいろいじっててなんとなく2.1以降のtoolchainの対応がわかったので必要事項をメモ書き。

  1. interrupt系の関数はフレームワークのINTCに移動 (includeはFrameworkのintc.hをsys/interrupt.hの代わりに設定)
  2. set_interrupt_baseは不要になった模様(フレームワークのcrt0.xで設定)
  3. Enable_global_interrupt();を明示実行する
  4. INTC_register_interrupt();は引数変更。割り込み種別とレベルのみ指定関数内で規定値設定)

前に上げたサンプルの修正方法としては、まず最初にSTK1000のフレームワークでINTCのみを有効にして作ったあとに、サンプルのソースコードを加えます。そのあとに、以前にあったtrampoline.xはなくなって、crt0.xが外に出されてそこにtrampoline.xと同じコードが入っていることでブートからジャンプするようになっていますから (_startがcrt0.xで定義されることで、ブートコードと同じ扱いになる)、これをコメントアウトしておきます。そうするとboot.xが機能するようになります。これで、boot.x→crt0.x→main()の順に動きます。
というわけで、GNU toolchain 2.1以降用のサンプルを提示。前のサンプルで.rodataがdata扱いになってたのになぜか動いてたのでw、Optimizationで修正してます(put r/odata 〜のとこ)。
しかし、いきなり大幅に変えられると右往左往するので勘弁してほしい(;´Д`)

<補足>
あとで気がつきましたが、Framework設定の最終画面でnewlibを使うかどうかの設定があって、これをnone以外にすると、既存の interrupt関連はそれなりに流用できるっぽいです。基本的にNGWでもSTK1000のFrameworkをベースにして作れって感じみたい。 というわけで、AP7xxxは見捨てられてるかも発言は撤回w 
まぁ、NGWがサポートにないのはEvaluation BoardじゃなくてReference Boardなんで、評価用じゃないからサポートしないよ、というのがATMELの立場なのかな。ただ、ヘッダのdefineをみるとNGW100のラベルで切ってあったりするんですけどね。なんにしても基本はFrameworkから作った方が間違 いないかも。
しかし、toolchainのフォルダを漁ったけど、AT32UC3用のライブラリをそのまま使ってるだけなのね。ただ、スタートアップはデフォルトのcrt0.xを使われてしまうので、それなりに修正は必要です。
posted by もろぼし☆らむ at 16:38| Comment(0) | TrackBack(0) | 電子工作

2009年03月21日

ATMEL AT32UC3B EVK1101 Evaluation Board

久しぶりにATMELのサイトをみたらAVR32 Studioが2.1.1、AVR32 gnu toolchainが2.1.4に上がっていたのでアップグレードしてみたら・・・・既存のプロジェクトがBuildできない(;´Д`)
説明書をよーく読んでみたら、sys/interrupts.hに入っていたinterrupt系の関数がFramework側のNEWLIB_ADDON側に放り出された模様(libc.aから無くなってます)。それはいいのですが、どうもこの対応がAT32UC3系のCPUにしかちゃんと入って無くて、AP7xxxは後回しにされている様子?。これじゃどうにもならんなぁ・・・と思ってたら、JTAGICE mk2の自動ファームアップデートでもNG出たりで結構散々(;´Д`) GUI上ではアップデートできたようにみえても、起動するたびに「JTAGICEのFirmwareアップグレードをしなきゃ駄目!」とEclipseからお叱りを受けます(泣。ちなみに2.1.4のtoolchainに入ってるバージョンのJTAGICEを単体制御するavr32programを実行すると、Failed to execute command with ID 0x01 とか謎エラーが出ます。
AVR Freaksをいろいろ読んでみたら、どうもたまに起きるようで向こうでも解決されていないようなので、自分で解決するしかないということで、散々いろいろやってみたところ、user/LocalSettings/Tempにアップデート用のテンポラリファイルがおかしな状態で入ると駄目になる模様(ここにEclipseがアップデータとかを一端入れて作業するので)。というわけで、Tempの下に貯まっていたファイルをばっさり削除して、Software Updateをし直したら、正常にFirmware ver.5.44へアップグレードされました。なんだかなぁ・・・。後でATMELへ報告しておくかなぁ・・・。
たぶん、Eclipseの自動アップデートに問題があるんでしょうけど。だから、Eclipseは嫌い。
結局のところ、対応見てるとATMELがAPxxxxを見放してるっぽい?ので、AT32UC3シリーズに手を出してみることにしました。以前と違ってAT32UC3シリーズが普通に手に入るようになったので、ATMegaレベルのアプリケーションはここらへんでもいいよね、ということで。
ちなみに久しぶりにDigiKeyで買いましたが、円高もあって8100円ぐらいです。いつの間にか7500円以上送料無料になってたんですね。
まぁ、このAT32UC3、ARMコアのNXPのLPCxxxxと思いっきりぶつかるような気がしますがw 新しいコアを出して売っていこうというだけあって、ATMELもソフトが楽できるようにコレに関しては結構最初っからFrameworkを出してきたりと熱心です。ARMのソフト資産が膨大だから、用途ダブってしまうとなかなか選択肢に出てきませんからね・・・・。コスト的に凄い条件出したら違うでしょうけど・・・・。
↓本番で使うのはAT32UC3B0128の予定。
b525.jpg
AT32UCA/BシリーズはAP7xxx系と違って、ローレベルの組み込み関連向けの製品で、パッケージもLQFPなどですから普通に自作に使えます。AP7xxxだとBGAしかないので、事実上NGWとかSTK1000でしか使わざるを得ないですから。
Frameworkは必要なものは結構一通り持ってます。低レベルのIP別の基本処理とかから、USB、加速度センサーやらSDCARD、NANDフラッシュとそのハミング符号ECC、FATなどです。NANDはハミング符号ECCなんでSLCの古いプロセスの石のみ対応です。USBはいまのところHIDのみですが、Mass Storageにも対応する予定、らしいです。あとFreeRTOSもネイティブサポートです。ITRON移植しようと思ってたけど、こっち使う方に流れそうw
↓フレームワークで作れる機能。結構盛りだくさんです。
b528.pngb529.pngb530.png
開発環境はお馴染みAVR32 StudioでEclipseベースですが、IAR Systemsの環境もお試し版がついてます。32KBまでのオブジェクトが作れるStarter Kit版と、制限無しだけど30日までよの試用版です。ただ、IAR版は使わない方がいいかも・・・。Eclipse版を窓から捨てたくなるのでw IAR版はデバッグ環境もキビキビ動きますし、環境設定もわかりやすいし、mapやリスト出力も見やすいですからねぇ。3万ぐらいでもうちょっと制限の緩いものがあれば買うんだけどなぁ。さすがに50万では手が出ません(;´Д`) オブジェクトサイズmax 128KBまでとかで、商用使用不可の安いのを出して欲しい・・・。
IAR Systemsの統合環境。せめて64KBまで作れれば・・・(;´Д`)
b531.png
このレベルにEclipse版が到達するのはいつになるんだろう・・・
EVK1101にデフォルト搭載デモはUSBで接続して、PC上のソフトから、ボード上にある照度センサーや加速度センサー情報の取得、LEDの点灯ができるものです。いまのところフレームワークがHID Classしかサポートしてないのでこんな感じ。転送はインタラプト転送のみ使ってます。一応ボード上にはこの他にSDカードスロットやシリアルDATAFlashがあるので、将来的にはこれが使えるデモになるかと。
↓基板表と裏
b527.jpgb526.jpg
↓PCのデモソフト。Java版もあります。
b532.png
まだ届いたばっかなので、適当にいじっただけですが、なにか一つ作ってみれば、いろいろとわかるでしょう。つーか、WinAVRのようにサクサク環境ならないのかな・・・。
posted by もろぼし☆らむ at 22:52| Comment(0) | TrackBack(0) | 電子工作

2008年07月12日

AVR32 AT32AP7000 NGW Network Gateway Reference Boardで遊ぶ 4

ポートの動作もさせましたので、次は割り込みです。とリあえず、これだけできれば一通りのことができるようになります。
さて、まずは割り込みといえばデバッグモニター用にシリアルを書くものと相場が決まってるのでw、これを作ってみることにします。NGWのシリアルポートはUSART1のRXDとTXDのみがRS-232Cのレベル変換ICに繋がっています。RTSとCTSのハードウェアフロー制御信号線は繋がっていないので使えません。これらの信号線は、NGWの端子側でループバックで接続されているだけです。そんなわけで、ハードウェアフロー制御はできないので、フロー制御処理は入れません。
AVR32のgccでは割り込み処理は以下のように記述します。

#include <sys/interrupts.h>

// 割り込みハンドラ
__int_handler *usart_int_handler()
{
  // 割り込み処理
  return (void *) 0;
}

// 割り込みハンドラの登録
  set_interrupts_base( (void *) AVR32_INTC_ADDRESS );
  register_interrupt( (__int_handler) (usart_int_handler),  // 割り込みハンドラ
            AVR32_USART1_IRQ/32,    // 割り込みグループ
            AVR32_USART1_IRQ % 32,     // 割り込みライン
            INT0);                    // 優先度

AVR32の割り込み処理では、割り込み入力を1つのグループの中でorゲートで接続されています。そのグループごとに優先度を設定できます。上記の処理を割り込みマスクを解除する前に実行することで、ハンドラが登録されます。
b113.jpg
AVR32のUSARTでは、普通の非同期シリアルの他にいろいろな機能がついています。例えばマンチェスター符号のエンコード/デコードができたりするので、ASKやFSKの変調/復調回路と組み合わせるだけで、ちょっとした無線データモデムを作れます。
まぁ、それをやってみるのもいいのですが、それにはNGWが2台必要なので今回はパスということでw

ポート、通信設定初期化
さて非同期シリアルの話に戻りますが、PIOAのPA17,18がRXD,TXDなので、これらをポートとして使わない設定にし、USARTのあるペリフェラルA(Bを選択するとタイマー0の端子)を選択しておきます。また、RXD,TXDの接続先は232Cのトランシーバーなので、プルアップはオフにします(トランシーバー内でプルダウンされているため)。

ボーレイトの設定
非同期シリアル通信では、通常はデータをスタートビットから特定のクロックでサンプリングして、多数決でビットの値を決定します。サンプリングクロック用のボーレイトジェネレイターの分周カウンタの設定をしなければなりません。
USART1の動作クロックはPBAから供給されます。PBAはPLLの再設定で30MHzにしましたが、USART1にはこれを8分周したクロックが供給されるようになっています。
今回はサンプリングを16倍で行うことにしますので、ボーレイトジェネレータの分周設定は115200bpsの場合以下のような計算式となります。

 CD=2: (30*10^6(Hz)/8) / (16 * CD) = 117187.5
 誤差 117187.5/115200 = 1.72%

取り合えず数%以内に収まっていれば、十分使えますので2で設定します。

割り込み処理
今回のシリアルドライバは、受信だけでなく送信も割り込みを使っています。といってもたいしたことなくて、単に送信バッファにデータを入れたときに割り込みを許可して、割り込み内でバッファが空になったら送信割り込みを禁止します。送信割り込みを使う場合に注意しなければいけないのが、送信割り込み許可マスクの解除タイミングと、割り込み処理部分です。誤った設計をすると、送信割り込みが停止したり、不要なところで許可してしまう場合がありますので注意が必要です。が、そういうのはフロー制御を実装するときに大問題になるので、今回は特にあまり気を払う必要はありませんw 実際の処理はサンプルフローを参照下さい。

取りあえず、一区切りつきましたので、SDRAMメモリ検査、LED点灯、シリアルループバックのみを行う、スタンドアロンのサンプルをアップロードしておきます。次はRTOSのポーティングをしますが、取りあえずμITRON v4.0互換のHOS-V4をAVR32対応にしてみることにします。TOPPERSは、なんかいろいろと公開するのが面倒くさそうなのでw たぶん時間がちょっとかかるので、このカテゴリの記事は当分おあずけ、かもしれません。
posted by もろぼし☆らむ at 00:50| Comment(0) | TrackBack(0) | 電子工作

2008年06月29日

AVR32 AT32AP7000 NGW Network Gateway Reference Boardで遊ぶ 3

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に入れるときにどの部分をセルフリフレッシュをかけるかなどのオプションがあります)。
b95.jpg
 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周りを割り込み含めて動かしましょうか。

posted by もろぼし☆らむ at 17:28| Comment(0) | TrackBack(0) | 電子工作

2008年06月24日

AVR32 AT32AP7000 NGW Network Gateway Reference Boardで遊ぶ 2

前回までは環境構築だけだったので、のんびりと概要から。

AT32AP7000のメモリ構成

NGWのCPUのAT32AP7000は内蔵Flashがありません。その代わり、NGWには一般的なCFIを持つNOR Flashを搭載しています。そんなわけで、基本的にプログラムはここに書き込みます。RAMは内蔵で32KB程度ありますが、基本的には外付けのSDRAMをアプリケーションが使うことが前提です。この手の内蔵RAMはCPUのディープスタンバイに入れたときに、最低限必要な情報だけいれておく場合や、特定の高速性が必要なコードを展開したいときに確実に1clock動作する場所として使うことが多いです。NGWの場合、この他にDataFlashというシリアルEEPROMを搭載しています。
NOR Flash  64MBit (Phy 00000000〜)
SDRAM     256MBit (Phy 10000000〜)
INRAM     256KBit (Phy 24000000〜)

物理メモリ構成は、SH系に似ていて 0xa0000000~0xbfffffffまでが非キャッシュ領域、ミラーの0x80000000~0x9fffffffがキャッシュ領域です。基本的に初期設定や特定の特殊な処理をする時しか非キャッシュ領域では実行しません。例えば、DMAなどを使うとき、特定のポイントでキャッシュのデータをパージしたりライトバックしたりする場合などは、非キャッシュ領域で実行する必要があります。なお、MMUをEnableにすると0〜0x7fffffffまでがTLBが聞くようになります。

リセット動作
AVR32はリセットがかかると0xA0000000にジャンプし、ここからコードが実行されます。AVR32-gccでは、crt0.sのスタートアップコードのエントリは.textセクションの先頭_stextですので、もしSDRAMをスタートアップ前にenableにするときは、リセット直後にそれようのコードを記述しておき、次に_stextへジャンプすれば、スタートアップコードに手を入れなくても対応できます。今回もそのような方法にて対応します。

スタートアップコードへ入るまでの初期化
 今回はSDRAMの置き換えですので、PLLとSDRAMの初期化だけは最初に行っておきます。なお、これらはスタートアップ処理前ですから当然Cは使えませんので、全部この処理はアセンブラで書く必要があります。
 さてAVR32のインストラクションですが、データシートをみてみるとわかりますが、8bit AVRと結構似てます。ただ、インストラクションが32ビット固定という関係上、結構無理な部分がありますが、16bit固定のSHよりはマシですw 注意なのは、AVR32では1ワード=32ビットということです。それに気がつかないで少々悩んだり・・・。まぁ、アーキテクチャ関連が書いてあるpdfには最初にしっかり書いてありますけどね。
  
 <AVR32のインストラクションの一例>
  st.w r0,r2  ; r2のデータを(r0)へ格納(32bit)
 // 32bitのデータを設定するときはpc相対でメモリ上からロードするか、
 // movとorhで2つにわけて設定
  mov  r0,0x4000 ; r0へ0x4000(21bit)を格納(bit21以上は0が入る)
  orh  r0,0xfff0 ; r0の上位16bitへ0xfff0をorする
 // <注> インストラクション表には movhi という命令がありますが、AP7000では
 // 使えません。これもavrではよくあること:)
 // 加算処理
  sub  r0,-1     ; immな加算命令は伝統のごとくないので、-1を引きましょう。
 
PLLの初期化
 NGWはOSC0に20MHz、OSC1に12MHzが繋がっています。OSC0がCPUなどのメインクロック用で、OSC1はぶっちゃけUSB用です(4てい倍して48MHzで使う)。AVR32では内部のブロックはCPU,HSB,PBA,PBBの4つの部分に分かれており、それぞれメインクロックでてい倍したクロックを分周して振り分けます。ただし、それぞれ動作上限のクロック周波数が異なりますので、設定時はそれを超えないようにしておかなければいけません。
  CPU : MAX 150MHz
  HSB : MAX 75MHz
  PBA : MAX 37.5MHz
  PBB : MAX 75MHz
 取りあえず、PLLは6てい倍の120MHzで動作させることにしますので、CPUは120MHz、HSBは60MHz、PBAは30MHz、PBBは60MHzで動作させることにしましょう。なお、SDRAMコントローラはHSBのクロックで動作しますので、60MHz動作となります。本来はPLL1も動かして適切に割り当てるべきですが、取りあえずということで。
 サンプルのPLLの初期化手順は以下の通りです。PLLは発振出力をループバックしたものを位相比較回路で元クロックと合わせますから、通常はてい倍率を変えたり、動作をONにしたあとは、切り替わるまで時間がかかります。切り替わって、周波数が安定している状態をLockされた状態と言いますが、その状態になるまで待機する必要があります。

  1.PLLCTRL0の設定(6定倍、PLL動作許可、クロックソース=OSC0)
  2.PLL0がロックするまで待機(ISRのLOCK0ビット)
  3.CKSELでCPU,HSB.PBA,PBBの分周比を設定 (0x80818000をCKSELへ設定)
  4.CKSELが反映されるまで待機(ISRのCKRDYビット)
  5.MCCTRLをPLLへ切り替え
 
 <SDRAMのCLK(HSB)の波形>
 TDS3014(fc=100MHz)で見てるので、へろへろになってますが周波数は合ってますw
 b93.jpg 

NORフラッシュのアクセスタイミングの再設定
 さて、実は上記の設定をいきなりやると暴走してふっとびますw なぜかというと、AP7000の場合プログラムは外部のフラッシュROMに格納されますが、このクロックにもHSBのクロックを使っており、この周波数を上げることで、ROMのアクセスタイミング規定を守れなくなるからです。そうなるとプログラムコードをフェッチするためにROMからコードを読み出すときにデータ化けが発生して、正常な命令を読み出せなくなるからです。
 NGWに載っているNORフラッシュはtRC=70nsのアクセスタイミングです。このNORフラッシュをAVR32はリセット時は4clk cycleでアクセスします。ブート時は20MHz(1Clk=50ns)動作ですから200nsまでのROMであれば十分に動作します。
 ところがPLLを起動して、バスクロックを上記の60MHz動作にすると、計算上16.666*4=66.66nsとなりますので間に合いません。またセットアップ時間がリセット時は1clkですが、こちらも16.66nsとなりフラッシュROMのtDFが25nsであることを考えると、かなり危ないです。
 そんなわけで、PLLを切り替える前にサイクルを各1clk分引き延ばします。これにより、十分タイミングに間に合うようになります。
 このようなタイミング設定をするのがSMCという(Static Memory Control)部分ですが、設定が結構細かくできます。ただ、設定方法は注意が必要です。基本的には以下のパラメータとなります。↓はデータシートからコピペ。
 b94.jpg  
  NRD_CYCLE = NRD_SETUP + NRD_PULSE + NRD_HOLD
  
 実際に設定するのはCYCLEとSETUPとPULSEで、HOLDはAVR32内部で勝手に決まります。例えば今回のようにサイクルを広げる場合、必ずCYCLEを先に設定しておく必要があります。そうしないと、SETUPやPULSE値を書き込んでも上記の式を超える値を設定しても反映されないからです。ちなみにレジスタの順番はSETUP、PULSE、CYCLEの順に並んでいますから、いかにも間違えてくれとも言わんばかりの順番だったりします・・・orz
 長くなってきたので、SDRAMの設定は次に。
posted by もろぼし☆らむ at 00:33| Comment(0) | TrackBack(0) | 電子工作