CCLとは
通常マイコンでは、各ピンのHIGHやLOWの出力についてはプログラミングによって制御を行います。そこで複数のピンの状態によって特定のピンへの出力を設定したい場合、ピンの状態変化による割り込み処理や、loop()関数の中で入力ピンの状態を読み込み出力ピンを設定する処理を記述する必要があります。しかしこの方法だと、AND回路やOR回路といった比較的単純な論理回路を実装したい場合、処理の割に実装が泥臭い感じになってしまいます。さらにこの処理でCPU時間を取られてしまい、他のプログラムへの影響も発生します。
そこでATtinyにはCCL(Configurable Custom Logic)と呼ばれるペリフェラルが用意されています。これは構成設定可能な論理回路で、あらかじめ決められた真理値表を設定することで、入力ピンの状態から出力ピンを自動的に制御することができ、AND回路やOR回路なども比較的簡単に実装することが出来ます。また単純な論理回路だけでなく、RSラッチやDフリップフロップなども設定させることが可能です。
AND/OR/XORの実装
本稿ではANDやOR、XORといった単純な論理回路を設定する方法について解説します。
ラッチやフリップフロップについてはまだ実装したことがないので、そのうち知見が得られたらまとめたいと思います。
構成
CCLはこのような構成になっています。
入力ソースの指定はINSELで行いますが、今回はピンを指定します。INSELの指定次第ではCCLの出力をつないだり、UARTやSPIの送信線を指定したりもできます。画像のTRUTHは真理値表になり、どの入力に対してどう1や0を出力させるかを設定させます。FILTSELやEDGEDETはよくわからないので、入力をそのまま出力させるように設定しています。
SEQSELは単純な論理回路か、またRSラッチやDフリップフロップなどを使うかを設定できます。今回は単純な論理回路を設定したいので、000を指定します。
初期化
前節のような設定を行うための初期化処理はこのようになります。
// おまじない
CCL.CTRLA = 0x00;
// 単純な論理回路として利用することを指定
CCL.SEQCTRL0 = 0x00;
// 入力0は使用しない、入力1はPIN_PA1として設定
CCL.LUT0CTRLB = 0x50;
// 入力2はPIN_PA2として設定
CCL.LUT0CTRLC = 0x05;
// 真理値表 詳細は後節で
CCL.TRUTH0 = 0x3C;
// 出力PINとLUT0を有効化
CCL.LUT0CTRLA = 0x09;
// CCLを有効化
CCL.CTRLA = 0x01;
簡単に解説します。
CCL.CTRLA = 0x00;
最初に下記のCCLのペリフェラルを無効かさせるおまじないを行います(これがないと正常動作しなかったです)。エラッタの「2.4.3. 単一LUT構成変更にCCLの禁止が必要」あたりが怪しいのかな?と思ってますが確証はありません。
CCL.SEQCTRL0 = 0x00;
次に単純な論理回路として利用することを、下位3ビットに000にセットすることで設定します。RSラッチは100、Dラッチは011(エラッタから動作はしないらしい)、JKFFは010、DFFは001を指定します。詳しい説明については省略します。
CCL.LUT0CTRLB = 0x50;
CCL.LUT0CTRLC = 0x05;
次に入力ソースを指定します。LUT0CTRLBの下位4ビットは入力0のソースを、上位4ビットは入力1のソースを指定します。またLUT0CTRLCの下位4ビットは入力2のソースを指定します(上位4ビットは不使用)。今回、入力0は不使用(0b0000)、入力1と入力2はピンをそのまま利用(0b0101=0x5)します。ATtiny406の場合LUT0の入力0はUPDIとピンが一致(PIN_PA0)するため、GPIOとして利用することが難しいので不使用としました。他の入力ソースを指定したい場合は、ATtiny406のデータシートの27.5.4や27.5.5を参照してください。
CCL.TRUTH0 = 0x3C;
今回はXORを実現させるために0x3Cを設定しています。詳細については後節にて解説します。
CCL.LUT0CTRLA = 0x09;
CCL.CTRLA = 0x01;
LUT0CTRLAに0x09を設定することでLUT0の有効化と、LUT0の出力をLUT0OUTピン(PIN_PA4)に接続します。そして最後にCCL.CTRLAに0x01を設定することで、CCLの設定の反映とCCLの有効化を行います。
真理値表
真理値表は、入力0、入力1、入力2に対してどのような出力を行うかを定めた表になります。CCLのLUT0ではTRUTH0で真理値表を設定します。
これは真理値表を設定する際の参考図になります(データシートより)。LUTn-TRUTHSEL0は入力0、LUTn-TRUTHSEL1は入力1、LUTn-TRUTHSEL2は入力2になります。TRUTHnXは直感的に逆となりややこしいですが、TRUTHn0は最下位ビット、TRUTHn7は最上位ビットとなります。従って0x42を設定した場合TRUTHn1とTRUTHn6が1でそれ以外は0となるため、入力0,入力1,入力2がそれぞれ1,0,0と0,0,1の時に1が出力される真理値表となります。今回、入力0は不使用であることを踏まえると、単純な論理回路の真理値表は入力1と入力2の値で判断しますので、AND回路の真理値表は0xC0、OR回路は0xFC、XOR回路は0x3C、XNOR回路は0xC3、NAND回路は0x3F、NOR回路は0x03となります。
最後に
今回はAND回路やOR回路といった単純な論理回路をCCLに設定する方法について記述しました。次はJKFFやDFF、RSラッチについても記述したいと思っています。