LPC810メモ:pattern match engine

pattern match engineを試す。

pattern match engineは、前に試したpin interruptsを高度化したような機能であり、単独のpinでなく複数pinの状態の組み合わせで割り込みを発生させる。

前提とする環境はこちら→LPC810メモ 共通の準備

  • pattern match engineは概略こんな感じ。
    • 0-7番の8つの「slice」を定義できる。
    • 各sliceでは、のpinから入力するか、どういう条件に反応するか(rising edgeとか、HIGH levelである、とか)を設定する。
    • 連続した複数のsliceの条件が、endpointのsliceまですべて成立すれば、割り込み発生。
      • このイメージは、「UM10601 8.5.2 Pattern match engine」のFig8,Fig9あたりをじっくり眺めていると理解できる。
      • 例) slice0を1番pinのrising edge、slice1を2番pinのrising edgeに設定して、slice1がendpointとすると、「1番pinと2番pinのrising edgeがそれぞれ1回づつあったら」割り込み発生。
  • 本例の動作
    • 1,2,3,4番pinに、押すとLOWになるpushボタンがそれぞれついている。それぞれボタン1,2,3,4と呼ぶ。
    • ボタン1,2,3,4を任意の順番で1回づつ押すと、LED点灯。これをslice0,1,2,3で実現。
    • ボタン1,3,を押下、ボタン2,4を離した状態になると、LED消灯。これをslice4,5,6,7で実現。

サンプルコード

#include "LPC8xx.h"

int main(void) {
    // GPIOの設定 8番pinを出力に設定して消灯しておく
    // (pattern matchとは直接関係ない)
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
    LPC_GPIO_PORT->DIR0 |= (1<<0);
    LPC_GPIO_PORT->CLR0 |= (1<<0);

    // SWMの設定
    // 固定pin機能をreset含めて無効化
    // (pattern matchとは直接関係ない)
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
    LPC_SWM->PINENABLE0 = 0xffffffffUL;

    // (pin interruptではなく)pattern matchを利用する旨の設定
    // UM10601 8.6.11 Pattern Match Interrupt Control Register
    LPC_PIN_INT->PMCTRL |= (1 << 0);

    // 各pinをpattern matchの入力に設定
    // 4.6.27 Pin interrupt select registers
    LPC_SYSCON->PINTSEL[0] = 5; // PIO0_5(1番pin)をPINTSEL0に設定
    LPC_SYSCON->PINTSEL[1] = 4; // PIO0_4(2番pin)をPINTSEL1に設定
    LPC_SYSCON->PINTSEL[2] = 3; // PIO0_3(3番pin)をPINTSEL2に設定
    LPC_SYSCON->PINTSEL[3] = 2; // PIO0_2(4番pin)をPINTSEL3に設定

    // 各sliceにどのPINTSELを割り当てるか設定
    // 8.6.12 Pattern Match Interrupt Bit-Slice Source register
    LPC_PIN_INT->PMSRC =
        (0 << 8) // slice0にPINTSEL0(1番pin)を設定
        | (1 << 11) // slice1にPINTSEL1(2番pin)を設定
        | (2 << 14) // slice2にPINTSEL2(3番pin)を設定
        | (3 << 17) // slice3にPINTSEL3(4番pin)を設定
        | (0 << 20) // slice4にPINTSEL0(1番pin)を設定
        | (1 << 23) // slice5にPINTSEL1(2番pin)を設定
        | (2 << 26) // slice6にPINTSEL2(3番pin)を設定
        | (3 << 29) // slice7にPINTSEL3(4番pin)を設定
        ; 

    // 各sliceの条件を設定
    // 8.6.13 Pattern Match Interrupt Bit Slice Configuration register
    LPC_PIN_INT->PMCFG =
        (0x2 << 8) // CFG0 = 0x2 slice0(1番pin)のfalling edge
        | (0x2 << 11) // CFG1 = 0x2 slice1(2番pin)のfalling edge
        | (0x2 << 14) // CFG2 = 0x2 slice2(3番pin)のfalling edge
        | (0x2 << 17) // CFG3 = 0x2 slice3(4番pin)のfalling edge
        |	(1 << 3) // PROD_ENDPTS3 = 1  slice3をendpointとする。
          //  以上合わせて、「1,2,3,4番pinの押下(falling edge)が各1回づつあったら割り込み発生」となる。

        | (0x5 << 20) // CFG4 = 0x5 slice4(1番pin)がLow leel
        | (0x4 << 23) // CFG5 = 0x4 slice5(2番pin)がHigh leel
        | (0x5 << 26) // CFG6 = 0x5 slice6(3番pin)がLow leel
        | (0x4 << 29) // CFG7 = 0x4 slice7(4番pin)がHigh leel
          //  以上合わせて、「1,3番pinが押された状態(Low)、2,4番pinが押されてない状態(High)で
          // 割り込み発生」となる。
          // ちなみに、slice7はデフォルトでend pointなので、end pointの設定は不要
        ; 

    //  slice3と7の割り込み有効化。
    //  UM10601  3.3.1 Interrupt sources
    NVIC->ISER[0] = (0x1 << 27) | (0x1 << 31);

    return 0 ;
}

extern "C" {
    // slice3に対応する割り込みハンドラ。
    // cr_startup_lpc8xx.cpp で定義されている名称。
    void PININT3_IRQHandler(void)
    {
        //	割り込みをクリア
        //	UM10601 8.6.13 Pattern Match Interrupt Bit Slice Configuration register
        // のRemarkより、SEL_PMATCHをclear(して、再度set)

        LPC_PIN_INT->PMCTRL &= ~0x1;
        LPC_PIN_INT->PMCTRL |= 0x1;

        // LED(8番pin)点灯
        LPC_GPIO_PORT->SET0 |= (1<<0);
    }

    // slice7に対応する割り込みハンドラ。
    void PININT7_IRQHandler(void)
    {
        // 割り込みをクリア
        LPC_PIN_INT->PMCTRL &= ~0x1;
        LPC_PIN_INT->PMCTRL |= 0x1;

        // LED(8番pin)消灯
        LPC_GPIO_PORT->CLR0 |= (1<<0);
    }

}

接続

  • 1,2,3,4番pinはそれぞれとりあえず3kΩでpull upしてあり、それぞれプッシュボタンを押すとLOWになるようにつないである
  • LEDは8番pin
  • 6,7番pin(Vdd,GND)は0.1μFのコンデンサ

補足/雑感

  • UM10601の「8.5.2 Pattern match engine」とか「8.7.2 Pattern Match engine example」とかを最初に読んだ時に、かなり柔軟なbool式を構成できるのかと誤解。なぜそんな事ができるのかわからず混乱。
  • 「UM10601 8.5.2 Pattern match engine」のFig8,Fig9を眺めて、基本的には連続するsliceをAND接続するだけということに気づいてからは理解早かった。
  • これをもって、当初試したいと思っていたLPC810の機能は全部試せた。3ヶ月くらいかかった。まだ初心者脱却を達成したとは思わないが、かなり勉強にはなったと思う。
  • せっかくなので成果をまとめたいところ。

みっかぼの無料Androidアプリはこちら。