Visual Initializerが出力するコード

まずVisual Initializerが出力するファイルは3つあります。

  • init_デバイス名.sinit_vi.h(C言語用ヘッダファイル)
  • init_デバイス名.sinit_vi.inc(アセンブラ用インクルードファイル)
  • init_デバイス名.s(アセンブル・ソースファイル)

「デバイス名」部分は「PIC24FJ64GA002」のようになります。

ここではアセンブル・ソースファイルの「init_PIC24FJ64GA002.s」を見ていきます。

最初に先頭部から。以後、不要なコメントや空行を省略しています。


.include "p24FJ64GA002.inc"
.GLOBAL _VisualInitialization
config __CONFIG1, 0x7D1F
config __CONFIG2, 0x01E3
.text
_VisualInitialization:
デバイス情報(レジスタ等)を定義してあるインクルードファイルを取り込んでいます。
レジスタを操作するなら、当然アプリケーション側でもこのインクルードファイルを取り込んで利用すべきでしょう。

configuration bitsの値がここで定義されています。これには要注意です。Visual Initializerの操作に対応してこれらの値は変化しますが、すべての値をVisual Initializerから操作できる訳ではありません。
MPLABのメニュー「Configure」→「Configuration bits...」ならすべての項目を設定できます。そちらを優先したいならMPLAB側で上書きするよう設定します。でも同じ項目で値が異なるときは設定ミスだし、ツールの役割に矛盾があります。Visual InitializerですべてのConfiguration Bitsを設定できないところが問題でしょう。

_VisualInitializationが初期化ルーチンのシンボルです。
ファイルの末尾に「return」があることからもcallで呼び出すことになるので、呼び出し前にW15のスタックポインタ設定しておく必要があります。


MOV #OSCCON, W1
MOV #0x46, W2
MOV #0x57, W3
MOV.B W2, [W1]
MOV.B W3, [W1]
BCLR OSCCON, #6
MOV #0x1F00, W0
MOV W0, RPINR0
...
ここから先は各レジスタ設定が最後のreturn直前まで続きます。
PeripheralPinMap(端子名でいうところのRP)関係では、前後にOSCCONのIOLOCKを解除/設定しています。
OSCCONは発信器制御レジスタで、簡単に変更できないよう書き換えシーケンスに従い変更する必要があります。IO端子の設定も簡単に書き換えられないようついでに(?)このレジスタにあるIOLOCKビットで設定ロックを解除/設定するようになっています。
つまりIO端子設定(ポートのR/Wは別ですが)は、OSCCONの書き換えシーケンスを実行してから、IOLOCKビットをクリアしないと変更できません。「OSCCON」で検索して、bit6を操作している周辺が該当箇所です。
このbit6という値が直接書かれていますが、できれば「IOLOCK」というシンボルを使って欲しいところです(p24FJ64GA002.inc等で定義済み)。
また各RPINRレジスタの設定も、

...
MOV #0x1F1F, W0
MOV W0, RPINR20
MOV #0x001F, W0
MOV W0, RPINR21
MOV #0x1F1F, W0
MOV W0, RPINR22
MOV #0x001F, W0
MOV W0, RPINR23
...
のように同一値を設定しているところは、以下のようにまとめて実施してくれるといいんですけどね。

MOV #0x1F1F, W0
MOV W0, RPINR20
MOV W0, RPINR22
MOV #0x001F, W0
MOV W0, RPINR21
MOV W0, RPINR23
FlushROMが足りないときは、少しだけメモリを減らす余地があります。「少しだけ」ね。

後はダラダラとレジスタ設定が続きます。
Visual Initializerで選択していないモジュールのレジスタまで親切に設定しています。
リセット初期値のままで良く、レジスタ設定が不要なら削ってしまっても構わないはずですが、メモリに余裕があるならそのままにしても良いでしょう。
ここでもメモリを減らす余地があります。