Arduino LeonardoはユーザスケッチでもUSB割り込みが走っている

Arduino LeonardoはユーザスケッチでもUSB割り込みが走っている

これ結構面倒くさい問題だったりします。

Arduino Uno とか nano とか一般的なArduinoは、PCとシリアル、UARTでつながってますが、PC側にはFT232のようなUSBーUART変換ICがちゃんと存在してていろいろ面倒な処理をした後のデータがAVRマイコンにやってくるわけで、ある意味分かり易いし、有り難い設計ですね。

ところが、Leonardoは、幸か不幸か、USBPhyチップを内蔵してるので、外づけ変換ICが必要無い分、ソフトがややこしい事に・・・

main()でこそっと。

int main(void)
{
    init();

    initVariant();

    #if defined(USBCON)
    USBDevice.attach();
    #endif

    setup();

    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }
    return 0;
}

って、見逃しがちですが、しっかりUSB blabla attach って、されてます。

void USBDevice_::attach()
{
    _usbConfiguration = 0;
    _usbCurrentStatus = 0;
    _usbSuspendState = 0;
    USB_ClockEnable();

    UDINT &= ~((1<<WAKEUPI) | (1<<SUSPI)); // clear already pending WAKEUP / SUSPEND requests
    UDIEN = (1<<EORSTE) | (1<<SOFE) | (1<<SUSPE); // Enable interrupts for EOR (End of Reset), SOF (start of frame) and SUSPEND

これ考えてみれば当たり前ですが、Leonardoのブートローダの場合、ユーザスケッチをロードして制御をユーザ側に移したあと、USBからの通信がなくなるとArduinoIDEと二度とつながらなくなりますね。またシリアルモニタも動作しませんしね。

ブートローダでリセット後の何秒かは待つ、みたいな仕様のものもあるようですが、いづれにしても扱いにくいものです。

USBをしゃぶりつくすレベルで知識を持ってないと、これを好きに扱うのはちょっと困難ですね。昨今はこの手のボードを何かに組み込むときにコストを考える必要はなくなってると思いますので、素直に情報の多いUNOとかを使うのが一番無難だという結論でした。