読者です 読者をやめる 読者になる 読者になる

Ichigo Exception <3

スマブラDXと、Linuxカーネルと、日々のつらい気持ち

PIC18で遊んだ

以前作成した PIC18F26K20 を使った GC 入力信号表示装置の改良版として、信号を GC に入力できるような装置を作ろうと思っています(思っているだけ)。

それで久々に PIC18 を触りましたが、やはり C で普通に記述できる魅力はすごいです(アーキテクチャの特性上自由にポインタ操作はできませんが)。フリーで使用できる開発環境 MPLAB とコンパイラ xc8/16/32 がチップベンダーの Microchip 社から提供されています。
GC 信号を入出力するには、1us 周期で HIGH/LOW を制御できる必要がありますが、この調整に苦労していました。
PIC18F26K20 ではチップ内蔵オシレータを最大の 16 MHz で動作させ、PLL で 4 倍の周波数を得ると、IPC が 4 なので秒間 16 サイクルを得られます。随分余裕があるように思いましたが、配列操作にやたら時間がかかり、以下のような普通の for ループでは間に合わず、アセンブリで書いても微妙に 1us に収まりませんでした。

for (i = 0; i < ARRAY_SIZE(a); i++) {
  arr[i] = PORTCbits.RC0;
}

結局全部マクロ展開に任せることにしました。xc8 の制約として、配列インデックスは 128 が最大なので、要素 2n 個で使える方法でぴったりです。

#define EVAL_128(exp, arr, port, n) EVAL_64(exp, arr, port, n - 64) EVAL_64(exp, arr, port, n)
#define EVAL_64(exp, arr, port, n)  EVAL_32(exp, arr, port, n - 32) EVAL_32(exp, arr, port, n)
#define EVAL_32(exp, arr, port, n)  EVAL_16(exp, arr, port, n - 16) EVAL_16(exp, arr, port, n)
#define EVAL_16(exp, arr, port, n)  EVAL_8(exp, arr, port, n - 8)   EVAL_8(exp, arr, port, n)
#define EVAL_8(exp, arr, port, n)   EVAL_4(exp, arr, port, n - 4)   EVAL_4(exp, arr, port, n)
#define EVAL_4(exp, arr, port, n)   EVAL_2(exp, arr, port, n - 2)   EVAL_2(exp, arr, port, n)
#define EVAL_2(exp, arr, port, n)   EVAL_1(exp, arr, port, n - 1)   EVAL_1(exp, arr, port, n)
#define EVAL_1(exp, arr, port, n) exp(arr, port, n)
#define RD(arr, port, n) arr[n] = port;
#define WB(arr, port, n) port = arr[n];

EVAL_128(RD, a, reg, ARRAY_SIZE(a) - 1)  // ポート入力
EVAL_128(WB, a, out, ARRAY_SIZE(a) - 1)  // ポート出力

EVO2017 のホテル・航空券予約が終わり、もう引き返せないところまできました。POINT OF NO RETURN です。

先週、プラスティック・メモリーズを見ました。老体になる前に寿命が来るとは、残酷な世界観です。まほろまてぃっくを感じました。
とはいえ、キャラクター達は悪意のない性格で、少女に戻ったような素直な気持ちで全話観終わることができました(少女ではなかった)。 アイラ可愛いです。