XIAO nRF52840 のVBUS判定

Seeed Studio XIAO nRF52840 (以下、XIAO nRF) で、USBが接続されているか (VBUSが給電されているか) を判定する方法を調査した。

何がしたいか?

XIAO nRFにはLiPoバッテリーを接続して給電/充電するパッドがある。USB接続されているときはマイコンにはUSBから給電され、USB接続されておらずバッテリーが接続されていればバッテリーから給電される。そこで、USB接続されているかどうかをマイコンのソフトウェアで判定したい。


判定方法

USBREGSTATUS レジスタの VBUSDETECT ビットの値をチェックする。VBUSが給電されていればビットがセットされる。Arduino環境のライブラリにそれらしいAPIが見当たらないので、レジスタの値を直接読み取る。

  uint32_t usb_reg = NRF_POWER->USBREGSTATUS;
  if (usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk) {

サンプルスケッチ

USB接続されていれば基板上の青色LEDが点灯し、シリアルポートがターミナルで開かれるのを待ってからメッセージを出力する。USBが接続されておらずバッテリーから給電されていれば赤色LEDが点灯する。

ボードの設定は Seeed nRF52 Boards を選択する。Seeed nRF52 mbed-enabled Boards を選択する場合は、1行目 (#include ...) をコメントアウトすること。

#include <Adafruit_TinyUSB.h> // for Serial

void setup()
{
  pinMode(LED_RED,  OUTPUT);
  pinMode(LED_BLUE, OUTPUT);
  digitalWrite(LED_BLUE, HIGH);
  digitalWrite(LED_RED,  HIGH);

  delay(100); // wait for VBUS detect (?)

  // VBUS detect
  uint32_t usb_reg = NRF_POWER->USBREGSTATUS;
  if (usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk)
  {
    digitalWrite(LED_BLUE, LOW);
    Serial.begin(115200);
    while(!Serial); // wait for Serial ready
    delay(10);      // wait a little more (?) 
    Serial.println("VBUS Detected!");
  }
  else
  {
    digitalWrite(LED_RED,  LOW);
  }
}

void loop()
{
}

注意点

XIAO nRF はいろいろクセがあるので要注意。

  • XIAO nRF の 5VピンはUSBのVBUSと直結。(上記回路図の VIN でなく VBUS )
  • そのため外部から5V給電するとVBUSと衝突するし、 VBUSでUSB接続を判定することができない。
  • 衝突を避けるには外部にダイオードが必要。
  • 起動直後にVBUS判定をするにはすこしウェイトが必要。
  • ボードの設定は Seeed nRF52 Boards と Seeed nRF52 mbed-enabled Boards の2種類があり、使えるライブラリが異なる。
  • Seeed nRF52 Boards では、Serial を使用するには Adafruit_TinyUSB.h のインクルードが必要。
  • ホスト側がCOMポートを開くまでにシリアル出力した内容はバッファされない。
  • while(!Serial); でホストがCOMポートを開くのを待った後、もうちょっとだけ待つ必要がある。
  • USBを使用しないスケッチを書き込むと、次にスケッチを書き込もうとしてもCOMポートが開けずにエラーになることがある。
  • その場合はリセットボタン (USBコネクタの横の小さいタクトスイッチ) をダブルクリックする。
  • その際、ホスト側でCOMポート番号が変わることがある。

参考


関連記事