Files
bumble-auracast/src/auracast/utils/reset_utils.py
pstruebi 430fb1009d bugfixes/prepare_for_first_unit (#8)
- update ui
- implement different features like restart
- bugfixes

Co-authored-by: pstruebi <struebin.patrick.com>
Reviewed-on: https://gitea.pstruebi.xyz/auracaster/bumble-auracast/pulls/8
2025-10-06 12:16:39 +02:00

78 lines
2.8 KiB
Python

import os
import asyncio
import logging as log
async def reset_nrf54l(slot: int = 0, timeout: float = 8.0):
"""
Reset the nRF54L target using OpenOCD before starting broadcast.
Looks for interface config files in the project at `src/openocd/` relative to this module only.
Accepts filename variants per slot:
- slot 0: raspberrypi-swd0.cfg or swd0.cfg
- slot 1: raspberrypi-swd1.cfg or swd1.cfg
Executes the equivalent of:
openocd \
-f ./raspberrypi-${INTERFACE}.cfg \
-f target/nordic/nrf54l.cfg \
-c "init" \
-c "reset run" \
-c "shutdown"
Best-effort: if OpenOCD is unavailable, logs a warning and continues.
"""
try:
# Resolve project directory and filenames
proj_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'openocd'))
names = ['raspberrypi-swd0.cfg', 'swd0.cfg'] if slot == 0 else ['raspberrypi-swd1.cfg', 'swd1.cfg']
cfg = None
for n in names:
p = os.path.join(proj_dir, n)
if os.path.exists(p):
cfg = p
break
if not cfg:
log.warning("reset_nrf54l: no interface CFG found in project dir %s; skipping reset", proj_dir)
return
# Build openocd command (no sudo required as per project setup).
cmd = ['openocd', '-f', cfg, '-f', 'target/nordic/nrf54l.cfg',
'-c', 'init', '-c', 'reset run', '-c', 'shutdown']
async def _run(cmd):
proc = await asyncio.create_subprocess_exec(
*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT
)
try:
out, _ = await asyncio.wait_for(proc.communicate(), timeout=timeout)
except asyncio.TimeoutError:
log.error("reset_nrf54l: %s timed out; terminating", cmd[0])
proc.kill()
return False
rc = proc.returncode
if rc != 0:
log.error("reset_nrf54l: %s exited with code %s; output: %s", cmd[0], rc, (out or b'').decode(errors='ignore'))
return False
return True
ok = await _run(cmd)
if ok:
log.info("reset_nrf54l: reset succeeded (slot %d) using %s", slot, cfg)
except FileNotFoundError:
log.error("reset_nrf54l: openocd not found; skipping reset")
except Exception:
log.error("reset_nrf54l failed", exc_info=True)
if __name__ == '__main__':
# Basic logging setup
log.basicConfig(
level=os.environ.get('LOG_LEVEL', log.INFO),
format='%(asctime)s.%(msecs)03d %(levelname)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
slot_to_reset = 1
log.info(f"Executing reset for slot {slot_to_reset}")
asyncio.run(reset_nrf54l(slot=slot_to_reset))