From 3f47512b1f4c0946797b8e1cb34c02e294587fe6 Mon Sep 17 00:00:00 2001 From: Marko Mecina <marko.mecina@univie.ac.at> Date: Mon, 5 May 2025 14:14:58 +0200 Subject: [PATCH] add utilities for ARIEL ASW on-board image generation --- Ccs/tools/asw_upload/asw_image_lib_ariel.py | 100 ++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 Ccs/tools/asw_upload/asw_image_lib_ariel.py diff --git a/Ccs/tools/asw_upload/asw_image_lib_ariel.py b/Ccs/tools/asw_upload/asw_image_lib_ariel.py new file mode 100644 index 0000000..a2a8a5a --- /dev/null +++ b/Ccs/tools/asw_upload/asw_image_lib_ariel.py @@ -0,0 +1,100 @@ +import crcmod +import ctypes + + +HEADER_VERSION = 0x01 +FILLER = 0x00 + +N_SECT_HEADERS = 8 +SECTION_HEADER_SIZE = 16 +HEADER_SIZE = 8 + N_SECT_HEADERS * SECTION_HEADER_SIZE + +MEM_MRAM_ID = 2 +MEM_MRAM_START = 0x10000000 +MEM_MRAM_SIZE = 0x200000 + +MEM_RAM_ID = 6 +MEM_RAM_START = 0x40000000 +MEM_RAM_SIZE = 0x1000000 + +ASW_IMG_OFFSET = 0x80000 + + +puscrc = crcmod.predefined.mkPredefinedCrcFun('crc-ccitt-false') + + +class SectionHeaderFields(ctypes.BigEndianStructure): + _pack_ = 1 + _fields_ = [("TARGET_ADDR", ctypes.c_uint32), + ("SIZE", ctypes.c_uint32), + ("SOURCE_ADDR", ctypes.c_uint32), + ("SOURCE_SECT_ID", ctypes.c_uint8), + ("FILLER", ctypes.c_uint8), + ("CRC16", ctypes.c_uint16)] + + +class ImageHeaderFields(ctypes.BigEndianStructure): + _pack_ = 1 + _fields_ = [("HEADER_CRC16", ctypes.c_uint16), + ("HEADER_VERSION", ctypes.c_uint8), + ("FILLER", ctypes.c_uint8), + ("ENTRY_POINT", ctypes.c_uint32), + ("SECTION1", SectionHeaderFields), + ("SECTION2", SectionHeaderFields), + ("SECTION3", SectionHeaderFields), + ("SECTION4", SectionHeaderFields), + ("SECTION5", SectionHeaderFields), + ("SECTION6", SectionHeaderFields), + ("SECTION7", SectionHeaderFields), + ("SECTION8", SectionHeaderFields)] + + +class ImageHeader(ctypes.Union): + _pack_ = 1 + _fields_ = [("fields", ImageHeaderFields), + ("bin", ctypes.c_ubyte * HEADER_SIZE)] + + def __init__(self, memid, entrypoint, data, data_addr_offset=HEADER_SIZE): + + super().__init__() + + self.fields.HEADER_VERSION = HEADER_VERSION + self.fields.FILLER = FILLER + self.fields.ENTRY_POINT = entrypoint + + self.set_section(1, data, entrypoint, data_addr_offset, memid) + + self.fields.HEADER_CRC16 = puscrc(bytes(self.bin[2:])) + + def set_section(self, n, data, target_addr, source_addr, memid): + + sect = getattr(self.fields, "SECTION{}".format(n)) + sect.TARGET_ADDR = target_addr + sect.SOURCE_ADDR = source_addr + sect.SOURCE_SECT_ID = memid + + # assert len(data) % 4 == 0 + + sect.SIZE = len(data) + sect.CRC16 = puscrc(data) + + +class AswImage: + + def __init__(self, memid, entrypoint, aswfile, skip_bytes=0): + + assert isinstance(aswfile, str) + + data = open(aswfile, 'rb').read()[skip_bytes:] + + self.header = ImageHeader(memid, entrypoint, data) + self.data = data + + @property + def img(self): + return bytes(self.header) + self.data + + @property + def size(self): + """Total size of ASW image, including header""" + return len(self.img) -- GitLab