Casio WSD-F30 のサブLCD を root なしで取り戻す: dual-layer 編 ― bit 7 LCD_PRIMARY と lock-out を WakeLock で攻略する

このシリーズについて
Casio WSD-F30 のサブLCD を root / bootloader unlock / 署名権限なしで取り戻す解析シリーズの Part 2 (dual-layer 編) です。
- Part 1: 入口編 ― 「HARUKI」初表示まで — APK 逆解析、AIDL 復元、
bindService+lcdCtl(9)でサブLCDに任意文字を出すまで - Part 2 (この記事): dual-layer 編 — OLED watchface + サブLCD content 同時可視を実現するための bit 7 LCD_PRIMARY 攻略と、lock-out 状態の解除方法の発見
- Part 3: プロトコル編 — wire-level (
/dev/MultiSensors_CD_01への 7-byte write) と native ライブラリ、隠し機能と mode 15+ reboot 領域
要旨
Part 1 では「Wear OS スリープ中にサブLCDで自前 content を出す」(OLED が消えた後にサブLCDだけ表示) を実現した。今回のスコープはもう一段上で、OLED watchface とサブLCD content が同時に見える状態 = ハードウェア的には可能なのに Casio 純正アプリでも実装されていない、隠れた dual-layer 表示。
なぜ Casio がやってないかは想像がつく。Wear OS が起動してるなら OLED で描画した方が鮮明で情報量も多いから、わざわざモノクロのサブLCD content を重ねる動機がメーカー側に薄かった。OLED をバックライト的に使う需要は Multi Timepiece (= OLED off モード) のように そもそも OLED を切る前提のシーン でだけ意味があったと思われる。
補足: Casio のいう Multi Timepiece は別物で、こちらは「Wear OS の電源を落としてサブLCDのみで動かす省電力モード」(Extend Mode と同系統)。本記事のスコープは OLED が生きたまま両層が同時可視になる状態 = 本来 IC ハードウェアが持っている能力を、純正がやっていない使い方で活用するパターン。
ここで必要になるのが Part 1 で意図的に避けた lcdCtlBits(9, 1, 1) (3 引数版) の bit 7 フラグ。これを立てた瞬間、サブLCDが強制 active 化されて OLED 表示中でも内容が可視になる代わりに、副作用として OLED が物理的に off になり、ユーザーがどう操作しても Wear OS の UI に戻れなくなる「lock-out 状態」 が発生する。Part 1 で「絶対呼ぶな」と書いていたやつ。
これを実用に持っていくため、
- 物理レイヤー構造を再理解 (上が monochrome memory LCD、下が AMOLED、LCD の「白」セグメントが半透明 mask、「黒」セグメントは透過で後ろの OLED が見える)
- bit 7 の正体を
CwdSegmentLcdServiceのbitLCD_ON = 0x80定数から特定 - lock-out 状態の解除方法を 5 種類の BroadcastReceiver を exported で公開して 1 個ずつ isolate 実験
WakeLock.release()一発だけが解除トリガであることを発見- 最終確定パターン (
wl.acquire()→ bit 7 + content 書込 →wl.release()) で実用 AOD 経路完成
その過程で「中央 7-seg は IC ハードコードで書けない」(Part 1 結論) も訂正される。Mode 0 (BLANK) と Mode 5 (BOTTOM_CLOCK) では setCenter7Seg が反映されることが分かり、ストップウォッチ等の自作機能の道が開けた。
物理レイヤー構造の正確な理解
Part 1 で「OLED の上にサブLCD」と書いたが、これは Casio のマーケティングコピー「DUAL LAYER DISPLAY」の正体を改めて整理するとこうなる:
前面 (上): monochrome memory LCD
・「白」セグメント (文字や模様) = 半透明 mask
・「黒」セグメント (背景) = 透過、後ろが見える
↓
背面 (下): AMOLED (発光、color 任意)
直感とは逆だが、物理的にはこう動いている:
- LCD の「白」セグメント → 液晶分子で半透明 mask がかかった状態。表面反射で白っぽく見える、後ろの OLED の光はうっすら弱まってちょっとぼやけて見える程度 (完全遮蔽はされない)
- LCD の「黒」セグメント (= LCD が描画していない領域) → 透過、後ろの OLED の色がそのまま見える。OLED が黒なら黒、OLED が赤なら赤
これで Casio MUS モードでボタンを押した瞬間に一瞬だけ発生する「OLED バックライト色 + サブLCD の文字」という見た目が説明できる (純正がこれを定常表示として実装することはしていない):
- OLED は単色 (赤 / 緑 / 白) で全体発光
- サブLCD の 「白」セグメントが文字として描画される (半透明 mask、表面反射で白く浮き出る)
- 周囲の 「黒」セグメント (描画していない領域) からは OLED の単色が透けて見える
- 結果: 色付き背景に白文字、視認しやすい
つまり 「dual-layer 同時可視」を実現するには、サブLCDを active のまま OLED にも何か (watchface) を出せばいい、という発想に切り替わる。Part 1 では「サブLCDを active にすると OLED が落ちる」副作用に詰まったので、今回はその副作用を制御する。
ハードルとブレークスルー
1. bit 7 = bitLCD_ON の正体
lcdCtlBits(mode, b6, b7) の b7 bit (= LCDCTL バイトの bit 7) は、CwdSegmentLcdService の定数で bitLCD_ON = -128 (0x80) と命名されていた。
正確な動作はこう:
- bit 7 OFF (デフォルト) = アプリの書き込みは IC のバッファに届くが、OLED 表示中はサブLCDが物理的に OFF なので画面には見えない。Wear OS がスリープして OLED が消えてサブLCD駆動に切り替わったタイミングで、IC バッファに保存されていた内容が表示される。Part 1 の「電源ボタンを押すと『HARUKI』が見える」はこの挙動を利用したもの (memory LCD の last frame 保持と組み合わさってる)
- bit 7 ON = サブLCDを強制的に即時 active 化する。OLED 表示中でもサブLCDが見える状態になる代わりに、OLED が物理 off になる副作用が発生 (= 我々が「lock-out」と呼んできた状態)
つまり Part 1 で「lcdCtl(9) (1 引数版) でも書けたじゃん、bit 7 不要じゃん」と思っていたのは半分正解で、書き込み自体は OFF でも届いていた、ただ OLED 表示中は見えなかっただけ。電源ボタン押して OLED を消すと見えるようになる、というのが Part 1 のスコープ。
lcdCtlBits(9, 1, 1) の第 3 引数 1 で bit 7 を立てると、IC が「LCD 強制 active 中は OLED を切る」設計のため、OLED が物理 off になる。これは IC のハードウェアレベルの挙動で AIDL からは止められない。これが lock-out 状態の正体。
2. Lock-out 状態の最初の遭遇
実機で lcdCtlBits(9, 1, 1) を実行 → サブLCDに「FUTABA」が表示 → OLED 真っ黒 → 電源ボタンを押しても無反応 → 画面タップしても無反応 → 完全に Wear OS UI に戻れない。
最初に試した脱出は adb shell am force-stop com.haruki.futabatest。アプリプロセスごと殺すと OLED が復帰して Wear OS に戻れる。
ただし放置していてもしばらくすると勝手に復帰することも分かった。Wear OS は明示的に WakeLock を取り続けてないアプリを一定時間後に自動お片付け (Doze / App Standby 相当の挙動) するので、そのタイミングで WakeLock が release され、IC が bit 7 状態を解除して OLED 復帰可能になる。Activity ベースの普通のアプリならこれが効く。
逆に Foreground Service + WakeLock 取りっぱなし のような常駐実装だと、Wear OS の自動お片付けが効かないので、force-stop しか脱出経路がない。Part 2 序盤で詰まったのはこちらのパターン。
ここで疑問が出る: 「自動お片付けで自然復帰できる」と「force-stop で強制脱出」の中間にある決定要素は何なのか? bindService が切れること? プロセスの kill 自体? それとも WakeLock の release? 切り分けないと安全な実用パターンが組めない。
3. 「force-stop で復帰する」のはなぜか? — 5 種類の isolation 実験
am force-stop で復帰するということは、その動作のどこかが bit 7 状態を解除している。候補:
- アプリプロセス kill 自体
- bindService が切れること
- foreground service の停止
- WakeLock の自動 release
- いずれかの組み合わせ
これを切り分けるため、自作テストアプリに 5 種類の BroadcastReceiver を exported で実装して、adb から個別に呼べるようにした:
<receiver android:name=".KillSelfReceiver" android:exported="true">
<intent-filter><action android:name="com.haruki.futabatest.KILL_SELF"/></intent-filter>
</receiver>
<receiver android:name=".UnbindReceiver" android:exported="true">
<intent-filter><action android:name="com.haruki.futabatest.UNBIND"/></intent-filter>
</receiver>
<receiver android:name=".WakeLockReceiver" android:exported="true">
<intent-filter><action android:name="com.haruki.futabatest.RELEASE_WAKELOCK"/></intent-filter>
</receiver>
<receiver android:name=".NotifyShutdownReceiver" android:exported="true">
<intent-filter><action android:name="com.haruki.futabatest.NOTIFY_SHUTDOWN"/></intent-filter>
</receiver>
<receiver android:name=".ResetReceiver" android:exported="true">
<intent-filter><action android:name="com.haruki.futabatest.EMERGENCY_RESET"/></intent-filter>
</receiver>
各 Receiver は対応するクリーンアップを 単独で 実行するだけ:
KillSelfReceiver→Process.killProcess(Process.myPid())UnbindReceiver→unbindService(conn)だけWakeLockReceiver→wl.release()だけNotifyShutdownReceiver→lcd.notifyAppShutdown()(tx 41) を呼ぶだけResetReceiver→ 上記全部 +lcd.lcdCtl(1)で classic mode に戻す
これらを 1 個ずつ adb から叩いて OLED が復帰するか観察。
4. isolation 実験の結果
| 試行 | OLED 復帰 (ユーザータップで)? |
|---|---|
unbindService だけ | ❌ 復帰しない |
WakeLock.release() だけ | ✅ 復帰する |
Process.killProcess (自殺) | ✅ 復帰する |
am force-stop | ✅ 復帰する |
notifyAppShutdown (tx 41) | ❌ 効果なし |
「lock-out 状態」の正体: アプリが PARTIAL_WAKE_LOCK を hold している間、IC が bit 7 状態を維持する。
WakeLock release → system が通常 idle 遷移に入る → OLED 復帰経路に入る、というメカニズム。bit 7 自体が即時リセットされているかは別途要検証 (LCD content は memory LCD で保持されたままなので、少なくとも書き込みバッファは生きている)。
Process.killProcess や am force-stop で復帰していたのは 副作用として WakeLock も release されていただけで、プロセス kill 自体は必須ではなかった。さらに notifyAppShutdown (tx 41) は名前から「アプリ終了通知 → IC が後処理する」を期待したが、Casio コード内でも 1 箇所も呼ばれていない deadcode だった。
5. 最終確定パターン: WakeLock 即 release + WearOS スリープ → 復帰
isolation 実験の結論と、その後の挙動検証から、実用パターンはこう:
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "tx");
wl.acquire();
try {
lcd.lcdCtl(1); // 一度 classic 経由
lcd.lcdCtlBits(0, 1, 1); // Mode 0 + bit 7 SET (LCD active)
lcd.setTopPanelText("FUTABA", 1, 1); // 任意 content 書き込み
lcd.setCenter7Seg(12, 34, 56, 0, 0); // ★ Mode 0 なら中央 7-seg も書ける!
} finally {
wl.release(); // ★ ここで OLED 復帰経路に入る (lock-out 解除)
}
// この後、一度 WearOS をスリープに入れて → 再復帰させると dual-layer 表示が見える
これで:
- アプリで Mode 0 (or Mode 5) + bit 7 SET + content 書き込み
- WakeLock 即 release (これで OLED が復帰可能な状態に入る。bit 7 自体が即時リセットされてるわけではなく、後続の状態遷移で OLED が戻ってくる)
- WearOS を一度スリープに入れる (電源ボタン or 放置で自動 sleep)
- 再度ユーザータップ or 電源ボタンで復帰
- → このタイミングで Wear OS watchface が OLED に表示される
- → サブLCD content (bit 7 SET 中に書き込んだ白セグメントの文字) は memory LCD で保持されたままなので、OLED の上に浮き出て見え、周囲の LCD 黒 (透過) 領域から OLED watchface が同時に見える
- → ハードウェアが本来持っている dual-layer 動作の常時表示版が成立 (Casio 純正アプリでは MUS バックライト押下時の一瞬以外で活用されていない領域)
「スリープ → 復帰」のひと手間を挟むのが肝で、bit 7 SET 直後にそのまま OLED 復帰させようとしてもうまく定常状態に入らないことがある。一度サブLCDモードに完全に降りてから再度 OLED モードに上がってくる、というステートマシン的な遷移が必要っぽい。
Mode 0 / Mode 5 が肝、Mode 9 では制限あり
このフローが安定するのは Mode 0 (BLANK) と Mode 5 (BOTTOM_CLOCK) のとき。Mode 9 (CUSTOM) で同じことをやると、うまく dual-layer 状態に入らなかったり、強い lock-out になって WakeLock release でも OLED が戻らないことが多い。原因は未解明だが、IC 側の mode 別ステートマシンに何か違いがあると推測される。
実用上は dual-layer 同時可視を狙うなら Mode 0 一択 と思っておくのが安全。Mode 9 は Part 1 のスコープ (Wear OS スリープ後にサブLCDだけで表示) 専用、と棲み分ける。
実機写真: サブLCDに「FUTABA」+ 「123456」、OLED に Wear OS watchface (時刻 12:45、日付 MAY 25、気圧計、コンパス等) が同時表示。これが Part 2 の目標到達点。
6. Mode 0 と Mode 5 で setCenter7Seg が動く発見
Part 1 で「中央 7-seg は IC ハードコード時計のままで setCenter7Seg は無視される」と結論していた。これは Mode 1 / 9 / 10 / 11 / 12 で真だったが、Mode 0 (BLANK = 全領域フリー) と Mode 5 (BOTTOM_CLOCK = 中央フリー、下部時計) では setCenter7Seg が反映されることが分かった。
つまり:
- ストップウォッチ、任意カウンタ等の中央 7-seg 活用機能は API レベルで実現可能
- Casio が純正アプリで実装していないだけで、ハードウェア能力は最初から備わっている
これは Part 1 の「mode 9 = MEASUREMENT」が「上部マトリクスのみフリー、中央 7-seg は時計」だったのに対して、mode 0 / mode 5 を選ぶと中央 7-seg もアプリ自由になる、というモード選択の幅が広がった話。
サブLCD のモード全体像 (確定版)
Part 1 で出した表を、Part 2 の知見で完全版に更新:
| mode | 名称 | 上部マトリクス | 中央 7-seg | 下部 7-seg |
|---|---|---|---|---|
| 0 | BLANK / APP_FULL_CONTROL ★ | アプリ | アプリ | アプリ |
| 1 | CLASSIC | IC 時計 | IC 時計 | IC 自動 |
| 2 | NO_DISPLAY | (全消灯) | ||
| 3 | CALI (校正モード) | “CALI” 固定 | ”- - -“ | IC 時計 |
| 4 | NO_DISPLAY | (全消灯) | ||
| 5 | BOTTOM_CLOCK ★ | アプリ | アプリ | IC 時計 |
| 6 | NO_DISPLAY | (全消灯) | ||
| 7 | BATTERY_ONLY | バッテリーアイコンのみ | ||
| 8 | ALL_ICONS | 全アイコン点灯 | ||
| 9 | CUSTOM | アプリ | IC 時計 | アプリ |
| 10 | DAILY / STYLE_1 | watchface “日常スタイル” | ||
| 11 | OUTDOOR / STYLE_2 | watchface “アウトドアスタイル” | ||
| 12 | STAMINA / EXTEND | Extend Mode (10 日タイマ) | ||
| 13 | OUTDOOR_SLOW | mode 11 の省電力 variant (10s 更新) | ||
| 14 | STEP_COUNTER | 中央 7-seg に歩数 (setSteps と連動) | ||
| 15-31 | ⚠️ REBOOT | watch が即時再起動するので絶対叩かない |
★ = setCenter7Seg がアプリから反映される mode。
「やりたい表示」に応じて mode を選ぶのが肝:
- 上部マトリクスだけ自前 → mode 9
- 中央 7-seg まで自前にしたい (ストップウォッチ等) → mode 0 (全部フリー) or mode 5 (下部時計のまま)
- 下部 7-seg まで含めて全部自前 → mode 0
副次的に判明した API
dual-layer 攻略のついでに発見があった項目を 1 個だけ挙げておく:
setPanelMode(byte n) (tx 24) = ブライト / ダーク反転
Casio 純正 watchface 系の設定にある「ブライト / ダーク」の正体。
- byte
1= ブライト (白地に黒字、Casio デフォルト) - byte
2= ダーク (黒地に白字、reverse video)
SharedPref face_segment_2layer (0 or 1) が 0 → byte 1, 1 → byte 2 にマップされて呼ばれている。アプリから直接 tx 24 を叩けば瞬時切り替え可能。
なお
setMultiSensor(tx 29、MUS モード + バックライト色)、notify2Layer(tx 42)、notifyAppShutdown(tx 41) などについても見当はついているが、現時点では確実な動作仕様の特定が済んでいないので、Part 3 以降で扱う。AIDL のメソッド名から機能を想像すると外しやすい領域なので、安易に書かない方針。
安全ガイドライン
dual-layer 攻略中に「これは絶対やるな」が確定したパターン:
- ❌ Mode 15-31 を
lcdCtl()に渡す → IC が invalid mode で firmware crash → 即時再起動 - ⚠️ Mode 0 / Mode 5 + bit 7 を立てたまま WakeLock release しない → OLED が戻らない状態が続く (WakeLock release で復帰経路に入る)
- ❌ tick (定期ループ) で bit 7 を re-assert し続ける → bit 7 ON 状態が維持される = OLED 戻らない状態が持続
- ⚠️ Mode 9 + bit 7 の挙動は未検証。Mode 0 / Mode 5 と挙動が違いそう (OLED 復帰時に LCD 表示が解除される傾向あり?) だが、確証取れたら追記予定
検証時は必ず emergency reset の adb broadcast を準備しておくこと:
adb shell am force-stop com.haruki.futabatest
adb shell am broadcast -n com.haruki.sublcdtest/.ModeReceiver \
-a com.haruki.sublcdtest.LCDCTL --es opt_name emergency_reset
これを別ターミナルで打てる準備をした上で実機実験する。
実機写真
(写真は後日追加予定)
サブLCDに「FUTABA」+ 中央 7-seg「12 34 56」、OLED に Wear OS の watchface (時刻、日付、コンパス等) が同時表示されている状態。これは Casio 純正アプリでも実装されていない構成で、ハードウェアが用意した可能性を初めて常時表示として活用したパターンになる (Multi Timepiece は OLED off モード、MUS バックライトはボタン押下時の一瞬のみ)。
教訓
bitLCD_ON = 0x80のような難読化された定数名は ProGuard の対象外で生き残る。これが解析の手がかり。AIDL Stub のメソッド名はa()b()に潰されても、static final int / String 定数は名前が残ることが多い- 「lock-out から復帰させる方法」は副作用の組み合わせを 1 個ずつ切り分けるしかない。
am force-stopで復帰したからといって、kill 自体が必須とは限らない。5 種類の BroadcastReceiver を exported で公開して isolate する手法が綺麗 - WakeLock の release が OLED 復帰の引き金になる、というのは AIDL からは見えない実装。Android の電源管理と Casio 独自 IC の協調を実機実験で炙り出す必要があった (なお bit 7 そのものがリセットされているかは要追加検証。LCD content は memory LCD で保持されたままなので、少なくとも書き込みバッファは生きてる)
- 「中央 7-seg は IC ハードコード」は半分正解、半分間違い。Mode 1/9/10/11/12 で真、Mode 0/5 で偽。一度結論したことも、別 mode でテストし直すと覆ることがある
- emergency reset の adb broadcast を準備してから実機実験する。
am force-stopだけだと WakeLock + bit 7 周りの細かい挙動切り分けには不十分
よくある質問
bit 7 を立てずに dual-layer は出せない?
出せない。lcdCtl(9) (1 引数版、bit 7 OFF) だと、書き込みは IC バッファに届くものの、OLED 表示中はサブLCDが物理 OFF なので画面には出てこない。Wear OS スリープ後 (OLED off) には memory LCD の保持で表示される (これが Part 1 のスコープ)。一方、OLED watchface 表示中に同時にサブLCDも見えるようにする (Part 2 のスコープ) には、bit 7 でサブLCDを強制 active 化する経路が必須。
WakeLock を取らずに bit 7 だけ立てるとどうなる?
そもそも bit 7 を立てる API (lcdCtlBits) を呼ぶ時に、IC が「LCD active 中は OLED 切る」副作用を発火させるので、WakeLock の有無に関わらず一旦 OLED は落ちる。違いは「WakeLock を hold していると OLED 復帰経路に入れない」点。WakeLock を取らずに bit 7 を立てた場合は、Wear OS の電源管理が自然に走って OLED が復帰してくる挙動になる。
ただし WakeLock なしだと、書き込み中に system idle 遷移が走ると content 書き込みが途中で切れる可能性がある。書き込み中だけ WakeLock を取って、書き終わったら即 release が最適パターン。
Mode 9 + bit 7 ではうまくいかない?
実機で何度か検証したが、Mode 9 + bit 7 では dual-layer 状態に安定して入らなかったり、強い lock-out になって WakeLock を release しても OLED が戻らないことが多い。Mode 0 + bit 7 は安定するので、dual-layer 同時可視を狙うなら Mode 0 一択。Mode 9 は Part 1 のスコープ (Wear OS スリープ後にサブLCDだけで表示) 専用で棲み分けるのが現実解。
force-stop なしで dual-layer 表示する仕組みは作れる?
作れる。最終確定パターンの定型フロー:
wl.acquire()lcd.lcdCtlBits(0, 1, 1)+ content 書き込みwl.release()(← 直後)- アプリは alive のまま待機
- WearOS が一度スリープに入って (放置 or 電源ボタン)、その後ユーザータップ or 電源ボタンで復帰
復帰した瞬間に Wear OS watchface が OLED に出て、その上にサブLCD の白セグメント (文字) が半透明 mask として浮き出る。「スリープ → 復帰」のひと手間が必要だが、それ以降は force-stop なしで定常的に dual-layer 表示が成立する。
サブLCD content はいつまで保持される?
memory LCD なので電源を切るまで最後のフレームが保持される。書き込んでから何時間放置しても、画面オフ → 電源 OFF まで残る。
Casio 純正 Multi Timepiece と同じになる?
別物。Multi Timepiece は Wear OS の電源を落としてサブLCDのみで動かす省電力モード (Extend Mode と同系統) なので、Part 2 のスコープ (OLED + サブLCD 同時可視) とは方向性が違う。
そして Part 2 で作っている「OLED watchface 表示中に、サブLCD content も同時に見える」体験は Casio 純正アプリにも存在しない構成。Wear OS が起動してるなら OLED で描画した方が鮮明で情報量も多いので、Casio 自身が実装する動機がなかったと推測される。OLED をバックライト的に使う MUS モードでも、実際に dual-layer 状態が成立するのはボタン押下時の一瞬のみで、常時表示としては使われていない。
つまり今回のパターンは「ハードウェアが持っている隠れた可能性を、常時表示として活用する」というハードウェアの再発見に近い。本物の Multi Timepiece 体験 (サブLCDだけで動く時計) を作りたいなら、bit 7 を立てた lock-out 状態を意図的に維持する設計が必要、これは今回のスコープ外。
Wear OS のバッテリーに悪影響は?
WakeLock を即 release するパターンなら、追加で電力を食う要素はほぼ無い (書き込み数 ms 間だけ wake する)。サブLCD自体は memory in-pixel なので保持コストはゼロ。Wear OS 通常使用と同じ駆動時間。常時 WakeLock 取りっぱなしにしない限り問題なし。
次回: プロトコル編
Part 1 と Part 2 で AIDL レベルの操作はおおむね網羅した。Part 3 では更にその下層、/dev/MultiSensors_CD_01 char device への 7 バイト write のワイヤレベル、libLcdCommands.so の disasm で見えた Transfer() / setClassic() の中身、サブLCD・歩数・気圧・心拍・wrist gesture の信号が全部 1 つの device node に多重化されている構造、mode 15+ で確実に reboot する境界の総当たり検証、隠し 1-byte 0x02 リセットコマンド、などの low-level な話に進みます。
制作プロセスについて
bit 7 = bitLCD_ON 定数の特定、5 種類の BroadcastReceiver による lock-out isolation 実験、WakeLock.release() トリガの発見、Mode 0 / Mode 5 での setCenter7Seg 反映検証、最終確定パターン (acquire → bit 7 → content → release) の構成、副次的 API (setPanelMode / setMultiSensor) の役割推定などの調査と試行錯誤は Anthropic の Claude Code を活用した。実機 (WSD-F30) での lock-out 発火と復帰検証、emergency reset broadcast の運用、dual-layer 同時可視の目視確認は人間担当。