Skip to content

Instantly share code, notes, and snippets.

@GOROman
Created August 21, 2026 08:07
Show Gist options
  • Select an option

  • Save GOROman/cbe3644bbe858d2b661a6723b22671ff to your computer and use it in GitHub Desktop.

Select an option

Save GOROman/cbe3644bbe858d2b661a6723b22671ff to your computer and use it in GitHub Desktop.
DW3720 (QM33120W) SPI コマンド一覧 — M5Stamp UWB の中身(ファストコマンド27種+レジスタ+API層)

DW3720 (QM33120W) の SPI コマンド一覧 — M5Stamp UWB の中身

M5Stack Stamp UWB (S017) に載っている Qorvo QM33120W(DW3720) を SPI から制御するときのコマンド体系まとめ。出典は公式 Arduino ライブラリ m5stack/M5Stamp-UWB に同梱されている Qorvo ドライバのヘッダ(src/qm33120w_sdk/dw3720/dw3720_deca_vals.h)。

SPI トランザクションは大きく3層に分かれる。

1. ファストコマンド(1バイト即時実行・27種)

レジスタアクセスを介さず、短い1バイト書き込みだけでチップの動作を切り替えるコマンド群。測距シーケンスのリアルタイム制御はこれで行う。

基本動作

コマンド 動作
CMD_TXRXOFF 0x00 TX/RX を停止しイベントをクリアして IDLE へ
CMD_TX 0x01 即時送信開始
CMD_RX 0x02 受信有効化

遅延送受信(測距の心臓部)

「◯◯の時刻を基準に、DX_TIME 後に正確に送信/受信する」をハードウェアが保証する。

コマンド 基準時刻
CMD_DTX / CMD_DRX 0x03 / 0x04 DX_TIME レジスタの絶対時刻
CMD_DTX_TS / CMD_DRX_TS 0x05 / 0x06 前回の送信時刻 + DX_TIME
CMD_DTX_RS / CMD_DRX_RS 0x07 / 0x08 前回の受信時刻 + DX_TIME
CMD_DTX_REF / CMD_DRX_REF 0x09 / 0x0A 基準時刻 DREF_TIME + DX_TIME

複合動作

コマンド 動作
CMD_CCA_TX 0x0B チャンネルクリア確認(CCA)後に送信
CMD_TX_W4R 0x0C 送信 → 完了後に自動で受信オン(Wait for Response)
CMD_DTX_W4R 0x0D 遅延送信(DTX)+ 送信後受信オン
CMD_DTX_TS_W4R 0x0E 遅延送信(DTX_TS)+ 送信後受信オン
CMD_DTX_RS_W4R 0x0F 遅延送信(DTX_RS)+ 送信後受信オン
CMD_DTX_REF_W4R 0x10 遅延送信(DTX_REF)+ 送信後受信オン
CMD_CCA_TX_W4R 0x11 CCA 送信 + 送信後受信オン

管理系

コマンド 動作
CMD_CLR_IRQS 0x12 全イベント/割り込みクリア
CMD_DB_TOGGLE 0x13 受信ダブルバッファのポインタ切り替え
CMD_SEMA_REQ 0x14 セマフォ取得要求(デュアル SPI マスター用)
CMD_SEMA_REL 0x15 セマフォ解放
CMD_SEMA_FORCE 0x16 セマフォ強制取得(SPI2 のみ発行可)
CMD_SEMA_RESET 0x18 グローバルデジタルリセット(セマフォ含む)
CMD_SEMA_RESET_NO_SEM 0x19 グローバルデジタルリセット(セマフォ除く)
CMD_ENTER_SLEEP 0x1A スリープ/ディープスリープ突入(ANA_CFG に従う)

dwt_softreset() が使うのはこのリセット系。RST ピンを配線していなくても SPI 経由でチップを初期状態に戻せる(前回の CONFIG_FAILED 記事参照)。

2. レジスタ読み書き(アドレス指定トランザクション)

1〜2バイトのヘッダ(R/W ビット + レジスタファイル ID + オフセット)に続けてデータを転送する通常アクセス。

  • デバイス ID 読み出し(DEV_ID = 0xDECA0314)
  • PHY 設定(チャンネル、プリアンブル、データレート、STS…)
  • 送信フレームデータの書き込み / 受信フレームの読み出し
  • 送受信タイムスタンプの読み出し(40bit、分解能 約15.65ps ≒ 4.7mm)
  • ステータス/イベントレジスタの確認

3. ドライバ API 層(実際に使う層)

生コマンドを直接叩くことは通常なく、Qorvo ドライバの dwt_* API(deca_device_api.h)を使う。代表的なもの:

  • dwt_initialise() / dwt_configure() — 初期化・PHY 設定
  • dwt_writetxdata() + dwt_starttx() — 送信(遅延送信・W4R のフラグあり)
  • dwt_rxenable() — 受信開始
  • dwt_readrxtimestamp() / dwt_readtxtimestamp() — タイムスタンプ取得
  • dwt_setdelayedtrxtime() — 遅延送受信の時刻設定
  • dwt_softreset() — SPI 経由のソフトリセット

M5Stamp-UWB ライブラリはさらにこの上に sendFrame() / receiveFrame() / requestRange() / requestDSRange() という Arduino 向け API を被せている。

なぜ DS-TWR が cm 級で測れるのか

鍵は CMD_DTX_RS(受信時刻基準の遅延送信)。「Poll を受信した瞬間の時刻 + 正確に N µs 後」に応答をハードウェアが送信するため、MCU のソフトウェア遅延が ToF 計算に一切乗らない。あとは 40bit・15.65ps 分解能のタイムスタンプを両側で交換すれば、電波の飛行時間(1ns ≒ 30cm)をサブナノ秒精度で求められる、という仕組み。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment