SNSへはこちら

STM32でUSBをベアメタル(5) - ついに認識!

あれから数日腐っていまして、死ぬほどハマりました。
出口が見えない難関って、こんなにもしんどくなるんですね。

さて、ひょんなことからついにデバイスが認識されたところまできましたので、ご報告です。
ここまで来たら今度こそトントン拍子のはず...そうだよね?そうだと言ってくれ。

原因:PMAの何か

というわけで色々と実験です。

取り敢えずSETUPごとに領域確保してみる

メモリが確実にあふれると思いますが、取り敢えずやってみます。

// Before
static void usb_ep0_handle_status(void) {
    if( g_last_setup.bRequest == SET_ADDRESS ) {
        USB->DADDR = USB_DADDR_EF | (g_last_setup.wValue & 0x7F);
    }
    // prepare for the next SETUP transaction
    iprintf("Ready for SETUP...\n");
    iprintf("Setup Packet Addr: 0x%x\n", pma_info.offsets.setup_packet);
    usb_ep0_receive(pma_info.offsets.setup_packet,
            sizeof(USBSetupPacket)
    );
}
 800056e:   8820        ldrh    r0, [r4, #0]
 8000570:   2108        movs    r1, #8
 8000572:   b280        uxth    r0, r0
 8000574:   f7ff ff9c   bl  80004b0 <usb_ep0_receive>

これは失敗。

// After
static void usb_ep0_handle_status(void) {
    if( g_last_setup.bRequest == SET_ADDRESS ) {
        USB->DADDR = USB_DADDR_EF | (g_last_setup.wValue & 0x7F);
    }
    // prepare for the next SETUP transaction
    iprintf("Ready for SETUP...\n");
    iprintf("Setup Packet Addr: 0x%x\n", pma_info.offsets.setup_packet);
    usb_ep0_receive(pma_info.offsets.setup_packet = alloc(sizeof(USBSetupPacket)),
            sizeof(USBSetupPacket)
    );
}
 8000586:   2008        movs    r0, #8
 8000588:   f7ff ff5c   bl  8000444 <alloc>
 800058c:   2108        movs    r1, #8
 800058e:   8020        strh    r0, [r4, #0]
 8000590:   f7ff ff9a   bl  80004c8 <usb_ep0_receive>

これは成功。

共にメモリアクセスに関しては大丈夫そう。ちなみに r4pma_info.offsets.setup_packet のアドレス。

適当にインクリメントしてみる

// After
static void usb_ep0_handle_status(void) {
    if( g_last_setup.bRequest == SET_ADDRESS ) {
        USB->DADDR = USB_DADDR_EF | (g_last_setup.wValue & 0x7F);
    }
    // prepare for the next SETUP transaction
    iprintf("Ready for SETUP...\n");
    iprintf("Setup Packet Addr: 0x%x\n", pma_info.offsets.setup_packet);
    pma_info.offsets.setup_packet += 20; // TEKITOU!!!!
    usb_ep0_receive(pma_info.offsets.setup_packet,
            sizeof(USBSetupPacket)
    );
}

成功するんだよなあ。つまり、バッファテーブルはうかつに変えるものではないらしい

ということで解決

なので、記述を一部見直し。基本的に addr_rxcont_rx は初期化時以外書き換えないように設定する。ついでに PMA に 64Bytes 分の領域を確保する。

さあ lsusb してみよう。すると...

Bus 020 Device 031: ID 0411:0231 Melco, Inc. Wired Gesture Mouse
Bus 020 Device 037: ID 04b4:120d Cypress Semiconductor Majestouch Convertible 2
Bus 020 Device 000: ID dead:beef dead Communication Device
Bus 020 Device 027: ID 2109:0102 VIA Labs, Inc. USB 2.0 BILLBOARD  Serial: 0000000000000001
Bus 000 Device 009: ID 2109:0817 VIA Labs, Inc. USB3.0 Hub

キターーーーーー!!!!!! ってか ストリングディスクリプタ無くても自動的に名前がつくのね

これにて第1目標達成です!次回から、その他ディスクリプタと USB CDC のお勉強をしながらコード追記していきたいと思います。
ソースコードはこちら