Pico三昧(10) Pico C/C++SDKでinterpその4、クランプモード

Joseph Halfmoon

ラズパイPicoのinterpユニットを使ってみる4回目は、Clampモードです。前回Blendモードを使ってみましたが、これは各コアに2個づつあるinterpのうち「0」のみの機能でした。じゃ「1」の方は何かないの?というとClampモードを持っているのです。上下の境界を超える値を「クランプ」してくれる機能です。

以下のデータシートのSIO(Single-cycle IO)という項目の中に、interpolator の説明があります。

RP2040 Datasheet

Clampモードの動作をかいつまむと以下のようです。

  1. interp1のbase[0]に下限値を設定
  2. interp1のbase[1]に上限値を設定
  3. interp1のaccum[0]に値を書き込む
  4. accum[0]の内容は設定どおりシフト、マスク、符号拡張を通過する
  5. しかしbaseとの加算は行われない
  6. accum[0]のレーンの出力が下限値を下回ると下限値が、上限値を上回ると上限値が出力される。上限下限の範囲内ならばそのまま出力される

結構、こういう処理は「よくやる」ですかね。

作製したサンプルテストプログラム

作製したサンプルプログラムの設定は以下です。

  • 下限、整数100
  • 上限、整数200
  • accum[0]に書き込んだ値はシフト、マスク、符号拡張は行わずそのまま通過とする
  • accum[0]に0から290まで10おきの値を書き込んで、読み出し(PEEK)てみる

当然、100を下回るときは100,200を上回るときは200という結果が出てくることが期待されます。

以下に、データシート例を参考に書いてみたサンプルプログラムの main()関数を掲げます。それ以外のところは過去回のものをそのまま流用しています。

int main()
{
    const uint LED_PIN = 25;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);
    stdio_init_all();

    printf("Interp training 004 -Clamp Mode-\n");
    interp_config cfg = interp_default_config();
    interp_config_set_clamp(&cfg, true);
    interp_set_config(interp1, 0, &cfg);

    while (1) {
        int x0 = 100;
        int x1 = 200;
        interp1->base[0] = x0;
        interp1->base[1] = x1;
        printf("TEST LOOP: %d\n", counter++);
        for (int i = 0; i<300; i=i+10) {
            interp1->accum[0] = i;
            printf("LOW CLAMP:%d HIGH CLAMP:%d RAW: %d CLAMPED:=%d\n", x0, x1, i, interp1->peek[0]);
        }
        gpio_put(LED_PIN, 1);
        sleep_ms(1000);
        gpio_put(LED_PIN, 0);
        sleep_ms(1000);
    }
    return 0;
}
実機動作の確認

ビルド後、実機で動作させてみた結果(ワン・ループ分)が以下に。

TEST LOOP: 14
LOW CLAMP:100 HIGH CLAMP:200 RAW: 0 CLAMPED:=100
LOW CLAMP:100 HIGH CLAMP:200 RAW: 10 CLAMPED:=100
LOW CLAMP:100 HIGH CLAMP:200 RAW: 20 CLAMPED:=100
LOW CLAMP:100 HIGH CLAMP:200 RAW: 30 CLAMPED:=100
LOW CLAMP:100 HIGH CLAMP:200 RAW: 40 CLAMPED:=100
LOW CLAMP:100 HIGH CLAMP:200 RAW: 50 CLAMPED:=100
LOW CLAMP:100 HIGH CLAMP:200 RAW: 60 CLAMPED:=100
LOW CLAMP:100 HIGH CLAMP:200 RAW: 70 CLAMPED:=100
LOW CLAMP:100 HIGH CLAMP:200 RAW: 80 CLAMPED:=100
LOW CLAMP:100 HIGH CLAMP:200 RAW: 90 CLAMPED:=100
LOW CLAMP:100 HIGH CLAMP:200 RAW: 100 CLAMPED:=100
LOW CLAMP:100 HIGH CLAMP:200 RAW: 110 CLAMPED:=110
LOW CLAMP:100 HIGH CLAMP:200 RAW: 120 CLAMPED:=120
LOW CLAMP:100 HIGH CLAMP:200 RAW: 130 CLAMPED:=130
LOW CLAMP:100 HIGH CLAMP:200 RAW: 140 CLAMPED:=140
LOW CLAMP:100 HIGH CLAMP:200 RAW: 150 CLAMPED:=150
LOW CLAMP:100 HIGH CLAMP:200 RAW: 160 CLAMPED:=160
LOW CLAMP:100 HIGH CLAMP:200 RAW: 170 CLAMPED:=170
LOW CLAMP:100 HIGH CLAMP:200 RAW: 180 CLAMPED:=180
LOW CLAMP:100 HIGH CLAMP:200 RAW: 190 CLAMPED:=190
LOW CLAMP:100 HIGH CLAMP:200 RAW: 200 CLAMPED:=200
LOW CLAMP:100 HIGH CLAMP:200 RAW: 210 CLAMPED:=200
LOW CLAMP:100 HIGH CLAMP:200 RAW: 220 CLAMPED:=200
LOW CLAMP:100 HIGH CLAMP:200 RAW: 230 CLAMPED:=200
LOW CLAMP:100 HIGH CLAMP:200 RAW: 240 CLAMPED:=200
LOW CLAMP:100 HIGH CLAMP:200 RAW: 250 CLAMPED:=200
LOW CLAMP:100 HIGH CLAMP:200 RAW: 260 CLAMPED:=200
LOW CLAMP:100 HIGH CLAMP:200 RAW: 270 CLAMPED:=200
LOW CLAMP:100 HIGH CLAMP:200 RAW: 280 CLAMPED:=200
LOW CLAMP:100 HIGH CLAMP:200 RAW: 290 CLAMPED:=200

100から200の間に「クランプ」されているのが分かりますかね。Clampモード、分かり易いモードで良かった。一発完動、珍しいな自分。

Pico三昧(9) Pico C/C++SDKでinterp その3、シンプルな線形補間 へ戻る

Pico三昧(11) Pico C/C++SDKでinterp#5、補間ついでに配列舐める へ進む