circuitpython/ports/mimxrt/boards/make-flexram-config.py

220 lines
8.5 KiB
Python

#!/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<size>.*);"
dtcm_regex = r"^\s*dtcm_size\s*=\s*(?P<size>.*);"
itcm_regex = r"^\s*itcm_size\s*=\s*(?P<size>.*);"
# Regex for GPR register base define in NXL hal
gpr_base_regex = r"^.*IOMUXC_GPR_BASE\s*\((?P<base_addr>\w*)u\)"
# Regex for FlexRAM parameters in NXP HAL
fsl_ram_bank_size_regex = r"^.*FSL_FEATURE_FLEXRAM_INTERNAL_RAM_BANK_SIZE\s*\((?P<size>\w*)\)"
fsl_bank_nbr_regex = (
r"^.*FSL_FEATURE_FLEXRAM_INTERNAL_RAM_TOTAL_BANK_NUMBERS\s*\((?P<number>\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 main(defines_file, features_file, ld_script, controller):
dispatcher = {
"MIMXRT1011": (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),
}
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)