2021年3月7日日曜日

Raspberry Pi Pico を動かしてみた

 とりあえず実機が手に入ったので定番のLチカでもしてみようと思います。といってもサンプルコードですでに用意されているのでそれを焼きこむだけです。

何も焼きこんでいない状態のPicoはUSBケーブルを刺すだけでブートモードになるようでドライブが現れますのでサンプルで用意されていたblink.uf2をドラッグアンドドロップで書き込みます。そうすると自動的にドライブが切断されてLEDがチカチカし始めました。非常にあっさりです。

ここでどれぐらいの速度でGPIOポートを操作できるのか確認しようとsleep関数をコメントアウトしてみました。

int main() {
    const uint LED_PIN = 25;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PINGPIO_OUT);
    while (true) {
        gpio_put(LED_PIN1);
    //    sleep_ms(250);
        gpio_put(LED_PIN0);
    //    sleep_ms(250);
    }
}

想定では少し暗くLEDが点灯するはずですが、消灯のままです。最適化でコードが無くなっちゃってるのかと思いアセンブラ出力ファイルblink.disを開いてみるとmain関数はこんな感じでコードが無くなっている感じはありません。

sleepあり

1000030c <main>:
1000030c: b570      push {r4, r5, r6, lr}
1000030e: 2019      movs r0, #25
10000310: f000 f82a bl 10000368 <gpio_init>
10000314: 23d0      movs r3, #208 ; 0xd0
10000316: 061b      lsls r3, r3, #24
10000318: 2280      movs r2, #128 ; 0x80
1000031a: 0492      lsls r2, r2, #18
1000031c: 625a      str r2, [r3, #36] ; 0x24
1000031e: 24d0      movs r4, #208 ; 0xd0
10000320: 0624      lsls r4, r4, #24
10000322: 2580      movs r5, #128 ; 0x80
10000324: 04ad      lsls r5, r5, #18
10000326: 6165      str r5, [r4, #20]
10000328: 20fa      movs r0, #250 ; 0xfa
1000032a: f000 fcb1 bl 10000c90 <sleep_ms>
1000032e: 61a5      str r5, [r4, #24]
10000330: 20fa      movs r0, #250 ; 0xfa
10000332: f000 fcad bl 10000c90 <sleep_ms>
10000336: e7f2      b.n 1000031e <main+0x12>

sleepなし

1000030c <main>:
1000030c: b510      push {r4, lr}
1000030e: 2019      movs r0, #25
10000310: f000 f824 bl 1000035c <gpio_init>
10000314: 23d0      movs r3, #208 ; 0xd0
10000316: 061b      lsls r3, r3, #24
10000318: 2280      movs r2, #128 ; 0x80
1000031a: 0492      lsls r2, r2, #18
1000031c: 625a      str r2, [r3, #36] ; 0x24
1000031e: 23d0      movs r3, #208 ; 0xd0
10000320: 061b      lsls r3, r3, #24
10000322: 2280      movs r2, #128 ; 0x80
10000324: 0492      lsls r2, r2, #18
10000326: 615a      str r2, [r3, #20]
10000328: 619a      str r2, [r3, #24]
1000032a: e7f8      b.n 1000031e <main+0x12>

赤字の部分がGPIOへのセットとリセットですが1命令で並んでいるのでペリフェラルへアクセスするタイミングでは同タイミングになってしまい無かったことになっているか100MHzのオシロスコープでは見えないようなパルスになっているのかもしれません。
試しに0と1の順番を変えてみるとLEDは点灯しっぱなしになりました。

    while (true) {
        gpio_put(LED_PIN0);
    //    sleep_ms(250);
        gpio_put(LED_PIN1);
    //    sleep_ms(250);
    }


しょうがないのでレジスタアクセスを無駄に1個増やしてみたところ、無事パルスが出るようになりました。

int main() {
    const uint LED_PIN = 25;
    const uint GPIO_PIN = 22;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PINGPIO_OUT);
    gpio_init(GPIO_PIN);
    gpio_set_dir(GPIO_PINGPIO_OUT);
    while (true) {
        gpio_put(LED_PIN0);
    //    sleep_ms(250);
        gpio_put(GPIO_PIN1);
        gpio_put(LED_PIN1);
    //    sleep_ms(250);
    }
}


1000030c <main>:
1000030c: b510      push {r4, lr}
1000030e: 2019      movs r0, #25
10000310: f000 f82e bl 10000370 <gpio_init>
10000314: 24d0      movs r4, #208 ; 0xd0
10000316: 0624      lsls r4, r4, #24
10000318: 2380      movs r3, #128 ; 0x80
1000031a: 049b      lsls r3, r3, #18
1000031c: 6263      str r3, [r4, #36] ; 0x24
1000031e: 2016      movs r0, #22
10000320: f000 f826 bl 10000370 <gpio_init>
10000324: 2380      movs r3, #128 ; 0x80
10000326: 03db      lsls r3, r3, #15
10000328: 6263      str r3, [r4, #36] ; 0x24
1000032a: 23d0      movs r3, #208 ; 0xd0
1000032c: 061b      lsls r3, r3, #24
1000032e: 2280      movs r2, #128 ; 0x80
10000330: 0492      lsls r2, r2, #18
10000332: 619a      str r2, [r3, #24]
10000334: 2180      movs r1, #128 ; 0x80
10000336: 03c9      lsls r1, r1, #15
10000338: 6159      str r1, [r3, #20]

1000033a: 615a      str r2, [r3, #20]
1000033c: e7f5      b.n 1000032a <main+0x1e>

0x1000032aからのループなのでちょうど10ステップ、このループが12MHzぐらいで回っているので、I/Oアクセスでもそれほどスピードが落ちていない感じです。


0 件のコメント:

コメントを投稿