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

Joseph Halfmoon

ラズパイPicoの特長の一つであるinterpを扱って三回目にして、ようやく回路名称である interpolator (補間器)の主目的である補間を試みてみます。今回は整数型のシンプルな線形補間です。Blend Modeというモードを設定するだけで、後はレジスタに値を書き込むだけで補間を行ってくれます。便利っちゃ便利ですが、Blend Modeって何者?という疑問が残ります。

※「Pico三昧」投稿順 index はこちら

参照しているのは 以下のデータシートです。SIO(Single-cycle IOです。シリアルIOではありませぬ)という一項目で30ページ以上も説明のある中に interpolator の説明があり、その奥の方に今回フォーカスしている Blend Mode の説明があります。

RP2040 Datasheet

冒頭のアイキャッチ画像に、このモードで計算できる線形な整数の補間機能の式を掲げました。二つの入力 X0、Xがあったときに、その間を256等分のα(αは0以上255以下)した値を返すというもの。もしかするとアルファ・ブレンディングなどの計算に使うつもりでBlendモードと唱えているのかも知れませんが、お名前の由来は書いてないみたいです。

早速サンプルテストプログラム作成

データシートの例を参考に、早速サンプルプログラムを書いてみました。実際の応用では数列を成して入力されてくるデータの隣り合うもの同士をX0、Xとして入力して、その中間の補間値を計算しつづける、ことになるのだと思います。今回サンプルは、

    • X0 整数1000
    • X1 整数2000

とキメウチのデータ組に対して、0%点(X0そのもの)、25%点、50%点、75%点と区間を4等分した途中の値を求めてみるというもの。分かり易いですかね?

イマイチどんな制御をしているのか不明な Blend モードですが、使用すること自体は簡単です。interp_config_set_blend()という関数を呼び出すだけでOK。特に面倒なパラメータの設定もなしです。前回計算要素のそれぞれを個別に設定してみましたが、そんな手間をかける必要もなかったです。

ただし、Blendモードには INTERP0 (のレーン0)にしか設定できないという制約があるみたいです。おさらいしておくと、

    • 2個のコアそれぞれに2個のインタポレータ、INTERP0, INTERP1を持つ
    • 1個のインタポレータ内には3つのレーン、0、1、2がある

です。どちらのコアも1系統のBlend Modeは使える。けれどもBlendモード使用時にはINTERP0の全てのレーンがBlendモードで使われる、ということみたいです。具体的な設定としては、

    • レーン0、blendモードを指定
    • レーン1、デフォルト設定のままにする
    • レーン2、何も設定せず、放置

で良いようです。作成したサンプルプログラムの main()関数が以下に。その他部分、CMakeLists.txt などは、前回のものをそのまま流用しとります。

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

    printf("Interp training 003\n");
    interp_config cfg = interp_default_config();
    interp_config_set_blend(&cfg, true);
    interp_set_config(interp0, 0, &cfg);
    cfg = interp_default_config();
    interp_set_config(interp0, 1, &cfg);

    while (1) {
        int x0 = 1000;
        int x1 = 2000;
        printf("TEST LOOP: %d\n", counter++);
        interp0->base[0] = x0; //x0
        interp0->base[1] = x1; //x1
        for (int i = 0; i<4; i++) {
            interp0->accum[1] = i * 64;
            printf("x0:%d x1:%d INTEROLATION(%d/4)=%d\n", x0, x1, i, interp0->peek[1]);
        }
        gpio_put(LED_PIN, 1);
        sleep_ms(1000);
        gpio_put(LED_PIN, 0);
        sleep_ms(1000);
    }
    return 0;
}
サンプルテストプログラム作成

データシートの例を参考に、早速サンプルプログラムを作成いたしました。WindowsPC上のVSCodeから、ラズパイPicoの母艦であるRaspberry Pi 4にSSH接続し、ラズパイPicoにSWDデバッグを行っているところが以下に。

vscodeInterpDebugEC
実際に、STDIOに出力されてきた「補間結果」が以下に。

x0とx1の値、0点、4分の1、4分の2,4分の3の値が読めているのが見えますかね。

Result

設定さえすれば、値の読み書きだけで補間できてしまう interp は計算はお楽。でも設定の裏側には今だ隠された秘密がある感じです。わたしゃそこが知りたいですが、ソース読むのメンドイ、気力が無い。。。

Pico三昧(8) Pico C/C++SDKでinterp その2、DeadBeef例題 に戻る

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