eive-tmtc/eive_tmtc/tmtc/payload/ploc_mpsoc.py

357 lines
13 KiB
Python
Raw Normal View History

2021-04-11 11:08:52 +02:00
# -*- coding: utf-8 -*-
"""
2021-07-11 14:29:11 +02:00
@file ploc_mpsoc.py
@brief Tests for commanding the MPSoC of the PLOC.
The MPSoC is programmed by the ILH.
2021-04-11 11:08:52 +02:00
@author J. Meier
2021-07-11 14:29:11 +02:00
@date 06.03.2021
2021-04-11 11:08:52 +02:00
"""
import struct
2022-03-21 16:22:41 +01:00
import enum
2021-04-11 11:08:52 +02:00
2022-11-29 16:53:29 +01:00
from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import get_object_ids, PLOC_MPSOC_ID
2022-08-18 15:52:06 +02:00
from tmtccmd.config.tmtc import (
tmtc_definitions_provider,
OpCodeEntry,
TmtcDefinitionWrapper,
)
2022-04-05 00:51:52 +02:00
from tmtccmd.logging import get_console_logger
2021-10-01 10:55:56 +02:00
from spacepackets.ecss.tc import PusTelecommand
2022-11-29 16:53:29 +01:00
from tmtccmd.tc import service_provider
2022-08-18 15:52:06 +02:00
from tmtccmd.tc.decorator import ServiceProviderParams
2022-11-29 16:53:29 +01:00
from eive_tmtc.utility.input_helper import InputHelper
2023-01-31 12:56:13 +01:00
from tmtccmd.tc.pus_200_fsfw_mode import pack_mode_data, Mode
2021-04-11 11:08:52 +02:00
2023-01-10 09:56:18 +01:00
2022-03-17 19:42:27 +01:00
LOGGER = get_console_logger()
2021-04-11 11:08:52 +02:00
2022-03-23 05:33:01 +01:00
MANUAL_INPUT = "1"
2022-01-18 14:03:56 +01:00
2022-03-21 16:22:41 +01:00
flash_write_file_dict = {
2022-03-17 19:42:27 +01:00
MANUAL_INPUT: ["manual input", ""],
2022-03-23 05:33:01 +01:00
"2": ["/mnt/sd0/ploc/mpsoc/flash_write.bin", "/mnt/sd0/ploc/mpsoc/flash_write.bin"],
2022-03-17 19:42:27 +01:00
}
2021-04-11 11:08:52 +02:00
2022-03-21 16:22:41 +01:00
mpsoc_file_dict = {
2022-03-26 20:48:39 +01:00
MANUAL_INPUT: ["manual input", ""],
"2": ["0:/flash", "0:/flash"],
}
2023-01-10 15:37:15 +01:00
SEQ_FILE_NAMES = ["0:/EM16/231", "0:/EQ04/E-75", "0:/EQ01/E130"]
2023-01-10 15:27:45 +01:00
SEQ_FILE_DICT = {
2022-03-21 16:22:41 +01:00
MANUAL_INPUT: ["manual input", ""],
2023-01-10 15:37:15 +01:00
"2": [f"16QRM On Carrier 200 MBd ({SEQ_FILE_NAMES[0]})", f"{SEQ_FILE_NAMES[0]}"],
"3": [f"QPSK On Carrier 780 MBd ({SEQ_FILE_NAMES[1]})", f"{SEQ_FILE_NAMES[1]}"],
2023-01-11 14:19:47 +01:00
"4": [f"Maximum Bandwidth QPSK ({SEQ_FILE_NAMES[2]})", f"{SEQ_FILE_NAMES[2]}"],
2022-03-21 16:22:41 +01:00
}
2021-04-11 11:08:52 +02:00
2023-01-10 15:27:45 +01:00
2022-04-20 21:34:14 +02:00
CARRIAGE_RETURN = 0xD
2022-03-21 16:22:41 +01:00
2023-01-16 14:13:06 +01:00
class CommandId(enum.IntEnum):
2022-03-21 16:22:41 +01:00
TC_MEM_WRITE = 1
TC_MEM_READ = 2
FLASH_WRITE = 9
TC_FLASH_DELETE = 10
TC_REPLAY_START = 11
TC_REPLAY_STOP = 12
TC_REPLAY_WRITE_SEQUENCE = 13
TC_DOWNLINK_PWR_ON = 14
TC_DOWNLINK_PWR_OFF = 15
2022-03-25 08:31:13 +01:00
OBSW_RESET_SEQ_COUNT = 50
2022-03-24 17:39:05 +01:00
TC_MODE_REPLAY = 16
2022-04-20 21:34:14 +02:00
TC_CAM_CMD_SEND = 17
TC_MODE_IDLE = 18
SET_UART_TX_TRISTATE = 20
RELEASE_UART_TX = 21
2022-03-24 17:39:05 +01:00
2023-01-16 14:13:06 +01:00
class OpCode:
2022-12-06 09:21:28 +01:00
ON = ["on"]
OFF = ["off"]
NORMAL = ["normal"]
VERIFY_BOOT = ["verify_boot"]
2022-12-06 10:34:12 +01:00
MODE_REPLAY = ["mode_replay"]
2023-01-10 09:56:18 +01:00
MODE_IDLE = ["mode_idle"]
REPLAY_WRITE_SEQ = ["replay_write"]
DOWNLINK_PWR_ON = ["downlink_pwr_on"]
REPLAY_START = ["replay_start"]
2022-12-06 09:21:28 +01:00
class Info:
ON = "On"
OFF = "Off"
NORMAL = "Normal"
VERIFY_BOOT = "Verify boot by reading 0xdeadbeef from DEADBEEF address"
2022-12-06 10:34:12 +01:00
MODE_REPLAY = "Switch to REPLAY mode"
2023-01-10 09:56:18 +01:00
MODE_IDLE = "Switch to IDLE mode"
REPLAY_WRITE_SEQ = "Replay write sequence"
DOWNLINK_PWR_ON = "Downlink Power On"
REPLAY_START = "Replay Start"
2022-12-06 10:34:12 +01:00
2022-12-06 09:21:28 +01:00
2022-03-24 17:39:05 +01:00
class MemAddresses(enum.IntEnum):
2022-03-28 11:40:13 +02:00
DEADBEEF = 0x40000004
2021-04-24 13:27:57 +02:00
2022-05-04 19:08:54 +02:00
class PlocReplyIds(enum.IntEnum):
TM_MEM_READ_RPT = 6
TM_CAM_CMD_RPT = 19
2021-04-11 11:08:52 +02:00
2022-08-18 15:52:06 +02:00
@tmtc_definitions_provider
def add_ploc_mpsoc_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry()
2023-01-16 14:13:06 +01:00
oce.add(OpCode.OFF, Info.OFF)
oce.add(OpCode.ON, Info.ON)
oce.add(OpCode.NORMAL, Info.NORMAL)
2022-08-18 15:52:06 +02:00
oce.add("3", "Ploc MPSoC: Memory write")
oce.add("4", "Ploc MPSoC: Memory read")
oce.add("5", "Ploc MPSoC: Flash write")
oce.add("6", "Ploc MPSoC: Flash delete")
2023-01-16 14:13:06 +01:00
oce.add(OpCode.REPLAY_START, Info.REPLAY_START)
2022-08-18 15:52:06 +02:00
oce.add("8", "Ploc MPSoC: Replay stop")
2023-01-16 14:13:06 +01:00
oce.add(OpCode.DOWNLINK_PWR_ON, Info.DOWNLINK_PWR_ON)
2022-08-18 15:52:06 +02:00
oce.add("10", "Ploc MPSoC: Downlink pwr off")
2023-01-16 14:13:06 +01:00
oce.add(OpCode.REPLAY_WRITE_SEQ, Info.REPLAY_WRITE_SEQ)
2022-08-18 15:52:06 +02:00
oce.add("12", "Ploc MPSoC: OBSW reset sequence count")
2023-01-16 14:13:06 +01:00
oce.add(OpCode.VERIFY_BOOT, "Ploc MPSoC: Read DEADBEEF address")
oce.add(OpCode.MODE_REPLAY, Info.MODE_REPLAY)
oce.add(OpCode.MODE_IDLE, Info.MODE_IDLE)
2022-08-18 15:52:06 +02:00
oce.add("16", "Ploc MPSoC: Tc cam command send")
oce.add("17", "Ploc MPSoC: Set UART TX tristate")
oce.add("18", "Ploc MPSoC: Relesase UART TX")
defs.add_service(CustomServiceList.PLOC_MPSOC.value, "Ploc MPSoC", oce)
@service_provider(CustomServiceList.PLOC_MPSOC)
def pack_ploc_mpsoc_commands(p: ServiceProviderParams):
object_id = get_object_ids().get(PLOC_MPSOC_ID)
q = p.queue_helper
2023-01-10 09:56:18 +01:00
prefix = "PLOC MPSoC"
2022-08-18 15:52:06 +02:00
op_code = p.op_code
2022-07-04 15:22:53 +02:00
q.add_log_cmd(
f"Generate command for PLOC MPSoC with object id: {object_id.as_hex_string}"
2021-04-11 11:08:52 +02:00
)
2022-07-04 15:22:53 +02:00
obyt = object_id.as_bytes
2023-01-16 14:13:06 +01:00
if op_code in OpCode.OFF:
2023-01-10 09:56:18 +01:00
q.add_log_cmd(f"{prefix}: {Info.OFF}")
2023-01-16 15:05:33 +01:00
command = pack_mode_data(obyt, Mode.OFF, 0)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=command))
2023-01-16 14:13:06 +01:00
if op_code in OpCode.ON:
2023-01-10 09:56:18 +01:00
q.add_log_cmd(f"{prefix}: {Info.ON}")
2023-01-16 15:05:33 +01:00
data = pack_mode_data(obyt, Mode.ON, 0)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=data))
2023-01-16 14:13:06 +01:00
if op_code in OpCode.NORMAL:
2023-01-10 09:56:18 +01:00
q.add_log_cmd(f"{prefix}: {Info.NORMAL}")
2023-01-16 15:05:33 +01:00
data = pack_mode_data(object_id.as_bytes, Mode.NORMAL, 0)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=200, subservice=1, app_data=data))
2022-03-31 11:36:50 +02:00
if op_code == "3":
2022-07-04 15:22:53 +02:00
q.add_log_cmd("PLOC MPSoC: TC mem write test")
memory_address = int(
input("PLOC MPSoC: Tc Mem Write: Type memory address: 0x"), 16
)
2022-03-17 19:42:27 +01:00
memory_data = int(input("PLOC MPSoC: Tc Mem Write: Type memory data: 0x"), 16)
# TODO: implement variable length mem write command
mem_len = 1 # 1 32-bit word
2022-07-04 15:22:53 +02:00
data = generate_write_mem_command(
object_id.as_bytes, memory_address, memory_data, mem_len
2022-01-18 14:03:56 +01:00
)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "4":
q.add_log_cmd("PLOC MPSoC: TC mem read test")
data = prepare_mem_read_command(object_id=object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "5":
q.add_log_cmd("PLOC MPSoC: Flash write")
data = prepare_flash_write_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "6":
q.add_log_cmd("PLOC MPSoC: Flash delete")
data = prepare_flash_delete_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
2023-01-16 14:13:06 +01:00
if op_code in OpCode.REPLAY_START:
2023-01-10 09:56:18 +01:00
q.add_log_cmd(f"{prefix}: {Info.REPLAY_START}")
2022-07-04 15:22:53 +02:00
data = prepare_replay_start_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "8":
q.add_log_cmd("PLOC MPSoC: Replay stop")
2023-01-16 14:13:06 +01:00
data = object_id.as_bytes + struct.pack("!I", CommandId.TC_REPLAY_STOP)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
2023-01-16 14:13:06 +01:00
if op_code in OpCode.DOWNLINK_PWR_ON:
q.add_log_cmd(f"{prefix}: {OpCode.DOWNLINK_PWR_ON}")
2022-07-04 15:22:53 +02:00
data = prepare_downlink_pwr_on_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "10":
q.add_log_cmd("PLOC MPSoC: Downlink pwr off")
2023-01-16 14:13:06 +01:00
data = object_id.as_bytes + struct.pack("!I", CommandId.TC_DOWNLINK_PWR_OFF)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
2023-01-16 14:13:06 +01:00
if op_code in OpCode.REPLAY_WRITE_SEQ:
2023-01-10 09:56:18 +01:00
q.add_log_cmd(f"{prefix}: {Info.REPLAY_WRITE_SEQ}")
2022-07-04 15:22:53 +02:00
data = prepare_replay_write_sequence_cmd(object_id.as_bytes)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "12":
q.add_log_cmd("PLOC MPSoC: Reset OBSW sequence count")
2023-01-16 14:13:06 +01:00
data = object_id.as_bytes + struct.pack("!I", CommandId.OBSW_RESET_SEQ_COUNT)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
2023-01-16 14:13:06 +01:00
if op_code in OpCode.VERIFY_BOOT:
2022-03-24 17:39:05 +01:00
num_words = 1
2022-12-06 09:21:28 +01:00
q.add_log_cmd(f"{prefix} {Info.VERIFY_BOOT}")
2022-07-04 15:22:53 +02:00
data = (
object_id.as_bytes
2023-01-16 14:13:06 +01:00
+ struct.pack("!I", CommandId.TC_MEM_READ)
+ struct.pack("!I", MemAddresses.DEADBEEF)
+ struct.pack("!H", num_words)
)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
2023-01-16 14:13:06 +01:00
if op_code in OpCode.MODE_REPLAY:
2022-07-04 15:22:53 +02:00
q.add_log_cmd("PLOC MPSoC: Tc mode replay")
2023-01-16 14:13:06 +01:00
data = object_id.as_bytes + struct.pack("!I", CommandId.TC_MODE_REPLAY)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
2023-01-16 14:13:06 +01:00
if op_code in OpCode.MODE_IDLE:
2022-07-04 15:22:53 +02:00
q.add_log_cmd("PLOC MPSoC: Tc mode idle")
2023-01-16 14:13:06 +01:00
data = object_id.as_bytes + struct.pack("!I", CommandId.TC_MODE_IDLE)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "16":
q.add_log_cmd("PLOC MPSoC: Tc cam command send")
2022-04-20 21:34:14 +02:00
cam_cmd = input("Specify cam command string: ")
2022-07-04 15:22:53 +02:00
data = (
object_id.as_bytes
2023-01-16 14:13:06 +01:00
+ struct.pack("!I", CommandId.TC_CAM_CMD_SEND)
2022-05-03 18:36:28 +02:00
+ bytearray(cam_cmd, "utf-8")
)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "17":
q.add_log_cmd("PLOC MPSoC: Set UART TX tristate")
2023-01-16 14:13:06 +01:00
data = object_id.as_bytes + struct.pack("!I", CommandId.SET_UART_TX_TRISTATE)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "18":
q.add_log_cmd("PLOC MPSoC: Release UART TX")
2023-01-16 14:13:06 +01:00
data = object_id.as_bytes + struct.pack("!I", CommandId.RELEASE_UART_TX)
2022-07-04 15:22:53 +02:00
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
2021-04-11 11:08:52 +02:00
2022-01-18 14:03:56 +01:00
def generate_write_mem_command(
2022-07-04 15:22:53 +02:00
object_id: bytes, memory_address: int, memory_data: int, mem_len: int
2022-01-18 14:03:56 +01:00
) -> bytearray:
2022-07-04 15:22:53 +02:00
"""This function generates the command to write to a memory address within the PLOC.
:param object_id: The object id of the PlocHandler
:param memory_address: The PLOC memory address where to write to.
:param memory_data: The data to write to the memory address specified by the
bytearray memory_address.
:param mem_len:
2021-04-11 11:08:52 +02:00
"""
2022-01-18 14:03:56 +01:00
command = (
object_id
2023-01-16 14:13:06 +01:00
+ struct.pack("!I", CommandId.TC_MEM_WRITE)
+ struct.pack("!I", memory_address)
+ struct.pack("!H", mem_len)
+ struct.pack("!I", memory_data)
2022-01-18 14:03:56 +01:00
)
2022-07-04 15:22:53 +02:00
return bytearray(command)
2022-03-17 19:42:27 +01:00
2022-07-04 15:22:53 +02:00
def prepare_mem_read_command(object_id: bytes) -> bytearray:
2022-03-17 19:42:27 +01:00
memory_address = int(input("PLOC MPSoC Tc Mem Read: Type memory address: 0x"), 16)
num_words = int(input("PLOC MPSoC specify number of words (32-bit) to read: "))
command = (
object_id
2023-01-16 14:13:06 +01:00
+ struct.pack("!I", CommandId.TC_MEM_READ)
+ struct.pack("!I", memory_address)
+ struct.pack("!H", num_words)
2022-03-17 19:42:27 +01:00
)
2022-07-04 15:22:53 +02:00
return bytearray(command)
2022-03-17 19:42:27 +01:00
2022-07-04 15:22:53 +02:00
def prepare_flash_write_cmd(object_id: bytes) -> bytearray:
2022-03-26 20:48:39 +01:00
obcFile = get_obc_file()
2022-03-23 05:33:01 +01:00
mpsocFile = get_mpsoc_file()
command = (
object_id
2023-01-16 14:13:06 +01:00
+ struct.pack("!I", CommandId.FLASH_WRITE)
+ bytearray(obcFile, "utf-8")
+ bytearray(mpsocFile, "utf-8")
)
2022-07-04 15:22:53 +02:00
return bytearray(command)
2022-03-21 16:22:41 +01:00
2022-07-04 15:22:53 +02:00
def prepare_flash_delete_cmd(object_id: bytes) -> bytearray:
2022-03-21 16:22:41 +01:00
file = get_mpsoc_file()
command = (
object_id
2023-01-16 14:13:06 +01:00
+ struct.pack("!I", CommandId.TC_FLASH_DELETE)
+ bytearray(file, "utf-8")
)
2022-07-04 15:22:53 +02:00
return bytearray(command)
2022-03-21 16:22:41 +01:00
2022-07-04 15:22:53 +02:00
def prepare_replay_start_cmd(object_id: bytes) -> bytearray:
replay = int(input("Specify replay mode (0 - once, 1 - repeated): "))
command = (
object_id
2023-01-16 14:13:06 +01:00
+ struct.pack("!I", CommandId.TC_REPLAY_START)
+ struct.pack("!B", replay)
)
2022-07-04 15:22:53 +02:00
return bytearray(command)
2022-03-21 16:22:41 +01:00
2022-07-04 15:22:53 +02:00
def prepare_downlink_pwr_on_cmd(object_id: bytes) -> bytearray:
2022-03-21 16:22:41 +01:00
mode = int(input("Specify JESD mode (0 - 5): "))
lane_rate = int(input("Specify lane rate (0 - 9): "))
command = (
object_id
2023-01-16 14:13:06 +01:00
+ struct.pack("!I", CommandId.TC_DOWNLINK_PWR_ON)
+ struct.pack("!B", mode)
+ struct.pack("!B", lane_rate)
)
2022-07-04 15:22:53 +02:00
return bytearray(command)
2022-03-21 16:22:41 +01:00
2022-07-04 15:22:53 +02:00
def prepare_replay_write_sequence_cmd(object_id: bytes) -> bytearray:
2022-03-21 16:22:41 +01:00
use_decoding = int(input("Use decoding (set to 1): "))
2022-03-26 20:48:39 +01:00
file = get_sequence_file()
command = (
object_id
2023-01-16 14:13:06 +01:00
+ struct.pack("!I", CommandId.TC_REPLAY_WRITE_SEQUENCE)
+ struct.pack("!B", use_decoding)
+ bytearray(file, "utf-8")
2022-12-06 10:34:12 +01:00
# + bytes([0])
)
2022-07-04 15:22:53 +02:00
return bytearray(command)
2022-03-17 19:42:27 +01:00
2022-03-26 20:48:39 +01:00
def get_obc_file() -> str:
LOGGER.info("Specify OBC file ")
2022-03-21 16:22:41 +01:00
input_helper = InputHelper(flash_write_file_dict)
key = input_helper.get_key()
if key == MANUAL_INPUT:
file = input("Ploc MPSoC: Specify absolute name of flash file: ")
else:
file = flash_write_file_dict[key][1]
return file
def get_mpsoc_file() -> str:
2022-03-26 20:48:39 +01:00
LOGGER.info("Specify MPSoC file")
2022-03-21 16:22:41 +01:00
input_helper = InputHelper(mpsoc_file_dict)
2022-03-17 19:42:27 +01:00
key = input_helper.get_key()
if key == MANUAL_INPUT:
2022-03-21 16:22:41 +01:00
file = input("Ploc MPSoC: Specify absolute name file: ")
2022-03-17 19:42:27 +01:00
else:
2022-03-21 16:22:41 +01:00
file = mpsoc_file_dict[key][1]
2022-03-17 19:42:27 +01:00
return file
2022-03-26 20:48:39 +01:00
def get_sequence_file() -> str:
LOGGER.info("Specify sequence file")
2023-01-10 15:27:45 +01:00
input_helper = InputHelper(SEQ_FILE_DICT)
2022-03-26 20:48:39 +01:00
key = input_helper.get_key()
if key == MANUAL_INPUT:
file = input("Ploc MPSoC: Specify absolute name file: ")
else:
2023-01-10 15:27:45 +01:00
file = SEQ_FILE_DICT[key][1]
2022-03-26 20:48:39 +01:00
return file