update: firmware and provisioning now supports bootloader and partition tables
This commit is contained in:
@@ -180,9 +180,14 @@ def _build_page(entries: List[bytes], slot_counts: List[int], seq: int = 0) -> b
|
||||
def generate(serial_number: str, hw_type: str, hw_version: str) -> bytes:
|
||||
"""Generate a 0x5000-byte NVS partition binary for a Vesper device.
|
||||
|
||||
serial_number: full SN string e.g. 'PV-26B27-VS01R-X7KQA'
|
||||
hw_type: board type e.g. 'vesper', 'vesper_plus', 'vesper_pro'
|
||||
hw_version: zero-padded version e.g. '01'
|
||||
serial_number: full SN string e.g. 'BSVSPR-26C13X-STD01R-X7KQA'
|
||||
hw_type: board family e.g. 'vesper', 'vesper_plus', 'vesper_pro'
|
||||
hw_version: zero-padded revision e.g. '01'
|
||||
|
||||
Writes the NEW schema keys (2.0+) expected by ConfigManager:
|
||||
serial ← full serial number
|
||||
hw_family ← board family (hw_type value, lowercase)
|
||||
hw_revision ← hardware revision string
|
||||
|
||||
Returns raw bytes ready to flash at 0x9000.
|
||||
"""
|
||||
@@ -190,9 +195,9 @@ def generate(serial_number: str, hw_type: str, hw_version: str) -> bytes:
|
||||
|
||||
# Build entries for namespace "device_id"
|
||||
ns_entry, ns_span = _build_namespace_entry("device_id", ns_index)
|
||||
uid_entry, uid_span = _build_string_entry(ns_index, "device_uid", serial_number)
|
||||
hwt_entry, hwt_span = _build_string_entry(ns_index, "hw_type", hw_type.lower())
|
||||
hwv_entry, hwv_span = _build_string_entry(ns_index, "hw_version", hw_version)
|
||||
uid_entry, uid_span = _build_string_entry(ns_index, "serial", serial_number)
|
||||
hwt_entry, hwt_span = _build_string_entry(ns_index, "hw_family", hw_type.lower())
|
||||
hwv_entry, hwv_span = _build_string_entry(ns_index, "hw_revision", hw_version)
|
||||
|
||||
entries = [ns_entry, uid_entry, hwt_entry, hwv_entry]
|
||||
spans = [ns_span, uid_span, hwt_span, hwv_span]
|
||||
|
||||
@@ -4,17 +4,75 @@ from datetime import datetime
|
||||
MONTH_CODES = "ABCDEFGHIJKL"
|
||||
SAFE_CHARS = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789" # No 0, O, 1, I — avoids label confusion
|
||||
|
||||
# Family segment (chars 3-6 of segment 1, after "BS")
|
||||
BOARD_FAMILY_CODES = {
|
||||
"vesper": "VSPR",
|
||||
"vesper_plus": "VSPR",
|
||||
"vesper_pro": "VSPR",
|
||||
"agnus": "AGNS",
|
||||
"agnus_mini": "AGNS",
|
||||
"chronos": "CRNS",
|
||||
"chronos_pro": "CRNS",
|
||||
}
|
||||
|
||||
# Variant segment (first 3 chars of segment 3)
|
||||
BOARD_VARIANT_CODES = {
|
||||
"vesper": "STD",
|
||||
"vesper_plus": "PLS",
|
||||
"vesper_pro": "PRO",
|
||||
"agnus": "STD",
|
||||
"agnus_mini": "MIN",
|
||||
"chronos": "STD",
|
||||
"chronos_pro": "PRO",
|
||||
}
|
||||
|
||||
|
||||
def _version_suffix(board_version: str) -> str:
|
||||
"""Convert version string to 3-char suffix.
|
||||
|
||||
Rules:
|
||||
- Strip the dot: "2.3" → "23", "10.2" → "102"
|
||||
- If result is 2 digits, append "R": "23" → "23R"
|
||||
- If result is already 3 digits, use as-is: "102" → "102"
|
||||
"""
|
||||
digits = board_version.replace(".", "")
|
||||
if len(digits) >= 3:
|
||||
return digits[:3]
|
||||
return digits.ljust(2, "0") + "R"
|
||||
|
||||
|
||||
def generate_serial(board_type: str, board_version: str) -> str:
|
||||
"""Generate a serial number in the format PV-YYMMM-BBTTR-XXXXX.
|
||||
"""Generate a serial number in the format BSFFFF-YYMDDFX-VVVHHH-XXXXXX.
|
||||
|
||||
board_type: 2-char uppercase code, e.g. 'VS', 'VP', 'VX'
|
||||
board_version: 2-char zero-padded version, e.g. '01'
|
||||
Format: BSFFFF-YYMDDf-VVVvvv-XXXXXX
|
||||
BS = Bell Systems (static)
|
||||
FFFF = 4-char family code (VSPR, AGNS, CRNS)
|
||||
YY = 2-digit year
|
||||
M = month code A-L
|
||||
DD = 2-digit day
|
||||
f = random filler char
|
||||
VVV = 3-char variant (STD, PLS, PRO, MIN)
|
||||
vvv = 3-char version suffix (e.g. 23R, 102)
|
||||
XXXXXX = 6-char random suffix
|
||||
|
||||
board_type: enum value e.g. 'vesper', 'vesper_plus', 'vesper_pro'
|
||||
board_version: version string e.g. '2.3', '10.2'
|
||||
"""
|
||||
key = board_type.lower()
|
||||
family = BOARD_FAMILY_CODES.get(key, "UNKN")
|
||||
variant = BOARD_VARIANT_CODES.get(key, "UNK")
|
||||
ver = _version_suffix(board_version)
|
||||
|
||||
now = datetime.utcnow()
|
||||
year = now.strftime("%y")
|
||||
year = now.strftime("%y")
|
||||
month = MONTH_CODES[now.month - 1]
|
||||
day = now.strftime("%d")
|
||||
suffix = "".join(random.choices(SAFE_CHARS, k=5))
|
||||
version_clean = board_version.replace(".", "")
|
||||
return f"PV-{year}{month}{day}-{board_type.upper()}{version_clean}R-{suffix}"
|
||||
day = now.strftime("%d")
|
||||
filler = random.choice(SAFE_CHARS)
|
||||
suffix = "".join(random.choices(SAFE_CHARS, k=6))
|
||||
|
||||
seg1 = f"BS{family}" # e.g. BSVSPR
|
||||
seg2 = f"{year}{month}{day}{filler}" # e.g. 26C13X
|
||||
seg3 = f"{variant}{ver}" # e.g. PRO23R
|
||||
seg4 = suffix # e.g. X9K4M2
|
||||
|
||||
return f"{seg1}-{seg2}-{seg3}-{seg4}"
|
||||
|
||||
Reference in New Issue
Block a user