Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

99L Communication Board

ESP32-S3上でMission BoardのClassic CANを受信し、最新のNatsu-B/Vault 99L仕様に従うcompact LoRa packetへ中継する通信基板です。GNSS、通信基板microSD、Recovery中継もこのrepositoryが所有します。

99L Control roll protocolの固定sourceとmigration状態はdocs/99l_source_contract.jsonを参照してください。CAN 0x10AとLoRa A7はunwrapped reference/deviationを保持し、ComBoardでは最短角へ再計算しません。A3を変更せず、flight中はA7を約0.5秒周期で追加し、reference captureまたはrange/error status変化で送信を追加要求します。

Architecture

  • src/can/protocol.rs: 11-bit standard CAN codec。125 kbit/s、little-endian、DLCとreserved bitを検証します。
  • src/can/cache.rs: CAN IDごとのlatest value、受信時刻、freshness、MissionEvent OR latchを保持します。
  • src/can/command.rs: pending最大16件とresult cache 16件を管理し、duplicate replayと同一ID異payload拒否を行います。
  • src/can/recovery.rs: Recovery command lifecycle、6-byte CAN fragmentの16-byte A6結合、sequence gapとresume offsetを管理します。
  • src/lora_scheduler.rs: 500 ms absolute deadline、送信source優先度、B1 queue policy、Recovery fairnessとmissed slot処理を定義します。
  • src/tasks/can_communication.rs: TWAI唯一owner。RX、raw CAN logging、優先TX、bus-off recoveryを行います。
  • src/tasks/lora_task.rs: LoRa UART RX/TX唯一owner。uplink dispatch、A0〜A8/B0/B1生成、AUX Low→High完了確認とRX activity guardを行います。
  • src/tasks/gnss_task.rs: GNSS UART/enable唯一owner。receiver、configuration、fix、invalid、staleを区別します。
  • src/tasks/sd_task.rs: SD SPI唯一owner。受信したraw CANをCAN.CSVへ記録し、0x10Aのdecoded値はversioned ROLLV2.CSVへ分離します。

CAN、LoRa、GNSS、SDはowner task以外から直接操作せず、bounded channelで要求を渡します。緊急uplinkは通常command queueを経由せず、専用CAN safety channelへ渡します。

Build / flash / run

Nixが必要です。初回だけESP Rust toolchainを導入し、shellへ入り直します。

nix develop
espup install
exit
nix develop

以降のbuildと書き込みはnix develop内で実行します。

cargo fmt --all -- --check
cargo check
cargo test
cargo clippy --all-targets -- -D warnings

cargo build --release --features firmware \
  --target xtensa-esp32s3-none-elf -Z build-std=core

LoRa timingの実機診断ではlora-timing-debugを追加します。10送信ごとにsource別件数、request/queue/AUX/UART/物理送信/idle、missed slotとtimestamp異常をLORA_TIMINGへ出力します。

cargo build --release --features firmware,lora-timing-debug \
  --target xtensa-esp32s3-none-elf -Z build-std=core

接続先をserialで確認してから、生成したELFをespflashでESP32-S3へ書き込みます。flake.nixがbuild先を$CARGO_TARGET_DIRへ変更するため、repository内のtarget/ではなくこの変数を使います。port番号を推測して指定しないでください。

ls -l /dev/serial/by-id/
espflash flash --chip esp32s3 \
  --port /dev/serial/by-id/<Espressifのdevice名> \
  "$CARGO_TARGET_DIR/xtensa-esp32s3-none-elf/release/c99l_comboard"

/dev/ttyACM<N>は接続順で変わるため、/dev/serial/by-id/の安定した名前を使用してください。実測結果はdocs/hardware_test_results.mdに記録しています。

Protocol

CANは11-bit standard ID、125 kbit/s、payload 8 byte以下です。対応IDは0x001、0x002、0x008、0x010〜0x014、0x020、0x100〜0x10Aです。Mission由来raw量子化値は再量子化せず、LoRa packet組立時にcache snapshotを使用します。

freshness初期値は100 Hz系30 ms、LPS 120 ms、10 Hz系300 ms、GNSS 3000 msです。stale値は04aのreserved rawへ置換します。MissionEventはsequence duplicateを抑止し、A1〜A3 Flight packetへ実際に載せたbitだけ送信成功後にclearします。

LoRa downlinkはA0 22 byte、A1〜A3 24 byte、A4 15 byte、A5 12 byte、A6 24 byte、A7 9 byte、A8 24 byte、B0 10 byte、B1 3 byteです。E220固定送信prefixは00 00 04、bit packingはLSB-first、XORはheaderからpaddingまでです。A1〜A4、A7、A8は約0.5秒、A5 RecoveryBeaconは約10秒、A6は最大5 Hzです。

A8はmode entryやreason/GNSS/CAN health変化を契機とする前倒し・追加送信を行わず、500 ms absolute periodic deadlineで通常生成します。送信競合時は既存の共通schedulerのpriority/fairness policyを適用し、A8専用の追加deadlineやretryは設けません。

uplinkは固定11 byteです。

55 kind transaction_id command args[6] xor

