-
64bit環境にMPLAB-Xをインストールする
投稿日 2016年 2月 13日 コメントはありません故あって、Ubuntu17.1 MATE 64bit環境に16bitPICをターゲットとしてMPLAB-Xをインストールしました。
ダウンロードしたMPLAB-Xのtarファイルを展開すると、シェルアーカイブがでてくるので、これをスーパーユーザー権限で実行しても、
~$ sudo ./MPLABX-v3.20-linux-installer.sh 64 Bit, check libraries Check for 32 Bit libraries These 32 bit libraries were not found and are needed for MPLAB X to run: libexpat.so libX11.so libXext.so
となって、32bitライブラリをインストールするよう要求されます。・・・が、ここで表示されているものを素直にapt-getでインストールしようとしてもダメなのです。
じゃあ、どうしたらいいのかについては、こちらに記載があります。
~$ sudo apt-get install libc6:i386 libx11-6:i386 libxext6:i386 libstdc++6:i386 libexpat1:i386 パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 以下の特別パッケージがインストールされます: gcc-4.8-base:i386 gcc-4.9-base:i386 libgcc1:i386 libxau6:i386 libxcb1:i386 libxdmcp6:i386 提案パッケージ: glibc-doc:i386 locales:i386 以下のパッケージが新たにインストールされます: gcc-4.8-base:i386 gcc-4.9-base:i386 libc6:i386 libexpat1:i386 libgcc1:i386 libstdc++6:i386 libx11-6:i386 libxau6:i386 libxcb1:i386 libxdmcp6:i386 libxext6:i386 アップグレード: 0 個、新規インストール: 11 個、削除: 0 個、保留: 12 個。 5,061 kB のアーカイブを取得する必要があります。 この操作後に追加で 13.7 MB のディスク容量が消費されます。 続行しますか? [Y/n] (以下略)
ということで、パッケージ名の後ろに「:i386」をつける必要があったようです。わかってしまえばなんと言うことはないのですが、わからないと困りますよねぇ・・・。
ここをパスできれば、あとは再びシェルアーカイブを実行するとインストール完了です。併せて、XC16もダウンロードしたシェルアーカイブを実行してやると途中でライセンスファイル生成のためにNICのMACアドレスの確認ダイアログが出ますが、そのまま次へ進めてしまえばインストール完了です。
-
PIC18F14K50でUSB-CDCを作成
投稿日 2015年 2月 8日 コメントはありません久しぶりに秋月PIC18F14K50ボードをターゲットとしてUSBシリアルエミュレータを作成する必要がでてきたので、環境構築しました。
1.OSのインストール
今回はUbuntu14.04 LTS 日本語Remix 32bit版を使いました。
例によってUSBデバイスにインストールしました。2.MPLAB-Xのインストール
ダウンロードしてzipファイルを展開します。
実行属性をつけた後、sudo suでrootになって、ファイルを実行すればインストールできます。。3.Cコンパイラのインストール
CコンパイラはXC8を使います。インストール方法はMPLAB-Xと概ね同じです。
前回はC18コンパイラを使ったのですが、すでにダウンロードできなくなっています。(後述の通り、XC8でもUSBシリアルエミュレータが動くようになっています)4.Microchip Libraries for Applicationsのインストール
CDCを使いたいのでライブラリを使います。2013年12月20日版以降のものはMPLAB-X IDE向けのもののみ対応とのことです。
やっぱりrootじゃないとインストールできないのですが、インストールは
/root/microchip
の下にされてしまいます。そのままだと一般ユーザーだとアクセスできませんので、
$ sudo su
# cp -rp microchip ~ユーザー名/.として自分のホームディレクトリの下にコピーしておきます。
5.MPLAB-Xでビルド
- MPLAB-Xを起動して、「File」→「Open Project」で『/home/ユーザー名/microchip/mla/v2014_07_22/apps/usb/device/cdc_serial_emulator/firmware/MPLAB.X』を指定してプロジェクトを開きます。
- この状態だとターゲットデバイスがPIC16F1459になっているので、設定を変更します。
Projectツリーを右クリックして「Set Configuration」で「LPCUSBDK_18F14K50」を選択します。 - ビルドします。
「Run」→「Clean and Build Project」でビルドします。
6.シリアルの速度を変更する
シリアルの初期化はプロジェクトツリーの下の「Source Files」の下の「bsp/low_pin_count_usb_development_kit/usart.c」で行っていて、その56行目付近を変更することでシリアルの速度を変更できます。
今回は9600bpsに設定するので、
SPBRG = 225; SPBRGH = 4;
に変更します。
あとがき
できればブートローダを書き込んでから、その上でCDC Serial Emulatorをインストールしたかったのですが、どうもソースを見るとXC8では対応している感じがしなかったのでブートローダなしとしました。
-
また気圧計の電池がなくなりました
投稿日 2013年 11月 24日 コメントはありません前回10月30日に電池交換した気圧計ですが、今日電池がなくなって止まってました。
今日の昼間は稼働していたので、ほぼ25日間の動作ということになります。単三で作れば2ヶ月くらい駆動できるかな?
自作の電池駆動機器で簡単にこれだけの期間連続動作させられるようになるなんてしばらく前には予想できませんでしたね。
-
DIP版18F14K50ボードを作ってみました
投稿日 2013年 11月 6日 コメントはありません余っていたDIP版のPIC18F14K50とユニバーサル基板でテスト用のボードを作ってみました。
このボードを作ってみたのは、部品が余っていたから・・・というのもありますが、秋月の800円PIC18F14K50ボードとブレッドボードの組み合わせでは不便な点があったからです。それは、
- 秋月の800円PIC18F14K50ボードではRA3はPICkit3へ接続するようになっている。
よって、ブレッドボードではこの端子は扱えない。 - USBでいろいろなソフトウェアを作って試すには、ブレッドボードでは持ち運びには不便。
というところからです。双方向でのデータのやりとりを試してみたいので、余っていた気圧センサとI2Cのキャラクタ液晶も載せてあります。気圧センサは液晶の下に置いてあります。(最初の写真は気圧センサから読み取った値を液晶に表示しています)
裏面はこんな感じです。(自分用です。回路図を作っていないのでその代用(^^;。クリックすると特大画像が開きます。)
各部分の説明(自分用です)
- 基板裏面から見て右上の部分
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バスのアドレスアサインは以下の通りです。
- 0x3E – AQM0802A液晶モジュール
(WRITE : 0x7C) - 0x5C – LPS331AP大気圧センサ
(WRITE : 0xB8 / READ : 0xB9)
ソフトウェアはとりあえず以下の通りです。
- PIC18F14K50側ブートローダ
タクトスイッチとLEDのポートアサインを修正 - PIC18F14K50側アプリケーション
カスタムHIDデバイスのデモプログラムをベースにして、先に作った気圧センサ用のPIC16F1823用のI2C/LPS331/LCDドライバを移植。
さらにTimer0割り込みを使って時間管理(似非マルチタスク処理)ができるように割り込み処理を追加。 - Linuxホスト側ブートローダ
Microchipのサンプルプログラムのまま - Linuxホスト側アプリケーション
昔作ったHIDRAWでデータをやりとりするプログラムを改造し、双方向で希望するデータのやりとりができることを確認
これでLinux環境下でデータのやりとりをUSB経由で好きなようにできそうです。
- 秋月の800円PIC18F14K50ボードではRA3はPICkit3へ接続するようになっている。
-
マウスエミュレータ(?)を作ってみた
投稿日 2013年 11月 5日 コメントはありません例によって Microchip Solutionsの中のサンプルプログラムの中にマウスのデモがあったので、これをベースにアナログジョイスティックで操作するマウスエミュレータを作ってみました。
写真が完成した状態です。アナログジョイスティックでマウスカーソルを上下左右に移動させることができ、その下のタクトスイッチ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番地以降にロードするようにリンクされていない、というものです。
もちろん、見た目ではという感じで 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の組み合わせで毎回書き換えて使うには、書き込む度に
- PIC18F14K50側のUSBケーブルを抜いて、
- PICkit3を接続し、
- ダウンロードをして、
- PICkit3側のUSBケーブルを外してから
- PICkit3を外して、
- PIC18F14K50側のUSBケーブルを挿す
- (次回書き込みに備えて)PICkit3側のUSBケーブルを挿す
というなかなか面倒くさい手順が必要です。理由は、
- ICSPの端子とUSBのD+/D-端子を共有している
- 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のパケットキャプチャをしてみました。
0040Hからが受信したデータの部分で、構造体の構造にそって読んでいくと、赤丸の部分がversionFlagで0xa5になっていることがわかります。つまり、ブートローダのファームウェア側からは正しく情報が上がっているようです。
SIGN_FLASHは送出されているのか?
書き込みの処理の部分全体をUSBパケットキャプチャしてみたところ、最後のパケットは、
となっていて、最後のコマンドは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」にあるようです。
-
気圧計の電池がなくなりました
投稿日 2013年 10月 30日 コメントはありません先に作った気圧計ですが、連続稼働していたら電池がなくなってました。稼働し始めて約9~10日というところですが、もともと何かの電池として使っていたものを持ってきたので、寿命としては怪しいです。
なので、改めて新しい電池(といっても、ダイソーアルカリ乾電池ですが・・・)を入れてみました。さて、どのくらいの寿命となるでしょうか。
-
PIC18F14K50の他のサンプルを動かしてみる
投稿日 2013年 10月 22日 コメントはありません調子に乗ってPIC18F14K50の他のサンプルを秋月の800円ボードで動かしてみました。
動作環境はLinuxMint13 + PicKit3です。「MPLAB-X」「MPLAB C18ツールチェーン」「Microchip Library for Applications」はすでにインストールされているものとします。(といっても、ダウンロードして、スーパーユーザー権限でスクリプトを走らせるだけでインストールできますが)
まず、サンプルプロジェクトを開いて初期設定を行います。ここではUSBキーボードのサンプルプロジェクトを動かしてみます。
- MPLAB-Xを起動します
- 「File」→「Open Project」で既存のプロジェクトを開きます。
ダイアログボックスが開くので、ホームディレクトリの下の
$HOME/microchip_solutions_v2013-06-15/USB/Device – HID – Keyboard/Firmware/MPLAB.X
を開きます。 - プロジェクトが読み込まれますが、この状態では他のチップ用になっていますので、PIC18F14K50では動きません。
- 「File」→「Project Properties(Device – HID – Keyboard)」でプロジェクトの設定を行います。
- 左下の方にある「Manage Configurations」をクリックします。
- 開いたダイアログから「LPC_USB_Development_Kit_PIC18F14K50」を選択して、右側の「Set Active」ボタンをクリックします。
- 「LPC_USB_Development_Kit_PIC18F14K50」の右側に「(active)」が移動したら、「OK」をクリックします。
- 左側の「Categories」から「Conf: [LPC_USB_Development_Kit_PIC18F14K50]」の下にある「PICkit3」を選択します。
- 右半分がPICkit3関連の設定画面に変わります。
- 上の方の「Option categories:」から「Power」を選択します。
- 「Power target circuit from PICkit3」にチェックを入れて、「Apply」をクリックします。
こうしないと、秋月の800円ボードに電源供給されないので書き込みができません。 - 「OK」をクリックして、ダイアログを抜けます。
次にビルド&書き込みを行います。
- 秋月の800円ボードのUSBコネクタをホストから外します。ICSPの信号線とUSBのD+/D-の信号線は同じ端子なので、USBを抜かないと書き込みできません。つまり、電源も供給されないので、PICkit3から電源供給してやらないとダメなのです。
- 次に、一旦PICkit3のUSB端子を外して改めて接続します。外すことでPICkit3からの電源供給を止めてやります。そうしないと、次にボードと接続する際に活線挿抜になってしまいます。運が悪いとボードが壊れるかもしれません。
- 秋月の800円ボードのICSP端子をPICkit3に接続します。
- IDE上の下向きの緑矢印がついたボタン(マウスカーソルを載せると「Make and Program Device」という表示が出ます)をクリックします。
- しばらくまつとコンパイル、書き込み、ベリファイが行われます。
「Programming/Verify complete」と表示されたら完了です。 - PICkit3をボードから引き抜きます。
この段階でPICkit3側のMiniUSBコネクタも一度引き抜いておいてもいいでしょう。 - 適当なエディタを開いて、新しいファイルを作成して、文字入力ができる状態にしておきます。
- ボードのUSBコネクタとホストをUSBケーブルで接続します。
- エディタに勝手に文字が入力されていきます。
ここで慌てて他のウインドウを選択するとそちらに入力されていきますので、ご注意を(笑)
動作を確認したら、USBケーブルを抜きましょう。
本来は評価ボードにはスイッチがついているので、そのスイッチを押すと文字が入力されるようなのですが、800円ボードにはそんなものはありませんので、勝手にキー入力されていってしまいます。
何のキーが入力されるかは、keyboard.c の907行目で HID REPORT にキーのコードに相当するusageを設定しています。usageはUSBの仕様書のうち、HID Usage Tableの53頁からの一覧表に乗っていて、4が「A」のキーに相当します。その後の926行目付近ではキーを話した場合のREPORTを送っています。
この辺を読んでソースを弄っていけば、変なキーボード(CTRL + ALT + DEL専用キーボードとか)も作れるはずです。(^^;
-
LPS331による気圧計の製作
投稿日 2013年 10月 21日 コメントはありませんしばらく前に秋月で安価な高精度気圧センサLPS331のモジュールが出ていたので購入してあったのですが、これを電池駆動の気圧センサとして仕立ててみました。
おもなキーパーツは、
- 気圧センサ:LPS331AP
- 液晶モジュール:AQM0802A
- マイコン:PIC16F1823
何でもよかったのですが、手頃なサイズでI2Cをもっているので採用しました。 - スイッチングレギュレータ:HT7750A
47uHのインダクタを使って一旦5Vを生成します。 - CMOS三端子レギュレータ:S-812C33AY-B-G
5VからPICマイコンおよびLCDモジュール用の3.3V生成に1個、センサの電源用に1個使っています。消費電流を抑えるため、CMOSのレギュレータとしています。
といったところです。
小型軽量かつ長時間駆動を目指すため、単4電池1本からスイッチングレギュレータを使って電源を生成しています。
当初はHT7733Aを使用し、LCフィルタでノイズを低減して使用していたのですが、どうも動作が安定しないのでノイズが原因かと疑って、一旦5Vにしてから3.3VのCMOSリニアレギュレータで電源を生成しています。(根本原因は他にあったので、結局これがどのくらい影響しているかはわかりません)センサにはLEDが搭載されていますが、電池での動作時間を伸ばすため、その右上の電流制限抵抗を除去することでLEDへの電流をカットしています。
背面は試行錯誤の繰り返しで汚くなってしまいました。
ソフトウェアはMPLAB-X+XC8で作成していますが、このLPS331というデバイスは結構くせがあり苦労しました。(XC8にもいろいろ癖があって苦労しました)
当初は自動モードで勝手に連続変換させて、変換終了時に割り込みにてPICに通知、値を読み取って表示させようとしていました。しかしこちらの記事にあるように連続モードで変換すると、変換の処理自体?が抜けていることがあるのです。そこで、約1秒周期でワンショットの変換コマンドを発行することにしたのですが、それでも表示の変動が起こります。「レジスタは初期値に関わらず全部書き込まないとダメ」など、いろいろWebで見かけた情報を取り込みながら、最終的には約2秒周期での変換とすると変換値の暴れが収まるようですので、約2秒周期での変換&表示としています。それでも時折温度については±1℃程度の範囲で暴れることがあるようですが、妥協しました。以前作ったArduinoベースの温度・湿度・気圧計との比較です。
気圧についてはLPS331APの方がごくわずか・・・0.2hPa程度ですが、低めに出る傾向があるようです。
温度の方はLPS331APの方が0.7℃程度ですが低めに出ています。
値の安定性については気圧・温度ともにSCP1000の方が明らかに安定しています。LPS331のほうはドキュメントもよく読むとおかしな所が結構あって(ドキュメントの)出来がよくありません。ドキュメントの出来が悪いデバイスは概してデバイス自体にもいろいろ問題を抱えている場合が多いように経験しています。
#原因切り分け用に買い足したLPS331APがあるのだけど、どうしようかな・・・(^^;
それと消費電流ですが、電池のところで測定すると、センサが動作していないタイミングでは1.8mAくらいで、センサが動作すると4mA程度に上がります。ただ、デジタルテスタで測定しているので、どのくらいが本当のピークなのかはわかりません。センサの動作時間自体は100msにも満たないようなので、平均でも2mA以下くらいなのでしょうか。2mAとすると、単4アルカリ乾電池の容量は700~800mAh程度のようですので、電池1本で350~400時間程度(電圧が下がってくるので、もうちょっと短いか)=約2週間程度の動作時間というところでしょうか。
現状では消費電流を下げて駆動時間を伸ばすためにPICの動作周波数は内蔵オシレータ使用で125kHzとしてあります。さらに消費電流を下げるために表示更新の待ち時間でのPIC自体のスリープも考えたのですが、内部の31kHzのLFINTOSCでスリープ動作させる方法が見つかりませんでした。どうやら外付けの32kHzのクリスタルで動作させないといけないようで、そこまで部品追加するのは面倒なので止めました。
ソースも置いておこうかな・・・と思ったのですが、コメントが古い(試行錯誤する前)ので、とりあえずやめておきます。(コメントを整理したら置くかも・・)
最近のコメント