趣味の電子工作などの記録。時にLinuxへ行ったり、ガジェットに浮気したりするので、なかなかまとまらない。
RSS icon
  • また気圧計の電池がなくなりました

    投稿日 2013年 11月 24日 コメントはありません

    前回10月30日に電池交換した気圧計ですが、今日電池がなくなって止まってました。
    今日の昼間は稼働していたので、ほぼ25日間の動作ということになります。単三で作れば2ヶ月くらい駆動できるかな?
    自作の電池駆動機器で簡単にこれだけの期間連続動作させられるようになるなんてしばらく前には予想できませんでしたね。


  • 秋月に新しいユニバーサル基板が登場

    投稿日 2013年 11月 24日 コメントはありません

    秋月電子のサイトを見ていたら、新しいユニバーサル基板が出ているのを発見。

    従来の2.54mmピッチの端子間に表と裏にそれぞれ異なる向きで電源バスを這わせて、交差点の部分にスルーホールを設けた構造みたい。
    単一電源の回路であれば電源・GND配線が格段に簡単になる上に、4層基板には届かなくても電源インピーダンスは確実に下がるはずので、いろいろ作りやすくなりそう。
    (かといって、沿面距離は何をしても大幅に小さくなってしまうので、高電圧がかかる回路は絶対に避けないといけないですが)

    プルアップやプルダウンの抵抗・パスコンも1005のチップ品を使えば電源グリッドのスルーホールから直接接続できそうな感じ。1608ではちょっと苦しいかな(いけたらうれしいのだけど)

    サイズはBタイプCタイプの2種類。今度見かけたら買ってみることにします。


  • 寒冷前線のレーダー画像

    投稿日 2013年 11月 10日 コメントはありません

    日本海の寒冷前線に沿って綺麗に強い雨の地域が並んでいます。

    201311100800-00

    一方で天気図は5時間前のものですが、

    13111003

    といった感じ。日本海の真ん中辺りにあった低気圧が今は石狩湾辺りにあるんですかね。
    画像は気象庁のホームページからのものです。誰でも居ながらにしてこういう情報が手に入る。便利な世の中です。

    <追伸>
    上記は5時間前の午前3時のものでしたが、2時間前の午前6時のものを追加しておきます。

    13111006


  • DIP版18F14K50ボードを作ってみました

    投稿日 2013年 11月 6日 コメントはありません

    余っていたDIP版のPIC18F14K50とユニバーサル基板でテスト用のボードを作ってみました。

    OLYMPUS DIGITAL CAMERA

    このボードを作ってみたのは、部品が余っていたから・・・というのもありますが、秋月の800円PIC18F14K50ボードとブレッドボードの組み合わせでは不便な点があったからです。それは、

    • 秋月の800円PIC18F14K50ボードではRA3はPICkit3へ接続するようになっている。
      よって、ブレッドボードではこの端子は扱えない。
    • USBでいろいろなソフトウェアを作って試すには、ブレッドボードでは持ち運びには不便。

    というところからです。双方向でのデータのやりとりを試してみたいので、余っていた気圧センサとI2Cのキャラクタ液晶も載せてあります。気圧センサは液晶の下に置いてあります。(最初の写真は気圧センサから読み取った値を液晶に表示しています)

    OLYMPUS DIGITAL CAMERA

    裏面はこんな感じです。(自分用です。回路図を作っていないのでその代用(^^;。クリックすると特大画像が開きます。)

    OLYMPUS DIGITAL CAMERA

    各部分の説明(自分用です)

    • 基板裏面から見て右上の部分
      USBのBコネクタで、緑色の部品は100mAの保護用ポリスイッチです。
    • 基板裏面から見て真ん中やや上
      PIC18F14K50です。GND周りに付いている2個の小さな1608のコンデンサは1uFのチップコンです。VUSBのコンデンサは0.22~0.47uFが推奨だったと思いますが、半端な容量のコンデンサが手持ちになかったので1uFとしています。茶色の2012の大きなコンデンサ2個はクリスタル周りの22pFで、その左の4.7kΩはRA3のプルアップ抵抗、その左の1.2kΩ×2個はLEDの電流制限抵抗、その左の24kΩはタクトスイッチのプルアップ抵抗です。ポートCは内蔵プルアップがないので外付けせざるを得ませんでした。
    • 基板裏面から見て左の部分
      アナログジョイスティックと3.3VのCMOSレギュレータです。CMOSレギュレータIN/OUTには1uF16Vのチップコンがそれぞれついています。
    • 基板裏面から見て左下の部分
      2個のタクトスイッチです
    • 基板裏面から見て右下の部分
      LCDモジュールへのコネクタと気圧センサです。4.7kΩ×2個はI2Cバスのプルアップ抵抗です。

    ポートアサインは以下の通りとしています。

    • RA3 – ブートローダスイッチ(L:ブートローダ起動)
    • RB4 – I2CバスSDA
    • RB5 – not use
    • RB6 – I2CバスSCL
    • RB7 – not use
    • RC0 – 3.3Vリファレンス電圧入力
    • RC1 – アナログジョイスティックY軸入力
    • RC2 – アナログジョイスティックX軸入力
    • RC3 – LED GREEN(H:点灯)
    • RC4 – LED RED(H:点灯)
    • RC5 – not use
    • RC6 – スイッチ入力左(L:ON)
    • RC7 – スイッチ入力右(L:ON)

    I2Cバスのアドレスアサインは以下の通りです。

    ソフトウェアはとりあえず以下の通りです。

    • PIC18F14K50側ブートローダ
      タクトスイッチとLEDのポートアサインを修正
    • PIC18F14K50側アプリケーション
      カスタムHIDデバイスのデモプログラムをベースにして、先に作った気圧センサ用のPIC16F1823用のI2C/LPS331/LCDドライバを移植。
      さらにTimer0割り込みを使って時間管理(似非マルチタスク処理)ができるように割り込み処理を追加。
    • Linuxホスト側ブートローダ
      Microchipのサンプルプログラムのまま
    • Linuxホスト側アプリケーション
      昔作ったHIDRAWでデータをやりとりするプログラムを改造し、双方向で希望するデータのやりとりができることを確認

    これでLinux環境下でデータのやりとりをUSB経由で好きなようにできそうです。


  • マウスエミュレータ(?)を作ってみた

    投稿日 2013年 11月 5日 コメントはありません

    例によって Microchip Solutionsの中のサンプルプログラムの中にマウスのデモがあったので、これをベースにアナログジョイスティックで操作するマウスエミュレータを作ってみました。

    OLYMPUS DIGITAL CAMERA

    写真が完成した状態です。アナログジョイスティックでマウスカーソルを上下左右に移動させることができ、その下のタクトスイッチ2つはマウスの左クリック・右クリックに対応します。中央やや上のタクトスイッチはBootloaderの起動スイッチです。押しながらUSBケーブルを挿すことでHID Bootloaderが起動します。

    USBバスは様々な要因で電圧が変動するので、USBの5Vから以前作った3.3Vレギュレータ小基板で3.3Vを生成してADCの基準電圧とアナログジョイスティックの入力電圧としています。ADCの基準電圧をRB4(AN4=Vref+)に加えて、X軸方向の出力をRB5(AN5)に、Y軸方向の出力をRB6(AN7)に加えています。左右クリックの代わりのタクトスイッチはRB6とRB7に接続し、内部プルアップを有効にしています。RB4にはLEDを接続、RB5にはBootloader用のタクトスイッチを接続していますが、RB5は外部プルアップを行っています。
    XY軸はアナログジョイスティックモジュールを基板に載せるときの結線とXYの正負の関係が合わなかったため、内部で読み替えています。

    ソフトウェアは上記のハードウェアに合わせた変更と、LEDやSWなどで評価ボードに載っているものに関する制御を取っ払っているのみです。参考になるかわかりませんが、ソースコードをアップロードしておきます。ライセンスは修正部分を除いてオリジナルに従ってください。修正箇所はご自由にどうぞ。なお当然無保証です。PIC18F14K50以外では余分なソースコードは取り除いていませんが一方でコンパイルすらしていませんので、そのつもりで。(修正したソースコード:mouse.c
    そうそう、USBのベンダID、デバイスIDも設定しているファイルを含んでいない=当然変わりませんので、これまたそのつもりでお願いします。

    コンパイルはMPLAB-X v1.90とMPLAB C18の組み合わせで、もちろんLinux上です。
    設計において今回苦労したのは、コンパイルして生成されたHEXファイルが1000H番地以降にロードするようにリンクされていない、というものです。
    もちろん、見た目では

    Screenshot

    という感じで rm18f14k50_g.lkr ファイルがプロジェクトに取り込まれていますし、ソースコード自身にも384行目付近からベクタを再配置するためのマクロ定義がされていて問題なさそうにみえるのですが、生成されるHEXファイルは0番地付近から生成されている・・・というものです。

    ・・・・で、悩んで悩んで・・・・ふとMPLAB-Xを再起動したところ、Linker Filesからrm18f15k50_g.lkrが抜けているではないですか・・・。改めてプロジェクトに取り込ませたところ、無事に1000H番地付近からのオブジェクトが生成されて、HID Bootloaderでダウンロード、実行することができました。

    しかし、(Linux版だけかもしれませんが)MPLAB-Xはまだこの手の「再起動すると治る」という不具合がたくさんあります。何とかならないもんですかね。趣味で使う分にはまだ納期もないのでいいですが、プロフェッショナル用途では致命的だと思うのですが。


  • PIC18F14K50用にブートローダを準備する

    投稿日 2013年 11月 4日 コメントはありません

    PIC18F4550でブートローダが動いたので、次に本来のターゲットであるPIC18F14K50で動かしてみます。

    1.ブートローダの準備

    PIC18F4550のプロジェクトを開きます(自分の場合にはディレクトリごとコピーしてから開いてリネームしています)。次にProjectのPropertyを開き、PIC18F14K50の設定をActiveにして、PICkit3から電源供給するように設定変更します。

    ブートローダ用のSWとLEDは io_cfg.h の131行目付近からに記述がありますので、

        /** LED ************************************************************/
    //    #define mInitAllLEDs()      LATC &= 0xFE; TRISC &= 0xFE;
    //    #define mLED_1              LATCbits.LATC0
    //    #define mLED_1_On()         mLED_1 = 1;
    //    #define mLED_1_Off()        mLED_1 = 0;
    //    #define mLED_1_Toggle()     mLED_1 = !mLED_1;
        #define mInitAllLEDs()      LATBbits.LATB4 = 0; TRISBbits.RB4 = 0;
        #define mLED_1              LATBbits.LATB4
        #define mLED_1_On()         mLED_1 = 1;
        #define mLED_1_Off()        mLED_1 = 0;
        #define mLED_1_Toggle()     mLED_1 = !mLED_1;
    
        /** SWITCH *********************************************************/
    //    #define mInitAllSwitches()  mInitSwitch2();
    //    #define mInitSwitch2()      {ADCON1 = 0x0F;}
    //    #define sw2                 PORTAbits.RA3
    //    #define mDeInitSwitch2()    {ADCON1 = 0x07;}
        #define mInitAllSwitches()  mInitSwitch2();
        #define mInitSwitch2()      {TRISBbits.RB5 = 1; ANSELHbits.ANS11=0;}
        #define sw2                 PORTBbits.RB5
        #define mDeInitSwitch2()    {TRISBbits.RB5 = 1; ANSELHbits.ANS11=1;}

    という感じで、修正します。ここではLEDはポートC0、SWがポートA3に接続する前提だったのを、LEDはポートB4、SWはポートB5に接続するように修正しています。そして、main.cの325行目にある ENABLE_FLASH_SIGNATURE_VERIFICATION の定義はコメントアウトして、SIGNATUREのチェックはしないようにします。
    これでビルドを行い、PIC18F14K50に書き込みを行うと、無事にブートローダアプリから認識されるようになりました。

    2.ブートローダでロードするサンプルの準備

    サンプルは例によってCDC Basic Demoを使いました。同様にProjectのPropertyを開き、PIC18F14K50の設定をActiveにします。プロジェクトのディレクトリ内に「microchip_solutions_v2013-06-15/USB/Device – Bootloaders/HID/Firmware – PIC18 Non-J/Linker files for applications」の下にある「rm18f14k50_g.lkr」をコピーして、Projectsの「Linker files」を右クリックして「Add Existing Item…」を選択してプロジェクトに加えます。他にもリンカファイルは存在しますが、今回加えたファイル以外は薄文字になっていることを確認します。
    さらに、このままビルドすると「p18f14k50.libが見つからない」というエラーに遭遇します。これはライブラリとして実在するのは「p18F14K50.lib」なのに対して、探しているのが「p18f14k50.lib」と全て小文字のファイル名のためです。ですので、

    $ cd /opt/microchip/mplabc18/v3.40/lib
    /opt/microchip/mplabc18/v3.40/lib $ sudo ln -s p18F14K50.lib p18f14k50.lib

    として、大文字でも探せるようシンボリックリンクを張って誤魔化します。(Windowsでは問題にならず、Linuxでは問題になるケース)

    これでビルドすると無事に通るようになりました。

    ビルドしたアプリケーションは「microchip_solutions_v2013-06-15/USB/Device – CDC – Basic Demo/Firmware/MPLAB.X/dist/LPC_USB_Development_Kit_PIC18F14K50/production」の下に置かれますので、ここにできたHEXファイルをブートローダアプリケーションで指定して書き込んでやると無事にCDC Basic Demoとして動作しました。


  • PIC18F用のHIDブートローダの調査

    投稿日 2013年 11月 2日 コメントはありません

    PIC18F14K50は割り切って使うにはなかなか便利なデバイスなのですが、MPLAB-X(Linux版)とPICkit3の組み合わせで毎回書き換えて使うには、書き込む度に

    1. PIC18F14K50側のUSBケーブルを抜いて、
    2. PICkit3を接続し、
    3. ダウンロードをして、
    4. PICkit3側のUSBケーブルを外してから
    5. PICkit3を外して、
    6. PIC18F14K50側のUSBケーブルを挿す
    7. (次回書き込みに備えて)PICkit3側のUSBケーブルを挿す

    というなかなか面倒くさい手順が必要です。理由は、

    1. ICSPの端子とUSBのD+/D-端子を共有している
    2. MPLAB-XのPICkit3に対する制御がイマイチ
      (MPLAB-Xからターゲットへの電源が供給されっぱなしなので、一旦PICkit3を外して電源供給を止める必要がある)

    というためです。

    そこで調べていたところ、HIDプロトコルによるブートローダがMicrochipから提供されていることがわかりました。これを使うと、

    • ブートローダを書き込んであればPICkit3なしでターゲットプログラムを書き換えることができる
    • PowerON時のポートの状態に応じてブートローダを起動させたり、ターゲットプログラムを起動させたりするのを切り替えることができる
    • ターゲットプログラムのダウンロード用のLinux用のホストプログラムはブートローダに同梱されている(Qtベースっぽい)
    • ブートローダは0番地付近の約4KBを占有する模様。割り込みベクタは4KB上のアドレス(1000H~)に移動させる細工がされている。
    • アプリケーションプログラムも当然1000Hあたりからに置かれるように細工しなければならない

    ということがわかりました。

    どこから手をつけるか考えていたところ、CDCクラスのBasic Demoのlkrファイルが「rm18f4550 – HID Bootload.lkr」となっていていかにも対応していそうなファイル名です。中身も、

    LIBPATH .
    
    FILES c018i.o
    FILES clib.lib
    FILES p18F4550.lib
    
    CODEPAGE   NAME=bootloader START=0x0          	   END=0xFFF          PROTECTED
    CODEPAGE   NAME=vectors    START=0x1000       	   END=0x1029         PROTECTED
    CODEPAGE   NAME=page       START=0x102A            END=0x7FFF
    CODEPAGE   NAME=idlocs     START=0x200000          END=0x200007       PROTECTED
    CODEPAGE   NAME=config     START=0x300000          END=0x30000D       PROTECTED
    CODEPAGE   NAME=devid      START=0x3FFFFE          END=0x3FFFFF       PROTECTED
    CODEPAGE   NAME=eedata     START=0xF00000          END=0xF000FF       PROTECTED

    102A番地から7FFF番地までに配置されそうな感じです。
    そこで、手始めにPIC18F4550(AE-18F4550ボード)でブートローダを動かしてみることにしました。

    途中までは順風満帆かと思われたのですが・・・・

    ブートローダのプロジェクトは microchip_solutions_v2013-06-15/USB/Device – Bootloaders/HID/Firmware – PIC18 Non-J/MPLAB.X に収められています。これを開いて、ProjectのPropertyを開いてPIC18F4550の設定をActiveにすることと、PICkit3から電源供給するように設定変更します。
    ブートローダ用のSWとLEDは io_cfg.h を見ると68行目付近から記述があり、LEDはPORT D0、SWはPORT B4に接続する前提になっていることがわかります。そこで、ブレッドボード上で適当にLEDとSW(プルアップ抵抗をつけておきます)を配線します。
    ビルド自体はこれで難なく通り、書き込みもできました。(コンパイラは例によってMPLABC18です)
    18F4550のPORT B4をGNDに落とした状態でUSBポートをホストPCと接続するとLEDがチカチカ点滅します。そして、「microchip_solutions_v2013-06-15/USB/Device – Bootloaders/HID/Firmware – PIC18 Non-J/HIDBootloader(Linux)」を起動すると「Device Attatched」という表示が出て、無事に認識されました。

    次にアプリケーションですが、先に調査した通り、CDC Basic Demoで試してみます。

    microchip_solutions_v2013-06-15/USB/Device – CDC – Basic Demo/Firmware/MPLAB.X に格納されたプロジェクトを開いて、ProjectのPropertyを開いてPIC18F4550の設定をActiveにしてビルドします。
    ビルドして出来上がったHEXファイルはmicrochip_solutions_v2013-06-15/USB/Device – CDC – Basic Demo/Firmware/MPLAB.X/dist/PICDEM_FSUSB/productionの下に格納されています。これをHIDBootloader(Linux)で File → Import Firmaware Image で読み込ませた後、Program → Erase/Program/Verify Device で書き込みます。書き込み後、PORT B4をHレベルになるようにした後、Program → Reset Device でリセットを掛けます。・・・が、再びBootloaderに認識されてしまいました。

    うーん、HID Bootloader上のアプリケーション・・・動きません。

    ここからが苦難の道のり・・・(涙)

    ブートローダのファームウェア側main.cを見ると、421行目近辺に

    DoFlashSignatureCheck:    
        //Check if the application region flash signature is valid
        #ifdef ENABLE_FLASH_SIGNATURE_VERIFICATION
            if(*(rom unsigned int*)APP_SIGNATURE_ADDRESS == APP_SIGNATURE_VALUE)
            {
                //The flash signature was valid, implying the previous 
                //erase/program/verify operation was a success.
    
                //Go ahead and jump out of bootloader mode into the application run mode
        		_asm goto REMAPPED_APPLICATION_RESET_VECTOR _endasm	
            }    
            //else the application image is missing or corrupt.  In this case, we
            //need to stay in the bootloader mode, so the user has the ability to 
            //try (again) to re-program a valid application image into the device.
    
        	//We should stay in bootloader mode
            _asm goto BootMain _endasm
        #else
    
            //Ideally we shouldn't get here.  It is not recommended for the user to 
            //disable both the I/O pin check and flash signature checking 
            //simultaneously.  Doing so would make the application non-recoverable
            //in the event of a failed bootload attempt (ex: due to power loss).
            _asm goto REMAPPED_APPLICATION_RESET_VECTOR _endasm	
    
        #endif

    というコードがあって、APP_SIGNATURE_ADDRESS番地にAPP_SIGNATURE_VALUEが書かれていないと、BootMain(ブートローダのMain)に飛んでいくことがわかります。具体的には、0x1006番地が0x600Dでなければなりません。
    そこで、MPLAB IPEでROMの内容を吸い出して確認してみたところ、見事に0xFFFFになっていました・・・。ここをMPLAB IPEで0x600Dに変更して書き戻してみたところ、ブートローダプログラムでは「Detached」になり、さらにGtkTermで /dev/ttyACM0 にアクセスしてCDC Basic Demo(入力した文字が1文字ずれてエコーバックされる)の機能を確認することができました。
    つまり、SIGNATURE VALUEが書かれていないことが原因であることがわかりました。

    では、SIGNATURE VALUEは誰が書くのか?

    ソースコードの「BootPIC18NonJ.c」の359行目からのProcessIO()を見ると、532行目付近に

    			case SIGN_FLASH:
    			    SignFlash();
    			    BootState = IDLE;
    			    break;

    というコードがあって、これはホスト(PC)からのコマンド解析部分のようです。ホストから「SIGN_FLASH」というコマンド(ちなみに値は0x09)が来ると、591行目付近のSignFlash()という関数が呼び出されて、該当領域を読み込んだ後、バッファ内のSIGNATUREの部分を書き換えて、書き込む処理を行うように見えます。
    つまり、そもそもこの「SIGN_FLASH」というコマンドが来ていないのではないか、ということになります。

    SIGN_FLASHが送られてくるコードになっているのか?

    こんどはホスト側のソースコードが格納されている「microchip_solutions_v2013-06-15/USB/Device – Bootloaders/HID/software_cross_platform/Bootloader」の下を見てみました。

    「SIGN_FLASH」を送出するっぽいコードは、Comm.cppの640行目付近にある、「Comm::SignFlash(void)」という関数のようです。送られていれば、それなりのデバッグメッセージを出すコードのようなのですが、残念ながらビルドできる環境がありません。(方法もわかりません)
    この部分を呼び出すのはMainWindow.cppの555行目付近のようです。

        if(failureDetected == false)
        {
            //Successfully verified all regions without error.
            //If this is a v1.01 or later device, we now need to issue the SIGN_FLASH
            //command, and then re-verify the first erase page worth of flash memory
            //(but with the exclusion of the signature WORD address from the verify,
            //since the bootloader firmware will have changed it to the new/magic
            //value (probably 0x600D, or "good" in leet speak).
            if(deviceFirmwareIsAtLeast101 == true)
            {
                comm->SignFlash();
                //Now re-verify the first erase page of flash memory.
                if(device->family == Device::PIC18)
                {

    書き込み後にVerifyをする関数の最後の方で、Verifyに問題がなく、なおかつdeviceFirmwareIsAtLeast101がセットされていれば、呼び出されるようです。で、この値はブートローダファームウェアのバージョンが1.01以上であればセットされるようです。
    実際にセットしている箇所は、MainWindow.cppの1150行目付近、GetQuery()という関数・・・GetQueryコマンドに対する応答パケットを解析する部分の中で、

        for(int i = 0; i < MAX_DATA_REGIONS; i++)
        {
            if(bootInfo.memoryRegions[i].type == END_OF_TYPES_LIST)
            {
                //Before we quit, check the special versionFlag byte,
                //to see if the bootloader firmware is at least version 1.01.
                //If it is, then it will support the extended query command.
                //If the device is based on v1.00 bootloader firmware, it will have
                //loaded the versionFlag location with 0x00, which was a pad byte.
                if(bootInfo.versionFlag == BOOTLOADER_V1_01_OR_NEWER_FLAG)
                {
                    deviceFirmwareIsAtLeast101 = true;
                    qDebug("Device bootloader firmware is v1.01 or newer and supports Extended Query.");
                    //Now fetch the extended query information packet from the USB firmware.
                    comm->ReadExtendedQueryInfo(&extendedBootInfo);
                    qDebug("Device bootloader firmware version is: " + extendedBootInfo.PIC18.bootloaderVersion);
                }
                else
                {
                    deviceFirmwareIsAtLeast101 = false;
                }
                break;
            }

    bootInfo構造体のversionFlagがBOOTLOADER_V1_01_OR_NEWER_FLAG(これはDeviceData.hの中で0xA5として定義されています)となっているかで判別しているようです。そしてこの構造体は、Comm.hというヘッダファイルで、

        #pragma pack(1)
        struct MemoryRegion
        {
            unsigned char type;
            unsigned long int address;
            unsigned long int size;
        };
    
        struct BootInfo
        {
            unsigned char command;
            unsigned char bytesPerPacket;
            unsigned char deviceFamily;
            MemoryRegion memoryRegions[MAX_DATA_REGIONS];
            unsigned char versionFlag;
            unsigned char pad[7];
        };

    として宣言されています。BootInfoは受信したパケットそのもののようなので、WiresharkでUSBのパケットキャプチャをしてみました。

    Screenshot-USB bus number 1   [Wireshark 1.6.7 ]

    0040Hからが受信したデータの部分で、構造体の構造にそって読んでいくと、赤丸の部分がversionFlagで0xa5になっていることがわかります。つまり、ブートローダのファームウェア側からは正しく情報が上がっているようです。

    SIGN_FLASHは送出されているのか?

    書き込みの処理の部分全体をUSBパケットキャプチャしてみたところ、最後のパケットは、

    Screenshot-USB bus number 1   [Wireshark 1.6.7 ]-1

    となっていて、最後のコマンドは0x07で「GET_DATA」でした。遡っていってもずーっと0x07で、その前が0x06(PROGRAM_COMPLETE)が2つ、その前が0x05(PROGRAM_DEVICE)がずっと続きます。先頭から書いていくと、

    • 0x04(ERASE_DEVICE)
    • 0x02(QUERY_DEVICE)
      これに対する応答もきちんとVer1.01以上である0xa5が含まれていました。
    • 0x05(PROGRAM_DEVICE)がたくさん
    • 0x06(PROGRAM_COMPLETE)が2つ
    • 0x07(GET_DEVICE)はたくさん

    という感じで、0x09(SIGN_FLASH)は含まれていません。・・・・そりゃあ、ダウンロードしたプログラムが動くわけがありません。

    で、ここで気づいたことが・・・・

    よくみると、ブートローダアプリケーションに表示される文字列は、ブートローダアプリのソースコードではコメントアウトされているものになっています。つまり、ソースコードはついているけど、それをコンパイルしたアプリケーションがついているわけではないようです。・・・・おいおい。

    ちなみに、タイムスタンプをみると、ソースコードのタイムスタンプは2013年6月18日2時37分18秒で、添付されているアプリケーションのタイムスタンプは2013年6月18日2時36分36秒です。・・・・この微妙な逆転、一体何なんでしょうね・・・・。

    最終的な対策

    Qt5をコンパイルする環境はないので、 処置するとしたらブートローダのファームウェア側で処置するしかありません。
    簡単に対策するなら、SIGNATUREのチェックを外す、ということになります。

    main.c の317行め付近に、

    //Never comment this out.  If you do, you won't be able to recover if the user
    //unplugs the USB cable (or power is lost) during an erase/program sequence, 
    //unless you rely on the I/O pin check entry method.  The only reason ever to
    //comment this out, is if you are trying to use this bootloader firmware with
    //an old bootloader PC application that does not have knowledge of the v1.01
    //and newer command set (with QUERY_EXTENDED_INFO and SIGN_FLASH commands).
    //However, a better solution in such a case, is to upgrade to use a newer PC
    //application to do the bootloading.
    #define ENABLE_FLASH_SIGNATURE_VERIFICATION

    というコードがあって、コメントには、「ここはコメントするな!」と書いてありますが、そんなことを言っても仕方ありませんので、ここをコメントアウトしてSIGNATUREチェックをやめさせます。コメントの内容によると、書き換え中に電源を切ったりUSBケーブルを抜いたりすると、復活できなくなる・・・・ということみたいです。

    ここをコメントしてビルドしたブートローダを書き込んで、PORT B4をGNDに落としてブートローダを起動、ブートローダアプリケーションでCDC Basic Demoを書き込んでみました。その後、PORT B4をHにしてブートローダアプリの「Reset Device」をクリックしたところ、無事にCDC Basic Demoが動作しました。

    疲れてしまったので、PIC18F14K50でのトライはまた今度ということで。

    おまけ

    HIDブートローダを使う場合の各PICでのリンカスクリプトは「microchip_solutions_v2013-06-15/USB/Device – Bootloaders/HID/Firmware – PIC18 Non-J/Linker files for applications」にあるようです。