楽天市場
[無料でホームページを作成] [通報・削除依頼]

LPC1114 USBブートローダー


前回ご紹介したLPC1114FN28/104のHID-SerialアダプターはLPC1114のリソースからして随分と勿体無い使い方でした。
この点を鑑み、今回の作例はリソースを十分に生かせるUSB直結のブートローダーです。
(mbed全盛の今、無謀な試みとも言える。)

2015.06.30 追記 ターゲットボードの回路図を更新し、基板を作り直しました。
img_20150630-235738.jpg
img_20150630-235809.jpg
img_20150713-124305.png
----------------------------- 追記 ここまで

2015.07.01 追記

ブートローダーの動作確認には
"番外 LPC1114FN28/102 アセンブラサンプル"のページで紹介したHEXファイルが使用できます。
以下は上記ページに添付の"flash_dump.hex"を読み込ませ、3つのSWをOFFにした状態でリセット
SWを押し、プログラムを実行させた結果です。

これはアセンブラで作成したHEXファイルですが、もちろんCで作成したHEXファイルでもサイズの制約を満たせば、
問題なく作動します。

img_20150701-220707.jpg
------------------------------ 追記 ここまで

2015.09.02 追記 以下の情報は間違いでしたので削除します。
2015.07.03 追記 
本ページに記載のファームウエアを別の2個のLPC1114に書き込んだところ、USBデバイスと認識されませんでした。
解決方法
 割り込みルーチンRecepcionUSB内のnopの数で調整する。

最初のデバイスをUSBデバイスと認識した条件
RecepcionUSB:
    push    {lr}
    nop
@    nop
@    nop
    mov    r1,r8


2つ目のデバイスをUSBデバイスと認識した条件
RecepcionUSB:
    push    {lr}
    nop
    nop
@    nop
    mov    r1,r8


3つ目のデバイスをUSBデバイスと認識した条件
RecepcionUSB:
    push    {lr}
    nop
    nop
    nop
    mov    r1,r8


------------------------------ 追記 ここまで


img_20150623-214802.jpg

[1]ファームウエアのジェネリック化
従来紹介してきたUSBのファームウエアは全てHID仕様でした。
HID仕様ではWindows標準のデバイスドライバーが使用されるため使い勝手が良いのですが、
ホストからの定期的な問い合わせに応える必要があります。
今回のファームウエアではHIDの仕様をジェネリック(汎用)の仕様に変更しました。


[2]ファームウエアの仕様
①汎用デバイスの場合、別途デバイスドライバーが必要ですが、これには16FUSBで公開しているlibusbのドライバーを使用します。
②16FUSBのソースを参考にLPC1114のソースに手を加えて、HIDの選択・非選択が行えるようにしました。
③データはホストからのVendor Requestに載せて転送される。
④Vendor Request概要
ホストからの bmrequesttype = 01000000B を受信すると、続くbmrequestの内容(コマンド)により該当するIAPを操作します。
ホストから転送されるコマンドは4種類
E:セクター0からセクター6までを一括消去、ブートローダーのファームウエアが書きこまれるセクター7は消去しない。
W:ホストから転送された4バイトのデータをバッファーRAM(アドレス$10000200~$100005FF)に書き込む。
C:バッファーRAMの内容1024バイトをPage No.で指定したFlash領域に書き込む。
B:バッファーRAMの消去(0xFFを書き込む)。
⑤ホストの要求によりデバイスからホストへデータを返すことも出来ますが、今回は使用していません。

img_20150623-215316.jpg

⑥ブートローダーモードとユーザープログラムモード
USBから給電できるのでUSBを繋いだままユーザープログラムを実行できるように工夫しました。
D-とプルアップ抵抗の間にスイッチ(Boot SW)を設け、ブートローダーを作動させる時のみBootSWをONにします。
書き込みが完了したら、USBプラグを抜かずにBootSWをOFFにします。
このときPCで認識していたUSBデバイスは無効となり、(認識が取り消される)USBケーブルは電源供給にのみ使用されます。
この状態でリセットSWを押すとユーザープログラムが起動します。

プログラムのフローチャートを以下に示します。
USBのD-とBootSWに繋がるPIO1_1の端子はBootSWをOFFにしてもデフォルトで内部プルアップされているので、いったんプルダウンしてからBootSWの状態を検出し、ブートローダーモードとユーザープログラムモードを切り替えます。

img_20150623-215146.jpg

⑦各モードのメモリーマップ
ユーザープログラムモード(右側)
転送されたHEXファイルと同じコードが書き込まれるが、リセットベクター$00000004~$00000007のみ書き換える。
元のリセットベクターは$00006FFC~$00006FFFの領域に書き込まれる。
ユーザープログラムは$00000000~$00006FFBの範囲で作成しなければならない。
ユーザープログラムのRAMの使用と割り込みの使用に制約はない。

ブートローダーモード(左側)
ブートローダーモードではホストとの接続手順に入る前にRAMをROM領域にリマップする。
GPIO1割り込みを使用するのでリマップされたRAM上$000000B8~$000000BBに割り込みベクターを記述する。
※この手順によりユーザーはGPIO1割り込みを自由に使用できる。
USBとブートローダーの作業変数は$00000000~$0000009Fに配置、IAPで使用する作業領域もここに配置する。
ブートローダー本体は$00007000~$00007FFFに配置されブートローダーホストによりコード保護される。
※RAMをROM領域にリマップした状態でもFlashの消去・書き込みは正常に行える。

img_20150623-215106.jpg

[3]ホストプログラム
VC++CLIでlibusbの使用例がないかネットで探したところ、非常に使い易いフレームワークを見つけました。
Joseph Chiu さんの作成されたWinFormLibUsbというプログラムです。
Joseph Chiu さんに感謝申し上げます。すばらしいプログラムをどうもありがとうございました。

http://libusb.6.n5.nabble.com/Accessing-LibUsb-Win32-with-Visual-C-and-WinForms-td10502.html

今回は16FUSBの16FUSB_dio_sample_application_win32-src-1.0のソースを参考にWinFormLibUsbを書き換えてホストプログラムを作成しました。

img_20150623-215018.jpg

[4]書き込みの手順
①ターゲットボードのBootSWをオンにして、D-の信号線をプルアップする。
②USBコネクタを接続する。
③ホストプログラムを立ち上げる。
④左下のメッセージを確認する。
  "\\.\libusb 0-0001-0x04d8-0x0628" 正常
"Device was not detected"         異常
⑤"Browse"ボタンを押して書き込みしたいHEXファイルを選択する。
⑥"File transfer"ボタンを押すと書き込みを開始する。書き込み中は右側に緑色のゲージが表示される。

[5]書き込んだプログラムをテストする。
⑥に続く、USBは抜かずに、
⑦ターゲットボードのBootSWをオフにする。
⑧ResetSWを押すと書き込んだプログラムが実行される。
⑨ユーザープログラムでGPIO1_0とGPIO1_1を使用する場合はそれぞれのショートピンを外し、USB
のデータ線から切り離す。

[6]ターゲットボードの回路図
img_20150623-214841.png



本ページに記載のソフト一式は以下のページからダウンロードできます。

https://drive.google.com/file/d/15E0i_LeM6qlqwQaU73GmjclGMpqBKFZy/view?usp=sharing