chakokuのブログ(rev4)

日々のごった煮ブログです

Raspberry Pi Picoに搭載されているRP2040のPIOをMicroPythonから叩きたい・・が、、あまり仕様が分からない

RP2040はWiFi/BLEがないので、どう使ったらいいのやらと思っていたけど、プログラミングできるステートマシンが搭載されたPIOが熱いと思う。多分。
CからPIOを叩くのが本筋かもしれないが、コンパイルしないといかんので面倒で、Try&Errorをなんどもやりたい場合はMicroPytonが便利と思う。なんだけど、、MicroPython版でPIOを叩くための情報があまりない。サンプルソースもあるにはあるけど、説明がないので、細かい部分がどうなっているのかわからない。仕様もStateMachine用のアセンブラとちょっと違ってるように思えるのだけど。。Pythonでputを使ってるけど、アセンブラにはPULL/OUTはあるけどPutは無いのでは?? 勉強中だから勘違いかもしれんが。Raspberry Pi Pico Python SDKとかいろいろ仕様書を読むのだけど、MicroPythonの表記法とPIOのハードウエアアーキテクチャが頭の中でリンクしないというか。。

sm.put(ar,8) というのが、8bitを除いて残り24bit(単位がbitかbyteか正確には理解できていません)を渡すということらしいが、、putって一体何・・


■追記
putはTxFIFOへの書き込み操作らしい。RxFIFOからの読み込みは、getの様だ。FIFOのR/W時にどれだけのbit数が欲しいのかを引数で指定するのだろう。多分。(単位はbit? byte??) 該当のソースコードは多分以下なのだが、、Python->Cの呼び出しシーケンスが分かっておらず、読み解けない。。

micropython/rp2_pio.c at master · micropython/micropython · GitHub

// StateMachine.put(value, shift=0)
STATIC mp_obj_t rp2_state_machine_put(size_t n_args, const mp_obj_t *args) {
    rp2_state_machine_obj_t *self = MP_OBJ_TO_PTR(args[0]);
    uint32_t shift = 0;
    if (n_args > 2) {
        shift = mp_obj_get_int(args[2]);
    }
    uint32_t data;
    mp_buffer_info_t bufinfo;
    if (!mp_get_buffer(args[1], &bufinfo, MP_BUFFER_READ)) {
        data = mp_obj_get_int_truncated(args[1]);
        bufinfo.buf = &data;
        bufinfo.len = sizeof(uint32_t);
        bufinfo.typecode = 'I';
    }
    const uint8_t *src = bufinfo.buf;
    const uint8_t *src_top = src + bufinfo.len;
    while (src < src_top) {
        uint32_t value;
        if (bufinfo.typecode == 'B' || bufinfo.typecode == BYTEARRAY_TYPECODE) {
            value = *(uint8_t *)src;
            src += sizeof(uint8_t);
        } else if (bufinfo.typecode == 'H') {
            value = *(uint16_t *)src;
            src += sizeof(uint16_t);
        } else if (bufinfo.typecode == 'I') {
            value = *(uint32_t *)src;
            src += sizeof(uint32_t);
        } else {
            mp_raise_ValueError("unsupported buffer type");
        }
        while (pio_sm_is_tx_fifo_full(self->pio, self->sm)) {
            // This delay must be fast.
            mp_handle_pending(true);
            MICROPY_HW_USBDEV_TASK_HOOK
        }
        pio_sm_put(self->pio, self->sm, value << shift);
    }
    return mp_const_none;
}

■追記

jmp命令で使える条件

    # jmp condition constants
    "not_x": 1,
    "x_dec": 2,
    "not_y": 3,
    "y_dec": 4,
    "x_not_y": 5,
    "pin": 6,
    "not_osre": 7,

GitHubより
micropython/rp2.py at master · micropython/micropython · GitHub


■ご参考URL

なんとなく活動記録。様のPIOまとめ記事
Raspberry Pi Pico(RP2040)のPIOについて備忘録(MicroPython)

「Get started with MicroPython on Raspberry Pi Pico」
HackSpace magazine
一見初心者向けの入門書のようだけど、最後の付録の章ではPIOについてもかなり詳しく書いている。これを見ながら勉強したが、、、分かり切らない。