From feaa1733ec0a0d23636c91de95a4c1dd037124f6 Mon Sep 17 00:00:00 2001 From: ryanpdx Date: Sun, 26 Nov 2023 21:14:50 -0800 Subject: [PATCH] add python script to set the node id --- doc/setting_node_ids.md | 42 ++++++------ flash_node_id.py | 146 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 21 deletions(-) create mode 100755 flash_node_id.py diff --git a/doc/setting_node_ids.md b/doc/setting_node_ids.md index 04416815..7af52ae1 100644 --- a/doc/setting_node_ids.md +++ b/doc/setting_node_ids.md @@ -74,7 +74,7 @@ Run `halt`. This seems to be important, we don’t want the processor doing weir Read all 32 bit option bytes registers: ``` -mdw 0x1ffff800 4 +> mdw 0x1ffff800 4 0x1ffff800: 00ff55aa 00ff00ff 00ff00ff 00ff00ff ``` @@ -83,7 +83,7 @@ We can see 0x1ffff804 is 00ff, which is our nData0:Data0. Check that the flash is locked: ``` -mdw 0x40022010 +> mdw 0x40022010 0x40022010: 00000080 ``` @@ -91,14 +91,14 @@ Unlock the flash directly performing the unlocking sequence on the FLASH_KEYR (0x40022004) register. ``` -mww 0x40022004 0x45670123 -mww 0x40022004 0xCDEF89AB +> mww 0x40022004 0x45670123 +> mww 0x40022004 0xCDEF89AB ``` Reassure that the flash is unlocked. Read the FLASH_CR: ``` -mdw 0x40022010 +> mdw 0x40022010 0x40022010: 00000000 ``` @@ -106,24 +106,24 @@ Unlock option bytes for writing (which is described in the reference manual as setting the OPTWRE bit in the FLASH_CR). ``` -mww 0x40022008 0x45670123 -mww 0x40022008 0xCDEF89AB -mdw 0x40022010 +> mww 0x40022008 0x45670123 +> mww 0x40022008 0xCDEF89AB +> mdw 0x40022010 0x40022010: 00000200 ``` Clear option bytes (they are stored in the FLASH after all). ``` -mww 0x40022010 0x00000220 -mww 0x40022010 0x00000260 +> mww 0x40022010 0x00000220 +> mww 0x40022010 0x00000260 ``` Enable programming by setting FLASH_CR.OPTPG: ``` -mww 0x40022010 0x00000210 -mdw 0x40022010 +> mww 0x40022010 0x00000210 +> mdw 0x40022010 0x40022010: 00000210 ``` @@ -140,20 +140,20 @@ ID in the high byte (e.g., 0xfb). - Solar Module 2 Node ID 0x14: 0xe ``` -mwh 0x1ffff800 0x55AA -mwh 0x1ffff802 0x00ff -mwh 0x1ffff804 0xfb04 // set node id here -mwh 0x1ffff806 0x00ff -mwh 0x1ffff808 0x00ff -mwh 0x1ffff80a 0x00ff -mwh 0x1ffff80c 0x00ff -mwh 0x1ffff80e 0x00ff +> mwh 0x1ffff800 0x55AA +> mwh 0x1ffff802 0x00ff +> mwh 0x1ffff804 0xfb04 // set node id here +> mwh 0x1ffff806 0x00ff +> mwh 0x1ffff808 0x00ff +> mwh 0x1ffff80a 0x00ff +> mwh 0x1ffff80c 0x00ff +> mwh 0x1ffff80e 0x00ff ``` Now we can check this worked: ``` -mdw 0x1ffff800 4 +> mdw 0x1ffff800 4 0x1ffff800: 00ff55aa 00fffb04 00ff00ff 00ff00ff ``` diff --git a/flash_node_id.py b/flash_node_id.py new file mode 100755 index 00000000..d4714bb0 --- /dev/null +++ b/flash_node_id.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python3 +"""Flash a node id to OreSat firmware card.""" + +import subprocess +import sys +import warnings +warnings.filterwarnings("ignore", category=DeprecationWarning) +from argparse import ArgumentParser +from telnetlib import Telnet +from threading import Thread +from time import sleep + +NODE_IDS = { + ("battery", 1): 0x04, + ("battery", 2): 0x08, + ("solar_module", 1): 0x0C, + ("solar_module", 2): 0x10, + ("solar_module", 3): 0x14, + ("solar_module", 4): 0x18, + ("solar_module", 5): 0x1C, + ("solar_module", 6): 0x20, + ("solar_module", 7): 0x24, + ("solar_module", 8): 0x28, + ("adcs", 1): 0x38, + ("reactiom_wheel", 1): 0x3C, + ("reactiom_wheel", 2): 0x40, + ("reactiom_wheel", 3): 0x44, + ("reactiom_wheel", 4): 0x48, +} + +CONFIG_PATH = { + "battery": "boards/BATTERY_V3/oocd.cfg", + "solar_module": "boards/SOLAR_V4/oocd.cfg", + "adcs": "boards/ORESAT_ADCS_V1_2/oocd.cfg", + "reactiom_wheel": "boards/ORESAT_RWB_V4/oocd.cfg", +} + +CARD_ALIASES = { + "battery": ["bat"], + "solar_module": ["solar"], + "adcs": ["imu"], + "reactiom_wheel": ["rw"], +} + +parser = ArgumentParser(description="Flash the node id to a OreSat firmware card") +parser.add_argument("card") +parser.add_argument("-n", "--number", type=int, default=1) +parser.add_argument("-o", "--host", default="localhost") +parser.add_argument("-p", "--port", default="4444") +args = parser.parse_args() + +node_id = 0x1 +card = args.card.lower().replace("-", "_") + +for key, values in CARD_ALIASES.items(): + if card == key: + break + elif card in values: + card = key + break +else: + print(f"failed to find card with name or alias of {args.card}") + sys.exit(1) + +try: + node_id = NODE_IDS[(card, args.number)] +except KeyError: + print(f"failed to find card with name {args.card} and number {args.number}") + sys.exit(1) + +proc = None +failed = False + +inv_node_id = 255 - node_id +value = hex(inv_node_id << 8 | node_id) + + +def run_openocd(): + print("starting openocd") + global proc + config_path = CONFIG_PATH[card] + proc = subprocess.Popen( + ["openocd", "-f", f"{config_path}"], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) + + +thread = Thread(target=run_openocd) +thread.start() + +sleep(2) + + +def telnet_write(tn: Telnet, msg: str): + tn.write(f"{msg}\r\n".encode()) + sleep(0.1) + + +try: + with Telnet(args.host, args.port) as tn: + print("connect with telnet") + sleep(2) + # stop the firmware + print("halting firmware") + tn.write(b"halt\r\n") + + # unlock flash + print("unlock flash") + telnet_write(tn, "mww 0x40022004 0x45670123") + telnet_write(tn, "mww 0x40022004 0xCDEF89AB") + + # unlock option bytes for writing + print("unlock option bytes") + telnet_write(tn, "mww 0x40022008 0x45670123") + telnet_write(tn, "mww 0x40022008 0xCDEF89AB") + + # clear option bytes + print("clear option bytes") + telnet_write(tn, "mww 0x40022010 0x00000220") + telnet_write(tn, "mww 0x40022010 0x00000260") + + # enable programing + print("enable programing") + telnet_write(tn, "mww 0x40022010 0x00000210") + + # write node_id + print("write node_id") + telnet_write(tn, "mwh 0x1ffff800 0x55AA") + telnet_write(tn, "mwh 0x1ffff802 0x00ff") + telnet_write(tn, f"mwh 0x1ffff804 {value}") # node id set here + telnet_write(tn, "mwh 0x1ffff806 0x00ff") + telnet_write(tn, "mwh 0x1ffff808 0x00ff") + telnet_write(tn, "mwh 0x1ffff80a 0x00ff") + telnet_write(tn, "mwh 0x1ffff80c 0x00ff") + telnet_write(tn, "mwh 0x1ffff80e 0x00ff") +except OSError: + print("Failed to write node id due to a telnet connection error") + failed = True + +sleep(0.5) +proc.terminate() +thread.join() + +if not failed: + print("node id was flashed")