#!/usr/bin/env python3 # # This file is part of the MicroPython project, http://micropython.org/ # # The MIT License (MIT) # # Copyright (c) 2021 Philipp Ebensberger # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. """Evaluate FlexRAM configuration and generate startup code.""" import re import argparse # Regex for linker script configuration ocram_regex = r"^\s*ocrm_size\s*=\s*(?P.*);" dtcm_regex = r"^\s*dtcm_size\s*=\s*(?P.*);" itcm_regex = r"^\s*itcm_size\s*=\s*(?P.*);" # Regex for GPR register base define in NXL hal gpr_base_regex = r"^.*IOMUXC_GPR_BASE\s*\((?P\w*)u\)" # Regex for FlexRAM parameters in NXP HAL fsl_ram_bank_size_regex = r"^.*FSL_FEATURE_FLEXRAM_INTERNAL_RAM_BANK_SIZE\s*\((?P\w*)\)" fsl_bank_nbr_regex = ( r"^.*FSL_FEATURE_FLEXRAM_INTERNAL_RAM_TOTAL_BANK_NUMBERS\s*\((?P\w*)\)" ) """ According to AN12077: The minimum configuration of OCRAM is 64 KB. This is required due to ROM code requires at least 64 KB of RAM for its execution. 2.1.1.1. Static configuration - Page 4 """ ocram_min_size = 0x00010000 # 64 KB # Value parser def mimxrt_default_parser(defines_file, features_file, ld_script): with open(ld_script, "r") as input_file: input_str = input_file.read() # ocram_match = re.search(ocram_regex, input_str, re.MULTILINE) dtcm_match = re.search(dtcm_regex, input_str, re.MULTILINE) itcm_match = re.search(itcm_regex, input_str, re.MULTILINE) with open(defines_file, "r") as input_file: input_str = input_file.read() mcu_define_file_match = re.search(gpr_base_regex, input_str, re.MULTILINE) with open(features_file, "r") as input_file: input_str = input_file.read() fsl_ram_bank_size_match = re.search(fsl_ram_bank_size_regex, input_str, re.MULTILINE) fsl_bank_nbr_match = re.search(fsl_bank_nbr_regex, input_str, re.MULTILINE) # extract = { "ocram_size": int(ocram_match.group("size"), 16), "dtcm_size": int(dtcm_match.group("size"), 16), "itcm_size": int(itcm_match.group("size"), 16), "gpr_base_addr": int(mcu_define_file_match.group("base_addr"), 16), "fsl_ram_bank_size": int(fsl_ram_bank_size_match.group("size")), "fsl_bank_nbr": int(fsl_bank_nbr_match.group("number")), } # Evaluate configuration if extract["ocram_size"] < ocram_min_size: raise ValueError("OCRAM size must be at least {:08X}!".format(ocram_min_size)) if (extract["ocram_size"] % extract["fsl_ram_bank_size"]) != 0: raise ValueError("Configuration invalid!") # Check if DTCM and ITCM size is either multiple of 32k or 4k,8k or 16k if extract["dtcm_size"] != 0x0: if extract["dtcm_size"] % extract["fsl_ram_bank_size"] != 0: if extract["dtcm_size"] not in (0x00000000, 0x00001000, 0x00002000, 0x00004000): raise ValueError("Configuration invalid!") if extract["itcm_size"] != 0x0: if extract["itcm_size"] % extract["fsl_ram_bank_size"] != 0: if extract["itcm_size"] not in (0x00000000, 0x00001000, 0x00002000, 0x00004000): raise ValueError("Configuration invalid!") # return extract # Code generators def mimxrt_default_gen_code(extract_dict): flexram_bank_cfg = "0b" avail_flexram = extract_dict["fsl_ram_bank_size"] * extract_dict["fsl_bank_nbr"] if ( extract_dict["ocram_size"] + extract_dict["dtcm_size"] + extract_dict["itcm_size"] ) > avail_flexram: raise ValueError("Configuration exceeds available FlexRAM!") bit_patterns = ( (extract_dict["ocram_size"], "01"), (extract_dict["dtcm_size"], "10"), (extract_dict["itcm_size"], "11"), ) for size, pattern in bit_patterns: for _ in range(0, size, extract_dict["fsl_ram_bank_size"]): flexram_bank_cfg += pattern # Generate GPR Register config print(".equ __iomux_gpr14_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x38)) print(".equ __iomux_gpr16_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x40)) print(".equ __iomux_gpr17_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x44)) print( ".equ __iomux_gpr17_value, 0x{:08X} /* {}k OCRAM, {}k DTCM, {}k ITCM */".format( int(flexram_bank_cfg, 2), extract_dict["ocram_size"] // 1024, extract_dict["dtcm_size"] // 1024, extract_dict["itcm_size"] // 1024, ) ) def mimxrt_106x_gen_code(extract_dict): flexram_bank_cfg = "0b" avail_flexram = extract_dict["fsl_ram_bank_size"] * extract_dict["fsl_bank_nbr"] flexram_configurable_ocram = ( extract_dict["ocram_size"] % 524288 ) # 512kB OCRAM are not part of FlexRAM configurable memory if ( flexram_configurable_ocram + extract_dict["dtcm_size"] + extract_dict["itcm_size"] ) > avail_flexram: raise ValueError("Configuration exceeds available FlexRAM!") for size, pattern in ( (flexram_configurable_ocram, "01"), (extract_dict["dtcm_size"], "10"), (extract_dict["itcm_size"], "11"), ): for _ in range(0, size, extract_dict["fsl_ram_bank_size"]): flexram_bank_cfg += pattern # Generate GPR Register config print(".equ __iomux_gpr14_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x38)) print(".equ __iomux_gpr16_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x40)) print(".equ __iomux_gpr17_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x44)) print( ".equ __iomux_gpr17_value, 0x{:08X} /* {}k OCRAM (512k OCRAM, {}k from FlexRAM), {}k DTCM, {}k ITCM */".format( int(flexram_bank_cfg, 2), extract_dict["ocram_size"] // 1024, flexram_configurable_ocram // 1024, extract_dict["dtcm_size"] // 1024, extract_dict["itcm_size"] // 1024, ) ) def mimxrt_1176_gen_code(extract_dict): flexram_bank_cfg = "0b" avail_flexram = extract_dict["fsl_ram_bank_size"] * extract_dict["fsl_bank_nbr"] flexram_configurable_ocram = ( extract_dict["ocram_size"] % 524288 ) # 512kB OCRAM are not part of FlexRAM configurable memory if ( flexram_configurable_ocram + extract_dict["dtcm_size"] + extract_dict["itcm_size"] ) > avail_flexram: raise ValueError("Configuration exceeds available FlexRAM!") for size, pattern in ( (flexram_configurable_ocram, "01"), (extract_dict["dtcm_size"], "10"), (extract_dict["itcm_size"], "11"), ): for _ in range(0, size, extract_dict["fsl_ram_bank_size"]): flexram_bank_cfg += pattern # Generate GPR Register config print(".equ __iomux_gpr14_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x38)) print(".equ __iomux_gpr16_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x40)) print(".equ __iomux_gpr17_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x44)) print(".equ __iomux_gpr18_adr, 0x{:08X}".format(extract_dict["gpr_base_addr"] + 0x48)) print( ".equ __iomux_gpr17_value, 0x{:08X} /* {}k OCRAM (512k OCRAM, {}k from FlexRAM), {}k DTCM, {}k ITCM */".format( int(flexram_bank_cfg, 2) & 0xFFFF, extract_dict["ocram_size"] // 1024, flexram_configurable_ocram // 1024, extract_dict["dtcm_size"] // 1024, extract_dict["itcm_size"] // 1024, ) ) print(".equ __iomux_gpr18_value, 0x{:08X}".format((int(flexram_bank_cfg, 2) >> 16) & 0xFFFF)) def main(defines_file, features_file, ld_script, controller): dispatcher = { "MIMXRT1011": (mimxrt_default_parser, mimxrt_default_gen_code), "MIMXRT1015": (mimxrt_default_parser, mimxrt_default_gen_code), "MIMXRT1021": (mimxrt_default_parser, mimxrt_default_gen_code), "MIMXRT1052": (mimxrt_default_parser, mimxrt_default_gen_code), "MIMXRT1062": (mimxrt_default_parser, mimxrt_106x_gen_code), "MIMXRT1064": (mimxrt_default_parser, mimxrt_106x_gen_code), "MIMXRT1176": (mimxrt_default_parser, mimxrt_1176_gen_code), } extractor, code_generator = dispatcher[controller] extract_dict = extractor(defines_file, features_file, ld_script) code_generator(extract_dict) if __name__ == "__main__": parser = argparse.ArgumentParser( prog="make-flexram-ld.py", usage="%(prog)s [options] [command]", description="Evaluate FlexRAM configuration and generate startup code.", ) parser.add_argument( "-d", "--defines_file", dest="defines_file", help="Path to MCU defines file", default="../../../lib/nxp_driver/sdk/devices/MIMXRT1021/MIMXRT1021.h", ) parser.add_argument( "-f", "--features_file", dest="features_file", help="Path to MCU features file", default="../../../lib/nxp_driver/sdk/devices/MIMXRT1021/MIMXRT1021_features.h", ) parser.add_argument( "-l", "--ld_file", dest="linker_file", help="Path to the aggregated linker-script", default="MIMXRT1021.ld", ) parser.add_argument( "-c", "--controller", dest="controller", help="Controller name", default="MIMXRT1021" ) # args = parser.parse_args() main(args.defines_file, args.features_file, args.linker_file, args.controller)