/* * magicFlash for LPC1830-Xplorer * by uratan! 2012.10.25 */ magicFlash は LPC1830-Xplorer 用に えいやぁ と作られた boot-loader / ISP / monitor の総称です。ええ もちろん Flash Magic を利用するために 作ったのです。 (Flash Magic とは→ ) ●boot-loader magicFlash を SPIFI-flash 上に置くことにより 2nd boot-loader として 機能します。この際、P1_8 (GPIO1[1]) の状態を見て、HIGH なら user- program を、low なら USART3 経由の ISP を 起動します。 GPIO の内蔵プルアップを使いますので GND に落とすか否か のスイッチを 一つ付けてください。 boot-loader としては、SPIFI-flash の 0x10_0000〜 を user-program と して実行します。具体的には、M3MEMMAP レジスタに 0x8010_0000 を設定して shadow window に反映させておき、M3-core のみに自己リセットをかけます。 (ですので ここに至るまでに boot-ROM 及び magicFlash が触ったハード (ウェア設定はそのままの状態です、PLL1 は 288MHz、M3-core は 96MHz、 (SPIFI の SCK 設定は 18MHz になっているようです) なお magicFlash は uart-boot / SPIFI-boot に関わらず常に RAM 上に コードをコピーしてから RAM 上で実行されます。占有する領域は 0x1008_0000〜0x1008_4fff あたりです。ちょっと時間かかるけど許してね。 ●ISP magicFlash を SPIFI-flash 上に置いた上で P1_8 を low にして起動すると LPC1857 の振りをした ISP が USART3 ベースで起動します。 USART3 ポートは LPC1830-Xplorer では 外部コネクタ J10 の、 pin#13 (マニュアルでは I2C1_SDA) が U3_TxD (LPC1830が出力)、 pin#14 (マニュアルでは I2C1_SCL) が U3_RxD (LPC1830に入力) を使用します。 (ボーレートは 115,200bps までにしてください、お勧めは 57,600bps) 本 ISP は、Flash Magic (v6.95 にて動作確認)にて LPC1857 指定で 使います。LPC1857 の内蔵 flash 512kB 分(0x1A00_0000〜0x1A07_ffff)を、 LPC1830 の SPIFI-flash の 0x8010_0000〜0x8017_ffff にマップしてあり、 書き込んだプログラムは そのまま magicFlash boot-loader にて起動できます。 ただし一点だけ、HEX ファイルのアドレスレンジに関して注意点があります。 LPC1830 を SPIFI-boot で使う関係上 user-program は 0x0000_0000〜など LPC1830 のメモリマップに従ってアドレス配置しますが、Flash Magic で LPC1857 として使う場合、HEX ファイルのアドレスが 0x1A00_0000〜のもの しか受け付けてくれません。 これは objcopy.exe にて HEX ファイルを出力する際に、以下の オプションで (バイナリ内の番地はそのままに) HEX ファイルの番地のみを ずらすことで回避できます。(指定値がアドレスに加算されます) objcopy.exe -O ihex --change-addresses=0x1a000000 input.elf output.hex Flash Magic を使う上での最低限の read-device-signature / erase / program / verify(read) が出来ることを確認してあります。 Flash の bank 指定は無視しますし、セキュリティ関連の操作も実装して ありませんので むやみな使い方はしないでください。 (web の screen-shot のオプション設定を参照のこと) 純正 ISP のプロトコル他 詳細は LPC1830 の User-Manual にも記載が ありますのでご覧ください。magicFlash がどんな手抜きをしているかは fake_isp.c をご覧ください。 magicFlash 独自の拡張として、コマンド '/' を追加してあります。 これは mini monitor に切り替えるためのコマンドです。ISP モードでは が終端となりますので、'/' の後 CTRL-J を入力してください。 Flash Magic に boot-signature を計算させられると便利じゃん、と 思って作り始めましたが、SPIFI-boot だと いらないみたいですね。 (今のところ boot-signature 計算+追加は してくれないみたいです。 (今後 Flash Magic が version up する過程でいろいろと特定アドレスに (細工するようになったりして使いにくくなる可能性はあります。 (Flash Magic サイドが用意した汎用の ISP protocol とその (base-program がちゃんと付属してましたね… orz (HEX を登録しておくと 毎回 uart-boot して通信できるように (するみたい…。詳細は Manual.pdf の External Flash 章に。 ●(mini) monitor magicFlash を SPIFI-flash 上に置いた上で P1_8 を low にして起動 するとまず上記の ISP が起動します。ここで 純正の ISP では、 文字 '?' のみを待ってボーレートの自動調整を行い通信を確立しますが、 magicFlash ISP では、同時に文字 '/' も受け付けます。 この '/' の受信をもってボーレートを確定し mini monitor モードが 開始されます。 (この '/' は ISP コマンドとしての '/' とは違いますので、ここでは (CTRL-J はいりません。ISP コマンドとして入力する場合には CTRL-J が (必要です。まず いつものように RETURN を押して、「あれ?反応が (ない…」となったら CTRL-J ! です。) mini monitor のコマンドはまあ習うより慣れてください。 数値はすべて 16進数として扱います。'_' は単純に無視されますので 活用すると間違いも減ります。 なおコマンドは大文字・小文字を区別します。隠しコマンドもありますので minimon.c もご覧ください。 メニューには書けてませんが、危険なコマンドの場合 パラメータの デフォルト値を持っておりますのでそれで問題なければ省略が可能です。 (行末に余計な SPACE は置かないで!) [ デフォルト値一覧 ] command | default value of parameters ---------+----------------------------------------------------- d/e/w/s | addr: 0x0000_0000 (D/E/W/S も同様) L | hex-offset: 0x0000_0000 K | 0 (12MHz) B | flash-addr: 0x8010_0000 P | flash-addr: 0x8010_0000 src_addr: 0x2000_0000 len: 0x1_0000 c | flash-addr: 0x8010_0000 src_addr: 0x2000_0000 len: 0x1_0000 ・D/E/W/S コマンドについて 汎用のメモリアクセスコマンドです。当初 'd'/'e' だけで済むと思って いたんですが、そうは問屋が卸しませんでした。 'w' を追加したわけ → 8bitアクセスだと見えないレジスタがあったから。 'W' を追加したわけ → 余計に読むことで例外領域に触れることがあったから。 'S' を追加したわけ → Write-Only のレジスタが例外起こしたから。 'D'/'E' を追加したわけ → W/S を追加した流れで。 です。 ・L コマンドについて 'L' コマンドでは intel-HEX ファイルの (hex-offset)番地〜を、メモリ 0x2000_0000〜0x2000_ffff にロードします。この際、受け側メモリの範囲に 入らないアドレスのデータは無視されます。 'L' + [RETURN] の後、Tera Term の「Send file」にて hex ファイルを 送信します。「bianry mode」でなくてもいいみたい。 中断する場合は ':' をいくつか打ってください。 ・SPIFI-flash の消去と書き込みについて SPIFI のオペレーションに当たっては必ず 'I' コマンドで初期化して ください。 消去 'B' では、指定したアドレスが含まれる sector (64kB単位) が消去 されます。 書き込み 'P' では、消去は行わず書き込みのみを行います。任意のバイト長 書き込めます。 ちなみに flash ROM の、書き込みとは 1 のビットを 0 にすること、 消去とは 0 のビットを 1 にすること です。ですので 0x0f がすでに 書かれている部分を 0x07 に書き換えることは 実はできます。0x1f に 書き換えることはできません。 ライブラリの write 処理では、1byte 毎に write+read-back+verify してる みたいで、後者の場合そこでエラーと扱われ書き込みがそこで中断します。 なお 'B', 'P' で与える flash-addr は、0x0000_0000〜0x003f_ffff でも 0x8000_0000〜0x803f_0000 でもよいみたいですが、'd' でメモリを覗く ことが多い場合には 0x8000_* の方が間違いにくいように思います。 SPIFI の SCK は 'K' コマンドで変更できますが、変更した場合には 'I' コマンドで再初期化した方が無難と今のところ考えます。 その他、下記の操作例や web にある screen-shot をご参照ください。 ●SPIFI-flash からの boot 方法 Xplorer の DipSW を #1 から off-ON-ON-ON にして起動します。 なおスイッチを外付けに引き出す場合には、P1_1 には LPC1830 が 出力することがある(boot 失敗の場合)ので注意が必要です。 ●USART3 接続と uart-boot 方法 [1] Xplorer から 3.3V→RS-232C へのレベルコンバーターを経由して PC とシリアル接続します。Xplorer 側は外部コネクタ J10 の pin#13 (マニュアルでは I2C1_SDA) が U3_TxD (LPC1830が出力) に、 pin#14 (マニュアルでは I2C1_SCL) が U3_RxD (LPC1830に入力) に なります。 [2] Tera Term を使用してシリアル回線を開きます。パラメータは 例えば 57600bps/8bit/non-parity/1stopbit あたりで。 [3] Xplorer の DipSW を #1 から ON-ON-ON-off にします。 [4] ボードリセット後に Tera Term より '?' を送信すると 'OK' が返ります。 [5] メニュー「File」→「Send file」にて 'boot-magicFlash.bin' を送信します。 オプションの「binary mode」を忘れないでください。 ●mini monitor の使い方の例 ・magicFlash を SPIFI-flash への書き込む (やり方その1) uart3-boot して '?' に続いて boot-magicFlash.bin をバイナリ送信 '/' を送って mini monitor を起動し 'I' で SPIFI を初期化 'L' で magicFlash.hex を送信 'B 0' で消去しといて 'P 0' で書き込み ・magicFlash を SPIFI-flash への書き込む (やり方その2) すでに magicFlash が SPIFI-flash に書き込んであれば、 P1_8=low で SPIFI-boot して '/' を送って mini monitor を起動し 'I' で SPIFI を初期化 'L' で magicFlash.hex を送信 'B 0' で消去しといて 'P 0' で書き込み (このようにあっさり自分で自分を消去できますのでご注意ください) ・test.hex を書き込む (やり方その1) すでに magicFlash が SPIFI-flash に書き込んであれば、 P1_8=low で SPIFI-boot して Flash Magic で USART3 につなぎ test-hex-@1a00.hex を選んで書き込む。 ・test.hex を書き込む (やり方その2) すでに magicFlash が SPIFI-flash に書き込んであれば、 P1_8 = low で SPIFI-boot して '/' を送って mini monitor を起動し 'I' で SPIFI を初期化 'L' で test.hex を送信 'B' で消去したのち 'P' で書き込み (64kB 以内であればデフォルト値を活用してシンプルに処理できます) ・test.hex を書き込む (やり方その3) uart3-boot して '?' に続いて boot-magicFlash.bin をバイナリ送信 '/' を送って mini monitor 起動 'I' で SPIFI を初期化 'L' で test.hex を送信 'B' で消去したのち 'P' で書き込み (uart-boot だけで monitor として活用できます) ・64kB を超えてしまった hex ファイルの書き込み方 (以下、magicFlash mini monitor 起動後の操作) 'I' で SPIFI を初期化 'L' で test.hex を送信 (0x0000〜0xffff のみがメモリに残る) 'B 8010_0000' で消去したのち 'P 8010_0000' で書き込み、続いて 'L 1_0000' で test.hex を送信 (0x1_0000〜0x1_ffff がメモリに残る) 'B 8011_0000' で消去したのち 'P 8011_0000' で書き込み (Flash Magic を使えば 512kB まではシームレスに扱えます) ●FILES [このプログラムは有用であることを願って頒布されますが、*全くの無保証*] [です。商業可能性の保証や特定の目的への適合性は、言外に示されたものも] [含め全く存在しません。] 00README.txt --- このファイル Makefile --- make.exe 用の Makefile LPC1830.h --- レジスタ定義 link.cmd --- リンカースクリプト (やっぱりようわからん) mem_usage.h --- メモリ用途定義 (link.cmd とは連携してない) version.h --- バージョン番号 Startup.S --- CPU スタートアップ (とりあえず全部いり) main.c --- boot-loader(?) 部分 common.h --- system 共有定義 common.c --- system 共有関数群 (GPIO, uart はここ管轄に) rprintf.c --- printf()関数 (WinARM_20060606.zip 付属のサンプルより) fake_isp.c --- ISP もどき minimon.c --- mini monitor 本体 ihex.c --- intel-HEX フォーマットのファイルを読む spifi.c --- SPIFI-flash 制御 spifi_rom_api.h --- NXP, AN11206 より spifi_drv_M3.lib --- 〃 boot-magicFlash.bin --- magicFlash.bin を uart-boot 用に追加工したもの。 magicflash.hex --- magicFlash.bin の hex 形式ファイル zz-boot_header.exe --- uart-boot 用に bin->bin で加工するツール zz-boot_header.c --- と そのソース test/* --- 一般プログラムのたたき台 test/test.hex --- その hex 形式ファイル test/test.hex-@1a00.hex --- hex ファイルとしてのアドレスのみを0x1A00_0000 にずらしたもの コンパイラは yagarto の gcc-4.7.1(2012-0616版)を 使用しました。sh.exe と rm.exe は別途なんとかしてください。 make.exe すると magicFlash.bin 他を作成します。 ●参考: boot-header について 細かいことは LPC1830 のマニュアルを見ていただくとして、ダウンロード データの先頭 16バイトのヘッダーデータはおおむね以下の内容となります。 ここで下線部には、512バイトframe単位でのダウンロードデータ長を設定します。 +---------------------------------------------------------- |FFFFFFF0 : 1A FF 04 00 55 55 55 55 55 55 55 55 FF FF FF FF | ~~~~~ +---------------------------------------------------------- 最終データの長さは (16 + 512xframe長)バイトとなります。 この長さになるようにお尻にはダミーデータを追加します。 zz-boot_header.exe では以上の処理を行います。 ●参考: boot-process とハードウェアの初期化 Hardware-level-RESET +-------+-------+-------+-------+ | 初期化: CLOCK | SPIFI | USART3| GPIO | V ------+-------+-------+-------+-------+ +-----------------------+ : (*2)| | | (*1) | | (genuine) boot-ROM | ======> : IRC/ | | | boot- | + - - - - - - - - - - - + : 96MHz| | | pins | | SPIFI boot| ======> : | SCK= | | SPIFI | | +----------+ : | 18MHz| | pins | | USART3-boot| | ==========> : | | Auto- | | +------------+ | : | | rate | | V (0x1000*) V (0x8000*) : | | | | +-----------------------+ : | | | | | magicFlash boot-ROM | : | | | | | (copy codes on RAM) |(*3) : | | | | + - - - - - - - - - - - + : | | | | | main() (0x1008*) | ======> : | | | LEDs/ | +-----------------------+ : | | | TP1_8 | | V (*4) : | | | | | +--------+ : | | | | | | spifi | ====> : | | | | V (*5) | _boot()| : | | | | +-----------+ +--------+ : | | | | | fake_ISP()|--+ ==========> : | SCK= | Auto- | | +-----------+ V : | 18MHz| rate | | ^ +-----------+ : | | | | +---->| minimon() | ======> : | SCK= | | | +-----------+ : | 12MHz| | | : | or 'K'| | | (*1) boot-pin の状態は、GPIO じゃない経路で読み込んでいるようです。 (*2) boot-ROM は PLL1 を 288MHz に、M3-core を 96MHz に設定します。 (magicFlash は clock 関連は (ISP での SPIFI clk を除いて) さわりません) (*3) (プログラムを読み出しながら書き換えはできないので) 抱えている SPIFI-flash 書き込みライブラリは RAM 上で実行する必要があります。 また M3MEMMAP レジスタを変える都合上 でもあります。 (*4) user-program は SPIFI-flash の 0x10_0000 より格納されますが、 メモリ shadow window 機能で 0x0000_0000〜にマップされます。 header 付きの load-image 形式はサポートされません。 (*5) magicFlash そのものを uart-boot で起動した場合には P1_8 に よらず常に ISP/monitor モードとなります。 -- uratan@st.rim.or.jp