transaction ID 0、checksum不一致、kind不明、Emergencyの非zero予約fieldは拒否します。Generic commandはCAN送信成功後にのみStartSequence連動のSD/GNSS副作用を開始します。CAN送信失敗結果もcacheし、同一requestへreplayします。

Recovery A6はtransfer IDとsequenceを検証します。gap、encode失敗、LoRa queue overflow時は結合を停止し、確認できたresume offsetをB0 detailへ返し、MissionへStopLogDumpを試行します。

LoRa TXは直前送信からの相対待機ではなく、500 msのabsolute deadlineを維持します。期限超過slotはburstで追送せずmissedとして進めます。送信優先度はEmergencyResult > CommandResult(B0) > GroundTimeRequest(B1) > Recovery(A6) > periodic(A0〜A8)です。B1は専用bounded queueを使い、同一request IDの連続duplicateを抑止し、満杯時はoldestをdropしてcounterへ記録します。

送信前はAUX Highを確認し、最後のLoRa RX activityから60 msを確保してAUX Highを再確認します。UART flush後は15 ms以内のAUX Low開始と、その後のHigh復帰を物理送信完了条件にします。旧fixed350 post-TX waitは使いません。実測値と判定はdocs/hardware_test_results.mdに記録しています。

Hardware assumptions

  • ESP32-S3、TWAI GPIO7/16、LoRa UART2 GPIO11/12、AUX GPIO8。
  • GNSS UART1 GPIO14/21、enable GPIO13。9600 baudで設定後115200 baudへ切替。
  • SD SPI GPIO41/42/40、CS GPIO2。既存PHY、pin、LED、task配置は変更していません。
  • Ground/ComBoard双方のE220 register readbackはC1 00 08 00 00 EC 81 04 C3 00 00で一致しました。搭載moduleの正確な型番を一次資料で確定できていないため、fieldの意味はこのrepositoryでは推測しません。

Test

testdata/99l_protocol_golden_vectors.txtはMission/Groundと同一です。host testは全CAN field、LoRa A0〜A8/B0/B1、uplink、reserved/error raw、freshness、MissionEvent、transaction replay、Recovery gap/partial/EOF、GNSS rangeを検証します。

cargo fmt --all -- --check
cargo check
cargo test
cargo clippy --all-targets -- -D warnings

GNSS設定応答、E220 readback、microSD read-only確認用firmwareは次で型検査できます。Mission Board用firmwareではないため、ComBoard以外へflashしないでください。

cargo check --test gnss_setting_response --features hardware-test \
  --target xtensa-esp32s3-none-elf -Z build-std=core
cargo check --test e220_readback --features hardware-test \
  --target xtensa-esp32s3-none-elf -Z build-std=core
cargo check --test sd_log_verify --features hardware-test \
  --target xtensa-esp32s3-none-elf -Z build-std=core

Known limitations

  • microSDは同一実機で初期化成功後、後続試験ではTimeoutCommand(41)が継続しました。loggingとCAN.CSV実データ確認はBLOCKEDで、card/hardware/初期化条件の切り分けが残っています。
  • GNSS設定は各UBX commandのACK/NAKを検証しますが、最後のbaud変更commandはbaud切替を伴うためACK未確認です。
  • GGAから位置/fixを取得します。NMEA日付をUnix時刻へ変換するperiodic GNSS TimeSyncは未実装で、MissionのTimeRequestはB1とGroundTimeResponse uplinkの経路を使用します。
  • A0/A6/B0/B1 layout、A0 status割当、local command code、freshness、Recovery rateはVaultの実装仮定台帳に記録した暫定値です。
  • A6はRAM上の16-byte queueへspoolします。通信基板microSDへの全Recovery dump spoolと自動resume requestは未実装です。
  • GNSS receiver/configurationと屋内NO_FIX/OFF stale-clearは実機確認済みです。屋外fixは未評価です。
  • 3基板でCAN 100 Hz系とLoRa 130秒連続通信を確認済みです。長時間・離距離・RF干渉・電源変動を含む耐久試験は別途必要です。
  • Emergency resultはgeneric transaction trackerに登録せず安全優先CAN queueで送ります。F0/F1はCAN ownerをblockしない専用priority LoRa queueへ送り、正常resultは実機PASS、CAN TX失敗時のFailed/Timeout B0はbuild/test PASSです。Mission非接続の実機失敗経路は未評価です。
  • PASS: ComBoardのabsolute scheduler、B1専用queue、AUX-RX guardはA0-onlyとA0+B1連続試験で確認済みです。Groundの安全boundary/AUX hardeningを含む最終artifactでは、0〜450 msの100位相試験が100/100成功し、g 0x7F/leの最大遅延は968.323/968.250 msでした。production復帰後は69.501秒で140 packet、全packet間隔平均500.007 ms、g 0x7F/leは909.386/909.339 msでfinal B0を返しました。CAN/LoRa/AUX/queue drop errorは0、診断logはproductionに残っていません。
  • PARTIAL: 全source同時競合のpriorityとB1満杯時oldest dropはhost testのみで、実機stressは未実施です。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages