M5Stack の UWB 測距モジュール Stamp UWB (S017 / QM33120W) を、StampC5 ではなく Seeed XIAO ESP32-C6 から使おうとして、初期化エラー CONFIG_FAILED に丸ハマりした記録。結論だけ知りたい人は最後の「原因と対策」へ。
- Seeed XIAO ESP32-C6
- M5Stack Stamp UWB(SKU: S017、Qorvo QM33120W / DW3720)
- Arduino ライブラリ: m5stack/M5Stamp-UWB
配線は最小の6本(+3V3, GND, SPI 4本)。RST / WAKEUP / IRQ / GP7 は未接続で、コード側で M5STAMP_UWB_PIN_UNUSED を指定。
| Stamp UWB | XIAO ESP32-C6 |
|---|---|
| 3V3 (パッド2) | 3V3 |
| GND (パッド1/8/12) | GND |
| SCK (パッド11, DW_CLK) | D8 (GPIO19) |
| MISO (パッド7, DW_CDO) | D9 (GPIO20) |
| MOSI (パッド9, DW_CDI) | D10 (GPIO18) |
| CS (パッド10, DW_CSn) | D3 (GPIO21) |
ライブラリのデフォルトは StampC5 のピン配置なので、XIAO では SPI ピンを全部明示する:
M5Stamp_UWBConfig cfg;
cfg.pin_sck = 19; // D8
cfg.pin_miso = 20; // D9
cfg.pin_mosi = 18; // D10
cfg.pin_cs = 21; // D3
cfg.pin_rst = M5STAMP_UWB_PIN_UNUSED;
cfg.pin_wakeup = M5STAMP_UWB_PIN_UNUSED;
cfg.pin_irq = M5STAMP_UWB_PIN_UNUSED;
cfg.pin_gp7 = M5STAMP_UWB_PIN_UNUSED;
uwb.begin(cfg);DS-TWR の Tag スケッチを書き込んだら一発で動いた。
UWB_ID,dev_id=0xDECA0314,chip=QM33120/DW3720
TEST_START,result=OK
DS_RANGE_STAT,count=10,ok=0,fail=10,last=FAIL,error=RX_TIMEOUT
RX_TIMEOUT は相手(Anchor)がまだいないだけなので正常。「楽勝では?」と思ったのが罠だった。
Anchor 版スケッチを上書き書き込みした瞬間から begin() が失敗するようになった。
UWB_BEGIN,result=FAIL,error=CONFIG_FAILED
UWB_RAW_ID,dev_id=0xDECA0314 ← デバイスIDは読める!!
ここが混乱ポイント。
- デバイスID
0xDECA0314は正しく読めている → SPI 配線は生きている - なのに PHY 設定(
dwt_configure())だけが失敗する
疑って外したもの:
- SPI が速すぎる説 — ジャンパ線で 16MHz は無謀かと思い 4MHz に落とした → 変わらず
- 電源品質説 — Stamp UWB は高PSRR LDO / リップル12mVpp以下を要求する。パスコン不足を疑った → (それはそれで入れるべきだが)今回の原因ではなかった
- 配線の接触不良説 — 繋ぎ直しても変わらず
決定打は再現条件の整理だった。
- USB 抜き差し(完全な電源断)→ 初期化成功 ✅
- 書き込み直後の再起動(MCUだけリセット、UWBは通電したまま)→ CONFIG_FAILED ❌
つまり最初に「一発で動いた」のは冷間起動だったから。スケッチを書き込むと esptool が MCU をリセットするが、UWB チップは通電したまま前回の動作状態(受信中など)を引きずる。RST を配線していないのでライブラリはチップをリセットできず、中途半端な状態のチップに dwt_configure() して失敗していた。
原因: RST 未配線 + ライブラリがソフトリセットを呼んでいない、の合わせ技。M5Stamp-UWB ライブラリの begin() は RST ピンがあればハードリセットするが、無い場合は何もせず初期化に進む。Qorvo ドライバには SPI 経由の dwt_softreset() があるのに未使用だった。
対策は2つ。どちらでも解決する:
Stamp UWB パッド6 (DW_RSTn) を空き GPIO に繋ぎ、cfg.pin_rst に指定する。
src/M5Stamp_UWB.cpp の init() で dwt_initialise() の前に1行:
// Recover from any state left by a previous run (e.g. warm MCU reboot with
// no RST wiring); without this dwt_configure() can fail until power cycle.
if (_active == this) {
dwt_softreset(0);
delay(2);
}これで RST 未配線・6本結線のままでも、書き込み→再起動のたびに USB を抜き差しする必要がなくなった。修正は GOROman/M5Stamp-UWB の fix-warm-reset ブランチ に置いてある。
- 「デバイスIDは読めるのに設定で失敗する」は配線ミスではなくチップの状態異常を疑う
- リセットラインを省略するなら、ソフトリセットを呼んでいるかライブラリのソースを確認する
- 「最初は動いたのに」系のバグは、冷間起動と温間リセットの違いを最初に切り分けると早い
公式 KiCad フットプリント + 回路図ライブラリから復元。1.27mm ピッチ、左右6パッドずつ。
┌───────────────────┐
│ アンテナ領域 │ ← 基板外へ/下に銅箔なし
GND 1 ──┤ ├── 12 GND
3V3 2 ──┤ ├── 11 DW_CLK (SCK)
DW_WAKEUP 3 ──┤ QM33120W ├── 10 DW_CSn (CS)
DW_IRQ 4 ──┤ ├── 9 DW_CDI (MOSI)
DW_GP7 5 ──┤ ├── 8 GND
DW_RSTn 6 ──┤ ├── 7 DW_CDO (MISO)
└───────────────────┘